Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qssgrenderuserpass.cpp
Go to the documentation of this file.
1
// Copyright (C) 2025 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
6
#
include
"qssgrenderuserpass_p.h"
7
#
include
<
QtQuick3DRuntimeRender
/
private
/
qssgrendercommands_p
.
h
>
8
#
include
<
QtQuick3DRuntimeRender
/
private
/
qssgrendershadertokenizer_p
.
h
>
9
#
include
<
QtCore
/
qcryptographichash
.
h
>
10
11
#
include
<
ssg
/
qssgrendercontextcore
.
h
>
12
13
#
include
<
iterator
>
14
15
QT_BEGIN_NAMESPACE
16
17
Q_STATIC_LOGGING_CATEGORY
(lcRenderUserPass,
"qt.quick3d.runtimerender.renderuserpass"
)
18
19
namespace
20
{
21
22
enum
class
AugmentMacro
:
size_t
{
23
BASE_COLOR
,
24
ROUGHNESS
,
25
METALNESS
,
26
DIFFUSE_LIGHT
,
27
SPECULAR_LIGHT
,
28
EMISSIVE_LIGHT
,
29
WORLD_NORMAL
,
30
WORLD_TANGENT
,
31
WORLD_BINORMAL
,
32
F0
,
33
F90
34
};
35
36
static
constexpr
QSSGUserShaderAugmentation
::
FeatureFlags
featureForMacro
(
AugmentMacro
macro)
37
{
38
switch
(macro) {
39
case
AugmentMacro::BASE_COLOR:
40
return
QSSGUserShaderAugmentation::FeatureFlags::BaseColor;
41
case
AugmentMacro::ROUGHNESS:
42
return
QSSGUserShaderAugmentation::FeatureFlags::Roughness;
43
case
AugmentMacro::METALNESS:
44
return
QSSGUserShaderAugmentation::FeatureFlags::Metalness;
45
case
AugmentMacro::DIFFUSE_LIGHT:
46
return
QSSGUserShaderAugmentation::FeatureFlags::DiffuseLight;
47
case
AugmentMacro::SPECULAR_LIGHT:
48
return
QSSGUserShaderAugmentation::FeatureFlags::SpecularLight;
49
case
AugmentMacro::EMISSIVE_LIGHT:
50
return
QSSGUserShaderAugmentation::FeatureFlags::EmissiveLight;
51
case
AugmentMacro::WORLD_NORMAL:
52
return
QSSGUserShaderAugmentation::FeatureFlags::WorldNormal;
53
case
AugmentMacro::WORLD_TANGENT:
54
return
QSSGUserShaderAugmentation::FeatureFlags::WorldTangent;
55
case
AugmentMacro::WORLD_BINORMAL:
56
return
QSSGUserShaderAugmentation::FeatureFlags::WorldBinormal;
57
case
AugmentMacro::F0:
58
return
QSSGUserShaderAugmentation::FeatureFlags::F0;
59
case
AugmentMacro::F90:
60
return
QSSGUserShaderAugmentation::FeatureFlags::F90;
61
}
62
63
Q_UNREACHABLE_RETURN(QSSGUserShaderAugmentation::FeatureFlags::None);
64
}
65
66
constexpr
size_t
QSSGMaxMacroLength
= 16;
67
constexpr
size_t
QSSGMaxReplacementLength
= 32;
68
69
struct
MacroPair
{
70
const
char
macroName
[QSSGMaxMacroLength];
71
const
char
replacement
[QSSGMaxReplacementLength];
72
};
73
74
static
constexpr
MacroPair
augmentMacroPairs
[] = {
75
{
"BASE_COLOR"
,
"qt_diffuseColor"
},
76
{
"ROUGHNESS"
,
"qt_roughnessAmount"
},
77
{
"METALNESS"
,
"qt_metalnessAmount"
},
78
{
"DIFFUSE_LIGHT"
,
"global_diffuse_light.rgb"
},
79
{
"SPECULAR_LIGHT"
,
"global_specular_light"
},
80
{
"EMISSIVE_LIGHT"
,
"global_emission"
},
81
{
"WORLD_NORMAL"
,
"qt_world_normal"
},
82
{
"WORLD_TANGENT"
,
"qt_tangent"
},
83
{
"WORLD_BINORMAL"
,
"qt_binormal"
},
84
{
"F0"
,
"qt_f0"
},
85
{
"F90"
,
"qt_f90"
}
86
};
87
88
constexpr
QByteArrayView
augmentMacroName
(
AugmentMacro
macro)
89
{
90
return
QByteArrayView(augmentMacroPairs[
static_cast
<size_t>(macro)].macroName);
91
}
92
93
constexpr
QByteArrayView
augmentMacroReplacement
(
AugmentMacro
macro)
94
{
95
return
QByteArrayView(augmentMacroPairs[
static_cast
<size_t>(macro)].replacement);
96
}
97
98
}
99
100
// NOTE: While this class doesn't have graphics resources itself, it manages commands that do!
101
QSSGRenderUserPass::QSSGRenderUserPass()
102
: QSSGRenderGraphObject(Type::RenderPass, FlagT(Flags::HasGraphicsResources))
103
{
104
105
}
106
107
QSSGRenderUserPass::~QSSGRenderUserPass()
108
{
109
resetCommands();
110
}
111
112
bool
QSSGRenderUserPass::isDirty(DirtyFlag flag)
const
113
{
114
return
(m_dirtyFlags & FlagT(flag)) != 0;
115
}
116
117
void
QSSGRenderUserPass::markDirty(DirtyFlag flag)
118
{
119
m_dirtyFlags |= FlagT(flag);
120
}
121
122
void
QSSGRenderUserPass::clearDirty(DirtyFlag flag)
123
{
124
m_dirtyFlags &= ~FlagT(flag);
125
}
126
127
void
QSSGRenderUserPass::replaceAugmentMacros(QByteArray &shaderCode, QSSGUserShaderAugmentation &augmentation)
128
{
129
// Tokenize the shader code and replace any identifier that matches one of the augment
130
// macros (e.g. BASE_COLOR) with the corresponding built-in variable name. Using the
131
// tokenizer means we only ever match whole identifiers - never a substring of a larger
132
// identifier - and macros inside comments are skipped, all without re-implementing that
133
// logic here.
134
QSSGShaderTokenizer tok;
135
tok.initialize(shaderCode.constData());
136
137
const
char
*
const
begin = shaderCode.constData();
138
const
char
*
const
end = begin + shaderCode.size();
139
const
char
*lastPos = begin;
// Start of the region not yet copied to the result.
140
141
QByteArray result;
142
result.reserve(shaderCode.size());
143
144
for
(QSSGShaderTokenizer::Token t = tok.next(); t != QSSGShaderTokenizer::Token_EOF; t = tok.next()) {
145
if
(t != QSSGShaderTokenizer::Token_Identifier)
146
continue
;
147
148
const
QByteArrayView id(tok.identifier, tok.pos - tok.identifier);
149
for
(size_t i = 0, n = std::size(augmentMacroPairs); i < n; ++i) {
150
const
AugmentMacro macro =
static_cast
<AugmentMacro>(i);
151
if
(id != augmentMacroName(macro))
152
continue
;
153
154
// Copy everything up to the macro verbatim (preserving comments, whitespace and
155
// any non-matching code), then append the replacement in its place.
156
const
QByteArrayView replacement = augmentMacroReplacement(macro);
157
result.append(lastPos, tok.identifier - lastPos);
158
result.append(replacement.data(), replacement.size());
159
lastPos = tok.pos;
160
augmentation.setFeatureFlag(featureForMacro(macro));
161
break
;
162
}
163
}
164
165
// No macros were found, leave the shader code untouched.
166
if
(lastPos == begin)
167
return
;
168
169
// Copy the trailing remainder after the last replacement.
170
result.append(lastPos, end - lastPos);
171
shaderCode = std::move(result);
172
}
173
174
void
QSSGRenderUserPass::finalizeShaders(
const
QSSGRenderContextInterface &ctx)
175
{
176
Q_UNUSED(ctx);
177
178
if
(materialMode != AugmentMaterial)
179
return
;
180
181
if
(!isDirty(DirtyFlag::ShaderDirty))
182
return
;
183
184
clearDirty(DirtyFlag::ShaderDirty);
185
186
shaderAugmentation.featureFlags = 0;
187
shaderAugmentation.hash.clear();
188
189
const
bool
hasShaderCode = (shaderAugmentation.hasUserAugmentation());
190
191
if
(hasShaderCode) {
192
qCDebug(lcRenderUserPass) <<
"Finalizing shaders for user pass with augment shader code."
;
193
194
// Replace any instances of the AugmentMacros with the appropriate built-in variable names
195
replaceAugmentMacros(shaderAugmentation.preamble, shaderAugmentation);
196
replaceAugmentMacros(shaderAugmentation.body, shaderAugmentation);
197
// Used to build the unique shader cache key. The shader key goes in the generated
198
// shader as a one line comment so it can't be multiline. Generate hash from the
199
// augmented shader preamble and body instead, which gets combined with the material key.
200
const
QByteArray fullAugmentation = shaderAugmentation.preamble + shaderAugmentation.body;
201
shaderAugmentation.hash = QCryptographicHash::hash(QByteArrayView(fullAugmentation),
202
QCryptographicHash::Algorithm::Sha1).toHex();
203
204
m_state = State::Ready;
205
}
else
{
206
m_state = State::Error;
207
208
qWarning() <<
"No augment shader code provided for user pass."
;
209
}
210
211
// Finalize shaders for all commands
212
qCDebug(lcRenderUserPass) <<
"Finalizing shaders for user pass commands"
;
213
}
214
215
void
QSSGRenderUserPass::resetCommands()
216
{
217
qDeleteAll(commands);
218
commands.clear();
219
}
220
221
QT_END_NAMESPACE
QT_BEGIN_NAMESPACE::augmentMacroReplacement
constexpr QByteArrayView augmentMacroReplacement(AugmentMacro macro)
Definition
qssgrenderuserpass.cpp:93
QT_BEGIN_NAMESPACE::augmentMacroPairs
static constexpr MacroPair augmentMacroPairs[]
Definition
qssgrenderuserpass.cpp:74
QT_BEGIN_NAMESPACE::featureForMacro
static constexpr QSSGUserShaderAugmentation::FeatureFlags featureForMacro(AugmentMacro macro)
Definition
qssgrenderuserpass.cpp:36
QT_BEGIN_NAMESPACE::AugmentMacro
AugmentMacro
Definition
qssgrenderuserpass.cpp:22
QT_BEGIN_NAMESPACE::AugmentMacro::F90
@ F90
Definition
qssgrenderuserpass.cpp:33
QT_BEGIN_NAMESPACE::AugmentMacro::METALNESS
@ METALNESS
Definition
qssgrenderuserpass.cpp:25
QT_BEGIN_NAMESPACE::AugmentMacro::SPECULAR_LIGHT
@ SPECULAR_LIGHT
Definition
qssgrenderuserpass.cpp:27
QT_BEGIN_NAMESPACE::AugmentMacro::DIFFUSE_LIGHT
@ DIFFUSE_LIGHT
Definition
qssgrenderuserpass.cpp:26
QT_BEGIN_NAMESPACE::AugmentMacro::BASE_COLOR
@ BASE_COLOR
Definition
qssgrenderuserpass.cpp:23
QT_BEGIN_NAMESPACE::AugmentMacro::ROUGHNESS
@ ROUGHNESS
Definition
qssgrenderuserpass.cpp:24
QT_BEGIN_NAMESPACE::AugmentMacro::WORLD_BINORMAL
@ WORLD_BINORMAL
Definition
qssgrenderuserpass.cpp:31
QT_BEGIN_NAMESPACE::AugmentMacro::EMISSIVE_LIGHT
@ EMISSIVE_LIGHT
Definition
qssgrenderuserpass.cpp:28
QT_BEGIN_NAMESPACE::AugmentMacro::WORLD_NORMAL
@ WORLD_NORMAL
Definition
qssgrenderuserpass.cpp:29
QT_BEGIN_NAMESPACE::AugmentMacro::WORLD_TANGENT
@ WORLD_TANGENT
Definition
qssgrenderuserpass.cpp:30
QT_BEGIN_NAMESPACE::AugmentMacro::F0
@ F0
Definition
qssgrenderuserpass.cpp:32
QT_BEGIN_NAMESPACE::augmentMacroName
constexpr QByteArrayView augmentMacroName(AugmentMacro macro)
Definition
qssgrenderuserpass.cpp:88
QT_BEGIN_NAMESPACE::QSSGMaxReplacementLength
constexpr size_t QSSGMaxReplacementLength
Definition
qssgrenderuserpass.cpp:67
QT_BEGIN_NAMESPACE::QSSGMaxMacroLength
constexpr size_t QSSGMaxMacroLength
Definition
qssgrenderuserpass.cpp:66
Q_STATIC_LOGGING_CATEGORY
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)
QT_BEGIN_NAMESPACE::MacroPair
Definition
qssgrenderuserpass.cpp:69
QT_BEGIN_NAMESPACE::MacroPair::replacement
const char replacement[QSSGMaxReplacementLength]
Definition
qssgrenderuserpass.cpp:71
QT_BEGIN_NAMESPACE::MacroPair::macroName
const char macroName[QSSGMaxMacroLength]
Definition
qssgrenderuserpass.cpp:70
qtquick3d
src
runtimerender
graphobjects
qssgrenderuserpass.cpp
Generated on
for Qt by
1.18.0