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 if (!debugCamera) {
83 debugCamera = std::make_unique<QSSGRenderCamera>(QSSGRenderGraphObject::Type::OrthographicCamera);
84 }
85 }
86}
87
89{
90 using namespace RenderHelpers;
91
92 // INPUT: Sorted opaque and transparent + depth, global lights (scoped lights not supported) and camera.
93
94 // DEPENDECY: None
95
96 // OUTPUT: Textures or cube maps
97
98 // CONDITION: Lights (shadowPassObjects)
99
100 if (enabled) {
101 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
102 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
103 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
104 cb->debugMarkBegin(QByteArrayLiteral("Quick3D shadow map"));
105 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D shadow map"));
106 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
107
109 rhiRenderShadowMap(rhiCtx.get(),
110 this,
111 ps,
113 *camera,
114 debugCamera.get(),
115 globalLights, // scoped lights are not relevant here
117 renderer,
120
121 cb->debugMarkEnd();
122 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("shadow_map"));
123 }
124}
125
127{
128 enabled = false;
129 camera = nullptr;
132 ps = {};
135}
136
137// REFLECTIONMAP PASS
138
140{
142 Q_UNUSED(data);
143
144 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
145 QSSGRenderCamera *camera = data.renderedCameras[0];
146
147 ps = data.getPipelineState();
151
152 reflectionProbes = data.reflectionProbes;
153 reflectionMapManager = data.requestReflectionMapManager();
154
155 const auto &sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects(*camera);
156 const auto &sortedTransparentObjects = data.getSortedTransparentRenderableObjects(*camera);
157 const auto &sortedScreenTextureObjects = data.getSortedScreenTextureRenderableObjects(*camera);
158
160
161 // NOTE: We should consider keeping track of the reflection casting objects to avoid
162 // filtering this list on each prep.
163 for (const auto &handles : { &sortedOpaqueObjects, &sortedTransparentObjects, &sortedScreenTextureObjects }) {
164 for (const auto &handle : *handles) {
165 if (handle.obj->renderableFlags.testFlag(QSSGRenderableObjectFlag::CastsReflections))
167 }
168 }
169}
170
172{
173 using namespace RenderHelpers;
174
175 // INPUT: Reflection probes, sorted opaque and transparent
176
177 // DEPENDECY: None
178
179 // OUTPUT: Cube maps (1 per probe)
180
181 // NOTE: Full pass with a sky box pass
182
183 // CONDITION: Probes and sorted opaque and transparent
184
185 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
186 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
187 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
188
189 const auto *layerData = QSSGLayerRenderData::getCurrent(renderer);
190 QSSG_ASSERT(layerData, return);
191
194 cb->debugMarkBegin(QByteArrayLiteral("Quick3D reflection map"));
195 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D reflection map"));
196 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
197 rhiRenderReflectionMap(rhiCtx.get(),
198 this,
199 *layerData,
200 &ps,
204 renderer);
205
206 cb->debugMarkEnd();
207 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("reflection_map"));
208 }
209}
210
217
218// ZPrePass
220{
221 using namespace RenderHelpers;
222
223 // INPUT: Item2Ds + depth write + depth prepass
224
225 // DEPENDECY: none
226
227 // OUTPUT: Depth buffer attchment for current target
228
229 // NOTE: Could we make the depth pass more complete and just do a blit here?
230 //
231 // 1. If we have a depth map, just do a blit and then update with the rest
232 // 2. If we don't have a depth map (and/or SSAO) consider using a lower lod level.
233
234 // CONDITION: Input + globally enabled or ?
235
236 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
237 QSSGRenderCamera *camera = data.renderedCameras[0];
238
239 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
240 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
241 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
242 ps = data.getPipelineState();
243
244 renderedDepthWriteObjects = data.getSortedRenderedDepthWriteObjects(*camera);
245 renderedOpaqueDepthPrepassObjects = data.getSortedrenderedOpaqueDepthPrepassObjects(*camera);
246
247 cb->debugMarkBegin(QByteArrayLiteral("Quick3D prepare Z prepass"));
248 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D prepare Z prepass"));
249 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
250 active = rhiPrepareDepthPass(rhiCtx.get(), this, ps, rhiCtx->mainRenderPassDescriptor(), data,
252 rhiCtx->mainPassSampleCount(), rhiCtx->mainPassViewCount());
253 data.setZPrePassPrepResult(active);
254 cb->debugMarkEnd();
255 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("prepare_z_prepass"));
256}
257
259{
260 using namespace RenderHelpers;
261
262 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
263 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
264
265 bool needsSetViewport = true;
266 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
267
268 if (active) {
269 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
270 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render Z prepass"));
271 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render Z prepass"));
272 rhiRenderDepthPass(rhiCtx.get(), ps, renderedDepthWriteObjects, renderedOpaqueDepthPrepassObjects, &needsSetViewport);
273 cb->debugMarkEnd();
274 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("render_z_prepass"));
275 }
276}
277
285
286// SSAO PASS
288{
289 using namespace RenderHelpers;
290
291 // Assumption for now is that all passes are keept alive and only reset once a frame is done.
292 // I.e., holding data like this should be safe (If that's no longer the case we need to do ref counting
293 // for shared data).
294
295 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
296 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
297
300 QSSG_ASSERT_X(!data.renderedCameras.isEmpty(), "Preparing AO pass failed, missing camera", return);
301 camera = data.renderedCameras[0];
302 QSSG_ASSERT_X((rhiDepthTexture && rhiDepthTexture->isValid()), "Preparing AO pass failed, missing equired texture(s)", return);
303
304 const auto &shaderCache = renderer.contextInterface()->shaderCache();
305 ssaoShaderPipeline = shaderCache->getBuiltInRhiShaders().getRhiSsaoShader(rhiCtx->mainPassViewCount());
306 aoSettings = { data.layer.aoStrength, data.layer.aoDistance, data.layer.aoSoftness, data.layer.aoBias, data.layer.aoSamplerate, data.layer.aoDither };
307
308 ps = data.getPipelineState();
309 const auto &layerPrepResult = data.layerPrepResult;
310 const bool ready = rhiAoTexture && rhiPrepareAoTexture(rhiCtx.get(), layerPrepResult.textureDimensions(), rhiAoTexture);
311
312 if (Q_UNLIKELY(!ready))
313 rhiAoTexture = nullptr;
314}
315
317{
318 using namespace RenderHelpers;
319
320 // INPUT: Camera + depth map
321
322 // DEPENDECY: Depth map (zprepass)
323
324 // OUTPUT: AO Texture
325
326 // NOTE:
327
328 // CONDITION: SSAO enabled
330
331 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
332 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
333
334 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
335 cb->debugMarkBegin(QByteArrayLiteral("Quick3D SSAO map"));
336 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D SSAO map"));
337 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
338
340 rhiRenderAoTexture(rhiCtx.get(),
341 this,
342 renderer,
344 ps,
348 *camera);
349 }
350
351 cb->debugMarkEnd();
352 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("ssao_map"));
353}
354
356{
357 rhiDepthTexture = nullptr;
358 rhiAoTexture = nullptr;
359 camera = nullptr;
360 ps = {};
361 aoSettings = {};
362}
363
364// DEPTH TEXTURE PASS
366{
367 using namespace RenderHelpers;
368
369 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
370 QSSGRenderCamera *camera = data.renderedCameras[0];
371
372 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
373 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
374 const auto &layerPrepResult = data.layerPrepResult;
375 bool ready = false;
376 ps = data.getPipelineState();
378 if (Q_LIKELY(rhiDepthTexture && rhiPrepareDepthTexture(rhiCtx.get(), layerPrepResult.textureDimensions(), rhiDepthTexture))) {
379 sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects(*camera);
380 sortedTransparentObjects = data.getSortedTransparentRenderableObjects(*camera);
381 // the depth texture is always non-MSAA, but is a 2D array with multiview
382 ready = rhiPrepareDepthPass(rhiCtx.get(), this, ps, rhiDepthTexture->rpDesc, data,
384 1, rhiCtx->mainPassViewCount());
385 }
386
387 if (Q_UNLIKELY(!ready))
388 rhiDepthTexture = nullptr;
389}
390
392{
393 using namespace RenderHelpers;
394
395 // INPUT: sorted objects (opaque + transparent) (maybe...)
396
397 // DEPENDECY: If this is only used for the AO case, that dictates if this should be done or not.
398
399 // OUTPUT: Texture
400
401 // NOTE: Why are we prepping opaque + transparent object if we're not using them? And why are we staying compatible with 5.15?
402 // Only used for AO? Merge into the AO pass?
403
404 // NOTES:
405 //
406 // 1: If requested, use this and blit it in the z-pre pass.
407 // 2. Why are we handling the transparent objects in the render prep (only)?
408
409 // CONDITION:
410
411 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
412 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
413 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
414 cb->debugMarkBegin(QByteArrayLiteral("Quick3D depth texture"));
415
417 bool needsSetViewport = true;
418 cb->beginPass(rhiDepthTexture->rt, Qt::transparent, { 1.0f, 0 }, nullptr, rhiCtx->commonPassFlags());
419 QSSGRHICTX_STAT(rhiCtx, beginRenderPass(rhiDepthTexture->rt));
420 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
421 // NB! We do not pass sortedTransparentObjects in the 4th
422 // argument to stay compatible with the 5.15 code base,
423 // which also does not include semi-transparent objects in
424 // the depth texture. In addition, capturing after the
425 // opaque pass, not including transparent objects, is part
426 // of the contract for screen reading custom materials,
427 // both for depth and color.
428 rhiRenderDepthPass(rhiCtx.get(), ps, sortedOpaqueObjects, {}, &needsSetViewport);
429 cb->endPass();
430 QSSGRHICTX_STAT(rhiCtx, endRenderPass());
431 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("depth_texture"));
432 }
433
434 cb->debugMarkEnd();
435}
436
444
445// SCREEN TEXTURE PASS
446
448{
449 using namespace RenderHelpers;
450
451 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
452 QSSGRenderCamera *camera = data.renderedCameras[0];
453
454 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
455 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
457 auto &layer = data.layer;
458 const auto &layerPrepResult = data.layerPrepResult;
459 wantsMips = layerPrepResult.flags.requiresMipmapsForScreenTexture();
460 sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects(*camera);
461 ps = data.getPipelineState();
462 ps.samples = 1; // screen texture is always non-MSAA
463 ps.viewCount = rhiCtx->mainPassViewCount(); // but is a 2D texture array when multiview
464
466 clearColor = QColor::fromRgbF(layer.clearColor.x(), layer.clearColor.y(), layer.clearColor.z());
467
468 if (rhiCtx->rhi()->isFeatureSupported(QRhi::TexelFetch)) {
469 if (layer.background == QSSGRenderLayer::Background::SkyBoxCubeMap && layer.skyBoxCubeMap) {
472
473 skyboxCubeMapPass->skipTonemapping = true;
474 skyboxCubeMapPass->renderPrep(renderer, data);
475
476 // The pass expects to output to the main render target, but we have
477 // our own texture here, possibly with a differing sample count, so
478 // override the relevant settings once renderPrep() is done.
479 skyboxCubeMapPass->ps.samples = ps.samples;
480
481 skyboxPass = std::nullopt;
482 } else if (layer.background == QSSGRenderLayer::Background::SkyBox && layer.lightProbe) {
483 if (!skyboxPass)
485
486 skyboxPass->skipTonemapping = true;
487 skyboxPass->renderPrep(renderer, data);
488
489 skyboxPass->ps.samples = ps.samples;
490
491 skyboxCubeMapPass = std::nullopt;
492 }
493 }
494
495 bool ready = false;
496 if (Q_LIKELY(rhiScreenTexture && rhiPrepareScreenTexture(rhiCtx.get(), layerPrepResult.textureDimensions(), wantsMips, rhiScreenTexture))) {
497 ready = true;
500 if (skyboxPass)
502 // NB: not compatible with disabling LayerEnableDepthTest
503 // because there are effectively no "opaque" objects then.
504 // Disable Tonemapping for all materials in the screen pass texture
505 shaderFeatures = data.getShaderFeatures();
507 const auto &sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects(*camera);
508 for (const auto &handle : sortedOpaqueObjects) {
509 // Reflection cube maps are not available at this point, make sure they are turned off.
510 bool recRef = handle.obj->renderableFlags.receivesReflections();
511 handle.obj->renderableFlags.setReceivesReflections(false);
512 rhiPrepareRenderable(rhiCtx.get(), this, data, *handle.obj, rhiScreenTexture->rpDesc, &ps, shaderFeatures, 1, rhiCtx->mainPassViewCount());
513 handle.obj->renderableFlags.setReceivesReflections(recRef);
514 }
515 }
516
517 if (Q_UNLIKELY(!ready))
518 rhiScreenTexture = nullptr;
519}
520
522{
523 using namespace RenderHelpers;
524
525 // INPUT: Sorted opaque objects + depth objects
526
527 // DEPENDECY: Depth pass (if enabled)
528
529 // OUTPUT: Texture (screen texture).
530
531 // NOTE: Used for refrection and effects (?)
532
533 // CONDITION:
534
535 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
536 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
537 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
538
539 cb->debugMarkBegin(QByteArrayLiteral("Quick3D screen texture"));
540
542 cb->beginPass(rhiScreenTexture->rt, clearColor, { 1.0f, 0 }, nullptr, rhiCtx->commonPassFlags());
543 QSSGRHICTX_STAT(rhiCtx, beginRenderPass(rhiScreenTexture->rt));
544 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
545
546 bool needsSetViewport = true;
547 for (const auto &handle : std::as_const(sortedOpaqueObjects))
548 rhiRenderRenderable(rhiCtx.get(), ps, *handle.obj, &needsSetViewport);
549
551 skyboxCubeMapPass->renderPass(renderer);
552 else if (skyboxPass)
553 skyboxPass->renderPass(renderer);
554
555 QRhiResourceUpdateBatch *rub = nullptr;
556 if (wantsMips) {
557 rub = rhiCtx->rhi()->nextResourceUpdateBatch();
559 }
560 cb->endPass(rub);
561 QSSGRHICTX_STAT(rhiCtx, endRenderPass());
562 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("screen_texture"));
563 }
564
565 cb->debugMarkEnd();
566}
567
569{
570 rhiScreenTexture = nullptr;
571 if (skyboxPass)
572 skyboxPass->resetForFrame();
574 skyboxCubeMapPass->resetForFrame();
575 ps = {};
576 wantsMips = false;
578 shaderFeatures = {};
580}
581
583{
584 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
585 QSSGRenderCamera *camera = data.renderedCameras[0];
586
587 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
588 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
590 QSSG_ASSERT_X(rhiScreenTexture && rhiScreenTexture->isValid(), "Invalid screen texture!", return);
591
592 const auto &layer = data.layer;
593 const auto shaderFeatures = data.getShaderFeatures();
594 const bool layerEnableDepthTest = layer.layerFlags.testFlag(QSSGRenderLayer::LayerFlag::EnableDepthTest);
595
596 QRhiRenderPassDescriptor *mainRpDesc = rhiCtx->mainRenderPassDescriptor();
597 const int samples = rhiCtx->mainPassSampleCount();
598 const int viewCount = rhiCtx->mainPassViewCount();
599
600 // NOTE: We're piggybacking on the screen map pass for now, but we could do better.
601 ps = data.getPipelineState();
602 const bool depthTestEnabled = (data.screenMapPass.ps.flags.testFlag(QSSGRhiGraphicsPipelineState::Flag::DepthTestEnabled));
604 const bool depthWriteEnabled = (data.screenMapPass.ps.flags.testFlag(QSSGRhiGraphicsPipelineState::Flag::DepthWriteEnabled));
606 sortedScreenTextureObjects = data.getSortedScreenTextureRenderableObjects(*camera);
607 for (const auto &handle : std::as_const(sortedScreenTextureObjects)) {
608 QSSGRenderableObject *theObject = handle.obj;
609 const auto depthWriteMode = theObject->depthWriteMode;
610 ps.flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::BlendEnabled, theObject->renderableFlags.hasTransparency());
611 const bool curDepthWriteEnabled = !(depthWriteMode == QSSGDepthDrawMode::Never || depthWriteMode == QSSGDepthDrawMode::OpaquePrePass
612 || data.isZPrePassActive() || !layerEnableDepthTest);
614 RenderHelpers::rhiPrepareRenderable(rhiCtx.get(), this, data, *theObject, mainRpDesc, &ps, shaderFeatures, samples, viewCount);
615 }
616}
617
619{
621 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
622 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
623 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
624
625 // 3. Screen texture depended objects
626 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render screen texture dependent"));
627 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
628 Q_TRACE(QSSG_renderPass_entry, QStringLiteral("Quick3D render screen texture dependent"));
629 bool needsSetViewport = true;
630 for (const auto &handle : std::as_const(sortedScreenTextureObjects)) {
631 QSSGRenderableObject *theObject = handle.obj;
632 RenderHelpers::rhiRenderRenderable(rhiCtx.get(), ps, *theObject, &needsSetViewport);
633 }
634 cb->debugMarkEnd();
635 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("screen_texture_dependent"));
636 Q_TRACE(QSSG_renderPass_exit);
637 }
638}
639
646
649 QSSGPassKey passKey,
651 QSSGShaderFeatures shaderFeatures,
653 const QSSGRenderableObjectList &sortedOpaqueObjects)
654{
655 const auto &rhiCtx = ctx.rhiContext();
656 QSSG_ASSERT(rpDesc && rhiCtx->rhi()->isRecordingFrame(), return);
657
658 const auto &layer = data.layer;
659 const bool layerEnableDepthTest = layer.layerFlags.testFlag(QSSGRenderLayer::LayerFlag::EnableDepthTest);
660
661 for (const auto &handle : std::as_const(sortedOpaqueObjects)) {
662 QSSGRenderableObject *theObject = handle.obj;
663 const auto depthWriteMode = theObject->depthWriteMode;
664 const bool curDepthWriteEnabled = !(depthWriteMode == QSSGDepthDrawMode::Never ||
665 depthWriteMode == QSSGDepthDrawMode::OpaquePrePass ||
666 data.isZPrePassActive() || !layerEnableDepthTest);
668 RenderHelpers::rhiPrepareRenderable(rhiCtx.get(), passKey, data, *theObject, rpDesc, &ps, shaderFeatures, ps.samples, ps.viewCount);
669 }
670}
671
674 const QSSGRenderableObjectList &sortedOpaqueObjects)
675{
676 const auto &rhiCtx = ctx.rhiContext();
677 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
678 bool needsSetViewport = true;
679 for (const auto &handle : std::as_const(sortedOpaqueObjects)) {
680 QSSGRenderableObject *theObject = handle.obj;
681 RenderHelpers::rhiRenderRenderable(rhiCtx.get(), ps, *theObject, &needsSetViewport);
682 }
683}
684
686{
687 auto *ctx = renderer.contextInterface();
688 const auto &rhiCtx = ctx->rhiContext();
689 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
690 QSSG_ASSERT(!data.renderedCameras.isEmpty() && data.renderedCameraData.has_value() , return);
691 QSSGRenderCamera *camera = data.renderedCameras[0];
692
693 ps = data.getPipelineState();
694 ps.samples = rhiCtx->mainPassSampleCount();
695 ps.viewCount = rhiCtx->mainPassViewCount();
698
699 // opaque objects (or, this list is empty when LayerEnableDepthTest is disabled)
700 sortedOpaqueObjects = data.getSortedOpaqueRenderableObjects(*camera);
701 shaderFeatures = data.getShaderFeatures();
702
703 QRhiRenderPassDescriptor *mainRpDesc = rhiCtx->mainRenderPassDescriptor();
704 prep(*ctx, data, this, ps, shaderFeatures, mainRpDesc, sortedOpaqueObjects);
705}
706
708{
709 auto *ctx = renderer.contextInterface();
710 const auto &rhiCtx = ctx->rhiContext();
711 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
712 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
713
714 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render opaque"));
715 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
716 Q_TRACE(QSSG_renderPass_entry, QStringLiteral("Quick3D render opaque"));
718 cb->debugMarkEnd();
719 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("opaque_pass"));
720 Q_TRACE(QSSG_renderPass_exit);
721}
722
724{
726 ps = {};
727 shaderFeatures = {};
728}
729
732 QSSGPassKey passKey,
734 QSSGShaderFeatures shaderFeatures,
736 const QSSGRenderableObjectList &sortedTransparentObjects)
737{
738 const auto &rhiCtx = ctx.rhiContext();
739 QSSG_ASSERT(rpDesc && rhiCtx->rhi()->isRecordingFrame(), return);
740
741 const bool zPrePassActive = data.isZPrePassActive();
742 for (const auto &handle : std::as_const(sortedTransparentObjects)) {
743 QSSGRenderableObject *theObject = handle.obj;
744 const auto depthWriteMode = theObject->depthWriteMode;
745 const bool curDepthWriteEnabled = (depthWriteMode == QSSGDepthDrawMode::Always && !zPrePassActive);
747 if (!(theObject->renderableFlags.isCompletelyTransparent()))
748 RenderHelpers::rhiPrepareRenderable(rhiCtx.get(), passKey, data, *theObject, rpDesc, &ps, shaderFeatures, ps.samples, ps.viewCount);
749 }
750}
751
754 const QSSGRenderableObjectList &sortedTransparentObjects)
755{
756 const auto &rhiCtx = ctx.rhiContext();
757 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
758 // If scissorRect is set, Item2Ds will be drawn by a workaround of modifying
759 // viewport, not using actual 3D scissor test.
760 // It means non-opaque objects may be affected by this viewport setting.
761 bool needsSetViewport = true;
762 for (const auto &handle : std::as_const(sortedTransparentObjects)) {
763 QSSGRenderableObject *theObject = handle.obj;
764 if (!theObject->renderableFlags.isCompletelyTransparent())
765 RenderHelpers::rhiRenderRenderable(rhiCtx.get(), ps, *theObject, &needsSetViewport);
766 }
767}
768
770{
771 auto *ctx = renderer.contextInterface();
772 const auto &rhiCtx = ctx->rhiContext();
773
774 QSSG_ASSERT(!data.renderedCameras.isEmpty() && data.renderedCameraData.has_value() , return);
775 QSSGRenderCamera *camera = data.renderedCameras[0];
776
777 QRhiRenderPassDescriptor *mainRpDesc = rhiCtx->mainRenderPassDescriptor();
778
779 ps = data.getPipelineState();
780 ps.samples = rhiCtx->mainPassSampleCount();
781 ps.viewCount = rhiCtx->mainPassViewCount();
782
783 // transparent objects (or, without LayerEnableDepthTest, all objects)
786
787 shaderFeatures = data.getShaderFeatures();
788 sortedTransparentObjects = data.getSortedTransparentRenderableObjects(*camera);
789
790 prep(*ctx, data, this, ps, shaderFeatures, mainRpDesc, sortedTransparentObjects);
791}
792
794{
795 auto *ctx = renderer.contextInterface();
796 const auto &rhiCtx = ctx->rhiContext();
797 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
798 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
799
800 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render alpha"));
801 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
802 Q_TRACE(QSSG_renderPass_entry, QStringLiteral("Quick3D render alpha"));
804 cb->debugMarkEnd();
805 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("transparent_pass"));
806 Q_TRACE(QSSG_renderPass_exit);
807}
808
815
817{
818 if (!skipPrep) {
819 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
820 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
821 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
822 QSSG_ASSERT(data.renderedCameras.count() == rhiCtx->mainPassViewCount(), return);
823 layer = &data.layer;
824 QSSG_ASSERT(layer, return);
825
826 rpDesc = rhiCtx->mainRenderPassDescriptor();
827 ps = data.getPipelineState();
828 ps.samples = rhiCtx->mainPassSampleCount();
829 ps.viewCount = rhiCtx->mainPassViewCount();
831
832 // When there are effects, then it is up to the last pass of the
833 // last effect to perform tonemapping, neither the skybox nor the
834 // main render pass should alter the colors then.
835 skipTonemapping = layer->firstEffect != nullptr;
836
837 RenderHelpers::rhiPrepareSkyBox(rhiCtx.get(), this, *layer, data.renderedCameras, renderer);
838 skipPrep = true;
839 }
840}
841
843{
844 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
845 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
846 QSSG_ASSERT(layer, return);
847
848 QRhiShaderResourceBindings *srb = layer->skyBoxSrb;
849 QSSG_ASSERT(srb, return);
850
851 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
852 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render skybox"));
853
854 // Note: We get the shader here, as the screen map pass might modify the state of
855 // the tonemap mode.
856
858 const auto &shaderCache = renderer.contextInterface()->shaderCache();
859 auto shaderPipeline = shaderCache->getBuiltInRhiShaders().getRhiSkyBoxShader(tonemapMode, layer->skyBoxIsRgbe8, rhiCtx->mainPassViewCount());
860 QSSG_CHECK(shaderPipeline);
862 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, rpDesc, { QSSGRhiQuadRenderer::DepthTest | QSSGRhiQuadRenderer::RenderBehind });
863 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("skybox_map"));
864}
865
867{
868 ps = {};
869 layer = nullptr;
870 skipPrep = false;
871}
872
874{
875 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
876 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
877 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
878 QSSG_ASSERT(data.renderedCameras.count() == rhiCtx->mainPassViewCount(), return);
879 layer = &data.layer;
880 QSSG_ASSERT(layer, return);
881
882 rpDesc = rhiCtx->mainRenderPassDescriptor();
883 ps = data.getPipelineState();
884 ps.samples = rhiCtx->mainPassSampleCount();
885 ps.viewCount = rhiCtx->mainPassViewCount();
887
888 const auto &shaderCache = renderer.contextInterface()->shaderCache();
889 skyBoxCubeShader = shaderCache->getBuiltInRhiShaders().getRhiSkyBoxCubeShader(rhiCtx->mainPassViewCount());
890
891 RenderHelpers::rhiPrepareSkyBox(rhiCtx.get(), this, *layer, data.renderedCameras, renderer);
892}
893
895{
896 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
897 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
899
900 QRhiShaderResourceBindings *srb = layer->skyBoxSrb;
901 QSSG_ASSERT(srb, return);
902
903 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
904 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render skybox"));
905
907 renderer.rhiCubeRenderer()->recordRenderCube(rhiCtx.get(), &ps, srb, rpDesc, { QSSGRhiQuadRenderer::DepthTest | QSSGRhiQuadRenderer::RenderBehind });
908 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("skybox_cube"));
909}
910
912{
913 ps = {};
914 layer = nullptr;
915}
916
918{
919 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
920 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
921 const auto &layer = data.layer;
922
923 ps = data.getPipelineState();
924
925 // objects rendered by Qt Quick 2D
927
928 item2Ds = data.getRenderableItem2Ds();
929 for (const auto &item2D: std::as_const(item2Ds)) {
930 // Set the projection matrix
931 if (!item2D->m_renderer)
932 continue;
933 if (item2D->m_renderer && item2D->m_renderer->currentRhi() != renderer.contextInterface()->rhiContext()->rhi()) {
934 static bool contextWarningShown = false;
935 if (!contextWarningShown) {
936 qWarning () << "Scene with embedded 2D content can only be rendered in one window.";
937 contextWarningShown = true;
938 }
939 continue;
940 }
941
942 auto layerPrepResult = data.layerPrepResult;
943
944 QRhiRenderTarget *renderTarget = rhiCtx->renderTarget();
945 item2D->m_renderer->setDevicePixelRatio(renderTarget->devicePixelRatio());
946 const QRect deviceRect(QPoint(0, 0), renderTarget->pixelSize());
947 const int viewCount = rhiCtx->mainPassViewCount();
948 QSSG_ASSERT(item2D->mvps.count() == viewCount, return);
949 if (layer.scissorRect.isValid()) {
950 QRect effScissor = layer.scissorRect & layerPrepResult.viewport.toRect();
951 QMatrix4x4 correctionMat = correctMVPForScissor(layerPrepResult.viewport,
952 effScissor,
953 rhiCtx->rhi()->isYUpInNDC());
954 for (int viewIndex = 0; viewIndex < viewCount; ++viewIndex) {
955 const QMatrix4x4 projectionMatrix = correctionMat * item2D->mvps[viewIndex];
956 item2D->m_renderer->setProjectionMatrix(projectionMatrix, viewIndex);
957 }
958 item2D->m_renderer->setViewportRect(effScissor);
959 } else {
960 for (int viewIndex = 0; viewIndex < viewCount; ++viewIndex)
961 item2D->m_renderer->setProjectionMatrix(item2D->mvps[viewIndex], viewIndex);
962 item2D->m_renderer->setViewportRect(RenderHelpers::correctViewportCoordinates(layerPrepResult.viewport, deviceRect));
963 }
964 item2D->m_renderer->setDeviceRect(deviceRect);
965 QRhiRenderPassDescriptor *oldRp = nullptr;
966 if (item2D->m_rp) {
967 // Changing render target, and so incompatible renderpass
968 // descriptors should be uncommon, but possible.
969 if (!item2D->m_rp->isCompatible(rhiCtx->mainRenderPassDescriptor()))
970 std::swap(item2D->m_rp, oldRp);
971 }
972 if (!item2D->m_rp) {
973 // Do not pass our object to the Qt Quick scenegraph. It may
974 // hold on to it, leading to lifetime and ownership issues.
975 // Rather, create a dedicated, compatible object.
976 item2D->m_rp = rhiCtx->mainRenderPassDescriptor()->newCompatibleRenderPassDescriptor();
977 QSSG_CHECK(item2D->m_rp);
978 }
979 QSGRenderTarget sgRt(renderTarget, item2D->m_rp, rhiCtx->commandBuffer());
980 sgRt.multiViewCount = rhiCtx->mainPassViewCount();
981 item2D->m_renderer->setRenderTarget(sgRt);
982 delete oldRp;
983 item2D->m_renderer->prepareSceneInline();
984 }
985}
986
988{
989 QSSG_ASSERT(!item2Ds.isEmpty(), return);
990
991 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
992 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
993 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
994
995 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render 2D sub-scene"));
996 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
997 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render 2D sub-scene"));
998 for (const auto &item : std::as_const(item2Ds)) {
999 QSSGRenderItem2D *item2D = static_cast<QSSGRenderItem2D *>(item);
1000 if (item2D->m_renderer && item2D->m_renderer->currentRhi() == renderer.contextInterface()->rhiContext()->rhi())
1001 item2D->m_renderer->renderSceneInline();
1002 }
1003 cb->debugMarkEnd();
1004 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("2D_sub_scene"));
1005}
1006
1008{
1009 item2Ds.clear();
1010 ps = {};
1011}
1012
1014{
1015 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
1016 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
1017 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
1018 QSSG_ASSERT(data.renderedCameras.count() == rhiCtx->mainPassViewCount(), return);
1019 layer = &data.layer;
1020 QSSG_ASSERT(layer, return);
1021
1022 const auto &shaderCache = renderer.contextInterface()->shaderCache();
1023 gridShader = shaderCache->getBuiltInRhiShaders().getRhiGridShader(rhiCtx->mainPassViewCount());
1024
1025 ps = data.getPipelineState();
1026 ps.samples = rhiCtx->mainPassSampleCount();
1027 ps.viewCount = rhiCtx->mainPassViewCount();
1029
1030 RenderHelpers::rhiPrepareGrid(rhiCtx.get(), this, *layer, data.renderedCameras, renderer);
1031}
1032
1034{
1035 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
1036 QSSG_ASSERT(gridShader && rhiCtx->rhi()->isRecordingFrame(), return);
1037 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
1038
1039 cb->debugMarkBegin(QByteArrayLiteral("Quick3D render grid"));
1040 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
1041 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick3D render grid"));
1043 QRhiShaderResourceBindings *srb = layer->gridSrb;
1044 QRhiRenderPassDescriptor *rpDesc = rhiCtx->mainRenderPassDescriptor();
1045 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &ps, srb, rpDesc, { QSSGRhiQuadRenderer::DepthTest });
1046 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("render_grid"));
1047}
1048
1050{
1051 ps = {};
1052 layer = nullptr;
1053}
1054
1056{
1057 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
1058 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(), return);
1059 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx.get());
1060 QSSG_ASSERT(!data.renderedCameras.isEmpty(), return);
1061 QSSG_ASSERT(data.renderedCameras.count() == rhiCtx->mainPassViewCount(), return);
1062
1063 const auto &shaderCache = renderer.contextInterface()->shaderCache();
1064 debugObjectShader = shaderCache->getBuiltInRhiShaders().getRhiDebugObjectShader();
1065 ps = data.getPipelineState();
1066
1067 // debug objects
1068 const auto &debugDraw = renderer.contextInterface()->debugDrawSystem();
1069 if (debugDraw && debugDraw->hasContent()) {
1070 QRhi *rhi = rhiCtx->rhi();
1072 debugDraw->prepareGeometry(rhiCtx.get(), rub);
1073 QSSGRhiDrawCallData &dcd = rhiCtxD->drawCallData({ this, nullptr, nullptr, 0 });
1074 if (!dcd.ubuf) {
1075 dcd.ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64 * data.renderedCameras.count());
1076 dcd.ubuf->create();
1077 }
1078 char *ubufData = dcd.ubuf->beginFullDynamicBufferUpdateForCurrentFrame();
1079 for (qsizetype viewIdx = 0; viewIdx < data.renderedCameras.count(); ++viewIdx) {
1080 QMatrix4x4 viewProjection(Qt::Uninitialized);
1081 data.renderedCameras[viewIdx]->calculateViewProjectionMatrix(viewProjection);
1082 viewProjection = rhi->clipSpaceCorrMatrix() * viewProjection;
1083 memcpy(ubufData, viewProjection.constData() + viewIdx * 64, 64);
1084 }
1085 dcd.ubuf->endFullDynamicBufferUpdateForCurrentFrame();
1086
1089 dcd.srb = rhiCtxD->srb(bindings);
1090
1091 rhiCtx->commandBuffer()->resourceUpdate(rub);
1092 }
1093}
1094
1096{
1097 const auto &rhiCtx = renderer.contextInterface()->rhiContext();
1098 QSSG_ASSERT(debugObjectShader && rhiCtx->rhi()->isRecordingFrame(), return);
1099 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
1100 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx.get());
1101
1102 const auto &debugDraw = renderer.contextInterface()->debugDrawSystem();
1103 if (debugDraw && debugDraw->hasContent()) {
1104 cb->debugMarkBegin(QByteArrayLiteral("Quick 3D debug objects"));
1105 Q_TRACE_SCOPE(QSSG_renderPass, QStringLiteral("Quick 3D debug objects"));
1106 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderPass);
1108 QSSGRhiDrawCallData &dcd = rhiCtxD->drawCallData({ this, nullptr, nullptr, 0 });
1109 QRhiShaderResourceBindings *srb = dcd.srb;
1110 QRhiRenderPassDescriptor *rpDesc = rhiCtx->mainRenderPassDescriptor();
1111 debugDraw->recordRenderDebugObjects(rhiCtx.get(), &ps, srb, rpDesc);
1112 cb->debugMarkEnd();
1113 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderPass, 0, QByteArrayLiteral("debug_objects"));
1114 }
1115}
1116
1118{
1119 ps = {};
1120}
1121
1123{
1125 auto &frameData = data.getFrameData();
1126 for (const auto &p : std::as_const(extensions)) {
1127 p->prepareRender(frameData);
1129 p->render(frameData);
1130 }
1131}
1132
1134{
1136 QSSG_ASSERT(data, return);
1137 auto &frameData = data->getFrameData();
1138 for (const auto &p : std::as_const(extensions)) {
1140 p->render(frameData);
1141 }
1142}
1143
1145{
1146 for (const auto &p : std::as_const(extensions))
1147 p->resetForFrame();
1148
1149 // TODO: We should track if we need to update this list.
1150 extensions.clear();
1151}
1152
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:76
bool isEmpty() const noexcept
Definition qlist.h:402
void push_back(parameter_type t)
Definition qlist.h:676
void clear()
Definition qlist.h:435
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:1652
\inmodule QtGui
Definition qrhi.h:1143
\inmodule QtGui
Definition qrhi.h:1159
virtual QSize pixelSize() const =0
virtual float devicePixelRatio() const =0
\inmodule QtGui
Definition qrhi.h:1732
void generateMips(QRhiTexture *tex)
Enqueues a mipmap generation operation for the specified texture tex.
Definition qrhi.cpp:9218
QRhi * rhi() const
Definition qrhi.cpp:3603
\inmodule QtGui
Definition qrhi.h:1215
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
Definition qrhi.h:1805
QRhiBuffer * newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
Definition qrhi.cpp:10516
QMatrix4x4 clipSpaceCorrMatrix() const
Definition qrhi.cpp:10099
bool isRecordingFrame() const
Definition qrhi.cpp:10810
@ TexelFetch
Definition qrhi.h:1853
QRhiResourceUpdateBatch * nextResourceUpdateBatch()
Definition qrhi.cpp:9260
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
QSSGBounds3 castingObjectsBox
QSSGShaderLightList globalLights
QSSGRenderableObjectList shadowPassObjects
QSSGRhiGraphicsPipelineState ps
QSSGBounds3 receivingObjectsBox
void resetForFrame() final
std::unique_ptr< QSSGRenderCamera > debugCamera
void renderPass(QSSGRenderer &renderer) final
std::shared_ptr< QSSGRenderShadowMap > shadowMapManager
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:167
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