tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ProgramLinkedResources.h (13876B)


      1 //
      2 // Copyright 2017 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // ProgramLinkedResources.h: implements link-time checks for default block uniforms, and generates
      8 // uniform locations. Populates data structures related to uniforms so that they can be stored in
      9 // program state.
     10 
     11 #ifndef LIBANGLE_UNIFORMLINKER_H_
     12 #define LIBANGLE_UNIFORMLINKER_H_
     13 
     14 #include "angle_gl.h"
     15 #include "common/PackedEnums.h"
     16 #include "common/angleutils.h"
     17 #include "libANGLE/VaryingPacking.h"
     18 
     19 #include <functional>
     20 
     21 namespace sh
     22 {
     23 class BlockLayoutEncoder;
     24 struct BlockMemberInfo;
     25 struct InterfaceBlock;
     26 struct ShaderVariable;
     27 class BlockEncoderVisitor;
     28 class ShaderVariableVisitor;
     29 struct ShaderVariable;
     30 }  // namespace sh
     31 
     32 namespace gl
     33 {
     34 struct BufferVariable;
     35 struct Caps;
     36 class Context;
     37 class InfoLog;
     38 struct InterfaceBlock;
     39 enum class LinkMismatchError;
     40 struct LinkedUniform;
     41 class ProgramState;
     42 class ProgramPipelineState;
     43 class ProgramBindings;
     44 class ProgramAliasedBindings;
     45 class Shader;
     46 struct ShaderVariableBuffer;
     47 struct UnusedUniform;
     48 struct VariableLocation;
     49 
     50 using AtomicCounterBuffer = ShaderVariableBuffer;
     51 using ShaderUniform       = std::pair<ShaderType, const sh::ShaderVariable *>;
     52 
     53 class UniformLinker final : angle::NonCopyable
     54 {
     55  public:
     56    UniformLinker(const ShaderBitSet &activeShaderStages,
     57                  const ShaderMap<std::vector<sh::ShaderVariable>> &shaderUniforms);
     58    ~UniformLinker();
     59 
     60    bool link(const Caps &caps,
     61              InfoLog &infoLog,
     62              const ProgramAliasedBindings &uniformLocationBindings);
     63 
     64    void getResults(std::vector<LinkedUniform> *uniforms,
     65                    std::vector<UnusedUniform> *unusedUniformsOutOrNull,
     66                    std::vector<VariableLocation> *uniformLocationsOutOrNull);
     67 
     68  private:
     69    bool validateGraphicsUniforms(InfoLog &infoLog) const;
     70    bool validateGraphicsUniformsPerShader(ShaderType shaderToLink,
     71                                           bool extendLinkedUniforms,
     72                                           std::map<std::string, ShaderUniform> *linkedUniforms,
     73                                           InfoLog &infoLog) const;
     74    bool flattenUniformsAndCheckCapsForShader(ShaderType shaderType,
     75                                              const Caps &caps,
     76                                              std::vector<LinkedUniform> &samplerUniforms,
     77                                              std::vector<LinkedUniform> &imageUniforms,
     78                                              std::vector<LinkedUniform> &atomicCounterUniforms,
     79                                              std::vector<LinkedUniform> &inputAttachmentUniforms,
     80                                              std::vector<UnusedUniform> &unusedUniforms,
     81                                              InfoLog &infoLog);
     82 
     83    bool flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog);
     84    bool checkMaxCombinedAtomicCounters(const Caps &caps, InfoLog &infoLog);
     85 
     86    bool indexUniforms(InfoLog &infoLog, const ProgramAliasedBindings &uniformLocationBindings);
     87    bool gatherUniformLocationsAndCheckConflicts(
     88        InfoLog &infoLog,
     89        const ProgramAliasedBindings &uniformLocationBindings,
     90        std::set<GLuint> *ignoredLocations,
     91        int *maxUniformLocation);
     92    void pruneUnusedUniforms();
     93 
     94    ShaderBitSet mActiveShaderStages;
     95    const ShaderMap<std::vector<sh::ShaderVariable>> &mShaderUniforms;
     96    std::vector<LinkedUniform> mUniforms;
     97    std::vector<UnusedUniform> mUnusedUniforms;
     98    std::vector<VariableLocation> mUniformLocations;
     99 };
    100 
    101 using GetBlockSizeFunc = std::function<
    102    bool(const std::string &blockName, const std::string &blockMappedName, size_t *sizeOut)>;
    103 using GetBlockMemberInfoFunc = std::function<
    104    bool(const std::string &name, const std::string &mappedName, sh::BlockMemberInfo *infoOut)>;
    105 
    106 // This class is intended to be used during the link step to store interface block information.
    107 // It is called by the Impl class during ProgramImpl::link so that it has access to the
    108 // real block size and layout.
    109 class InterfaceBlockLinker : angle::NonCopyable
    110 {
    111  public:
    112    virtual ~InterfaceBlockLinker();
    113 
    114    // This is called once per shader stage. It stores a pointer to the block vector, so it's
    115    // important that this class does not persist longer than the duration of Program::link.
    116    void addShaderBlocks(ShaderType shader, const std::vector<sh::InterfaceBlock> *blocks);
    117 
    118    // This is called once during a link operation, after all shader blocks are added.
    119    void linkBlocks(const GetBlockSizeFunc &getBlockSize,
    120                    const GetBlockMemberInfoFunc &getMemberInfo) const;
    121 
    122    const std::vector<sh::InterfaceBlock> &getShaderBlocks(ShaderType shaderType) const
    123    {
    124        ASSERT(mShaderBlocks[shaderType]);
    125        return *mShaderBlocks[shaderType];
    126    }
    127 
    128  protected:
    129    InterfaceBlockLinker();
    130    void init(std::vector<InterfaceBlock> *blocksOut,
    131              std::vector<std::string> *unusedInterfaceBlocksOut);
    132    void defineInterfaceBlock(const GetBlockSizeFunc &getBlockSize,
    133                              const GetBlockMemberInfoFunc &getMemberInfo,
    134                              const sh::InterfaceBlock &interfaceBlock,
    135                              ShaderType shaderType) const;
    136 
    137    virtual size_t getCurrentBlockMemberIndex() const = 0;
    138 
    139    virtual sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
    140                                                  const std::string &namePrefix,
    141                                                  const std::string &mappedNamePrefix,
    142                                                  ShaderType shaderType,
    143                                                  int blockIndex) const = 0;
    144 
    145    ShaderMap<const std::vector<sh::InterfaceBlock> *> mShaderBlocks = {};
    146 
    147    std::vector<InterfaceBlock> *mBlocksOut             = nullptr;
    148    std::vector<std::string> *mUnusedInterfaceBlocksOut = nullptr;
    149 };
    150 
    151 class UniformBlockLinker final : public InterfaceBlockLinker
    152 {
    153  public:
    154    UniformBlockLinker();
    155    ~UniformBlockLinker() override;
    156 
    157    void init(std::vector<InterfaceBlock> *blocksOut,
    158              std::vector<LinkedUniform> *uniformsOut,
    159              std::vector<std::string> *unusedInterfaceBlocksOut);
    160 
    161  private:
    162    size_t getCurrentBlockMemberIndex() const override;
    163 
    164    sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
    165                                          const std::string &namePrefix,
    166                                          const std::string &mappedNamePrefix,
    167                                          ShaderType shaderType,
    168                                          int blockIndex) const override;
    169 
    170    std::vector<LinkedUniform> *mUniformsOut = nullptr;
    171 };
    172 
    173 class ShaderStorageBlockLinker final : public InterfaceBlockLinker
    174 {
    175  public:
    176    ShaderStorageBlockLinker();
    177    ~ShaderStorageBlockLinker() override;
    178 
    179    void init(std::vector<InterfaceBlock> *blocksOut,
    180              std::vector<BufferVariable> *bufferVariablesOut,
    181              std::vector<std::string> *unusedInterfaceBlocksOut);
    182 
    183  private:
    184    size_t getCurrentBlockMemberIndex() const override;
    185 
    186    sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
    187                                          const std::string &namePrefix,
    188                                          const std::string &mappedNamePrefix,
    189                                          ShaderType shaderType,
    190                                          int blockIndex) const override;
    191 
    192    std::vector<BufferVariable> *mBufferVariablesOut = nullptr;
    193 };
    194 
    195 class AtomicCounterBufferLinker final : angle::NonCopyable
    196 {
    197  public:
    198    AtomicCounterBufferLinker();
    199    ~AtomicCounterBufferLinker();
    200 
    201    void init(std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut);
    202    void link(const std::map<int, unsigned int> &sizeMap) const;
    203 
    204  private:
    205    std::vector<AtomicCounterBuffer> *mAtomicCounterBuffersOut = nullptr;
    206 };
    207 
    208 // The link operation is responsible for finishing the link of uniform and interface blocks.
    209 // This way it can filter out unreferenced resources and still have access to the info.
    210 // TODO(jmadill): Integrate uniform linking/filtering as well as interface blocks.
    211 struct UnusedUniform
    212 {
    213    UnusedUniform(std::string name,
    214                  bool isSampler,
    215                  bool isImage,
    216                  bool isAtomicCounter,
    217                  bool isFragmentInOut)
    218    {
    219        this->name            = name;
    220        this->isSampler       = isSampler;
    221        this->isImage         = isImage;
    222        this->isAtomicCounter = isAtomicCounter;
    223        this->isFragmentInOut = isFragmentInOut;
    224    }
    225 
    226    std::string name;
    227    bool isSampler;
    228    bool isImage;
    229    bool isAtomicCounter;
    230    bool isFragmentInOut;
    231 };
    232 
    233 struct ProgramLinkedResources
    234 {
    235    ProgramLinkedResources();
    236    ~ProgramLinkedResources();
    237 
    238    void init(std::vector<InterfaceBlock> *uniformBlocksOut,
    239              std::vector<LinkedUniform> *uniformsOut,
    240              std::vector<InterfaceBlock> *shaderStorageBlocksOut,
    241              std::vector<BufferVariable> *bufferVariablesOut,
    242              std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut);
    243 
    244    ProgramVaryingPacking varyingPacking;
    245    UniformBlockLinker uniformBlockLinker;
    246    ShaderStorageBlockLinker shaderStorageBlockLinker;
    247    AtomicCounterBufferLinker atomicCounterBufferLinker;
    248    std::vector<UnusedUniform> unusedUniforms;
    249    std::vector<std::string> unusedInterfaceBlocks;
    250 };
    251 
    252 struct LinkingVariables final : private angle::NonCopyable
    253 {
    254    LinkingVariables(const Context *context, const ProgramState &state);
    255    LinkingVariables(const ProgramPipelineState &state);
    256    ~LinkingVariables();
    257 
    258    ShaderMap<std::vector<sh::ShaderVariable>> outputVaryings;
    259    ShaderMap<std::vector<sh::ShaderVariable>> inputVaryings;
    260    ShaderMap<std::vector<sh::ShaderVariable>> uniforms;
    261    ShaderMap<std::vector<sh::InterfaceBlock>> uniformBlocks;
    262    ShaderBitSet isShaderStageUsedBitset;
    263 };
    264 
    265 class CustomBlockLayoutEncoderFactory : angle::NonCopyable
    266 {
    267  public:
    268    virtual ~CustomBlockLayoutEncoderFactory() {}
    269 
    270    virtual sh::BlockLayoutEncoder *makeEncoder() = 0;
    271 };
    272 
    273 // Used by the backends in Program*::linkResources to parse interface blocks and provide
    274 // information to ProgramLinkedResources' linkers.
    275 class ProgramLinkedResourcesLinker final : angle::NonCopyable
    276 {
    277  public:
    278    ProgramLinkedResourcesLinker(CustomBlockLayoutEncoderFactory *customEncoderFactory)
    279        : mCustomEncoderFactory(customEncoderFactory)
    280    {}
    281 
    282    void linkResources(const Context *context,
    283                       const ProgramState &programState,
    284                       const ProgramLinkedResources &resources) const;
    285 
    286  private:
    287    void getAtomicCounterBufferSizeMap(const ProgramState &programState,
    288                                       std::map<int, unsigned int> &sizeMapOut) const;
    289 
    290    CustomBlockLayoutEncoderFactory *mCustomEncoderFactory;
    291 };
    292 
    293 using ShaderInterfaceBlock = std::pair<ShaderType, const sh::InterfaceBlock *>;
    294 using InterfaceBlockMap    = std::map<std::string, ShaderInterfaceBlock>;
    295 
    296 bool LinkValidateProgramGlobalNames(InfoLog &infoLog,
    297                                    const ProgramExecutable &executable,
    298                                    const LinkingVariables &linkingVariables);
    299 bool LinkValidateShaderInterfaceMatching(const std::vector<sh::ShaderVariable> &outputVaryings,
    300                                         const std::vector<sh::ShaderVariable> &inputVaryings,
    301                                         ShaderType frontShaderType,
    302                                         ShaderType backShaderType,
    303                                         int frontShaderVersion,
    304                                         int backShaderVersion,
    305                                         bool isSeparable,
    306                                         InfoLog &infoLog);
    307 bool LinkValidateBuiltInVaryingsInvariant(const std::vector<sh::ShaderVariable> &vertexVaryings,
    308                                          const std::vector<sh::ShaderVariable> &fragmentVaryings,
    309                                          int vertexShaderVersion,
    310                                          InfoLog &infoLog);
    311 bool LinkValidateBuiltInVaryings(const std::vector<sh::ShaderVariable> &inputVaryings,
    312                                 const std::vector<sh::ShaderVariable> &outputVaryings,
    313                                 ShaderType inputShaderType,
    314                                 ShaderType outputShaderType,
    315                                 int inputShaderVersion,
    316                                 int outputShaderVersion,
    317                                 InfoLog &infoLog);
    318 LinkMismatchError LinkValidateProgramVariables(const sh::ShaderVariable &variable1,
    319                                               const sh::ShaderVariable &variable2,
    320                                               bool validatePrecision,
    321                                               bool treatVariable1AsNonArray,
    322                                               bool treatVariable2AsNonArray,
    323                                               std::string *mismatchedStructOrBlockMemberName);
    324 void AddProgramVariableParentPrefix(const std::string &parentName,
    325                                    std::string *mismatchedFieldName);
    326 bool LinkValidateProgramInterfaceBlocks(const Context *context,
    327                                        ShaderBitSet activeProgramStages,
    328                                        const ProgramLinkedResources &resources,
    329                                        InfoLog &infoLog,
    330                                        GLuint *combinedShaderStorageBlocksCountOut);
    331 }  // namespace gl
    332 
    333 #endif  // LIBANGLE_UNIFORMLINKER_H_