Edit

kc3-lang/angle/src/compiler/translator/blocklayout.h

Branch :

  • Show log

    Commit

  • Author : Mohan Maiya
    Date : 2021-02-24 09:49:42
    Hash : 550f2a3e
    Message : Vulkan: Shader support for EXT_shader_framebuffer_fetch_non_coherent Translator can accept gl_LastFragData and 'inout' variable to gain access to framebuffer attachment data. The Vulkan translator replaces it with the SubpassInput type variable. Note that this works only for the noncoherent version of the extension. Bug: angleproject:5454 Test: *EXTShaderFramebufferFetchNoncoherent*.* Change-Id: I392f84ee3ad3eb9fbd09d0b7ff83731a9a3f33f6 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2598060 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Mohan Maiya <m.maiya@samsung.com>

  • src/compiler/translator/blocklayout.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.
    //
    // blocklayout.h:
    //   Methods and classes related to uniform layout and packing in GLSL and HLSL.
    //
    
    #ifndef COMMON_BLOCKLAYOUT_H_
    #define COMMON_BLOCKLAYOUT_H_
    
    #include <cstddef>
    #include <map>
    #include <vector>
    
    #include <GLSLANG/ShaderLang.h>
    #include "angle_gl.h"
    
    namespace sh
    {
    struct ShaderVariable;
    struct InterfaceBlock;
    
    struct BlockMemberInfo
    {
        constexpr BlockMemberInfo() = default;
    
        constexpr BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
            : offset(offset),
              arrayStride(arrayStride),
              matrixStride(matrixStride),
              isRowMajorMatrix(isRowMajorMatrix)
        {}
    
        constexpr BlockMemberInfo(int offset,
                                  int arrayStride,
                                  int matrixStride,
                                  bool isRowMajorMatrix,
                                  int topLevelArrayStride)
            : offset(offset),
              arrayStride(arrayStride),
              matrixStride(matrixStride),
              isRowMajorMatrix(isRowMajorMatrix),
              topLevelArrayStride(topLevelArrayStride)
        {}
    
        // A single integer identifying the offset of an active variable.
        int offset = -1;
    
        // A single integer identifying the stride between array elements in an active variable.
        int arrayStride = -1;
    
        // A single integer identifying the stride between columns of a column-major matrix or rows of a
        // row-major matrix.
        int matrixStride = -1;
    
        // A single integer identifying whether an active variable is a row-major matrix.
        bool isRowMajorMatrix = false;
    
        // A single integer identifying the number of active array elements of the top-level shader
        // storage block member containing the active variable.
        int topLevelArrayStride = -1;
    };
    
    constexpr size_t ComponentAlignment(size_t numComponents)
    {
        return (numComponents == 3u ? 4u : numComponents);
    }
    
    constexpr BlockMemberInfo kDefaultBlockMemberInfo;
    
    class BlockLayoutEncoder
    {
      public:
        BlockLayoutEncoder();
        virtual ~BlockLayoutEncoder() {}
    
        BlockMemberInfo encodeType(GLenum type,
                                   const std::vector<unsigned int> &arraySizes,
                                   bool isRowMajorMatrix);
    
        size_t getCurrentOffset() const { return mCurrentOffset * kBytesPerComponent; }
        size_t getShaderVariableSize(const ShaderVariable &structVar, bool isRowMajor);
    
        // Called when entering/exiting a structure variable.
        virtual void enterAggregateType(const ShaderVariable &structVar) = 0;
        virtual void exitAggregateType(const ShaderVariable &structVar)  = 0;
    
        static constexpr size_t kBytesPerComponent           = 4u;
        static constexpr unsigned int kComponentsPerRegister = 4u;
    
        static size_t GetBlockRegister(const BlockMemberInfo &info);
        static size_t GetBlockRegisterElement(const BlockMemberInfo &info);
    
      protected:
        void align(size_t baseAlignment);
    
        virtual void getBlockLayoutInfo(GLenum type,
                                        const std::vector<unsigned int> &arraySizes,
                                        bool isRowMajorMatrix,
                                        int *arrayStrideOut,
                                        int *matrixStrideOut) = 0;
        virtual void advanceOffset(GLenum type,
                                   const std::vector<unsigned int> &arraySizes,
                                   bool isRowMajorMatrix,
                                   int arrayStride,
                                   int matrixStride)          = 0;
    
        size_t mCurrentOffset;
    };
    
    // Will return default values for everything.
    class StubBlockEncoder : public BlockLayoutEncoder
    {
      public:
        StubBlockEncoder() = default;
    
        void enterAggregateType(const ShaderVariable &structVar) override {}
        void exitAggregateType(const ShaderVariable &structVar) override {}
    
      protected:
        void getBlockLayoutInfo(GLenum type,
                                const std::vector<unsigned int> &arraySizes,
                                bool isRowMajorMatrix,
                                int *arrayStrideOut,
                                int *matrixStrideOut) override;
    
        void advanceOffset(GLenum type,
                           const std::vector<unsigned int> &arraySizes,
                           bool isRowMajorMatrix,
                           int arrayStride,
                           int matrixStride) override
        {}
    };
    
    // Block layout according to the std140 block layout
    // See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification
    
    class Std140BlockEncoder : public BlockLayoutEncoder
    {
      public:
        Std140BlockEncoder();
    
        void enterAggregateType(const ShaderVariable &structVar) override;
        void exitAggregateType(const ShaderVariable &structVar) override;
    
      protected:
        void getBlockLayoutInfo(GLenum type,
                                const std::vector<unsigned int> &arraySizes,
                                bool isRowMajorMatrix,
                                int *arrayStrideOut,
                                int *matrixStrideOut) override;
        void advanceOffset(GLenum type,
                           const std::vector<unsigned int> &arraySizes,
                           bool isRowMajorMatrix,
                           int arrayStride,
                           int matrixStride) override;
    
        virtual size_t getBaseAlignment(const ShaderVariable &variable) const;
        virtual size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const;
    };
    
    class Std430BlockEncoder : public Std140BlockEncoder
    {
      public:
        Std430BlockEncoder();
    
      protected:
        size_t getBaseAlignment(const ShaderVariable &variable) const override;
        size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const override;
    };
    
    using BlockLayoutMap = std::map<std::string, BlockMemberInfo>;
    
    void GetInterfaceBlockInfo(const std::vector<ShaderVariable> &fields,
                               const std::string &prefix,
                               BlockLayoutEncoder *encoder,
                               BlockLayoutMap *blockInfoOut);
    
    // Used for laying out the default uniform block on the Vulkan backend.
    void GetActiveUniformBlockInfo(const std::vector<ShaderVariable> &uniforms,
                                   const std::string &prefix,
                                   BlockLayoutEncoder *encoder,
                                   BlockLayoutMap *blockInfoOut);
    
    class ShaderVariableVisitor
    {
      public:
        virtual ~ShaderVariableVisitor() {}
    
        virtual void enterStruct(const ShaderVariable &structVar) {}
        virtual void exitStruct(const ShaderVariable &structVar) {}
    
        virtual void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) {}
        virtual void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) {}
    
        virtual void enterArray(const ShaderVariable &arrayVar) {}
        virtual void exitArray(const ShaderVariable &arrayVar) {}
    
        virtual void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) {}
        virtual void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) {}
    
        virtual void visitOpaqueObject(const sh::ShaderVariable &variable) {}
    
        virtual void visitVariable(const ShaderVariable &variable, bool isRowMajor) = 0;
    
      protected:
        ShaderVariableVisitor() {}
    };
    
    class VariableNameVisitor : public ShaderVariableVisitor
    {
      public:
        VariableNameVisitor(const std::string &namePrefix, const std::string &mappedNamePrefix);
        ~VariableNameVisitor() override;
    
        void enterStruct(const ShaderVariable &structVar) override;
        void exitStruct(const ShaderVariable &structVar) override;
        void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
        void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
        void enterArray(const ShaderVariable &arrayVar) override;
        void exitArray(const ShaderVariable &arrayVar) override;
        void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
        void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
    
      protected:
        virtual void visitNamedOpaqueObject(const sh::ShaderVariable &variable,
                                            const std::string &name,
                                            const std::string &mappedName,
                                            const std::vector<unsigned int> &arraySizes)
        {}
        virtual void visitNamedVariable(const ShaderVariable &variable,
                                        bool isRowMajor,
                                        const std::string &name,
                                        const std::string &mappedName,
                                        const std::vector<unsigned int> &arraySizes) = 0;
    
        std::string collapseNameStack() const;
        std::string collapseMappedNameStack() const;
    
      private:
        void visitOpaqueObject(const sh::ShaderVariable &variable) final;
        void visitVariable(const ShaderVariable &variable, bool isRowMajor) final;
    
        std::vector<std::string> mNameStack;
        std::vector<std::string> mMappedNameStack;
        std::vector<unsigned int> mArraySizeStack;
    };
    
    class BlockEncoderVisitor : public VariableNameVisitor
    {
      public:
        BlockEncoderVisitor(const std::string &namePrefix,
                            const std::string &mappedNamePrefix,
                            BlockLayoutEncoder *encoder);
        ~BlockEncoderVisitor() override;
    
        void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
        void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
        void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
        void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
    
        void visitNamedVariable(const ShaderVariable &variable,
                                bool isRowMajor,
                                const std::string &name,
                                const std::string &mappedName,
                                const std::vector<unsigned int> &arraySizes) override;
    
        virtual void encodeVariable(const ShaderVariable &variable,
                                    const BlockMemberInfo &variableInfo,
                                    const std::string &name,
                                    const std::string &mappedName)
        {}
    
      protected:
        int mTopLevelArraySize           = 1;
        int mTopLevelArrayStride         = 0;
        bool mIsTopLevelArrayStrideReady = true;
        bool mSkipEnabled                = false;
    
      private:
        BlockLayoutEncoder *mEncoder;
        unsigned int mStructStackSize = 0;
    };
    
    void TraverseShaderVariable(const ShaderVariable &variable,
                                bool isRowMajorLayout,
                                ShaderVariableVisitor *visitor);
    
    template <typename T>
    void TraverseShaderVariables(const std::vector<T> &vars,
                                 bool isRowMajorLayout,
                                 ShaderVariableVisitor *visitor)
    {
        for (const T &var : vars)
        {
            TraverseShaderVariable(var, isRowMajorLayout, visitor);
        }
    }
    
    template <typename T>
    void TraverseActiveShaderVariables(const std::vector<T> &vars,
                                       bool isRowMajorLayout,
                                       ShaderVariableVisitor *visitor)
    {
        for (const T &var : vars)
        {
            if (var.active)
            {
                TraverseShaderVariable(var, isRowMajorLayout, visitor);
            }
        }
    }
    }  // namespace sh
    
    #endif  // COMMON_BLOCKLAYOUT_H_