tor-browser

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

VaryingPacking.h (11900B)


      1 //
      2 // Copyright 2015 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 // VaryingPacking:
      7 //   Class which describes a mapping from varyings to registers, according
      8 //   to the spec, or using custom packing algorithms. We also keep a register
      9 //   allocation list for the D3D renderer.
     10 //
     11 
     12 #ifndef LIBANGLE_VARYINGPACKING_H_
     13 #define LIBANGLE_VARYINGPACKING_H_
     14 
     15 #include <GLSLANG/ShaderVars.h>
     16 
     17 #include "angle_gl.h"
     18 #include "common/angleutils.h"
     19 #include "libANGLE/angletypes.h"
     20 
     21 #include <map>
     22 
     23 namespace gl
     24 {
     25 class InfoLog;
     26 class ProgramExecutable;
     27 struct Caps;
     28 struct LinkingVariables;
     29 struct ProgramVaryingRef;
     30 
     31 using ProgramMergedVaryings = std::vector<ProgramVaryingRef>;
     32 
     33 // A varying can have different names between stages if matched by the location layout qualifier.
     34 // Additionally, same name varyings could still be of two identical struct types with different
     35 // names.  This struct contains information on the varying in one of the two stages.  PackedVarying
     36 // will thus contain two copies of this along with common information, such as interpolation or
     37 // field index.
     38 struct VaryingInShaderRef : angle::NonCopyable
     39 {
     40    VaryingInShaderRef(ShaderType stageIn, const sh::ShaderVariable *varyingIn);
     41    VaryingInShaderRef(VaryingInShaderRef &&other);
     42    ~VaryingInShaderRef();
     43 
     44    VaryingInShaderRef &operator=(VaryingInShaderRef &&other);
     45 
     46    const sh::ShaderVariable *varying;
     47 
     48    ShaderType stage;
     49 
     50    // Struct name
     51    std::string parentStructName;
     52    std::string parentStructMappedName;
     53 };
     54 
     55 struct PackedVarying : angle::NonCopyable
     56 {
     57    // Throughout this file, the "front" stage refers to the stage that outputs the varying, and the
     58    // "back" stage refers to the stage that takes the varying as input.  Note that this struct
     59    // contains linked varyings, which means both front and back stage varyings are valid, except
     60    // for the following which may have only one valid stage.
     61    //
     62    //  - transform-feedback-captured varyings
     63    //  - builtins
     64    //  - separable program stages,
     65    //
     66    PackedVarying(VaryingInShaderRef &&frontVaryingIn,
     67                  VaryingInShaderRef &&backVaryingIn,
     68                  sh::InterpolationType interpolationIn);
     69    PackedVarying(VaryingInShaderRef &&frontVaryingIn,
     70                  VaryingInShaderRef &&backVaryingIn,
     71                  sh::InterpolationType interpolationIn,
     72                  GLuint arrayIndexIn,
     73                  GLuint fieldIndexIn,
     74                  GLuint secondaryFieldIndexIn);
     75    PackedVarying(PackedVarying &&other);
     76    ~PackedVarying();
     77 
     78    PackedVarying &operator=(PackedVarying &&other);
     79 
     80    bool isStructField() const
     81    {
     82        return frontVarying.varying ? !frontVarying.parentStructName.empty()
     83                                    : !backVarying.parentStructName.empty();
     84    }
     85 
     86    bool isTransformFeedbackArrayElement() const
     87    {
     88        return isTransformFeedback && arrayIndex != GL_INVALID_INDEX;
     89    }
     90 
     91    // Return either front or back varying, whichever is available.  Only used when the name of the
     92    // varying is not important, but only the type is interesting.
     93    const sh::ShaderVariable &varying() const
     94    {
     95        return frontVarying.varying ? *frontVarying.varying : *backVarying.varying;
     96    }
     97 
     98    const std::string &getParentStructName() const
     99    {
    100        ASSERT(isStructField());
    101        return frontVarying.varying ? frontVarying.parentStructName : backVarying.parentStructName;
    102    }
    103 
    104    std::string fullName(ShaderType stage) const
    105    {
    106        ASSERT(stage == frontVarying.stage || stage == backVarying.stage);
    107        const VaryingInShaderRef &varying =
    108            stage == frontVarying.stage ? frontVarying : backVarying;
    109 
    110        std::stringstream fullNameStr;
    111        if (isStructField())
    112        {
    113            fullNameStr << varying.parentStructName << ".";
    114        }
    115 
    116        fullNameStr << varying.varying->name;
    117        if (arrayIndex != GL_INVALID_INDEX)
    118        {
    119            fullNameStr << "[" << arrayIndex << "]";
    120        }
    121        return fullNameStr.str();
    122    }
    123 
    124    // Transform feedback varyings can be only referenced in the VS.
    125    bool vertexOnly() const
    126    {
    127        return frontVarying.stage == ShaderType::Vertex && backVarying.varying == nullptr;
    128    }
    129 
    130    // Special handling for GS/TS array inputs.
    131    unsigned int getBasicTypeElementCount() const;
    132 
    133    VaryingInShaderRef frontVarying;
    134    VaryingInShaderRef backVarying;
    135 
    136    // Cached so we can store sh::ShaderVariable to point to varying fields.
    137    sh::InterpolationType interpolation;
    138 
    139    // Used by varyings that are captured with transform feedback, xor arrays of shader I/O blocks,
    140    // distinguished by isTransformFeedback;
    141    GLuint arrayIndex;
    142    bool isTransformFeedback;
    143 
    144    // Field index in the struct.  In Vulkan, this is used to assign a
    145    // struct-typed varying location to the location of its first field.
    146    GLuint fieldIndex;
    147    GLuint secondaryFieldIndex;
    148 };
    149 
    150 struct PackedVaryingRegister final
    151 {
    152    PackedVaryingRegister()
    153        : packedVarying(nullptr),
    154          varyingArrayIndex(0),
    155          varyingRowIndex(0),
    156          registerRow(0),
    157          registerColumn(0)
    158    {}
    159 
    160    PackedVaryingRegister(const PackedVaryingRegister &)            = default;
    161    PackedVaryingRegister &operator=(const PackedVaryingRegister &) = default;
    162 
    163    bool operator<(const PackedVaryingRegister &other) const
    164    {
    165        return sortOrder() < other.sortOrder();
    166    }
    167 
    168    unsigned int sortOrder() const
    169    {
    170        // TODO(jmadill): Handle interpolation types
    171        return registerRow * 4 + registerColumn;
    172    }
    173 
    174    std::string tfVaryingName() const
    175    {
    176        return packedVarying->fullName(packedVarying->frontVarying.stage);
    177    }
    178 
    179    // Index to the array of varyings.
    180    const PackedVarying *packedVarying;
    181 
    182    // The array element of the packed varying.
    183    unsigned int varyingArrayIndex;
    184 
    185    // The row of the array element of the packed varying.
    186    unsigned int varyingRowIndex;
    187 
    188    // The register row to which we've assigned this packed varying.
    189    unsigned int registerRow;
    190 
    191    // The column of the register row into which we've packed this varying.
    192    unsigned int registerColumn;
    193 };
    194 
    195 // Supported packing modes:
    196 enum class PackMode
    197 {
    198    // We treat mat2 arrays as taking two full rows.
    199    WEBGL_STRICT,
    200 
    201    // We allow mat2 to take a 2x2 chunk.
    202    ANGLE_RELAXED,
    203 
    204    // Each varying takes a separate register. No register sharing.
    205    ANGLE_NON_CONFORMANT_D3D9,
    206 };
    207 
    208 class VaryingPacking final : angle::NonCopyable
    209 {
    210  public:
    211    VaryingPacking();
    212    ~VaryingPacking();
    213 
    214    [[nodiscard]] bool collectAndPackUserVaryings(InfoLog &infoLog,
    215                                                  GLint maxVaryingVectors,
    216                                                  PackMode packMode,
    217                                                  ShaderType frontShaderStage,
    218                                                  ShaderType backShaderStage,
    219                                                  const ProgramMergedVaryings &mergedVaryings,
    220                                                  const std::vector<std::string> &tfVaryings,
    221                                                  const bool isSeparableProgram);
    222 
    223    struct Register
    224    {
    225        Register() { data[0] = data[1] = data[2] = data[3] = false; }
    226 
    227        bool &operator[](unsigned int index) { return data[index]; }
    228        bool operator[](unsigned int index) const { return data[index]; }
    229 
    230        bool data[4];
    231    };
    232 
    233    Register &operator[](unsigned int index) { return mRegisterMap[index]; }
    234    const Register &operator[](unsigned int index) const { return mRegisterMap[index]; }
    235 
    236    const std::vector<PackedVaryingRegister> &getRegisterList() const { return mRegisterList; }
    237    unsigned int getMaxSemanticIndex() const
    238    {
    239        return static_cast<unsigned int>(mRegisterList.size());
    240    }
    241 
    242    const ShaderMap<std::vector<std::string>> &getInactiveVaryingMappedNames() const
    243    {
    244        return mInactiveVaryingMappedNames;
    245    }
    246 
    247    const ShaderMap<std::vector<std::string>> &getActiveOutputBuiltInNames() const
    248    {
    249        return mActiveOutputBuiltIns;
    250    }
    251 
    252    void reset();
    253 
    254  private:
    255    using VaryingUniqueFullNames = ShaderMap<std::set<std::string>>;
    256 
    257    // Register map functions.
    258    bool packUserVaryings(InfoLog &infoLog,
    259                          GLint maxVaryingVectors,
    260                          PackMode packMode,
    261                          const std::vector<PackedVarying> &packedVaryings);
    262    bool packVaryingIntoRegisterMap(PackMode packMode, const PackedVarying &packedVarying);
    263    bool isRegisterRangeFree(unsigned int registerRow,
    264                             unsigned int registerColumn,
    265                             unsigned int varyingRows,
    266                             unsigned int varyingColumns) const;
    267    void insertVaryingIntoRegisterMap(unsigned int registerRow,
    268                                      unsigned int registerColumn,
    269                                      unsigned int varyingColumns,
    270                                      const PackedVarying &packedVarying);
    271    void clearRegisterMap();
    272 
    273    // Collection functions.
    274    void collectUserVarying(const ProgramVaryingRef &ref, VaryingUniqueFullNames *uniqueFullNames);
    275    void collectUserVaryingField(const ProgramVaryingRef &ref,
    276                                 GLuint arrayIndex,
    277                                 GLuint fieldIndex,
    278                                 GLuint secondaryFieldIndex,
    279                                 VaryingUniqueFullNames *uniqueFullNames);
    280    void collectUserVaryingTF(const ProgramVaryingRef &ref, size_t subscript);
    281    void collectUserVaryingFieldTF(const ProgramVaryingRef &ref,
    282                                   const sh::ShaderVariable &field,
    283                                   GLuint fieldIndex,
    284                                   GLuint secondaryFieldIndex);
    285    void collectVarying(const sh::ShaderVariable &varying,
    286                        const ProgramVaryingRef &ref,
    287                        PackMode packMode,
    288                        VaryingUniqueFullNames *uniqueFullNames);
    289    void collectTFVarying(const std::string &tfVarying,
    290                          const ProgramVaryingRef &ref,
    291                          VaryingUniqueFullNames *uniqueFullNames);
    292 
    293    std::vector<Register> mRegisterMap;
    294    std::vector<PackedVaryingRegister> mRegisterList;
    295    std::vector<PackedVarying> mPackedVaryings;
    296    ShaderMap<std::vector<std::string>> mInactiveVaryingMappedNames;
    297    ShaderMap<std::vector<std::string>> mActiveOutputBuiltIns;
    298 };
    299 
    300 class ProgramVaryingPacking final : angle::NonCopyable
    301 {
    302  public:
    303    ProgramVaryingPacking();
    304    ~ProgramVaryingPacking();
    305 
    306    const VaryingPacking &getInputPacking(ShaderType backShaderStage) const;
    307    const VaryingPacking &getOutputPacking(ShaderType frontShaderStage) const;
    308 
    309    [[nodiscard]] bool collectAndPackUserVaryings(InfoLog &infoLog,
    310                                                  const Caps &caps,
    311                                                  PackMode packMode,
    312                                                  const ShaderBitSet &activeShadersMask,
    313                                                  const ProgramMergedVaryings &mergedVaryings,
    314                                                  const std::vector<std::string> &tfVaryings,
    315                                                  bool isSeparableProgram);
    316 
    317  private:
    318    // Indexed by the front shader.
    319    ShaderMap<VaryingPacking> mVaryingPackings;
    320 
    321    // Looks up the front stage from the back stage.
    322    ShaderMap<ShaderType> mBackToFrontStageMap;
    323 };
    324 
    325 ProgramMergedVaryings GetMergedVaryingsFromLinkingVariables(
    326    const LinkingVariables &linkingVariables);
    327 }  // namespace gl
    328 
    329 #endif  // LIBANGLE_VARYINGPACKING_H_