1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2008-2012 NVIDIA Corporation. 4 ** Copyright (C) 2019 The Qt Company Ltd. 5 ** Contact: https://www.qt.io/licensing/ 6 ** 7 ** This file is part of Qt Quick 3D. 8 ** 9 ** $QT_BEGIN_LICENSE:GPL$ 10 ** Commercial License Usage 11 ** Licensees holding valid commercial Qt licenses may use this file in 12 ** accordance with the commercial license agreement provided with the 13 ** Software or, alternatively, in accordance with the terms contained in 14 ** a written agreement between you and The Qt Company. For licensing terms 15 ** and conditions see https://www.qt.io/terms-conditions. For further 16 ** information use the contact form at https://www.qt.io/contact-us. 17 ** 18 ** GNU General Public License Usage 19 ** Alternatively, this file may be used under the terms of the GNU 20 ** General Public License version 3 or (at your option) any later version 21 ** approved by the KDE Free Qt Foundation. The licenses are as published by 22 ** the Free Software Foundation and appearing in the file LICENSE.GPL3 23 ** included in the packaging of this file. Please review the following 24 ** information to ensure the GNU General Public License requirements will 25 ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 26 ** 27 ** $QT_END_LICENSE$ 28 ** 29 ****************************************************************************/ 30 31 #ifndef QSSG_RENDERER_IMPL_LAYER_RENDER_PREPARATION_DATA_H 32 #define QSSG_RENDERER_IMPL_LAYER_RENDER_PREPARATION_DATA_H 33 34 // 35 // W A R N I N G 36 // ------------- 37 // 38 // This file is not part of the Qt API. It exists purely as an 39 // implementation detail. This header file may change from version to 40 // version without notice, or even be removed. 41 // 42 // We mean it. 43 // 44 45 #include <QtQuick3DRuntimeRender/private/qssgrendererimpllayerrenderhelper_p.h> 46 #include <QtQuick3DRuntimeRender/private/qssgrendershadercache_p.h> 47 #include <QtQuick3DRuntimeRender/private/qssgrenderableobjects_p.h> 48 #include <QtQuick3DRuntimeRender/private/qssgrenderclippingfrustum_p.h> 49 #include <QtQuick3DRuntimeRender/private/qssgrenderresourcetexture2d_p.h> 50 #include <QtQuick3DRuntimeRender/private/qssgrendergpuprofiler_p.h> 51 #include <QtQuick3DRuntimeRender/private/qssgrendershadowmap_p.h> 52 #include <QtQuick3DRuntimeRender/private/qssgrenderableobjects_p.h> 53 54 #include <QtQuick3DRuntimeRender/private/qssgrenderitem2d_p.h> 55 56 #define QSSG_RENDER_MINIMUM_RENDER_OPACITY .01f 57 58 QT_BEGIN_NAMESPACE 59 struct QSSGLayerRenderData; 60 class QSSGRendererImpl; 61 struct QSSGRenderableObject; 62 63 enum class QSSGLayerRenderPreparationResultFlag 64 { 65 // Was the data in this layer dirty (meaning re-render to texture, possibly) 66 WasLayerDataDirty = 1, 67 // Was the data in this layer dirty *or* this layer *or* any effect dirty. 68 WasDirty = 1 << 1, 69 70 // Should create independent viewport 71 // If we aren't rendering to texture we still may have width/height manipulations 72 // that require our own viewport. 73 ShouldCreateIndependentViewport = 1 << 2, 74 75 RequiresDepthTexture = 1 << 3, 76 77 // SSAO should be done in a separate pass 78 // Note that having an AO pass necessitates a DepthTexture so this flag should 79 // never be set without the RequiresDepthTexture flag as well. 80 RequiresSsaoPass = 1 << 4, 81 82 // if some light cause shadow 83 // we need a separate per light shadow map pass 84 RequiresShadowMapPass = 1 << 5, 85 86 // This is the case when direct rendering, and need to clear an FBO, but not a Window 87 RequiresTransparentClear = 1 << 6 88 }; 89 90 struct QSSGLayerRenderPreparationResultFlags : public QFlags<QSSGLayerRenderPreparationResultFlag> 91 { wasLayerDataDirtyQSSGLayerRenderPreparationResultFlags92 bool wasLayerDataDirty() const 93 { 94 return this->operator&(QSSGLayerRenderPreparationResultFlag::WasLayerDataDirty); 95 } setLayerDataDirtyQSSGLayerRenderPreparationResultFlags96 void setLayerDataDirty(bool inValue) 97 { 98 setFlag(QSSGLayerRenderPreparationResultFlag::WasLayerDataDirty, inValue); 99 } 100 wasDirtyQSSGLayerRenderPreparationResultFlags101 bool wasDirty() const { return this->operator&(QSSGLayerRenderPreparationResultFlag::WasDirty); } setWasDirtyQSSGLayerRenderPreparationResultFlags102 void setWasDirty(bool inValue) { setFlag(QSSGLayerRenderPreparationResultFlag::WasDirty, inValue); } 103 shouldCreateIndependentViewportQSSGLayerRenderPreparationResultFlags104 bool shouldCreateIndependentViewport() const 105 { 106 return this->operator&(QSSGLayerRenderPreparationResultFlag::ShouldCreateIndependentViewport); 107 } setShouldCreateIndependentViewportQSSGLayerRenderPreparationResultFlags108 void setShouldCreateIndependentViewport(bool inValue) 109 { 110 setFlag(QSSGLayerRenderPreparationResultFlag::ShouldCreateIndependentViewport, inValue); 111 } 112 requiresDepthTextureQSSGLayerRenderPreparationResultFlags113 bool requiresDepthTexture() const 114 { 115 return this->operator&(QSSGLayerRenderPreparationResultFlag::RequiresDepthTexture); 116 } setRequiresDepthTextureQSSGLayerRenderPreparationResultFlags117 void setRequiresDepthTexture(bool inValue) 118 { 119 setFlag(QSSGLayerRenderPreparationResultFlag::RequiresDepthTexture, inValue); 120 } 121 requiresSsaoPassQSSGLayerRenderPreparationResultFlags122 bool requiresSsaoPass() const { return this->operator&(QSSGLayerRenderPreparationResultFlag::RequiresSsaoPass); } setRequiresSsaoPassQSSGLayerRenderPreparationResultFlags123 void setRequiresSsaoPass(bool inValue) 124 { 125 setFlag(QSSGLayerRenderPreparationResultFlag::RequiresSsaoPass, inValue); 126 } 127 requiresShadowMapPassQSSGLayerRenderPreparationResultFlags128 bool requiresShadowMapPass() const 129 { 130 return this->operator&(QSSGLayerRenderPreparationResultFlag::RequiresShadowMapPass); 131 } setRequiresShadowMapPassQSSGLayerRenderPreparationResultFlags132 void setRequiresShadowMapPass(bool inValue) 133 { 134 setFlag(QSSGLayerRenderPreparationResultFlag::RequiresShadowMapPass, inValue); 135 } 136 requiresTransparentClearQSSGLayerRenderPreparationResultFlags137 bool requiresTransparentClear() const 138 { 139 return this->operator&(QSSGLayerRenderPreparationResultFlag::RequiresTransparentClear); 140 } 141 setRequiresTransparentClearQSSGLayerRenderPreparationResultFlags142 void setRequiresTransparentClear(bool inValue) 143 { 144 setFlag(QSSGLayerRenderPreparationResultFlag::RequiresTransparentClear, inValue); 145 } 146 147 }; 148 149 struct QSSGLayerRenderPreparationResult : public QSSGLayerRenderHelper 150 { 151 QSSGRenderEffect *lastEffect = nullptr; 152 QSSGLayerRenderPreparationResultFlags flags; 153 quint32 maxAAPassIndex = 0; 154 QSSGLayerRenderPreparationResult() = default; QSSGLayerRenderPreparationResultQSSGLayerRenderPreparationResult155 QSSGLayerRenderPreparationResult(const QSSGLayerRenderHelper &inHelper) 156 : QSSGLayerRenderHelper(inHelper), lastEffect(nullptr), maxAAPassIndex(0) 157 { 158 } 159 }; 160 161 struct QSSGRenderableNodeEntry 162 { 163 QSSGRenderNode *node = nullptr; 164 QSSGNodeLightEntryList lights; 165 QSSGRenderableNodeEntry() = default; QSSGRenderableNodeEntryQSSGRenderableNodeEntry166 QSSGRenderableNodeEntry(QSSGRenderNode &inNode) : node(&inNode) {} 167 }; 168 169 struct QSSGScopedLightsListScope 170 { 171 QVector<QSSGRenderLight *> &lightsList; 172 QVector<QVector3D> &lightDirList; 173 qint32 listOriginalSize; QSSGScopedLightsListScopeQSSGScopedLightsListScope174 QSSGScopedLightsListScope(QVector<QSSGRenderLight *> &inLights, 175 QVector<QVector3D> &inDestLightDirList, 176 QVector<QVector3D> &inSrcLightDirList, 177 QSSGNodeLightEntryList &inScopedLights) 178 : lightsList(inLights), lightDirList(inDestLightDirList), listOriginalSize(lightsList.size()) 179 { 180 auto iter = inScopedLights.begin(); 181 const auto end = inScopedLights.end(); 182 while (iter != end) { 183 lightsList.push_back(iter->light); 184 lightDirList.push_back(inSrcLightDirList.at(iter->lightIndex)); 185 ++iter; 186 } 187 } ~QSSGScopedLightsListScopeQSSGScopedLightsListScope188 ~QSSGScopedLightsListScope() 189 { 190 lightsList.resize(listOriginalSize); 191 lightDirList.resize(listOriginalSize); 192 } 193 }; 194 195 struct QSSGDefaultMaterialPreparationResult 196 { 197 QSSGRenderableImage *firstImage; 198 float opacity; 199 QSSGRenderableObjectFlags renderableFlags; 200 QSSGShaderDefaultMaterialKey materialKey; 201 bool dirty; 202 203 QSSGDefaultMaterialPreparationResult(QSSGShaderDefaultMaterialKey inMaterialKey); 204 }; 205 206 // Data used strictly in the render preparation step. 207 struct QSSGLayerRenderPreparationData 208 { 209 typedef void (*TRenderRenderableFunction)(QSSGLayerRenderData &inData, 210 QSSGRenderableObject &inObject, 211 const QVector2D &inCameraProps, 212 const ShaderFeatureSetList &inShaderFeatures, 213 quint32 lightIndex, 214 const QSSGRenderCamera &inCamera); 215 typedef QHash<QSSGRenderLight *, QSSGRenderNode *> TLightToNodeMap; 216 typedef QVector<QSSGModelContext *> TModelContextPtrList; 217 typedef QVector<QSSGRenderableObjectHandle> TRenderableObjectList; 218 219 // typedef Pool<SNodeLightEntry, ForwardingAllocator> TNodeLightEntryPoolType; 220 221 enum Enum { 222 MAX_AA_LEVELS = 8, 223 MAX_TEMPORAL_AA_LEVELS = 2, 224 }; 225 226 QSSGRenderLayer &layer; 227 QSSGRef<QSSGRendererImpl> renderer; 228 // List of nodes we can render, not all may be active. Found by doing a depth-first 229 // search through m_FirstChild if length is zero. 230 231 // TNodeLightEntryPoolType m_RenderableNodeLightEntryPool; 232 QVector<QSSGRenderableNodeEntry> renderableNodes; 233 QVector<QSSGRenderableNodeEntry> renderableItem2Ds; 234 QVector<QSSGRenderableNodeEntry> renderedItem2Ds; 235 TLightToNodeMap lightToNodeMap; // map of lights to nodes to cache if we have looked up a 236 // given scoped light yet. 237 // Built at the same time as the renderable nodes map. 238 // these are processed so they are available when the shaders for the models 239 // are being generated. 240 QVector<QSSGRenderCamera *> cameras; 241 QVector<QSSGRenderLight *> lights; 242 243 // Results of prepare for render. 244 QSSGRenderCamera *camera; 245 QVector<QSSGRenderLight *> globalLights; // Only contains lights that are global. 246 TRenderableObjectList opaqueObjects; 247 TRenderableObjectList transparentObjects; 248 // Sorted lists of the rendered objects. There may be other transforms applied so 249 // it is simplest to duplicate the lists. 250 TRenderableObjectList renderedOpaqueObjects; 251 TRenderableObjectList renderedTransparentObjects; 252 QMatrix4x4 viewProjection; 253 QSSGOption<QSSGClippingFrustum> clippingFrustum; 254 QSSGOption<QSSGLayerRenderPreparationResult> layerPrepResult; 255 QSSGOption<QVector3D> cameraDirection; 256 // Scoped lights need a level of indirection into a light direction list. The source light 257 // directions list is as long as there are lights on the layer. It holds invalid 258 // information for 259 // any lights that are not both active and scoped; but the relative position for a given 260 // light 261 // in this list is completely constant and immutable; this relative position is saved on a 262 // structure 263 // and used when looking up the light direction for a given light. 264 QVector<QVector3D> sourceLightDirections; 265 QVector<QVector3D> lightDirections; 266 TModelContextPtrList modelContexts; 267 268 ShaderFeatureSetList features; 269 bool featuresDirty; 270 size_t featureSetHash; 271 bool tooManyLightsError; 272 273 // shadow mapps 274 QSSGRef<QSSGRenderShadowMap> shadowMapManager; 275 276 QSSGLayerRenderPreparationData(QSSGRenderLayer &inLayer, const QSSGRef<QSSGRendererImpl> &inRenderer); 277 virtual ~QSSGLayerRenderPreparationData(); 278 void createShadowMapManager(); 279 280 static QByteArray cgLightingFeatureName(); 281 282 QSSGShaderDefaultMaterialKey generateLightingKey(QSSGRenderDefaultMaterial::MaterialLighting inLightingType, bool receivesShadows = true); 283 284 void prepareImageForRender(QSSGRenderImage &inImage, 285 QSSGImageMapTypes inMapType, 286 QSSGRenderableImage *&ioFirstImage, 287 QSSGRenderableImage *&ioNextImage, 288 QSSGRenderableObjectFlags &ioFlags, 289 QSSGShaderDefaultMaterialKey &ioGeneratedShaderKey, 290 quint32 inImageIndex, QSSGRenderDefaultMaterial *inMaterial = nullptr); 291 292 void setVertexInputPresence(const QSSGRenderableObjectFlags &renderableFlags, 293 QSSGShaderDefaultMaterialKey &key); 294 295 QSSGDefaultMaterialPreparationResult prepareDefaultMaterialForRender(QSSGRenderDefaultMaterial &inMaterial, 296 QSSGRenderableObjectFlags &inExistingFlags, 297 float inOpacity); 298 299 QSSGDefaultMaterialPreparationResult prepareCustomMaterialForRender(QSSGRenderCustomMaterial &inMaterial, 300 QSSGRenderableObjectFlags &inExistingFlags, 301 float inOpacity, bool alreadyDirty); 302 303 bool prepareModelForRender(QSSGRenderModel &inModel, 304 const QMatrix4x4 &inViewProjection, 305 const QSSGOption<QSSGClippingFrustum> &inClipFrustum, 306 QSSGNodeLightEntryList &inScopedLights); 307 308 // Helper function used during PRepareForRender and PrepareAndRender 309 bool prepareRenderablesForRender(const QMatrix4x4 &inViewProjection, 310 const QSSGOption<QSSGClippingFrustum> &inClipFrustum, 311 QSSGLayerRenderPreparationResultFlags &ioFlags); 312 313 // returns true if this object will render something different than it rendered the last 314 // time. 315 virtual void prepareForRender(const QSize &inViewportDimensions); 316 bool checkLightProbeDirty(QSSGRenderImage &inLightProbe); 317 void setShaderFeature(const char *inName, bool inValue); 318 ShaderFeatureSetList getShaderFeatureSet(); 319 size_t getShaderFeatureSetHash(); 320 321 QVector3D getCameraDirection(); 322 // Per-frame cache of renderable objects post-sort. 323 const QVector<QSSGRenderableObjectHandle> &getOpaqueRenderableObjects(bool performSort = true); 324 // If layer depth test is false, this may also contain opaque objects. 325 const QVector<QSSGRenderableObjectHandle> &getTransparentRenderableObjects(); 326 const QVector<QSSGRenderableNodeEntry> &getRenderableItem2Ds(); 327 328 virtual void resetForFrame(); 329 }; 330 QT_END_NAMESPACE 331 #endif 332