• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2013 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 // ShaderVars.h:
7 //  Types to represent GL variables (varyings, uniforms, etc)
8 //
9 
10 #ifndef GLSLANG_SHADERVARS_H_
11 #define GLSLANG_SHADERVARS_H_
12 
13 #include <algorithm>
14 #include <array>
15 #include <string>
16 #include <vector>
17 
18 // This type is defined here to simplify ANGLE's integration with glslang for SPIRv.
19 using ShCompileOptions = uint64_t;
20 
21 namespace sh
22 {
23 // GLenum alias
24 typedef unsigned int GLenum;
25 
26 // Varying interpolation qualifier, see section 4.3.9 of the ESSL 3.00.4 spec
27 enum InterpolationType
28 {
29     INTERPOLATION_SMOOTH,
30     INTERPOLATION_CENTROID,
31     INTERPOLATION_FLAT,
32     INTERPOLATION_NOPERSPECTIVE
33 };
34 
35 // Validate link & SSO consistency of interpolation qualifiers
36 bool InterpolationTypesMatch(InterpolationType a, InterpolationType b);
37 
38 // Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec
39 enum BlockLayoutType
40 {
41     BLOCKLAYOUT_STANDARD,
42     BLOCKLAYOUT_STD140 = BLOCKLAYOUT_STANDARD,
43     BLOCKLAYOUT_STD430,  // Shader storage block layout qualifier
44     BLOCKLAYOUT_PACKED,
45     BLOCKLAYOUT_SHARED
46 };
47 
48 // Interface Blocks, see section 4.3.9 of the ESSL 3.10 spec
49 enum class BlockType
50 {
51     BLOCK_UNIFORM,
52     BLOCK_BUFFER,
53 
54     // Required in OpenGL ES 3.1 extension GL_OES_shader_io_blocks.
55     // TODO(jiawei.shao@intel.com): add BLOCK_OUT.
56     // Also used in GLSL
57     BLOCK_IN
58 };
59 
60 // Base class for all variables defined in shaders, including Varyings, Uniforms, etc
61 // Note: we must override the copy constructor and assignment operator so we can
62 // work around excessive GCC binary bloating:
63 // See https://code.google.com/p/angleproject/issues/detail?id=697
64 struct ShaderVariable
65 {
66     ShaderVariable();
67     ShaderVariable(GLenum typeIn);
68     ShaderVariable(GLenum typeIn, unsigned int arraySizeIn);
69     ~ShaderVariable();
70     ShaderVariable(const ShaderVariable &other);
71     ShaderVariable &operator=(const ShaderVariable &other);
72     bool operator==(const ShaderVariable &other) const;
73     bool operator!=(const ShaderVariable &other) const { return !operator==(other); }
74 
isArrayOfArraysShaderVariable75     bool isArrayOfArrays() const { return arraySizes.size() >= 2u; }
isArrayShaderVariable76     bool isArray() const { return !arraySizes.empty(); }
77     unsigned int getArraySizeProduct() const;
78     // Return the inner array size product.
79     // For example, if there's a variable declared as size 3 array of size 4 array of size 5 array
80     // of int:
81     //   int a[3][4][5];
82     // then getInnerArraySizeProduct of a would be 4*5.
83     unsigned int getInnerArraySizeProduct() const;
84 
85     // Array size 0 means not an array when passed to or returned from these functions.
86     // Note that setArraySize() is deprecated and should not be used inside ANGLE.
getOutermostArraySizeShaderVariable87     unsigned int getOutermostArraySize() const { return isArray() ? arraySizes.back() : 0; }
88     void setArraySize(unsigned int size);
89 
90     // Turn this ShaderVariable from an array into a specific element in that array. Will update
91     // flattenedOffsetInParentArrays.
92     void indexIntoArray(unsigned int arrayIndex);
93 
94     // Get the nth nested array size from the top. Caller is responsible for range checking
95     // arrayNestingIndex.
96     unsigned int getNestedArraySize(unsigned int arrayNestingIndex) const;
97 
98     // This function should only be used with variables that are of a basic type or an array of a
99     // basic type. Shader interface variables that are enumerated according to rules in GLES 3.1
100     // spec section 7.3.1.1 page 77 are fine. For those variables the return value should match the
101     // ARRAY_SIZE value that can be queried through the API.
102     unsigned int getBasicTypeElementCount() const;
103 
104     unsigned int getExternalSize() const;
105 
isStructShaderVariable106     bool isStruct() const { return !fields.empty(); }
107 
108     // All of the shader's variables are described using nested data
109     // structures. This is needed in order to disambiguate similar looking
110     // types, such as two structs containing the same fields, but in
111     // different orders. "findInfoByMappedName" provides an easy query for
112     // users to dive into the data structure and fetch the unique variable
113     // instance corresponding to a dereferencing chain of the top-level
114     // variable.
115     // Given a mapped name like 'a[0].b.c[0]', return the ShaderVariable
116     // that defines 'c' in |leafVar|, and the original name 'A[0].B.C[0]'
117     // in |originalName|, based on the assumption that |this| defines 'a'.
118     // If no match is found, return false.
119     bool findInfoByMappedName(const std::string &mappedFullName,
120                               const ShaderVariable **leafVar,
121                               std::string *originalFullName) const;
122 
123     // Find the child field which matches 'fullName' == var.name + "." + field.name.
124     // Return nullptr if not found.
125     const sh::ShaderVariable *findField(const std::string &fullName, uint32_t *fieldIndexOut) const;
126 
127     bool isBuiltIn() const;
128     bool isEmulatedBuiltIn() const;
129 
130     GLenum type;
131     GLenum precision;
132     std::string name;
133     std::string mappedName;
134 
135     // Used to make an array type. Outermost array size is stored at the end of the vector.
136     std::vector<unsigned int> arraySizes;
137 
138     // Offset of this variable in parent arrays. In case the parent is an array of arrays, the
139     // offset is outerArrayElement * innerArraySize + innerArrayElement.
140     // For example, if there's a variable declared as size 3 array of size 4 array of int:
141     //   int a[3][4];
142     // then the flattenedOffsetInParentArrays of a[2] would be 2.
143     // and flattenedOffsetInParentArrays of a[2][1] would be 2*4 + 1 = 9.
parentArrayIndexShaderVariable144     int parentArrayIndex() const
145     {
146         return hasParentArrayIndex() ? flattenedOffsetInParentArrays : 0;
147     }
148 
setParentArrayIndexShaderVariable149     void setParentArrayIndex(int indexIn) { flattenedOffsetInParentArrays = indexIn; }
150 
hasParentArrayIndexShaderVariable151     bool hasParentArrayIndex() const { return flattenedOffsetInParentArrays != -1; }
152 
153     // Static use means that the variable is accessed somewhere in the shader source.
154     bool staticUse;
155     // A variable is active unless the compiler determined that it is not accessed by the shader.
156     // All active variables are statically used, but not all statically used variables are
157     // necessarily active. GLES 3.0.5 section 2.12.6. GLES 3.1 section 7.3.1.
158     bool active;
159     std::vector<ShaderVariable> fields;
160     std::string structName;
161 
162     // Only applies to interface block fields. Kept here for simplicity.
163     bool isRowMajorLayout;
164 
165     // VariableWithLocation
166     int location;
167 
168     // Uniform
169     int binding;
170     // Decide whether two uniforms are the same at shader link time,
171     // assuming one from vertex shader and the other from fragment shader.
172     // GLSL ES Spec 3.00.3, section 4.3.5.
173     // GLSL ES Spec 3.10.4, section 4.4.5
174     bool isSameUniformAtLinkTime(const ShaderVariable &other) const;
175     GLenum imageUnitFormat;
176     int offset;
177     bool readonly;
178     bool writeonly;
179 
180     // OutputVariable
181     // From EXT_blend_func_extended.
182     int index;
183 
184     // InterfaceBlockField
185     // Decide whether two InterfaceBlock fields are the same at shader
186     // link time, assuming one from vertex shader and the other from
187     // fragment shader.
188     // See GLSL ES Spec 3.00.3, sec 4.3.7.
189     bool isSameInterfaceBlockFieldAtLinkTime(const ShaderVariable &other) const;
190 
191     // Varying
192     InterpolationType interpolation;
193     bool isInvariant;
194     // Decide whether two varyings are the same at shader link time,
195     // assuming one from vertex shader and the other from fragment shader.
196     // Invariance needs to match only in ESSL1. Relevant spec sections:
197     // GLSL ES 3.00.4, sections 4.6.1 and 4.3.9.
198     // GLSL ES 1.00.17, section 4.6.4.
199     bool isSameVaryingAtLinkTime(const ShaderVariable &other, int shaderVersion) const;
200     // Deprecated version of isSameVaryingAtLinkTime, which assumes ESSL1.
201     bool isSameVaryingAtLinkTime(const ShaderVariable &other) const;
202 
203   protected:
204     bool isSameVariableAtLinkTime(const ShaderVariable &other,
205                                   bool matchPrecision,
206                                   bool matchName) const;
207 
208     int flattenedOffsetInParentArrays;
209 };
210 
211 // TODO: anglebug.com/3899
212 // For backwards compatibility for other codebases (e.g., chromium/src/gpu/command_buffer/service)
213 using Uniform             = ShaderVariable;
214 using Attribute           = ShaderVariable;
215 using OutputVariable      = ShaderVariable;
216 using InterfaceBlockField = ShaderVariable;
217 using Varying             = ShaderVariable;
218 
219 struct InterfaceBlock
220 {
221     InterfaceBlock();
222     ~InterfaceBlock();
223     InterfaceBlock(const InterfaceBlock &other);
224     InterfaceBlock &operator=(const InterfaceBlock &other);
225 
226     // Fields from blocks with non-empty instance names are prefixed with the block name.
227     std::string fieldPrefix() const;
228     std::string fieldMappedPrefix() const;
229 
230     // Decide whether two interface blocks are the same at shader link time.
231     bool isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const;
232 
233     bool isBuiltIn() const;
234 
isArrayInterfaceBlock235     bool isArray() const { return arraySize > 0; }
elementCountInterfaceBlock236     unsigned int elementCount() const { return std::max(1u, arraySize); }
237 
238     std::string name;
239     std::string mappedName;
240     std::string instanceName;
241     unsigned int arraySize;
242     BlockLayoutType layout;
243 
244     // Deprecated. Matrix packing should only be queried from individual fields of the block.
245     // TODO(oetuaho): Remove this once it is no longer used in Chromium.
246     bool isRowMajorLayout;
247 
248     int binding;
249     bool staticUse;
250     bool active;
251     BlockType blockType;
252     std::vector<ShaderVariable> fields;
253 };
254 
255 struct WorkGroupSize
256 {
257     // Must have a trivial default constructor since it is used in YYSTYPE.
258     inline WorkGroupSize() = default;
259     inline explicit constexpr WorkGroupSize(int initialSize);
260 
261     void fill(int fillValue);
262     void setLocalSize(int localSizeX, int localSizeY, int localSizeZ);
263 
264     int &operator[](size_t index);
265     int operator[](size_t index) const;
266     size_t size() const;
267 
268     // Checks whether two work group size declarations match.
269     // Two work group size declarations are the same if the explicitly specified elements are the
270     // same or if one of them is specified as one and the other one is not specified
271     bool isWorkGroupSizeMatching(const WorkGroupSize &right) const;
272 
273     // Checks whether any of the values are set.
274     bool isAnyValueSet() const;
275 
276     // Checks whether all of the values are set.
277     bool isDeclared() const;
278 
279     // Checks whether either all of the values are set, or none of them are.
280     bool isLocalSizeValid() const;
281 
282     int localSizeQualifiers[3];
283 };
284 
WorkGroupSize(int initialSize)285 inline constexpr WorkGroupSize::WorkGroupSize(int initialSize)
286     : localSizeQualifiers{initialSize, initialSize, initialSize}
287 {}
288 
289 }  // namespace sh
290 
291 #endif  // GLSLANG_SHADERVARS_H_
292