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