• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/utilities.h"
17 #include "compiler/translator/blocklayout.h"
18 #include "libANGLE/angletypes.h"
19 
20 namespace gl
21 {
22 class BinaryInputStream;
23 class BinaryOutputStream;
24 struct UniformTypeInfo;
25 struct UsedUniform;
26 
27 // Note: keep this struct memcpy-able: i.e, a simple struct with basic types only and no virtual
28 // functions. LinkedUniform relies on this so that it can use memcpy to initialize uniform for
29 // performance.
30 struct ActiveVariable
31 {
32     ActiveVariable();
33     ActiveVariable(const ActiveVariable &rhs);
34     ~ActiveVariable();
35 
36     ActiveVariable &operator=(const ActiveVariable &rhs);
37 
getFirstActiveShaderTypeActiveVariable38     ShaderType getFirstActiveShaderType() const
39     {
40         return static_cast<ShaderType>(ScanForward(mActiveUseBits.bits()));
41     }
42     void setActive(ShaderType shaderType, bool used, uint32_t id);
43     void unionReferencesWith(const ActiveVariable &other);
isActiveActiveVariable44     bool isActive(ShaderType shaderType) const
45     {
46         ASSERT(shaderType != ShaderType::InvalidEnum);
47         return mActiveUseBits[shaderType];
48     }
getIdsActiveVariable49     const ShaderMap<uint32_t> &getIds() const { return mIds; }
getIdActiveVariable50     uint32_t getId(ShaderType shaderType) const { return mIds[shaderType]; }
activeShadersActiveVariable51     ShaderBitSet activeShaders() const { return mActiveUseBits; }
activeShaderCountActiveVariable52     GLuint activeShaderCount() const { return static_cast<GLuint>(mActiveUseBits.count()); }
53 
54   private:
55     ShaderBitSet mActiveUseBits;
56     // The id of a linked variable in each shader stage.  This id originates from
57     // sh::ShaderVariable::id or sh::InterfaceBlock::id
58     ShaderMap<uint32_t> mIds;
59 };
60 
61 // Helper struct representing a single shader uniform. Most of this structure's data member and
62 // access functions mirrors ShaderVariable; See ShaderVars.h for more info.
63 struct LinkedUniform
64 {
65     LinkedUniform();
66     LinkedUniform(GLenum typeIn,
67                   GLenum precisionIn,
68                   const std::string &nameIn,
69                   const std::vector<unsigned int> &arraySizesIn,
70                   const int bindingIn,
71                   const int offsetIn,
72                   const int locationIn,
73                   const int bufferIndexIn,
74                   const sh::BlockMemberInfo &blockInfoIn);
75     LinkedUniform(const LinkedUniform &other);
76     LinkedUniform(const UsedUniform &usedUniform);
77     LinkedUniform &operator=(const LinkedUniform &other);
78     ~LinkedUniform();
79 
setBlockInfoLinkedUniform80     void setBlockInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
81     {
82         mFixedSizeData.blockInfo.offset           = offset;
83         mFixedSizeData.blockInfo.arrayStride      = arrayStride;
84         mFixedSizeData.blockInfo.matrixStride     = matrixStride;
85         mFixedSizeData.blockInfo.isRowMajorMatrix = isRowMajorMatrix;
86     }
setBufferIndexLinkedUniform87     void setBufferIndex(int bufferIndex) { mFixedSizeData.bufferIndex = bufferIndex; }
88 
isSamplerLinkedUniform89     bool isSampler() const { return typeInfo->isSampler; }
isImageLinkedUniform90     bool isImage() const { return typeInfo->isImageType; }
isAtomicCounterLinkedUniform91     bool isAtomicCounter() const { return IsAtomicCounterType(mFixedSizeData.type); }
isInDefaultBlockLinkedUniform92     bool isInDefaultBlock() const { return mFixedSizeData.bufferIndex == -1; }
getElementSizeLinkedUniform93     size_t getElementSize() const { return typeInfo->externalSize; }
getElementComponentsLinkedUniform94     size_t getElementComponents() const { return typeInfo->componentCount; }
95 
isStructLinkedUniform96     bool isStruct() const { return mFixedSizeData.flagBits.isStruct; }
isTexelFetchStaticUseLinkedUniform97     bool isTexelFetchStaticUse() const { return mFixedSizeData.flagBits.texelFetchStaticUse; }
isFragmentInOutLinkedUniform98     bool isFragmentInOut() const { return mFixedSizeData.flagBits.isFragmentInOut; }
99 
isArrayOfArraysLinkedUniform100     bool isArrayOfArrays() const { return arraySizes.size() >= 2u; }
isArrayLinkedUniform101     bool isArray() const { return !arraySizes.empty(); }
getArraySizeProductLinkedUniform102     unsigned int getArraySizeProduct() const { return gl::ArraySizeProduct(arraySizes); }
getOutermostArraySizeLinkedUniform103     unsigned int getOutermostArraySize() const { return isArray() ? arraySizes.back() : 0; }
getBasicTypeElementCountLinkedUniform104     unsigned int getBasicTypeElementCount() const
105     {
106         ASSERT(!isArrayOfArrays());
107         ASSERT(!isStruct() || !isArray());
108 
109         if (isArray())
110         {
111             return getOutermostArraySize();
112         }
113         return 1u;
114     }
115 
getTypeLinkedUniform116     GLenum getType() const { return mFixedSizeData.type; }
117     unsigned int getExternalSize() const;
getOuterArrayOffsetLinkedUniform118     unsigned int getOuterArrayOffset() const { return mFixedSizeData.outerArrayOffset; }
getOuterArraySizeProductLinkedUniform119     unsigned int getOuterArraySizeProduct() const { return mFixedSizeData.outerArraySizeProduct; }
getBindingLinkedUniform120     int getBinding() const { return mFixedSizeData.binding; }
getOffsetLinkedUniform121     int getOffset() const { return mFixedSizeData.offset; }
getBlockInfoLinkedUniform122     const sh::BlockMemberInfo &getBlockInfo() const { return mFixedSizeData.blockInfo; }
getBufferIndexLinkedUniform123     int getBufferIndex() const { return mFixedSizeData.bufferIndex; }
getLocationLinkedUniform124     int getLocation() const { return mFixedSizeData.location; }
getImageUnitFormatLinkedUniform125     GLenum getImageUnitFormat() const { return mFixedSizeData.imageUnitFormat; }
126 
127     bool findInfoByMappedName(const std::string &mappedFullName,
128                               const sh::ShaderVariable **leafVar,
129                               std::string *originalFullName) const;
isBuiltInLinkedUniform130     bool isBuiltIn() const { return gl::IsBuiltInName(name); }
131 
parentArrayIndexLinkedUniform132     int parentArrayIndex() const
133     {
134         return hasParentArrayIndex() ? mFixedSizeData.flattenedOffsetInParentArrays : 0;
135     }
136 
hasParentArrayIndexLinkedUniform137     bool hasParentArrayIndex() const { return mFixedSizeData.flattenedOffsetInParentArrays != -1; }
138     bool isSameInterfaceBlockFieldAtLinkTime(const sh::ShaderVariable &other) const;
139 
140     bool isSameVariableAtLinkTime(const sh::ShaderVariable &other,
141                                   bool matchPrecision,
142                                   bool matchName) const;
143 
getFirstActiveShaderTypeLinkedUniform144     ShaderType getFirstActiveShaderType() const
145     {
146         return mFixedSizeData.activeVariable.getFirstActiveShaderType();
147     }
setActiveLinkedUniform148     void setActive(ShaderType shaderType, bool used, uint32_t _id)
149     {
150         mFixedSizeData.activeVariable.setActive(shaderType, used, _id);
151     }
isActiveLinkedUniform152     bool isActive(ShaderType shaderType) const
153     {
154         return mFixedSizeData.activeVariable.isActive(shaderType);
155     }
getIdsLinkedUniform156     const ShaderMap<uint32_t> &getIds() const { return mFixedSizeData.activeVariable.getIds(); }
getIdLinkedUniform157     uint32_t getId(ShaderType shaderType) const
158     {
159         return mFixedSizeData.activeVariable.getId(shaderType);
160     }
activeShadersLinkedUniform161     ShaderBitSet activeShaders() const { return mFixedSizeData.activeVariable.activeShaders(); }
activeShaderCountLinkedUniform162     GLuint activeShaderCount() const { return mFixedSizeData.activeVariable.activeShaderCount(); }
getActiveVariableLinkedUniform163     const ActiveVariable &getActiveVariable() const { return mFixedSizeData.activeVariable; }
164 
165     void save(BinaryOutputStream *stream) const;
166     void load(BinaryInputStream *stream);
167 
168     std::string name;
169     // Only used by GL backend
170     std::string mappedName;
171 
172     std::vector<unsigned int> arraySizes;
173 
174     const UniformTypeInfo *typeInfo;
175 
176   private:
177     // Important: The fixed size data structure with fundamental data types only, so that we can
178     // initialize with memcpy. Do not put any std::vector or objects with virtual functions in it.
179     struct
180     {
181         GLenum type;
182         GLenum precision;
183         int location;
184         int binding;
185         GLenum imageUnitFormat;
186         int offset;
187         uint32_t id;
188         int flattenedOffsetInParentArrays;
189         int bufferIndex;
190         sh::BlockMemberInfo blockInfo;
191         unsigned int outerArraySizeProduct;
192         unsigned int outerArrayOffset;
193         ActiveVariable activeVariable;
194 
195         union
196         {
197             struct
198             {
199                 uint32_t staticUse : 1;
200                 uint32_t active : 1;
201                 uint32_t isStruct : 1;
202                 uint32_t rasterOrdered : 1;
203                 uint32_t readonly : 1;
204                 uint32_t writeonly : 1;
205                 uint32_t isFragmentInOut : 1;
206                 uint32_t texelFetchStaticUse : 1;
207                 uint32_t padding : 24;
208             } flagBits;
209 
210             uint32_t flagBitsAsUInt;
211         };
212     } mFixedSizeData;
213 };
214 
215 struct BufferVariable : public sh::ShaderVariable
216 {
217     BufferVariable();
218     BufferVariable(GLenum type,
219                    GLenum precision,
220                    const std::string &name,
221                    const std::vector<unsigned int> &arraySizes,
222                    const int bufferIndex,
223                    const sh::BlockMemberInfo &blockInfo);
224     ~BufferVariable();
225 
setActiveBufferVariable226     void setActive(ShaderType shaderType, bool used, uint32_t _id)
227     {
228         activeVariable.setActive(shaderType, used, _id);
229     }
isActiveBufferVariable230     bool isActive(ShaderType shaderType) const { return activeVariable.isActive(shaderType); }
getIdBufferVariable231     uint32_t getId(ShaderType shaderType) const { return activeVariable.getId(shaderType); }
activeShadersBufferVariable232     ShaderBitSet activeShaders() const { return activeVariable.activeShaders(); }
233 
234     ActiveVariable activeVariable;
235     int bufferIndex;
236     sh::BlockMemberInfo blockInfo;
237 
238     int topLevelArraySize;
239 };
240 
241 // Parent struct for atomic counter, uniform block, and shader storage block buffer, which all
242 // contain a group of shader variables, and have a GL buffer backed.
243 struct ShaderVariableBuffer
244 {
245     ShaderVariableBuffer();
246     ShaderVariableBuffer(const ShaderVariableBuffer &other);
247     ~ShaderVariableBuffer();
248 
getFirstActiveShaderTypeShaderVariableBuffer249     ShaderType getFirstActiveShaderType() const
250     {
251         return activeVariable.getFirstActiveShaderType();
252     }
setActiveShaderVariableBuffer253     void setActive(ShaderType shaderType, bool used, uint32_t _id)
254     {
255         activeVariable.setActive(shaderType, used, _id);
256     }
unionReferencesWithShaderVariableBuffer257     void unionReferencesWith(const ActiveVariable &other)
258     {
259         activeVariable.unionReferencesWith(other);
260     }
isActiveShaderVariableBuffer261     bool isActive(ShaderType shaderType) const { return activeVariable.isActive(shaderType); }
getIdsShaderVariableBuffer262     const ShaderMap<uint32_t> &getIds() const { return activeVariable.getIds(); }
getIdShaderVariableBuffer263     uint32_t getId(ShaderType shaderType) const { return activeVariable.getId(shaderType); }
activeShadersShaderVariableBuffer264     ShaderBitSet activeShaders() const { return activeVariable.activeShaders(); }
265     int numActiveVariables() const;
266 
267     ActiveVariable activeVariable;
268     int binding;
269     unsigned int dataSize;
270     std::vector<unsigned int> memberIndexes;
271 };
272 
273 using AtomicCounterBuffer = ShaderVariableBuffer;
274 
275 // Helper struct representing a single shader interface block
276 struct InterfaceBlock : public ShaderVariableBuffer
277 {
278     InterfaceBlock();
279     InterfaceBlock(const std::string &nameIn,
280                    const std::string &mappedNameIn,
281                    bool isArrayIn,
282                    bool isReadOnlyIn,
283                    unsigned int arrayElementIn,
284                    unsigned int firstFieldArraySizeIn,
285                    int bindingIn);
286     InterfaceBlock(const InterfaceBlock &other);
287 
288     std::string nameWithArrayIndex() const;
289     std::string mappedNameWithArrayIndex() const;
290 
291     std::string name;
292     std::string mappedName;
293     bool isArray;
294     // Only valid for SSBOs, specifies whether it has the readonly qualifier.
295     bool isReadOnly;
296     unsigned int arrayElement;
297     unsigned int firstFieldArraySize;
298 };
299 
300 }  // namespace gl
301 
302 #endif  // LIBANGLE_UNIFORM_H_
303