Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qssglayerrenderdata_p.h
Go to the documentation of this file.
1// Copyright (C) 2008-2012 NVIDIA Corporation.
2// Copyright (C) 2022 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
6
7#ifndef QSSG_LAYER_RENDER_DATA_H
8#define QSSG_LAYER_RENDER_DATA_H
9
10
11//
12// W A R N I N G
13// -------------
14//
15// This file is not part of the Qt API. It exists purely as an
16// implementation detail. This header file may change from version to
17// version without notice, or even be removed.
18//
19// We mean it.
20//
21
22#include <QtQuick3DRuntimeRender/private/qssgrenderitem2d_p.h>
23#include <QtQuick3DRuntimeRender/private/qssgrenderer_p.h>
24#include <QtQuick3DRuntimeRender/private/qssgrendershadercache_p.h>
25#include <QtQuick3DRuntimeRender/private/qssgrenderableobjects_p.h>
26#include <QtQuick3DRuntimeRender/private/qssgrendershadowmap_p.h>
27#include <QtQuick3DRuntimeRender/private/qssgrendereffect_p.h>
28#include <QtQuick3DRuntimeRender/private/qssgrenderresourceloader_p.h>
29#include <QtQuick3DRuntimeRender/private/qssgrenderreflectionmap_p.h>
30#include <QtQuick3DRuntimeRender/private/qssgrenderskymaterialmanager_p.h>
31#include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h>
32#include <QtQuick3DRuntimeRender/private/qssgrhicontext_p.h>
33#include <QtQuick3DRuntimeRender/private/qssgperframeallocator_p.h>
34#include <QtQuick3DRuntimeRender/private/qssgshadermapkey_p.h>
35#include <QtQuick3DRuntimeRender/private/qssglightmapbaker_p.h>
36#include <QtQuick3DRuntimeRender/private/qssguserrenderpassmanager_p.h>
37#include <ssg/qssgrenderextensions.h>
38
39#include <QtQuick3DUtils/private/qssgrenderbasetypes_p.h>
40
41#include <optional>
42#include <unordered_map>
43
46
48
50
51class QSGRenderer;
52
54{
55
74
75inline QSSGRenderResult::Key toInternalRenderResultKey(QSSGFrameData::RenderResult id)
76{
77 switch (id) {
78 case QSSGFrameData::RenderResult::AoTexture:
80 case QSSGFrameData::RenderResult::DepthTexture:
82 case QSSGFrameData::RenderResult::ScreenTexture:
84 case QSSGFrameData::RenderResult::NormalTexture:
86 case QSSGFrameData::RenderResult::MotionVectorTexture:
88 }
89
90 if (size_t(QSSGRenderResult::Key::CounterImage) > size_t(id))
91 return static_cast<QSSGRenderResult::Key>(size_t(id));
92
94}
95
96} // namespace QSSGRenderResult
97
99{
100 // Was the data in this layer dirty (meaning re-render to texture, possibly)
102
103 // Was the data in this layer dirty *or* this layer *or* any effect dirty.
104 WasDirty = 1 << 1,
105
107
108 // SSAO should be done in a separate pass
109 // Note that having an AO pass necessitates a DepthTexture so this flag should
110 // never be set without the RequiresDepthTexture flag as well.
112
113 // if some light cause shadow
114 // we need a separate per light shadow map pass
116
118
119 // set together with RequiresScreenTexture when SCREEN_MIP_TEXTURE is used
121
122 // Set when material has custom blend mode(not SourceOver)
124
125 // Set when multisampled depth texture is required
127
129
131
133};
134
136{
137 bool wasLayerDataDirty() const
138 {
140 }
141 void setLayerDataDirty(bool inValue)
142 {
144 }
145
146 bool wasDirty() const { return this->operator&(QSSGLayerRenderPreparationResultFlag::WasDirty); }
147 void setWasDirty(bool inValue) { setFlag(QSSGLayerRenderPreparationResultFlag::WasDirty, inValue); }
148
150 {
152 }
153 void setRequiresDepthTexture(bool inValue)
154 {
156 }
157
166
168 void setRequiresSsaoPass(bool inValue)
169 {
171 }
172
174 {
176 }
181
183 {
185 }
190
199
208
210 {
212 }
217
226
235};
236
238{
239public:
240 enum class State : quint8
241 {
242 Null = 0,
245 };
246
248 QSSGLayerRenderPreparationResult(const QRectF &inViewport, QSSGRenderLayer &inLayer);
249
250 void setState(State state) { m_state = state; }
251 State getState() const { return m_state; }
252 bool isNull() const { return !layer && m_state == State::Null; }
253 bool isLayerVisible() const;
254 QSize textureDimensions() const;
255 QRectF getViewport() const { return viewport; }
256 const QSSGLayerRenderPreparationResultFlags &getFlags() const { return flags; }
257 QSSGRenderLayer *getLayer() const { return layer; }
258
259private:
261 friend class QSSGFrameData;
262
264 QRectF viewport;
265 QSSGRenderLayer *layer = nullptr;
266 State m_state = State::Null;
267};
268
279
281{
282 QSSGBakedLightingModel(const QSSGRenderModel *model, const QVector<QSSGRenderableObjectHandle> &renderables)
283 : model(model),
285 { }
286
289};
290
292{
295 QRhiTexture *copyTexture = nullptr;
296 QRhiBuffer *aBuffer = nullptr;
302 void reset()
303 {
304 delete oitRenderTarget;
305 delete renderPassDescriptor;
306 delete copyTexture;
307 delete aBuffer;
308 delete auxBuffer;
309 delete counterBuffer;
310 for (const auto *result : std::as_const(completedResults))
311 delete result;
312 completedResults.clear();
313 if (rub) {
314 rub->release();
315 rub = nullptr;
316 delete pendingResult;
317 } else if (pendingResult) {
318 // Still in flight: QRhi writes to it later, so the completion callback takes ownership.
319 pendingResult->completed = [result = pendingResult] { delete result; };
320 }
321 oitRenderTarget = nullptr;
322 renderPassDescriptor = nullptr;
323 copyTexture = nullptr;
324 aBuffer = nullptr;
325 auxBuffer = nullptr;
326 counterBuffer = nullptr;
327 pendingResult = nullptr;
328 }
329};
330
331class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGLayerRenderData
332{
333public:
334 enum Enum {
335 MAX_AA_LEVELS = 8,
336 MAX_TEMPORAL_AA_LEVELS = 2,
337 };
338
339 using InstanceTransforms = QSSGGlobalRenderNodeData::InstanceTransforms;
340 using ModelViewProjections = QSSGRenderModelData::ModelViewProjections;
341
342 using QSSGModelsView = QSSGDataView<QSSGRenderModel *>;
343 using QSSGParticlesView = QSSGDataView<QSSGRenderParticles *>;
344 using QSSGItem2DsView = QSSGDataView<QSSGRenderItem2D *>;
345 using QSSGCamerasView = QSSGDataView<QSSGRenderCamera *>;
346 using QSSGLightsView = QSSGDataView<QSSGRenderLight *>;
347 using QSSGReflectionProbesView = QSSGDataView<QSSGRenderReflectionProbe *>;
348 using QSSGNonCategorizedView = QSSGDataView<QSSGRenderNode *>;
349
350 using RenderableFilter = std::function<bool(QSSGModelContext *)>;
351
352 QSSGLayerRenderData(QSSGRenderLayer &inLayer, QSSGRenderer &inRenderer);
353 ~QSSGLayerRenderData();
354
355 typedef QVector<QSSGModelContext *> TModelContextPtrList;
356 using RenderableNodeEntries = QVector<QSSGRenderableNodeEntry>;
357 using RenderableItem2DEntries = QVector<QSSGRenderItem2D *>;
358
359 void prepareImageForRender(QSSGRenderImage &inImage,
360 QSSGRenderableImage::Type inMapType,
361 QSSGRenderableImage *&ioFirstImage,
362 QSSGRenderableImage *&ioNextImage,
363 QSSGRenderableObjectFlags &ioFlags,
364 QSSGShaderDefaultMaterialKey &ioGeneratedShaderKey,
365 quint32 inImageIndex, QSSGRenderDefaultMaterial *inMaterial = nullptr);
366
367 void setVertexInputPresence(const QSSGRenderableObjectFlags &renderableFlags,
368 QSSGShaderDefaultMaterialKey &key);
369
370 static void prepareModelBoneTextures(const QSSGRenderContextInterface &contextInterface,
371 const RenderableNodeEntries &renderableModels);
372
373 // Helper functions used during PrepareForRender and PrepareAndRender
374 // Updates lights with model receivesShadows. Do not pass globalLights.
375 bool prepareModelsForRender(QSSGRenderContextInterface &ctx,
376 const RenderableNodeEntries &renderableModels,
377 QSSGLayerRenderPreparationResultFlags &ioFlags,
378 const QSSGRenderCameraList &allCameras,
379 const QSSGRenderCameraDataList &allCameraData,
380 TModelContextPtrList &modelContexts,
381 QSSGRenderableObjectList &opaqueObjects,
382 QSSGRenderableObjectList &transparentObjects,
383 QSSGRenderableObjectList &screenTextureObjects,
384 float lodThreshold = 0.0f);
385 bool prepareParticlesForRender(const RenderableNodeEntries &renderableParticles, const QSSGRenderCameraData &cameraData, QSSGLayerRenderPreparationResultFlags &ioFlags);
386
387 void prepareResourceLoaders();
388
389 void prepareForRender();
390 // Helper function used during prepareForRender
391 void prepareReflectionProbesForRender();
392
393 [[nodiscard]] static qsizetype frustumCullingInline(const QSSGClippingFrustum &clipFrustum, QSSGRenderableObjectList &renderables);
394
395 [[nodiscard]] static qsizetype filterLayerMaskInline(quint32 layerMask, QSSGRenderableObjectList &renderables);
396
397
398 // Per-frame cache of renderable objects post-sort (for the MAIN rendering camera, i.e., don't use these lists for rendering from a different camera).
399 const QSSGRenderableObjectList &getSortedOpaqueRenderableObjects(const QSSGRenderCamera &camera, size_t index = 0, quint32 layerMask = 0xFFFFFFFF);
400 // If layer depth test is false, this may also contain opaque objects.
401 const QSSGRenderableObjectList &getSortedTransparentRenderableObjects(const QSSGRenderCamera &camera, size_t index = 0, quint32 layerMask = 0xFFFFFFFF);
402 const QSSGRenderableObjectList &getSortedScreenTextureRenderableObjects(const QSSGRenderCamera &camera, size_t index = 0);
403 const QVector<QSSGBakedLightingModel> &getSortedBakedLightingModels();
404 const RenderableItem2DEntries &getRenderableItem2Ds();
405 const QSSGRenderableObjectList &getSortedRenderedDepthWriteObjects(const QSSGRenderCamera &camera, size_t index = 0);
406 const QSSGRenderableObjectList &getSortedrenderedOpaqueDepthPrepassObjects(const QSSGRenderCamera &camera, size_t index = 0);
407 void getShadowCastingObjects(const QSSGRenderCamera &camera,
408 QSSGRenderableObjectList &outObjects,
409 QSSGBounds3 &outBoundsCasting,
410 QSSGBounds3 &outBoundsReceiving);
411
412 void resetForFrame();
413
414 QSSGFrameData &getFrameData();
415
416 ShadowMapPass shadowMapPass;
417 ReflectionMapPass reflectionMapPass;
418 ZPrePassPass zPrePassPass;
419 SSAOMapPass ssaoMapPass;
420 DepthMapPass depthMapPass;
421 DepthMapPass depthMapPassMS;
422 SkyMaterialPass skyMaterialPass;
423 ScreenMapPass screenMapPass;
424 ScreenReflectionPass reflectionPass;
425 Item2DPass item2DPass;
426 SkyboxPass skyboxPass;
427 SkyMaterialBackgroundPass skyMaterialBackgroundPass;
428 SkyboxCubeMapPass skyboxCubeMapPass;
429 UserRenderPass userRenderPasses;
430 static constexpr size_t USERPASSES = 3; // See QSSGRenderLayer::RenderExtensionMode::Count
431 UserExtensionPass userPasses[USERPASSES];
432 OpaquePass opaquePass;
433 TransparentPass transparentPass;
434 OITRenderPass oitRenderPass;
435 OITCompositePass oitCompositePass;
436 InfiniteGridPass infiniteGridPass;
437 DebugDrawPass debugDrawPass;
438 NormalPass normalPass;
439 MotionVectorMapPass motionVectorMapPass;
440
441 // Built-in passes
442 QVarLengthArray<QSSGRenderPass *, 16> activePasses;
443
444 QSSGRenderLayer &layer;
445 QSSGRenderer *renderer = nullptr;
446 // List of nodes we can render, not all may be active. Found by doing a depth-first
447 // search through m_FirstChild if length is zero.
448
449 using LayerNodes = std::vector<QSSGRenderNode *>;
450 QSSGGlobalRenderNodeData::LayerNodeView layerNodes;
451
452 // renderableNodes have all lights, but properties configured for specific node
453 RenderableNodeEntries renderableModels;
454 RenderableNodeEntries renderableParticles;
455
456 // Views into the collected nodes (unsorted)
457 class NodeCollection
458 {
459 Q_DISABLE_COPY(NodeCollection)
460 public:
461 NodeCollection() = default;
462
463 QSSGModelsView modelsView;
464 QSSGParticlesView particlesView;
465 QSSGItem2DsView item2DsView;
466 QSSGCamerasView camerasView;
467 QSSGLightsView lightsView;
468 QSSGReflectionProbesView reflectionProbesView;
469 QSSGNonCategorizedView nonCategorizedView;
470 LayerNodes layerNodesCategorized;
471 };
472 NodeCollection nodeCollection;
473 // FIXME: Convenience for now
474 QSSGModelsView &modelsView = nodeCollection.modelsView;
475 QSSGParticlesView &particlesView = nodeCollection.particlesView;
476 QSSGItem2DsView &item2DsView = nodeCollection.item2DsView;
477 QSSGCamerasView &camerasView = nodeCollection.camerasView;
478 QSSGLightsView &lightsView = nodeCollection.lightsView;
479 QSSGReflectionProbesView &reflectionProbesView = nodeCollection.reflectionProbesView;
480 QSSGNonCategorizedView &nonCategorizedView = nodeCollection.nonCategorizedView;
481
482 // Results of prepare for render.
483 QSSGRenderCameraList renderedCameras; // multiple items with multiview, one otherwise (or zero if no cameras at all)
484 QSSGShaderLightList globalLights; // All non-scoped lights
485
486 QVector<QSSGBakedLightingModel> bakedLightingModels;
487 // Sorted lists of the rendered objects. There may be other transforms applied so
488 // it is simplest to duplicate the lists.
489 QVector<QSSGBakedLightingModel> renderedBakedLightingModels;
490 RenderableItem2DEntries renderedItem2Ds;
491
492 QSSGLayerRenderPreparationResult layerPrepResult;
493 std::optional<QSSGRenderCameraDataList> renderedCameraData;
494
495 TModelContextPtrList modelContexts;
496
497 QQsbCollection::EntryMap m_particleShaderEntries;
498
499 bool nonExplicitCameraWithLayerMaskWarningShown = false;
500 bool tooManyLightsWarningShown = false;
501 bool tooManyDirectionalLightsWarningShown = false;
502 bool oitWarningUnsupportedShown = false;
503 bool oitWarningInvalidBlendModeShown = false;
504 bool orderIndependentTransparencyEnabled = false;
505 bool disableMainPasses = true;
506
507 std::unique_ptr<QSSGLightmapBaker> lightmapBaker = nullptr;
508
509 QSSGShaderFeatures getShaderFeatures() const { return features; }
510 QSSGRhiGraphicsPipelineState getPipelineState() const { return ps; }
511
512 void initializeLightmapBaking(QSSGLightmapBaker::Context &ctx);
513 void maybeProcessLightmapBaking();
514
515 [[nodiscard]] QSSGRenderGraphObject *getCamera(QSSGCameraId id) const;
516 [[nodiscard]] QSSGRenderCamera *activeCamera() const { return !renderedCameras.isEmpty() ? renderedCameras[0] : nullptr; }
517
518 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(const QSSGRenderCamera *camera);
519 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(const QSSGRenderCamera *camera) const;
520
521 void setLightmapTexture(const QSSGModelContext &modelContext, QRhiTexture *lightmapTexture);
522 [[nodiscard]] QRhiTexture *getLightmapTexture(const QSSGModelContext &modelContext) const;
523
524 void setBonemapTexture(const QSSGModelContext &modelContext, QRhiTexture *bonemapTexture);
525 [[nodiscard]] QRhiTexture *getBonemapTexture(const QSSGModelContext &modelContext) const;
526
527 [[nodiscard]] QSSGRenderContextInterface *contextInterface() const;
528 // Note: temp. API to report the state of the z-prepass step
529 [[nodiscard]] bool isZPrePassActive() const { return zPrePassActive; }
530 void setZPrePassPrepResult(bool res) { zPrePassActive = res; }
531
532 // Exposed as const, as we often need to use this to look-up values from a specific key.
533 [[nodiscard]] const QSSGShaderDefaultMaterialKeyProperties &getDefaultMaterialPropertyTable() const
534 {
535 return defaultMaterialShaderKeyProperties;
536 }
537 [[nodiscard]] const QSSGShaderParticleMaterialKeyProperties &getParticleMaterialPropertyTable() const
538 {
539 return particleMaterialShaderKeyProperties;
540 }
541
542 struct GlobalRenderProperties
543 {
544 bool isYUpInFramebuffer = true;
545 bool isYUpInNDC = true;
546 bool isClipDepthZeroToOne = true;
547 };
548
549 [[nodiscard]] static GlobalRenderProperties globalRenderProperties(const QSSGRenderContextInterface &ctx);
550
551 // Temp. API. Ideally there shouldn't be a reason for anyone to hold onto these,
552 // but we follow the existing pattern for now.
553 const QSSGRenderShadowMapPtr &requestShadowMapManager();
554 const QSSGRenderReflectionMapPtr &requestReflectionMapManager();
555 const QSSGRenderSkyMaterialManagerPtr &requestSkyMaterialManager();
556 const QSSGUserRenderPassManagerPtr &requestUserRenderPassManager();
557 const QSSGRenderMotionVectorMapPtr &requestMotionVectorMapManager();
558 const QSSGRenderShadowMapPtr &getShadowMapManager() const { return shadowMapManager; }
559 const QSSGRenderReflectionMapPtr &getReflectionMapManager() const { return reflectionMapManager; }
560 const QSSGRenderSkyMaterialManagerPtr &getSkyMaterialManager() const { return skyMaterialManager; }
561 const QSSGUserRenderPassManagerPtr &getUserRenderPassManager() const { return userRenderPassManager; }
562 const QSSGRenderMotionVectorMapPtr &getMotionvectorMapManager() const { return motionVectorMapManager; }
563
564 QSSGOITRenderContext &getOitRenderContext() { return oitRenderContext; }
565 const QSSGOITRenderContext &getOitRenderContextConst() const { return oitRenderContext; }
566
567 static bool prepareInstancing(QSSGRhiContext *rhiCtx,
568 QSSGSubsetRenderable *renderable,
569 const QVector3D &cameraDirection,
570 const QVector3D &cameraPosition,
571 float minThreshold,
572 float maxThreshold);
573
574 [[nodiscard]] QSSGRhiRenderableTexture *getRenderResult(QSSGRenderResult::Key id) { return &renderResults[size_t(id)]; }
575 [[nodiscard]] const QSSGRhiRenderableTexture *getRenderResult(QSSGRenderResult::Key id) const { return &renderResults[size_t(id)]; }
576
577 QSSGRenderImageTexture skyMaterialTexture; // Always a cubemap, might be IBL
578 void resolveLayerIblTexture(QSSGPassKey passKey);
579
580 [[nodiscard]] static inline const std::unique_ptr<QSSGPerFrameAllocator> &perFrameAllocator(QSSGRenderContextInterface &ctx);
581 [[nodiscard]] static inline QSSGLayerRenderData *getCurrent(const QSSGRenderer &renderer) { return renderer.m_currentLayer; }
582 void saveRenderState(const QSSGRenderer &renderer);
583 void restoreRenderState(QSSGRenderer &renderer);
584
585 static void setTonemapFeatures(QSSGShaderFeatures &features, QSSGRenderLayer::TonemapMode tonemapMode)
586 {
587 features.set(QSSGShaderFeatures::Feature::LinearTonemapping,
588 tonemapMode == QSSGRenderLayer::TonemapMode::Linear);
589 features.set(QSSGShaderFeatures::Feature::AcesTonemapping,
590 tonemapMode == QSSGRenderLayer::TonemapMode::Aces);
591 features.set(QSSGShaderFeatures::Feature::HejlDawsonTonemapping,
592 tonemapMode == QSSGRenderLayer::TonemapMode::HejlDawson);
593 features.set(QSSGShaderFeatures::Feature::FilmicTonemapping,
594 tonemapMode == QSSGRenderLayer::TonemapMode::Filmic);
595 features.set(QSSGShaderFeatures::Feature::ForceIblExposure,
596 tonemapMode == QSSGRenderLayer::TonemapMode::Custom);
597 }
598
599 QSSGPrepContextId getOrCreateExtensionContext(const QSSGRenderExtension &ext,
600 QSSGRenderCamera *camera = nullptr,
601 quint32 slot = 0);
602
603 // Model API
604 QSSGRenderablesId createRenderables(QSSGPrepContextId prepId, const QSSGNodeIdList &nodes, QSSGRenderHelpers::CreateFlags createFlags);
605 void setGlobalTransform(QSSGRenderablesId renderablesId, const QSSGRenderModel &model, const QMatrix4x4 &mvp);
606 QMatrix4x4 getGlobalTransform(QSSGPrepContextId prepId, const QSSGRenderModel &model);
607 void setGlobalOpacity(QSSGRenderablesId renderablesId, const QSSGRenderModel &model, float opacity);
608 float getGlobalOpacity(QSSGPrepContextId prepId, const QSSGRenderModel &model);
609 [[nodiscard]] QMatrix4x4 getModelMvps(QSSGPrepContextId prepId, const QSSGRenderModel &model) const;
610 void setModelMaterials(QSSGRenderablesId renderablesId, const QSSGRenderModel &model, const QList<QSSGResourceId> &materials);
611 void setModelMaterials(const QSSGRenderablesId renderablesId, const QList<QSSGResourceId> &materials);
612 [[nodiscard]] QSSGPrepResultId prepareModelsForRender(QSSGRenderContextInterface &contextInterface,
613 QSSGPrepContextId prepId,
614 QSSGRenderablesId renderablesId,
615 float lodThreshold);
616
617 // Convenience wrappers for getting values from the node, model store.
618 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h, const QMatrix4x4 &defaultValue) const
619 {
620 return nodeData->getGlobalTransform(h, defaultValue);
621 }
622 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h) const
623 {
624 return nodeData->getGlobalTransform(h, QMatrix4x4());
625 }
626 [[nodiscard]] QMatrix4x4 getGlobalTransform(const QSSGRenderNode &node) const
627 {
628 return nodeData->getGlobalTransform(node.h, node.localTransform);
629 }
630 [[nodiscard]] QMatrix3x3 getNormalMatrix(QSSGRenderNodeHandle h) const
631 {
632 return modelData->getNormalMatrix(h, QMatrix3x3(Qt::Uninitialized));
633 }
634 [[nodiscard]] QMatrix3x3 getNormalMatrix(const QSSGRenderModel &model) const
635 {
636 return modelData->getNormalMatrix(model);
637 }
638 [[nodiscard]] ModelViewProjections getModelMvps(QSSGRenderNodeHandle h) const
639 {
640 return modelData->getModelViewProjection(h);
641 }
642 [[nodiscard]] ModelViewProjections getModelMvps(const QSSGRenderModel &model) const
643 {
644 return modelData->getModelViewProjection(model);
645 }
646 [[nodiscard]] InstanceTransforms getInstanceTransforms(QSSGRenderNodeHandle h) const
647 {
648 return nodeData->getInstanceTransforms(h);
649 }
650 [[nodiscard]] InstanceTransforms getInstanceTransforms(const QSSGRenderNode &node) const
651 {
652 return nodeData->getInstanceTransforms(node.h);
653 }
654 [[nodiscard]] float getGlobalOpacity(QSSGRenderNodeHandle h, float defaultValue = 1.0f) const
655 {
656 return nodeData->getGlobalOpacity(h, defaultValue);
657 }
658 [[nodiscard]] float getGlobalOpacity(const QSSGRenderNode &node) const
659 {
660 return nodeData->getGlobalOpacity(node.h);
661 }
662
663 //
664 [[nodiscard]] QSSGRenderItem2DData::Item2DRenderer getItem2DRenderer(const QSSGRenderItem2D &item) const
665 {
666 return item2DData->getItem2DRenderer(item);
667 }
668
669 [[nodiscard]] ModelViewProjections getItem2DMvps(QSSGRenderNodeHandle h) const
670 {
671 return item2DData->getModelViewProjection(h);
672 }
673
674 [[nodiscard]] ModelViewProjections getItem2DMvps(const QSSGRenderItem2D &item) const
675 {
676 return item2DData->getModelViewProjection(item);
677 }
678
679
680 //
681 void prepareRenderables(QSSGRenderContextInterface &ctx,
682 QSSGPrepResultId prepId,
683 QRhiRenderPassDescriptor *renderPassDescriptor,
684 const QSSGRhiGraphicsPipelineState &ps,
685 QSSGRenderablesFilters filter);
686 void renderRenderables(QSSGRenderContextInterface &ctx,
687 QSSGPrepResultId prepId);
688
689 static bool calculateGlobalVariables(QSSGRenderNode &node,
690 std::vector<QMatrix4x4> &globalTransforms,
691 std::vector<float> &globalOpacities);
692
693 QSSGRenderCameraData getCameraDataImpl(const QSSGRenderCamera *camera) const;
694
695 static QSSGNodeIdList filter(const QSSGGlobalRenderNodeData::LayerNodeView &layerNodes,
696 quint32 layerMask,
697 quint32 typeMask);
698
699 [[nodiscard]] static QSSGLayerRenderData *getCurrent(const QSSGFrameData &data) { return data.getCurrent(); }
700
701 QSSGDefaultMaterialPreparationResult prepareDefaultMaterialForRender(QSSGRenderDefaultMaterial &inMaterial,
702 QSSGRenderableObjectFlags &inExistingFlags,
703 float inOpacity,
704 bool hasAnyLights,
705 bool anyLightHasShadows,
706 QSSGLayerRenderPreparationResultFlags &ioFlags);
707
708 QSSGDefaultMaterialPreparationResult prepareCustomMaterialForRender(QSSGRenderCustomMaterial &inMaterial,
709 QSSGRenderableObjectFlags &inExistingFlags,
710 float inOpacity, bool alreadyDirty,
711 bool hasAnyLights,
712 bool anyLightHasShadows,
713 QSSGLayerRenderPreparationResultFlags &ioFlags);
714
715 static void categorizeAndFilterNodes(const QSSGGlobalRenderNodeData::LayerNodeView &layerNodes,
716 QSSGLayerRenderData::NodeCollection &nodeCollection,
717 quint32 layerMask);
718 void updateFilteredLayerNodes(quint32 layerMask);
719private:
720 friend class QSSGRenderer;
721 friend class QSSGRendererPrivate;
722 friend class QSSGFrameData;
723 friend class QSSGModelHelpers;
724 friend class QSSGRenderHelpers;
725 friend class QSSGParticleRenderer;
726
727 class ExtensionContext
728 {
729 public:
730 explicit ExtensionContext() = default;
731 explicit ExtensionContext(const QSSGRenderExtension &ownerExt, QSSGRenderCamera *cam, size_t idx, quint32 slot)
732 : owner(&ownerExt), camera(cam), ps{}, filter{0}, index(idx), slot(slot)
733 { }
734 const QSSGRenderExtension *owner = nullptr;
735 QSSGRenderCamera *camera = nullptr;
736 QSSGRhiGraphicsPipelineState ps[3] {};
737 QSSGRenderablesFilters filter { 0 };
738 size_t index = 0; // index into the model store
739 quint32 slot = 0;
740 };
741
742 std::vector<ExtensionContext> extContexts { ExtensionContext{ /* 0 - Always available */ } };
743 std::vector<RenderableNodeEntries> renderableModelStore { RenderableNodeEntries{ /* 0 - Always available */ } };
744 std::vector<TModelContextPtrList> modelContextStore { TModelContextPtrList{ /* 0 - Always available */ }};
745 std::vector<QSSGRenderableObjectList> renderableObjectStore { QSSGRenderableObjectList{ /* 0 - Always available */ }};
746 std::vector<QSSGRenderableObjectList> opaqueObjectStore { QSSGRenderableObjectList{ /* 0 - Always available */ }};
747 std::vector<QSSGRenderableObjectList> transparentObjectStore { QSSGRenderableObjectList{ /* 0 - Always available */ }};
748 std::vector<QSSGRenderableObjectList> screenTextureObjectStore { QSSGRenderableObjectList{ /* 0 - Always available */ }};
749
750 std::shared_ptr<QSSGGlobalRenderNodeData> nodeData;
751 std::unique_ptr<QSSGRenderModelData> modelData;
752 std::unique_ptr<QSSGRenderItem2DData> item2DData;
753
754 // Soreted cache (per camera and extension)
755 using CameraKey = std::pair<const QSSGRenderCamera*, uint32_t>;
756
757 struct CameraKeyHash {
758 std::size_t operator()(const CameraKey& k) const noexcept {
759 // Hash combine: pointer hash ^ (uint hash shifted)
760 return std::hash<const QSSGRenderCamera*>()(k.first) ^
761 (std::hash<uint32_t>()(k.second) << 1);
762 }
763 };
764
765 struct CameraKeyEq {
766 bool operator()(const CameraKey& a, const CameraKey& b) const noexcept {
767 return a.first == b.first && a.second == b.second;
768 }
769 };
770
771 using PerCameraCache = std::unordered_map<CameraKey, QSSGRenderableObjectList, CameraKeyHash, CameraKeyEq>;
772 std::vector<PerCameraCache> sortedOpaqueObjectCache { PerCameraCache{ /* 0 - Always available */ } };
773 std::vector<PerCameraCache> sortedTransparentObjectCache { PerCameraCache{ /* 0 - Always available */ } };
774 std::vector<PerCameraCache> sortedScreenTextureObjectCache { PerCameraCache{ /* 0 - Always available */ } };
775 std::vector<PerCameraCache> sortedOpaqueDepthPrepassCache { PerCameraCache{ /* 0 - Always available */ } };
776 std::vector<PerCameraCache> sortedDepthWriteCache { PerCameraCache{ /* 0 - Always available */ } };
777
778 [[nodiscard]] const QSSGRenderCameraDataList &getCachedCameraDatas();
779 void ensureCachedCameraDatas();
780 void updateSortedDepthObjectsListImp(const QSSGRenderCamera &camera, size_t index);
781
782 static void prepareModelMaterials(RenderableNodeEntries &renderableModels, bool cullUnrenderables);
783 static void prepareModelMaterials(const RenderableNodeEntries::ConstIterator &begin,
784 const RenderableNodeEntries::ConstIterator &end);
785
786 // Persistent data
787 QHash<QSSGShaderMapKey, QSSGRhiShaderPipelinePtr> shaderMap;
788 QHash<QSSGParticleShaderMapKey, QSSGRhiShaderPipelinePtr> particleShaderMap;
789
790 // Cached buffer.
791 QByteArray generatedShaderString;
792
793 // Saved render state (for sublayers)
794 struct SavedRenderState
795 {
796 QRect viewport;
797 QRect scissorRect;
798 float dpr = 1.0;
799 // The main pass state on the shared rhi context. A sublayer can contain a
800 // nested 3D scene, e.g. a View3D inside an Item2D, which renders to its own
801 // target and leaves its own state behind on the context. The passes of this
802 // layer that come after would otherwise build their graphics pipelines for
803 // that target's render pass and sample count instead of their own.
804 QRhiRenderPassDescriptor *mainRenderPassDescriptor = nullptr;
805 QRhiRenderTarget *renderTarget = nullptr;
806 QRhiCommandBuffer *commandBuffer = nullptr;
807 int mainPassSampleCount = 1;
808 int mainPassViewCount = 1;
809 };
810
811 std::optional<SavedRenderState> savedRenderState;
812
813 // Note: Re-used to avoid expensive initialization.
814 // - Should be revisit, as we can do better.
815 QSSGShaderDefaultMaterialKeyProperties defaultMaterialShaderKeyProperties;
816 QSSGShaderParticleMaterialKeyProperties particleMaterialShaderKeyProperties;
817 QSSGFrameData frameData;
818 QSSGRhiGraphicsPipelineState ps; // Base pipleline state
819 QSSGShaderFeatures features; // Base feature set
820 QSSGRenderNodeVersionType version = 0;
821 QSSGRenderNodeVersionType stateGeneration = 0; // Last seen QSSGGlobalRenderNodeData::stateGeneration()
822 bool particlesEnabled = true;
823 bool hasDepthWriteObjects = false;
824 bool zPrePassActive = false;
825 // NOTE: For the time being we need to keep track of extensions modifying the renderables
826 // because then we need to reset the lists.
827 // FIXME: This should be revisited, as we can do better (hence the verbose name).
828 bool renderablesModifiedByExtension = false;
829 enum class DepthPrepassObject : quint8
830 {
831 None = 0x0,
832 ScreenTexture = 0x1,
833 Transparent = 0x2,
834 Opaque = 0x4
835 };
836 using DepthPrepassObjectStateT = std::underlying_type_t<DepthPrepassObject>;
837 DepthPrepassObjectStateT depthPrepassObjectsState { DepthPrepassObjectStateT(DepthPrepassObject::None) };
838 QSSGRenderShadowMapPtr shadowMapManager;
839 QSSGRenderReflectionMapPtr reflectionMapManager;
840 QSSGRenderSkyMaterialManagerPtr skyMaterialManager;
841 QSSGUserRenderPassManagerPtr userRenderPassManager;
842 QSSGRenderMotionVectorMapPtr motionVectorMapManager;
843 QHash<const QSSGModelContext *, QRhiTexture *> lightmapTextures;
844 QHash<const QSSGModelContext *, QRhiTexture *> bonemapTextures;
845 QSSGRhiRenderableTexture renderResults[size_t(QSSGRenderResult::Key::RenderResultCount)] {};
846 QSSGOITRenderContext oitRenderContext;
847};
848
849QT_END_NAMESPACE
850
851#endif // QSSG_LAYER_RENDER_DATA_H
QSSGLayerRenderPreparationResult(const QRectF &inViewport, QSSGRenderLayer &inLayer)
const QSSGLayerRenderPreparationResultFlags & getFlags() const
QSSGRenderResult::Key toInternalRenderResultKey(QSSGFrameData::RenderResult id)
Combined button and popup list for selecting options.
QSSGLayerRenderPreparationResultFlag
static const char * effect_fragment_main_with_tonemapping
static const char * effect_vertex_main_post
static const char * effect_vertex_main_pre
static const char * effect_vertex_main_position
static const char * effect_fragment_main
QVector< QSSGRenderableObjectHandle > renderables
QSSGBakedLightingModel(const QSSGRenderModel *model, const QVector< QSSGRenderableObjectHandle > &renderables)
const QSSGRenderModel * model
QSSGDefaultMaterialPreparationResult(QSSGShaderDefaultMaterialKey inMaterialKey)
QSSGShaderDefaultMaterialKey materialKey
QRhiReadbackResult * pendingResult
QList< QRhiReadbackResult * > completedResults
QRhiTextureRenderTarget * oitRenderTarget
QRhiResourceUpdateBatch * rub
QRhiRenderPassDescriptor * renderPassDescriptor