1 | // Copyright (C) 2008-2012 NVIDIA Corporation. |
2 | // Copyright (C) 2019 The Qt Company Ltd. |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
4 | |
5 | #ifndef QSSG_RENDERER_H |
6 | #define QSSG_RENDERER_H |
7 | |
8 | // |
9 | // W A R N I N G |
10 | // ------------- |
11 | // |
12 | // This file is not part of the Qt API. It exists purely as an |
13 | // implementation detail. This header file may change from version to |
14 | // version without notice, or even be removed. |
15 | // |
16 | // We mean it. |
17 | // |
18 | |
19 | #include <QtQuick3DRuntimeRender/private/qssgrenderableobjects_p.h> |
20 | #include <QtQuick3DRuntimeRender/private/qssgrendermesh_p.h> |
21 | #include <QtQuick3DRuntimeRender/private/qssgrendermodel_p.h> |
22 | #include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterial_p.h> |
23 | #include <QtQuick3DRuntimeRender/private/qssgrenderlayer_p.h> |
24 | #include <QtQuick3DRuntimeRender/private/qssgrenderray_p.h> |
25 | #include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h> |
26 | #include <QtQuick3DRuntimeRender/private/qssgrendershadercache_p.h> |
27 | #include <QtQuick3DRuntimeRender/private/qssgrenderclippingfrustum_p.h> |
28 | #include <QtQuick3DRuntimeRender/private/qssgrendershaderkeys_p.h> |
29 | #include <QtQuick3DRuntimeRender/private/qssgrendershadercache_p.h> |
30 | #include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterialshadergenerator_p.h> |
31 | #include <QtQuick3DRuntimeRender/private/qssgrenderbuffermanager_p.h> |
32 | #include <QtQuick3DRuntimeRender/private/qssgrenderpickresult_p.h> |
33 | #include <QtQuick3DRuntimeRender/private/qssgshadermapkey_p.h> |
34 | #include <QtQuick3DRuntimeRender/private/qssgrenderpass_p.h> |
35 | |
36 | #include <QtQuick3DUtils/private/qssgbounds3_p.h> |
37 | #include <QtQuick3DUtils/private/qssgdataref_p.h> |
38 | |
39 | QT_BEGIN_NAMESPACE |
40 | |
41 | class QSSGRhiQuadRenderer; |
42 | class QSSGRhiCubeRenderer; |
43 | struct QSSGRenderItem2D; |
44 | struct QSSGReflectionMapEntry; |
45 | |
46 | class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderer |
47 | { |
48 | Q_DISABLE_COPY(QSSGRenderer) |
49 | using PickResultList = QVarLengthArray<QSSGRenderPickResult, 20>; // Lets assume most items are filtered out already |
50 | public: |
51 | QSSGRenderer(); |
52 | ~QSSGRenderer(); |
53 | |
54 | QSSGShaderDefaultMaterialKeyProperties &defaultMaterialShaderKeyProperties() |
55 | { |
56 | return m_defaultMaterialShaderKeyProperties; |
57 | } |
58 | |
59 | void setRenderContextInterface(QSSGRenderContextInterface *ctx); |
60 | |
61 | // Returns true if this layer or a sibling was dirty. |
62 | bool prepareLayerForRender(QSSGRenderLayer &inLayer); |
63 | |
64 | void rhiPrepare(QSSGRenderLayer &inLayer); |
65 | void rhiRender(QSSGRenderLayer &inLayer); |
66 | |
67 | void cleanupResources(QList<QSSGRenderGraphObject*> &resources); |
68 | void cleanupResources(QSet<QSSGRenderGraphObject*> &resources); |
69 | |
70 | QSSGLayerRenderData *getOrCreateLayerRenderData(QSSGRenderLayer &layer); |
71 | |
72 | // The QSSGRenderContextInterface calls these, clients should not. |
73 | void beginFrame(QSSGRenderLayer *layer); |
74 | void endFrame(QSSGRenderLayer *layer); |
75 | |
76 | PickResultList syncPickAll(const QSSGRenderLayer &layer, |
77 | QSSGBufferManager &bufferManager, |
78 | const QSSGRenderRay &ray); |
79 | |
80 | QSSGRenderPickResult syncPick(const QSSGRenderLayer &layer, |
81 | QSSGBufferManager &bufferManager, |
82 | const QSSGRenderRay &ray, |
83 | QSSGRenderNode *target = nullptr); |
84 | |
85 | // Setting this true enables picking for all the models, regardless of |
86 | // the models pickable property. |
87 | bool isGlobalPickingEnabled() const; |
88 | void setGlobalPickingEnabled(bool isEnabled); |
89 | |
90 | QSSGRhiQuadRenderer *rhiQuadRenderer(); |
91 | QSSGRhiCubeRenderer *rhiCubeRenderer(); |
92 | |
93 | void beginLayerRender(QSSGLayerRenderData &inLayer); |
94 | void endLayerRender(); |
95 | void addMaterialDirtyClear(QSSGRenderGraphObject *material); |
96 | |
97 | static QSSGRhiShaderPipelinePtr generateRhiShaderPipelineImpl(QSSGSubsetRenderable &renderable, QSSGShaderLibraryManager &shaderLibraryManager, |
98 | QSSGShaderCache &shaderCache, |
99 | QSSGProgramGenerator &shaderProgramGenerator, |
100 | QSSGShaderDefaultMaterialKeyProperties &shaderKeyProperties, |
101 | const QSSGShaderFeatures &featureSet, |
102 | QByteArray &shaderString); |
103 | |
104 | QSSGRhiShaderPipelinePtr getShaderPipelineForDefaultMaterial(QSSGSubsetRenderable &inRenderable, |
105 | const QSSGShaderFeatures &inFeatureSet); |
106 | |
107 | QSSGLayerGlobalRenderProperties getLayerGlobalRenderProperties(); |
108 | |
109 | QSSGRenderContextInterface *contextInterface() const { return m_contextInterface; } |
110 | |
111 | enum class LightmapUVRasterizationShaderMode { |
112 | Default, |
113 | Uv, |
114 | UvTangent |
115 | }; |
116 | |
117 | // shader implementations, RHI, implemented in qssgrendererimplshaders_rhi.cpp |
118 | QSSGRhiShaderPipelinePtr getRhiCubemapShadowBlurXShader(); |
119 | QSSGRhiShaderPipelinePtr getRhiCubemapShadowBlurYShader(); |
120 | QSSGRhiShaderPipelinePtr getRhiGridShader(); |
121 | QSSGRhiShaderPipelinePtr getRhiOrthographicShadowBlurXShader(); |
122 | QSSGRhiShaderPipelinePtr getRhiOrthographicShadowBlurYShader(); |
123 | QSSGRhiShaderPipelinePtr getRhiSsaoShader(); |
124 | QSSGRhiShaderPipelinePtr getRhiSkyBoxCubeShader(); |
125 | QSSGRhiShaderPipelinePtr getRhiSkyBoxShader(QSSGRenderLayer::TonemapMode tonemapMode, bool isRGBE); |
126 | QSSGRhiShaderPipelinePtr getRhiSupersampleResolveShader(); |
127 | QSSGRhiShaderPipelinePtr getRhiProgressiveAAShader(); |
128 | QSSGRhiShaderPipelinePtr getRhiTexturedQuadShader(); |
129 | QSSGRhiShaderPipelinePtr getRhiParticleShader(QSSGRenderParticles::FeatureLevel featureLevel); |
130 | QSSGRhiShaderPipelinePtr getRhiSimpleQuadShader(); |
131 | QSSGRhiShaderPipelinePtr getRhiLightmapUVRasterizationShader(LightmapUVRasterizationShaderMode mode); |
132 | QSSGRhiShaderPipelinePtr getRhiLightmapDilateShader(); |
133 | QSSGRhiShaderPipelinePtr getRhiDebugObjectShader(); |
134 | |
135 | static void setTonemapFeatures(QSSGShaderFeatures &features, QSSGRenderLayer::TonemapMode tonemapMode); |
136 | |
137 | protected: |
138 | static void getLayerHitObjectList(const QSSGRenderLayer &layer, |
139 | QSSGBufferManager &bufferManager, |
140 | const QSSGRenderRay &ray, |
141 | bool inPickEverything, |
142 | PickResultList &outIntersectionResult); |
143 | static void intersectRayWithSubsetRenderable(QSSGBufferManager &bufferManager, |
144 | const QSSGRenderRay &inRay, |
145 | const QSSGRenderNode &node, |
146 | PickResultList &outIntersectionResultList); |
147 | static void intersectRayWithItem2D(const QSSGRenderRay &inRay, const QSSGRenderItem2D &item2D, PickResultList &outIntersectionResultList); |
148 | |
149 | private: |
150 | friend class QSSGRenderContextInterface; |
151 | friend class QSSGLayerRenderData; |
152 | |
153 | void releaseCachedResources(); |
154 | QSSGRhiShaderPipelinePtr getBuiltinRhiShader(const QByteArray &name, |
155 | QSSGRhiShaderPipelinePtr &storage); |
156 | QSSGRhiShaderPipelinePtr generateRhiShaderPipeline(QSSGSubsetRenderable &inRenderable, const QSSGShaderFeatures &inFeatureSet); |
157 | |
158 | QSSGRenderContextInterface *m_contextInterface = nullptr; // We're own by the context interface |
159 | |
160 | // The shader refs are non-null if we have attempted to generate the |
161 | // shader. This does not mean we were successul, however. |
162 | |
163 | // RHI |
164 | QSSGRhiShaderPipelinePtr m_cubemapShadowBlurXRhiShader; |
165 | QSSGRhiShaderPipelinePtr m_cubemapShadowBlurYRhiShader; |
166 | QSSGRhiShaderPipelinePtr m_gridShader; |
167 | QSSGRhiShaderPipelinePtr m_orthographicShadowBlurXRhiShader; |
168 | QSSGRhiShaderPipelinePtr m_orthographicShadowBlurYRhiShader; |
169 | QSSGRhiShaderPipelinePtr m_ssaoRhiShader; |
170 | QSSGRhiShaderPipelinePtr m_skyBoxRhiShader; |
171 | QSSGRhiShaderPipelinePtr m_skyBoxCubeRhiShader; |
172 | QSSGRhiShaderPipelinePtr m_supersampleResolveRhiShader; |
173 | QSSGRhiShaderPipelinePtr m_progressiveAARhiShader; |
174 | QSSGRhiShaderPipelinePtr m_texturedQuadRhiShader; |
175 | QSSGRhiShaderPipelinePtr m_simpleQuadRhiShader; |
176 | QSSGRhiShaderPipelinePtr m_lightmapUVRasterShader; |
177 | QSSGRhiShaderPipelinePtr m_lightmapUVRasterShader_uv; |
178 | QSSGRhiShaderPipelinePtr m_lightmapUVRasterShader_uv_tangent; |
179 | QSSGRhiShaderPipelinePtr m_lightmapDilateShader; |
180 | QSSGRhiShaderPipelinePtr m_debugObjectShader; |
181 | |
182 | QSSGRhiShaderPipelinePtr m_particlesNoLightingSimpleRhiShader; |
183 | QSSGRhiShaderPipelinePtr m_particlesNoLightingMappedRhiShader; |
184 | QSSGRhiShaderPipelinePtr m_particlesNoLightingAnimatedRhiShader; |
185 | QSSGRhiShaderPipelinePtr m_particlesVLightingSimpleRhiShader; |
186 | QSSGRhiShaderPipelinePtr m_particlesVLightingMappedRhiShader; |
187 | QSSGRhiShaderPipelinePtr m_particlesVLightingAnimatedRhiShader; |
188 | QSSGRhiShaderPipelinePtr m_lineParticlesRhiShader; |
189 | QSSGRhiShaderPipelinePtr m_lineParticlesMappedRhiShader; |
190 | QSSGRhiShaderPipelinePtr m_lineParticlesAnimatedRhiShader; |
191 | QSSGRhiShaderPipelinePtr m_lineParticlesVLightRhiShader; |
192 | QSSGRhiShaderPipelinePtr m_lineParticlesMappedVLightRhiShader; |
193 | QSSGRhiShaderPipelinePtr m_lineParticlesAnimatedVLightRhiShader; |
194 | |
195 | bool m_globalPickingEnabled = false; |
196 | |
197 | // Temporary information stored only when rendering a particular layer. |
198 | QSSGLayerRenderData *m_currentLayer = nullptr; |
199 | QMatrix4x4 m_viewProjection; |
200 | QByteArray m_generatedShaderString; |
201 | |
202 | QSSGShaderDefaultMaterialKeyProperties m_defaultMaterialShaderKeyProperties; |
203 | |
204 | QSet<QSSGRenderGraphObject *> m_materialClearDirty; |
205 | |
206 | QSSGRhiQuadRenderer *m_rhiQuadRenderer = nullptr; |
207 | QSSGRhiCubeRenderer *m_rhiCubeRenderer = nullptr; |
208 | |
209 | QHash<QSSGShaderMapKey, QSSGRhiShaderPipelinePtr> m_shaderMap; |
210 | |
211 | // Skybox shader state |
212 | QSSGRenderLayer::TonemapMode m_skyboxTonemapMode = QSSGRenderLayer::TonemapMode::None; |
213 | bool m_isSkyboxRGBE = false; |
214 | }; |
215 | |
216 | namespace RenderHelpers |
217 | { |
218 | |
219 | std::pair<QSSGBoxPoints, QSSGBoxPoints> calculateSortedObjectBounds(const QVector<QSSGRenderableObjectHandle> &sortedOpaqueObjects, |
220 | const QVector<QSSGRenderableObjectHandle> &sortedTransparentObjects); |
221 | |
222 | void rhiRenderShadowMap(QSSGRhiContext *rhiCtx, QSSGPassKey passKey, |
223 | QSSGRhiGraphicsPipelineState &ps, |
224 | QSSGRenderShadowMap &shadowMapManager, |
225 | const QSSGRenderCamera &camera, |
226 | const QSSGShaderLightList &globalLights, |
227 | const QVector<QSSGRenderableObjectHandle> &sortedOpaqueObjects, |
228 | QSSGRenderer &renderer, |
229 | const QSSGBoxPoints &castingObjectsBox, |
230 | const QSSGBoxPoints &receivingObjectsBox); |
231 | |
232 | void rhiRenderReflectionMap(QSSGRhiContext *rhiCtx, |
233 | QSSGPassKey passKey, |
234 | const QSSGLayerRenderData &inData, QSSGRhiGraphicsPipelineState *ps, |
235 | QSSGRenderReflectionMap &reflectionMapManager, |
236 | const QVector<QSSGRenderReflectionProbe *> &reflectionProbes, |
237 | const QVector<QSSGRenderableObjectHandle> &reflectionPassObjects, |
238 | QSSGRenderer &renderer); |
239 | |
240 | bool rhiPrepareDepthPass(QSSGRhiContext *rhiCtx, QSSGPassKey passKey, |
241 | const QSSGRhiGraphicsPipelineState &basePipelineState, |
242 | QRhiRenderPassDescriptor *rpDesc, |
243 | QSSGLayerRenderData &inData, |
244 | const QVector<QSSGRenderableObjectHandle> &sortedOpaqueObjects, |
245 | const QVector<QSSGRenderableObjectHandle> &sortedTransparentObjects, |
246 | int samples); |
247 | |
248 | void rhiRenderDepthPass(QSSGRhiContext *rhiCtx, const QSSGRhiGraphicsPipelineState &ps, |
249 | const QVector<QSSGRenderableObjectHandle> &sortedOpaqueObjects, |
250 | const QVector<QSSGRenderableObjectHandle> &sortedTransparentObjects, |
251 | bool *needsSetViewport); |
252 | |
253 | bool rhiPrepareAoTexture(QSSGRhiContext *rhiCtx, const QSize &size, QSSGRhiRenderableTexture *renderableTex); |
254 | |
255 | void rhiRenderAoTexture(QSSGRhiContext *rhiCtx, QSSGPassKey passKey, QSSGRenderer &renderer, QSSGRhiShaderPipeline &shaderPipeline, |
256 | QSSGRhiGraphicsPipelineState &ps, const SSAOMapPass::AmbientOcclusion &ao, const QSSGRhiRenderableTexture &rhiAoTexture, const QSSGRhiRenderableTexture &rhiDepthTexture, |
257 | const QSSGRenderCamera &camera); |
258 | |
259 | bool rhiPrepareScreenTexture(QSSGRhiContext *rhiCtx, const QSize &size, bool wantsMips, QSSGRhiRenderableTexture *renderableTex); |
260 | |
261 | void rhiPrepareGrid(QSSGRhiContext *rhiCtx, QSSGPassKey passKey, QSSGRenderLayer &layer, |
262 | QSSGRenderCamera &inCamera, QSSGRenderer &renderer); |
263 | |
264 | |
265 | void rhiPrepareSkyBox(QSSGRhiContext *rhiCtx, QSSGPassKey passKey, |
266 | QSSGRenderLayer &layer, |
267 | QSSGRenderCamera &inCamera, |
268 | QSSGRenderer &renderer); |
269 | |
270 | void rhiPrepareSkyBoxForReflectionMap(QSSGRhiContext *rhiCtx, QSSGPassKey passKey, |
271 | QSSGRenderLayer &layer, |
272 | QSSGRenderCamera &inCamera, |
273 | QSSGRenderer &renderer, |
274 | QSSGReflectionMapEntry *entry, |
275 | QSSGRenderTextureCubeFace cubeFace); |
276 | |
277 | Q_QUICK3DRUNTIMERENDER_EXPORT void rhiPrepareRenderable(QSSGRhiContext *rhiCtx, QSSGPassKey passKey, |
278 | const QSSGLayerRenderData &inData, |
279 | QSSGRenderableObject &inObject, |
280 | QRhiRenderPassDescriptor *renderPassDescriptor, |
281 | QSSGRhiGraphicsPipelineState *ps, |
282 | QSSGShaderFeatures featureSet, |
283 | int samples, |
284 | QSSGRenderCamera *inCamera = nullptr, |
285 | QMatrix4x4 *alteredModelViewProjection = nullptr, |
286 | QSSGRenderTextureCubeFace cubeFace = QSSGRenderTextureCubeFaceNone, |
287 | QSSGReflectionMapEntry *entry = nullptr); |
288 | |
289 | Q_QUICK3DRUNTIMERENDER_EXPORT void rhiRenderRenderable(QSSGRhiContext *rhiCtx, |
290 | const QSSGRhiGraphicsPipelineState &state, |
291 | QSSGRenderableObject &object, |
292 | bool *needsSetViewport, |
293 | QSSGRenderTextureCubeFace cubeFace = QSSGRenderTextureCubeFaceNone); |
294 | |
295 | bool rhiPrepareDepthTexture(QSSGRhiContext *rhiCtx, const QSize &size, QSSGRhiRenderableTexture *renderableTex); |
296 | |
297 | inline QRect correctViewportCoordinates(const QRectF &layerViewport, const QRect &deviceRect) |
298 | { |
299 | const int y = deviceRect.bottom() - layerViewport.bottom() + 1; |
300 | return QRect(layerViewport.x(), y, layerViewport.width(), layerViewport.height()); |
301 | } |
302 | } |
303 | |
304 | QT_END_NAMESPACE |
305 | |
306 | #endif |
307 | |