Coverage Report

Created: 2018-09-25 14:53

/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_