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#include "qssgrendererimplshaders_p.h"
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
18QT_BEGIN_NAMESPACE
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(inKey: 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::getRhiCubemapShadowBlurXShader()
43{
44 return getBuiltinRhiShader(QByteArrayLiteral("cubeshadowblurx"), storage&: m_cache.cubemapShadowBlurXRhiShader);
45}
46
47QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiCubemapShadowBlurYShader()
48{
49 return getBuiltinRhiShader(QByteArrayLiteral("cubeshadowblury"), storage&: m_cache.cubemapShadowBlurYRhiShader);
50}
51
52QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiGridShader(int viewCount)
53{
54 return getBuiltinRhiShader(QByteArrayLiteral("grid"), storage&: m_cache.gridShader, viewCount);
55}
56
57QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiOrthographicShadowBlurXShader()
58{
59 return getBuiltinRhiShader(QByteArrayLiteral("orthoshadowblurx"), storage&: m_cache.orthographicShadowBlurXRhiShader);
60}
61
62QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiOrthographicShadowBlurYShader()
63{
64 return getBuiltinRhiShader(QByteArrayLiteral("orthoshadowblury"), storage&: m_cache.orthographicShadowBlurYRhiShader);
65}
66
67QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiSsaoShader(int viewCount)
68{
69 return getBuiltinRhiShader(QByteArrayLiteral("ssao"), storage&: m_cache.ssaoRhiShader, viewCount);
70}
71
72QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiSkyBoxCubeShader(int viewCount)
73{
74 return getBuiltinRhiShader(QByteArrayLiteral("skyboxcube"), storage&: m_cache.skyBoxCubeRhiShader, viewCount);
75}
76
77static inline constexpr size_t getSkyboxIndex(QSSGRenderLayer::TonemapMode tonemapMode, bool isRGBE)
78{
79 switch (tonemapMode) {
80 case QSSGRenderLayer::TonemapMode::None:
81 return 0 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount);
82 case QSSGRenderLayer::TonemapMode::Linear:
83 return 1 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount);
84 case QSSGRenderLayer::TonemapMode::Aces:
85 return 2 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount);
86 case QSSGRenderLayer::TonemapMode::HejlDawson:
87 return 3 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount);
88 case QSSGRenderLayer::TonemapMode::Filmic:
89 return 4 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount);
90 case QSSGRenderLayer::TonemapMode::Custom:
91 return 5 + (size_t(isRGBE) * QSSGRenderLayer::TonemapModeCount);
92 }
93
94 // GCC 8.x does not treat __builtin_unreachable() as constexpr
95# if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
96 // NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
97 Q_UNREACHABLE();
98# endif
99 return 0;
100}
101
102QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiSkyBoxShader(QSSGRenderLayer::TonemapMode tonemapMode, bool isRGBE, int viewCount)
103{
104 // Skybox shader is special and has multiple possible shaders so we have to do
105 // a bit of manual work here (mapping resolved in getSkyboxIndex()).
106 static constexpr char variant[][23] { "skybox_hdr_none",
107 "skybox_hdr_linear",
108 "skybox_hdr_aces",
109 "skybox_hdr_hejldawson",
110 "skybox_hdr_filmic",
111 "skybox_hdr_custom",
112 "skybox_rgbe_none",
113 "skybox_rgbe_linear",
114 "skybox_rgbe_aces",
115 "skybox_rgbe_hejldawson",
116 "skybox_rgbe_filmic",
117 "skybox_rgbe_custom",
118 };
119
120 const size_t skyboxIndex = getSkyboxIndex(tonemapMode, isRGBE);
121 return getBuiltinRhiShader(name: QByteArray::fromRawData(data: variant[skyboxIndex], size: std::char_traits<char>::length(s: variant[skyboxIndex])), storage&: m_cache.skyBoxRhiShader[skyboxIndex], viewCount);
122}
123
124QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiSupersampleResolveShader(int viewCount)
125{
126 return getBuiltinRhiShader(QByteArrayLiteral("ssaaresolve"), storage&: m_cache.supersampleResolveRhiShader, viewCount);
127}
128
129QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiProgressiveAAShader()
130{
131 return getBuiltinRhiShader(QByteArrayLiteral("progressiveaa"), storage&: m_cache.progressiveAARhiShader);
132}
133
134QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiParticleShader(QSSGRenderParticles::FeatureLevel featureLevel, int viewCount)
135{
136 switch (featureLevel) {
137 case QSSGRenderParticles::FeatureLevel::Simple:
138 return getBuiltinRhiShader(QByteArrayLiteral("particlesnolightsimple"), storage&: m_cache.particlesNoLightingSimpleRhiShader, viewCount);
139 break;
140 case QSSGRenderParticles::FeatureLevel::Mapped:
141 return getBuiltinRhiShader(QByteArrayLiteral("particlesnolightmapped"), storage&: m_cache.particlesNoLightingMappedRhiShader, viewCount);
142 break;
143 case QSSGRenderParticles::FeatureLevel::Animated:
144 return getBuiltinRhiShader(QByteArrayLiteral("particlesnolightanimated"), storage&: m_cache.particlesNoLightingAnimatedRhiShader, viewCount);
145 break;
146 case QSSGRenderParticles::FeatureLevel::SimpleVLight:
147 return getBuiltinRhiShader(QByteArrayLiteral("particlesvlightsimple"), storage&: m_cache.particlesVLightingSimpleRhiShader, viewCount);
148 break;
149 case QSSGRenderParticles::FeatureLevel::MappedVLight:
150 return getBuiltinRhiShader(QByteArrayLiteral("particlesvlightmapped"), storage&: m_cache.particlesVLightingMappedRhiShader, viewCount);
151 break;
152 case QSSGRenderParticles::FeatureLevel::AnimatedVLight:
153 return getBuiltinRhiShader(QByteArrayLiteral("particlesvlightanimated"), storage&: m_cache.particlesVLightingAnimatedRhiShader, viewCount);
154 break;
155 case QSSGRenderParticles::FeatureLevel::Line:
156 return getBuiltinRhiShader(QByteArrayLiteral("lineparticles"), storage&: m_cache.lineParticlesRhiShader, viewCount);
157 break;
158 case QSSGRenderParticles::FeatureLevel::LineMapped:
159 return getBuiltinRhiShader(QByteArrayLiteral("lineparticlesmapped"), storage&: m_cache.lineParticlesMappedRhiShader, viewCount);
160 break;
161 case QSSGRenderParticles::FeatureLevel::LineAnimated:
162 return getBuiltinRhiShader(QByteArrayLiteral("lineparticlesanimated"), storage&: m_cache.lineParticlesAnimatedRhiShader, viewCount);
163 break;
164 case QSSGRenderParticles::FeatureLevel::LineVLight:
165 return getBuiltinRhiShader(QByteArrayLiteral("lineparticlesvlightsimple"), storage&: m_cache.lineParticlesVLightRhiShader, viewCount);
166 break;
167 case QSSGRenderParticles::FeatureLevel::LineMappedVLight:
168 return getBuiltinRhiShader(QByteArrayLiteral("lineparticlesvlightmapped"), storage&: m_cache.lineParticlesMappedVLightRhiShader, viewCount);
169 break;
170 case QSSGRenderParticles::FeatureLevel::LineAnimatedVLight:
171 return getBuiltinRhiShader(QByteArrayLiteral("lineparticlesvlightanimated"), storage&: m_cache.lineParticlesAnimatedVLightRhiShader, viewCount);
172 break;
173 }
174 return getBuiltinRhiShader(QByteArrayLiteral("particlesnolightanimated"), storage&: m_cache.particlesNoLightingAnimatedRhiShader, viewCount);
175}
176
177QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiSimpleQuadShader(int viewCount)
178{
179 return getBuiltinRhiShader(QByteArrayLiteral("simplequad"), storage&: m_cache.simpleQuadRhiShader, viewCount);
180}
181
182QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiLightmapUVRasterizationShader(LightmapUVRasterizationShaderMode mode)
183{
184 switch (mode) {
185 case LightmapUVRasterizationShaderMode::Uv:
186 return getBuiltinRhiShader(QByteArrayLiteral("lightmapuvraster_uv"), storage&: m_cache.lightmapUVRasterShader_uv);
187 case LightmapUVRasterizationShaderMode::UvTangent:
188 return getBuiltinRhiShader(QByteArrayLiteral("lightmapuvraster_uv_tangent"), storage&: m_cache.lightmapUVRasterShader_uv_tangent);
189 case LightmapUVRasterizationShaderMode::Default:
190 return getBuiltinRhiShader(QByteArrayLiteral("lightmapuvraster"), storage&: m_cache.lightmapUVRasterShader);
191 }
192
193 Q_UNREACHABLE_RETURN(getBuiltinRhiShader(QByteArrayLiteral("lightmapuvraster"), m_cache.lightmapUVRasterShader));
194}
195
196QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiLightmapDilateShader()
197{
198 return getBuiltinRhiShader(QByteArrayLiteral("lightmapdilate"), storage&: m_cache.lightmapDilateShader);
199}
200
201QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiDebugObjectShader(int viewCount)
202{
203 return getBuiltinRhiShader(QByteArrayLiteral("debugobject"), storage&: m_cache.debugObjectShader, viewCount);
204}
205
206QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiReflectionprobePreFilterShader()
207{
208 return getBuiltinRhiShader(QByteArrayLiteral("reflectionprobeprefilter"), storage&: m_cache.reflectionprobePreFilterShader);
209}
210
211QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhienvironmentmapPreFilterShader(bool isRGBE)
212{
213 static constexpr char variant[][29] { "environmentmapprefilter", "environmentmapprefilter_rgbe" };
214 const quint8 idx = quint8(isRGBE);
215 return getBuiltinRhiShader(name: QByteArray::fromRawData(data: variant[idx], size: std::char_traits<char>::length(s: variant[idx])), storage&: m_cache.environmentmapPreFilterShader[idx]);
216}
217
218QSSGRhiShaderPipelinePtr QSSGBuiltInRhiShaderCache::getRhiEnvironmentmapShader()
219{
220 return getBuiltinRhiShader(QByteArrayLiteral("environmentmap"), storage&: m_cache.environmentmapShader);
221}
222
223QT_END_NAMESPACE
224

source code of qtquick3d/src/runtimerender/rendererimpl/qssgrendererimplshaders_rhi.cpp