Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qssgrhicustommaterialsystem.cpp
Go to the documentation of this file.
1// Copyright (C) 2008-2012 NVIDIA Corporation.
2// Copyright (C) 2019 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4
6
7#include <QtQuick3DUtils/private/qssgutils_p.h>
8
9#include <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h>
10#include <QtQuick3DRuntimeRender/private/qssgrenderbuffermanager_p.h>
11#include <QtQuick3DRuntimeRender/private/qssgrendermesh_p.h>
12#include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h>
13#include <QtQuick3DRuntimeRender/private/qssgrenderlight_p.h>
14#include <QtQuick3DRuntimeRender/private/qssgrenderlayer_p.h>
15#include <QtQuick3DRuntimeRender/private/qssgrenderableimage_p.h>
16#include <QtQuick3DRuntimeRender/private/qssgvertexpipelineimpl_p.h>
17#include <QtQuick3DRuntimeRender/private/qssglayerrenderdata_p.h>
18#include <QtQuick3DRuntimeRender/private/qssgrendermodel_p.h>
19#include <QtQuick3DRuntimeRender/private/qssgruntimerenderlogging_p.h>
20#include <QtQuick3DRuntimeRender/private/qssgrhiparticles_p.h>
21#include <qtquick3d_tracepoints_p.h>
22
23#include <QtCore/qbitarray.h>
24
26
27Q_TRACE_POINT(qtquick3d, QSSG_generateShader_entry)
28Q_TRACE_POINT(qtquick3d, QSSG_generateShader_exit)
29
31
33{
34}
35
37 const QSSGRenderSubset &,
38 QSSGRenderCustomMaterial &inMaterial)
39{
40 return inMaterial.isDirty();
41}
42
44{
45 context = inContext;
46}
47
49{
50 shaderMap.clear();
51}
52
54 const QSSGRenderCustomMaterial &material,
55 QSSGSubsetRenderable &renderable,
56 const QSSGShaderFeatures &featureSet)
57{
59 timer.start();
60
61 QSSGRhiShaderPipelinePtr shaderPipeline;
62
63 // This just references inFeatureSet and inRenderable.shaderDescription -
64 // cheap to construct and is good enough for the find(). This is the first
65 // level, fast lookup. (equivalent to what
66 // QSSGRenderer::getShaderPipelineForDefaultMaterial does for the
67 // default/principled material)
69 featureSet,
70 renderable.shaderDescription);
71 auto it = shaderMap.find(skey);
72 if (it == shaderMap.end()) {
73 // NB this key calculation must replicate exactly what the generator does in generateMaterialRhiShader()
74 QByteArray shaderString = material.m_shaderPathKey;
76 matKey.toString(shaderString, context->renderer()->defaultMaterialShaderKeyProperties());
77
78 // Try the persistent (disk-based) cache.
80 shaderPipeline = context->shaderCache()->tryNewPipelineFromPersistentCache(qsbcKey, material.m_shaderPathKey, featureSet);
81
82 if (!shaderPipeline) {
83 // Have to generate the shaders and send it all through the shader conditioning pipeline.
84 Q_TRACE_SCOPE(QSSG_generateShader);
85 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DGenerateShader);
86 QSSGMaterialVertexPipeline vertexPipeline(*context->shaderProgramGenerator(),
87 context->renderer()->defaultMaterialShaderKeyProperties(),
88 material.adapter);
89
91 vertexPipeline,
92 renderable.shaderDescription,
93 context->renderer()->defaultMaterialShaderKeyProperties(),
94 featureSet,
95 renderable.material,
96 renderable.lights,
97 renderable.firstImage,
98 *context->shaderLibraryManager(),
99 *context->shaderCache());
100 Q_QUICK3D_PROFILE_END_WITH_ID(QQuick3DProfiler::Quick3DGenerateShader, 0, material.profilingId);
101 }
102
103 // make skey useable as a key for the QHash (makes copies of materialKey and featureSet, instead of just referencing)
104 skey.detach();
105 // insert it no matter what, no point in trying over and over again
106 shaderMap.insert(skey, shaderPipeline);
107 } else {
108 shaderPipeline = it.value();
109 }
110
111 if (shaderPipeline) {
112 ps->shaderPipeline = shaderPipeline.get();
113 shaderPipeline->resetExtraTextures();
114 }
115
116 context->rhiContext()->stats().registerMaterialShaderGenerationTime(timer.elapsed());
117
118 return shaderPipeline;
119}
120
122 QSSGRhiContext *rhiCtx,
123 const QSSGLayerRenderData &inData,
124 char *ubufData,
126 const QSSGRenderCustomMaterial &material,
127 QSSGSubsetRenderable &renderable,
129 const QVector2D *depthAdjust,
130 const QMatrix4x4 *alteredModelViewProjection)
131{
132 const QMatrix4x4 &mvp(alteredModelViewProjection ? *alteredModelViewProjection
133 : renderable.modelContext.modelViewProjection);
134
135 const QMatrix4x4 clipSpaceCorrMatrix = rhiCtx->rhi()->clipSpaceCorrMatrix();
136 QRhiTexture *lightmapTexture = inData.getLightmapTexture(renderable.modelContext);
137
138 const auto &modelNode = renderable.modelContext.model;
139 const QMatrix4x4 &localInstanceTransform(modelNode.localInstanceTransform);
140 const QMatrix4x4 &globalInstanceTransform(modelNode.globalInstanceTransform);
141
142
143 const QMatrix4x4 &modelMatrix(modelNode.usesBoneTexture() ? QMatrix4x4() : renderable.globalTransform);
144
146 shaderPipeline,
147 ubufData,
148 ps,
149 material,
150 renderable.shaderDescription,
151 context->renderer()->defaultMaterialShaderKeyProperties(),
152 camera,
153 mvp,
154 renderable.modelContext.normalMatrix,
155 modelMatrix,
156 clipSpaceCorrMatrix,
157 localInstanceTransform,
158 globalInstanceTransform,
159 toDataView(modelNode.morphWeights),
160 renderable.firstImage,
161 renderable.opacity,
163 renderable.lights,
164 renderable.reflectionProbe,
165 true,
167 depthAdjust,
168 lightmapTexture);
169}
170
171static const QRhiShaderResourceBinding::StageFlags CUSTOM_MATERIAL_VISIBILITY_ALL =
173
175 QSSGPassKey passKey,
176 QSSGSubsetRenderable &renderable,
177 const QSSGShaderFeatures &featureSet,
178 const QSSGRenderCustomMaterial &material,
179 const QSSGLayerRenderData &layerData,
180 QRhiRenderPassDescriptor *renderPassDescriptor,
181 int samples,
183 int cubeFace,
184 QMatrix4x4 *modelViewProjection,
186{
187 QSSGRhiContext *rhiCtx = context->rhiContext().get();
188
189 QRhiGraphicsPipeline::TargetBlend blend; // no blending by default
191 blend.enable = true;
192 blend.srcColor = material.m_srcBlend;
193 blend.srcAlpha = material.m_srcBlend;
194 blend.dstColor = material.m_dstBlend;
195 blend.dstAlpha = material.m_dstBlend;
196 }
197
198 const QSSGCullFaceMode cullMode = material.m_cullMode;
199
200 const bool blendParticles = renderable.renderer->defaultMaterialShaderKeyProperties().m_blendParticles.getValue(renderable.shaderDescription);
201
202 const auto &shaderPipeline = shadersForCustomMaterial(ps, material, renderable, featureSet);
203
204 if (shaderPipeline) {
206 const auto &modelNode = renderable.modelContext.model;
207
208 QSSGRhiDrawCallData &dcd(cubeFace < 0 ? rhiCtx->drawCallData({ passKey,
209 &modelNode,
210 &material,
211 0,
213 : rhiCtx->drawCallData({ passKey,
214 &modelNode,
215 entry, cubeFace + int(renderable.subset.offset << 3),
217
218 shaderPipeline->ensureCombinedMainLightsUniformBuffer(&dcd.ubuf);
220 if (!camera)
221 updateUniformsForCustomMaterial(*shaderPipeline, rhiCtx, layerData, ubufData, ps, material, renderable, *layerData.camera, nullptr, nullptr);
222 else
223 updateUniformsForCustomMaterial(*shaderPipeline, rhiCtx, layerData, ubufData, ps, material, renderable, *camera, nullptr, modelViewProjection);
224 if (blendParticles)
225 QSSGParticleRenderer::updateUniformsForParticleModel(*shaderPipeline, ubufData, &renderable.modelContext.model, renderable.subset.offset);
227
228 if (blendParticles)
229 QSSGParticleRenderer::prepareParticlesForModel(*shaderPipeline, rhiCtx, bindings, &renderable.modelContext.model);
230 bool instancing = false;
231 if (!camera)
232 instancing = renderable.prepareInstancing(rhiCtx, layerData.cameraData->direction, layerData.cameraData->position, renderable.instancingLodMin, renderable.instancingLodMax);
233 else
234 instancing = renderable.prepareInstancing(rhiCtx, camera->getScalingCorrectDirection(), camera->getGlobalPos(), renderable.instancingLodMin, renderable.instancingLodMax);
235
236 ps->samples = samples;
237
239
240 ps->targetBlend = blend;
241
242 ps->ia = renderable.subset.rhi.ia;
243
244 //### Copied code from default materials
245 int instanceBufferBinding = 0;
246 if (instancing) {
247 // Need to setup new bindings for instanced buffers
248 const quint32 stride = renderable.modelContext.model.instanceTable->stride();
250 std::copy(ps->ia.inputLayout.cbeginBindings(),
252 std::back_inserter(bindings));
254 instanceBufferBinding = bindings.size() - 1;
255 ps->ia.inputLayout.setBindings(bindings.cbegin(), bindings.cend());
256 }
257
258 ps->ia.bakeVertexInputLocations(*shaderPipeline, instanceBufferBinding);
259
260 QRhiResourceUpdateBatch *resourceUpdates = rhiCtx->rhi()->nextResourceUpdateBatch();
261 QRhiTexture *dummyTexture = rhiCtx->dummyTexture({}, resourceUpdates);
262 QRhiTexture *dummyCubeTexture = rhiCtx->dummyTexture(QRhiTexture::CubeMap, resourceUpdates);
263 rhiCtx->commandBuffer()->resourceUpdate(resourceUpdates);
264
265 bindings.addUniformBuffer(0, CUSTOM_MATERIAL_VISIBILITY_ALL, dcd.ubuf, 0, shaderPipeline->ub0Size());
267 shaderPipeline->ub0LightDataOffset(),
268 shaderPipeline->ub0LightDataSize());
269
271 shaderPipeline->fragmentStage()->shader().description().combinedImageSamplers();
272 for (const QShaderDescription::InOutVariable &var : shaderPipeline->vertexStage()->shader().description().combinedImageSamplers()) {
273 auto it = std::find_if(samplerVars.cbegin(), samplerVars.cend(),
274 [&var](const QShaderDescription::InOutVariable &v) { return var.binding == v.binding; });
275 if (it == samplerVars.cend())
276 samplerVars.append(var);
277 }
278
279 int maxSamplerBinding = -1;
280 for (const QShaderDescription::InOutVariable &var : samplerVars)
281 maxSamplerBinding = qMax(maxSamplerBinding, var.binding);
282
283 // Will need to set unused image-samplers to something dummy
284 // because the shader code contains all custom property textures,
285 // and not providing a binding for all of them is invalid with some
286 // graphics APIs (and will need a real texture because setting a
287 // null handle or similar is not permitted with some of them so the
288 // srb does not accept null QRhiTextures either; but first let's
289 // figure out what bindings are unused in this frame)
290 QBitArray samplerBindingsSpecified(maxSamplerBinding + 1);
291
292 if (blendParticles)
293 samplerBindingsSpecified.setBit(shaderPipeline->bindingForTexture("qt_particleTexture"));
294
295 // Skinning
296 if (QRhiTexture *boneTexture = layerData.getBonemapTexture(renderable.modelContext)) {
297 int binding = shaderPipeline->bindingForTexture("qt_boneTexture");
298 if (binding >= 0) {
299 QRhiSampler *boneSampler = rhiCtx->sampler({ QRhiSampler::Nearest,
305 });
306 bindings.addTexture(binding,
308 boneTexture,
309 boneSampler);
310 samplerBindingsSpecified.setBit(binding);
311 }
312 }
313
314 // Morphing
315 auto *targetsTexture = renderable.subset.rhi.targetsTexture;
316 if (targetsTexture) {
317 int binding = shaderPipeline->bindingForTexture("qt_morphTargetTexture");
318 if (binding >= 0) {
319 QRhiSampler *targetsSampler = rhiCtx->sampler({ QRhiSampler::Nearest,
325 });
326 bindings.addTexture(binding, QRhiShaderResourceBinding::VertexStage, renderable.subset.rhi.targetsTexture, targetsSampler);
327 samplerBindingsSpecified.setBit(binding);
328 }
329 }
330
331 // Prioritize reflection texture over Light Probe texture because
332 // reflection texture also contains the irradiance and pre filtered
333 // values for the light probe.
335 int reflectionSampler = shaderPipeline->bindingForTexture("qt_reflectionMap");
338 QRhiTexture* reflectionTexture = layerData.getReflectionMapManager()->reflectionMapEntry(renderable.reflectionProbeIndex)->m_rhiPrefilteredCube;
339 if (reflectionSampler >= 0 && reflectionTexture) {
340 bindings.addTexture(reflectionSampler, QRhiShaderResourceBinding::FragmentStage, reflectionTexture, sampler);
341 samplerBindingsSpecified.setBit(reflectionSampler);
342 }
343 } else if (shaderPipeline->lightProbeTexture()) {
344 int binding = shaderPipeline->bindingForTexture("qt_lightProbe", int(QSSGRhiSamplerBindingHints::LightProbe));
345 if (binding >= 0) {
346 samplerBindingsSpecified.setBit(binding);
347 QPair<QSSGRenderTextureCoordOp, QSSGRenderTextureCoordOp> tiling = shaderPipeline->lightProbeTiling();
349 toRhi(tiling.first), toRhi(tiling.second), QRhiSampler::Repeat });
350 bindings.addTexture(binding,
352 shaderPipeline->lightProbeTexture(), sampler);
353 } // else ignore, not an error (for example, an unshaded material's fragment shader will not have this sampler)
354 }
355
356 if (shaderPipeline->screenTexture()) {
357 int binding = shaderPipeline->bindingForTexture("qt_screenTexture", int(QSSGRhiSamplerBindingHints::ScreenTexture));
358 if (binding >= 0) {
359 samplerBindingsSpecified.setBit(binding);
360 // linear min/mag, mipmap filtering depends on the
361 // texture, with SCREEN_TEXTURE there are no mipmaps, but
362 // once SCREEN_MIP_TEXTURE is seen the texture (the same
363 // one) has mipmaps generated.
364 QRhiSampler::Filter mipFilter = shaderPipeline->screenTexture()->flags().testFlag(QRhiTexture::MipMapped)
368 bindings.addTexture(binding,
370 shaderPipeline->screenTexture(), sampler);
371 } // else ignore, not an error
372 }
373
374 if (shaderPipeline->depthTexture()) {
375 int binding = shaderPipeline->bindingForTexture("qt_depthTexture", int(QSSGRhiSamplerBindingHints::DepthTexture));
376 if (binding >= 0) {
377 samplerBindingsSpecified.setBit(binding);
378 // nearest min/mag, no mipmap
381 bindings.addTexture(binding,
383 shaderPipeline->depthTexture(), sampler);
384 } // else ignore, not an error
385 }
386
387 if (shaderPipeline->ssaoTexture()) {
388 int binding = shaderPipeline->bindingForTexture("qt_aoTexture", int(QSSGRhiSamplerBindingHints::AoTexture));
389 if (binding >= 0) {
390 samplerBindingsSpecified.setBit(binding);
391 // linear min/mag, no mipmap
394 bindings.addTexture(binding,
396 shaderPipeline->ssaoTexture(), sampler);
397 } // else ignore, not an error
398 }
399
400 if (shaderPipeline->lightmapTexture()) {
401 int binding = shaderPipeline->bindingForTexture("qt_lightmap", int(QSSGRhiSamplerBindingHints::LightmapTexture));
402 if (binding >= 0) {
403 samplerBindingsSpecified.setBit(binding);
406 bindings.addTexture(binding,
408 shaderPipeline->lightmapTexture(), sampler);
409 } // else ignore, not an error
410 }
411
412 const int shadowMapCount = shaderPipeline->shadowMapCount();
413 for (int i = 0; i < shadowMapCount; ++i) {
414 QSSGRhiShadowMapProperties &shadowMapProperties(shaderPipeline->shadowMapAt(i));
415 QRhiTexture *texture = shadowMapProperties.shadowMapTexture;
418 const QByteArray &name(shadowMapProperties.shadowMapTextureUniformName);
419 if (shadowMapProperties.cachedBinding < 0)
420 shadowMapProperties.cachedBinding = shaderPipeline->bindingForTexture(name);
421 if (shadowMapProperties.cachedBinding < 0) // may not be used in the shader with unshaded custom materials, that's normal
422 continue;
423 samplerBindingsSpecified.setBit(shadowMapProperties.cachedBinding);
424 bindings.addTexture(shadowMapProperties.cachedBinding,
426 texture,
427 sampler);
428 }
429
430 QSSGRenderableImage *renderableImage = renderable.firstImage;
431 while (renderableImage) {
432 const char *samplerName = QSSGMaterialShaderGenerator::getSamplerName(renderableImage->m_mapType);
433 const int samplerHint = int(renderableImage->m_mapType);
434 int samplerBinding = shaderPipeline->bindingForTexture(samplerName, samplerHint);
435 if (samplerBinding >= 0) {
436 QRhiTexture *texture = renderableImage->m_texture.m_texture;
437 if (samplerBinding >= 0 && texture) {
438 const bool mipmapped = texture->flags().testFlag(QRhiTexture::MipMapped);
439 QSSGRhiSamplerDescription samplerDesc = {
440 toRhi(renderableImage->m_imageNode.m_minFilterType),
441 toRhi(renderableImage->m_imageNode.m_magFilterType),
442 mipmapped ? toRhi(renderableImage->m_imageNode.m_mipFilterType) : QRhiSampler::None,
443 toRhi(renderableImage->m_imageNode.m_horizontalTilingMode),
444 toRhi(renderableImage->m_imageNode.m_verticalTilingMode),
446 };
447 rhiCtx->checkAndAdjustForNPoT(texture, &samplerDesc);
448 QRhiSampler *sampler = rhiCtx->sampler(samplerDesc);
449 samplerBindingsSpecified.setBit(samplerBinding);
450 bindings.addTexture(samplerBinding,
453 }
454 } // else this is not necessarily an error, e.g. having metalness/roughness maps with metalness disabled
455 renderableImage = renderableImage->m_nextImage;
456 }
457
458 if (maxSamplerBinding >= 0) {
459 // custom property textures
460 int customTexCount = shaderPipeline->extraTextureCount();
461 for (int i = 0; i < customTexCount; ++i) {
462 QSSGRhiTexture &t(shaderPipeline->extraTextureAt(i));
463 const int samplerBinding = shaderPipeline->bindingForTexture(t.name);
464 if (samplerBinding >= 0) {
465 samplerBindingsSpecified.setBit(samplerBinding);
466 rhiCtx->checkAndAdjustForNPoT(t.texture, &t.samplerDesc);
467 QRhiSampler *sampler = rhiCtx->sampler(t.samplerDesc);
468 bindings.addTexture(samplerBinding,
470 t.texture,
471 sampler);
472 }
473 }
474
475 // use a dummy texture for the unused samplers in the shader
478
479 for (const QShaderDescription::InOutVariable &var : samplerVars) {
480 if (!samplerBindingsSpecified.testBit(var.binding)) {
481 QRhiTexture *t = var.type == QShaderDescription::SamplerCube ? dummyCubeTexture : dummyTexture;
482 bindings.addTexture(var.binding, CUSTOM_MATERIAL_VISIBILITY_ALL, t, dummySampler);
483 }
484 }
485 }
486
487 // do the same srb lookup acceleration as default materials
489 bool srbChanged = false;
490 if (!srb || bindings != dcd.bindings) {
491 srb = rhiCtx->srb(bindings);
492 dcd.bindings = bindings;
493 srbChanged = true;
494 }
495
496 if (cubeFace < 0)
497 renderable.rhiRenderData.mainPass.srb = srb;
498 else
499 renderable.rhiRenderData.reflectionPass.srb[cubeFace] = srb;
500
501 const QSSGGraphicsPipelineStateKey pipelineKey = QSSGGraphicsPipelineStateKey::create(*ps, renderPassDescriptor, srb);
502 if (dcd.pipeline
503 && !srbChanged
506 && dcd.ps == *ps)
507 {
508 if (cubeFace < 0)
509 renderable.rhiRenderData.mainPass.pipeline = dcd.pipeline;
510 else
512 } else {
513 if (cubeFace < 0) {
514 renderable.rhiRenderData.mainPass.pipeline = rhiCtx->pipeline(pipelineKey,
515 renderPassDescriptor,
516 srb);
517 dcd.pipeline = renderable.rhiRenderData.mainPass.pipeline;
518 } else {
519 renderable.rhiRenderData.reflectionPass.pipeline = rhiCtx->pipeline(pipelineKey,
520 renderPassDescriptor,
521 srb);
523 }
524
527 dcd.ps = *ps;
528 }
529 }
530}
531
532void QSSGCustomMaterialSystem::setShaderResources(char *ubufData,
533 const QSSGRenderCustomMaterial &inMaterial,
534 const QByteArray &inPropertyName,
535 const QVariant &propertyValue,
536 QSSGRenderShaderDataType inPropertyType,
537 QSSGRhiShaderPipeline &shaderPipeline)
538{
539 Q_UNUSED(inMaterial);
540
541 if (inPropertyType == QSSGRenderShaderDataType::Texture) {
543 reinterpret_cast<QSSGRenderCustomMaterial::TextureProperty *>(propertyValue.value<void *>());
544 QSSGRenderImage *image = textureProperty->texImage;
545 if (image) {
546 const auto &theBufferManager(context->bufferManager());
547 const QSSGRenderImageTexture texture = theBufferManager->loadRenderImage(image);
548 if (texture.m_texture) {
549 const QSSGRhiTexture t = {
550 inPropertyName,
551 texture.m_texture,
552 { toRhi(textureProperty->minFilterType),
553 toRhi(textureProperty->magFilterType),
554 textureProperty->mipFilterType != QSSGRenderTextureFilterOp::None ? toRhi(textureProperty->mipFilterType) : QRhiSampler::None,
555 toRhi(textureProperty->horizontalClampType),
556 toRhi(textureProperty->verticalClampType),
558 }
559 };
560 shaderPipeline.addExtraTexture(t);
561 }
562 }
563 } else {
564 shaderPipeline.setUniformValue(ubufData, inPropertyName, propertyValue, inPropertyType);
565 }
566}
567
569 const QSSGRenderCustomMaterial &material,
570 QSSGRhiShaderPipeline &shaderPipeline)
571{
572 const auto &properties = material.m_properties;
573 for (const auto &prop : properties)
574 setShaderResources(ubufData, material, prop.name, prop.value, prop.shaderDataType, shaderPipeline);
575
576 const auto textProps = material.m_textureProperties;
577 for (const auto &prop : textProps)
578 setShaderResources(ubufData, material, prop.name, QVariant::fromValue((void *)&prop), prop.shaderDataType, shaderPipeline);
579}
580
582 QSSGSubsetRenderable &renderable,
583 bool *needsSetViewport,
584 int cubeFace,
586{
589
590 if (cubeFace >= 0) {
591 ps = renderable.rhiRenderData.reflectionPass.pipeline;
592 srb = renderable.rhiRenderData.reflectionPass.srb[cubeFace];
593 }
594
595 if (!ps || !srb)
596 return;
597
598 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderCall);
599 QRhiBuffer *vertexBuffer = renderable.subset.rhi.vertexBuffer->buffer();
600 QRhiBuffer *indexBuffer = renderable.subset.rhi.indexBuffer ? renderable.subset.rhi.indexBuffer->buffer() : nullptr;
601
603 cb->setGraphicsPipeline(ps);
604 cb->setShaderResources(srb);
605
606 if (*needsSetViewport) {
607 cb->setViewport(state.viewport);
608 *needsSetViewport = false;
609 }
610
611 QRhiCommandBuffer::VertexInput vertexBuffers[2];
612 int vertexBufferCount = 1;
613 vertexBuffers[0] = QRhiCommandBuffer::VertexInput(vertexBuffer, 0);
614 quint32 instances = 1;
615 if (renderable.modelContext.model.instancing()) {
616 instances = renderable.modelContext.model.instanceCount();
617 vertexBuffers[1] = QRhiCommandBuffer::VertexInput(renderable.instanceBuffer, 0);
619 }
620 if (indexBuffer) {
621 cb->setVertexInput(0, vertexBufferCount, vertexBuffers, indexBuffer, 0, renderable.subset.rhi.indexBuffer->indexFormat());
622 cb->drawIndexed(renderable.subset.count, instances, renderable.subset.offset);
623 QSSGRHICTX_STAT(rhiCtx, drawIndexed(renderable.subset.count, instances));
624 } else {
625 cb->setVertexInput(0, vertexBufferCount, vertexBuffers);
626 cb->draw(renderable.subset.count, instances, renderable.subset.offset);
627 QSSGRHICTX_STAT(rhiCtx, draw(renderable.subset.count, instances));
628 }
629 Q_QUICK3D_PROFILE_END_WITH_IDS(QQuick3DProfiler::Quick3DRenderCall, (renderable.subset.count | quint64(instances) << 32),
630 QVector<int>({renderable.modelContext.model.profilingId,
631 renderable.material.profilingId}));
632}
633
\inmodule QtCore
Definition qbitarray.h:13
bool testBit(qsizetype i) const
Returns true if the bit at index position i is 1; otherwise returns false.
Definition qbitarray.h:84
void setBit(qsizetype i)
Sets the bit at index position i to 1.
Definition qbitarray.h:88
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
Definition qhash.h:1258
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
Definition qhash.h:1206
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
Definition qhash.h:949
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1283
Definition qlist.h:74
const_iterator cend() const noexcept
Definition qlist.h:614
void append(parameter_type t)
Definition qlist.h:441
const_iterator cbegin() const noexcept
Definition qlist.h:613
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
static FeatureSet toFeatureSet(const T &ssgFeatureSet)
\inmodule QtGui
Definition qrhi.h:834
virtual char * beginFullDynamicBufferUpdateForCurrentFrame()
Definition qrhi.cpp:3844
virtual void endFullDynamicBufferUpdateForCurrentFrame()
To be called when the entire contents of the buffer data has been updated in the memory block returne...
Definition qrhi.cpp:3854
\inmodule QtGui
Definition qrhi.h:1614
QPair< QRhiBuffer *, quint32 > VertexInput
Synonym for QPair<QRhiBuffer *, quint32>.
Definition qrhi.h:1643
void resourceUpdate(QRhiResourceUpdateBatch *resourceUpdates)
Sometimes committing resource updates is necessary or just more convenient without starting a render ...
Definition qrhi.cpp:8986
\inmodule QtGui
Definition qrhi.h:1241
\inmodule QtGui
Definition qrhi.h:1119
\inmodule QtGui
Definition qrhi.h:1694
\inmodule QtGui
Definition qrhi.h:1007
Filter
Specifies the minification, magnification, or mipmap filtering.
Definition qrhi.h:1009
@ ClampToEdge
Definition qrhi.h:1017
\inmodule QtGui
Definition qrhi.h:1190
\inmodule QtGui
Definition qrhi.h:883
@ MipMapped
Definition qrhi.h:888
@ CubeMap
Definition qrhi.h:887
Flags flags() const
Definition qrhi.h:980
void setBindings(std::initializer_list< QRhiVertexInputBinding > list)
Sets the bindings from the specified list.
Definition qrhi.h:317
const QRhiVertexInputBinding * cendBindings() const
Definition qrhi.h:325
const QRhiVertexInputBinding * cbeginBindings() const
Definition qrhi.h:324
QMatrix4x4 clipSpaceCorrMatrix() const
Definition qrhi.cpp:9662
QRhiResourceUpdateBatch * nextResourceUpdateBatch()
Definition qrhi.cpp:8854
void rhiRenderRenderable(QSSGRhiContext *rhiCtx, QSSGSubsetRenderable &renderable, bool *needsSetViewport, int cubeFace, const QSSGRhiGraphicsPipelineState &state)
void applyRhiShaderPropertyValues(char *ubufData, const QSSGRenderCustomMaterial &inMaterial, QSSGRhiShaderPipeline &shaderPipeline)
void setRenderContextInterface(QSSGRenderContextInterface *inContext)
void updateUniformsForCustomMaterial(QSSGRhiShaderPipeline &shaderPipeline, QSSGRhiContext *rhiCtx, const QSSGLayerRenderData &inData, char *ubufData, QSSGRhiGraphicsPipelineState *ps, const QSSGRenderCustomMaterial &material, QSSGSubsetRenderable &renderable, const QSSGRenderCamera &camera, const QVector2D *depthAdjust, const QMatrix4x4 *alteredModelViewProjection)
bool prepareForRender(const QSSGRenderModel &inModel, const QSSGRenderSubset &inSubset, QSSGRenderCustomMaterial &inMaterial)
void rhiPrepareRenderable(QSSGRhiGraphicsPipelineState *ps, QSSGPassKey passKey, QSSGSubsetRenderable &renderable, const QSSGShaderFeatures &featureSet, const QSSGRenderCustomMaterial &material, const QSSGLayerRenderData &layerData, QRhiRenderPassDescriptor *renderPassDescriptor, int samples, QSSGRenderCamera *camera=nullptr, int cubeFace=-1, QMatrix4x4 *modelViewProjection=nullptr, QSSGReflectionMapEntry *entry=nullptr)
QSSGRhiShaderPipelinePtr shadersForCustomMaterial(QSSGRhiGraphicsPipelineState *ps, const QSSGRenderCustomMaterial &material, QSSGSubsetRenderable &renderable, const QSSGShaderFeatures &featureSet)
QRhiTexture * getLightmapTexture(const QSSGModelContext &modelContext) const
const QSSGRenderReflectionMapPtr & getReflectionMapManager() const
QSSGRenderCamera * camera
QRhiTexture * getBonemapTexture(const QSSGModelContext &modelContext) const
std::optional< QSSGCameraRenderData > cameraData
static void updateUniformsForParticleModel(QSSGRhiShaderPipeline &shaderPipeline, char *ubufData, const QSSGRenderModel *model, quint32 offset)
static void prepareParticlesForModel(QSSGRhiShaderPipeline &shaderPipeline, QSSGRhiContext *rhiCtx, QSSGRhiShaderResourceBindingList &bindings, const QSSGRenderModel *model)
const std::unique_ptr< QSSGRhiContext > & rhiContext() const
const std::unique_ptr< QSSGProgramGenerator > & shaderProgramGenerator() const
const std::shared_ptr< QSSGShaderLibraryManager > & shaderLibraryManager() const
const std::unique_ptr< QSSGBufferManager > & bufferManager() const
const std::unique_ptr< QSSGRenderer > & renderer() const
const std::unique_ptr< QSSGShaderCache > & shaderCache() const
QSSGShaderDefaultMaterialKeyProperties & defaultMaterialShaderKeyProperties()
QSSGLayerGlobalRenderProperties getLayerGlobalRenderProperties()
QRhiTexture * dummyTexture(QRhiTexture::Flags flags, QRhiResourceUpdateBatch *rub, const QSize &size=QSize(64, 64), const QColor &fillColor=Qt::black)
QRhiCommandBuffer * commandBuffer() const
QSSGRhiDrawCallData & drawCallData(const QSSGRhiDrawCallDataKey &key)
void checkAndAdjustForNPoT(QRhiTexture *texture, QSSGRhiSamplerDescription *samplerDescription)
QRhiShaderResourceBindings * srb(const QSSGRhiShaderResourceBindingList &bindings)
QRhiGraphicsPipeline * pipeline(const QSSGGraphicsPipelineStateKey &key, QRhiRenderPassDescriptor *rpDesc, QRhiShaderResourceBindings *srb)
QRhi * rhi() const
QRhiSampler * sampler(const QSSGRhiSamplerDescription &samplerDescription)
void setUniformValue(char *ubufData, const char *name, const QVariant &value, QSSGRenderShaderDataType type)
void addExtraTexture(const QSSGRhiTexture &t)
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
Definition qtimer.cpp:208
constexpr size_type size() const noexcept
const_iterator cbegin() const noexcept
const_iterator cend() const noexcept
void append(const T &t)
\inmodule QtCore
Definition qvariant.h:64
T value() const &
Definition qvariant.h:511
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:531
The QVector2D class represents a vector or vertex in 2D space.
Definition qvectornd.h:31
QCamera * camera
Definition camera.cpp:19
QSet< QString >::iterator it
else opt state
[0]
Combined button and popup list for selecting options.
Definition image.cpp:4
std::pair< T1, T2 > QPair
static const QCssKnownValue properties[NumProperties - 1]
@ Repeat
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLsizei const GLfloat * v
[13]
GLsizei samples
GLuint sampler
const void GLsizei GLsizei stride
GLenum GLuint texture
GLuint name
GLuint entry
GLdouble GLdouble t
Definition qopenglext.h:243
const void GLsizei GLsizei GLint vertexBufferCount
#define Q_QUICK3D_PROFILE_START(Type)
#define Q_QUICK3D_PROFILE_END_WITH_ID(Type, Payload, POID)
#define Q_QUICK3D_PROFILE_END_WITH_IDS(Type, Payload, POIDs)
QSSGDataView< T > toDataView(const T &type)
QSSGRenderShaderDataType
#define QSSGRHICTX_STAT(ctx, f)
std::shared_ptr< QSSGRhiShaderPipeline > QSSGRhiShaderPipelinePtr
QRhiSampler::Filter toRhi(QSSGRenderTextureFilterOp op)
static const QRhiShaderResourceBinding::StageFlags CUSTOM_MATERIAL_VISIBILITY_ALL
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define Q_UNUSED(x)
const void * QSSGPassKey
#define Q_TRACE_SCOPE(x,...)
Definition qtrace_p.h:146
#define Q_TRACE_POINT(provider, tracepoint,...)
Definition qtrace_p.h:232
unsigned int quint32
Definition qtypes.h:45
unsigned long long quint64
Definition qtypes.h:56
QTimer * timer
[3]
myFilter draw(painter, QPoint(0, 0), originalPixmap)
QByteArray generateSha() const
static QSSGGraphicsPipelineStateKey create(const QSSGRhiGraphicsPipelineState &state, const QRhiRenderPassDescriptor *rpDesc, const QRhiShaderResourceBindings *srb)
struct QSSGGraphicsPipelineStateKey::@759 extra
QVector< quint32 > renderTargetDescription
static QSSGRhiShaderPipelinePtr generateMaterialRhiShader(const QByteArray &inShaderKeyPrefix, QSSGMaterialVertexPipeline &vertexGenerator, const QSSGShaderDefaultMaterialKey &key, QSSGShaderDefaultMaterialKeyProperties &inProperties, const QSSGShaderFeatures &inFeatureSet, const QSSGRenderGraphObject &inMaterial, const QSSGShaderLightListView &inLights, QSSGRenderableImage *inFirstImage, QSSGShaderLibraryManager &shaderLibraryManager, QSSGShaderCache &theCache)
static const char * getSamplerName(QSSGRenderableImage::Type type)
static void setRhiMaterialProperties(const QSSGRenderContextInterface &, QSSGRhiShaderPipeline &shaders, char *ubufData, QSSGRhiGraphicsPipelineState *inPipelineState, const QSSGRenderGraphObject &inMaterial, const QSSGShaderDefaultMaterialKey &inKey, QSSGShaderDefaultMaterialKeyProperties &inProperties, const QSSGRenderCamera &inCamera, const QMatrix4x4 &inModelViewProjection, const QMatrix3x3 &inNormalMatrix, const QMatrix4x4 &inGlobalTransform, const QMatrix4x4 &clipSpaceCorrMatrix, const QMatrix4x4 &localInstanceTransform, const QMatrix4x4 &globalInstanceTransform, const QSSGDataView< float > &inMorphWeights, QSSGRenderableImage *inFirstImage, float inOpacity, const QSSGLayerGlobalRenderProperties &inRenderProperties, const QSSGShaderLightListView &inLights, const QSSGShaderReflectionProbe &reflectionProbe, bool receivesShadows, bool receivesReflections, const QVector2D *shadowDepthAdjust, QRhiTexture *lightmapTexture)
const QSSGRenderModel & model
QRhiGraphicsPipeline::BlendFactor m_srcBlend
QSSGShaderMaterialAdapter * adapter
QRhiGraphicsPipeline::BlendFactor m_dstBlend
QSSGRenderTextureFilterOp m_mipFilterType
QSSGRenderTextureCoordOp m_horizontalTilingMode
QSSGRenderTextureFilterOp m_minFilterType
QSSGRenderTextureCoordOp m_verticalTilingMode
QSSGRenderTextureFilterOp m_magFilterType
int instanceCount() const
bool instancing() const
QSSGRenderInstanceTable * instanceTable
QSSGRhiBufferPtr indexBuffer
QSSGRhiInputAssemblerState ia
QRhiTexture * targetsTexture
QSSGRhiBufferPtr vertexBuffer
struct QSSGRenderSubset::@751 rhi
QSSGRenderImageTexture m_texture
QSSGRenderableImage * m_nextImage
const QSSGRenderImage & m_imageNode
const QMatrix4x4 & globalTransform
QSSGRenderableObjectFlags renderableFlags
QSSGRhiShaderResourceBindingList bindings
QSSGRhiGraphicsPipelineState ps
QRhiShaderResourceBindings * srb
QVector< quint32 > renderTargetDescription
QRhiGraphicsPipeline * pipeline
QSSGRhiInputAssemblerState ia
QRhiGraphicsPipeline::CullMode cullMode
static QRhiGraphicsPipeline::CullMode toCullMode(QSSGCullFaceMode cullFaceMode)
QRhiGraphicsPipeline::TargetBlend targetBlend
const QSSGRhiShaderPipeline * shaderPipeline
void bakeVertexInputLocations(const QSSGRhiShaderPipeline &shaders, int instanceBufferBinding=0)
QRhiVertexInputLayout inputLayout
void addUniformBuffer(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiBuffer *buf, int offset, int size)
void addTexture(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
void toString(QByteArray &ioString, const QSSGShaderDefaultMaterialKeyProperties &inProperties) const
constexpr bool isSet(Feature feature) const
bool getValue(QSSGDataView< quint32 > inDataStore) const
QRhiGraphicsPipeline * pipeline
bool prepareInstancing(QSSGRhiContext *rhiCtx, const QVector3D &cameraDirection, const QVector3D &cameraPosition, float minThreshold, float maxThreshold)
const QSSGShaderLightListView & lights
struct QSSGSubsetRenderable::@762 rhiRenderData
QSSGShaderReflectionProbe reflectionProbe
struct QSSGSubsetRenderable::@762::@763 mainPass
const QSSGRenderSubset & subset
struct QSSGSubsetRenderable::@762::@766 reflectionPass
QRhiShaderResourceBindings * srb
QSSGShaderDefaultMaterialKey shaderDescription
QSSGRenderableImage * firstImage
const QSSGModelContext & modelContext
const QSSGRenderGraphObject & material