1// Copyright (C) 2014 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_OPENGL_SHADERPARAMETERPACK_P_H
5#define QT3DRENDER_RENDER_OPENGL_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 <QOpenGLShaderProgram>
21#include <Qt3DCore/qnodeid.h>
22#include <Qt3DRender/private/renderlogging_p.h>
23#include <Qt3DRender/private/uniform_p.h>
24#include <shadervariables_p.h>
25
26QT_BEGIN_NAMESPACE
27
28class QOpenGLShaderProgram;
29
30namespace Qt3DRender {
31namespace Render {
32namespace OpenGL {
33
34class GraphicsContext;
35
36struct BlockToUBO {
37 int m_blockIndex;
38 Qt3DCore::QNodeId m_bufferID;
39 bool m_needsUpdate;
40 QHash<QString, QVariant> m_updatedProperties;
41};
42QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, OpenGL, BlockToUBO, Q_RELOCATABLE_TYPE)
43
44struct BlockToSSBO {
45 int m_blockIndex;
46 int m_bindingIndex;
47 Qt3DCore::QNodeId m_bufferID;
48};
49QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, OpenGL, BlockToSSBO, Q_PRIMITIVE_TYPE)
50
51
52struct PackUniformHash
53{
54 std::vector<int> keys;
55 std::vector<UniformValue> values;
56
57 PackUniformHash()
58 {
59 }
60
61 void reserve(int count)
62 {
63 keys.reserve(n: count);
64 values.reserve(n: count);
65 }
66
67 size_t size() const
68 {
69 return keys.size();
70 }
71
72 inline int indexForKey(int key) const
73 {
74 const auto b = keys.cbegin();
75 const auto e = keys.cend();
76 const auto it = std::find(first: b, last: e, val: key);
77 if (it == e)
78 return -1;
79 return std::distance(first: b, last: it);
80 }
81
82 void insert(int key, const UniformValue &value)
83 {
84 const int idx = indexForKey(key);
85 if (idx != -1) {
86 values[idx] = value;
87 } else {
88 keys.push_back(x: key);
89 values.push_back(x: value);
90 }
91 }
92
93 void insert(int key, UniformValue &&value)
94 {
95 const int idx = indexForKey(key);
96 if (idx != -1) {
97 values[idx] = std::move(value);
98 } else {
99 keys.push_back(x: key);
100 values.push_back(x: std::move(value));
101 }
102 }
103
104 UniformValue value(int key) const noexcept
105 {
106 const int idx = indexForKey(key);
107 if (idx != -1)
108 return values.at(n: idx);
109 return UniformValue();
110 }
111
112 UniformValue& value(int key)
113 {
114 const int idx = indexForKey(key);
115 if (idx != -1)
116 return values[idx];
117 insert(key, value: UniformValue());
118 return value(key);
119 }
120
121 template<typename F>
122 void apply(int key, F func) const noexcept
123 {
124 const int idx = indexForKey(key);
125 if (idx != -1)
126 func(values[idx]);
127 }
128
129 void erase(int idx)
130 {
131 keys.erase(position: keys.begin() + idx);
132 values.erase(position: values.begin() + idx);
133 }
134
135 bool contains(int key) const noexcept
136 {
137 const auto b = keys.cbegin();
138 const auto e = keys.cend();
139 return std::find(first: b, last: e, val: key) != e;
140 }
141};
142
143class Q_AUTOTEST_EXPORT ShaderParameterPack
144{
145public:
146 ~ShaderParameterPack();
147
148 void reserve(int uniformCount);
149 void setUniform(const int glslNameId, const UniformValue &val);
150 void setTexture(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId id);
151 void setImage(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId id);
152
153 void setUniformBuffer(BlockToUBO blockToUBO);
154 void setShaderStorageBuffer(BlockToSSBO blockToSSBO);
155 void setSubmissionUniformIndex(const int shaderUniformIndex);
156
157 inline PackUniformHash &uniforms() { return m_uniforms; }
158 inline const PackUniformHash &uniforms() const { return m_uniforms; }
159 UniformValue uniform(const int glslNameId) const { return m_uniforms.value(key: glslNameId); }
160
161
162 struct NamedResource
163 {
164 enum Type {
165 Texture = 0,
166 Image
167 };
168
169 NamedResource() {}
170 NamedResource(const int glslNameId, Qt3DCore::QNodeId texId,
171 int uniformArrayIndex, Type type)
172 : glslNameId(glslNameId)
173 , nodeId(texId)
174 , uniformArrayIndex(uniformArrayIndex)
175 , type(type)
176 { }
177
178 int glslNameId;
179 Qt3DCore::QNodeId nodeId;
180 int uniformArrayIndex;
181 Type type;
182
183 bool operator==(const NamedResource &other) const
184 {
185 return glslNameId == other.glslNameId &&
186 nodeId == other.nodeId &&
187 uniformArrayIndex == other.uniformArrayIndex &&
188 type == other.type;
189 }
190
191 bool operator!=(const NamedResource &other) const
192 {
193 return !(*this == other);
194 }
195 };
196
197 inline const std::vector<NamedResource> &textures() const { return m_textures; }
198 inline const std::vector<NamedResource> &images() const { return m_images; }
199 inline const std::vector<BlockToUBO> &uniformBuffers() const { return m_uniformBuffers; }
200 inline const std::vector<BlockToSSBO> &shaderStorageBuffers() const { return m_shaderStorageBuffers; }
201 inline const std::vector<int> &submissionUniformIndices() const { return m_submissionUniformIndices; }
202private:
203 PackUniformHash m_uniforms;
204
205 std::vector<NamedResource> m_textures;
206 std::vector<NamedResource> m_images;
207 std::vector<BlockToUBO> m_uniformBuffers;
208 std::vector<BlockToSSBO> m_shaderStorageBuffers;
209 std::vector<int> m_submissionUniformIndices;
210
211 friend class RenderView;
212};
213QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, OpenGL, ShaderParameterPack::NamedResource, Q_PRIMITIVE_TYPE)
214
215} // namespace OpenGL
216} // namespace Render
217} // namespace Qt3DRender
218
219QT_END_NAMESPACE
220
221Q_DECLARE_METATYPE(Qt3DRender::Render::OpenGL::ShaderParameterPack)
222
223#endif // QT3DRENDER_RENDER_OPENGL_SHADERPARAMETERPACK_P_H
224

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