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