Edit

kc3-lang/angle/include/GLSLANG/ShaderVars.h

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2021-08-16 07:59:18
    Hash : 49af677a
    Message : Capture/Replay: Update serialization logic. - Uses more common toString methods instead of custom ones. - Uses enum to string in more places intsead of numeric enums. - Adds missing group scopes in several places. - Skips serializing empty image levels. Bug: angleproject:5133 Change-Id: I2c9523981aba4ec0afb5f0623cb34154db263e6b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3097805 Reviewed-by: Gert Wollny <gert.wollny@collabora.com> Reviewed-by: Cody Northrop <cnorthrop@google.com> Reviewed-by: Tim Van Patten <timvp@google.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>

  • include/GLSLANG/ShaderVars.h
  • //
    // Copyright 2013 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    // ShaderVars.h:
    //  Types to represent GL variables (varyings, uniforms, etc)
    //
    
    #ifndef GLSLANG_SHADERVARS_H_
    #define GLSLANG_SHADERVARS_H_
    
    #include <algorithm>
    #include <array>
    #include <string>
    #include <vector>
    
    // This type is defined here to simplify ANGLE's integration with glslang for SPIRv.
    using ShCompileOptions = uint64_t;
    
    namespace sh
    {
    // GLenum alias
    typedef unsigned int GLenum;
    
    // Varying interpolation qualifier, see section 4.3.9 of the ESSL 3.00.4 spec
    enum InterpolationType
    {
        INTERPOLATION_SMOOTH,
        INTERPOLATION_CENTROID,
        INTERPOLATION_SAMPLE,
        INTERPOLATION_FLAT,
        INTERPOLATION_NOPERSPECTIVE
    };
    
    const char *InterpolationTypeToString(InterpolationType type);
    
    // Validate link & SSO consistency of interpolation qualifiers
    bool InterpolationTypesMatch(InterpolationType a, InterpolationType b);
    
    // Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec
    enum BlockLayoutType
    {
        BLOCKLAYOUT_STANDARD,
        BLOCKLAYOUT_STD140 = BLOCKLAYOUT_STANDARD,
        BLOCKLAYOUT_STD430,  // Shader storage block layout qualifier
        BLOCKLAYOUT_PACKED,
        BLOCKLAYOUT_SHARED
    };
    
    const char *BlockLayoutTypeToString(BlockLayoutType type);
    
    // Interface Blocks, see section 4.3.9 of the ESSL 3.10 spec
    enum class BlockType
    {
        BLOCK_UNIFORM,
        BLOCK_BUFFER,
    };
    
    const char *BlockTypeToString(BlockType type);
    
    // Base class for all variables defined in shaders, including Varyings, Uniforms, etc
    // Note: we must override the copy constructor and assignment operator so we can
    // work around excessive GCC binary bloating:
    // See https://code.google.com/p/angleproject/issues/detail?id=697
    struct ShaderVariable
    {
        ShaderVariable();
        ShaderVariable(GLenum typeIn);
        ShaderVariable(GLenum typeIn, unsigned int arraySizeIn);
        ~ShaderVariable();
        ShaderVariable(const ShaderVariable &other);
        ShaderVariable &operator=(const ShaderVariable &other);
        bool operator==(const ShaderVariable &other) const;
        bool operator!=(const ShaderVariable &other) const { return !operator==(other); }
    
        bool isArrayOfArrays() const { return arraySizes.size() >= 2u; }
        bool isArray() const { return !arraySizes.empty(); }
        unsigned int getArraySizeProduct() const;
        // Return the inner array size product.
        // For example, if there's a variable declared as size 3 array of size 4 array of size 5 array
        // of int:
        //   int a[3][4][5];
        // then getInnerArraySizeProduct of a would be 4*5.
        unsigned int getInnerArraySizeProduct() const;
    
        // Array size 0 means not an array when passed to or returned from these functions.
        // Note that setArraySize() is deprecated and should not be used inside ANGLE.
        unsigned int getOutermostArraySize() const { return isArray() ? arraySizes.back() : 0; }
        void setArraySize(unsigned int size);
    
        // Turn this ShaderVariable from an array into a specific element in that array. Will update
        // flattenedOffsetInParentArrays.
        void indexIntoArray(unsigned int arrayIndex);
    
        // Get the nth nested array size from the top. Caller is responsible for range checking
        // arrayNestingIndex.
        unsigned int getNestedArraySize(unsigned int arrayNestingIndex) const;
    
        // This function should only be used with variables that are of a basic type or an array of a
        // basic type. Shader interface variables that are enumerated according to rules in GLES 3.1
        // spec section 7.3.1.1 page 77 are fine. For those variables the return value should match the
        // ARRAY_SIZE value that can be queried through the API.
        unsigned int getBasicTypeElementCount() const;
    
        unsigned int getExternalSize() const;
    
        bool isStruct() const { return !fields.empty(); }
        const std::string &getStructName() const { return structOrBlockName; }
        void setStructName(const std::string &newName) { structOrBlockName = newName; }
    
        // All of the shader's variables are described using nested data
        // structures. This is needed in order to disambiguate similar looking
        // types, such as two structs containing the same fields, but in
        // different orders. "findInfoByMappedName" provides an easy query for
        // users to dive into the data structure and fetch the unique variable
        // instance corresponding to a dereferencing chain of the top-level
        // variable.
        // Given a mapped name like 'a[0].b.c[0]', return the ShaderVariable
        // that defines 'c' in |leafVar|, and the original name 'A[0].B.C[0]'
        // in |originalName|, based on the assumption that |this| defines 'a'.
        // If no match is found, return false.
        bool findInfoByMappedName(const std::string &mappedFullName,
                                  const ShaderVariable **leafVar,
                                  std::string *originalFullName) const;
    
        // Find the child field which matches 'fullName' == var.name + "." + field.name.
        // Return nullptr if not found.
        const sh::ShaderVariable *findField(const std::string &fullName, uint32_t *fieldIndexOut) const;
    
        bool isBuiltIn() const;
        bool isEmulatedBuiltIn() const;
    
        // Offset of this variable in parent arrays. In case the parent is an array of arrays, the
        // offset is outerArrayElement * innerArraySize + innerArrayElement.
        // For example, if there's a variable declared as size 3 array of size 4 array of int:
        //   int a[3][4];
        // then the flattenedOffsetInParentArrays of a[2] would be 2.
        // and flattenedOffsetInParentArrays of a[2][1] would be 2*4 + 1 = 9.
        int parentArrayIndex() const
        {
            return hasParentArrayIndex() ? flattenedOffsetInParentArrays : 0;
        }
    
        int getFlattenedOffsetInParentArrays() const { return flattenedOffsetInParentArrays; }
        void setParentArrayIndex(int indexIn) { flattenedOffsetInParentArrays = indexIn; }
    
        bool hasParentArrayIndex() const { return flattenedOffsetInParentArrays != -1; }
    
        void resetEffectiveLocation();
        void updateEffectiveLocation(const sh::ShaderVariable &parent);
    
        // Decide whether two uniforms are the same at shader link time,
        // assuming they are from consecutive shader stages.
        // GLSL ES Spec 3.00.3, section 4.3.5.
        // GLSL ES Spec 3.10.4, section 4.4.5
        bool isSameUniformAtLinkTime(const ShaderVariable &other) const;
    
        // InterfaceBlockField
        // Decide whether two InterfaceBlock fields are the same at shader
        // link time, assuming they are from consecutive shader stages.
        // See GLSL ES Spec 3.00.3, sec 4.3.7.
        bool isSameInterfaceBlockFieldAtLinkTime(const ShaderVariable &other) const;
    
        // Decide whether two varyings are the same at shader link time,
        // assuming they are from consecutive shader stages.
        // Invariance needs to match only in ESSL1. Relevant spec sections:
        // GLSL ES 3.00.4, sections 4.6.1 and 4.3.9.
        // GLSL ES 1.00.17, section 4.6.4.
        bool isSameVaryingAtLinkTime(const ShaderVariable &other, int shaderVersion) const;
        // Deprecated version of isSameVaryingAtLinkTime, which assumes ESSL1.
        bool isSameVaryingAtLinkTime(const ShaderVariable &other) const;
    
        // Shader I/O blocks may match by block name or instance, based on whether both stages have an
        // instance name or not.
        bool isSameNameAtLinkTime(const ShaderVariable &other) const;
    
        // NOTE: When adding new members, the following functions also need to be updated:
        // gl::WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var)
        // gl::LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var)
    
        GLenum type;
        GLenum precision;
        std::string name;
        std::string mappedName;
    
        // Used to make an array type. Outermost array size is stored at the end of the vector.
        std::vector<unsigned int> arraySizes;
    
        // Static use means that the variable is accessed somewhere in the shader source.
        bool staticUse;
        // A variable is active unless the compiler determined that it is not accessed by the shader.
        // All active variables are statically used, but not all statically used variables are
        // necessarily active. GLES 3.0.5 section 2.12.6. GLES 3.1 section 7.3.1.
        bool active;
        std::vector<ShaderVariable> fields;
        // structOrBlockName is used for:
        // - varyings of struct type, in which case it contains the struct name.
        // - shader I/O blocks, in which case it contains the block name.
        std::string structOrBlockName;
        std::string mappedStructOrBlockName;
    
        // Only applies to interface block fields. Kept here for simplicity.
        bool isRowMajorLayout;
    
        // VariableWithLocation
        int location;
    
        // The location of inputs or outputs without location layout quailifer will be updated to '-1'.
        // GLES Spec 3.1, Section 7.3. PROGRAM OBJECTS
        // Not all active variables are assigned valid locations;
        // the following variables will have an effective location of -1:
        bool hasImplicitLocation;
    
        // Uniform
        int binding;
        GLenum imageUnitFormat;
        int offset;
        bool readonly;
        bool writeonly;
    
        // From EXT_shader_framebuffer_fetch
        bool isFragmentInOut;
    
        // OutputVariable
        // From EXT_blend_func_extended.
        int index;
    
        // From EXT_YUV_target
        bool yuv;
    
        // Varying
        InterpolationType interpolation;
        bool isInvariant;
        bool isShaderIOBlock;
        bool isPatch;
    
        // If the variable is a sampler that has ever been statically used with texelFetch
        bool texelFetchStaticUse;
    
      protected:
        bool isSameVariableAtLinkTime(const ShaderVariable &other,
                                      bool matchPrecision,
                                      bool matchName) const;
    
        // NOTE: When adding new members, the following functions also need to be updated:
        // gl::WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var)
        // gl::LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var)
    
        int flattenedOffsetInParentArrays;
    };
    
    // TODO: anglebug.com/3899
    // For backwards compatibility for other codebases (e.g., chromium/src/gpu/command_buffer/service)
    using Uniform             = ShaderVariable;
    using Attribute           = ShaderVariable;
    using OutputVariable      = ShaderVariable;
    using InterfaceBlockField = ShaderVariable;
    using Varying             = ShaderVariable;
    
    struct InterfaceBlock
    {
        InterfaceBlock();
        ~InterfaceBlock();
        InterfaceBlock(const InterfaceBlock &other);
        InterfaceBlock &operator=(const InterfaceBlock &other);
    
        // Fields from blocks with non-empty instance names are prefixed with the block name.
        std::string fieldPrefix() const;
        std::string fieldMappedPrefix() const;
    
        // Decide whether two interface blocks are the same at shader link time.
        bool isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const;
    
        bool isBuiltIn() const;
    
        bool isArray() const { return arraySize > 0; }
        unsigned int elementCount() const { return std::max(1u, arraySize); }
    
        std::string name;
        std::string mappedName;
        std::string instanceName;
        unsigned int arraySize;
        BlockLayoutType layout;
    
        // Deprecated. Matrix packing should only be queried from individual fields of the block.
        // TODO(oetuaho): Remove this once it is no longer used in Chromium.
        bool isRowMajorLayout;
    
        int binding;
        bool staticUse;
        bool active;
        BlockType blockType;
        std::vector<ShaderVariable> fields;
    };
    
    struct WorkGroupSize
    {
        // Must have a trivial default constructor since it is used in YYSTYPE.
        inline WorkGroupSize() = default;
        inline explicit constexpr WorkGroupSize(int initialSize);
    
        void fill(int fillValue);
        void setLocalSize(int localSizeX, int localSizeY, int localSizeZ);
    
        int &operator[](size_t index);
        int operator[](size_t index) const;
        size_t size() const;
    
        // Checks whether two work group size declarations match.
        // Two work group size declarations are the same if the explicitly specified elements are the
        // same or if one of them is specified as one and the other one is not specified
        bool isWorkGroupSizeMatching(const WorkGroupSize &right) const;
    
        // Checks whether any of the values are set.
        bool isAnyValueSet() const;
    
        // Checks whether all of the values are set.
        bool isDeclared() const;
    
        // Checks whether either all of the values are set, or none of them are.
        bool isLocalSizeValid() const;
    
        int localSizeQualifiers[3];
    };
    
    inline constexpr WorkGroupSize::WorkGroupSize(int initialSize)
        : localSizeQualifiers{initialSize, initialSize, initialSize}
    {}
    
    }  // namespace sh
    
    #endif  // GLSLANG_SHADERVARS_H_