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
qssgrendererimplshaders_rhi.cpp
Go to the documentation of this file.
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// Qt-Security score:significant reason:default
5
6
8
9#include <QtQuick3DRuntimeRender/private/qssgrenderer_p.h>
10#include <QtQuick3DRuntimeRender/private/qssgrenderlight_p.h>
11#include "../qssgrendercontextcore.h"
12#include <QtQuick3DRuntimeRender/private/qssgrendershadercache_p.h>
13#include <QtQuick3DRuntimeRender/private/qssgrendershaderlibrarymanager_p.h>
14#include <QtQuick3DRuntimeRender/private/qssgrendershadercodegenerator_p.h>
15#include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterialshadergenerator_p.h>
16#include <QtQuick3DRuntimeRender/private/qssgvertexpipelineimpl_p.h>
17
18// this file contains the getXxxxShader implementations suitable for the QRhi-based rendering path
19
21
22QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getBuiltinRhiShader(const QByteArray &name,
23 BuiltinShader &storage,
24 int viewCount,
25 QSSGRhiShaderPipeline::StageFlags vertexStageFlags)
26{
27 if (storage.shaderPipeline && storage.viewCount != viewCount)
28 storage = {};
29
30 if (!storage.shaderPipeline) {
31 // loadBuiltin must always return a valid QSSGRhiShaderPipeline.
32 // There will just be no stages if loading fails.
33 storage.shaderPipeline = m_shaderCache.loadBuiltinUncached(name, viewCount, vertexStageFlags);
34 storage.viewCount = viewCount;
35 }
36
37 return storage.shaderPipeline;
38}
39
40void QSSGBuiltInRhiShaderCache::releaseCachedResources()
41{
42 m_cache = {};
43}
44
45QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiGridShader(int viewCount)
46{
47 return getBuiltinRhiShader(QByteArrayLiteral("grid"), m_cache.gridShader, viewCount);
48}
49
50QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiSsaoShader(int viewCount)
51{
52 return getBuiltinRhiShader(QByteArrayLiteral("ssao"), m_cache.ssaoRhiShader, viewCount);
53}
54
55QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiSkyBoxCubeShader(QSSGRenderLayer::TonemapMode tonemapMode, bool isLinear, int viewCount)
56{
57 const bool rawPixels = (!isLinear && tonemapMode == QSSGRenderLayer::TonemapMode::Linear) || (isLinear && tonemapMode == QSSGRenderLayer::TonemapMode::None);
58 auto shaderName = rawPixels ? QByteArrayLiteral("skyboxcube") : QByteArrayLiteral("skyboxcube_runtime_tonemapping");
59 return getBuiltinRhiShader(shaderName, m_cache.skyBoxCubeRhiShader, viewCount);
60}
61
62static inline constexpr size_t getSkyboxIndex(QSSGRenderLayer::TonemapMode tonemapMode, bool isRGBE)
63{
64 switch (tonemapMode) {
65 case QSSGRenderLayer::TonemapMode::None:
66 return 0 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount);
67 case QSSGRenderLayer::TonemapMode::Linear:
68 return 1 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount);
69 case QSSGRenderLayer::TonemapMode::Aces:
70 return 2 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount);
71 case QSSGRenderLayer::TonemapMode::HejlDawson:
72 return 3 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount);
73 case QSSGRenderLayer::TonemapMode::Filmic:
74 return 4 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount);
75 case QSSGRenderLayer::TonemapMode::Custom:
76 return 5 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount);
77 }
78
79 // GCC 8.x does not treat __builtin_unreachable() as constexpr
80# if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
81 // NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
82 Q_UNREACHABLE();
83# endif
84 return 0;
85}
86
87QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiSkyBoxShader(QSSGRenderLayer::TonemapMode tonemapMode, bool isRGBE, int viewCount)
88{
89 // Skybox shader is special and has multiple possible shaders so we have to do
90 // a bit of manual work here (mapping resolved in getSkyboxIndex()).
91 static constexpr char variant[][23] { "skybox_hdr_none",
92 "skybox_hdr_linear",
93 "skybox_hdr_aces",
94 "skybox_hdr_hejldawson",
95 "skybox_hdr_filmic",
96 "skybox_hdr_custom",
97 "skybox_rgbe_none",
98 "skybox_rgbe_linear",
99 "skybox_rgbe_aces",
100 "skybox_rgbe_hejldawson",
101 "skybox_rgbe_filmic",
102 "skybox_rgbe_custom",
103 };
104
105 const size_t skyboxIndex = getSkyboxIndex(tonemapMode, isRGBE);
106 return getBuiltinRhiShader(QByteArray::fromRawData(variant[skyboxIndex], std::char_traits<char>::length(variant[skyboxIndex])), m_cache.skyBoxRhiShader[skyboxIndex], viewCount);
107}
108
109QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiSupersampleResolveShader(int viewCount)
110{
111 return getBuiltinRhiShader(QByteArrayLiteral("ssaaresolve"), m_cache.supersampleResolveRhiShader, viewCount);
112}
113
114QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiProgressiveAAShader()
115{
116 return getBuiltinRhiShader(QByteArrayLiteral("progressiveaa"), m_cache.progressiveAARhiShader);
117}
118
119QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiMotionVectorShader(bool skin, bool instance, bool morph)
120{
121 QByteArray shaderName = "motionvector";
122 if (skin)
123 shaderName += "_skin";
124 if (instance)
125 shaderName += "_instance";
126 if (morph)
127 shaderName += "_morph";
128
129 int index = (int(skin) << 2) | (int(instance) << 1) | int(morph);
130 return getBuiltinRhiShader(shaderName, m_cache.motionVectorRhiShader[index], 1, {});
131}
132
133QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiTemporalAAShader()
134{
135 return getBuiltinRhiShader(QByteArrayLiteral("temporalaa"), m_cache.temporalAARhiShader);
136}
137
138QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiSimpleQuadShader(int viewCount, QSSGRenderLayer::TonemapMode tonemapMode)
139{
140 static constexpr char variant[][22] = {
141 "simplequad",
142 "simplequad_linear",
143 "simplequad_aces",
144 "simplequad_hejldawson",
145 "simplequad_filmic",
146 };
147
148 if (tonemapMode == QSSGRenderLayer::TonemapMode::Custom)
149 tonemapMode = QSSGRenderLayer::TonemapMode::None;
150
151 const size_t index = qMin(size_t(tonemapMode), std::size(variant) - 1);
152 return getBuiltinRhiShader(QByteArray(variant[index]), m_cache.simpleQuadRhiShader, viewCount);
153}
154
155QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiLightmapUVRasterizationShader(LightmapUVRasterizationShaderMode mode)
156{
157 switch (mode) {
158 case LightmapUVRasterizationShaderMode::Uv:
159 return getBuiltinRhiShader(QByteArrayLiteral("lightmapuvraster_uv"), m_cache.lightmapUVRasterShader_uv);
160 case LightmapUVRasterizationShaderMode::UvTangent:
161 return getBuiltinRhiShader(QByteArrayLiteral("lightmapuvraster_uv_tangent"), m_cache.lightmapUVRasterShader_uv_tangent);
162 case LightmapUVRasterizationShaderMode::Default:
163 return getBuiltinRhiShader(QByteArrayLiteral("lightmapuvraster"), m_cache.lightmapUVRasterShader);
164 }
165
166 Q_UNREACHABLE_RETURN(getBuiltinRhiShader(QByteArrayLiteral("lightmapuvraster"), m_cache.lightmapUVRasterShader));
167}
168
169QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiLightmapDilateShader()
170{
171 return getBuiltinRhiShader(QByteArrayLiteral("lightmapdilate"), m_cache.lightmapDilateShader);
172}
173
174QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiDebugObjectShader(int viewCount)
175{
176 return getBuiltinRhiShader(QByteArrayLiteral("debugobject"), m_cache.debugObjectShader, viewCount);
177}
178
179QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiReflectionprobePreFilterShader()
180{
181 return getBuiltinRhiShader(QByteArrayLiteral("reflectionprobeprefilter"), m_cache.reflectionprobePreFilterShader);
182}
183
184QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhienvironmentmapPreFilterShader(bool isRGBE)
185{
186 static constexpr char variant[][29] { "environmentmapprefilter", "environmentmapprefilter_rgbe" };
187 const quint8 idx = quint8(isRGBE);
188 return getBuiltinRhiShader(QByteArray::fromRawData(variant[idx], std::char_traits<char>::length(variant[idx])), m_cache.environmentmapPreFilterShader[idx]);
189}
190
191QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiEnvironmentmapShader()
192{
193 return getBuiltinRhiShader(QByteArrayLiteral("environmentmap"), m_cache.environmentmapShader);
194}
195
196QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiClearMRTShader()
197{
198 return getBuiltinRhiShader(QByteArrayLiteral("clear_mrt"), m_cache.clearMRTShader);
199}
200
201QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiOitCompositeShader(QSSGRenderLayer::OITMethod method, bool multisample, bool use_buffers)
202{
203 if (method == QSSGRenderLayer::OITMethod::WeightedBlended){
204 if (multisample)
205 return getBuiltinRhiShader(QByteArrayLiteral("oitcomposite_weightedblended_ms"), m_cache.oitCompositeShader[1]);
206 else
207 return getBuiltinRhiShader(QByteArrayLiteral("oitcomposite_weightedblended"), m_cache.oitCompositeShader[0]);
208 } else if (method == QSSGRenderLayer::OITMethod::LinkedList) {
209 if (use_buffers) {
210 if (multisample)
211 return getBuiltinRhiShader(QByteArrayLiteral("oitcomposite_linkedlist_ms_buf"), m_cache.oitCompositeShader[5]);
212 else
213 return getBuiltinRhiShader(QByteArrayLiteral("oitcomposite_linkedlist_buf"), m_cache.oitCompositeShader[4]);
214 } else {
215 if (multisample)
216 return getBuiltinRhiShader(QByteArrayLiteral("oitcomposite_linkedlist_ms"), m_cache.oitCompositeShader[3]);
217 else
218 return getBuiltinRhiShader(QByteArrayLiteral("oitcomposite_linkedlist"), m_cache.oitCompositeShader[2]);
219 }
220 }
221 Q_UNREACHABLE_RETURN(getBuiltinRhiShader(QByteArrayLiteral("oitcomposite_weightedblended"), m_cache.oitCompositeShader[0]));
222}
223
224QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiCubeMapToAtlasShader()
225{
226 return getBuiltinRhiShader(QByteArrayLiteral("cubeMapToHemisphere"), m_cache.cubeMapToAtlasShader);
227}
228
229QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiClearShadowMapShader()
230{
231 return getBuiltinRhiShader(QByteArrayLiteral("clearshadowmap"), m_cache.clearShadowMapShader);
232}
233
234QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiClearImageShader()
235{
236 return getBuiltinRhiShader(QByteArrayLiteral("clearimage"), m_cache.clearImageShader);
237}
238
239QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiClearBufferShader()
240{
241 return getBuiltinRhiShader(QByteArrayLiteral("clearbuffer"), m_cache.clearBufferShader);
242}
243
244QT_END_NAMESPACE
Combined button and popup list for selecting options.
static constexpr size_t getSkyboxIndex(QSSGRenderLayer::TonemapMode tonemapMode, bool isRGBE)