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;
299 void reset()
300 {
301 delete oitRenderTarget;
302 delete renderPassDescriptor;
303 delete copyTexture;
304 delete aBuffer;
305 delete auxBuffer;
306 delete counterBuffer;
307 oitRenderTarget = nullptr;
308 renderPassDescriptor = nullptr;
309 copyTexture = nullptr;
310 aBuffer = nullptr;
311 auxBuffer = nullptr;
312 counterBuffer = nullptr;
313 }
314};
315
316class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGLayerRenderData
317{
318public:
319 enum Enum {
320 MAX_AA_LEVELS = 8,
321 MAX_TEMPORAL_AA_LEVELS = 2,
322 };
323
324 using InstanceTransforms = QSSGGlobalRenderNodeData::InstanceTransforms;
325 using ModelViewProjections = QSSGRenderModelData::ModelViewProjections;
326
327 using QSSGModelsView = QSSGDataView<QSSGRenderModel *>;
328 using QSSGParticlesView = QSSGDataView<QSSGRenderParticles *>;
329 using QSSGItem2DsView = QSSGDataView<QSSGRenderItem2D *>;
330 using QSSGCamerasView = QSSGDataView<QSSGRenderCamera *>;
331 using QSSGLightsView = QSSGDataView<QSSGRenderLight *>;
332 using QSSGReflectionProbesView = QSSGDataView<QSSGRenderReflectionProbe *>;
333 using QSSGNonCategorizedView = QSSGDataView<QSSGRenderNode *>;
334
335 using RenderableFilter = std::function<bool(QSSGModelContext *)>;
336
337 QSSGLayerRenderData(QSSGRenderLayer &inLayer, QSSGRenderer &inRenderer);
338 ~QSSGLayerRenderData();
339
340 typedef QVector<QSSGModelContext *> TModelContextPtrList;
341 using RenderableNodeEntries = QVector<QSSGRenderableNodeEntry>;
342 using RenderableItem2DEntries = QVector<QSSGRenderItem2D *>;
343
344 void prepareImageForRender(QSSGRenderImage &inImage,
345 QSSGRenderableImage::Type inMapType,
346 QSSGRenderableImage *&ioFirstImage,
347 QSSGRenderableImage *&ioNextImage,
348 QSSGRenderableObjectFlags &ioFlags,
349 QSSGShaderDefaultMaterialKey &ioGeneratedShaderKey,
350 quint32 inImageIndex, QSSGRenderDefaultMaterial *inMaterial = nullptr);
351
352 void setVertexInputPresence(const QSSGRenderableObjectFlags &renderableFlags,
353 QSSGShaderDefaultMaterialKey &key);
354
355 static void prepareModelBoneTextures(const QSSGRenderContextInterface &contextInterface,
356 const RenderableNodeEntries &renderableModels);
357
358 // Helper functions used during PrepareForRender and PrepareAndRender
359 // Updates lights with model receivesShadows. Do not pass globalLights.
360 bool prepareModelsForRender(QSSGRenderContextInterface &ctx,
361 const RenderableNodeEntries &renderableModels,
362 QSSGLayerRenderPreparationResultFlags &ioFlags,
363 const QSSGRenderCameraList &allCameras,
364 const QSSGRenderCameraDataList &allCameraData,
365 TModelContextPtrList &modelContexts,
366 QSSGRenderableObjectList &opaqueObjects,
367 QSSGRenderableObjectList &transparentObjects,
368 QSSGRenderableObjectList &screenTextureObjects,
369 float lodThreshold = 0.0f);
370 bool prepareParticlesForRender(const RenderableNodeEntries &renderableParticles, const QSSGRenderCameraData &cameraData, QSSGLayerRenderPreparationResultFlags &ioFlags);
371
372 void prepareResourceLoaders();
373
374 void prepareForRender();
375 // Helper function used during prepareForRender
376 void prepareReflectionProbesForRender();
377
378 [[nodiscard]] static qsizetype frustumCullingInline(const QSSGClippingFrustum &clipFrustum, QSSGRenderableObjectList &renderables);
379
380 [[nodiscard]] static qsizetype filterLayerMaskInline(quint32 layerMask, QSSGRenderableObjectList &renderables);
381
382
383 // 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).
384 const QSSGRenderableObjectList &getSortedOpaqueRenderableObjects(const QSSGRenderCamera &camera, size_t index = 0, quint32 layerMask = 0xFFFFFFFF);
385 // If layer depth test is false, this may also contain opaque objects.
386 const QSSGRenderableObjectList &getSortedTransparentRenderableObjects(const QSSGRenderCamera &camera, size_t index = 0, quint32 layerMask = 0xFFFFFFFF);
387 const QSSGRenderableObjectList &getSortedScreenTextureRenderableObjects(const QSSGRenderCamera &camera, size_t index = 0);
388 const QVector<QSSGBakedLightingModel> &getSortedBakedLightingModels();
389 const RenderableItem2DEntries &getRenderableItem2Ds();
390 const QSSGRenderableObjectList &getSortedRenderedDepthWriteObjects(const QSSGRenderCamera &camera, size_t index = 0);
391 const QSSGRenderableObjectList &getSortedrenderedOpaqueDepthPrepassObjects(const QSSGRenderCamera &camera, size_t index = 0);
392 void getShadowCastingObjects(const QSSGRenderCamera &camera,
393 QSSGRenderableObjectList &outObjects,
394 QSSGBounds3 &outBoundsCasting,
395 QSSGBounds3 &outBoundsReceiving);
396
397 void resetForFrame();
398
399 QSSGFrameData &getFrameData();
400
401 ShadowMapPass shadowMapPass;
402 ReflectionMapPass reflectionMapPass;
403 ZPrePassPass zPrePassPass;
404 SSAOMapPass ssaoMapPass;
405 DepthMapPass depthMapPass;
406 DepthMapPass depthMapPassMS;
407 SkyMaterialPass skyMaterialPass;
408 ScreenMapPass screenMapPass;
409 ScreenReflectionPass reflectionPass;
410 Item2DPass item2DPass;
411 SkyboxPass skyboxPass;
412 SkyMaterialBackgroundPass skyMaterialBackgroundPass;
413 SkyboxCubeMapPass skyboxCubeMapPass;
414 UserRenderPass userRenderPasses;
415 static constexpr size_t USERPASSES = 3; // See QSSGRenderLayer::RenderExtensionMode::Count
416 UserExtensionPass userPasses[USERPASSES];
417 OpaquePass opaquePass;
418 TransparentPass transparentPass;
419 OITRenderPass oitRenderPass;
420 OITCompositePass oitCompositePass;
421 InfiniteGridPass infiniteGridPass;
422 DebugDrawPass debugDrawPass;
423 NormalPass normalPass;
424 MotionVectorMapPass motionVectorMapPass;
425
426 // Built-in passes
427 QVarLengthArray<QSSGRenderPass *, 16> activePasses;
428
429 QSSGRenderLayer &layer;
430 QSSGRenderer *renderer = nullptr;
431 // List of nodes we can render, not all may be active. Found by doing a depth-first
432 // search through m_FirstChild if length is zero.
433
434 using LayerNodes = std::vector<QSSGRenderNode *>;
435 QSSGGlobalRenderNodeData::LayerNodeView layerNodes;
436
437 // renderableNodes have all lights, but properties configured for specific node
438 RenderableNodeEntries renderableModels;
439 RenderableNodeEntries renderableParticles;
440
441 // Views into the collected nodes (unsorted)
442 class NodeCollection
443 {
444 Q_DISABLE_COPY(NodeCollection)
445 public:
446 NodeCollection() = default;
447
448 QSSGModelsView modelsView;
449 QSSGParticlesView particlesView;
450 QSSGItem2DsView item2DsView;
451 QSSGCamerasView camerasView;
452 QSSGLightsView lightsView;
453 QSSGReflectionProbesView reflectionProbesView;
454 QSSGNonCategorizedView nonCategorizedView;
455 LayerNodes layerNodesCategorized;
456 };
457 NodeCollection nodeCollection;
458 // FIXME: Convenience for now
459 QSSGModelsView &modelsView = nodeCollection.modelsView;
460 QSSGParticlesView &particlesView = nodeCollection.particlesView;
461 QSSGItem2DsView &item2DsView = nodeCollection.item2DsView;
462 QSSGCamerasView &camerasView = nodeCollection.camerasView;
463 QSSGLightsView &lightsView = nodeCollection.lightsView;
464 QSSGReflectionProbesView &reflectionProbesView = nodeCollection.reflectionProbesView;
465 QSSGNonCategorizedView &nonCategorizedView = nodeCollection.nonCategorizedView;
466
467 // Results of prepare for render.
468 QSSGRenderCameraList renderedCameras; // multiple items with multiview, one otherwise (or zero if no cameras at all)
469 QSSGShaderLightList globalLights; // All non-scoped lights
470
471 QVector<QSSGBakedLightingModel> bakedLightingModels;
472 // Sorted lists of the rendered objects. There may be other transforms applied so
473 // it is simplest to duplicate the lists.
474 QVector<QSSGBakedLightingModel> renderedBakedLightingModels;
475 RenderableItem2DEntries renderedItem2Ds;
476
477 QSSGLayerRenderPreparationResult layerPrepResult;
478 std::optional<QSSGRenderCameraDataList> renderedCameraData;
479
480 TModelContextPtrList modelContexts;
481
482 QQsbCollection::EntryMap m_particleShaderEntries;
483
484 bool nonExplicitCameraWithLayerMaskWarningShown = false;
485 bool tooManyLightsWarningShown = false;
486 bool tooManyDirectionalLightsWarningShown = false;
487 bool oitWarningUnsupportedShown = false;
488 bool oitWarningInvalidBlendModeShown = false;
489 bool orderIndependentTransparencyEnabled = false;
490 bool disableMainPasses = true;
491
492 std::unique_ptr<QSSGLightmapBaker> lightmapBaker = nullptr;
493
494 QSSGShaderFeatures getShaderFeatures() const { return features; }
495 QSSGRhiGraphicsPipelineState getPipelineState() const { return ps; }
496
497 void initializeLightmapBaking(QSSGLightmapBaker::Context &ctx);
498 void maybeProcessLightmapBaking();
499
500 [[nodiscard]] QSSGRenderGraphObject *getCamera(QSSGCameraId id) const;
501 [[nodiscard]] QSSGRenderCamera *activeCamera() const { return !renderedCameras.isEmpty() ? renderedCameras[0] : nullptr; }
502
503 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(const QSSGRenderCamera *camera);
504 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(const QSSGRenderCamera *camera) const;
505
506 void setLightmapTexture(const QSSGModelContext &modelContext, QRhiTexture *lightmapTexture);
507 [[nodiscard]] QRhiTexture *getLightmapTexture(const QSSGModelContext &modelContext) const;
508
509 void setBonemapTexture(const QSSGModelContext &modelContext, QRhiTexture *bonemapTexture);
510 [[nodiscard]] QRhiTexture *getBonemapTexture(const QSSGModelContext &modelContext) const;
511
512 [[nodiscard]] QSSGRenderContextInterface *contextInterface() const;
513 // Note: temp. API to report the state of the z-prepass step
514 [[nodiscard]] bool isZPrePassActive() const { return zPrePassActive; }
515 void setZPrePassPrepResult(bool res) { zPrePassActive = res; }
516
517 // Exposed as const, as we often need to use this to look-up values from a specific key.
518 [[nodiscard]] const QSSGShaderDefaultMaterialKeyProperties &getDefaultMaterialPropertyTable() const
519 {
520 return defaultMaterialShaderKeyProperties;
521 }
522 [[nodiscard]] const QSSGShaderParticleMaterialKeyProperties &getParticleMaterialPropertyTable() const
523 {
524 return particleMaterialShaderKeyProperties;
525 }
526
527 struct GlobalRenderProperties
528 {
529 bool isYUpInFramebuffer = true;
530 bool isYUpInNDC = true;
531 bool isClipDepthZeroToOne = true;
532 };
533
534 [[nodiscard]] static GlobalRenderProperties globalRenderProperties(const QSSGRenderContextInterface &ctx);
535
536 // Temp. API. Ideally there shouldn't be a reason for anyone to hold onto these,
537 // but we follow the existing pattern for now.
538 const QSSGRenderShadowMapPtr &requestShadowMapManager();
539 const QSSGRenderReflectionMapPtr &requestReflectionMapManager();
540 const QSSGRenderSkyMaterialManagerPtr &requestSkyMaterialManager();
541 const QSSGUserRenderPassManagerPtr &requestUserRenderPassManager();
542 const QSSGRenderMotionVectorMapPtr &requestMotionVectorMapManager();
543 const QSSGRenderShadowMapPtr &getShadowMapManager() const { return shadowMapManager; }
544 const QSSGRenderReflectionMapPtr &getReflectionMapManager() const { return reflectionMapManager; }
545 const QSSGRenderSkyMaterialManagerPtr &getSkyMaterialManager() const { return skyMaterialManager; }
546 const QSSGUserRenderPassManagerPtr &getUserRenderPassManager() const { return userRenderPassManager; }
547 const QSSGRenderMotionVectorMapPtr &getMotionvectorMapManager() const { return motionVectorMapManager; }
548
549 QSSGOITRenderContext &getOitRenderContext() { return oitRenderContext; }
550 const QSSGOITRenderContext &getOitRenderContextConst() const { return oitRenderContext; }
551
552 static bool prepareInstancing(QSSGRhiContext *rhiCtx,
553 QSSGSubsetRenderable *renderable,
554 const QVector3D &cameraDirection,
555 const QVector3D &cameraPosition,
556 float minThreshold,
557 float maxThreshold);
558
559 [[nodiscard]] QSSGRhiRenderableTexture *getRenderResult(QSSGRenderResult::Key id) { return &renderResults[size_t(id)]; }
560 [[nodiscard]] const QSSGRhiRenderableTexture *getRenderResult(QSSGRenderResult::Key id) const { return &renderResults[size_t(id)]; }
561
562 QSSGRenderImageTexture skyMaterialTexture; // Always a cubemap, might be IBL
563 void resolveLayerIblTexture();
564
565 [[nodiscard]] static inline const std::unique_ptr<QSSGPerFrameAllocator> &perFrameAllocator(QSSGRenderContextInterface &ctx);
566 [[nodiscard]] static inline QSSGLayerRenderData *getCurrent(const QSSGRenderer &renderer) { return renderer.m_currentLayer; }
567 void saveRenderState(const QSSGRenderer &renderer);
568 void restoreRenderState(QSSGRenderer &renderer);
569
570 static void setTonemapFeatures(QSSGShaderFeatures &features, QSSGRenderLayer::TonemapMode tonemapMode)
571 {
572 features.set(QSSGShaderFeatures::Feature::LinearTonemapping,
573 tonemapMode == QSSGRenderLayer::TonemapMode::Linear);
574 features.set(QSSGShaderFeatures::Feature::AcesTonemapping,
575 tonemapMode == QSSGRenderLayer::TonemapMode::Aces);
576 features.set(QSSGShaderFeatures::Feature::HejlDawsonTonemapping,
577 tonemapMode == QSSGRenderLayer::TonemapMode::HejlDawson);
578 features.set(QSSGShaderFeatures::Feature::FilmicTonemapping,
579 tonemapMode == QSSGRenderLayer::TonemapMode::Filmic);
580 features.set(QSSGShaderFeatures::Feature::ForceIblExposure,
581 tonemapMode == QSSGRenderLayer::TonemapMode::Custom);
582 }
583
584 QSSGPrepContextId getOrCreateExtensionContext(const QSSGRenderExtension &ext,
585 QSSGRenderCamera *camera = nullptr,
586 quint32 slot = 0);
587
588 // Model API
589 QSSGRenderablesId createRenderables(QSSGPrepContextId prepId, const QSSGNodeIdList &nodes, QSSGRenderHelpers::CreateFlags createFlags);
590 void setGlobalTransform(QSSGRenderablesId renderablesId, const QSSGRenderModel &model, const QMatrix4x4 &mvp);
591 QMatrix4x4 getGlobalTransform(QSSGPrepContextId prepId, const QSSGRenderModel &model);
592 void setGlobalOpacity(QSSGRenderablesId renderablesId, const QSSGRenderModel &model, float opacity);
593 float getGlobalOpacity(QSSGPrepContextId prepId, const QSSGRenderModel &model);
594 [[nodiscard]] QMatrix4x4 getModelMvps(QSSGPrepContextId prepId, const QSSGRenderModel &model) const;
595 void setModelMaterials(QSSGRenderablesId renderablesId, const QSSGRenderModel &model, const QList<QSSGResourceId> &materials);
596 void setModelMaterials(const QSSGRenderablesId renderablesId, const QList<QSSGResourceId> &materials);
597 [[nodiscard]] QSSGPrepResultId prepareModelsForRender(QSSGRenderContextInterface &contextInterface,
598 QSSGPrepContextId prepId,
599 QSSGRenderablesId renderablesId,
600 float lodThreshold);
601
602 // Convenience wrappers for getting values from the node, model store.
603 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h, const QMatrix4x4 &defaultValue) const
604 {
605 return nodeData->getGlobalTransform(h, defaultValue);
606 }
607 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h) const
608 {
609 return nodeData->getGlobalTransform(h, QMatrix4x4());
610 }
611 [[nodiscard]] QMatrix4x4 getGlobalTransform(const QSSGRenderNode &node) const
612 {
613 return nodeData->getGlobalTransform(node.h, node.localTransform);
614 }
615 [[nodiscard]] QMatrix3x3 getNormalMatrix(QSSGRenderNodeHandle h) const
616 {
617 return modelData->getNormalMatrix(h, QMatrix3x3(Qt::Uninitialized));
618 }
619 [[nodiscard]] QMatrix3x3 getNormalMatrix(const QSSGRenderModel &model) const
620 {
621 return modelData->getNormalMatrix(model);
622 }
623 [[nodiscard]] ModelViewProjections getModelMvps(QSSGRenderNodeHandle h) const
624 {
625 return modelData->getModelViewProjection(h);
626 }
627 [[nodiscard]] ModelViewProjections getModelMvps(const QSSGRenderModel &model) const
628 {
629 return modelData->getModelViewProjection(model);
630 }
631 [[nodiscard]] InstanceTransforms getInstanceTransforms(QSSGRenderNodeHandle h) const
632 {
633 return nodeData->getInstanceTransforms(h);
634 }
635 [[nodiscard]] InstanceTransforms getInstanceTransforms(const QSSGRenderNode &node) const
636 {
637 return nodeData->getInstanceTransforms(node.h);
638 }
639 [[nodiscard]] float getGlobalOpacity(QSSGRenderNodeHandle h, float defaultValue = 1.0f) const
640 {
641 return nodeData->getGlobalOpacity(h, defaultValue);
642 }
643 [[nodiscard]] float getGlobalOpacity(const QSSGRenderNode &node) const
644 {
645 return nodeData->getGlobalOpacity(node.h);
646 }
647
648 //
649 [[nodiscard]] QSSGRenderItem2DData::Item2DRenderer getItem2DRenderer(const QSSGRenderItem2D &item) const
650 {
651 return item2DData->getItem2DRenderer(item);
652 }
653
654 [[nodiscard]] ModelViewProjections getItem2DMvps(QSSGRenderNodeHandle h) const
655 {
656 return item2DData->getModelViewProjection(h);
657 }
658
659 [[nodiscard]] ModelViewProjections getItem2DMvps(const QSSGRenderItem2D &item) const
660 {
661 return item2DData->getModelViewProjection(item);
662 }
663
664
665 //
666 void prepareRenderables(QSSGRenderContextInterface &ctx,
667 QSSGPrepResultId prepId,
668 QRhiRenderPassDescriptor *renderPassDescriptor,
669 const QSSGRhiGraphicsPipelineState &ps,
670 QSSGRenderablesFilters filter);
671 void renderRenderables(QSSGRenderContextInterface &ctx,
672 QSSGPrepResultId prepId);
673
674 static bool calculateGlobalVariables(QSSGRenderNode &node,
675 std::vector<QMatrix4x4> &globalTransforms,
676 std::vector<float> &globalOpacities);
677
678 QSSGRenderCameraData getCameraDataImpl(const QSSGRenderCamera *camera) const;
679
680 static QSSGNodeIdList filter(const QSSGGlobalRenderNodeData::LayerNodeView &layerNodes,
681 quint32 layerMask,
682 quint32 typeMask);
683
684 [[nodiscard]] static QSSGLayerRenderData *getCurrent(const QSSGFrameData &data) { return data.getCurrent(); }
685
686 QSSGDefaultMaterialPreparationResult prepareDefaultMaterialForRender(QSSGRenderDefaultMaterial &inMaterial,
687 QSSGRenderableObjectFlags &inExistingFlags,
688 float inOpacity,
689 bool hasAnyLights,
690 bool anyLightHasShadows,
691 QSSGLayerRenderPreparationResultFlags &ioFlags);
692
693 QSSGDefaultMaterialPreparationResult prepareCustomMaterialForRender(QSSGRenderCustomMaterial &inMaterial,
694 QSSGRenderableObjectFlags &inExistingFlags,
695 float inOpacity, bool alreadyDirty,
696 bool hasAnyLights,
697 bool anyLightHasShadows,
698 QSSGLayerRenderPreparationResultFlags &ioFlags);
699
700 static void categorizeAndFilterNodes(const QSSGGlobalRenderNodeData::LayerNodeView &layerNodes,
701 QSSGLayerRenderData::NodeCollection &nodeCollection,
702 quint32 layerMask);
703 void updateFilteredLayerNodes(quint32 layerMask);
704private:
705 friend class QSSGRenderer;
706 friend class QSSGRendererPrivate;
707 friend class QSSGFrameData;
708 friend class QSSGModelHelpers;
709 friend class QSSGRenderHelpers;
710 friend class QSSGParticleRenderer;
711
712 class ExtensionContext
713 {
714 public:
715 explicit ExtensionContext() = default;
716 explicit ExtensionContext(const QSSGRenderExtension &ownerExt, QSSGRenderCamera *cam, size_t idx, quint32 slot)
717 : owner(&ownerExt), camera(cam), ps{}, filter{0}, index(idx), slot(slot)
718 { }
719 const QSSGRenderExtension *owner = nullptr;
720 QSSGRenderCamera *camera = nullptr;
721 QSSGRhiGraphicsPipelineState ps[3] {};
722 QSSGRenderablesFilters filter { 0 };
723 size_t index = 0; // index into the model store
724 quint32 slot = 0;
725 };
726
727 std::vector<ExtensionContext> extContexts { ExtensionContext{ /* 0 - Always available */ } };
728 std::vector<RenderableNodeEntries> renderableModelStore { RenderableNodeEntries{ /* 0 - Always available */ } };
729 std::vector<TModelContextPtrList> modelContextStore { TModelContextPtrList{ /* 0 - Always available */ }};
730 std::vector<QSSGRenderableObjectList> renderableObjectStore { QSSGRenderableObjectList{ /* 0 - Always available */ }};
731 std::vector<QSSGRenderableObjectList> opaqueObjectStore { QSSGRenderableObjectList{ /* 0 - Always available */ }};
732 std::vector<QSSGRenderableObjectList> transparentObjectStore { QSSGRenderableObjectList{ /* 0 - Always available */ }};
733 std::vector<QSSGRenderableObjectList> screenTextureObjectStore { QSSGRenderableObjectList{ /* 0 - Always available */ }};
734
735 std::shared_ptr<QSSGGlobalRenderNodeData> nodeData;
736 std::unique_ptr<QSSGRenderModelData> modelData;
737 std::unique_ptr<QSSGRenderItem2DData> item2DData;
738
739 // Soreted cache (per camera and extension)
740 using CameraKey = std::pair<const QSSGRenderCamera*, uint32_t>;
741
742 struct CameraKeyHash {
743 std::size_t operator()(const CameraKey& k) const noexcept {
744 // Hash combine: pointer hash ^ (uint hash shifted)
745 return std::hash<const QSSGRenderCamera*>()(k.first) ^
746 (std::hash<uint32_t>()(k.second) << 1);
747 }
748 };
749
750 struct CameraKeyEq {
751 bool operator()(const CameraKey& a, const CameraKey& b) const noexcept {
752 return a.first == b.first && a.second == b.second;
753 }
754 };
755
756 using PerCameraCache = std::unordered_map<CameraKey, QSSGRenderableObjectList, CameraKeyHash, CameraKeyEq>;
757 std::vector<PerCameraCache> sortedOpaqueObjectCache { PerCameraCache{ /* 0 - Always available */ } };
758 std::vector<PerCameraCache> sortedTransparentObjectCache { PerCameraCache{ /* 0 - Always available */ } };
759 std::vector<PerCameraCache> sortedScreenTextureObjectCache { PerCameraCache{ /* 0 - Always available */ } };
760 std::vector<PerCameraCache> sortedOpaqueDepthPrepassCache { PerCameraCache{ /* 0 - Always available */ } };
761 std::vector<PerCameraCache> sortedDepthWriteCache { PerCameraCache{ /* 0 - Always available */ } };
762
763 [[nodiscard]] const QSSGRenderCameraDataList &getCachedCameraDatas();
764 void ensureCachedCameraDatas();
765 void updateSortedDepthObjectsListImp(const QSSGRenderCamera &camera, size_t index);
766
767 static void prepareModelMaterials(RenderableNodeEntries &renderableModels, bool cullUnrenderables);
768 static void prepareModelMaterials(const RenderableNodeEntries::ConstIterator &begin,
769 const RenderableNodeEntries::ConstIterator &end);
770
771 // Persistent data
772 QHash<QSSGShaderMapKey, QSSGRhiShaderPipelinePtr> shaderMap;
773 QHash<QSSGParticleShaderMapKey, QSSGRhiShaderPipelinePtr> particleShaderMap;
774
775 // Cached buffer.
776 QByteArray generatedShaderString;
777
778 // Saved render state (for sublayers)
779 struct SavedRenderState
780 {
781 QRect viewport;
782 QRect scissorRect;
783 float dpr = 1.0;
784 };
785
786 std::optional<SavedRenderState> savedRenderState;
787
788 // Note: Re-used to avoid expensive initialization.
789 // - Should be revisit, as we can do better.
790 QSSGShaderDefaultMaterialKeyProperties defaultMaterialShaderKeyProperties;
791 QSSGShaderParticleMaterialKeyProperties particleMaterialShaderKeyProperties;
792 QSSGFrameData frameData;
793 QSSGRhiGraphicsPipelineState ps; // Base pipleline state
794 QSSGShaderFeatures features; // Base feature set
795 QSSGRenderNodeVersionType version = 0;
796 bool particlesEnabled = true;
797 bool hasDepthWriteObjects = false;
798 bool zPrePassActive = false;
799 // NOTE: For the time being we need to keep track of extensions modifying the renderables
800 // because then we need to reset the lists.
801 // FIXME: This should be revisited, as we can do better (hence the verbose name).
802 bool renderablesModifiedByExtension = false;
803 enum class DepthPrepassObject : quint8
804 {
805 None = 0x0,
806 ScreenTexture = 0x1,
807 Transparent = 0x2,
808 Opaque = 0x4
809 };
810 using DepthPrepassObjectStateT = std::underlying_type_t<DepthPrepassObject>;
811 DepthPrepassObjectStateT depthPrepassObjectsState { DepthPrepassObjectStateT(DepthPrepassObject::None) };
812 QSSGRenderShadowMapPtr shadowMapManager;
813 QSSGRenderReflectionMapPtr reflectionMapManager;
814 QSSGRenderSkyMaterialManagerPtr skyMaterialManager;
815 QSSGUserRenderPassManagerPtr userRenderPassManager;
816 QSSGRenderMotionVectorMapPtr motionVectorMapManager;
817 QHash<const QSSGModelContext *, QRhiTexture *> lightmapTextures;
818 QHash<const QSSGModelContext *, QRhiTexture *> bonemapTextures;
819 QSSGRhiRenderableTexture renderResults[size_t(QSSGRenderResult::Key::RenderResultCount)] {};
820 QSSGOITRenderContext oitRenderContext;
821};
822
823QT_END_NAMESPACE
824
825#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
QRhiTextureRenderTarget * oitRenderTarget
QRhiRenderPassDescriptor * renderPassDescriptor