tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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_