1 //
2 // Copyright 2010 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #ifndef LIBANGLE_UNIFORM_H_
8 #define LIBANGLE_UNIFORM_H_
9
10 #include <string>
11 #include <vector>
12
13 #include "angle_gl.h"
14 #include "common/MemoryBuffer.h"
15 #include "common/debug.h"
16 #include "common/uniform_type_info_autogen.h"
17 #include "common/utilities.h"
18 #include "compiler/translator/blocklayout.h"
19 #include "libANGLE/angletypes.h"
20
21 namespace gl
22 {
23 class BinaryInputStream;
24 class BinaryOutputStream;
25 struct UniformTypeInfo;
26 struct UsedUniform;
27 struct LinkedUniform;
28
29 #define ACTIVE_VARIABLE_COMMON_INTERFACES \
30 void setActive(ShaderType shaderType, bool used, uint32_t id) \
31 { \
32 ASSERT(shaderType != ShaderType::InvalidEnum); \
33 pod.activeUseBits.set(shaderType, used); \
34 pod.ids[shaderType] = id; \
35 } \
36 ShaderType getFirstActiveShaderType() const \
37 { \
38 return pod.activeUseBits.first(); \
39 } \
40 bool isActive(ShaderType shaderType) const \
41 { \
42 return pod.activeUseBits[shaderType]; \
43 } \
44 const ShaderMap<uint32_t> &getIds() const \
45 { \
46 return pod.ids; \
47 } \
48 uint32_t getId(ShaderType shaderType) const \
49 { \
50 return pod.ids[shaderType]; \
51 } \
52 ShaderBitSet activeShaders() const \
53 { \
54 return pod.activeUseBits; \
55 } \
56 uint32_t activeShaderCount() const \
57 { \
58 return static_cast<uint32_t>(pod.activeUseBits.count()); \
59 }
60
61 struct ActiveVariable
62 {
ActiveVariableActiveVariable63 ActiveVariable() { memset(&pod, 0, sizeof(pod)); }
64
65 ACTIVE_VARIABLE_COMMON_INTERFACES
66
67 struct PODStruct
68 {
69 ShaderBitSet activeUseBits;
70 // The id of a linked variable in each shader stage. This id originates from
71 // sh::ShaderVariable::id or sh::InterfaceBlock::id
72 ShaderMap<uint32_t> ids;
73 } pod;
74 };
75
GetUniformTypeInfoFromIndex(UniformTypeIndex index)76 inline const UniformTypeInfo &GetUniformTypeInfoFromIndex(UniformTypeIndex index)
77 {
78 ASSERT(index.value >= 0 && index.value < kUniformInfoTable.size());
79 return kUniformInfoTable[index.value];
80 }
81
82 // Important: This struct must have basic data types only, so that we can initialize with memcpy. Do
83 // not put any std::vector or objects with virtual functions in it.
84 // Helper struct representing a single shader uniform. Most of this structure's data member and
85 // access functions mirrors ShaderVariable; See ShaderVars.h for more info.
86 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
87 struct LinkedUniform
88 {
89 LinkedUniform() = default;
90 LinkedUniform(GLenum typeIn,
91 GLenum precisionIn,
92 const std::vector<unsigned int> &arraySizesIn,
93 const int bindingIn,
94 const int offsetIn,
95 const int locationIn,
96 const int bufferIndexIn,
97 const sh::BlockMemberInfo &blockInfoIn);
98 LinkedUniform(const UsedUniform &usedUniform);
99
getUniformTypeInfoLinkedUniform100 const UniformTypeInfo &getUniformTypeInfo() const
101 {
102 return GetUniformTypeInfoFromIndex(pod.typeIndex);
103 }
104
isSamplerLinkedUniform105 bool isSampler() const { return getUniformTypeInfo().isSampler; }
isImageLinkedUniform106 bool isImage() const { return getUniformTypeInfo().isImageType; }
isAtomicCounterLinkedUniform107 bool isAtomicCounter() const { return IsAtomicCounterType(getType()); }
isInDefaultBlockLinkedUniform108 bool isInDefaultBlock() const { return pod.bufferIndex == -1; }
getElementSizeLinkedUniform109 size_t getElementSize() const { return getUniformTypeInfo().externalSize; }
getElementComponentsLinkedUniform110 GLint getElementComponents() const { return GetUniformElementComponents(pod.typeIndex); }
111
isTexelFetchStaticUseLinkedUniform112 bool isTexelFetchStaticUse() const { return pod.flagBits.texelFetchStaticUse; }
isFragmentInOutLinkedUniform113 bool isFragmentInOut() const { return pod.flagBits.isFragmentInOut; }
114
isArrayLinkedUniform115 bool isArray() const { return pod.flagBits.isArray; }
getBasicTypeElementCountLinkedUniform116 uint16_t getBasicTypeElementCount() const
117 {
118 ASSERT(pod.flagBits.isArray || pod.arraySize == 1u);
119 return pod.arraySize;
120 }
121
getTypeLinkedUniform122 GLenum getType() const { return getUniformTypeInfo().type; }
getOuterArrayOffsetLinkedUniform123 uint16_t getOuterArrayOffset() const { return pod.outerArrayOffset; }
getOuterArraySizeProductLinkedUniform124 uint16_t getOuterArraySizeProduct() const { return pod.outerArraySizeProduct; }
getBindingLinkedUniform125 int16_t getBinding() const { return pod.binding; }
getOffsetLinkedUniform126 int16_t getOffset() const { return pod.offset; }
getBufferIndexLinkedUniform127 int getBufferIndex() const { return pod.bufferIndex; }
getLocationLinkedUniform128 int getLocation() const { return pod.location; }
getImageUnitFormatLinkedUniform129 GLenum getImageUnitFormat() const { return pod.imageUnitFormat; }
130
131 ACTIVE_VARIABLE_COMMON_INTERFACES
132
133 struct PODStruct
134 {
135 UniformTypeIndex typeIndex;
136 uint16_t precision;
137
138 int32_t location;
139
140 // These are from sh::struct BlockMemberInfo struct. See locklayout.h for detail.
141 uint16_t blockOffset;
142 uint16_t blockArrayStride;
143
144 uint16_t blockMatrixStride;
145 uint16_t imageUnitFormat;
146
147 // maxUniformVectorsCount is 4K due to we clamp maxUniformBlockSize to 64KB. All of these
148 // variable should be enough to pack into 16 bits to reduce the size of mUniforms.
149 int16_t binding;
150 int16_t bufferIndex;
151
152 int16_t offset;
153 uint16_t arraySize;
154
155 uint16_t outerArraySizeProduct;
156 uint16_t outerArrayOffset;
157
158 uint16_t parentArrayIndex;
159 union
160 {
161 struct
162 {
163 uint8_t isFragmentInOut : 1;
164 uint8_t texelFetchStaticUse : 1;
165 uint8_t isArray : 1;
166 uint8_t blockIsRowMajorMatrix : 1;
167 uint8_t isBlock : 1;
168 uint8_t padding : 3;
169 } flagBits;
170 uint8_t flagBitsAsUByte;
171 };
172 ShaderBitSet activeUseBits;
173
174 uint32_t id;
175 // The id of a linked variable in each shader stage. This id originates from
176 // sh::ShaderVariable::id or sh::InterfaceBlock::id
177 ShaderMap<uint32_t> ids;
178 } pod;
179 };
180 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
181
182 struct BufferVariable
183 {
184 BufferVariable();
185 BufferVariable(GLenum type,
186 GLenum precision,
187 const std::string &name,
188 const std::vector<unsigned int> &arraySizes,
189 const int bufferIndex,
190 int topLevelArraySize,
191 const sh::BlockMemberInfo &blockInfo);
~BufferVariableBufferVariable192 ~BufferVariable() {}
193
isArrayBufferVariable194 bool isArray() const { return pod.isArray; }
getBasicTypeElementCountBufferVariable195 uint32_t getBasicTypeElementCount() const { return pod.basicTypeElementCount; }
196
197 ACTIVE_VARIABLE_COMMON_INTERFACES
198
199 std::string name;
200 std::string mappedName;
201
202 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
203 struct PODStruct
204 {
205 uint16_t type;
206 uint16_t precision;
207
208 // 1 byte each
209 ShaderBitSet activeUseBits;
210 bool isArray;
211
212 int16_t bufferIndex;
213
214 // The id of a linked variable in each shader stage. This id originates from
215 // sh::ShaderVariable::id or sh::InterfaceBlock::id
216 ShaderMap<uint32_t> ids;
217
218 sh::BlockMemberInfo blockInfo;
219
220 int32_t topLevelArraySize;
221 uint32_t basicTypeElementCount;
222 } pod;
223 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
224 };
225
226 // Represents a single atomic counter buffer
227 struct AtomicCounterBuffer
228 {
229 AtomicCounterBuffer();
~AtomicCounterBufferAtomicCounterBuffer230 ~AtomicCounterBuffer() {}
231
232 ACTIVE_VARIABLE_COMMON_INTERFACES
numActiveVariablesAtomicCounterBuffer233 int numActiveVariables() const { return static_cast<int>(memberIndexes.size()); }
234 void unionReferencesWith(const LinkedUniform &otherUniform);
235
236 std::vector<unsigned int> memberIndexes;
237
238 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
239 struct PODStruct
240 {
241 // The id of a linked variable in each shader stage. This id originates from
242 // sh::ShaderVariable::id or sh::InterfaceBlock::id
243 ShaderMap<uint32_t> ids;
244 // The binding as specified by the shader.
245 int inShaderBinding;
246 unsigned int dataSize;
247 ShaderBitSet activeUseBits;
248 uint8_t pads[3];
249 } pod;
250 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
251 };
252
253 // Helper struct representing a single shader interface block
254 struct InterfaceBlock
255 {
256 InterfaceBlock();
257 InterfaceBlock(const std::string &nameIn,
258 const std::string &mappedNameIn,
259 bool isArrayIn,
260 bool isReadOnlyIn,
261 unsigned int arrayElementIn,
262 unsigned int firstFieldArraySizeIn,
263 int bindingIn);
264
265 std::string nameWithArrayIndex() const;
266 std::string mappedNameWithArrayIndex() const;
267
268 ACTIVE_VARIABLE_COMMON_INTERFACES
269
numActiveVariablesInterfaceBlock270 int numActiveVariables() const { return static_cast<int>(memberIndexes.size()); }
271
272 std::string name;
273 std::string mappedName;
274 std::vector<unsigned int> memberIndexes;
275
276 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
277 struct PODStruct
278 {
279 uint32_t arrayElement;
280 uint32_t firstFieldArraySize;
281
282 ShaderBitSet activeUseBits;
283 uint8_t isArray : 1;
284 // Only valid for SSBOs, specifies whether it has the readonly qualifier.
285 uint8_t isReadOnly : 1;
286 uint8_t padings : 6;
287 // The binding as specified by the shader (0 if unspecified, per spec)
288 int16_t inShaderBinding;
289
290 unsigned int dataSize;
291 // The id of a linked variable in each shader stage. This id originates from
292 // sh::ShaderVariable::id or sh::InterfaceBlock::id
293 ShaderMap<uint32_t> ids;
294 } pod;
295 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
296 };
297
298 #undef ACTIVE_VARIABLE_COMMON_INTERFACES
299 } // namespace gl
300
301 #endif // LIBANGLE_UNIFORM_H_
302