7#include <QtQuick3DRuntimeRender/private/qssgrenderloadedtexture_p.h>
9#include <QtQuick3DRuntimeRender/private/qssgruntimerenderlogging_p.h>
10#include <QtQuick3DUtils/private/qssgmeshbvhbuilder_p.h>
11#include <QtQuick3DUtils/private/qssgbounds3_p.h>
12#include <QtQuick3DUtils/private/qssgassert_p.h>
14#include <QtQuick/QSGTexture>
17#include <QtGui/private/qimage_p.h>
18#include <QtQuick/private/qsgtexture_p.h>
19#include <QtQuick/private/qsgcompressedtexture_p.h>
21#include "../utils/qssgrenderbasetypes_p.h"
22#include <QtQuick3DRuntimeRender/private/qssgrendergeometry_p.h>
23#include <QtQuick3DRuntimeRender/private/qssgrendermodel_p.h>
24#include <QtQuick3DRuntimeRender/private/qssgrenderimage_p.h>
25#include <QtQuick3DRuntimeRender/private/qssgrendertexturedata_p.h>
27#include <QtQuick3DRuntimeRender/private/qssglightmapper_p.h>
28#include <QtQuick3DRuntimeRender/private/qssgrenderresourceloader_p.h>
29#include <qtquick3d_tracepoints_p.h>
91 const auto &
path = rpath.path();
107 const char *primitive;
115 {
"#Rectangle",
"/Rectangle.mesh"},
116 {
"#Sphere",
"/Sphere.mesh"},
117 {
"#Cube",
"/Cube.mesh"},
118 {
"#Cone",
"/Cone.mesh"},
119 {
"#Cylinder",
"/Cylinder.mesh"},
126 return QSize(
qMax(1, baseLevelSize.width() >> mipLevel),
qMax(1, baseLevelSize.height() >> mipLevel));
136 m_contextInterface =
nullptr;
141 m_contextInterface =
ctx;
160 LoadRenderImageFlags
flags)
167 if (
image->m_qsgTexture) {
171 if (!rhiTex || rhiTex->rhi() == rhi) {
176 if (qsgTexture->isAtlasTexture()) {
183 qsgTexture = qsgTexture->removedFromAtlas(rub);
185 qsgTexture->commitTextureOperations(rhi, rub);
186 context->commandBuffer()->resourceUpdate(rub);
187 auto theImage = qsgImageMap.find(qsgTexture);
188 if (theImage == qsgImageMap.end())
189 theImage = qsgImageMap.insert(qsgTexture,
ImageData());
190 theImage.value().renderImageTexture.m_texture = qsgTexture->rhiTexture();
191 theImage.value().renderImageTexture.m_flags.setHasTransparency(qsgTexture->hasAlphaChannel());
192 theImage.value().usageCounts[currentLayer]++;
193 result = theImage.value().renderImageTexture;
200 qWarning(
"Cannot use QSGTexture from Texture.sourceItem as light probe.");
202 qWarning(
"Cannot use QSGTexture (presumably from Texture.sourceItem) created in another "
203 "window that was using a different graphics device/context. "
204 "Avoid using View3D.importScene between multiple windows.");
207 }
else if (
image->m_rawTextureData) {
210 result = loadTextureData(
image->m_rawTextureData, inMipMode);
212 }
else if (!
image->m_imagePath.isEmpty()) {
215 auto foundIt = imageMap.find(imageKey);
216 if (foundIt != imageMap.cend()) {
217 result = foundIt.value().renderImageTexture;
220 QScopedPointer<QSSGLoadedTexture> theLoadedTexture;
221 const auto &
path =
image->m_imagePath.path();
225 if (theLoadedTexture) {
226 foundIt = imageMap.insert(imageKey,
ImageData());
227 CreateRhiTextureFlags rhiTexFlags = ScanForTransparency;
228 if (
image->type == QSSGRenderGraphObject::Type::ImageCube)
229 rhiTexFlags |= CubeMap;
230 if (!createRhiTexture(foundIt.value().renderImageTexture, theLoadedTexture.data(), inMipMode, rhiTexFlags,
QFileInfo(
path).
fileName())) {
233 qDebug() <<
"+ uploadTexture: " <<
image->m_imagePath.path() << currentLayer;
235 result = foundIt.value().renderImageTexture;
241 foundIt = imageMap.insert(imageKey,
ImageData());
246 foundIt.value().usageCounts[currentLayer]++;
247 }
else if (
image->m_extensionsSource) {
248 auto it = renderExtensionTexture.find(
image->m_extensionsSource);
249 if (
it != renderExtensionTexture.end()) {
250 it->usageCounts[currentLayer]++;
260 const CustomImageCacheKey imageKey = {
data, inMipMode };
261 auto theImageData = customTextureMap.find(imageKey);
262 if (theImageData == customTextureMap.end()) {
263 theImageData = customTextureMap.insert(imageKey, ImageData());
264 }
else if (
data->generationId() != theImageData->generationId) {
268 theImageData = customTextureMap.insert(imageKey, ImageData());
271 theImageData.value().usageCounts[currentLayer]++;
272 return theImageData.value().renderImageTexture;
276 QScopedPointer<QSSGLoadedTexture> theLoadedTexture;
277 if (!
data->textureData().isNull()) {
279 theLoadedTexture->ownsData =
false;
280 CreateRhiTextureFlags rhiTexFlags = {};
281 if (theLoadedTexture->depth > 0)
282 rhiTexFlags |= Texture3D;
283 if (createRhiTexture(theImageData.value().renderImageTexture, theLoadedTexture.data(), inMipMode, rhiTexFlags,
data->debugObjectName)) {
285 qDebug() <<
"+ uploadTexture: " <<
data << currentLayer;
286 theImageData.value().generationId =
data->generationId();
289 theImageData.value() = ImageData();
293 theImageData.value().usageCounts[currentLayer]++;
294 return theImageData.value().renderImageTexture;
304 auto foundIt = imageMap.find(imageKey);
305 if (foundIt != imageMap.end()) {
306 result = foundIt.value().renderImageTexture;
310 QScopedPointer<QSSGLoadedTexture> theLoadedTexture;
312 if (!theLoadedTexture)
314 foundIt = imageMap.insert(imageKey,
ImageData());
315 if (theLoadedTexture) {
316 if (!createRhiTexture(foundIt.value().renderImageTexture, theLoadedTexture.data(),
MipModeDisable, {}, imagePath))
318 result = foundIt.value().renderImageTexture;
323 foundIt.value().usageCounts[currentLayer]++;
334 if (!
model.meshPath.isNull()) {
335 const auto foundIt = meshMap.constFind(
model.meshPath);
336 if (foundIt != meshMap.constEnd())
337 return foundIt->mesh;
340 if (
model.geometry) {
341 const auto foundIt = customMeshMap.constFind(
model.geometry);
342 if (foundIt != customMeshMap.constEnd())
343 return foundIt->mesh;
538 int suggestedSize = inImage->height * 0.5f;
539 suggestedSize =
qMax(512, suggestedSize);
540 const QSize environmentMapSize(suggestedSize, suggestedSize);
544 if (!rhi->isTextureFormatSupported(sourceTextureFormat))
549 : sourceTextureFormat;
556 const int colorSpace = inImage->isSRGB ? 1 : 0;
559 QRhiTexture *envCubeMap = rhi->newTexture(cubeTextureFormat, environmentMapSize, 1,
561 if (!envCubeMap->create()) {
562 qWarning(
"Failed to create Environment Cube Map");
565 envCubeMap->deleteLater();
569 if (!envMapRenderBuffer->create()) {
570 qWarning(
"Failed to create Environment Map Render Buffer");
573 envMapRenderBuffer->deleteLater();
578 QVarLengthArray<QRhiTextureRenderTarget *, 6> renderTargets;
585 auto renderTarget = rhi->newTextureRenderTarget(rtDesc);
587 renderTarget->setDescription(rtDesc);
589 renderPassDesc = renderTarget->newCompatibleRenderPassDescriptor();
590 renderTarget->setRenderPassDescriptor(renderPassDesc);
591 if (!renderTarget->create()) {
592 qWarning(
"Failed to build env map render target");
595 renderTarget->deleteLater();
596 renderTargets << renderTarget;
598 renderPassDesc->deleteLater();
601 QSize size(inImage->width, inImage->height);
604 qWarning(
"failed to create source env map texture");
610 const auto desc = inImage->textureFileData.isValid()
615 auto *rub = rhi->nextResourceUpdateBatch();
629 const auto &shaderCache = m_contextInterface->
shaderCache();
630 const auto &envMapShaderStages = shaderCache->getBuiltInRhiShaders().getRhiEnvironmentmapShader();
636 rub->uploadStaticBuffer(vertexBuffer,
cube);
639 int ubufElementSize = rhi->ubufAligned(128);
644 int ubufEnvMapElementSize = rhi->ubufAligned(4);
647 uBufEnvMap->deleteLater();
657 envMapSrb->deleteLater();
663 envMapPipeline->setShaderStages({
664 *envMapShaderStages->vertexStage(),
665 *envMapShaderStages->fragmentStage()
670 { 3 *
sizeof(float) }
676 envMapPipeline->setVertexInputLayout(inputLayout);
677 envMapPipeline->setShaderResourceBindings(envMapSrb);
678 envMapPipeline->setRenderPassDescriptor(renderPassDesc);
679 if (!envMapPipeline->create()) {
680 qWarning(
"failed to create source env map pipeline state");
683 envMapPipeline->deleteLater();
687 cb->debugMarkBegin(
"Environment Cubemap Generation");
698 viewMatrix.
lookAt(eye, center, up);
701 QVarLengthArray<QMatrix4x4, 6> views;
704 if (rhi->isYUpInFramebuffer()) {
714 rub->updateDynamicBuffer(uBuf,
quint8(
face) * ubufElementSize, 64, mvp.constData());
715 rub->updateDynamicBuffer(uBuf,
quint8(
face) * ubufElementSize + 64, 64, views[
quint8(
face)].constData());
716 rub->updateDynamicBuffer(uBufEnvMap,
quint8(
face) * ubufEnvMapElementSize, 4, &colorSpace);
718 cb->resourceUpdate(rub);
726 cb->setGraphicsPipeline(envMapPipeline);
727 cb->setVertexInput(0, 1, &vbufBinding);
728 cb->setViewport(
QRhiViewport(0, 0, environmentMapSize.width(), environmentMapSize.height()));
729 QVector<QPair<int, quint32>> dynamicOffset = {
733 cb->setShaderResources(envMapSrb, 2, dynamicOffset.constData());
749 rub = rhi->nextResourceUpdateBatch();
750 rub->generateMips(envCubeMap);
751 cb->resourceUpdate(rub);
755 cb->debugMarkBegin(
"Pre-filtered Environment Cubemap Generation");
759 if (!preFilteredEnvCubeMap->create())
760 qWarning(
"Failed to create Pre-filtered Environment Cube Map");
761 preFilteredEnvCubeMap->setName(rtName);
762 int mipmapCount = rhi->mipLevelsForSize(environmentMapSize);
763 mipmapCount =
qMin(mipmapCount, 6);
764 QMap<int, QSize> mipLevelSizes;
765 QMap<int, QVarLengthArray<QRhiTextureRenderTarget *, 6>> renderTargetsMap;
769 for (
int mipLevel = 0; mipLevel < mipmapCount; ++mipLevel) {
770 const QSize levelSize =
QSize(environmentMapSize.width() * std::pow(0.5, mipLevel),
771 environmentMapSize.height() * std::pow(0.5, mipLevel));
772 mipLevelSizes.insert(mipLevel, levelSize);
774 QVarLengthArray<QRhiTextureRenderTarget *, 6> renderTargets;
778 att.setLevel(mipLevel);
781 auto renderTarget = rhi->newTextureRenderTarget(rtDesc);
784 renderTarget->setDescription(rtDesc);
785 if (!renderPassDescriptorPhase2)
786 renderPassDescriptorPhase2 = renderTarget->newCompatibleRenderPassDescriptor();
787 renderTarget->setRenderPassDescriptor(renderPassDescriptorPhase2);
788 if (!renderTarget->create())
789 qWarning(
"Failed to build prefilter env map render target");
790 renderTarget->deleteLater();
791 renderTargets << renderTarget;
793 renderTargetsMap.insert(mipLevel, renderTargets);
794 renderPassDescriptorPhase2->deleteLater();
798 const auto &prefilterShaderStages = shaderCache->getBuiltInRhiShaders().getRhienvironmentmapPreFilterShader(isRGBE);
813 envMapCubeSampler =
context->sampler(samplerMipMapDesc);
827 int ubufPrefilterElementSize = rhi->ubufAligned(20);
830 uBufPrefilter->deleteLater();
839 preFilterSrb->create();
840 preFilterSrb->deleteLater();
847 prefilterPipeline->setShaderStages({
848 *prefilterShaderStages->vertexStage(),
849 *prefilterShaderStages->fragmentStage()
852 prefilterPipeline->setVertexInputLayout(inputLayout);
853 prefilterPipeline->setShaderResourceBindings(preFilterSrb);
854 prefilterPipeline->setRenderPassDescriptor(renderPassDescriptorPhase2);
855 if (!prefilterPipeline->create()) {
856 qWarning(
"failed to create pre-filter env map pipeline state");
859 prefilterPipeline->deleteLater();
863 rub = rhi->nextResourceUpdateBatch();
864 const float resolution = environmentMapSize.width();
865 const float lodBias = 0.0f;
866 const int sampleCount = 1024;
867 for (
int mipLevel = 0; mipLevel < mipmapCount; ++mipLevel) {
869 const float roughness = float(mipLevel) / float(mipmapCount - 2);
870 const int distribution = mipLevel == (mipmapCount - 1) ? 0 : 1;
871 rub->updateDynamicBuffer(uBufPrefilter, mipLevel * ubufPrefilterElementSize, 4, &roughness);
872 rub->updateDynamicBuffer(uBufPrefilter, mipLevel * ubufPrefilterElementSize + 4, 4, &resolution);
873 rub->updateDynamicBuffer(uBufPrefilter, mipLevel * ubufPrefilterElementSize + 4 + 4, 4, &lodBias);
874 rub->updateDynamicBuffer(uBufPrefilter, mipLevel * ubufPrefilterElementSize + 4 + 4 + 4, 4, &sampleCount);
875 rub->updateDynamicBuffer(uBufPrefilter, mipLevel * ubufPrefilterElementSize + 4 + 4 + 4 + 4, 4, &distribution);
878 cb->resourceUpdate(rub);
881 for (
int mipLevel = 0; mipLevel < mipmapCount; ++mipLevel) {
883 cb->beginPass(renderTargetsMap[mipLevel][
quint8(
face)],
QColor(0, 0, 0, 1), { 1.0f, 0 },
nullptr,
context->commonPassFlags());
886 cb->setGraphicsPipeline(prefilterPipeline);
887 cb->setVertexInput(0, 1, &vbufBinding);
889 QVector<QPair<int, quint32>> dynamicOffsets = {
891 { 2,
quint32(ubufPrefilterElementSize * mipLevel) }
895 cb->setShaderResources(preFilterSrb, 2, dynamicOffsets.constData());
908 outTexture->m_texture = preFilteredEnvCubeMap;
909 outTexture->m_mipmapCount = mipmapCount;
916 CreateRhiTextureFlags inFlags,
917 const QString &debugObjectName)
920 QVarLengthArray<QRhiTextureUploadEntry, 16> textureUploads;
921 int textureSampleCount = 1;
922 QRhiTexture::Flags textureFlags;
924 const bool checkTransp = inFlags.testFlag(ScanForTransparency);
925 bool hasTransp =
false;
934 texture.m_flags.setRgbe8(
true);
935 if (!inTexture->isSRGB)
936 texture.m_flags.setLinear(
true);
937 if (inMipMode ==
MipModeBsdf && (inTexture->data || inTexture->textureFileData.isValid())) {
940 if (inTexture->textureFileData.isValid() && inTexture->textureFileData.keyValueMetadata().contains(
"QT_IBL_BAKER_VERSION")) {
941 Q_ASSERT(inTexture->textureFileData.numFaces() == 6);
942 Q_ASSERT(inTexture->textureFileData.numLevels() >= 5);
948 const int faceCount = tex.
numFaces();
951 environmentCubeMap->create();
960 texture.m_texture = environmentCubeMap;
963 uploadDescription.
setEntries(textureUploads.cbegin(), textureUploads.cend());
964 auto *rub = rhi->nextResourceUpdateBatch();
965 rub->uploadTexture(environmentCubeMap, uploadDescription);
966 context->commandBuffer()->resourceUpdate(rub);
967 texture.m_mipmapCount = mipmapCount;
968 rhiCtxD->registerTexture(
texture.m_texture);
973 if (createEnvironmentMap(inTexture, &
texture, debugObjectName)) {
974 rhiCtxD->registerTexture(
texture.m_texture);
977 qWarning() <<
"Failed to create environment map";
980 }
else if (inTexture->textureFileData.isValid()) {
989 if (tex.
numFaces() == 6 && inFlags.testFlag(CubeMap))
1001 rhiFormat =
toRhiFormat(inTexture->format.format);
1006 }
else if (inFlags.testFlag(Texture3D)) {
1008 quint32 formatSize = (
quint32)inTexture->format.getSizeofFormat();
1009 quint32 size2D = inTexture->width * inTexture->height * formatSize;
1010 if (inTexture->dataSizeInBytes >= (
quint32)(size2D * inTexture->depth)) {
1011 size =
QSize(inTexture->width, inTexture->height);
1012 depth = inTexture->depth;
1013 rhiFormat =
toRhiFormat(inTexture->format.format);
1014 for (
int slice = 0; slice < inTexture->depth; ++slice) {
1019 qWarning() <<
"Texture size set larger than the data";
1023 if (!inTexture->image.isNull()) {
1024 rhiFormat =
toRhiFormat(inTexture->format.format);
1025 size = inTexture->image.size();
1026 subDesc.setImage(inTexture->image);
1029 }
else if (inTexture->data) {
1030 rhiFormat =
toRhiFormat(inTexture->format.format);
1031 size =
QSize(inTexture->width, inTexture->height);
1032 QByteArray buf(
static_cast<const char *
>(inTexture->data),
qMax(0,
int(inTexture->dataSizeInBytes)));
1033 subDesc.setData(
buf);
1035 hasTransp = inTexture->scanForTransparency();
1038 subDesc.setSourceSize(
size);
1039 if (!subDesc.data().isEmpty() || !subDesc.image().isNull())
1043 static const auto textureSizeWarning = [](
QSize requestedSize,
qsizetype maxSize) {
1044 return QStringLiteral(
"Requested texture width and height (%1x%2) exceeds the maximum allowed size (%3)!")
1045 .arg(requestedSize.width()).arg(requestedSize.height()).arg(maxSize);
1048 const auto validTexSize =
size.width() <= maxTextureSize &&
size.height() <= maxTextureSize;
1051 bool generateMipmaps =
false;
1054 generateMipmaps =
true;
1055 mipmapCount = rhi->mipLevelsForSize(
size);
1058 if (mipmapCount > 1)
1061 if (inFlags.testFlag(CubeMap))
1065 qWarning() <<
"Could not load texture";
1067 }
else if (!rhi->isTextureFormatSupported(rhiFormat)) {
1068 qWarning() <<
"Unsupported texture format";
1073 if (inFlags.testFlag(Texture3D) &&
depth > 0)
1074 tex = rhi->newTexture(rhiFormat,
size.width(),
size.height(),
depth, textureSampleCount, textureFlags);
1076 tex = rhi->newTexture(rhiFormat,
size, textureSampleCount, textureFlags);
1084 texture.m_flags.setHasTransparency(hasTransp);
1088 uploadDescription.
setEntries(textureUploads.cbegin(), textureUploads.cend());
1089 auto *rub = rhi->nextResourceUpdateBatch();
1090 rub->uploadTexture(tex, uploadDescription);
1091 if (generateMipmaps)
1092 rub->generateMips(tex);
1093 context->commandBuffer()->resourceUpdate(rub);
1095 texture.m_mipmapCount = mipmapCount;
1097 rhiCtxD->registerTexture(
texture.m_texture);
1116 return &meshBufferMutex;
1137 if (
model->hasLightmap()) {
1143 if (
model->meshPath.isNull() &&
model->geometry) {
1144 theMesh = loadRenderMesh(
model->geometry, options);
1146 if (
model->hasLightmap()) {
1150 theMesh = loadRenderMesh(
model->meshPath, options);
1160 if (
model->geometry) {
1162 }
else if (!
model->meshPath.isNull()){
1165 auto meshItr = meshMap.constFind(
model->meshPath);
1166 if (meshItr != meshMap.cend())
1167 theMesh = meshItr.value().mesh;
1171 const auto &subSets = theMesh->subsets;
1172 for (
const auto &subSet : subSets)
1173 retval.include(subSet.bounds);
1179 auto const &subsets = mesh.
subsets();
1180 for (
const auto &subset : subsets)
1181 retval.include(
QSSGBounds3(subset.bounds.min, subset.bounds.max));
1201 if (sizeofType == 2 || sizeofType == 4) {
1224 rhi.vertexBuffer = std::make_shared<QSSGRhiBuffer>(*
context.get(),
1229 rhi.vertexBuffer->buffer()->setName(debugObjectName.
toLatin1());
1230 rub->uploadStaticBuffer(rhi.vertexBuffer->buffer(), vertexBuffer.
data);
1233 rhi.indexBuffer = std::make_shared<QSSGRhiBuffer>(*
context.get(),
1239 rub->uploadStaticBuffer(rhi.indexBuffer->buffer(), indexBuffer.
data);
1244 const int numTexels = (targetBuffer.
data.
size() / arraySize) >> 4;
1245 const int texWidth =
qCeil(
qSqrt(numTexels));
1246 const QSize texSize(texWidth, texWidth);
1247 if (!rhi.targetsTexture) {
1249 rhi.targetsTexture->create();
1250 rhiCtxD->registerTexture(rhi.targetsTexture);
1251 }
else if (rhi.targetsTexture->pixelSize() != texSize
1252 || rhi.targetsTexture->arraySize() != arraySize) {
1253 rhi.targetsTexture->setPixelSize(texSize);
1254 rhi.targetsTexture->setArraySize(arraySize);
1255 rhi.targetsTexture->create();
1258 const quint32 layerSize = texWidth * texWidth * 4 * 4;
1259 for (
int arrayId = 0; arrayId < arraySize; ++arrayId) {
1262 rub->uploadTexture(rhi.targetsTexture, desc);
1265 for (
quint32 entryIdx = 0, entryEnd = targetBuffer.
entries.size(); entryIdx < entryEnd; ++entryIdx) {
1266 const char *nameStr = targetBuffer.
entries[entryIdx].name.constData();
1268 rhi.ia.targetOffsets[QSSGRhiInputAssemblerState::PositionSemantic] = entryIdx * targetBuffer.
numTargets;
1270 rhi.ia.targetOffsets[QSSGRhiInputAssemblerState::NormalSemantic] = entryIdx * targetBuffer.
numTargets;
1272 rhi.ia.targetOffsets[QSSGRhiInputAssemblerState::TexCoord0Semantic] = entryIdx * targetBuffer.
numTargets;
1274 rhi.ia.targetOffsets[QSSGRhiInputAssemblerState::TexCoord1Semantic] = entryIdx * targetBuffer.
numTargets;
1276 rhi.ia.targetOffsets[QSSGRhiInputAssemblerState::TangentSemantic] = entryIdx * targetBuffer.
numTargets;
1278 rhi.ia.targetOffsets[QSSGRhiInputAssemblerState::BinormalSemantic] = entryIdx * targetBuffer.
numTargets;
1280 rhi.ia.targetOffsets[QSSGRhiInputAssemblerState::ColorSemantic] = entryIdx * targetBuffer.
numTargets;
1283 rhi.ia.targetCount = targetBuffer.
numTargets;
1284 }
else if (rhi.targetsTexture) {
1285 rhiCtxD->releaseTexture(rhi.targetsTexture);
1286 rhi.targetsTexture =
nullptr;
1287 rhi.ia.targetOffsets = { UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX,
1288 UINT8_MAX, UINT8_MAX, UINT8_MAX };
1289 rhi.ia.targetCount = 0;
1292 QVector<QSSGRenderVertexBufferEntry> entryBuffer;
1293 entryBuffer.resize(vertexBuffer.
entries.size());
1294 for (
quint32 entryIdx = 0, entryEnd = vertexBuffer.
entries.size(); entryIdx < entryEnd; ++entryIdx)
1295 entryBuffer[entryIdx] = vertexBuffer.
entries[entryIdx].toRenderVertexBufferEntry();
1297 QVarLengthArray<QRhiVertexInputAttribute, 4> inputAttrs;
1298 for (
quint32 entryIdx = 0, entryEnd = entryBuffer.size(); entryIdx < entryEnd; ++entryIdx) {
1300 const int binding = 0;
1303 const int offset = int(vbe.m_firstItemOffset);
1306 const char *nameStr = vbe.m_name.constData();
1308 rhi.ia.inputs << QSSGRhiInputAssemblerState::PositionSemantic;
1310 rhi.ia.inputs << QSSGRhiInputAssemblerState::NormalSemantic;
1312 rhi.ia.inputs << QSSGRhiInputAssemblerState::TexCoord0Semantic;
1314 rhi.ia.inputs << QSSGRhiInputAssemblerState::TexCoord1Semantic;
1316 rhi.ia.inputs << QSSGRhiInputAssemblerState::TexCoordLightmapSemantic;
1318 rhi.ia.inputs << QSSGRhiInputAssemblerState::TangentSemantic;
1320 rhi.ia.inputs << QSSGRhiInputAssemblerState::BinormalSemantic;
1322 rhi.ia.inputs << QSSGRhiInputAssemblerState::ColorSemantic;
1324 rhi.ia.inputs << QSSGRhiInputAssemblerState::JointSemantic;
1326 rhi.ia.inputs << QSSGRhiInputAssemblerState::WeightSemantic;
1328 qWarning(
"Unknown vertex input %s in mesh", nameStr);
1333 inputAttrs.append(inputAttr);
1336 rhi.ia.inputLayout.setAttributes(inputAttrs.cbegin(), inputAttrs.cend());
1337 rhi.ia.inputLayout.setBindings({ vertexBuffer.
stride });
1341 qWarning(
"Mesh topology is TriangleFan but this is not supported with the active graphics API. Rendering will be incorrect.");
1343 QVector<QSSGMesh::Mesh::Subset> meshSubsets = mesh.
subsets();
1344 for (
quint32 subsetIdx = 0, subsetEnd = meshSubsets.size(); subsetIdx < subsetEnd; ++subsetIdx) {
1354 if (rhi.vertexBuffer) {
1355 subset.
rhi.vertexBuffer = rhi.vertexBuffer;
1356 subset.
rhi.ia = rhi.ia;
1358 if (rhi.indexBuffer)
1359 subset.
rhi.indexBuffer = rhi.indexBuffer;
1360 if (rhi.targetsTexture)
1361 subset.
rhi.targetsTexture = rhi.targetsTexture;
1363 newMesh->subsets.push_back(subset);
1366 if (!meshSubsets.isEmpty())
1367 newMesh->lightmapSizeHint = meshSubsets.first().lightmapSizeHint;
1375 const auto meshItr = customMeshMap.constFind(geometry);
1376 if (meshItr != customMeshMap.cend()) {
1378 qDebug() <<
"- releaseGeometry: " << geometry << currentLayer;
1383 rhiCtxD->releaseMesh(meshItr.value().mesh);
1384 customMeshMap.erase(meshItr);
1392 QVarLengthArray<CustomImageCacheKey, 4>
keys;
1393 for (
auto it = customTextureMap.cbegin(),
end = customTextureMap.cend();
it !=
end; ++
it) {
1394 if (
it.key().data ==
data)
1403 const auto textureDataItr = customTextureMap.constFind(
key);
1404 if (textureDataItr != customTextureMap.cend()) {
1405 auto rhiTexture = textureDataItr.value().renderImageTexture.m_texture;
1408 qDebug() <<
"- releaseTextureData: " << rhiTexture << currentLayer;
1413 rhiCtxD->releaseTexture(rhiTexture);
1418 customTextureMap.erase(textureDataItr);
1424 renderExtensionTexture.remove(&rext);
1427void QSSGBufferManager::releaseMesh(
const QSSGRenderPath &inSourcePath)
1430 const auto meshItr = meshMap.constFind(inSourcePath);
1431 if (meshItr != meshMap.cend()) {
1433 qDebug() <<
"- releaseMesh: " << inSourcePath.path() << currentLayer;
1438 rhiCtxD->releaseMesh(meshItr.value().mesh);
1439 meshMap.erase(meshItr);
1445void QSSGBufferManager::releaseImage(
const ImageCacheKey &
key)
1447 const auto imageItr = imageMap.constFind(
key);
1448 if (imageItr != imageMap.cend()) {
1449 auto rhiTexture = imageItr.value().renderImageTexture.m_texture;
1452 qDebug() <<
"- releaseTexture: " <<
key.path.path() << currentLayer;
1457 rhiCtxD->releaseTexture(rhiTexture);
1461 imageMap.erase(imageItr);
1472 if (frameId == frameCleanupIndex)
1475 auto isUnused = [] (
const QHash<QSSGRenderLayer*, uint32_t> &usages) ->
bool {
1476 for (
const auto &
value : std::as_const(usages))
1485 auto meshIterator = meshMap.cbegin();
1486 while (meshIterator != meshMap.cend()) {
1487 if (isUnused(meshIterator.value().usageCounts)) {
1489 qDebug() <<
"- releaseGeometry: " << meshIterator.key().path() << currentLayer;
1491 rhiCtxD->releaseMesh(meshIterator.value().mesh);
1492 meshIterator = meshMap.erase(meshIterator);
1499 auto customMeshIterator = customMeshMap.cbegin();
1500 while (customMeshIterator != customMeshMap.cend()) {
1501 if (isUnused(customMeshIterator.value().usageCounts)) {
1503 qDebug() <<
"- releaseGeometry: " << customMeshIterator.key() << currentLayer;
1505 rhiCtxD->releaseMesh(customMeshIterator.value().mesh);
1506 customMeshIterator = customMeshMap.erase(customMeshIterator);
1508 ++customMeshIterator;
1514 auto sgIterator = qsgImageMap.cbegin();
1515 while (sgIterator != qsgImageMap.cend()) {
1516 if (isUnused(sgIterator.value().usageCounts)) {
1520 sgIterator = qsgImageMap.erase(sgIterator);
1527 auto imageKeyIterator = imageMap.cbegin();
1528 while (imageKeyIterator != imageMap.cend()) {
1529 if (isUnused(imageKeyIterator.value().usageCounts)) {
1530 auto rhiTexture = imageKeyIterator.value().renderImageTexture.m_texture;
1533 qDebug() <<
"- releaseTexture: " << imageKeyIterator.key().path.path() << currentLayer;
1535 rhiCtxD->releaseTexture(rhiTexture);
1537 imageKeyIterator = imageMap.erase(imageKeyIterator);
1544 auto textureDataIterator = customTextureMap.cbegin();
1545 while (textureDataIterator != customTextureMap.cend()) {
1546 if (isUnused(textureDataIterator.value().usageCounts)) {
1547 auto rhiTexture = textureDataIterator.value().renderImageTexture.m_texture;
1550 qDebug() <<
"- releaseTextureData: " << rhiTexture << currentLayer;
1552 rhiCtxD->releaseTexture(rhiTexture);
1554 textureDataIterator = customTextureMap.erase(textureDataIterator);
1556 ++textureDataIterator;
1561 auto renderExtensionTextureKeyIterator = renderExtensionTexture.cbegin();
1562 while (renderExtensionTextureKeyIterator != renderExtensionTexture.cend()) {
1563 if (isUnused(renderExtensionTextureKeyIterator.value().usageCounts)) {
1564 auto rhiTexture = renderExtensionTextureKeyIterator.value().renderImageTexture.m_texture;
1567 qDebug() <<
"- releaseTexture: " << (*renderExtensionTextureKeyIterator).renderImageTexture.m_texture << currentLayer;
1571 renderExtensionTextureKeyIterator = renderExtensionTexture.erase(renderExtensionTextureKeyIterator);
1573 ++renderExtensionTextureKeyIterator;
1578 frameCleanupIndex = frameId;
1580 qDebug() <<
"QSSGBufferManager::cleanupUnreferencedBuffers()" <<
this <<
"frame:" << frameCleanupIndex << currentLayer;
1581 qDebug() <<
"Textures(by path): " << imageMap.count();
1582 qDebug() <<
"Textures(custom): " << customTextureMap.count();
1583 qDebug() <<
"Textures(Extension)" << renderExtensionTexture.count();
1584 qDebug() <<
"Textures(qsg): " << qsgImageMap.count();
1585 qDebug() <<
"Geometry(by path): " << meshMap.count();
1586 qDebug() <<
"Geometry(custom): " << customMeshMap.count();
1592 currentLayer =
layer;
1593 if (frameResetIndex == frameId)
1605 for (
auto &
imageData : customTextureMap)
1608 for (
auto &meshData : meshMap)
1609 meshData.usageCounts[
layer] = 0;
1612 for (
auto &meshData : customMeshMap)
1613 meshData.usageCounts[
layer] = 0;
1618 for (
auto &retData : renderExtensionTexture) {
1619 const bool hasTexture = (retData.renderImageTexture.m_texture !=
nullptr);
1620 retData.usageCounts[
layer] = uint32_t(hasTexture) * 1;
1623 frameResetIndex = frameId;
1628 auto it = g_assetMeshMap->
find(assetId);
1629 if (
it != g_assetMeshMap->
end())
1632 g_assetMeshMap->
insert(assetId, { meshData, 1 });
1637 auto it = g_assetMeshMap->
find(assetId);
1638 if (
it != g_assetMeshMap->
end() && (--
it->ref == 0))
1639 g_assetMeshMap->erase(AssetMeshMap::const_iterator(
it));
1644 if (inMeshPath.isNull())
1648 auto meshItr = meshMap.find(inMeshPath);
1649 if (meshItr != meshMap.cend()) {
1651 meshItr.value().usageCounts[currentLayer]++;
1652 return meshItr.value().mesh;
1656 auto *mesh = meshItr->mesh;
1657 meshMap.erase(meshItr);
1658 meshMap.insert(
QSSGRenderPath(inMeshPath.path() + u
"@reaped"), { mesh, {{currentLayer, 0}}, 0, {} });
1679 resultSourcePath = inMeshPath.path();
1680 result = loadMeshData(inMeshPath);
1686 stats.meshDataSize);
1690 qDebug() <<
"+ uploadGeometry: " << inMeshPath.path() << currentLayer;
1700 meshMap.insert(inMeshPath, {
ret, {{currentLayer, 1}}, 0, options });
1702 rhiCtxD->registerMesh(
ret);
1703 increaseMemoryStat(
ret);
1705 stats.meshDataSize, inMeshPath.path().toUtf8());
1713 auto meshIterator = customMeshMap.find(geometry);
1714 if (meshIterator == customMeshMap.end()) {
1715 meshIterator = customMeshMap.insert(geometry, MeshData());
1716 }
else if (geometry->
generationId() != meshIterator->generationId || !options.
isCompatible(meshIterator->options)) {
1719 meshIterator = customMeshMap.insert(geometry, MeshData());
1722 meshIterator.value().usageCounts[currentLayer]++;
1723 return meshIterator.value().mesh;
1735 qDebug() <<
"+ uploadGeometry: " << geometry << currentLayer;
1742 meshIterator->mesh = createRenderMesh(mesh, geometry->
debugObjectName);
1743 meshIterator->usageCounts[currentLayer] = 1;
1745 meshIterator->options = options;
1746 rhiCtxD->registerMesh(meshIterator->mesh);
1756 return meshIterator->mesh;
1767 return meshBVHBuilder.buildTree();
1776 if (geometry->
primitiveType() != QSSGMesh::Mesh::DrawMode::Triangles)
1780 bool hasIndexBuffer =
false;
1797 hasIndexBuffer =
true;
1798 if (
attribute.componentType == QSSGMesh::Mesh::ComponentType::Int16)
1800 else if (
attribute.componentType == QSSGMesh::Mesh::ComponentType::Int32)
1813 return meshBVHBuilder.buildTree();
1821 if (inMeshPath.path().startsWith(QChar::fromLatin1(
'#')))
1822 result = loadPrimitive(inMeshPath.path());
1825 if (!
result.isValid() && inMeshPath.path().startsWith(u
'!')) {
1828 const auto ait = g_assetMeshMap->constFind(assetId);
1829 if (ait != g_assetMeshMap->constEnd()) {
1830 const auto &meshes = ait->meshes;
1831 if (idx < meshes.size())
1832 result = ait->meshes.at(idx);
1841 QString pathBuilder = inMeshPath.path();
1842 int poundIndex = pathBuilder.
lastIndexOf(QChar::fromLatin1(
'#'));
1844 if (poundIndex != -1) {
1846 pathBuilder = pathBuilder.left(poundIndex);
1848 if (!pathBuilder.isEmpty()) {
1879 flags.setLinear(!isSRGB);
1881 flags.setRgbe8(isRGBA8);
1882 const quint32 usageCount = 1 ;
1885 renderExtensionTexture.insert(&extensions, {});
1889void QSSGBufferManager::clear()
1893 if (meshBufferUpdates) {
1895 meshBufferUpdates =
nullptr;
1901 auto meshMapCopy = meshMap;
1902 meshMapCopy.detach();
1903 for (
auto iter = meshMapCopy.begin(),
end = meshMapCopy.end();
iter !=
end; ++
iter) {
1907 qDebug() <<
"- releaseGeometry: " <<
iter.key().path() << currentLayer;
1909 rhiCtxD->releaseMesh(theMesh);
1915 auto customMeshMapCopy = customMeshMap;
1916 customMeshMapCopy.detach();
1917 for (
auto iter = customMeshMapCopy.begin(),
end = customMeshMapCopy.end();
iter !=
end; ++
iter) {
1921 qDebug() <<
"- releaseGeometry: " <<
iter.key() << currentLayer;
1923 rhiCtxD->releaseMesh(theMesh);
1926 customMeshMap.clear();
1930 for (
auto it = imageMap.constBegin(),
end = imageMap.constEnd();
it !=
end; ++
it)
1931 releaseImage(
it.key());
1936 for (
auto it = customTextureMap.cbegin(),
end = customTextureMap.cend();
it !=
end; ++
it)
1939 customTextureMap.clear();
1943 qsgImageMap.clear();
1948 if (!meshBufferUpdates)
1949 meshBufferUpdates = m_contextInterface->
rhiContext()->rhi()->nextResourceUpdateBatch();
1950 return meshBufferUpdates;
1955 if (meshBufferUpdates) {
1956 m_contextInterface->
rhiContext()->commandBuffer()->resourceUpdate(meshBufferUpdates);
1957 meshBufferUpdates =
nullptr;
1963 for (
auto &mesh : std::as_const(loader->
meshes))
1964 loadRenderMesh(mesh, {});
1966 for (
auto customMesh : std::as_const(loader->
geometries))
2007 static const quint64 pixelSizes[] = {0, 4, 4, 1, 2, 2, 4, 1, 2, 4, 2, 4, 4, 2, 4, 4, 4};
2019 static const quint64 blockSizes[] = {8, 16, 16, 8, 16, 16, 16, 8, 8, 16};
2021 "QRhiTexture format constant value missmatch.");
IOBluetoothDevice * device
QByteArray toByteArray() const
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
The QColor class provides colors based on RGB, HSV or CMYK values.
bool exists() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
constexpr bool testFlag(Enum flag) const noexcept
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
void lookAt(const QVector3D &eye, const QVector3D ¢er, const QVector3D &up)
Multiplies this matrix by a viewing matrix derived from an eye point.
void perspective(float verticalAngle, float aspectRatio, float nearPlane, float farPlane)
Multiplies this matrix by another that applies a perspective projection.
virtual bool create()=0
Creates the corresponding native graphics resources.
QPair< QRhiBuffer *, quint32 > VertexInput
Synonym for QPair<QRhiBuffer *, quint32>.
IndexFormat
Specifies the index data type.
void setCullMode(CullMode mode)
Sets the specified face culling mode.
void setName(const QByteArray &name)
Sets a name for the object.
void deleteLater()
When called without a frame being recorded, this function is equivalent to deleting the object.
static QRhiShaderResourceBinding sampledTexture(int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
static QRhiShaderResourceBinding uniformBufferWithDynamicOffset(int binding, StageFlags stage, QRhiBuffer *buf, quint32 size)
void setBindings(std::initializer_list< QRhiShaderResourceBinding > list)
Sets the list of bindings.
void setColorAttachments(std::initializer_list< QRhiColorAttachment > list)
Sets the list of color attachments.
void setSourceSize(const QSize &size)
Sets the source size in pixels.
void setEntries(std::initializer_list< QRhiTextureUploadEntry > list)
Sets the list of entries.
virtual bool create()=0
Creates the corresponding native graphics resources.
Format
Specifies the texture format.
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
static int mipLevelsForSize(const QSize &size)
QRhiResourceUpdateBatch * nextResourceUpdateBatch()
static bool formatIsOpaque(quint32 glTextureFormat)
static const char * displayName(QSSGRenderTextureCubeFace face)
static size_t getSizeOfType(QSSGRenderComponentType type)
Class representing 3D range or axis aligned bounding box.
void releaseCachedResources()
void setRenderContextInterface(QSSGRenderContextInterface *ctx)
QSSGRenderImageTexture loadSkinmap(QSSGRenderTextureData *skin)
static std::unique_ptr< QSSGMeshBVH > loadMeshBVH(const QSSGRenderPath &inSourcePath)
void releaseGeometry(QSSGRenderGeometry *geometry)
QSSGBounds3 getModelBounds(const QSSGRenderModel *model) const
static QRhiTexture::Format toRhiFormat(const QSSGRenderTextureFormat format)
void increaseMemoryStat(QRhiTexture *texture)
void releaseResourcesForLayer(QSSGRenderLayer *layer)
void cleanupUnreferencedBuffers(quint32 frameId, QSSGRenderLayer *layer)
QSSGRenderMesh * getMeshForPicking(const QSSGRenderModel &model) const
static QSSGMesh::Mesh loadMeshData(const QSSGRenderPath &inSourcePath)
QSSGRenderImageTexture loadRenderImage(const QSSGRenderImage *image, MipMode inMipMode=MipModeFollowRenderImage, LoadRenderImageFlags flags=LoadWithFlippedY)
void commitBufferResourceUpdates()
void registerExtensionResult(const QSSGRenderExtension &extensions, QRhiTexture *texture)
@ MipModeFollowRenderImage
static void unregisterMeshData(const QString &assetId)
static QString primitivePath(const QString &primitive)
void releaseTextureData(const QSSGRenderTextureData *data)
void releaseExtensionResult(const QSSGRenderExtension &rext)
QSSGRenderMesh * loadMesh(const QSSGRenderModel *model)
QSSGRenderImageTexture loadLightmap(const QSSGRenderModel &model)
QMutex * meshUpdateMutex()
static void registerMeshData(const QString &assetId, const QVector< QSSGMesh::Mesh > &meshData)
void decreaseMemoryStat(QRhiTexture *texture)
void resetUsageCounters(quint32 frameId, QSSGRenderLayer *layer)
void processResourceLoader(const QSSGRenderResourceLoader *loader)
static QString lightmapAssetPathForLoad(const QSSGRenderModel &model, LightmapAsset asset)
bool createLightmapUVChannel(uint lightmapBaseResolution)
static Mesh fromRuntimeData(const RuntimeMeshData &data, QString *error)
static Mesh loadMesh(QIODevice *device, quint32 id=0)
VertexBuffer vertexBuffer() const
IndexBuffer indexBuffer() const
QVector< Subset > subsets() const
TargetBuffer targetBuffer() const
DrawMode drawMode() const
const std::unique_ptr< QSSGRhiContext > & rhiContext() const
const std::unique_ptr< QSSGShaderCache > & shaderCache() const
Attribute attribute(int idx) const
const QSSGMesh::RuntimeMeshData & meshData() const
uint32_t generationId() const
int attributeCount() const
const QByteArray & indexBuffer() const
const QByteArray & vertexBuffer() const
QSSGMesh::Mesh::DrawMode primitiveType() const
static QSSGRhiContextPrivate * get(QSSGRhiContext *q)
static QSSGRhiContextStats & get(QSSGRhiContext &rhiCtx)
iterator find(const T &value)
iterator insert(const T &value)
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QByteArray toLatin1() const &
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QString fromUtf16(const char16_t *, qsizetype size=-1)
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray toUtf8() const &
quint32 glInternalFormat() const
QByteArrayView getDataView(int level=0, int face=0) const
The QVector3D class represents a vector or vertex in 3D space.
list append(new Employee("Blackpool", "Stephen"))
QSet< QString >::iterator it
QRhiVertexInputAttribute::Format toVertexInputFormat(QSSGRenderComponentType compType, quint32 numComps)
QRhiGraphicsPipeline::Topology toTopology(QSSGRenderDrawMode drawMode)
Combined button and popup list for selecting options.
QTextStream & center(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignCenter) on stream and returns stream.
#define Q_STATIC_ASSERT_X(Condition, Message)
#define QByteArrayLiteral(str)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter * iter
DBusConnection const char DBusError * error
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
EGLOutputLayerEXT EGLint attribute
qfloat16 qSqrt(qfloat16 f)
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qCCritical(category,...)
#define qCWarning(category,...)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
GLsizei const GLfloat * v
[13]
GLint GLenum GLsizei GLsizei GLsizei depth
GLenum GLuint GLint level
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLsizei const GLchar ** strings
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum GLuint GLintptr offset
GLint GLsizei GLsizei GLenum format
GLsizei GLsizei GLchar * source
GLsizei const GLchar *const * path
QT_BEGIN_NAMESPACE constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
#define Q_QUICK3D_PROFILE_END_WITH_PAYLOAD(Type, Payload)
#define Q_QUICK3D_PROFILE_START(Type)
#define Q_QUICK3D_PROFILE_END_WITH_ID(Type, Payload, POID)
#define QSSG_RENDERPASS_NAME(passName, level, face)
#define Q_QUICK3D_PROFILE_END_WITH_STRING(Type, Payload, Str)
#define QSSG_ASSERT_X(cond, msg, action)
#define QSSG_ASSERT(cond, action)
static constexpr QSSGRenderTextureCubeFace QSSGRenderTextureCubeFaces[]
static constexpr QSize sizeForMipLevel(int mipLevel, const QSize &baseLevelSize)
static quint64 textureMemorySize(QRhiTexture *texture)
static MeshIdxNamePair splitRuntimeMeshPath(const QSSGRenderPath &rpath)
static const float cube[]
static const PrimitiveEntry primitives[nPrimitives]
static quint64 bufferMemorySize(const QSSGRhiBufferPtr &buffer)
static const int nPrimitives
QHash< QString, MeshStorageRef > AssetMeshMap
struct MeshStorageRef Q_TRACE_POINT
static const char * primitivesDirectory
QPair< qsizetype, QString > MeshIdxNamePair
#define QSSGRHICTX_STAT(ctx, f)
std::shared_ptr< QSSGRhiBuffer > QSSGRhiBufferPtr
QSSGRhiInputAssemblerStatePrivate::InputAssemblerState QSSGRhiInputAssemblerState
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define qPrintable(string)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
#define Q_TRACE_SCOPE(x,...)
unsigned long long quint64
QSqlQueryModel * model
[16]
myFilter draw(painter, QPoint(0, 0), originalPixmap)
QVector< QSSGMesh::Mesh > meshes
static QImageData * get(QImage &img) noexcept
static constexpr bool enabled(Level)
static QSSGLoadedTexture * load(const QString &inPath, const QSSGRenderTextureFormat &inFormat, bool inFlipY=true)
static QSSGLoadedTexture * loadTextureData(QSSGRenderTextureData *textureData)
bool isCompatible(const QSSGMeshProcessingOptions &other) const
uint lightmapBaseResolution
static const char * getLightmapUVAttrName()
static const char * getNormalAttrName()
static const char * getUV1AttrName()
static const char * getTexBinormalAttrName()
static const char * getPositionAttrName()
static const char * getTexTanAttrName()
static const char * getColorAttrName()
static const char * getJointAttrName()
static const char * getUV0AttrName()
static const char * getWeightAttrName()
ComponentType componentType
QVector< VertexBufferEntry > entries
QVector< VertexBufferEntry > entries
QByteArray m_vertexBuffer
QVector< QSSGRenderSubset > subsets
QVector< QSSGRenderGraphObject * > geometries
QVector< QSSGRenderGraphObject * > textures
QVector< QSSGRenderPath > meshes
struct QSSGRenderSubset::@757 rhi
\variable QSSGRhiGraphicsPipelineState::depthFunc