tor-browser

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

blocklayout.h (12022B)


      1 //
      2 // Copyright 2013 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 // blocklayout.h:
      7 //   Methods and classes related to uniform layout and packing in GLSL and HLSL.
      8 //
      9 
     10 #ifndef COMMON_BLOCKLAYOUT_H_
     11 #define COMMON_BLOCKLAYOUT_H_
     12 
     13 #include <cstddef>
     14 #include <map>
     15 #include <vector>
     16 
     17 #include <GLSLANG/ShaderLang.h>
     18 #include "angle_gl.h"
     19 
     20 namespace sh
     21 {
     22 struct ShaderVariable;
     23 struct InterfaceBlock;
     24 
     25 struct BlockMemberInfo
     26 {
     27    constexpr BlockMemberInfo() = default;
     28 
     29    constexpr BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
     30        : offset(offset),
     31          arrayStride(arrayStride),
     32          matrixStride(matrixStride),
     33          isRowMajorMatrix(isRowMajorMatrix)
     34    {}
     35 
     36    constexpr BlockMemberInfo(int offset,
     37                              int arrayStride,
     38                              int matrixStride,
     39                              bool isRowMajorMatrix,
     40                              int topLevelArrayStride)
     41        : offset(offset),
     42          arrayStride(arrayStride),
     43          matrixStride(matrixStride),
     44          isRowMajorMatrix(isRowMajorMatrix),
     45          topLevelArrayStride(topLevelArrayStride)
     46    {}
     47 
     48    // A single integer identifying the offset of an active variable.
     49    int offset = -1;
     50 
     51    // A single integer identifying the stride between array elements in an active variable.
     52    int arrayStride = -1;
     53 
     54    // A single integer identifying the stride between columns of a column-major matrix or rows of a
     55    // row-major matrix.
     56    int matrixStride = -1;
     57 
     58    // A single integer identifying whether an active variable is a row-major matrix.
     59    bool isRowMajorMatrix = false;
     60 
     61    // A single integer identifying the number of active array elements of the top-level shader
     62    // storage block member containing the active variable.
     63    int topLevelArrayStride = -1;
     64 };
     65 
     66 constexpr size_t ComponentAlignment(size_t numComponents)
     67 {
     68    return (numComponents == 3u ? 4u : numComponents);
     69 }
     70 
     71 constexpr BlockMemberInfo kDefaultBlockMemberInfo;
     72 
     73 class BlockLayoutEncoder
     74 {
     75  public:
     76    BlockLayoutEncoder();
     77    virtual ~BlockLayoutEncoder() {}
     78 
     79    BlockMemberInfo encodeType(GLenum type,
     80                               const std::vector<unsigned int> &arraySizes,
     81                               bool isRowMajorMatrix);
     82    // Advance the offset based on struct size and array dimensions.  Size can be calculated with
     83    // getShaderVariableSize() or equivalent.  |enterAggregateType|/|exitAggregateType| is necessary
     84    // around this call.
     85    BlockMemberInfo encodeArrayOfPreEncodedStructs(size_t size,
     86                                                   const std::vector<unsigned int> &arraySizes);
     87 
     88    size_t getCurrentOffset() const;
     89    size_t getShaderVariableSize(const ShaderVariable &structVar, bool isRowMajor);
     90 
     91    // Called when entering/exiting a structure variable.
     92    virtual void enterAggregateType(const ShaderVariable &structVar) = 0;
     93    virtual void exitAggregateType(const ShaderVariable &structVar)  = 0;
     94 
     95    static constexpr size_t kBytesPerComponent           = 4u;
     96    static constexpr unsigned int kComponentsPerRegister = 4u;
     97 
     98    static size_t GetBlockRegister(const BlockMemberInfo &info);
     99    static size_t GetBlockRegisterElement(const BlockMemberInfo &info);
    100 
    101  protected:
    102    void align(size_t baseAlignment);
    103 
    104    virtual void getBlockLayoutInfo(GLenum type,
    105                                    const std::vector<unsigned int> &arraySizes,
    106                                    bool isRowMajorMatrix,
    107                                    int *arrayStrideOut,
    108                                    int *matrixStrideOut) = 0;
    109    virtual void advanceOffset(GLenum type,
    110                               const std::vector<unsigned int> &arraySizes,
    111                               bool isRowMajorMatrix,
    112                               int arrayStride,
    113                               int matrixStride)          = 0;
    114 
    115    size_t mCurrentOffset;
    116 };
    117 
    118 // Will return default values for everything.
    119 class StubBlockEncoder : public BlockLayoutEncoder
    120 {
    121  public:
    122    StubBlockEncoder() = default;
    123 
    124    void enterAggregateType(const ShaderVariable &structVar) override {}
    125    void exitAggregateType(const ShaderVariable &structVar) override {}
    126 
    127  protected:
    128    void getBlockLayoutInfo(GLenum type,
    129                            const std::vector<unsigned int> &arraySizes,
    130                            bool isRowMajorMatrix,
    131                            int *arrayStrideOut,
    132                            int *matrixStrideOut) override;
    133 
    134    void advanceOffset(GLenum type,
    135                       const std::vector<unsigned int> &arraySizes,
    136                       bool isRowMajorMatrix,
    137                       int arrayStride,
    138                       int matrixStride) override
    139    {}
    140 };
    141 
    142 // Block layout according to the std140 block layout
    143 // See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification
    144 
    145 class Std140BlockEncoder : public BlockLayoutEncoder
    146 {
    147  public:
    148    Std140BlockEncoder();
    149 
    150    void enterAggregateType(const ShaderVariable &structVar) override;
    151    void exitAggregateType(const ShaderVariable &structVar) override;
    152 
    153  protected:
    154    void getBlockLayoutInfo(GLenum type,
    155                            const std::vector<unsigned int> &arraySizes,
    156                            bool isRowMajorMatrix,
    157                            int *arrayStrideOut,
    158                            int *matrixStrideOut) override;
    159    void advanceOffset(GLenum type,
    160                       const std::vector<unsigned int> &arraySizes,
    161                       bool isRowMajorMatrix,
    162                       int arrayStride,
    163                       int matrixStride) override;
    164 
    165    virtual size_t getBaseAlignment(const ShaderVariable &variable) const;
    166    virtual size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const;
    167 };
    168 
    169 class Std430BlockEncoder : public Std140BlockEncoder
    170 {
    171  public:
    172    Std430BlockEncoder();
    173 
    174  protected:
    175    size_t getBaseAlignment(const ShaderVariable &variable) const override;
    176    size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const override;
    177 };
    178 
    179 using BlockLayoutMap = std::map<std::string, BlockMemberInfo>;
    180 
    181 void GetInterfaceBlockInfo(const std::vector<ShaderVariable> &fields,
    182                           const std::string &prefix,
    183                           BlockLayoutEncoder *encoder,
    184                           BlockLayoutMap *blockInfoOut);
    185 
    186 // Used for laying out the default uniform block on the Vulkan backend.
    187 void GetActiveUniformBlockInfo(const std::vector<ShaderVariable> &uniforms,
    188                               const std::string &prefix,
    189                               BlockLayoutEncoder *encoder,
    190                               BlockLayoutMap *blockInfoOut);
    191 
    192 class ShaderVariableVisitor
    193 {
    194  public:
    195    virtual ~ShaderVariableVisitor() {}
    196 
    197    virtual void enterStruct(const ShaderVariable &structVar) {}
    198    virtual void exitStruct(const ShaderVariable &structVar) {}
    199 
    200    virtual void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) {}
    201    virtual void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) {}
    202 
    203    virtual void enterArray(const ShaderVariable &arrayVar) {}
    204    virtual void exitArray(const ShaderVariable &arrayVar) {}
    205 
    206    virtual void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) {}
    207    virtual void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) {}
    208 
    209    virtual void visitOpaqueObject(const sh::ShaderVariable &variable) {}
    210 
    211    virtual void visitVariable(const ShaderVariable &variable, bool isRowMajor) = 0;
    212 
    213  protected:
    214    ShaderVariableVisitor() {}
    215 };
    216 
    217 class VariableNameVisitor : public ShaderVariableVisitor
    218 {
    219  public:
    220    VariableNameVisitor(const std::string &namePrefix, const std::string &mappedNamePrefix);
    221    ~VariableNameVisitor() override;
    222 
    223    void enterStruct(const ShaderVariable &structVar) override;
    224    void exitStruct(const ShaderVariable &structVar) override;
    225    void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
    226    void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
    227    void enterArray(const ShaderVariable &arrayVar) override;
    228    void exitArray(const ShaderVariable &arrayVar) override;
    229    void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
    230    void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
    231 
    232  protected:
    233    virtual void visitNamedOpaqueObject(const sh::ShaderVariable &variable,
    234                                        const std::string &name,
    235                                        const std::string &mappedName,
    236                                        const std::vector<unsigned int> &arraySizes)
    237    {}
    238    virtual void visitNamedVariable(const ShaderVariable &variable,
    239                                    bool isRowMajor,
    240                                    const std::string &name,
    241                                    const std::string &mappedName,
    242                                    const std::vector<unsigned int> &arraySizes) = 0;
    243 
    244    std::string collapseNameStack() const;
    245    std::string collapseMappedNameStack() const;
    246 
    247  private:
    248    void visitOpaqueObject(const sh::ShaderVariable &variable) final;
    249    void visitVariable(const ShaderVariable &variable, bool isRowMajor) final;
    250 
    251    std::vector<std::string> mNameStack;
    252    std::vector<std::string> mMappedNameStack;
    253    std::vector<unsigned int> mArraySizeStack;
    254 };
    255 
    256 class BlockEncoderVisitor : public VariableNameVisitor
    257 {
    258  public:
    259    BlockEncoderVisitor(const std::string &namePrefix,
    260                        const std::string &mappedNamePrefix,
    261                        BlockLayoutEncoder *encoder);
    262    ~BlockEncoderVisitor() override;
    263 
    264    void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
    265    void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
    266    void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
    267    void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
    268 
    269    void visitNamedVariable(const ShaderVariable &variable,
    270                            bool isRowMajor,
    271                            const std::string &name,
    272                            const std::string &mappedName,
    273                            const std::vector<unsigned int> &arraySizes) override;
    274 
    275    virtual void encodeVariable(const ShaderVariable &variable,
    276                                const BlockMemberInfo &variableInfo,
    277                                const std::string &name,
    278                                const std::string &mappedName)
    279    {}
    280 
    281  protected:
    282    int mTopLevelArraySize           = 1;
    283    int mTopLevelArrayStride         = 0;
    284    bool mIsTopLevelArrayStrideReady = true;
    285    bool mSkipEnabled                = false;
    286 
    287  private:
    288    BlockLayoutEncoder *mEncoder;
    289    unsigned int mStructStackSize = 0;
    290 };
    291 
    292 void TraverseShaderVariable(const ShaderVariable &variable,
    293                            bool isRowMajorLayout,
    294                            ShaderVariableVisitor *visitor);
    295 
    296 template <typename T>
    297 void TraverseShaderVariables(const std::vector<T> &vars,
    298                             bool isRowMajorLayout,
    299                             ShaderVariableVisitor *visitor)
    300 {
    301    for (const T &var : vars)
    302    {
    303        TraverseShaderVariable(var, isRowMajorLayout, visitor);
    304    }
    305 }
    306 
    307 template <typename T>
    308 void TraverseActiveShaderVariables(const std::vector<T> &vars,
    309                                   bool isRowMajorLayout,
    310                                   ShaderVariableVisitor *visitor)
    311 {
    312    for (const T &var : vars)
    313    {
    314        if (var.active)
    315        {
    316            TraverseShaderVariable(var, isRowMajorLayout, visitor);
    317        }
    318    }
    319 }
    320 }  // namespace sh
    321 
    322 #endif  // COMMON_BLOCKLAYOUT_H_