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
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
22
23QT_BEGIN_NAMESPACE
24
25class QSSGShaderResourceMergeContext
26{
27public:
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 QByteArray qualifiers;
59 };
60
61 struct BlockMember {
62 QByteArray type;
63 QByteArray name;
64 QSSGRenderShaderMetadata::Uniform::Condition conditionType;
65 QByteArray conditionName;
66 };
67
68 // Using QMap intentionally - while it is not strictly required to use an
69 // ordered map, being sorted by key when iterating is helpful to get the
70 // same ordered list of vertex inputs, uniforms, etc. on every run, which
71 // in turn helps shader (disk) cache efficiency due to not generating a
72 // different shader string just because QHash decided to iterate entries in
73 // a different order.
74 QMap<QByteArray, InOutVar> m_inOutVars;
75 QMap<QByteArray, Sampler> m_samplers;
76 QMap<QByteArray, Image> m_images;
77 QMap<QByteArray, BlockMember> m_uniformMembers;
78
79 int m_nextFreeResourceBinding = FIRST_CUSTOM_RESOURCE_BINDING_POINT;
80 int m_nextFreeImageBinding = 0;
81 QHash<int, int> m_nextFreeInLocation;
82 QHash<int, int> m_nextFreeOutLocation;
83
84 int viewCount = 1;
85
86 void rearrangeResources()
87 {
88 // Put the images before samplers since images have
89 // separate binding points in OpenGL and minimum
90 // amount is only 8 so with many textures we might run
91 // out of binding points. Minimum amount of texture
92 // binding points is 16.
93 int binding = FIRST_CUSTOM_RESOURCE_BINDING_POINT + s_additionalBuffers;
94 for (auto &image : m_images)
95 image.binding = binding++;
96 for (auto &sampler : m_samplers)
97 sampler.binding = binding++;
98 }
99
100 void registerInput(QSSGShaderGeneratorStage stage, const QByteArray &type, const QByteArray &name, bool flat = false)
101 {
102 auto it = m_inOutVars.find(name);
103 if (it != m_inOutVars.end()) {
104 it->stagesInputIn |= stage;
105 return;
106 }
107 InOutVar var { {}, stage, type, name, m_nextFreeInLocation[int(stage)]++, false, flat };
108 m_inOutVars.insert(name, var);
109 }
110
111 void registerOutput(QSSGShaderGeneratorStage stage, const QByteArray &type, const QByteArray &name, bool flat = false)
112 {
113 auto it = m_inOutVars.find(name);
114 if (it != m_inOutVars.end()) {
115 it->stageOutputFrom |= stage;
116 return;
117 }
118 InOutVar var { stage, {}, type, name, m_nextFreeOutLocation[int(stage)]++, true, flat };
119 m_inOutVars.insert(name, var);
120 }
121
122 void registerSampler(const QByteArray &type,
123 const QByteArray &name,
124 QSSGRenderShaderMetadata::Uniform::Condition conditionType = QSSGRenderShaderMetadata::Uniform::None,
125 const QByteArray &conditionName = QByteArray())
126 {
127 if (m_samplers.contains(name) || m_images.contains(name))
128 return;
129 Sampler var { type, name, conditionType, conditionName, m_nextFreeResourceBinding++ };
130 m_samplers.insert(name, var);
131 }
132
133 void registerImage(const QByteArray &type,
134 const QByteArray &name,
135 const QByteArray &imgtype,
136 const QByteArray &qualifiers,
137 QSSGRenderShaderMetadata::Uniform::Condition conditionType = QSSGRenderShaderMetadata::Uniform::None,
138 const QByteArray &conditionName = QByteArray())
139 {
140 if (m_samplers.contains(name) || m_images.contains(name))
141 return;
142 Image var { {type, name, conditionType, conditionName, m_nextFreeResourceBinding++}, imgtype, qualifiers};
143 m_images.insert(name, var);
144 }
145
146 void registerUniformMember(const QByteArray &type,
147 const QByteArray &name,
148 QSSGRenderShaderMetadata::Uniform::Condition conditionType = QSSGRenderShaderMetadata::Uniform::None,
149 const QByteArray &conditionName = QByteArray())
150 {
151 auto it = m_uniformMembers.constFind(name);
152 if (it != m_uniformMembers.constEnd()) {
153 if (it->conditionType != conditionType) {
154 qWarning("Encountered uniform %s with different conditions, this is not supported.",
155 name.constData());
156 }
157 return;
158 }
159 BlockMember var { type, name, conditionType, conditionName };
160 m_uniformMembers.insert(name, var);
161 }
162 static int s_additionalBuffers;
163 static void setAdditionalBufferAmount(int amount)
164 {
165 s_additionalBuffers = amount;
166 }
167};
168
169QT_END_NAMESPACE
170
171#endif