1// Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB).
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QT3DRENDER_RENDER_RHI_SHADERPARAMETERPACK_P_H
5#define QT3DRENDER_RENDER_RHI_SHADERPARAMETERPACK_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists for the convenience
12// of other Qt classes. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QVariant>
19#include <QByteArray>
20#include <vector>
21#include <QOpenGLShaderProgram>
22#include <Qt3DCore/qnodeid.h>
23#include <Qt3DRender/private/renderlogging_p.h>
24#include <Qt3DRender/private/uniform_p.h>
25#include <shadervariables_p.h>
26
27QT_BEGIN_NAMESPACE
28
29class QOpenGLShaderProgram;
30
31namespace Qt3DRender {
32namespace Render {
33namespace Rhi {
34
35class GraphicsContext;
36
37struct BlockToUBO
38{
39 int m_blockIndex;
40 int m_bindingIndex;
41 Qt3DCore::QNodeId m_bufferID;
42 bool m_needsUpdate;
43 QHash<QString, QVariant> m_updatedProperties;
44};
45QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, Rhi, BlockToUBO, Q_RELOCATABLE_TYPE)
46
47struct BlockToSSBO
48{
49 int m_blockIndex;
50 int m_bindingIndex;
51 Qt3DCore::QNodeId m_bufferID;
52};
53QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, Rhi, BlockToSSBO, Q_PRIMITIVE_TYPE)
54
55struct ShaderDataForUBO
56{
57 int m_bindingIndex;
58 Qt3DCore::QNodeId m_shaderDataID;
59};
60QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, Rhi, ShaderDataForUBO, Q_PRIMITIVE_TYPE)
61
62bool operator==(const ShaderDataForUBO &a, const ShaderDataForUBO &b);
63
64struct PackUniformHash
65{
66 std::vector<int> keys;
67 std::vector<UniformValue> values;
68
69 PackUniformHash()
70 {
71 }
72
73 void reserve(int count)
74 {
75 keys.reserve(n: count);
76 values.reserve(n: count);
77 }
78
79 inline int indexForKey(int key) const
80 {
81 const auto b = keys.cbegin();
82 const auto e = keys.cend();
83 const auto it = std::find(first: b, last: e, val: key);
84 if (it == e)
85 return -1;
86 return std::distance(first: b, last: it);
87 }
88
89 void insert(int key, const UniformValue &value)
90 {
91 const int idx = indexForKey(key);
92 if (idx != -1) {
93 values[idx] = value;
94 } else {
95 keys.push_back(x: key);
96 values.push_back(x: value);
97 }
98 }
99
100 void insert(int key, UniformValue &&value)
101 {
102 const int idx = indexForKey(key);
103 if (idx != -1) {
104 values[idx] = std::move(value);
105 } else {
106 keys.push_back(x: key);
107 values.push_back(x: std::move(value));
108 }
109 }
110
111 const UniformValue &value(int key) const
112 {
113 const int idx = indexForKey(key);
114 return values[idx];
115 }
116
117 UniformValue &value(int key)
118 {
119 const int idx = indexForKey(key);
120 if (idx != -1)
121 return values[idx];
122 insert(key, value: UniformValue());
123 return value(key);
124 }
125
126 template<typename F>
127 void apply(int key, F func) const noexcept
128 {
129 const int idx = indexForKey(key);
130 if (idx != -1)
131 func(values[idx]);
132 }
133
134 void erase(int idx)
135 {
136 keys.erase(position: keys.begin() + idx);
137 values.erase(position: values.begin() + idx);
138 }
139
140 bool contains(int key) const noexcept
141 {
142 const auto b = keys.cbegin();
143 const auto e = keys.cend();
144 return std::find(first: b, last: e, val: key) != e;
145 }
146};
147
148class Q_AUTOTEST_EXPORT ShaderParameterPack
149{
150public:
151 ~ShaderParameterPack();
152
153 void reserve(int uniformCount);
154 void setUniform(const int glslNameId, const UniformValue &val);
155 void setTexture(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId id);
156 void setImage(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId id);
157
158 void setUniformBuffer(BlockToUBO blockToUBO);
159 void setShaderStorageBuffer(BlockToSSBO blockToSSBO);
160 void setShaderDataForUBO(ShaderDataForUBO shaderDataForUBO);
161 void setSubmissionUniformIndex(const int shaderUniformIndex);
162
163 inline PackUniformHash &uniforms() { return m_uniforms; }
164 inline const PackUniformHash &uniforms() const { return m_uniforms; }
165 UniformValue uniform(const int glslNameId) const { return m_uniforms.value(key: glslNameId); }
166
167
168 struct NamedResource
169 {
170 enum Type {
171 Texture = 0,
172 Image
173 };
174
175 NamedResource() {}
176 NamedResource(const int glslNameId, Qt3DCore::QNodeId texId,
177 int uniformArrayIndex, Type type)
178 : glslNameId(glslNameId)
179 , nodeId(texId)
180 , uniformArrayIndex(uniformArrayIndex)
181 , type(type)
182 { }
183
184 int glslNameId;
185 Qt3DCore::QNodeId nodeId;
186 int uniformArrayIndex;
187 Type type;
188
189 bool operator==(const NamedResource &other) const
190 {
191 return glslNameId == other.glslNameId &&
192 nodeId == other.nodeId &&
193 uniformArrayIndex == other.uniformArrayIndex &&
194 type == other.type;
195 }
196
197 bool operator!=(const NamedResource &other) const
198 {
199 return !(*this == other);
200 }
201 };
202
203 inline const std::vector<NamedResource> &textures() const { return m_textures; }
204 inline const std::vector<NamedResource> &images() const { return m_images; }
205 inline const std::vector<BlockToUBO> &uniformBuffers() const { return m_uniformBuffers; }
206 inline const std::vector<BlockToSSBO> &shaderStorageBuffers() const { return m_shaderStorageBuffers; }
207 inline const std::vector<int> &submissionUniformIndices() const { return m_submissionUniformIndices; }
208 inline const std::vector<ShaderDataForUBO> &shaderDatasForUBOs() const { return m_shaderDatasForUBOs; }
209private:
210 PackUniformHash m_uniforms;
211
212 std::vector<NamedResource> m_textures;
213 std::vector<NamedResource> m_images;
214 std::vector<BlockToUBO> m_uniformBuffers;
215 std::vector<BlockToSSBO> m_shaderStorageBuffers;
216 std::vector<int> m_submissionUniformIndices;
217 std::vector<ShaderDataForUBO> m_shaderDatasForUBOs;
218
219 friend class RenderView;
220};
221QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, Rhi, ShaderParameterPack::NamedResource, Q_PRIMITIVE_TYPE)
222
223} // namespace Rhi
224} // namespace Render
225} // namespace Qt3DRender
226
227QT_END_NAMESPACE
228
229Q_DECLARE_METATYPE(Qt3DRender::Render::Rhi::ShaderParameterPack)
230
231#endif // QT3DRENDER_RENDER_RHI_SHADERPARAMETERPACK_P_H
232

source code of qt3d/src/plugins/renderers/rhi/renderer/shaderparameterpack_p.h