Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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#include "qssgrenderhelpers_p.h"
11
12#include "../utils/qssgassert_p.h"
13
14#include <QtQuick/private/qsgrenderer_p.h>
15#include <qtquick3d_tracepoints_p.h>
16
18
19static inline QMatrix4x4 correctMVPForScissor(QRectF viewportRect, QRect scissorRect, bool isYUp) {
20 const auto &scissorCenter = scissorRect.center();
21 const auto &viewCenter = viewportRect.center();
22 const float scaleX = viewportRect.width() / float(scissorRect.width());
23 const float scaleY = viewportRect.height() / float(scissorRect.height());
24 const float dx = 2 * (viewCenter.x() - scissorCenter.x()) / scissorRect.width();
25 const float dyRect = isYUp ? (scissorCenter.y() - viewCenter.y())
26 : (viewCenter.y() - scissorCenter.y());
27 const float dy = 2 * dyRect / scissorRect.height();
28
29 return QMatrix4x4(scaleX, 0.0f, 0.0f, dx,
30 0.0f, scaleY, 0.0f, dy,
31 0.0f, 0.0f, 1.0f, 0.0f,
32 0.0f, 0.0f, 0.0f, 1.0f);
33}
34
39
40// SHADOW PASS
41
43{
45 using namespace RenderHelpers;
46
47 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
48 camera = data.renderedCameras[0];
49
50 const auto &renderedDepthWriteObjects = data.getSortedRenderedDepthWriteObjects(*camera);
51 const auto &renderedOpaqueDepthPrepassObjects = data.getSortedrenderedOpaqueDepthPrepassObjects(*camera);
52
54
55 for (const auto &handles : { &renderedDepthWriteObjects, &renderedOpaqueDepthPrepassObjects }) {
56 for (const auto &handle : *handles) {
57 if (handle.obj->renderableFlags.castsShadows())
59 }
60 }
61
62 globalLights = data.globalLights;
63
65
66 if (enabled) {
67 shadowMapManager = data.requestShadowMapManager();
68
69 ps = data.getPipelineState();
71 // Try reducing self-shadowing and artifacts.
72 ps.depthBias = 2;
74
75 const auto &sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects(*camera);
76 const auto &sortedTransparentObjects = data.getSortedTransparentRenderableObjects(*camera);
77 const auto [casting, receiving] = calculateSortedObjectBounds(sortedOpaqueObjects,
78 sortedTransparentObjects);
79 castingObjectsBox = casting;
80 receivingObjectsBox = receiving;
81 }
82}
83
85{
86 using namespace RenderHelpers;
87
88 // INPUT: Sorted opaque and transparent + depth, global lights (scoped lights not supported) and camera.
89
90 // DEPENDECY: None
91
92 // OUTPUT: Textures or cube maps
93
94 // CONDITION: Lights (shadowPassObjects)
95
96 if (enabled) {
97 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
98 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
99 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
100 cb->debugMarkBegin(QByteArrayLiteral("Quick3D shadow map"));
101 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D shadow map"));
102 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
103
105 rhiRenderShadowMap(rhiCtx.get(),
106 this,
107 ps,
109 *camera,
110 globalLights, // scoped lights are not relevant here
112 renderer,
115
116 cb->debugMarkEnd();
117 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("shadow_map"));
118 }
119}
120
122{
123 enabled = false;
124 camera = nullptr;
127 ps = {};
130}
131
132// REFLECTIONMAP PASS
133
135{
137 Q_UNUSED(data);
138
139 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
140 QSSGRenderCamera *camera = data.renderedCameras[0];
141
142 ps = data.getPipelineState();
146
147 reflectionProbes = data.reflectionProbes;
148 reflectionMapManager = data.requestReflectionMapManager();
149
150 const auto &sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects(*camera);
151 const auto &sortedTransparentObjects = data.getSortedTransparentRenderableObjects(*camera);
152 const auto &sortedScreenTextureObjects = data.getSortedScreenTextureRenderableObjects(*camera);
153
155
156 // NOTE: We should consider keeping track of the reflection casting objects to avoid
157 // filtering this list on each prep.
158 for (const auto &handles : { &sortedOpaqueObjects, &sortedTransparentObjects, &sortedScreenTextureObjects }) {
159 for (const auto &handle : *handles) {
160 if (handle.obj->renderableFlags.testFlag(QSSGRenderableObjectFlag::CastsReflections))
162 }
163 }
164}
165
167{
168 using namespace RenderHelpers;
169
170 // INPUT: Reflection probes, sorted opaque and transparent
171
172 // DEPENDECY: None
173
174 // OUTPUT: Cube maps (1 per probe)
175
176 // NOTE: Full pass with a sky box pass
177
178 // CONDITION: Probes and sorted opaque and transparent
179
180 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
181 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
182 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
183
184 const auto *layerData = QSSGLayerRenderData::getCurrent(renderer);
185 QSSG_ASSERT(layerData, return);
186
189 cb->debugMarkBegin(QByteArrayLiteral("Quick3D reflection map"));
190 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D reflection map"));
191 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
192 rhiRenderReflectionMap(rhiCtx.get(),
193 this,
194 *layerData,
195 &ps,
199 renderer);
200
201 cb->debugMarkEnd();
202 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("reflection_map"));
203 }
204}
205
212
213// ZPrePass
215{
216 using namespace RenderHelpers;
217
218 // INPUT: Item2Ds + depth write + depth prepass
219
220 // DEPENDECY: none
221
222 // OUTPUT: Depth buffer attchment for current target
223
224 // NOTE: Could we make the depth pass more complete and just do a blit here?
225 //
226 // 1. If we have a depth map, just do a blit and then update with the rest
227 // 2. If we don't have a depth map (and/or SSAO) consider using a lower lod level.
228
229 // CONDITION: Input + globally enabled or ?
230
231 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
232 QSSGRenderCamera *camera = data.renderedCameras[0];
233
234 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
235 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
236 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
237 ps = data.getPipelineState();
238
239 renderedDepthWriteObjects = data.getSortedRenderedDepthWriteObjects(*camera);
240 renderedOpaqueDepthPrepassObjects = data.getSortedrenderedOpaqueDepthPrepassObjects(*camera);
241
242 cb->debugMarkBegin(QByteArrayLiteral("Quick3D prepare Z prepass"));
243 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D prepare Z prepass"));
244 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
245 active = rhiPrepareDepthPass(rhiCtx.get(), this, ps, rhiCtx->mainRenderPassDescriptor(), data,
247 rhiCtx->mainPassSampleCount(), rhiCtx->mainPassViewCount());
248 data.setZPrePassPrepResult(active);
249 cb->debugMarkEnd();
250 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("prepare_z_prepass"));
251}
252
254{
255 using namespace RenderHelpers;
256
257 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
258 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
259
260 bool needsSetViewport = true;
261 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
262
263 if (active) {
264 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
265 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render Z prepass"));
266 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render Z prepass"));
267 rhiRenderDepthPass(rhiCtx.get(), ps, renderedDepthWriteObjects, renderedOpaqueDepthPrepassObjects, &needsSetViewport);
268 cb->debugMarkEnd();
269 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("render_z_prepass"));
270 }
271}
272
280
281// SSAO PASS
283{
284 using namespace RenderHelpers;
285
286 // Assumption for now is that all passes are keept alive and only reset once a frame is done.
287 // I.e., holding data like this should be safe (If that's no longer the case we need to do ref counting
288 // for shared data).
289
290 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
291 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
292
295 QSSG_ASSERT_X(!data.renderedCameras.isEmpty(), "Preparing AO pass failed, missing camera", return);
296 camera = data.renderedCameras[0];
297 QSSG_ASSERT_X((rhiDepthTexture && rhiDepthTexture->isValid()), "Preparing AO pass failed, missing equired texture(s)", return);
298
299 const auto &shaderCache = renderer.contextInterface()->shaderCache();
300 ssaoShaderPipeline = shaderCache->getBuiltInRhiShaders().getRhiSsaoShader(rhiCtx->mainPassViewCount());
301 aoSettings = { data.layer.aoStrength, data.layer.aoDistance, data.layer.aoSoftness, data.layer.aoBias, data.layer.aoSamplerate, data.layer.aoDither };
302
303 ps = data.getPipelineState();
304 const auto &layerPrepResult = data.layerPrepResult;
305 const bool ready = rhiAoTexture && rhiPrepareAoTexture(rhiCtx.get(), layerPrepResult.textureDimensions(), rhiAoTexture);
306
307 if (Q_UNLIKELY(!ready))
308 rhiAoTexture = nullptr;
309}
310
312{
313 using namespace RenderHelpers;
314
315 // INPUT: Camera + depth map
316
317 // DEPENDECY: Depth map (zprepass)
318
319 // OUTPUT: AO Texture
320
321 // NOTE:
322
323 // CONDITION: SSAO enabled
325
326 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
327 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
328
329 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
330 cb->debugMarkBegin(QByteArrayLiteral("Quick3D SSAO map"));
331 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D SSAO map"));
332 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
333
335 rhiRenderAoTexture(rhiCtx.get(),
336 this,
337 renderer,
339 ps,
343 *camera);
344 }
345
346 cb->debugMarkEnd();
347 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("ssao_map"));
348}
349
351{
352 rhiDepthTexture = nullptr;
353 rhiAoTexture = nullptr;
354 camera = nullptr;
355 ps = {};
356 aoSettings = {};
357}
358
359// DEPTH TEXTURE PASS
361{
362 using namespace RenderHelpers;
363
364 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
365 QSSGRenderCamera *camera = data.renderedCameras[0];
366
367 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
368 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
369 const auto &layerPrepResult = data.layerPrepResult;
370 bool ready = false;
371 ps = data.getPipelineState();
373 if (Q_LIKELY(rhiDepthTexture && rhiPrepareDepthTexture(rhiCtx.get(), layerPrepResult.textureDimensions(), rhiDepthTexture))) {
374 sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects(*camera);
375 sortedTransparentObjects = data.getSortedTransparentRenderableObjects(*camera);
376 // the depth texture is always non-MSAA, but is a 2D array with multiview
377 ready = rhiPrepareDepthPass(rhiCtx.get(), this, ps, rhiDepthTexture->rpDesc, data,
379 1, rhiCtx->mainPassViewCount());
380 }
381
382 if (Q_UNLIKELY(!ready))
383 rhiDepthTexture = nullptr;
384}
385
387{
388 using namespace RenderHelpers;
389
390 // INPUT: sorted objects (opaque + transparent) (maybe...)
391
392 // DEPENDECY: If this is only used for the AO case, that dictates if this should be done or not.
393
394 // OUTPUT: Texture
395
396 // NOTE: Why are we prepping opaque + transparent object if we're not using them? And why are we staying compatible with 5.15?
397 // Only used for AO? Merge into the AO pass?
398
399 // NOTES:
400 //
401 // 1: If requested, use this and blit it in the z-pre pass.
402 // 2. Why are we handling the transparent objects in the render prep (only)?
403
404 // CONDITION:
405
406 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
407 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
408 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
409 cb->debugMarkBegin(QByteArrayLiteral("Quick3D depth texture"));
410
412 bool needsSetViewport = true;
413 cb->beginPass(rhiDepthTexture->rt, Qt::transparent, { 1.0f, 0 }, nullptr, rhiCtx->commonPassFlags());
414 QSSGRHICTX_STAT(rhiCtx, beginRenderPass(rhiDepthTexture->rt));
415 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
416 // NB! We do not pass sortedTransparentObjects in the 4th
417 // argument to stay compatible with the 5.15 code base,
418 // which also does not include semi-transparent objects in
419 // the depth texture. In addition, capturing after the
420 // opaque pass, not including transparent objects, is part
421 // of the contract for screen reading custom materials,
422 // both for depth and color.
423 rhiRenderDepthPass(rhiCtx.get(), ps, sortedOpaqueObjects, {}, &needsSetViewport);
424 cb->endPass();
425 QSSGRHICTX_STAT(rhiCtx, endRenderPass());
426 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("depth_texture"));
427 }
428
429 cb->debugMarkEnd();
430}
431
439
440// SCREEN TEXTURE PASS
441
443{
444 using namespace RenderHelpers;
445
446 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
447 QSSGRenderCamera *camera = data.renderedCameras[0];
448
449 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
450 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
452 auto &layer = data.layer;
453 const auto &layerPrepResult = data.layerPrepResult;
454 wantsMips = layerPrepResult.flags.requiresMipmapsForScreenTexture();
455 sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects(*camera);
456 ps = data.getPipelineState();
457 ps.samples = 1; // screen texture is always non-MSAA
458 ps.viewCount = rhiCtx->mainPassViewCount(); // but is a 2D texture array when multiview
459
461 clearColor = QColor::fromRgbF(layer.clearColor.x(), layer.clearColor.y(), layer.clearColor.z());
462
463 if (rhiCtx->rhi()->isFeatureSupported(QRhi::TexelFetch)) {
464 if (layer.background == QSSGRenderLayer::Background::SkyBoxCubeMap && layer.skyBoxCubeMap) {
467
468 skyboxCubeMapPass->skipTonemapping = true;
469 skyboxCubeMapPass->renderPrep(renderer, data);
470
471 // The pass expects to output to the main render target, but we have
472 // our own texture here, possibly with a differing sample count, so
473 // override the relevant settings once renderPrep() is done.
474 skyboxCubeMapPass->ps.samples = ps.samples;
475
476 skyboxPass = std::nullopt;
477 } else if (layer.background == QSSGRenderLayer::Background::SkyBox && layer.lightProbe) {
478 if (!skyboxPass)
480
481 skyboxPass->skipTonemapping = true;
482 skyboxPass->renderPrep(renderer, data);
483
484 skyboxPass->ps.samples = ps.samples;
485
486 skyboxCubeMapPass = std::nullopt;
487 }
488 }
489
490 bool ready = false;
491 if (Q_LIKELY(rhiScreenTexture && rhiPrepareScreenTexture(rhiCtx.get(), layerPrepResult.textureDimensions(), wantsMips, rhiScreenTexture))) {
492 ready = true;
495 if (skyboxPass)
497 // NB: not compatible with disabling LayerEnableDepthTest
498 // because there are effectively no "opaque" objects then.
499 // Disable Tonemapping for all materials in the screen pass texture
500 shaderFeatures = data.getShaderFeatures();
502 const auto &sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects(*camera);
503 for (const auto &handle : sortedOpaqueObjects) {
504 // Reflection cube maps are not available at this point, make sure they are turned off.
505 bool recRef = handle.obj->renderableFlags.receivesReflections();
506 handle.obj->renderableFlags.setReceivesReflections(false);
507 rhiPrepareRenderable(rhiCtx.get(), this, data, *handle.obj, rhiScreenTexture->rpDesc, &ps, shaderFeatures, 1, rhiCtx->mainPassViewCount());
508 handle.obj->renderableFlags.setReceivesReflections(recRef);
509 }
510 }
511
512 if (Q_UNLIKELY(!ready))
513 rhiScreenTexture = nullptr;
514}
515
517{
518 using namespace RenderHelpers;
519
520 // INPUT: Sorted opaque objects + depth objects
521
522 // DEPENDECY: Depth pass (if enabled)
523
524 // OUTPUT: Texture (screen texture).
525
526 // NOTE: Used for refrection and effects (?)
527
528 // CONDITION:
529
530 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
531 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
532 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
533
534 cb->debugMarkBegin(QByteArrayLiteral("Quick3D screen texture"));
535
537 cb->beginPass(rhiScreenTexture->rt, clearColor, { 1.0f, 0 }, nullptr, rhiCtx->commonPassFlags());
538 QSSGRHICTX_STAT(rhiCtx, beginRenderPass(rhiScreenTexture->rt));
539 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
540
541 bool needsSetViewport = true;
542 for (const auto &handle : std::as_const(sortedOpaqueObjects))
543 rhiRenderRenderable(rhiCtx.get(), ps, *handle.obj, &needsSetViewport);
544
546 skyboxCubeMapPass->renderPass(renderer);
547 else if (skyboxPass)
548 skyboxPass->renderPass(renderer);
549
550 QRhiResourceUpdateBatch *rub = nullptr;
551 if (wantsMips) {
552 rub = rhiCtx->rhi()->nextResourceUpdateBatch();
554 }
555 cb->endPass(rub);
556 QSSGRHICTX_STAT(rhiCtx, endRenderPass());
557 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("screen_texture"));
558 }
559
560 cb->debugMarkEnd();
561}
562
564{
565 rhiScreenTexture = nullptr;
566 if (skyboxPass)
567 skyboxPass->resetForFrame();
569 skyboxCubeMapPass->resetForFrame();
570 ps = {};
571 wantsMips = false;
573 shaderFeatures = {};
575}
576
578{
579 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
580 QSSGRenderCamera *camera = data.renderedCameras[0];
581
582 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
583 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
585 QSSG_ASSERT_X(rhiScreenTexture && rhiScreenTexture->isValid(), "Invalid screen texture!", return);
586
587 const auto &layer = data.layer;
588 const auto shaderFeatures = data.getShaderFeatures();
589 const bool layerEnableDepthTest = layer.layerFlags.testFlag(QSSGRenderLayer::LayerFlag::EnableDepthTest);
590
591 QRhiRenderPassDescriptor *mainRpDesc = rhiCtx->mainRenderPassDescriptor();
592 const int samples = rhiCtx->mainPassSampleCount();
593 const int viewCount = rhiCtx->mainPassViewCount();
594
595 // NOTE: We're piggybacking on the screen map pass for now, but we could do better.
596 ps = data.getPipelineState();
597 const bool depthTestEnabled = (data.screenMapPass.ps.flags.testFlag(QSSGRhiGraphicsPipelineState::Flag::DepthTestEnabled));
599 const bool depthWriteEnabled = (data.screenMapPass.ps.flags.testFlag(QSSGRhiGraphicsPipelineState::Flag::DepthWriteEnabled));
601 sortedScreenTextureObjects = data.getSortedScreenTextureRenderableObjects(*camera);
602 for (const auto &handle : std::as_const(sortedScreenTextureObjects)) {
603 QSSGRenderableObject *theObject = handle.obj;
604 const auto depthWriteMode = theObject->depthWriteMode;
605 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled, theObject->renderableFlags.hasTransparency());
606 const bool curDepthWriteEnabled = !(depthWriteMode == QSSGDepthDrawMode::Never || depthWriteMode == QSSGDepthDrawMode::OpaquePrePass
607 || data.isZPrePassActive() || !layerEnableDepthTest);
609 RenderHelpers::rhiPrepareRenderable(rhiCtx.get(), this, data, *theObject, mainRpDesc, &ps, shaderFeatures, samples, viewCount);
610 }
611}
612
614{
616 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
617 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
618 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
619
620 // 3. Screen texture depended objects
621 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render screen texture dependent"));
622 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
623 Q_TRACE(QSSG_renderPass_entry, QStringLiteral("Quick3D render screen texture dependent"));
624 bool needsSetViewport = true;
625 for (const auto &handle : std::as_const(sortedScreenTextureObjects)) {
626 QSSGRenderableObject *theObject = handle.obj;
627 RenderHelpers::rhiRenderRenderable(rhiCtx.get(), ps, *theObject, &needsSetViewport);
628 }
629 cb->debugMarkEnd();
630 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("screen_texture_dependent"));
631 Q_TRACE(QSSG_renderPass_exit);
632 }
633}
634
641
644 QSSGPassKey passKey,
646 QSSGShaderFeatures shaderFeatures,
648 const QSSGRenderableObjectList &sortedOpaqueObjects)
649{
650 const auto &rhiCtx = ctx.rhiContext();
651 QSSG_ASSERT(rpDesc && rhiCtx->rhi()->isRecordingFrame(), return);
652
653 const auto &layer = data.layer;
654 const bool layerEnableDepthTest = layer.layerFlags.testFlag(QSSGRenderLayer::LayerFlag::EnableDepthTest);
655
656 for (const auto &handle : std::as_const(sortedOpaqueObjects)) {
657 QSSGRenderableObject *theObject = handle.obj;
658 const auto depthWriteMode = theObject->depthWriteMode;
659 const bool curDepthWriteEnabled = !(depthWriteMode == QSSGDepthDrawMode::Never ||
660 depthWriteMode == QSSGDepthDrawMode::OpaquePrePass ||
661 data.isZPrePassActive() || !layerEnableDepthTest);
663 RenderHelpers::rhiPrepareRenderable(rhiCtx.get(), passKey, data, *theObject, rpDesc, &ps, shaderFeatures, ps.samples, ps.viewCount);
664 }
665}
666
669 const QSSGRenderableObjectList &sortedOpaqueObjects)
670{
671 const auto &rhiCtx = ctx.rhiContext();
672 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
673 bool needsSetViewport = true;
674 for (const auto &handle : std::as_const(sortedOpaqueObjects)) {
675 QSSGRenderableObject *theObject = handle.obj;
676 RenderHelpers::rhiRenderRenderable(rhiCtx.get(), ps, *theObject, &needsSetViewport);
677 }
678}
679
681{
682 auto *ctx = renderer.contextInterface();
683 const auto &rhiCtx = ctx->rhiContext();
684 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
685 QSSG_ASSERT(!data.renderedCameras.isEmpty() && data.renderedCameraData.has_value() , return);
686 QSSGRenderCamera *camera = data.renderedCameras[0];
687
688 ps = data.getPipelineState();
689 ps.samples = rhiCtx->mainPassSampleCount();
690 ps.viewCount = rhiCtx->mainPassViewCount();
693
694 // opaque objects (or, this list is empty when LayerEnableDepthTest is disabled)
695 sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects(*camera);
696 shaderFeatures = data.getShaderFeatures();
697
698 QRhiRenderPassDescriptor *mainRpDesc = rhiCtx->mainRenderPassDescriptor();
699 prep(*ctx, data, this, ps, shaderFeatures, mainRpDesc, sortedOpaqueObjects);
700}
701
703{
704 auto *ctx = renderer.contextInterface();
705 const auto &rhiCtx = ctx->rhiContext();
706 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
707 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
708
709 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render opaque"));
710 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
711 Q_TRACE(QSSG_renderPass_entry, QStringLiteral("Quick3D render opaque"));
713 cb->debugMarkEnd();
714 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("opaque_pass"));
715 Q_TRACE(QSSG_renderPass_exit);
716}
717
719{
721 ps = {};
722 shaderFeatures = {};
723}
724
727 QSSGPassKey passKey,
729 QSSGShaderFeatures shaderFeatures,
731 const QSSGRenderableObjectList &sortedTransparentObjects)
732{
733 const auto &rhiCtx = ctx.rhiContext();
734 QSSG_ASSERT(rpDesc && rhiCtx->rhi()->isRecordingFrame(), return);
735
736 const bool zPrePassActive = data.isZPrePassActive();
737 for (const auto &handle : std::as_const(sortedTransparentObjects)) {
738 QSSGRenderableObject *theObject = handle.obj;
739 const auto depthWriteMode = theObject->depthWriteMode;
740 const bool curDepthWriteEnabled = (depthWriteMode == QSSGDepthDrawMode::Always && !zPrePassActive);
742 if (!(theObject->renderableFlags.isCompletelyTransparent()))
743 RenderHelpers::rhiPrepareRenderable(rhiCtx.get(), passKey, data, *theObject, rpDesc, &ps, shaderFeatures, ps.samples, ps.viewCount);
744 }
745}
746
749 const QSSGRenderableObjectList &sortedTransparentObjects)
750{
751 const auto &rhiCtx = ctx.rhiContext();
752 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
753 // If scissorRect is set, Item2Ds will be drawn by a workaround of modifying
754 // viewport, not using actual 3D scissor test.
755 // It means non-opaque objects may be affected by this viewport setting.
756 bool needsSetViewport = true;
757 for (const auto &handle : std::as_const(sortedTransparentObjects)) {
758 QSSGRenderableObject *theObject = handle.obj;
759 if (!theObject->renderableFlags.isCompletelyTransparent())
760 RenderHelpers::rhiRenderRenderable(rhiCtx.get(), ps, *theObject, &needsSetViewport);
761 }
762}
763
765{
766 auto *ctx = renderer.contextInterface();
767 const auto &rhiCtx = ctx->rhiContext();
768
769 QSSG_ASSERT(!data.renderedCameras.isEmpty() && data.renderedCameraData.has_value() , return);
770 QSSGRenderCamera *camera = data.renderedCameras[0];
771
772 QRhiRenderPassDescriptor *mainRpDesc = rhiCtx->mainRenderPassDescriptor();
773
774 ps = data.getPipelineState();
775 ps.samples = rhiCtx->mainPassSampleCount();
776 ps.viewCount = rhiCtx->mainPassViewCount();
777
778 // transparent objects (or, without LayerEnableDepthTest, all objects)
781
782 shaderFeatures = data.getShaderFeatures();
783 sortedTransparentObjects = data.getSortedTransparentRenderableObjects(*camera);
784
785 prep(*ctx, data, this, ps, shaderFeatures, mainRpDesc, sortedTransparentObjects);
786}
787
789{
790 auto *ctx = renderer.contextInterface();
791 const auto &rhiCtx = ctx->rhiContext();
792 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
793 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
794
795 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render alpha"));
796 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
797 Q_TRACE(QSSG_renderPass_entry, QStringLiteral("Quick3D render alpha"));
799 cb->debugMarkEnd();
800 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("transparent_pass"));
801 Q_TRACE(QSSG_renderPass_exit);
802}
803
810
812{
813 if (!skipPrep) {
814 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
815 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
816 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
817 QSSG_ASSERT(data.renderedCameras.count() == rhiCtx->mainPassViewCount(), return);
818 layer = &data.layer;
819 QSSG_ASSERT(layer, return);
820
821 rpDesc = rhiCtx->mainRenderPassDescriptor();
822 ps = data.getPipelineState();
823 ps.samples = rhiCtx->mainPassSampleCount();
824 ps.viewCount = rhiCtx->mainPassViewCount();
826
827 // When there are effects, then it is up to the last pass of the
828 // last effect to perform tonemapping, neither the skybox nor the
829 // main render pass should alter the colors then.
830 skipTonemapping = layer->firstEffect != nullptr;
831
832 RenderHelpers::rhiPrepareSkyBox(rhiCtx.get(), this, *layer, data.renderedCameras, renderer);
833 skipPrep = true;
834 }
835}
836
838{
839 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
840 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
841 QSSG_ASSERT(layer, return);
842
843 QRhiShaderResourceBindings *srb = layer->skyBoxSrb;
844 QSSG_ASSERT(srb, return);
845
846 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
847 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render skybox"));
848
849 // Note: We get the shader here, as the screen map pass might modify the state of
850 // the tonemap mode.
851
853 const auto &shaderCache = renderer.contextInterface()->shaderCache();
854 auto shaderPipeline = shaderCache->getBuiltInRhiShaders().getRhiSkyBoxShader(tonemapMode, layer->skyBoxIsRgbe8, rhiCtx->mainPassViewCount());
855 QSSG_CHECK(shaderPipeline);
857 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, rpDesc, { QSSGRhiQuadRenderer::DepthTest | QSSGRhiQuadRenderer::RenderBehind });
858 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("skybox_map"));
859}
860
862{
863 ps = {};
864 layer = nullptr;
865 skipPrep = false;
866}
867
869{
870 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
871 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
872 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
873 QSSG_ASSERT(data.renderedCameras.count() == rhiCtx->mainPassViewCount(), return);
874 layer = &data.layer;
875 QSSG_ASSERT(layer, return);
876
877 rpDesc = rhiCtx->mainRenderPassDescriptor();
878 ps = data.getPipelineState();
879 ps.samples = rhiCtx->mainPassSampleCount();
880 ps.viewCount = rhiCtx->mainPassViewCount();
882
883 const auto &shaderCache = renderer.contextInterface()->shaderCache();
884 skyBoxCubeShader = shaderCache->getBuiltInRhiShaders().getRhiSkyBoxCubeShader(rhiCtx->mainPassViewCount());
885
886 RenderHelpers::rhiPrepareSkyBox(rhiCtx.get(), this, *layer, data.renderedCameras, renderer);
887}
888
890{
891 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
892 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
894
895 QRhiShaderResourceBindings *srb = layer->skyBoxSrb;
896 QSSG_ASSERT(srb, return);
897
898 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
899 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render skybox"));
900
902 renderer.rhiCubeRenderer()->recordRenderCube(rhiCtx.get(), &ps, srb, rpDesc, { QSSGRhiQuadRenderer::DepthTest | QSSGRhiQuadRenderer::RenderBehind });
903 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("skybox_cube"));
904}
905
907{
908 ps = {};
909 layer = nullptr;
910}
911
913{
914 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
915 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
916 const auto &layer = data.layer;
917
918 ps = data.getPipelineState();
919
920 // objects rendered by Qt Quick 2D
922
923 item2Ds = data.getRenderableItem2Ds();
924 for (const auto &item2D: std::as_const(item2Ds)) {
925 // Set the projection matrix
926 if (!item2D->m_renderer)
927 continue;
928 if (item2D->m_renderer && item2D->m_renderer->currentRhi() != renderer.contextInterface()->rhiContext()->rhi()) {
929 static bool contextWarningShown = false;
930 if (!contextWarningShown) {
931 qWarning () << "Scene with embedded 2D content can only be rendered in one window.";
932 contextWarningShown = true;
933 }
934 continue;
935 }
936
937 auto layerPrepResult = data.layerPrepResult;
938
939 QRhiRenderTarget *renderTarget = rhiCtx->renderTarget();
940 item2D->m_renderer->setDevicePixelRatio(renderTarget->devicePixelRatio());
941 const QRect deviceRect(QPoint(0, 0), renderTarget->pixelSize());
942 const int viewCount = rhiCtx->mainPassViewCount();
943 QSSG_ASSERT(item2D->mvps.count() == viewCount, return);
944 if (layer.scissorRect.isValid()) {
945 QRect effScissor = layer.scissorRect & layerPrepResult.viewport.toRect();
946 QMatrix4x4 correctionMat = correctMVPForScissor(layerPrepResult.viewport,
947 effScissor,
948 rhiCtx->rhi()->isYUpInNDC());
949 for (int viewIndex = 0; viewIndex < viewCount; ++viewIndex) {
950 const QMatrix4x4 projectionMatrix = correctionMat * item2D->mvps[viewIndex];
951 item2D->m_renderer->setProjectionMatrix(projectionMatrix, viewIndex);
952 }
953 item2D->m_renderer->setViewportRect(effScissor);
954 } else {
955 for (int viewIndex = 0; viewIndex < viewCount; ++viewIndex)
956 item2D->m_renderer->setProjectionMatrix(item2D->mvps[viewIndex], viewIndex);
957 item2D->m_renderer->setViewportRect(RenderHelpers::correctViewportCoordinates(layerPrepResult.viewport, deviceRect));
958 }
959 item2D->m_renderer->setDeviceRect(deviceRect);
960 QRhiRenderPassDescriptor *oldRp = nullptr;
961 if (item2D->m_rp) {
962 // Changing render target, and so incompatible renderpass
963 // descriptors should be uncommon, but possible.
964 if (!item2D->m_rp->isCompatible(rhiCtx->mainRenderPassDescriptor()))
965 std::swap(item2D->m_rp, oldRp);
966 }
967 if (!item2D->m_rp) {
968 // Do not pass our object to the Qt Quick scenegraph. It may
969 // hold on to it, leading to lifetime and ownership issues.
970 // Rather, create a dedicated, compatible object.
971 item2D->m_rp = rhiCtx->mainRenderPassDescriptor()->newCompatibleRenderPassDescriptor();
972 QSSG_CHECK(item2D->m_rp);
973 }
974 QSGRenderTarget sgRt(renderTarget, item2D->m_rp, rhiCtx->commandBuffer());
975 sgRt.multiViewCount = rhiCtx->mainPassViewCount();
976 item2D->m_renderer->setRenderTarget(sgRt);
977 delete oldRp;
978 item2D->m_renderer->prepareSceneInline();
979 }
980}
981
983{
984 QSSG_ASSERT(!item2Ds.isEmpty(), return);
985
986 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
987 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
988 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
989
990 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render 2D sub-scene"));
991 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
992 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render 2D sub-scene"));
993 for (const auto &item : std::as_const(item2Ds)) {
994 QSSGRenderItem2D *item2D = static_cast<QSSGRenderItem2D *>(item);
995 if (item2D->m_renderer && item2D->m_renderer->currentRhi() == renderer.contextInterface()->rhiContext()->rhi())
996 item2D->m_renderer->renderSceneInline();
997 }
998 cb->debugMarkEnd();
999 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("2D_sub_scene"));
1000}
1001
1003{
1004 item2Ds.clear();
1005 ps = {};
1006}
1007
1009{
1010 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
1011 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
1012 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
1013 QSSG_ASSERT(data.renderedCameras.count() == rhiCtx->mainPassViewCount(), return);
1014 layer = &data.layer;
1015 QSSG_ASSERT(layer, return);
1016
1017 const auto &shaderCache = renderer.contextInterface()->shaderCache();
1018 gridShader = shaderCache->getBuiltInRhiShaders().getRhiGridShader(rhiCtx->mainPassViewCount());
1019
1020 ps = data.getPipelineState();
1021 ps.samples = rhiCtx->mainPassSampleCount();
1022 ps.viewCount = rhiCtx->mainPassViewCount();
1024
1025 RenderHelpers::rhiPrepareGrid(rhiCtx.get(), this, *layer, data.renderedCameras, renderer);
1026}
1027
1029{
1030 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
1031 QSSG_ASSERT(gridShader && rhiCtx->rhi()->isRecordingFrame(), return);
1032 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
1033
1034 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render grid"));
1035 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
1036 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render grid"));
1038 QRhiShaderResourceBindings *srb = layer->gridSrb;
1039 QRhiRenderPassDescriptor *rpDesc = rhiCtx->mainRenderPassDescriptor();
1040 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, rpDesc, { QSSGRhiQuadRenderer::DepthTest });
1041 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("render_grid"));
1042}
1043
1045{
1046 ps = {};
1047 layer = nullptr;
1048}
1049
1051{
1052 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
1053 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
1054 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx.get());
1055 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
1056 QSSG_ASSERT(data.renderedCameras.count() == rhiCtx->mainPassViewCount(), return);
1057
1058 const auto &shaderCache = renderer.contextInterface()->shaderCache();
1059 debugObjectShader = shaderCache->getBuiltInRhiShaders().getRhiDebugObjectShader();
1060 ps = data.getPipelineState();
1061
1062 // debug objects
1063 const auto &debugDraw = renderer.contextInterface()->debugDrawSystem();
1064 if (debugDraw && debugDraw->hasContent()) {
1065 QRhi *rhi = rhiCtx->rhi();
1067 debugDraw->prepareGeometry(rhiCtx.get(), rub);
1068 QSSGRhiDrawCallData &dcd = rhiCtxD->drawCallData({ this, nullptr, nullptr, 0 });
1069 if (!dcd.ubuf) {
1070 dcd.ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64 * data.renderedCameras.count());
1071 dcd.ubuf->create();
1072 }
1073 char *ubufData = dcd.ubuf->beginFullDynamicBufferUpdateForCurrentFrame();
1074 for (qsizetype viewIdx = 0; viewIdx < data.renderedCameras.count(); ++viewIdx) {
1075 QMatrix4x4 viewProjection(Qt::Uninitialized);
1076 data.renderedCameras[viewIdx]->calculateViewProjectionMatrix(viewProjection);
1077 viewProjection = rhi->clipSpaceCorrMatrix() * viewProjection;
1078 memcpy(ubufData, viewProjection.constData() + viewIdx * 64, 64);
1079 }
1080 dcd.ubuf->endFullDynamicBufferUpdateForCurrentFrame();
1081
1084 dcd.srb = rhiCtxD->srb(bindings);
1085
1086 rhiCtx->commandBuffer()->resourceUpdate(rub);
1087 }
1088}
1089
1091{
1092 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
1093 QSSG_ASSERT(debugObjectShader && rhiCtx->rhi()->isRecordingFrame(), return);
1094 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
1095 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx.get());
1096
1097 const auto &debugDraw = renderer.contextInterface()->debugDrawSystem();
1098 if (debugDraw && debugDraw->hasContent()) {
1099 cb->debugMarkBegin(QByteArrayLiteral("Quick 3D debug objects"));
1100 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick 3D debug objects"));
1101 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
1103 QSSGRhiDrawCallData &dcd = rhiCtxD->drawCallData({ this, nullptr, nullptr, 0 });
1104 QRhiShaderResourceBindings *srb = dcd.srb;
1105 QRhiRenderPassDescriptor *rpDesc = rhiCtx->mainRenderPassDescriptor();
1106 debugDraw->recordRenderDebugObjects(rhiCtx.get(), &ps, srb, rpDesc);
1107 cb->debugMarkEnd();
1108 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("debug_objects"));
1109 }
1110}
1111
1113{
1114 ps = {};
1115}
1116
1118{
1120 auto &frameData = data.getFrameData();
1121 for (const auto &p : std::as_const(extensions)) {
1122 p->prepareRender(frameData);
1124 p->render(frameData);
1125 }
1126}
1127
1129{
1131 QSSG_ASSERT(data, return);
1132 auto &frameData = data->getFrameData();
1133 for (const auto &p : std::as_const(extensions)) {
1135 p->render(frameData);
1136 }
1137}
1138
1140{
1141 for (const auto &p : std::as_const(extensions))
1142 p->resetForFrame();
1143
1144 // TODO: We should track if we need to update this list.
1145 extensions.clear();
1146}
1147
QSSGRhiShaderPipelinePtr debugObjectShader
QSSGRhiGraphicsPipelineState ps
void renderPass(QSSGRenderer &renderer) final
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void resetForFrame() final
void resetForFrame() final
QSSGRhiRenderableTexture * rhiDepthTexture
QSSGRhiGraphicsPipelineState ps
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
QSSGRenderableObjectList sortedTransparentObjects
void renderPass(QSSGRenderer &renderer) final
QSSGRenderableObjectList sortedOpaqueObjects
void renderPass(QSSGRenderer &renderer) final
QSSGRhiGraphicsPipelineState ps
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
QSSGRhiShaderPipelinePtr gridShader
void resetForFrame() final
QList< QSSGRenderItem2D * > item2Ds
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void renderPass(QSSGRenderer &renderer) final
void resetForFrame() final
QSSGRhiGraphicsPipelineState ps
static void prep(const QSSGRenderContextInterface &ctx, QSSGLayerRenderData &data, QSSGPassKey passKey, QSSGRhiGraphicsPipelineState &ps, QSSGShaderFeatures shaderFeatures, QRhiRenderPassDescriptor *rpDesc, const QSSGRenderableObjectList &sortedOpaqueObjects)
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void resetForFrame() final
void renderPass(QSSGRenderer &renderer) final
QSSGShaderFeatures shaderFeatures
QSSGRhiGraphicsPipelineState ps
static void render(const QSSGRenderContextInterface &ctx, const QSSGRhiGraphicsPipelineState &ps, const QSSGRenderableObjectList &sortedOpaqueObjects)
QSSGRenderableObjectList sortedOpaqueObjects
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
Definition qlist.h:75
bool isEmpty() const noexcept
Definition qlist.h:401
void push_back(parameter_type t)
Definition qlist.h:675
void clear()
Definition qlist.h:434
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:25
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr qreal height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:732
constexpr qreal width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:729
constexpr QPointF center() const noexcept
Returns the center point of the rectangle.
Definition qrect.h:699
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:239
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:236
constexpr QPoint center() const noexcept
Returns the center point of the rectangle.
Definition qrect.h:233
@ Dynamic
Definition qrhi.h:851
@ UniformBuffer
Definition qrhi.h:857
virtual bool create()=0
Creates the corresponding native graphics resources.
\inmodule QtGui
Definition qrhi.h:1651
\inmodule QtGui
Definition qrhi.h:1142
\inmodule QtGui
Definition qrhi.h:1158
virtual QSize pixelSize() const =0
virtual float devicePixelRatio() const =0
\inmodule QtGui
Definition qrhi.h:1731
void generateMips(QRhiTexture *tex)
Enqueues a mipmap generation operation for the specified texture tex.
Definition qrhi.cpp:9210
QRhi * rhi() const
Definition qrhi.cpp:3603
\inmodule QtGui
Definition qrhi.h:1214
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
Definition qrhi.h:1804
QRhiBuffer * newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
Definition qrhi.cpp:10508
QMatrix4x4 clipSpaceCorrMatrix() const
Definition qrhi.cpp:10091
bool isRecordingFrame() const
Definition qrhi.cpp:10802
@ TexelFetch
Definition qrhi.h:1852
QRhiResourceUpdateBatch * nextResourceUpdateBatch()
Definition qrhi.cpp:9252
void renderSceneInline() override
static QSSGLayerRenderData * getCurrent(const QSSGRenderer &renderer)
virtual ~QSSGRenderPass()
static QSSGRhiContextPrivate * get(QSSGRhiContext *q)
QRhiGraphicsPipeline::PolygonMode polygonMode
QRhiGraphicsPipeline::CompareOp depthFunc
void addUniformBuffer(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiBuffer *buf, int offset=0, int size=0)
bool isEmpty() const
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void renderPass(QSSGRenderer &renderer) final
void resetForFrame() final
std::shared_ptr< QSSGRenderReflectionMap > reflectionMapManager
QSSGRenderableObjectList reflectionPassObjects
QSSGRhiGraphicsPipelineState ps
QList< QSSGRenderReflectionProbe * > reflectionProbes
QSSGRhiRenderableTexture * rhiAoTexture
const QSSGRhiRenderableTexture * rhiDepthTexture
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void resetForFrame() final
QSSGRhiShaderPipelinePtr ssaoShaderPipeline
QSSGAmbientOcclusionSettings aoSettings
void renderPass(QSSGRenderer &renderer) final
const QSSGRenderCamera * camera
QSSGRhiGraphicsPipelineState ps
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void renderPass(QSSGRenderer &renderer) final
void resetForFrame() final
QSSGRhiGraphicsPipelineState ps
std::optional< SkyboxPass > skyboxPass
QSSGShaderFeatures shaderFeatures
QSSGRenderableObjectList sortedOpaqueObjects
std::optional< SkyboxCubeMapPass > skyboxCubeMapPass
QSSGRhiRenderableTexture * rhiScreenTexture
QSSGRenderableObjectList sortedScreenTextureObjects
const QSSGRhiRenderableTexture * rhiScreenTexture
void renderPass(QSSGRenderer &renderer) final
QSSGRhiGraphicsPipelineState ps
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
QSSGRenderCamera * camera
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
QSSGShaderLightList globalLights
QSSGRenderableObjectList shadowPassObjects
QSSGRhiGraphicsPipelineState ps
void resetForFrame() final
QSSGBoxPoints castingObjectsBox
void renderPass(QSSGRenderer &renderer) final
std::shared_ptr< QSSGRenderShadowMap > shadowMapManager
QSSGBoxPoints receivingObjectsBox
QRhiRenderPassDescriptor * rpDesc
void renderPass(QSSGRenderer &renderer) final
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
QSSGRhiShaderPipelinePtr skyBoxCubeShader
QSSGRhiGraphicsPipelineState ps
void resetForFrame() final
void renderPass(QSSGRenderer &renderer) final
void resetForFrame() final
QRhiRenderPassDescriptor * rpDesc
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
QSSGRhiGraphicsPipelineState ps
QSSGRenderableObjectList sortedTransparentObjects
static void render(const QSSGRenderContextInterface &ctx, const QSSGRhiGraphicsPipelineState &ps, const QSSGRenderableObjectList &sortedTransparentObjects)
void renderPass(QSSGRenderer &renderer) final
QSSGShaderFeatures shaderFeatures
QSSGRhiGraphicsPipelineState ps
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void resetForFrame() final
static void prep(const QSSGRenderContextInterface &ctx, QSSGLayerRenderData &data, QSSGPassKey passKey, QSSGRhiGraphicsPipelineState &ps, QSSGShaderFeatures shaderFeatures, QRhiRenderPassDescriptor *rpDesc, const QSSGRenderableObjectList &sortedTransparentObjects)
void renderPass(QSSGRenderer &renderer) final
QList< QSSGRenderExtension * > extensions
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void resetForFrame() final
void resetForFrame() final
void renderPass(QSSGRenderer &renderer) final
QSSGRenderableObjectList renderedOpaqueDepthPrepassObjects
QSSGRhiGraphicsPipelineState ps
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
QSSGRenderableObjectList renderedDepthWriteObjects
EGLContext ctx
QCamera * camera
Definition camera.cpp:19
Combined button and popup list for selecting options.
@ transparent
Definition qnamespace.h:47
constexpr Initialization Uninitialized
void rhiPrepareGrid(QSSGRhiContext *rhiCtx, QSSGPassKey passKey, QSSGRenderLayer &layer, QSSGRenderCameraList &cameras, QSSGRenderer &renderer)
Q_QUICK3DRUNTIMERENDER_EXPORT void rhiRenderRenderable(QSSGRhiContext *rhiCtx, const QSSGRhiGraphicsPipelineState &state, QSSGRenderableObject &object, bool *needsSetViewport, QSSGRenderTextureCubeFace cubeFace=QSSGRenderTextureCubeFaceNone)
QRect correctViewportCoordinates(const QRectF &layerViewport, const QRect &deviceRect)
void rhiPrepareSkyBox(QSSGRhiContext *rhiCtx, QSSGPassKey passKey, QSSGRenderLayer &layer, QSSGRenderCameraList &cameras, QSSGRenderer &renderer)
Q_QUICK3DRUNTIMERENDER_EXPORT void rhiPrepareRenderable(QSSGRhiContext *rhiCtx, QSSGPassKey passKey, const QSSGLayerRenderData &inData, QSSGRenderableObject &inObject, QRhiRenderPassDescriptor *renderPassDescriptor, QSSGRhiGraphicsPipelineState *ps, QSSGShaderFeatures featureSet, int samples, int viewCount, QSSGRenderCamera *alteredCamera=nullptr, QMatrix4x4 *alteredModelViewProjection=nullptr, QSSGRenderTextureCubeFace cubeFace=QSSGRenderTextureCubeFaceNone, QSSGReflectionMapEntry *entry=nullptr)
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
EGLOutputLayerEXT layer
#define qWarning
Definition qlogging.h:166
GLuint64 GLenum void * handle
GLsizei samples
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLfloat GLfloat p
[1]
#define Q_QUICK3D_PROFILE_START(Type)
#define Q_QUICK3D_PROFILE_END_WITH_STRING(Type, Payload, Str)
#define QSSG_ASSERT_X(cond, msg, action)
#define QSSG_CHECK(cond)
#define QSSG_ASSERT(cond, action)
#define QSSG_GUARD(cond)
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
ptrdiff_t qsizetype
Definition qtypes.h:165
QGraphicsItem * item
QSvgRenderer * renderer
[0]
QPointer< QSGRenderer > m_renderer
static void setShaderPipeline(QSSGRhiGraphicsPipelineState &ps, const QSSGRhiShaderPipeline *pipeline)
QRhiTextureRenderTarget * rt
QRhiRenderPassDescriptor * rpDesc