Edit

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

Branch :

  • Show log

    Commit

  • Author : Olli Etuaho
    Date : 2017-05-17 14:05:06
    Hash : 855d964b
    Message : Prefix user-defined names in GLSL output Now user-defined names are prefixed by _u in GLSL output in case name hashing is not on. Internal names such as names of temporary variables created in AST transformations are written out as such. This makes handling of internal function names and internal variable names consistent. It also removes the possibility of name conflicts between user-defined names and internal names in case name hashing is not on. In the same vein, it makes it safe to use GLSL reserved words that are not reserved in ESSL as variable names in case name hashing is not on. This also makes the GLSL output more consistent with how names are handled in HLSL output. Name hashing code is shared between VariableInfo and OutputGLSLBase to ensure names are handled consistently in both. The name that's used in the shader source for a given interface variable is written out to ShaderVariable::mappedName. An exception needs to be made for identifiers close to the length limit, since adding any prefix would take them over the limit. But they can be just written out as such, since we don't have any builtins or ANGLE internal variables that have as long names and could create a conflict. BUG=angleproject:2139 BUG=angleproject:2038 TEST=angle_unittests, angle_end2end_tests, WebGL conformance tests Change-Id: Id6ed052c4fab2d091227dc9a3668083053b67a38 Reviewed-on: https://chromium-review.googlesource.com/507647 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: Jamie Madill <jmadill@chromium.org>

  • include/GLSLANG/ShaderVars.h
  • //
    // Copyright (c) 2013-2014 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 <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_FLAT
    };
    
    // 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_PACKED,
        BLOCKLAYOUT_SHARED
    };
    
    // Interface Blocks, see section 4.3.9 of the ESSL 3.10 spec
    enum class BlockType
    {
        BLOCK_UNIFORM,
        BLOCK_BUFFER,
    
        // Required in OpenGL ES 3.1 extension GL_OES_shader_io_blocks.
        // TODO(jiawei.shao@intel.com): add BLOCK_OUT.
        BLOCK_IN
    };
    
    // 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, unsigned int arraySizeIn);
        ~ShaderVariable();
        ShaderVariable(const ShaderVariable &other);
        ShaderVariable &operator=(const ShaderVariable &other);
    
        bool isArray() const { return arraySize > 0; }
        unsigned int elementCount() const { return std::max(1u, arraySize); }
        bool isStruct() const { return !fields.empty(); }
    
        // 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;
    
        bool isBuiltIn() const { return name.compare(0, 3, "gl_") == 0; }
    
        GLenum type;
        GLenum precision;
        std::string name;
        std::string mappedName;
        unsigned int arraySize;
        bool staticUse;
        std::vector<ShaderVariable> fields;
        std::string structName;
    
      protected:
        bool isSameVariableAtLinkTime(const ShaderVariable &other,
                                      bool matchPrecision) const;
    
        bool operator==(const ShaderVariable &other) const;
        bool operator!=(const ShaderVariable &other) const
        {
            return !operator==(other);
        }
    };
    
    // A variable with an integer location to pass back to the GL API: either uniform (can have location
    // in GLES3.1+), vertex shader input or fragment shader output.
    struct VariableWithLocation : public ShaderVariable
    {
        VariableWithLocation();
        ~VariableWithLocation();
        VariableWithLocation(const VariableWithLocation &other);
        VariableWithLocation &operator=(const VariableWithLocation &other);
        bool operator==(const VariableWithLocation &other) const;
        bool operator!=(const VariableWithLocation &other) const { return !operator==(other); }
    
        int location;
    };
    
    struct Uniform : public VariableWithLocation
    {
        Uniform();
        ~Uniform();
        Uniform(const Uniform &other);
        Uniform &operator=(const Uniform &other);
        bool operator==(const Uniform &other) const;
        bool operator!=(const Uniform &other) const
        {
            return !operator==(other);
        }
    
        int binding;
        int offset;
    
        // Decide whether two uniforms are the same at shader link time,
        // assuming one from vertex shader and the other from fragment shader.
        // GLSL ES Spec 3.00.3, section 4.3.5.
        // GLSL ES Spec 3.10.4, section 4.4.5
        bool isSameUniformAtLinkTime(const Uniform &other) const;
    };
    
    struct Attribute : public VariableWithLocation
    {
        Attribute();
        ~Attribute();
        Attribute(const Attribute &other);
        Attribute &operator=(const Attribute &other);
        bool operator==(const Attribute &other) const;
        bool operator!=(const Attribute &other) const { return !operator==(other); }
    };
    
    struct OutputVariable : public VariableWithLocation
    {
        OutputVariable();
        ~OutputVariable();
        OutputVariable(const OutputVariable &other);
        OutputVariable &operator=(const OutputVariable &other);
        bool operator==(const OutputVariable &other) const;
        bool operator!=(const OutputVariable &other) const { return !operator==(other); }
    };
    
    struct InterfaceBlockField : public ShaderVariable
    {
        InterfaceBlockField();
        ~InterfaceBlockField();
        InterfaceBlockField(const InterfaceBlockField &other);
        InterfaceBlockField &operator=(const InterfaceBlockField &other);
        bool operator==(const InterfaceBlockField &other) const;
        bool operator!=(const InterfaceBlockField &other) const
        {
            return !operator==(other);
        }
    
        // Decide whether two InterfaceBlock fields are the same at shader
        // link time, assuming one from vertex shader and the other from
        // fragment shader.
        // See GLSL ES Spec 3.00.3, sec 4.3.7.
        bool isSameInterfaceBlockFieldAtLinkTime(
            const InterfaceBlockField &other) const;
    
        bool isRowMajorLayout;
    };
    
    struct Varying : public ShaderVariable
    {
        Varying();
        ~Varying();
        Varying(const Varying &otherg);
        Varying &operator=(const Varying &other);
        bool operator==(const Varying &other) const;
        bool operator!=(const Varying &other) const
        {
            return !operator==(other);
        }
    
        // Decide whether two varyings are the same at shader link time,
        // assuming one from vertex shader and the other from fragment shader.
        // 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 Varying &other, int shaderVersion) const;
    
        // Deprecated version of isSameVaryingAtLinkTime, which assumes ESSL1.
        bool isSameVaryingAtLinkTime(const Varying &other) const;
    
        InterpolationType interpolation;
        bool isInvariant;
    };
    
    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 { return name.compare(0, 3, "gl_") == 0; }
    
        std::string name;
        std::string mappedName;
        std::string instanceName;
        unsigned int arraySize;
        BlockLayoutType layout;
        bool isRowMajorLayout;
        int binding;
        bool staticUse;
        BlockType blockType;
        std::vector<InterfaceBlockField> fields;
    };
    
    struct WorkGroupSize
    {
        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];
    };
    
    }  // namespace sh
    
    #endif // GLSLANG_SHADERVARS_H_