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
5#ifndef QSSG_LAYER_RENDER_DATA_H
6#define QSSG_LAYER_RENDER_DATA_H
7
8
9//
10// W A R N I N G
11// -------------
12//
13// This file is not part of the Qt API. It exists purely as an
14// implementation detail. This header file may change from version to
15// version without notice, or even be removed.
16//
17// We mean it.
18//
19
20#include <QtQuick3DRuntimeRender/private/qssgrenderitem2d_p.h>
21#include <QtQuick3DRuntimeRender/private/qssgrenderer_p.h>
22#include <QtQuick3DRuntimeRender/private/qssgrendershadercache_p.h>
23#include <QtQuick3DRuntimeRender/private/qssgrenderableobjects_p.h>
24#include <QtQuick3DRuntimeRender/private/qssgrendershadowmap_p.h>
25#include <QtQuick3DRuntimeRender/private/qssgrendereffect_p.h>
26#include <QtQuick3DRuntimeRender/private/qssgrenderresourceloader_p.h>
27#include <QtQuick3DRuntimeRender/private/qssgrenderreflectionmap_p.h>
28#include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h>
29#include <QtQuick3DRuntimeRender/private/qssgrhicontext_p.h>
30#include <QtQuick3DRuntimeRender/private/qssgperframeallocator_p.h>
31#include <QtQuick3DRuntimeRender/private/qssgshadermapkey_p.h>
32#include <QtQuick3DRuntimeRender/private/qssglightmapbaker_p.h>
33#include <ssg/qssgrenderextensions.h>
34
35#include <QtQuick3DUtils/private/qssgrenderbasetypes_p.h>
36
37#include <optional>
38#include <unordered_map>
39
40#include "qssgrenderpass_p.h"
41#include "qssgrenderdata_p.h"
42
43QT_BEGIN_NAMESPACE
44
45class QSSGRenderableObject;
46
47class QSGRenderer;
48
49enum class QSSGLayerRenderPreparationResultFlag
50{
51 // Was the data in this layer dirty (meaning re-render to texture, possibly)
52 WasLayerDataDirty = 1 << 0,
53
54 // Was the data in this layer dirty *or* this layer *or* any effect dirty.
55 WasDirty = 1 << 1,
56
57 RequiresDepthTexture = 1 << 2,
58
59 // SSAO should be done in a separate pass
60 // Note that having an AO pass necessitates a DepthTexture so this flag should
61 // never be set without the RequiresDepthTexture flag as well.
62 RequiresSsaoPass = 1 << 3,
63
64 // if some light cause shadow
65 // we need a separate per light shadow map pass
66 RequiresShadowMapPass = 1 << 4,
67
68 RequiresScreenTexture = 1 << 5,
69
70 // set together with RequiresScreenTexture when SCREEN_MIP_TEXTURE is used
71 RequiresMipmapsForScreenTexture = 1 << 6,
72
73 // Set when material has custom blend mode(not SourceOver)
74 MaterialHasCustomBlendMode = 1 << 7,
75
76 // Set when multisampled depth texture is required
77 RequiresDepthTextureMS = 1 << 8
78};
79
80struct QSSGLayerRenderPreparationResultFlags : public QFlags<QSSGLayerRenderPreparationResultFlag>
81{
82 bool wasLayerDataDirty() const
83 {
84 return this->operator&(other: QSSGLayerRenderPreparationResultFlag::WasLayerDataDirty);
85 }
86 void setLayerDataDirty(bool inValue)
87 {
88 setFlag(flag: QSSGLayerRenderPreparationResultFlag::WasLayerDataDirty, on: inValue);
89 }
90
91 bool wasDirty() const { return this->operator&(other: QSSGLayerRenderPreparationResultFlag::WasDirty); }
92 void setWasDirty(bool inValue) { setFlag(flag: QSSGLayerRenderPreparationResultFlag::WasDirty, on: inValue); }
93
94 bool requiresDepthTexture() const
95 {
96 return this->operator&(other: QSSGLayerRenderPreparationResultFlag::RequiresDepthTexture);
97 }
98 void setRequiresDepthTexture(bool inValue)
99 {
100 setFlag(flag: QSSGLayerRenderPreparationResultFlag::RequiresDepthTexture, on: inValue);
101 }
102
103 bool requiresDepthTextureMS() const
104 {
105 return this->operator&(other: QSSGLayerRenderPreparationResultFlag::RequiresDepthTextureMS);
106 }
107 void setRequiresDepthTextureMS(bool inValue)
108 {
109 setFlag(flag: QSSGLayerRenderPreparationResultFlag::RequiresDepthTextureMS, on: inValue);
110 }
111
112 bool requiresSsaoPass() const { return this->operator&(other: QSSGLayerRenderPreparationResultFlag::RequiresSsaoPass); }
113 void setRequiresSsaoPass(bool inValue)
114 {
115 setFlag(flag: QSSGLayerRenderPreparationResultFlag::RequiresSsaoPass, on: inValue);
116 }
117
118 bool requiresShadowMapPass() const
119 {
120 return this->operator&(other: QSSGLayerRenderPreparationResultFlag::RequiresShadowMapPass);
121 }
122 void setRequiresShadowMapPass(bool inValue)
123 {
124 setFlag(flag: QSSGLayerRenderPreparationResultFlag::RequiresShadowMapPass, on: inValue);
125 }
126
127 bool requiresScreenTexture() const
128 {
129 return this->operator&(other: QSSGLayerRenderPreparationResultFlag::RequiresScreenTexture);
130 }
131 void setRequiresScreenTexture(bool inValue)
132 {
133 setFlag(flag: QSSGLayerRenderPreparationResultFlag::RequiresScreenTexture, on: inValue);
134 }
135
136 bool requiresMipmapsForScreenTexture() const
137 {
138 return this->operator&(other: QSSGLayerRenderPreparationResultFlag::RequiresMipmapsForScreenTexture);
139 }
140 void setRequiresMipmapsForScreenTexture(bool inValue)
141 {
142 setFlag(flag: QSSGLayerRenderPreparationResultFlag::RequiresMipmapsForScreenTexture, on: inValue);
143 }
144
145 bool hasCustomBlendMode() const
146 {
147 return this->operator&(other: QSSGLayerRenderPreparationResultFlag::MaterialHasCustomBlendMode);
148 }
149 void setHasCustomBlendMode(bool inValue)
150 {
151 setFlag(flag: QSSGLayerRenderPreparationResultFlag::MaterialHasCustomBlendMode, on: inValue);
152 }
153};
154
155struct QSSGLayerRenderPreparationResult
156{
157 QSSGLayerRenderPreparationResultFlags flags;
158 QRectF viewport;
159 QSSGRenderLayer *layer = nullptr;
160
161 QSSGLayerRenderPreparationResult() = default;
162 QSSGLayerRenderPreparationResult(const QRectF &inViewport, QSSGRenderLayer &inLayer);
163
164 bool isNull() const { return !layer; }
165 bool isLayerVisible() const;
166 QSize textureDimensions() const;
167};
168
169struct QSSGDefaultMaterialPreparationResult
170{
171 QSSGRenderableImage *firstImage;
172 float opacity;
173 QSSGRenderableObjectFlags renderableFlags;
174 QSSGShaderDefaultMaterialKey materialKey;
175 bool dirty;
176
177 explicit QSSGDefaultMaterialPreparationResult(QSSGShaderDefaultMaterialKey inMaterialKey);
178};
179
180struct QSSGBakedLightingModel
181{
182 QSSGBakedLightingModel(const QSSGRenderModel *model, const QVector<QSSGRenderableObjectHandle> &renderables)
183 : model(model),
184 renderables(renderables)
185 { }
186
187 const QSSGRenderModel *model;
188 QVector<QSSGRenderableObjectHandle> renderables;
189};
190
191struct QSSGOITRenderContext
192{
193 QRhiTextureRenderTarget *oitRenderTarget = nullptr;
194 QRhiRenderPassDescriptor *renderPassDescriptor = nullptr;
195 void reset()
196 {
197 delete oitRenderTarget;
198 delete renderPassDescriptor;
199 oitRenderTarget = nullptr;
200 renderPassDescriptor = nullptr;
201 }
202};
203
204class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGLayerRenderData
205{
206public:
207 enum Enum {
208 MAX_AA_LEVELS = 8,
209 MAX_TEMPORAL_AA_LEVELS = 2,
210 };
211
212 using InstanceTransforms = QSSGGlobalRenderNodeData::InstanceTransforms;
213 using ModelViewProjections = QSSGRenderModelData::ModelViewProjections;
214
215 using QSSGModelsView = QSSGDataView<QSSGRenderModel *>;
216 using QSSGParticlesView = QSSGDataView<QSSGRenderParticles *>;
217 using QSSGItem2DsView = QSSGDataView<QSSGRenderItem2D *>;
218 using QSSGCamerasView = QSSGDataView<QSSGRenderCamera *>;
219 using QSSGLightsView = QSSGDataView<QSSGRenderLight *>;
220 using QSSGReflectionProbesView = QSSGDataView<QSSGRenderReflectionProbe *>;
221 using QSSGNonCategorizedView = QSSGDataView<QSSGRenderNode *>;
222
223 using RenderableFilter = std::function<bool(QSSGModelContext *)>;
224
225 QSSGLayerRenderData(QSSGRenderLayer &inLayer, QSSGRenderer &inRenderer);
226 ~QSSGLayerRenderData();
227
228 typedef QVector<QSSGModelContext *> TModelContextPtrList;
229 using RenderableNodeEntries = QVector<QSSGRenderableNodeEntry>;
230 using RenderableItem2DEntries = QVector<QSSGRenderItem2D *>;
231
232 QSSGShaderDefaultMaterialKey generateLightingKey(QSSGRenderDefaultMaterial::MaterialLighting inLightingType,
233 const QSSGShaderLightListView &lights, bool receivesShadows = true);
234
235 void prepareImageForRender(QSSGRenderImage &inImage,
236 QSSGRenderableImage::Type inMapType,
237 QSSGRenderableImage *&ioFirstImage,
238 QSSGRenderableImage *&ioNextImage,
239 QSSGRenderableObjectFlags &ioFlags,
240 QSSGShaderDefaultMaterialKey &ioGeneratedShaderKey,
241 quint32 inImageIndex, QSSGRenderDefaultMaterial *inMaterial = nullptr);
242
243 void setVertexInputPresence(const QSSGRenderableObjectFlags &renderableFlags,
244 QSSGShaderDefaultMaterialKey &key);
245
246 static void prepareModelBoneTextures(const QSSGRenderContextInterface &contextInterface,
247 const RenderableNodeEntries &renderableModels);
248
249 // Helper functions used during PrepareForRender and PrepareAndRender
250 // Updates lights with model receivesShadows. Do not pass globalLights.
251 bool prepareModelsForRender(QSSGRenderContextInterface &ctx,
252 const RenderableNodeEntries &renderableModels,
253 QSSGLayerRenderPreparationResultFlags &ioFlags,
254 const QSSGRenderCameraList &allCameras,
255 const QSSGRenderCameraDataList &allCameraData,
256 TModelContextPtrList &modelContexts,
257 QSSGRenderableObjectList &opaqueObjects,
258 QSSGRenderableObjectList &transparentObjects,
259 QSSGRenderableObjectList &screenTextureObjects,
260 float lodThreshold = 0.0f);
261 bool prepareParticlesForRender(const RenderableNodeEntries &renderableParticles, const QSSGRenderCameraData &cameraData, QSSGLayerRenderPreparationResultFlags &ioFlags);
262 bool prepareItem2DsForRender(const QSSGRenderContextInterface &ctxIfc,
263 const QSSGItem2DsView &renderableItem2Ds);
264
265 void prepareResourceLoaders();
266
267 void prepareForRender();
268 // Helper function used during prepareForRender
269 void prepareReflectionProbesForRender();
270
271 static qsizetype frustumCulling(const QSSGClippingFrustum &clipFrustum, const QSSGRenderableObjectList &renderables, QSSGRenderableObjectList &visibleRenderables);
272 [[nodiscard]] static qsizetype frustumCullingInline(const QSSGClippingFrustum &clipFrustum, QSSGRenderableObjectList &renderables);
273
274
275 // 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).
276 const QSSGRenderableObjectList &getSortedOpaqueRenderableObjects(const QSSGRenderCamera &camera, size_t index = 0);
277 // If layer depth test is false, this may also contain opaque objects.
278 const QSSGRenderableObjectList &getSortedTransparentRenderableObjects(const QSSGRenderCamera &camera, size_t index = 0);
279 const QSSGRenderableObjectList &getSortedScreenTextureRenderableObjects(const QSSGRenderCamera &camera, size_t index = 0);
280 const QVector<QSSGBakedLightingModel> &getSortedBakedLightingModels();
281 const RenderableItem2DEntries &getRenderableItem2Ds();
282 const QSSGRenderableObjectList &getSortedRenderedDepthWriteObjects(const QSSGRenderCamera &camera, size_t index = 0);
283 const QSSGRenderableObjectList &getSortedrenderedOpaqueDepthPrepassObjects(const QSSGRenderCamera &camera, size_t index = 0);
284
285 void resetForFrame();
286
287 QSSGFrameData &getFrameData();
288
289 ShadowMapPass shadowMapPass;
290 ReflectionMapPass reflectionMapPass;
291 ZPrePassPass zPrePassPass;
292 SSAOMapPass ssaoMapPass;
293 DepthMapPass depthMapPass;
294 DepthMapPass depthMapPassMS;
295 ScreenMapPass screenMapPass;
296 ScreenReflectionPass reflectionPass;
297 Item2DPass item2DPass;
298 SkyboxPass skyboxPass;
299 SkyboxCubeMapPass skyboxCubeMapPass;
300 static constexpr size_t USERPASSES = 2; // See QSSGRenderLayer::RenderExtensionMode::Count
301 UserPass userPasses[USERPASSES];
302 OpaquePass opaquePass;
303 TransparentPass transparentPass;
304 OITRenderPass oitRenderPass;
305 OITCompositePass oitCompositePass;
306 InfiniteGridPass infiniteGridPass;
307 DebugDrawPass debugDrawPass;
308
309 // Built-in passes
310 QVarLengthArray<QSSGRenderPass *, 16> activePasses;
311
312 QSSGRenderLayer &layer;
313 QSSGRenderer *renderer = nullptr;
314 // List of nodes we can render, not all may be active. Found by doing a depth-first
315 // search through m_FirstChild if length is zero.
316
317 using LayerNodes = std::vector<QSSGRenderNode *>;
318 QSSGGlobalRenderNodeData::LayerNodeView layerNodes;
319 LayerNodes layerNodesCategorized;
320
321 // renderableNodes have all lights, but properties configured for specific node
322 RenderableNodeEntries renderableModels;
323 RenderableNodeEntries renderableParticles;
324
325 // Views into the collected nodes (unsorted)
326 QSSGModelsView modelsView;
327 QSSGParticlesView particlesView;
328 QSSGItem2DsView item2DsView;
329 QSSGCamerasView camerasView;
330 QSSGLightsView lightsView;
331 QSSGReflectionProbesView reflectionProbesView;
332 QSSGNonCategorizedView nonCategorizedView;
333
334 // Results of prepare for render.
335 QSSGRenderCameraList renderedCameras; // multiple items with multiview, one otherwise (or zero if no cameras at all)
336 QSSGShaderLightList globalLights; // All non-scoped lights
337
338 QVector<QSSGBakedLightingModel> bakedLightingModels;
339 // Sorted lists of the rendered objects. There may be other transforms applied so
340 // it is simplest to duplicate the lists.
341 QVector<QSSGBakedLightingModel> renderedBakedLightingModels;
342 RenderableItem2DEntries renderedItem2Ds;
343 // Temporary look-up map for Item2D data (for use in prepareItem2DsForRender()).
344 QSSGRenderer::Item2DDataMap item2DDataMap;
345 QPointer<QSGRenderContext> item2DRenderContext;
346
347 QSSGLayerRenderPreparationResult layerPrepResult;
348 std::optional<QSSGRenderCameraDataList> renderedCameraData;
349
350 TModelContextPtrList modelContexts;
351
352
353 bool tooManyLightsWarningShown = false;
354 bool tooManyShadowLightsWarningShown = false;
355 bool oitWarningUnsupportedShown = false;
356 bool oitWarningInvalidBlendModeShown = false;
357 bool orderIndependentTransparencyEnabled = false;
358
359 std::unique_ptr<QSSGLightmapBaker> lightmapBaker = nullptr;
360
361 QSSGShaderFeatures getShaderFeatures() const { return features; }
362 QSSGRhiGraphicsPipelineState getPipelineState() const { return ps; }
363
364 void initializeLightmapBaking(QSSGLightmapBaker::Context &ctx);
365 void maybeProcessLightmapBaking();
366
367 [[nodiscard]] QSSGRenderGraphObject *getCamera(QSSGCameraId id) const;
368 [[nodiscard]] QSSGRenderCamera *activeCamera() const { return !renderedCameras.isEmpty() ? renderedCameras[0] : nullptr; }
369
370 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(const QSSGRenderCamera *camera);
371 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(const QSSGRenderCamera *camera) const;
372
373 void setLightmapTexture(const QSSGModelContext &modelContext, QRhiTexture *lightmapTexture);
374 [[nodiscard]] QRhiTexture *getLightmapTexture(const QSSGModelContext &modelContext) const;
375
376 void setBonemapTexture(const QSSGModelContext &modelContext, QRhiTexture *bonemapTexture);
377 [[nodiscard]] QRhiTexture *getBonemapTexture(const QSSGModelContext &modelContext) const;
378
379 [[nodiscard]] QSSGRenderContextInterface *contextInterface() const;
380 // Note: temp. API to report the state of the z-prepass step
381 [[nodiscard]] bool isZPrePassActive() const { return zPrePassActive; }
382 void setZPrePassPrepResult(bool res) { zPrePassActive = res; }
383
384 // Exposed as const, as we often need to use this to look-up values from a specific key.
385 [[nodiscard]] const QSSGShaderDefaultMaterialKeyProperties &getDefaultMaterialPropertyTable() const
386 {
387 return defaultMaterialShaderKeyProperties;
388 }
389
390 struct GlobalRenderProperties
391 {
392 bool isYUpInFramebuffer = true;
393 bool isYUpInNDC = true;
394 bool isClipDepthZeroToOne = true;
395 };
396
397 [[nodiscard]] static GlobalRenderProperties globalRenderProperties(const QSSGRenderContextInterface &ctx);
398
399 // Temp. API. Ideally there shouldn't be a reason for anyone to hold onto these,
400 // but we follow the existing pattern for now.
401 const QSSGRenderShadowMapPtr &requestShadowMapManager();
402 const QSSGRenderReflectionMapPtr &requestReflectionMapManager();
403 const QSSGRenderShadowMapPtr &getShadowMapManager() const { return shadowMapManager; }
404 const QSSGRenderReflectionMapPtr &getReflectionMapManager() const { return reflectionMapManager; }
405
406 QSSGOITRenderContext &getOitRenderContext() { return oitRenderContext; }
407
408 static bool prepareInstancing(QSSGRhiContext *rhiCtx,
409 QSSGSubsetRenderable *renderable,
410 const QVector3D &cameraDirection,
411 const QVector3D &cameraPosition,
412 float minThreshold,
413 float maxThreshold);
414
415 [[nodiscard]] QSSGRhiRenderableTexture *getRenderResult(QSSGFrameData::RenderResult id) { return &renderResults[size_t(id)]; }
416 [[nodiscard]] const QSSGRhiRenderableTexture *getRenderResult(QSSGFrameData::RenderResult id) const { return &renderResults[size_t(id)]; }
417 [[nodiscard]] static inline const std::unique_ptr<QSSGPerFrameAllocator> &perFrameAllocator(QSSGRenderContextInterface &ctx);
418 [[nodiscard]] static inline QSSGLayerRenderData *getCurrent(const QSSGRenderer &renderer) { return renderer.m_currentLayer; }
419 void saveRenderState(const QSSGRenderer &renderer);
420 void restoreRenderState(QSSGRenderer &renderer);
421
422 static void setTonemapFeatures(QSSGShaderFeatures &features, QSSGRenderLayer::TonemapMode tonemapMode)
423 {
424 features.set(feature: QSSGShaderFeatures::Feature::LinearTonemapping,
425 val: tonemapMode == QSSGRenderLayer::TonemapMode::Linear);
426 features.set(feature: QSSGShaderFeatures::Feature::AcesTonemapping,
427 val: tonemapMode == QSSGRenderLayer::TonemapMode::Aces);
428 features.set(feature: QSSGShaderFeatures::Feature::HejlDawsonTonemapping,
429 val: tonemapMode == QSSGRenderLayer::TonemapMode::HejlDawson);
430 features.set(feature: QSSGShaderFeatures::Feature::FilmicTonemapping,
431 val: tonemapMode == QSSGRenderLayer::TonemapMode::Filmic);
432 features.set(feature: QSSGShaderFeatures::Feature::ForceIblExposure,
433 val: tonemapMode == QSSGRenderLayer::TonemapMode::Custom);
434 }
435
436 QSSGPrepContextId getOrCreateExtensionContext(const QSSGRenderExtension &ext,
437 QSSGRenderCamera *camera = nullptr,
438 quint32 slot = 0);
439
440 // Model API
441 QSSGRenderablesId createRenderables(QSSGPrepContextId prepId, const QList<QSSGNodeId> &nodes, QSSGRenderHelpers::CreateFlags createFlags);
442 void setGlobalTransform(QSSGRenderablesId renderablesId, const QSSGRenderModel &model, const QMatrix4x4 &mvp);
443 QMatrix4x4 getGlobalTransform(QSSGPrepContextId prepId, const QSSGRenderModel &model);
444 void setGlobalOpacity(QSSGRenderablesId renderablesId, const QSSGRenderModel &model, float opacity);
445 float getGlobalOpacity(QSSGPrepContextId prepId, const QSSGRenderModel &model);
446 [[nodiscard]] QMatrix4x4 getModelMvps(QSSGPrepContextId prepId, const QSSGRenderModel &model) const;
447 void setModelMaterials(QSSGRenderablesId renderablesId, const QSSGRenderModel &model, const QList<QSSGResourceId> &materials);
448 void setModelMaterials(const QSSGRenderablesId renderablesId, const QList<QSSGResourceId> &materials);
449 [[nodiscard]] QSSGPrepResultId prepareModelsForRender(QSSGRenderContextInterface &contextInterface,
450 QSSGPrepContextId prepId,
451 QSSGRenderablesId renderablesId,
452 float lodThreshold);
453
454 // Convenience wrappers for getting values from the node, model store.
455 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h, QMatrix4x4 defaultValue) const;
456 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h) const;
457 [[nodiscard]] QMatrix4x4 getGlobalTransform(const QSSGRenderNode &node) const;
458
459 [[nodiscard]] QMatrix3x3 getNormalMatrix(QSSGRenderModelHandle h) const;
460 [[nodiscard]] QMatrix3x3 getNormalMatrix(const QSSGRenderModel &model) const;
461
462 [[nodiscard]] ModelViewProjections getModelMvps(QSSGRenderModelHandle h) const;
463 [[nodiscard]] ModelViewProjections getModelMvps(const QSSGRenderModel &model) const;
464
465 [[nodiscard]] InstanceTransforms getInstanceTransforms(QSSGRenderNodeHandle h) const;
466 [[nodiscard]] InstanceTransforms getInstanceTransforms(const QSSGRenderNode &node) const;
467
468 [[nodiscard]] float getGlobalOpacity(QSSGRenderNodeHandle h, float defaultValue = 1.0f) const;
469 [[nodiscard]] float getGlobalOpacity(const QSSGRenderNode &node) const;
470
471 //
472 void prepareRenderables(QSSGRenderContextInterface &ctx,
473 QSSGPrepResultId prepId,
474 QRhiRenderPassDescriptor *renderPassDescriptor,
475 const QSSGRhiGraphicsPipelineState &ps,
476 QSSGRenderablesFilters filter);
477 void renderRenderables(QSSGRenderContextInterface &ctx,
478 QSSGPrepResultId prepId);
479
480 static bool calculateGlobalVariables(QSSGRenderNode &node,
481 std::vector<QMatrix4x4> &globalTransforms,
482 std::vector<float> &globalOpacities);
483
484 QSSGRenderCameraData getCameraDataImpl(const QSSGRenderCamera *camera) const;
485
486private:
487 friend class QSSGRenderer;
488 friend class QSSGRendererPrivate;
489 friend class QSSGFrameData;
490 friend class QSSGModelHelpers;
491 friend class QSSGRenderHelpers;
492
493 class ExtensionContext
494 {
495 public:
496 explicit ExtensionContext() = default;
497 explicit ExtensionContext(const QSSGRenderExtension &ownerExt, QSSGRenderCamera *cam, size_t idx, quint32 slot)
498 : owner(&ownerExt), camera(cam), ps{}, filter{0}, index(idx), slot(slot)
499 { }
500 const QSSGRenderExtension *owner = nullptr;
501 QSSGRenderCamera *camera = nullptr;
502 QSSGRhiGraphicsPipelineState ps[3] {};
503 QSSGRenderablesFilters filter { 0 };
504 size_t index = 0; // index into the model store
505 quint32 slot = 0;
506 };
507
508 std::vector<ExtensionContext> extContexts { ExtensionContext{ /* 0 - Always available */ } };
509 std::vector<RenderableNodeEntries> renderableModelStore { RenderableNodeEntries{ /* 0 - Always available */ } };
510 std::vector<TModelContextPtrList> modelContextStore { TModelContextPtrList{ /* 0 - Always available */ }};
511 std::vector<QSSGRenderableObjectList> renderableObjectStore { QSSGRenderableObjectList{ /* 0 - Always available */ }};
512 std::vector<QSSGRenderableObjectList> opaqueObjectStore { QSSGRenderableObjectList{ /* 0 - Always available */ }};
513 std::vector<QSSGRenderableObjectList> transparentObjectStore { QSSGRenderableObjectList{ /* 0 - Always available */ }};
514 std::vector<QSSGRenderableObjectList> screenTextureObjectStore { QSSGRenderableObjectList{ /* 0 - Always available */ }};
515
516 std::shared_ptr<QSSGGlobalRenderNodeData> nodeData;
517 std::unique_ptr<QSSGRenderModelData> modelData;
518
519 // Soreted cache (per camera and extension)
520 using PerCameraCache = std::unordered_map<const QSSGRenderCamera *, QSSGRenderableObjectList>;
521 std::vector<PerCameraCache> sortedOpaqueObjectCache { PerCameraCache{ /* 0 - Always available */ } };
522 std::vector<PerCameraCache> sortedTransparentObjectCache { PerCameraCache{ /* 0 - Always available */ } };
523 std::vector<PerCameraCache> sortedScreenTextureObjectCache { PerCameraCache{ /* 0 - Always available */ } };
524 std::vector<PerCameraCache> sortedOpaqueDepthPrepassCache { PerCameraCache{ /* 0 - Always available */ } };
525 std::vector<PerCameraCache> sortedDepthWriteCache { PerCameraCache{ /* 0 - Always available */ } };
526
527 [[nodiscard]] const QSSGRenderCameraDataList &getCachedCameraDatas();
528 void ensureCachedCameraDatas();
529 void updateSortedDepthObjectsListImp(const QSSGRenderCamera &camera, size_t index);
530
531
532 QSSGDefaultMaterialPreparationResult prepareDefaultMaterialForRender(QSSGRenderDefaultMaterial &inMaterial,
533 QSSGRenderableObjectFlags &inExistingFlags,
534 float inOpacity,
535 const QSSGShaderLightListView &lights,
536 QSSGLayerRenderPreparationResultFlags &ioFlags);
537
538 QSSGDefaultMaterialPreparationResult prepareCustomMaterialForRender(QSSGRenderCustomMaterial &inMaterial,
539 QSSGRenderableObjectFlags &inExistingFlags,
540 float inOpacity, bool alreadyDirty,
541 const QSSGShaderLightListView &lights,
542 QSSGLayerRenderPreparationResultFlags &ioFlags);
543
544 static void prepareModelMaterials(RenderableNodeEntries &renderableModels, bool cullUnrenderables);
545 static void prepareModelMaterials(const RenderableNodeEntries::ConstIterator &begin,
546 const RenderableNodeEntries::ConstIterator &end);
547
548 // Persistent data
549 QHash<QSSGShaderMapKey, QSSGRhiShaderPipelinePtr> shaderMap;
550
551 // Cached buffer.
552 QByteArray generatedShaderString;
553
554 // Saved render state (for sublayers)
555 struct SavedRenderState
556 {
557 QRect viewport;
558 QRect scissorRect;
559 float dpr = 1.0;
560 };
561
562 std::optional<SavedRenderState> savedRenderState;
563
564 // Note: Re-used to avoid expensive initialization.
565 // - Should be revisit, as we can do better.
566 QSSGShaderDefaultMaterialKeyProperties defaultMaterialShaderKeyProperties;
567 QSSGFrameData frameData;
568 QSSGRhiGraphicsPipelineState ps; // Base pipleline state
569 QSSGShaderFeatures features; // Base feature set
570 quint32 version = 0;
571 bool particlesEnabled = true;
572 bool hasDepthWriteObjects = false;
573 bool zPrePassActive = false;
574 // NOTE: For the time being we need to keep track of extensions modifying the renderables
575 // because then we need to reset the lists.
576 // FIXME: This should be revisited, as we can do better (hence the verbose name).
577 bool renderablesModifiedByExtension = false;
578 enum class DepthPrepassObject : quint8
579 {
580 None = 0x0,
581 ScreenTexture = 0x1,
582 Transparent = 0x2,
583 Opaque = 0x4
584 };
585 using DepthPrepassObjectStateT = std::underlying_type_t<DepthPrepassObject>;
586 DepthPrepassObjectStateT depthPrepassObjectsState { DepthPrepassObjectStateT(DepthPrepassObject::None) };
587 QSSGRenderShadowMapPtr shadowMapManager;
588 QSSGRenderReflectionMapPtr reflectionMapManager;
589 QHash<const QSSGModelContext *, QRhiTexture *> lightmapTextures;
590 QHash<const QSSGModelContext *, QRhiTexture *> bonemapTextures;
591 QSSGRhiRenderableTexture renderResults[6] {};
592 QSSGOITRenderContext oitRenderContext;
593};
594
595QT_END_NAMESPACE
596
597#endif // QSSG_LAYER_RENDER_DATA_H
598
599

source code of qtquick3d/src/runtimerender/rendererimpl/qssglayerrenderdata_p.h