Edit

kc3-lang/angle/src/libANGLE/ProgramLinkedResources.h

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2020-11-27 11:08:41
    Hash : b912eec5
    Message : Vulkan: Support GL_EXT_tessellation_shader. Shader translator changes done in http://crrev.com/c/2633936 Adds a new DIRTY_BIT_PATCH_VERTICES state to Context. Supportes state query and transform feedback. 4 test suppressions remain as follow-up fixes. Adds a new varying packing mode for a simple Vulkan rule set. Based on work by Mohan Maiya (m.maiya@samsung.com). Test: dEQP-GLES31.functional.tessellation.* Bug: angleproject:3572 Change-Id: I4cad2cca30adb754fd12c83027673906541f566a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2568234 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Mohan Maiya <m.maiya@samsung.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>

  • src/libANGLE/ProgramLinkedResources.h
  • //
    // Copyright 2017 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.
    //
    
    // ProgramLinkedResources.h: implements link-time checks for default block uniforms, and generates
    // uniform locations. Populates data structures related to uniforms so that they can be stored in
    // program state.
    
    #ifndef LIBANGLE_UNIFORMLINKER_H_
    #define LIBANGLE_UNIFORMLINKER_H_
    
    #include "angle_gl.h"
    #include "common/PackedEnums.h"
    #include "common/angleutils.h"
    #include "libANGLE/VaryingPacking.h"
    
    #include <functional>
    
    namespace sh
    {
    class BlockLayoutEncoder;
    struct BlockMemberInfo;
    struct InterfaceBlock;
    struct ShaderVariable;
    class BlockEncoderVisitor;
    class ShaderVariableVisitor;
    struct ShaderVariable;
    }  // namespace sh
    
    namespace gl
    {
    struct BufferVariable;
    struct Caps;
    class Context;
    class InfoLog;
    struct InterfaceBlock;
    enum class LinkMismatchError;
    struct LinkedUniform;
    class ProgramState;
    class ProgramBindings;
    class ProgramAliasedBindings;
    class Shader;
    struct ShaderVariableBuffer;
    struct UnusedUniform;
    struct VariableLocation;
    
    using AtomicCounterBuffer = ShaderVariableBuffer;
    
    class UniformLinker final : angle::NonCopyable
    {
      public:
        UniformLinker(const ProgramState &state);
        ~UniformLinker();
    
        bool link(const Caps &caps,
                  InfoLog &infoLog,
                  const ProgramAliasedBindings &uniformLocationBindings);
    
        void getResults(std::vector<LinkedUniform> *uniforms,
                        std::vector<UnusedUniform> *unusedUniforms,
                        std::vector<VariableLocation> *uniformLocations);
    
      private:
        bool validateGraphicsUniforms(InfoLog &infoLog) const;
    
        bool flattenUniformsAndCheckCapsForShader(Shader *shader,
                                                  const Caps &caps,
                                                  std::vector<LinkedUniform> &samplerUniforms,
                                                  std::vector<LinkedUniform> &imageUniforms,
                                                  std::vector<LinkedUniform> &atomicCounterUniforms,
                                                  std::vector<UnusedUniform> &unusedUniforms,
                                                  InfoLog &infoLog);
    
        bool flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog);
        bool checkMaxCombinedAtomicCounters(const Caps &caps, InfoLog &infoLog);
    
        bool indexUniforms(InfoLog &infoLog, const ProgramAliasedBindings &uniformLocationBindings);
        bool gatherUniformLocationsAndCheckConflicts(
            InfoLog &infoLog,
            const ProgramAliasedBindings &uniformLocationBindings,
            std::set<GLuint> *ignoredLocations,
            int *maxUniformLocation);
        void pruneUnusedUniforms();
    
        const ProgramState &mState;
        std::vector<LinkedUniform> mUniforms;
        std::vector<UnusedUniform> mUnusedUniforms;
        std::vector<VariableLocation> mUniformLocations;
    };
    
    using GetBlockSizeFunc = std::function<
        bool(const std::string &blockName, const std::string &blockMappedName, size_t *sizeOut)>;
    using GetBlockMemberInfoFunc = std::function<
        bool(const std::string &name, const std::string &mappedName, sh::BlockMemberInfo *infoOut)>;
    
    // This class is intended to be used during the link step to store interface block information.
    // It is called by the Impl class during ProgramImpl::link so that it has access to the
    // real block size and layout.
    class InterfaceBlockLinker : angle::NonCopyable
    {
      public:
        virtual ~InterfaceBlockLinker();
    
        // This is called once per shader stage. It stores a pointer to the block vector, so it's
        // important that this class does not persist longer than the duration of Program::link.
        void addShaderBlocks(ShaderType shader, const std::vector<sh::InterfaceBlock> *blocks);
    
        // This is called once during a link operation, after all shader blocks are added.
        void linkBlocks(const GetBlockSizeFunc &getBlockSize,
                        const GetBlockMemberInfoFunc &getMemberInfo) const;
    
      protected:
        InterfaceBlockLinker();
        void init(std::vector<InterfaceBlock> *blocksOut,
                  std::vector<std::string> *unusedInterfaceBlocksOut);
        void defineInterfaceBlock(const GetBlockSizeFunc &getBlockSize,
                                  const GetBlockMemberInfoFunc &getMemberInfo,
                                  const sh::InterfaceBlock &interfaceBlock,
                                  ShaderType shaderType) const;
    
        virtual size_t getCurrentBlockMemberIndex() const = 0;
    
        virtual sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
                                                      const std::string &namePrefix,
                                                      const std::string &mappedNamePrefix,
                                                      ShaderType shaderType,
                                                      int blockIndex) const = 0;
    
        ShaderMap<const std::vector<sh::InterfaceBlock> *> mShaderBlocks = {};
    
        std::vector<InterfaceBlock> *mBlocksOut             = nullptr;
        std::vector<std::string> *mUnusedInterfaceBlocksOut = nullptr;
    };
    
    class UniformBlockLinker final : public InterfaceBlockLinker
    {
      public:
        UniformBlockLinker();
        ~UniformBlockLinker() override;
    
        void init(std::vector<InterfaceBlock> *blocksOut,
                  std::vector<LinkedUniform> *uniformsOut,
                  std::vector<std::string> *unusedInterfaceBlocksOut);
    
      private:
        size_t getCurrentBlockMemberIndex() const override;
    
        sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
                                              const std::string &namePrefix,
                                              const std::string &mappedNamePrefix,
                                              ShaderType shaderType,
                                              int blockIndex) const override;
    
        std::vector<LinkedUniform> *mUniformsOut = nullptr;
    };
    
    class ShaderStorageBlockLinker final : public InterfaceBlockLinker
    {
      public:
        ShaderStorageBlockLinker();
        ~ShaderStorageBlockLinker() override;
    
        void init(std::vector<InterfaceBlock> *blocksOut,
                  std::vector<BufferVariable> *bufferVariablesOut,
                  std::vector<std::string> *unusedInterfaceBlocksOut);
    
      private:
        size_t getCurrentBlockMemberIndex() const override;
    
        sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
                                              const std::string &namePrefix,
                                              const std::string &mappedNamePrefix,
                                              ShaderType shaderType,
                                              int blockIndex) const override;
    
        std::vector<BufferVariable> *mBufferVariablesOut = nullptr;
    };
    
    class AtomicCounterBufferLinker final : angle::NonCopyable
    {
      public:
        AtomicCounterBufferLinker();
        ~AtomicCounterBufferLinker();
    
        void init(std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut);
        void link(const std::map<int, unsigned int> &sizeMap) const;
    
      private:
        std::vector<AtomicCounterBuffer> *mAtomicCounterBuffersOut = nullptr;
    };
    
    // The link operation is responsible for finishing the link of uniform and interface blocks.
    // This way it can filter out unreferenced resources and still have access to the info.
    // TODO(jmadill): Integrate uniform linking/filtering as well as interface blocks.
    struct UnusedUniform
    {
        UnusedUniform(std::string name, bool isSampler, bool isImage, bool isAtomicCounter)
        {
            this->name            = name;
            this->isSampler       = isSampler;
            this->isImage         = isImage;
            this->isAtomicCounter = isAtomicCounter;
        }
    
        std::string name;
        bool isSampler;
        bool isImage;
        bool isAtomicCounter;
    };
    
    struct ProgramLinkedResources
    {
        ProgramLinkedResources();
        ~ProgramLinkedResources();
    
        void init(std::vector<InterfaceBlock> *uniformBlocksOut,
                  std::vector<LinkedUniform> *uniformsOut,
                  std::vector<InterfaceBlock> *shaderStorageBlocksOut,
                  std::vector<BufferVariable> *bufferVariablesOut,
                  std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut);
    
        ProgramVaryingPacking varyingPacking;
        UniformBlockLinker uniformBlockLinker;
        ShaderStorageBlockLinker shaderStorageBlockLinker;
        AtomicCounterBufferLinker atomicCounterBufferLinker;
        std::vector<UnusedUniform> unusedUniforms;
        std::vector<std::string> unusedInterfaceBlocks;
    };
    
    class CustomBlockLayoutEncoderFactory : angle::NonCopyable
    {
      public:
        virtual ~CustomBlockLayoutEncoderFactory() {}
    
        virtual sh::BlockLayoutEncoder *makeEncoder() = 0;
    };
    
    // Used by the backends in Program*::linkResources to parse interface blocks and provide
    // information to ProgramLinkedResources' linkers.
    class ProgramLinkedResourcesLinker final : angle::NonCopyable
    {
      public:
        ProgramLinkedResourcesLinker(CustomBlockLayoutEncoderFactory *customEncoderFactory)
            : mCustomEncoderFactory(customEncoderFactory)
        {}
    
        void linkResources(const ProgramState &programState,
                           const ProgramLinkedResources &resources) const;
    
      private:
        void getAtomicCounterBufferSizeMap(const ProgramState &programState,
                                           std::map<int, unsigned int> &sizeMapOut) const;
    
        CustomBlockLayoutEncoderFactory *mCustomEncoderFactory;
    };
    
    bool LinkValidateProgramGlobalNames(InfoLog &infoLog, const HasAttachedShaders &programOrPipeline);
    bool LinkValidateShaderInterfaceMatching(const std::vector<sh::ShaderVariable> &outputVaryings,
                                             const std::vector<sh::ShaderVariable> &inputVaryings,
                                             ShaderType frontShaderType,
                                             ShaderType backShaderType,
                                             int frontShaderVersion,
                                             int backShaderVersion,
                                             bool isSeparable,
                                             InfoLog &infoLog);
    bool LinkValidateBuiltInVaryingsInvariant(const std::vector<sh::ShaderVariable> &vertexVaryings,
                                              const std::vector<sh::ShaderVariable> &fragmentVaryings,
                                              int vertexShaderVersion,
                                              InfoLog &infoLog);
    bool LinkValidateBuiltInVaryings(const std::vector<sh::ShaderVariable> &inputVaryings,
                                     const std::vector<sh::ShaderVariable> &outputVaryings,
                                     ShaderType inputShaderType,
                                     ShaderType outputShaderType,
                                     int inputShaderVersion,
                                     int outputShaderVersion,
                                     InfoLog &infoLog);
    LinkMismatchError LinkValidateProgramVariables(const sh::ShaderVariable &variable1,
                                                   const sh::ShaderVariable &variable2,
                                                   bool validatePrecision,
                                                   bool treatVariable1AsNonArray,
                                                   bool treatVariable2AsNonArray,
                                                   std::string *mismatchedStructOrBlockMemberName);
    void AddProgramVariableParentPrefix(const std::string &parentName,
                                        std::string *mismatchedFieldName);
    }  // namespace gl
    
    #endif  // LIBANGLE_UNIFORMLINKER_H_