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