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
qssgshaderresourcemergecontext_p.h
Go to the documentation of this file.
1
// Copyright (C) 2019 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
#
ifndef
QSSGSHADERRESOURCEMERGECONTEXT_P_H
7
#
define
QSSGSHADERRESOURCEMERGECONTEXT_P_H
8
9
//
10
// W A R N I N G
11
// -------------
12
//
13
// This file is not part of the Qt API. It exists purely as an
14
// implementation detail. This header file may change from version to
15
// version without notice, or even be removed.
16
//
17
// We mean it.
18
//
19
20
#
include
"qssgrendershadercodegenerator_p.h"
21
#
include
"qssgrendershadermetadata_p.h"
22
23
QT_BEGIN_NAMESPACE
24
25
class
QSSGShaderResourceMergeContext
26
{
27
public
:
28
29
QSSGShaderResourceMergeContext()
30
: m_nextFreeResourceBinding(FIRST_CUSTOM_RESOURCE_BINDING_POINT + s_additionalBuffers)
31
{
32
}
33
// Resource bindings 0..2 are reserved for uniform buffers.
34
// (0 is cbMain, 1 is cbLights)
35
static
const
int
FIRST_CUSTOM_RESOURCE_BINDING_POINT = 3;
36
37
struct
InOutVar {
38
QSSGShaderGeneratorStageFlags stageOutputFrom;
39
QSSGShaderGeneratorStageFlags stagesInputIn;
40
QByteArray type;
41
QByteArray name;
42
int
location;
43
bool
output;
44
bool
flat;
45
};
46
47
struct
Sampler {
48
QByteArray type;
49
QByteArray name;
50
QSSGRenderShaderMetadata::Uniform::Condition conditionType;
51
QByteArray conditionName;
52
int
binding;
53
};
54
55
struct
Image :
public
Sampler
56
{
57
QByteArray imgType;
58
QSSGMemoryQualifiers qualifiers;
59
QSSGShaderGeneratorStageFlags stages;
60
};
61
62
struct
BlockMember {
63
QByteArray type;
64
QByteArray name;
65
QSSGRenderShaderMetadata::Uniform::Condition conditionType;
66
QByteArray conditionName;
67
};
68
69
struct
Buffer :
public
BlockMember
70
{
71
int
binding;
72
QByteArray contentType;
73
QSSGMemoryQualifiers qualifiers;
74
QSSGShaderGeneratorStageFlags stages;
75
};
76
77
// Using QMap intentionally - while it is not strictly required to use an
78
// ordered map, being sorted by key when iterating is helpful to get the
79
// same ordered list of vertex inputs, uniforms, etc. on every run, which
80
// in turn helps shader (disk) cache efficiency due to not generating a
81
// different shader string just because QHash decided to iterate entries in
82
// a different order.
83
QMap<QByteArray, InOutVar> m_inOutVars;
84
QMap<QByteArray, Sampler> m_samplers;
85
QMap<QByteArray, Image> m_images;
86
QMap<QByteArray, Buffer> m_buffers;
87
QMap<QByteArray, BlockMember> m_uniformMembers;
88
89
int
m_nextFreeResourceBinding = FIRST_CUSTOM_RESOURCE_BINDING_POINT;
90
int
m_nextFreeImageBinding = 0;
91
QHash<
int
,
int
> m_nextFreeInLocation;
92
QHash<
int
,
int
> m_nextFreeOutLocation;
93
94
int
viewCount = 1;
95
96
void
rearrangeResources()
97
{
98
// Put images and storage buffers before samplers. QRhi's OpenGL
99
// backend uses the binding number directly as the image unit and as
100
// the shader storage buffer binding point, and the guaranteed minimum
101
// for both is only 8 (GL_MAX_IMAGE_UNITS, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS).
102
// These are separate namespaces in OpenGL, but QRhi needs unique binding
103
// numbers across all resource types, so the numbers used by uniform buffers (0..2),
104
// images and buffers all count against both limits. Linked list OIT adds three
105
// images, which leaves two bindings for custom images and buffers.
106
// Samplers and uniform buffers are not affected: QRhi assigns texture
107
// units itself and sets uniform block members as plain uniforms.
108
int
binding = FIRST_CUSTOM_RESOURCE_BINDING_POINT + s_additionalBuffers;
109
for
(
auto
&image : m_images)
110
image.binding = binding++;
111
for
(
auto
&buffer : m_buffers)
112
buffer.binding = binding++;
113
for
(
auto
&sampler : m_samplers)
114
sampler.binding = binding++;
115
}
116
117
void
registerInput(QSSGShaderGeneratorStage stage,
const
QByteArray &type,
const
QByteArray &name,
bool
flat =
false
)
118
{
119
auto
it = m_inOutVars.find(name);
120
if
(it != m_inOutVars.end()) {
121
it->stagesInputIn |= stage;
122
return
;
123
}
124
InOutVar var { {}, stage, type, name, m_nextFreeInLocation[
int
(stage)]++,
false
, flat };
125
m_inOutVars.insert(name, var);
126
}
127
128
void
registerOutput(QSSGShaderGeneratorStage stage,
const
QByteArray &type,
const
QByteArray &name,
bool
flat =
false
)
129
{
130
auto
it = m_inOutVars.find(name);
131
if
(it != m_inOutVars.end()) {
132
it->stageOutputFrom |= stage;
133
return
;
134
}
135
InOutVar var { stage, {}, type, name, m_nextFreeOutLocation[
int
(stage)]++,
true
, flat };
136
m_inOutVars.insert(name, var);
137
}
138
139
void
registerSampler(
const
QByteArray &type,
140
const
QByteArray &name,
141
QSSGRenderShaderMetadata::Uniform::Condition conditionType = QSSGRenderShaderMetadata::Uniform::None,
142
const
QByteArray &conditionName = QByteArray())
143
{
144
if
(m_images.contains(name) || m_buffers.contains(name)) {
145
qWarning(
"Sampler %s name conflicts with existing image or buffer."
, name.constData());
146
return
;
147
}
148
if
(m_samplers.contains(name))
149
return
;
150
Sampler var { type, name, conditionType, conditionName, m_nextFreeResourceBinding++ };
151
m_samplers.insert(name, var);
152
}
153
154
void
registerImage(QSSGShaderGeneratorStage stage,
155
const
QByteArray &type,
156
const
QByteArray &name,
157
const
QByteArray &imgtype,
158
QSSGMemoryQualifiers qualifiers,
159
QSSGRenderShaderMetadata::Uniform::Condition conditionType = QSSGRenderShaderMetadata::Uniform::None,
160
const
QByteArray &conditionName = QByteArray())
161
{
162
if
(m_samplers.contains(name) || m_buffers.contains(name)) {
163
qWarning(
"Image %s name conflicts with existing sampler or buffer."
, name.constData());
164
return
;
165
}
166
auto
iter = m_images.find(name);
167
if
(iter != m_images.end()) {
168
auto
&img = *iter;
169
if
(img.type != type || img.imgType != imgtype || img.qualifiers != qualifiers)
170
qWarning(
"Image %s is declared differently between shader stages."
, name.constData());
171
if
(img.conditionType != conditionType || img.conditionName != conditionName)
172
qWarning(
"Image %s condition doesn't match between shader stages."
, name.constData());
173
img.stages |= stage;
174
return
;
175
}
176
Image var {{type, name, conditionType, conditionName, m_nextFreeResourceBinding++}, imgtype, qualifiers, stage};
177
m_images.insert(name, var);
178
}
179
void
registerBuffer(QSSGShaderGeneratorStage stage,
180
const
QByteArray &contentType,
181
const
QByteArray &name,
182
QSSGMemoryQualifiers qualifiers,
183
QSSGRenderShaderMetadata::Uniform::Condition conditionType = QSSGRenderShaderMetadata::Uniform::None,
184
const
QByteArray &conditionName = QByteArray())
185
{
186
if
(m_samplers.contains(name) || m_images.contains(name)) {
187
qWarning(
"Buffer %s name conflicts with existing sampler or image."
, name.constData());
188
return
;
189
}
190
auto
iter = m_buffers.find(name);
191
if
(iter != m_buffers.end()) {
192
auto
&buf = *iter;
193
if
(buf.contentType.simplified() != contentType.simplified() || buf.qualifiers != qualifiers)
194
qWarning(
"Storage buffer %s is declared differently between shader stages."
, name.constData());
195
if
(buf.conditionType != conditionType || buf.conditionName != conditionName)
196
qWarning(
"Storage buffer %s condition doesn't match between shader stages."
, name.constData());
197
buf.stages |= stage;
198
return
;
199
}
200
Buffer var {{
"buffer"
, name, conditionType, conditionName}, m_nextFreeResourceBinding++, contentType, qualifiers, stage};
201
m_buffers.insert(name, var);
202
}
203
204
void
registerUniformMember(
const
QByteArray &type,
205
const
QByteArray &name,
206
QSSGRenderShaderMetadata::Uniform::Condition conditionType = QSSGRenderShaderMetadata::Uniform::None,
207
const
QByteArray &conditionName = QByteArray())
208
{
209
auto
it = m_uniformMembers.constFind(name);
210
if
(it != m_uniformMembers.constEnd()) {
211
if
(it->conditionType != conditionType) {
212
qWarning(
"Encountered uniform %s with different conditions, this is not supported."
,
213
name.constData());
214
}
215
return
;
216
}
217
BlockMember var { type, name, conditionType, conditionName };
218
m_uniformMembers.insert(name, var);
219
}
220
static
int
s_additionalBuffers;
221
static
void
setAdditionalBufferAmount(
int
amount)
222
{
223
s_additionalBuffers = amount;
224
}
225
};
226
227
QT_END_NAMESPACE
228
229
#
endif
qtquick3d
src
runtimerender
qssgshaderresourcemergecontext_p.h
Generated on
for Qt by
1.18.0