Edit

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

Branch :

  • Show log

    Commit

  • Author : Qin Jiajia
    Date : 2019-01-07 12:44:44
    Hash : 15214423
    Message : ES31: Add top_level_array_stride support Bug: angleproject:1920 Change-Id: Id18c6cc1bb840c05f73a019156c462886f01d9eb Reviewed-on: https://chromium-review.googlesource.com/c/1396745 Commit-Queue: Jiajia Qin <jiajia.qin@intel.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org>

  • src/libANGLE/ProgramLinkedResources.h
  • //
    // Copyright (c) 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
    {
    struct BlockMemberInfo;
    struct InterfaceBlock;
    struct ShaderVariable;
    class BlockEncoderVisitor;
    class ShaderVariableVisitor;
    struct Uniform;
    }  // namespace sh
    
    namespace gl
    {
    struct BufferVariable;
    struct Caps;
    class Context;
    class InfoLog;
    struct InterfaceBlock;
    enum class LinkMismatchError;
    struct LinkedUniform;
    class ProgramState;
    class ProgramBindings;
    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 ProgramBindings &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 ProgramBindings &uniformLocationBindings);
        bool gatherUniformLocationsAndCheckConflicts(InfoLog &infoLog,
                                                     const ProgramBindings &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(std::vector<InterfaceBlock> *blocksOut);
        void defineInterfaceBlock(const GetBlockSizeFunc &getBlockSize,
                                  const GetBlockMemberInfoFunc &getMemberInfo,
                                  const sh::InterfaceBlock &interfaceBlock,
                                  ShaderType shaderType) const;
    
        virtual size_t getCurrentBlockMemberIndex() const = 0;
    
        ShaderMap<const std::vector<sh::InterfaceBlock> *> mShaderBlocks;
    
        std::vector<InterfaceBlock> *mBlocksOut;
    
        virtual sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
                                                      const std::string &namePrefix,
                                                      const std::string &mappedNamePrefix,
                                                      ShaderType shaderType,
                                                      int blockIndex) const = 0;
    };
    
    class UniformBlockLinker final : public InterfaceBlockLinker
    {
      public:
        UniformBlockLinker(std::vector<InterfaceBlock> *blocksOut,
                           std::vector<LinkedUniform> *uniformsOut);
        ~UniformBlockLinker() override;
    
      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;
    };
    
    class ShaderStorageBlockLinker final : public InterfaceBlockLinker
    {
      public:
        ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut,
                                 std::vector<BufferVariable> *bufferVariablesOut);
        ~ShaderStorageBlockLinker() override;
    
      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;
    };
    
    class AtomicCounterBufferLinker final : angle::NonCopyable
    {
      public:
        AtomicCounterBufferLinker(std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut);
        ~AtomicCounterBufferLinker();
    
        void link(const std::map<int, unsigned int> &sizeMap) const;
    
      private:
        std::vector<AtomicCounterBuffer> *mAtomicCounterBuffersOut;
    };
    
    // 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)
        {
            this->name      = name;
            this->isSampler = isSampler;
        }
    
        std::string name;
        bool isSampler;
    };
    
    struct ProgramLinkedResources
    {
        ProgramLinkedResources(GLuint maxVaryingVectors,
                               PackMode packMode,
                               std::vector<InterfaceBlock> *uniformBlocksOut,
                               std::vector<LinkedUniform> *uniformsOut,
                               std::vector<InterfaceBlock> *shaderStorageBlocksOut,
                               std::vector<BufferVariable> *bufferVariablesOut,
                               std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut);
        ~ProgramLinkedResources();
    
        VaryingPacking varyingPacking;
        UniformBlockLinker uniformBlockLinker;
        ShaderStorageBlockLinker shaderStorageBlockLinker;
        AtomicCounterBufferLinker atomicCounterBufferLinker;
        std::vector<UnusedUniform> unusedUniforms;
    };
    
    }  // namespace gl
    
    #endif  // LIBANGLE_UNIFORMLINKER_H_