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