ShaderVars.h (12728B)
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 <cstdint> 16 #include <string> 17 #include <vector> 18 19 namespace sh 20 { 21 // GLenum alias 22 typedef unsigned int GLenum; 23 24 // Varying interpolation qualifier, see section 4.3.9 of the ESSL 3.00.4 spec 25 enum InterpolationType 26 { 27 INTERPOLATION_SMOOTH, 28 INTERPOLATION_CENTROID, 29 INTERPOLATION_SAMPLE, 30 INTERPOLATION_FLAT, 31 INTERPOLATION_NOPERSPECTIVE 32 }; 33 34 const char *InterpolationTypeToString(InterpolationType type); 35 36 // Validate link & SSO consistency of interpolation qualifiers 37 bool InterpolationTypesMatch(InterpolationType a, InterpolationType b); 38 39 // Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec 40 enum BlockLayoutType 41 { 42 BLOCKLAYOUT_STANDARD, 43 BLOCKLAYOUT_STD140 = BLOCKLAYOUT_STANDARD, 44 BLOCKLAYOUT_STD430, // Shader storage block layout qualifier 45 BLOCKLAYOUT_PACKED, 46 BLOCKLAYOUT_SHARED 47 }; 48 49 const char *BlockLayoutTypeToString(BlockLayoutType type); 50 51 // Interface Blocks, see section 4.3.9 of the ESSL 3.10 spec 52 enum class BlockType 53 { 54 BLOCK_UNIFORM, 55 BLOCK_BUFFER, 56 }; 57 58 const char *BlockTypeToString(BlockType type); 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 75 bool isArrayOfArrays() const { return arraySizes.size() >= 2u; } 76 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. 87 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 106 bool isStruct() const { return !fields.empty(); } 107 const std::string &getStructName() const { return structOrBlockName; } 108 void setStructName(const std::string &newName) { structOrBlockName = newName; } 109 110 // All of the shader's variables are described using nested data 111 // structures. This is needed in order to disambiguate similar looking 112 // types, such as two structs containing the same fields, but in 113 // different orders. "findInfoByMappedName" provides an easy query for 114 // users to dive into the data structure and fetch the unique variable 115 // instance corresponding to a dereferencing chain of the top-level 116 // variable. 117 // Given a mapped name like 'a[0].b.c[0]', return the ShaderVariable 118 // that defines 'c' in |leafVar|, and the original name 'A[0].B.C[0]' 119 // in |originalName|, based on the assumption that |this| defines 'a'. 120 // If no match is found, return false. 121 bool findInfoByMappedName(const std::string &mappedFullName, 122 const ShaderVariable **leafVar, 123 std::string *originalFullName) const; 124 125 // Find the child field which matches 'fullName' == var.name + "." + field.name. 126 // Return nullptr if not found. 127 const sh::ShaderVariable *findField(const std::string &fullName, uint32_t *fieldIndexOut) const; 128 129 bool isBuiltIn() const; 130 bool isEmulatedBuiltIn() const; 131 132 // Offset of this variable in parent arrays. In case the parent is an array of arrays, the 133 // offset is outerArrayElement * innerArraySize + innerArrayElement. 134 // For example, if there's a variable declared as size 3 array of size 4 array of int: 135 // int a[3][4]; 136 // then the flattenedOffsetInParentArrays of a[2] would be 2. 137 // and flattenedOffsetInParentArrays of a[2][1] would be 2*4 + 1 = 9. 138 int parentArrayIndex() const 139 { 140 return hasParentArrayIndex() ? flattenedOffsetInParentArrays : 0; 141 } 142 143 int getFlattenedOffsetInParentArrays() const { return flattenedOffsetInParentArrays; } 144 void setParentArrayIndex(int indexIn) { flattenedOffsetInParentArrays = indexIn; } 145 146 bool hasParentArrayIndex() const { return flattenedOffsetInParentArrays != -1; } 147 148 void resetEffectiveLocation(); 149 void updateEffectiveLocation(const sh::ShaderVariable &parent); 150 151 // Decide whether two uniforms are the same at shader link time, 152 // assuming they are from consecutive shader stages. 153 // GLSL ES Spec 3.00.3, section 4.3.5. 154 // GLSL ES Spec 3.10.4, section 4.4.5 155 bool isSameUniformAtLinkTime(const ShaderVariable &other) const; 156 157 // InterfaceBlockField 158 // Decide whether two InterfaceBlock fields are the same at shader 159 // link time, assuming they are from consecutive shader stages. 160 // See GLSL ES Spec 3.00.3, sec 4.3.7. 161 bool isSameInterfaceBlockFieldAtLinkTime(const ShaderVariable &other) const; 162 163 // Decide whether two varyings are the same at shader link time, 164 // assuming they are from consecutive shader stages. 165 // Invariance needs to match only in ESSL1. Relevant spec sections: 166 // GLSL ES 3.00.4, sections 4.6.1 and 4.3.9. 167 // GLSL ES 1.00.17, section 4.6.4. 168 bool isSameVaryingAtLinkTime(const ShaderVariable &other, int shaderVersion) const; 169 // Deprecated version of isSameVaryingAtLinkTime, which assumes ESSL1. 170 bool isSameVaryingAtLinkTime(const ShaderVariable &other) const; 171 172 // Shader I/O blocks may match by block name or instance, based on whether both stages have an 173 // instance name or not. 174 bool isSameNameAtLinkTime(const ShaderVariable &other) const; 175 176 // NOTE: When adding new members, the following functions also need to be updated: 177 // gl::WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var) 178 // gl::LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var) 179 180 GLenum type; 181 GLenum precision; 182 std::string name; 183 std::string mappedName; 184 185 // Used to make an array type. Outermost array size is stored at the end of the vector. 186 std::vector<unsigned int> arraySizes; 187 188 // Static use means that the variable is accessed somewhere in the shader source. 189 bool staticUse; 190 // A variable is active unless the compiler determined that it is not accessed by the shader. 191 // All active variables are statically used, but not all statically used variables are 192 // necessarily active. GLES 3.0.5 section 2.12.6. GLES 3.1 section 7.3.1. 193 bool active; 194 std::vector<ShaderVariable> fields; 195 // structOrBlockName is used for: 196 // - varyings of struct type, in which case it contains the struct name. 197 // - shader I/O blocks, in which case it contains the block name. 198 std::string structOrBlockName; 199 std::string mappedStructOrBlockName; 200 201 // Only applies to interface block fields. Kept here for simplicity. 202 bool isRowMajorLayout; 203 204 // VariableWithLocation 205 int location; 206 207 // The location of inputs or outputs without location layout quailifer will be updated to '-1'. 208 // GLES Spec 3.1, Section 7.3. PROGRAM OBJECTS 209 // Not all active variables are assigned valid locations; 210 // the following variables will have an effective location of -1: 211 bool hasImplicitLocation; 212 213 // Uniform 214 int binding; 215 GLenum imageUnitFormat; 216 int offset; 217 bool rasterOrdered; 218 bool readonly; 219 bool writeonly; 220 221 // From EXT_shader_framebuffer_fetch / KHR_blend_equation_advanced 222 bool isFragmentInOut; 223 224 // OutputVariable 225 // From EXT_blend_func_extended. 226 int index; 227 228 // From EXT_YUV_target 229 bool yuv; 230 231 // Varying 232 InterpolationType interpolation; 233 bool isInvariant; 234 bool isShaderIOBlock; 235 bool isPatch; 236 237 // If the variable is a sampler that has ever been statically used with texelFetch 238 bool texelFetchStaticUse; 239 240 protected: 241 bool isSameVariableAtLinkTime(const ShaderVariable &other, 242 bool matchPrecision, 243 bool matchName) const; 244 245 // NOTE: When adding new members, the following functions also need to be updated: 246 // gl::WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var) 247 // gl::LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var) 248 249 int flattenedOffsetInParentArrays; 250 }; 251 252 // TODO: anglebug.com/3899 253 // For backwards compatibility for other codebases (e.g., chromium/src/gpu/command_buffer/service) 254 using Uniform = ShaderVariable; 255 using Attribute = ShaderVariable; 256 using OutputVariable = ShaderVariable; 257 using InterfaceBlockField = ShaderVariable; 258 using Varying = ShaderVariable; 259 260 struct InterfaceBlock 261 { 262 InterfaceBlock(); 263 ~InterfaceBlock(); 264 InterfaceBlock(const InterfaceBlock &other); 265 InterfaceBlock &operator=(const InterfaceBlock &other); 266 267 // Fields from blocks with non-empty instance names are prefixed with the block name. 268 std::string fieldPrefix() const; 269 std::string fieldMappedPrefix() const; 270 271 // Decide whether two interface blocks are the same at shader link time. 272 bool isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const; 273 274 bool isBuiltIn() const; 275 276 bool isArray() const { return arraySize > 0; } 277 unsigned int elementCount() const { return std::max(1u, arraySize); } 278 279 std::string name; 280 std::string mappedName; 281 std::string instanceName; 282 unsigned int arraySize; 283 BlockLayoutType layout; 284 285 // Deprecated. Matrix packing should only be queried from individual fields of the block. 286 // TODO(oetuaho): Remove this once it is no longer used in Chromium. 287 bool isRowMajorLayout; 288 289 int binding; 290 bool staticUse; 291 bool active; 292 BlockType blockType; 293 std::vector<ShaderVariable> fields; 294 }; 295 296 struct WorkGroupSize 297 { 298 // Must have a trivial default constructor since it is used in YYSTYPE. 299 inline WorkGroupSize() = default; 300 inline explicit constexpr WorkGroupSize(int initialSize); 301 302 void fill(int fillValue); 303 void setLocalSize(int localSizeX, int localSizeY, int localSizeZ); 304 305 int &operator[](size_t index); 306 int operator[](size_t index) const; 307 size_t size() const; 308 309 // Checks whether two work group size declarations match. 310 // Two work group size declarations are the same if the explicitly specified elements are the 311 // same or if one of them is specified as one and the other one is not specified 312 bool isWorkGroupSizeMatching(const WorkGroupSize &right) const; 313 314 // Checks whether any of the values are set. 315 bool isAnyValueSet() const; 316 317 // Checks whether all of the values are set. 318 bool isDeclared() const; 319 320 // Checks whether either all of the values are set, or none of them are. 321 bool isLocalSizeValid() const; 322 323 int localSizeQualifiers[3]; 324 }; 325 326 inline constexpr WorkGroupSize::WorkGroupSize(int initialSize) 327 : localSizeQualifiers{initialSize, initialSize, initialSize} 328 {} 329 330 } // namespace sh 331 332 #endif // GLSLANG_SHADERVARS_H_