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