Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qssgrenderpass.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qssgrenderpass_p.h"
10
11#include "../utils/qssgassert_p.h"
12
13#include <QtQuick/private/qsgrenderer_p.h>
14#include <qtquick3d_tracepoints_p.h>
15
16#include <QtQuick3D/QQuick3DObject>
17
19
20static inline QMatrix4x4 correctMVPForScissor(QRectF viewportRect, QRect scissorRect, bool isYUp) {
21 const auto &scissorCenter = scissorRect.center();
22 const auto &viewCenter = viewportRect.center();
23 const float scaleX = viewportRect.width() / float(scissorRect.width());
24 const float scaleY = viewportRect.height() / float(scissorRect.height());
25 const float dx = 2 * (viewCenter.x() - scissorCenter.x()) / scissorRect.width();
26 const float dyRect = isYUp ? (scissorCenter.y() - viewCenter.y())
27 : (viewCenter.y() - scissorCenter.y());
28 const float dy = 2 * dyRect / scissorRect.height();
29
30 return QMatrix4x4(scaleX, 0.0f, 0.0f, dx,
31 0.0f, scaleY, 0.0f, dy,
32 0.0f, 0.0f, 1.0f, 0.0f,
33 0.0f, 0.0f, 0.0f, 1.0f);
34}
35// SHADOW PASS
36
38{
40 using namespace RenderHelpers;
41
42 camera = data.camera;
43 QSSG_ASSERT(camera, return);
44
45 const auto &renderedDepthWriteObjects = data.getSortedRenderedDepthWriteObjects();
46 const auto &renderedOpaqueDepthPrepassObjects = data.getSortedrenderedOpaqueDepthPrepassObjects();
47
49
50 for (const auto &handles : { &renderedDepthWriteObjects, &renderedOpaqueDepthPrepassObjects }) {
51 for (const auto &handle : *handles) {
52 if (handle.obj->renderableFlags.castsShadows())
54 }
55 }
56
57 globalLights = data.globalLights;
58
60
61 if (enabled) {
62 shadowMapManager = data.requestShadowMapManager();
63
64 ps = data.getPipelineState();
65 ps.depthTestEnable = true;
66 ps.depthWriteEnable = true;
67 // Try reducing self-shadowing and artifacts.
68 ps.depthBias = 2;
70
71 const auto &sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects();
72 const auto &sortedTransparentObjects = data.getSortedTransparentRenderableObjects();
73 const auto [casting, receiving] = calculateSortedObjectBounds(sortedOpaqueObjects,
74 sortedTransparentObjects);
75 castingObjectsBox = casting;
76 receivingObjectsBox = receiving;
77 }
78}
79
81{
82 using namespace RenderHelpers;
83
84 // INPUT: Sorted opaque and transparent + depth, global lights (scoped lights not supported) and camera.
85
86 // DEPENDECY: None
87
88 // OUTPUT: Textures or cube maps
89
90 // CONDITION: Lights (shadowPassObjects)
91
92 if (enabled) {
93 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
94 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
95 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
96 cb->debugMarkBegin(QByteArrayLiteral("Quick3D shadow map"));
97 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D shadow map"));
98 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
99
101 rhiRenderShadowMap(rhiCtx.get(),
102 this,
103 ps,
105 *camera,
106 globalLights, // scoped lights are not relevant here
108 renderer,
111
112 cb->debugMarkEnd();
113 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("shadow_map"));
114 }
115}
116
118{
119 enabled = false;
120 camera = nullptr;
123 ps = {};
126}
127
128// REFLECTIONMAP PASS
129
131{
133 Q_UNUSED(data);
134
135 ps = data.getPipelineState();
136 ps.depthTestEnable = true;
137 ps.depthWriteEnable = true;
138 ps.blendEnable = true;
139
140 reflectionProbes = data.reflectionProbes;
141 reflectionMapManager = data.requestReflectionMapManager();
142
143 const auto &sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects();
144 const auto &sortedTransparentObjects = data.getSortedTransparentRenderableObjects();
145
147
148 // NOTE: We should consider keeping track of the reflection casting objects to avoid
149 // filtering this list on each prep.
150 for (const auto &handles : { &sortedOpaqueObjects, &sortedTransparentObjects }) {
151 for (const auto &handle : *handles) {
152 if (handle.obj->renderableFlags.testFlag(QSSGRenderableObjectFlag::CastsReflections))
154 }
155 }
156}
157
159{
160 using namespace RenderHelpers;
161
162 // INPUT: Reflection probes, sorted opaque and transparent
163
164 // DEPENDECY: None
165
166 // OUTPUT: Cube maps (1 per probe)
167
168 // NOTE: Full pass with a sky box pass
169
170 // CONDITION: Probes and sorted opaque and transparent
171
172 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
173 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
174 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
175
176 // TODO: Workaroud as we using the layer data in rhiRenderReflectionMap() consider
177 // if we can extract the data we need for rendering in the prep step...
178 QSSG_ASSERT(renderer.getLayerGlobalRenderProperties().layer.renderData, return);
179 const auto &data = *renderer.getLayerGlobalRenderProperties().layer.renderData;
180
182 if (!reflectionPassObjects.isEmpty() || !reflectionProbes.isEmpty()) {
183 cb->debugMarkBegin(QByteArrayLiteral("Quick3D reflection map"));
184 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D reflection map"));
185 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
186 rhiRenderReflectionMap(rhiCtx.get(),
187 this,
188 data,
189 &ps,
193 renderer);
194
195 cb->debugMarkEnd();
196 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("reflection_map"));
197 }
198}
199
201{
202 ps = {};
203 reflectionProbes.clear();
205}
206
207// ZPrePass
209{
210 using namespace RenderHelpers;
211
212 // INPUT: Item2Ds + depth write + depth prepass
213
214 // DEPENDECY: none
215
216 // OUTPUT: Depth buffer attchment for current target
217
218 // NOTE: Could we make the depth pass more complete and just do a blit here?
219
220 // CONDITION: Input + globally enabled or ?
221
222 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
223 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
224 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
225 ps = data.getPipelineState();
226
227 renderedDepthWriteObjects = data.getSortedRenderedDepthWriteObjects();
228 renderedOpaqueDepthPrepassObjects = data.getSortedrenderedOpaqueDepthPrepassObjects();
229
230 const auto &layer = data.layer;
231 const bool hasItem2Ds = data.renderableItem2Ds.isEmpty();
232 bool zPrePass = layer.layerFlags.testFlag(QSSGRenderLayer::LayerFlag::EnableDepthPrePass)
234 && (!renderedDepthWriteObjects.isEmpty() || hasItem2Ds);
235 if (zPrePass || !renderedOpaqueDepthPrepassObjects.isEmpty()) {
236 cb->debugMarkBegin(QByteArrayLiteral("Quick3D prepare Z prepass"));
237 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D prepare Z prepass"));
238 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
239 if (!zPrePass) {
240 state = { State::Forced };
241 rhiPrepareDepthPass(rhiCtx.get(), this, ps, rhiCtx->mainRenderPassDescriptor(), data,
244 rhiCtx->mainPassSampleCount());
245 } else if (rhiPrepareDepthPass(rhiCtx.get(), this, ps, rhiCtx->mainRenderPassDescriptor(), data,
248 rhiCtx->mainPassSampleCount())) {
249 state = { State::Active };
250 }
251 cb->debugMarkEnd();
252 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("prepare_z_prepass"));
253 }
254}
255
257{
258 using namespace RenderHelpers;
259
260 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
261 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
262
263 bool needsSetViewport = true;
264 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
265
266 if (state == State::Active) {
267 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
268 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render Z prepass"));
269 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render Z prepass"));
270 rhiRenderDepthPass(rhiCtx.get(), ps, renderedDepthWriteObjects, renderedOpaqueDepthPrepassObjects, &needsSetViewport);
271 cb->debugMarkEnd();
272 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("render_z_prepass"));
273 } else if (state == State::Forced) {
274 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
275 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render Z forced prepass"));
276 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render Z forced prepass"));
277 rhiRenderDepthPass(rhiCtx.get(), ps, {}, renderedOpaqueDepthPrepassObjects, &needsSetViewport);
278 cb->debugMarkEnd();
279 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("render_z_prepass_forced"));
280 }
281}
282
284{
287 ps = {};
289}
290
291// SSAO PASS
293{
294 using namespace RenderHelpers;
295
296 // Assumption for now is that all passes are keept alive and only reset once a frame is done.
297 // I.e., holding data like this should be safe (If that's no longer the case we need to do ref counting
298 // for shared data).
299
300 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
301 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
302
303 rhiDepthTexture = &data.depthMapPass.rhiDepthTexture;
304 camera = data.camera;
305 QSSG_ASSERT_X((camera && rhiDepthTexture->isValid()), "Preparing AO pass failed, missing camera or depth texture", return);
306
307 ssaoShaderPipeline = data.renderer->getRhiSsaoShader();
308 ambientOcclusion = { data.layer.aoStrength, data.layer.aoDistance, data.layer.aoSoftness, data.layer.aoBias, data.layer.aoSamplerate, data.layer.aoDither };
309
310 ps = data.getPipelineState();
311 const auto &layerPrepResult = data.layerPrepResult;
312 const bool ready = rhiPrepareAoTexture(rhiCtx.get(), layerPrepResult->textureDimensions(), &rhiAoTexture);
313
314 if (Q_UNLIKELY(!ready))
316}
317
319{
320 using namespace RenderHelpers;
321
322 // INPUT: Camera + depth map
323
324 // DEPENDECY: Depth map (zprepass)
325
326 // OUTPUT: AO Texture
327
328 // NOTE:
329
330 // CONDITION: SSAO enabled
331 QSSG_ASSERT(camera, return);
333
334 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
335 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
336
337 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
338 cb->debugMarkBegin(QByteArrayLiteral("Quick3D SSAO map"));
339 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D SSAO map"));
340 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
341
343 rhiRenderAoTexture(rhiCtx.get(),
344 this,
345 renderer,
347 ps,
351 *camera);
352
353 cb->debugMarkEnd();
354 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("ssao_map"));
355}
356
358{
359 rhiDepthTexture = nullptr;
360 camera = nullptr;
362 ps = {};
364}
365
366// DEPTH TEXTURE PASS
368{
369 using namespace RenderHelpers;
370
371 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
372 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
373 const auto &layerPrepResult = data.layerPrepResult;
374 bool ready = false;
375 ps = data.getPipelineState();
376 if (Q_LIKELY(rhiPrepareDepthTexture(rhiCtx.get(), layerPrepResult->textureDimensions(), &rhiDepthTexture))) {
377 sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects();
378 sortedTransparentObjects = data.getSortedTransparentRenderableObjects();
379 ready = rhiPrepareDepthPass(rhiCtx.get(), this, ps, rhiDepthTexture.rpDesc, data,
382 1);
383 }
384
385 if (Q_UNLIKELY(!ready))
387}
388
390{
391 using namespace RenderHelpers;
392
393 // INPUT: sorted objects (opaque + transparent) (maybe...)
394
395 // DEPENDECY: If this is only used for the AO case, that dictates if this should be done or not.
396
397 // OUTPUT: Texture
398
399 // NOTE: Why are we prepping opaque + transparent object if we're not using them? And why are we staying compatible with 5.15?
400 // Only used for AO? Merge into the AO pass?
401
402 // CONDITION:
403
404 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
405 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
406 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
407 cb->debugMarkBegin(QByteArrayLiteral("Quick3D depth texture"));
408
410 bool needsSetViewport = true;
411 cb->beginPass(rhiDepthTexture.rt, Qt::transparent, { 1.0f, 0 }, nullptr, QSSGRhiContext::commonPassFlags());
412 QSSGRHICTX_STAT(rhiCtx, beginRenderPass(rhiDepthTexture.rt));
413 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
414 // NB! We do not pass sortedTransparentObjects in the 4th
415 // argument to stay compatible with the 5.15 code base,
416 // which also does not include semi-transparent objects in
417 // the depth texture. In addition, capturing after the
418 // opaque pass, not including transparent objects, is part
419 // of the contract for screen reading custom materials,
420 // both for depth and color.
421 rhiRenderDepthPass(rhiCtx.get(), ps, sortedOpaqueObjects, {}, &needsSetViewport);
422 cb->endPass();
423 QSSGRHICTX_STAT(rhiCtx, endRenderPass());
424 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("depth_texture"));
425 }
426
427 cb->debugMarkEnd();
428}
429
431{
435 ps = {};
436}
437
438// SCREEN TEXTURE PASS
439
441{
442 using namespace RenderHelpers;
443
444 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
445 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
446 auto camera = data.camera;
447 QSSG_ASSERT(camera, return);
448 auto &layer = data.layer;
449 const auto &layerPrepResult = data.layerPrepResult;
450 wantsMips = layerPrepResult->flags.requiresMipmapsForScreenTexture();
451 sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects();
452 const auto &renderedOpaqueDepthPrepassObjects = data.getSortedrenderedOpaqueDepthPrepassObjects();
453 const auto &renderedDepthWriteObjects = data.getSortedRenderedDepthWriteObjects();
454 ps = data.getPipelineState();
455
457 clearColor = QColor::fromRgbF(layer.clearColor.x(), layer.clearColor.y(), layer.clearColor.z());
458
459 if ((layer.background == QSSGRenderLayer::Background::SkyBox && layer.lightProbe)
460 || (layer.background == QSSGRenderLayer::Background::SkyBoxCubeMap && layer.skyBoxCubeMap))
461 {
462 if (!data.plainSkyBoxPrepared) {
463 data.plainSkyBoxPrepared = true;
464 rhiPrepareSkyBox(rhiCtx.get(), this, layer, *camera, renderer);
465 }
466 }
467
468 const bool layerEnableDepthTest = layer.layerFlags.testFlag(QSSGRenderLayer::LayerFlag::EnableDepthTest);
469 const bool depthTestEnableDefault = layerEnableDepthTest && (!sortedOpaqueObjects.isEmpty() || !renderedOpaqueDepthPrepassObjects.isEmpty() || !renderedDepthWriteObjects.isEmpty());
470 // enable depth write for opaque objects when there was no Z prepass
471 const bool depthWriteEnableDefault = depthTestEnableDefault && (!layer.layerFlags.testFlag(QSSGRenderLayer::LayerFlag::EnableDepthPrePass) || (data.zPrePassPass.state != ZPrePassPass::State::Active));
472
473 ps.depthTestEnable = depthTestEnableDefault;
474 ps.depthWriteEnable = depthWriteEnableDefault;
475
476 bool ready = false;
477 if (Q_LIKELY(rhiPrepareScreenTexture(rhiCtx.get(), layerPrepResult->textureDimensions(), wantsMips, &rhiScreenTexture))) {
478 ready = true;
479 // NB: not compatible with disabling LayerEnableDepthTest
480 // because there are effectively no "opaque" objects then.
481 // Disable Tonemapping for all materials in the screen pass texture
482 shaderFeatures = data.getShaderFeatures();
484 const auto &sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects();
485 for (const auto &handle : sortedOpaqueObjects)
486 rhiPrepareRenderable(rhiCtx.get(), this, data, *handle.obj, rhiScreenTexture.rpDesc, &ps, shaderFeatures, 1);
487 }
488
489 if (Q_UNLIKELY(!ready))
491}
492
494{
495 using namespace RenderHelpers;
496
497 // INPUT: Sorted opaque objects + depth objects
498
499 // DEPENDECY: Depth pass (if enabled)
500
501 // OUTPUT: Texture (screen texture).
502
503 // NOTE: Used for refrection and effects (?)
504
505 // CONDITION:
506
507 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
508 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
509 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
510
511 cb->debugMarkBegin(QByteArrayLiteral("Quick3D screen texture"));
512
514 const auto &layer = renderer.getLayerGlobalRenderProperties().layer;
515 cb->beginPass(rhiScreenTexture.rt, clearColor, { 1.0f, 0 }, nullptr, QSSGRhiContext::commonPassFlags());
516 QSSGRHICTX_STAT(rhiCtx, beginRenderPass(rhiScreenTexture.rt));
517 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
518
520 && rhiCtx->rhi()->isFeatureSupported(QRhi::TexelFetch) && layer.skyBoxSrb) {
521 // This is offscreen, so rendered untonemapped
522 auto shaderPipeline = renderer.getRhiSkyBoxShader(QSSGRenderLayer::TonemapMode::None, layer.skyBoxIsRgbe8);
523 QSSG_CHECK(shaderPipeline);
524 ps.shaderPipeline = shaderPipeline.get();
525 QRhiShaderResourceBindings *srb = layer.skyBoxSrb;
526 QRhiRenderPassDescriptor *rpDesc = rhiCtx->mainRenderPassDescriptor();
527 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, rpDesc, {});
529 && rhiCtx->rhi()->isFeatureSupported(QRhi::TexelFetch) && layer.skyBoxSrb) {
530 auto shaderPipeline = renderer.getRhiSkyBoxCubeShader();
531 QSSG_CHECK(shaderPipeline);
532 ps.shaderPipeline = shaderPipeline.get();
533 QRhiShaderResourceBindings *srb = layer.skyBoxSrb;
534 QRhiRenderPassDescriptor *rpDesc = rhiCtx->mainRenderPassDescriptor();
535 renderer.rhiCubeRenderer()->recordRenderCube(rhiCtx.get(), &ps, srb, rpDesc, {});
536 }
537 bool needsSetViewport = true;
538 for (const auto &handle : std::as_const(sortedOpaqueObjects))
539 rhiRenderRenderable(rhiCtx.get(), ps, *handle.obj, &needsSetViewport);
540
541 QRhiResourceUpdateBatch *rub = nullptr;
542 if (wantsMips) {
543 rub = rhiCtx->rhi()->nextResourceUpdateBatch();
545 }
546 cb->endPass(rub);
547 QSSGRHICTX_STAT(rhiCtx, endRenderPass());
548 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("screen_texture"));
549 }
550
551 cb->debugMarkEnd();
552}
553
555{
557 ps = {};
558 wantsMips = false;
560 shaderFeatures = {};
562}
563
564// MAIN PASS
566{
567 using namespace RenderHelpers;
568
569 // INPUT: Everything available
570
571 // DEPENDECY: Result from previous passes
572
573 // OUTPUT: Screen
574
575 // NOTE: (Does not write to the depth buffer as that's done in the ZPrePass).
576
577 // CONDITION: Always
578
579 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
580 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
581 auto camera = data.camera;
582 QSSG_ASSERT(camera, return);
583
584 ps = data.getPipelineState();
586 ps.blendEnable = false;
587
588 auto &layer = data.layer;
589 shaderFeatures = data.getShaderFeatures();
590
591 if ((layer.background == QSSGRenderLayer::Background::SkyBox && layer.lightProbe)
592 || (layer.background == QSSGRenderLayer::Background::SkyBoxCubeMap && layer.skyBoxCubeMap))
593 {
594 if (!data.plainSkyBoxPrepared) {
595 data.plainSkyBoxPrepared = true;
596 rhiPrepareSkyBox(rhiCtx.get(), this, layer, *camera, renderer);
597 }
598 }
599
600 {
601 const auto &clippingFrustum = data.clippingFrustum;
602 const auto &opaqueObjects = data.getSortedOpaqueRenderableObjects();
603 const auto &transparentObject = data.getSortedTransparentRenderableObjects();
604 if (clippingFrustum.has_value()) {
605 QSSGLayerRenderData::frustumCulling(clippingFrustum.value(), opaqueObjects, sortedOpaqueObjects);
606 QSSGLayerRenderData::frustumCulling(clippingFrustum.value(), transparentObject, sortedTransparentObjects);
607 } else {
608 sortedOpaqueObjects = opaqueObjects;
609 sortedTransparentObjects = transparentObject;
610 }
611 }
612 const bool layerEnableDepthTest = layer.layerFlags.testFlag(QSSGRenderLayer::LayerFlag::EnableDepthTest);
613 const auto &renderedOpaqueDepthPrepassObjects = data.getSortedrenderedOpaqueDepthPrepassObjects();
614 const auto &renderedDepthWriteObjects = data.getSortedRenderedDepthWriteObjects();
615 const bool depthTestEnableDefault = layerEnableDepthTest && (!sortedOpaqueObjects.isEmpty() || !renderedOpaqueDepthPrepassObjects.isEmpty() || !renderedDepthWriteObjects.isEmpty());;
616 const bool depthWriteEnableDefault = depthTestEnableDefault && (!layer.layerFlags.testFlag(QSSGRenderLayer::LayerFlag::EnableDepthPrePass) || (data.zPrePassPass.state != ZPrePassPass::State::Active));;
617
618 ps.depthTestEnable = depthTestEnableDefault;
619 // enable depth write for opaque objects when there was no Z prepass
620 ps.depthWriteEnable = depthWriteEnableDefault;
621
622 // Enable Wireframe mode
624
625 // make the buffer copies and other stuff we put on the command buffer in
626 // here show up within a named section in tools like RenderDoc when running
627 // with QSG_RHI_PROFILE=1 (which enables debug markers)
628 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
629 cb->debugMarkBegin(QByteArrayLiteral("Quick3D prepare renderables"));
630 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D prepare renderables"));
631 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
632
633 QRhiRenderPassDescriptor *mainRpDesc = rhiCtx->mainRenderPassDescriptor();
634 const int samples = rhiCtx->mainPassSampleCount();
635
636 // opaque objects (or, this list is empty when LayerEnableDepthTest is disabled)
637 for (const auto &handle : std::as_const(sortedOpaqueObjects)) {
638 QSSGRenderableObject *theObject = handle.obj;
639 const auto depthWriteMode = theObject->depthWriteMode;
640 ps.depthWriteEnable = !(depthWriteMode == QSSGDepthDrawMode::Never ||
641 depthWriteMode == QSSGDepthDrawMode::OpaquePrePass ||
642 (data.zPrePassPass.state == ZPrePassPass::State::Active) || !layerEnableDepthTest);
643 rhiPrepareRenderable(rhiCtx.get(), this, data, *theObject, mainRpDesc, &ps, shaderFeatures, samples);
644 }
645
646 // objects that requires the screen texture
647 ps.depthTestEnable = depthTestEnableDefault;
648 ps.depthWriteEnable = depthWriteEnableDefault;
649 sortedScreenTextureObjects = data.getSortedScreenTextureRenderableObjects();
650 for (const auto &handle : std::as_const(sortedScreenTextureObjects)) {
651 QSSGRenderableObject *theObject = handle.obj;
652 const auto depthWriteMode = theObject->depthWriteMode;
654 ps.depthWriteEnable = !(depthWriteMode == QSSGDepthDrawMode::Never || depthWriteMode == QSSGDepthDrawMode::OpaquePrePass
655 || (data.zPrePassPass.state == ZPrePassPass::State::Active) || !layerEnableDepthTest);
656 rhiPrepareRenderable(rhiCtx.get(), this, data, *theObject, mainRpDesc, &ps, shaderFeatures, samples);
657 }
658
659 // objects rendered by Qt Quick 2D
660 ps.depthTestEnable = depthTestEnableDefault;
661 ps.depthWriteEnable = depthWriteEnableDefault;
662 ps.blendEnable = false;
663
664 item2Ds = data.getRenderableItem2Ds();
665 for (const auto &item2D: std::as_const(item2Ds)) {
666 // Set the projection matrix
667 if (!item2D->m_renderer)
668 continue;
669 if (item2D->m_renderer && item2D->m_renderer->currentRhi() != renderer.contextInterface()->rhi()) {
670 static bool contextWarningShown = false;
671 if (!contextWarningShown) {
672 qWarning () << "Scene with embedded 2D content can only be rendered in one window.";
673 contextWarningShown = true;
674 }
675 continue;
676 }
677
678 auto layerPrepResult = data.layerPrepResult;
679
680 const auto &renderTarget = rhiCtx->renderTarget();
681 item2D->m_renderer->setDevicePixelRatio(renderTarget->devicePixelRatio());
682 const QRect deviceRect(QPoint(0, 0), renderTarget->pixelSize());
683 if (layer.scissorRect.isValid()) {
684 QRect effScissor = layer.scissorRect & layerPrepResult->viewport.toRect();
685 QMatrix4x4 correctionMat = correctMVPForScissor(layerPrepResult->viewport,
686 effScissor,
687 rhiCtx->rhi()->isYUpInNDC());
688 item2D->m_renderer->setProjectionMatrix(correctionMat * item2D->MVP);
689 item2D->m_renderer->setViewportRect(effScissor);
690 } else {
691 item2D->m_renderer->setProjectionMatrix(item2D->MVP);
692 item2D->m_renderer->setViewportRect(correctViewportCoordinates(layerPrepResult->viewport, deviceRect));
693 }
694 item2D->m_renderer->setDeviceRect(deviceRect);
695 QRhiRenderPassDescriptor *oldRp = nullptr;
696 if (item2D->m_rp) {
697 // Changing render target, and so incompatible renderpass
698 // descriptors should be uncommon, but possible.
699 if (!item2D->m_rp->isCompatible(rhiCtx->mainRenderPassDescriptor()))
700 std::swap(item2D->m_rp, oldRp);
701 }
702 if (!item2D->m_rp) {
703 // Do not pass our object to the Qt Quick scenegraph. It may
704 // hold on to it, leading to lifetime and ownership issues.
705 // Rather, create a dedicated, compatible object.
706 item2D->m_rp = rhiCtx->mainRenderPassDescriptor()->newCompatibleRenderPassDescriptor();
707 QSSG_CHECK(item2D->m_rp);
708 }
709 item2D->m_renderer->setRenderTarget({ renderTarget, item2D->m_rp, rhiCtx->commandBuffer() });
710 delete oldRp;
711 item2D->m_renderer->prepareSceneInline();
712 }
713
714 // transparent objects (or, without LayerEnableDepthTest, all objects)
715 ps.blendEnable = true;
716 ps.depthWriteEnable = false;
717
718 for (const auto &handle : std::as_const(sortedTransparentObjects)) {
719 QSSGRenderableObject *theObject = handle.obj;
720 const auto depthWriteMode = theObject->depthWriteMode;
721 ps.depthWriteEnable = (depthWriteMode == QSSGDepthDrawMode::Always && (data.zPrePassPass.state != ZPrePassPass::State::Active));
722 if (!(theObject->renderableFlags.isCompletelyTransparent()))
723 rhiPrepareRenderable(rhiCtx.get(), this, data, *theObject, mainRpDesc, &ps, shaderFeatures, samples);
724 }
725
726
727 if (layer.gridEnabled)
728 rhiPrepareGrid(rhiCtx.get(), layer, *camera, renderer);
729
730 // debug objects
731 const auto &debugDraw = renderer.contextInterface()->debugDrawSystem();
732 if (debugDraw && debugDraw->hasContent()) {
733 QRhiResourceUpdateBatch *rub = rhiCtx->rhi()->nextResourceUpdateBatch();
734 debugDraw->prepareGeometry(rhiCtx.get(), rub);
735 QSSGRhiDrawCallData &dcd = rhiCtx->drawCallData({ &layer, nullptr, nullptr, 0, QSSGRhiDrawCallDataKey::DebugObjects });
736 if (!dcd.ubuf) {
738 dcd.ubuf->create();
739 }
741 QMatrix4x4 viewProjection(Qt::Uninitialized);
742 camera->calculateViewProjectionMatrix(viewProjection);
743 viewProjection = rhiCtx->rhi()->clipSpaceCorrMatrix() * viewProjection;
744 memcpy(ubufData, viewProjection.constData(), 64);
746
749 dcd.srb = rhiCtx->srb(bindings);
750
751 rhiCtx->commandBuffer()->resourceUpdate(rub);
752 }
753
754 cb->debugMarkEnd();
755 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("prepare_renderables"));
756}
757
759{
760 using namespace RenderHelpers;
761
762 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
763 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
764 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
765
766 bool needsSetViewport = true;
767
768 // 1. Render opaque objects
769 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render opaque"));
770 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
771 Q_TRACE(QSSG_renderPass_entry, QStringLiteral("Quick3D render opaque"));
772 for (const auto &handle : std::as_const(sortedOpaqueObjects)) {
773 QSSGRenderableObject *theObject = handle.obj;
774 rhiRenderRenderable(rhiCtx.get(), ps, *theObject, &needsSetViewport);
775 }
776 cb->debugMarkEnd();
777 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("opaque_pass"));
778 Q_TRACE(QSSG_renderPass_exit);
779
780 // 2. Render sky box (opt)
781
782 const auto &layer = renderer.getLayerGlobalRenderProperties().layer;
783 auto polygonMode = ps.polygonMode;
786 && rhiCtx->rhi()->isFeatureSupported(QRhi::TexelFetch)
787 && layer.skyBoxSrb)
788 {
789 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
790 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render skybox"));
791 auto shaderPipeline = renderer.getRhiSkyBoxCubeShader();
792 QSSG_CHECK(shaderPipeline);
793 ps.shaderPipeline = shaderPipeline.get();
794 QRhiShaderResourceBindings *srb = layer.skyBoxSrb;
795 QRhiRenderPassDescriptor *rpDesc = rhiCtx->mainRenderPassDescriptor();
796 renderer.rhiCubeRenderer()->recordRenderCube(rhiCtx.get(), &ps, srb, rpDesc, { QSSGRhiQuadRenderer::DepthTest | QSSGRhiQuadRenderer::RenderBehind });
797 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("skybox_cube"));
798
799 } else if (layer.background == QSSGRenderLayer::Background::SkyBox
800 && rhiCtx->rhi()->isFeatureSupported(QRhi::TexelFetch)
801 && layer.skyBoxSrb)
802 {
803 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
804 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render skybox"));
805 QSSGRenderLayer::TonemapMode tonemapMode = layer.tonemapMode;
806 // When there are effects, then it is up to the last pass of the
807 // last effect to perform tonemapping, neither the skybox nor the
808 // main render pass should alter the colors then.
809 if (layer.firstEffect)
811
812 auto shaderPipeline = renderer.getRhiSkyBoxShader(tonemapMode, layer.skyBoxIsRgbe8);
813 QSSG_CHECK(shaderPipeline);
814 ps.shaderPipeline = shaderPipeline.get();
815 QRhiShaderResourceBindings *srb = layer.skyBoxSrb;
816 QRhiRenderPassDescriptor *rpDesc = rhiCtx->mainRenderPassDescriptor();
817 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, rpDesc, { QSSGRhiQuadRenderer::DepthTest | QSSGRhiQuadRenderer::RenderBehind });
818 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("skybox_map"));
819 }
820 ps.polygonMode = polygonMode;
821
822 // 3. Screen texture depended objects
823 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render screen texture dependent"));
824 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
825 Q_TRACE(QSSG_renderPass_entry, QStringLiteral("Quick3D render screen texture dependent"));
826 for (const auto &handle : std::as_const(sortedScreenTextureObjects)) {
827 QSSGRenderableObject *theObject = handle.obj;
828 rhiRenderRenderable(rhiCtx.get(), ps, *theObject, &needsSetViewport);
829 }
830 cb->debugMarkEnd();
831 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("screen_texture_dependent"));
832 Q_TRACE(QSSG_renderPass_exit);
833
834 // 4. Item2Ds
835 if (!item2Ds.isEmpty()) {
836 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render 2D sub-scene"));
837 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
838 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render 2D sub-scene"));
839 for (const auto &item : std::as_const(item2Ds)) {
840 QSSGRenderItem2D *item2D = static_cast<QSSGRenderItem2D *>(item);
841 if (item2D->m_renderer && item2D->m_renderer->currentRhi() == renderer.contextInterface()->rhi())
842 item2D->m_renderer->renderSceneInline();
843 }
844 cb->debugMarkEnd();
845 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("2D_sub_scene"));
846 }
847
848 // 5. Non-opaque objects
849 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render alpha"));
850 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
851 Q_TRACE(QSSG_renderPass_entry, QStringLiteral("Quick3D render alpha"));
852 // If scissorRect is set, Item2Ds will be drawn by a workaround of modifying
853 // viewport, not using actual 3D scissor test.
854 // It means non-opaque objects may be affected by this viewport setting.
855 needsSetViewport = true;
856 for (const auto &handle : std::as_const(sortedTransparentObjects)) {
857 QSSGRenderableObject *theObject = handle.obj;
859 rhiRenderRenderable(rhiCtx.get(), ps, *theObject, &needsSetViewport);
860 }
861 cb->debugMarkEnd();
862 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("transparent_pass"));
863 Q_TRACE(QSSG_renderPass_exit);
864
865 // 6. Infinite grid
866 if (layer.gridEnabled) {
867 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render grid"));
868 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
869 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render grid"));
870 const auto &shaderPipeline = renderer.getRhiGridShader();
871 Q_ASSERT(shaderPipeline);
872 ps.shaderPipeline = shaderPipeline.get();
873 QRhiShaderResourceBindings *srb = layer.gridSrb;
874 QRhiRenderPassDescriptor *rpDesc = rhiCtx->mainRenderPassDescriptor();
875 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, rpDesc, { QSSGRhiQuadRenderer::DepthTest });
876 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("render_grid"));
877 }
878
879 // 7. Debug Draw content
880 const auto &debugDraw = renderer.contextInterface()->debugDrawSystem();
881 if (debugDraw && debugDraw->hasContent()) {
882 cb->debugMarkBegin(QByteArrayLiteral("Quick 3D debug objects"));
883 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick 3D debug objects"));
884 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
885 auto shaderPipeline = renderer.getRhiDebugObjectShader();
886 QSSG_CHECK(shaderPipeline);
887 ps.shaderPipeline = shaderPipeline.get();
888 QSSGRhiDrawCallData &dcd = rhiCtx->drawCallData({ &layer, nullptr, nullptr, 0, QSSGRhiDrawCallDataKey::DebugObjects });
890 QRhiRenderPassDescriptor *rpDesc = rhiCtx->mainRenderPassDescriptor();
891 debugDraw->recordRenderDebugObjects(rhiCtx.get(), &ps, srb, rpDesc);
892 cb->debugMarkEnd();
893 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("debug_objects"));
894 }
895}
896
898{
899 ps = {};
900 shaderFeatures = {};
904 item2Ds.clear();
905}
906
908{
909 auto &frameData = data.getFrameData();
910 for (const auto &p : std::as_const(extensions)) {
911 p->prepareRender(renderer, frameData);
912 if (p->type() == QSSGRenderExtension::Type::Standalone)
913 p->render(renderer);
914 }
915}
916
918{
919 for (const auto &p : std::as_const(extensions)) {
920 if (p->type() == QSSGRenderExtension::Type::Main)
921 p->render(renderer);
922 }
923}
924
926{
927 for (const auto &p : std::as_const(extensions))
928 p->release();
929
930 // TODO: We should track if we need to update this list.
932}
933
QSSGRhiGraphicsPipelineState ps
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
QSSGRhiRenderableTexture rhiDepthTexture
QSSGRenderableObjectList sortedTransparentObjects
void release() final
void renderPass(QSSGRenderer &renderer) final
QSSGRenderableObjectList sortedOpaqueObjects
QVector< QSSGRenderItem2D * > item2Ds
void release() final
QSSGRenderableObjectList sortedScreenTextureObjects
QSSGShaderFeatures shaderFeatures
QSSGRhiGraphicsPipelineState ps
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
QSSGRenderableObjectList sortedOpaqueObjects
QSSGRenderableObjectList sortedTransparentObjects
void renderPass(QSSGRenderer &renderer) final
static QColor fromRgbF(float r, float g, float b, float a=1.0)
Static convenience function that returns a QColor constructed from the RGB color values,...
Definition qcolor.cpp:2427
bool isEmpty() const noexcept
Definition qlist.h:390
void push_back(parameter_type t)
Definition qlist.h:672
void clear()
Definition qlist.h:417
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
const float * constData() const
Returns a constant pointer to the raw data of this matrix.
Definition qmatrix4x4.h:147
\inmodule QtCore\reentrant
Definition qpoint.h:23
\inmodule QtCore\reentrant
Definition qrect.h:483
constexpr qreal height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:718
constexpr qreal width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:715
constexpr QPointF center() const noexcept
Returns the center point of the rectangle.
Definition qrect.h:685
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:238
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:235
constexpr QPoint center() const noexcept
Returns the center point of the rectangle.
Definition qrect.h:232
virtual char * beginFullDynamicBufferUpdateForCurrentFrame()
Definition qrhi.cpp:3844
@ Dynamic
Definition qrhi.h:839
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
@ UniformBuffer
Definition qrhi.h:845
virtual bool create()=0
Creates the corresponding native graphics resources.
\inmodule QtGui
Definition qrhi.h:1614
\inmodule QtGui
Definition qrhi.h:1119
\inmodule QtGui
Definition qrhi.h:1694
void generateMips(QRhiTexture *tex)
Enqueues a mipmap generation operation for the specified texture tex.
Definition qrhi.cpp:8812
QRhi * rhi() const
Definition qrhi.cpp:3477
\inmodule QtGui
Definition qrhi.h:1190
QRhiBuffer * newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
Definition qrhi.cpp:10079
@ TexelFetch
Definition qrhi.h:1814
void renderSceneInline() override
QRhi * currentRhi() const
static qsizetype frustumCulling(const QSSGClippingFrustum &clipFrustum, const QSSGRenderableObjectList &renderables, QSSGRenderableObjectList &visibleRenderables)
static QRhiCommandBuffer::BeginPassFlags commonPassFlags()
bool isEmpty() const
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void renderPass(QSSGRenderer &renderer) final
std::shared_ptr< QSSGRenderReflectionMap > reflectionMapManager
QSSGRenderableObjectList reflectionPassObjects
QVector< QSSGRenderReflectionProbe * > reflectionProbes
QSSGRhiGraphicsPipelineState ps
const QSSGRhiRenderableTexture * rhiDepthTexture
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void release() final
QSSGRhiShaderPipelinePtr ssaoShaderPipeline
void renderPass(QSSGRenderer &renderer) final
const QSSGRenderCamera * camera
QSSGRhiGraphicsPipelineState ps
QSSGRhiRenderableTexture rhiAoTexture
AmbientOcclusion ao
struct SSAOMapPass::AmbientOcclusion ambientOcclusion
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void renderPass(QSSGRenderer &renderer) final
QSSGRhiGraphicsPipelineState ps
void release() final
QSSGShaderFeatures shaderFeatures
QSSGRenderableObjectList sortedOpaqueObjects
QSSGRhiRenderableTexture rhiScreenTexture
QSSGRenderCamera * camera
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void release() final
QSSGShaderLightList globalLights
QSSGRenderableObjectList shadowPassObjects
QSSGRhiGraphicsPipelineState ps
QSSGBoxPoints castingObjectsBox
void renderPass(QSSGRenderer &renderer) final
std::shared_ptr< QSSGRenderShadowMap > shadowMapManager
QSSGBoxPoints receivingObjectsBox
void release() final
void renderPass(QSSGRenderer &renderer) final
QList< QSSGRenderExtension * > extensions
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void renderPass(QSSGRenderer &renderer) final
QSSGRenderableObjectList renderedOpaqueDepthPrepassObjects
QSSGRhiGraphicsPipelineState ps
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void release() final
QSSGRenderableObjectList renderedDepthWriteObjects
QCamera * camera
Definition camera.cpp:19
Combined button and popup list for selecting options.
@ transparent
Definition qnamespace.h:46
constexpr Initialization Uninitialized
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
EGLOutputLayerEXT layer
#define qWarning
Definition qlogging.h:162
GLuint64 GLenum void * handle
GLsizei samples
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat p
[1]
#define Q_QUICK3D_PROFILE_START(Type)
#define Q_QUICK3D_PROFILE_END_WITH_STRING(Type, Payload, Str)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QSSG_ASSERT_X(cond, msg, action)
#define QSSG_CHECK(cond)
#define QSSG_ASSERT(cond, action)
static QT_BEGIN_NAMESPACE QMatrix4x4 correctMVPForScissor(QRectF viewportRect, QRect scissorRect, bool isYUp)
#define QSSGRHICTX_STAT(ctx, f)
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define QStringLiteral(str)
#define Q_UNUSED(x)
#define Q_TRACE_SCOPE(x,...)
Definition qtrace_p.h:146
#define Q_TRACE(x,...)
Definition qtrace_p.h:144
QGraphicsItem * item
QSvgRenderer * renderer
[0]
QPointer< QSGRenderer > m_renderer
@ EnableDepthPrePass
True when we render a depth pass before.
QSSGRenderableObjectFlags renderableFlags
QRhiShaderResourceBindings * srb
QRhiGraphicsPipeline::PolygonMode polygonMode
QRhiGraphicsPipeline::CompareOp depthFunc
const QSSGRhiShaderPipeline * shaderPipeline
QRhiTextureRenderTarget * rt
QRhiRenderPassDescriptor * rpDesc
void addUniformBuffer(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiBuffer *buf, int offset, int size)