tor-browser

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

EmulateMultiDrawShaderBuiltins.cpp (9974B)


      1 //
      2 // Copyright 2019 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 // EmulateGLDrawID is an AST traverser to convert the gl_DrawID builtin
      7 // to a uniform int
      8 //
      9 // EmulateGLBaseVertex is an AST traverser to convert the gl_BaseVertex builtin
     10 // to a uniform int
     11 //
     12 // EmulateGLBaseInstance is an AST traverser to convert the gl_BaseInstance builtin
     13 // to a uniform int
     14 //
     15 
     16 #include "compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h"
     17 
     18 #include "angle_gl.h"
     19 #include "compiler/translator/StaticType.h"
     20 #include "compiler/translator/Symbol.h"
     21 #include "compiler/translator/SymbolTable.h"
     22 #include "compiler/translator/tree_util/BuiltIn.h"
     23 #include "compiler/translator/tree_util/IntermTraverse.h"
     24 #include "compiler/translator/tree_util/ReplaceVariable.h"
     25 #include "compiler/translator/util.h"
     26 
     27 namespace sh
     28 {
     29 
     30 namespace
     31 {
     32 
     33 constexpr const ImmutableString kEmulatedGLDrawIDName("angle_DrawID");
     34 
     35 class FindGLDrawIDTraverser : public TIntermTraverser
     36 {
     37  public:
     38    FindGLDrawIDTraverser() : TIntermTraverser(true, false, false), mVariable(nullptr) {}
     39 
     40    const TVariable *getGLDrawIDBuiltinVariable() { return mVariable; }
     41 
     42  protected:
     43    void visitSymbol(TIntermSymbol *node) override
     44    {
     45        if (&node->variable() == BuiltInVariable::gl_DrawID())
     46        {
     47            mVariable = &node->variable();
     48        }
     49    }
     50 
     51  private:
     52    const TVariable *mVariable;
     53 };
     54 
     55 class AddBaseVertexToGLVertexIDTraverser : public TIntermTraverser
     56 {
     57  public:
     58    AddBaseVertexToGLVertexIDTraverser() : TIntermTraverser(true, false, false) {}
     59 
     60  protected:
     61    void visitSymbol(TIntermSymbol *node) override
     62    {
     63        if (&node->variable() == BuiltInVariable::gl_VertexID())
     64        {
     65 
     66            TIntermSymbol *baseVertexRef = new TIntermSymbol(BuiltInVariable::gl_BaseVertex());
     67 
     68            TIntermBinary *addBaseVertex = new TIntermBinary(EOpAdd, node, baseVertexRef);
     69            queueReplacement(addBaseVertex, OriginalNode::BECOMES_CHILD);
     70        }
     71    }
     72 };
     73 
     74 constexpr const ImmutableString kEmulatedGLBaseVertexName("angle_BaseVertex");
     75 
     76 class FindGLBaseVertexTraverser : public TIntermTraverser
     77 {
     78  public:
     79    FindGLBaseVertexTraverser() : TIntermTraverser(true, false, false), mVariable(nullptr) {}
     80 
     81    const TVariable *getGLBaseVertexBuiltinVariable() { return mVariable; }
     82 
     83  protected:
     84    void visitSymbol(TIntermSymbol *node) override
     85    {
     86        if (&node->variable() == BuiltInVariable::gl_BaseVertex())
     87        {
     88            mVariable = &node->variable();
     89        }
     90    }
     91 
     92  private:
     93    const TVariable *mVariable;
     94 };
     95 
     96 constexpr const ImmutableString kEmulatedGLBaseInstanceName("angle_BaseInstance");
     97 
     98 class FindGLBaseInstanceTraverser : public TIntermTraverser
     99 {
    100  public:
    101    FindGLBaseInstanceTraverser() : TIntermTraverser(true, false, false), mVariable(nullptr) {}
    102 
    103    const TVariable *getGLBaseInstanceBuiltinVariable() { return mVariable; }
    104 
    105  protected:
    106    void visitSymbol(TIntermSymbol *node) override
    107    {
    108        if (&node->variable() == BuiltInVariable::gl_BaseInstance())
    109        {
    110            mVariable = &node->variable();
    111        }
    112    }
    113 
    114  private:
    115    const TVariable *mVariable;
    116 };
    117 
    118 }  // namespace
    119 
    120 bool EmulateGLDrawID(TCompiler *compiler,
    121                     TIntermBlock *root,
    122                     TSymbolTable *symbolTable,
    123                     std::vector<sh::ShaderVariable> *uniforms,
    124                     bool shouldCollect)
    125 {
    126    FindGLDrawIDTraverser traverser;
    127    root->traverse(&traverser);
    128    const TVariable *builtInVariable = traverser.getGLDrawIDBuiltinVariable();
    129    if (builtInVariable)
    130    {
    131        const TType *type = StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>();
    132        const TVariable *drawID =
    133            new TVariable(symbolTable, kEmulatedGLDrawIDName, type, SymbolType::AngleInternal);
    134        const TIntermSymbol *drawIDSymbol = new TIntermSymbol(drawID);
    135 
    136        // AngleInternal variables don't get collected
    137        if (shouldCollect)
    138        {
    139            ShaderVariable uniform;
    140            uniform.name          = kEmulatedGLDrawIDName.data();
    141            uniform.mappedName    = kEmulatedGLDrawIDName.data();
    142            uniform.type          = GLVariableType(*type);
    143            uniform.precision     = GLVariablePrecision(*type);
    144            uniform.staticUse     = symbolTable->isStaticallyUsed(*builtInVariable);
    145            uniform.active        = true;
    146            uniform.binding       = type->getLayoutQualifier().binding;
    147            uniform.location      = type->getLayoutQualifier().location;
    148            uniform.offset        = type->getLayoutQualifier().offset;
    149            uniform.rasterOrdered = type->getLayoutQualifier().rasterOrdered;
    150            uniform.readonly      = type->getMemoryQualifier().readonly;
    151            uniform.writeonly     = type->getMemoryQualifier().writeonly;
    152            uniforms->push_back(uniform);
    153        }
    154 
    155        DeclareGlobalVariable(root, drawID);
    156        if (!ReplaceVariableWithTyped(compiler, root, builtInVariable, drawIDSymbol))
    157        {
    158            return false;
    159        }
    160    }
    161 
    162    return true;
    163 }
    164 
    165 bool EmulateGLBaseVertexBaseInstance(TCompiler *compiler,
    166                                     TIntermBlock *root,
    167                                     TSymbolTable *symbolTable,
    168                                     std::vector<sh::ShaderVariable> *uniforms,
    169                                     bool shouldCollect,
    170                                     bool addBaseVertexToVertexID)
    171 {
    172    bool addBaseVertex = false, addBaseInstance = false;
    173    ShaderVariable uniformBaseVertex, uniformBaseInstance;
    174 
    175    if (addBaseVertexToVertexID)
    176    {
    177        // This is a workaround for Mac AMD GPU
    178        // Replace gl_VertexID with (gl_VertexID + gl_BaseVertex)
    179        AddBaseVertexToGLVertexIDTraverser traverserVertexID;
    180        root->traverse(&traverserVertexID);
    181        if (!traverserVertexID.updateTree(compiler, root))
    182        {
    183            return false;
    184        }
    185    }
    186 
    187    FindGLBaseVertexTraverser traverserBaseVertex;
    188    root->traverse(&traverserBaseVertex);
    189    const TVariable *builtInVariableBaseVertex =
    190        traverserBaseVertex.getGLBaseVertexBuiltinVariable();
    191 
    192    if (builtInVariableBaseVertex)
    193    {
    194        const TVariable *baseVertex           = BuiltInVariable::angle_BaseVertex();
    195        const TType &type                     = baseVertex->getType();
    196        const TIntermSymbol *baseVertexSymbol = new TIntermSymbol(baseVertex);
    197 
    198        // AngleInternal variables don't get collected
    199        if (shouldCollect)
    200        {
    201            uniformBaseVertex.name       = kEmulatedGLBaseVertexName.data();
    202            uniformBaseVertex.mappedName = kEmulatedGLBaseVertexName.data();
    203            uniformBaseVertex.type       = GLVariableType(type);
    204            uniformBaseVertex.precision  = GLVariablePrecision(type);
    205            uniformBaseVertex.staticUse = symbolTable->isStaticallyUsed(*builtInVariableBaseVertex);
    206            uniformBaseVertex.active    = true;
    207            uniformBaseVertex.binding   = type.getLayoutQualifier().binding;
    208            uniformBaseVertex.location  = type.getLayoutQualifier().location;
    209            uniformBaseVertex.offset    = type.getLayoutQualifier().offset;
    210            uniformBaseVertex.rasterOrdered = type.getLayoutQualifier().rasterOrdered;
    211            uniformBaseVertex.readonly      = type.getMemoryQualifier().readonly;
    212            uniformBaseVertex.writeonly     = type.getMemoryQualifier().writeonly;
    213            addBaseVertex                   = true;
    214        }
    215 
    216        DeclareGlobalVariable(root, baseVertex);
    217        if (!ReplaceVariableWithTyped(compiler, root, builtInVariableBaseVertex, baseVertexSymbol))
    218        {
    219            return false;
    220        }
    221    }
    222 
    223    FindGLBaseInstanceTraverser traverserInstance;
    224    root->traverse(&traverserInstance);
    225    const TVariable *builtInVariableBaseInstance =
    226        traverserInstance.getGLBaseInstanceBuiltinVariable();
    227 
    228    if (builtInVariableBaseInstance)
    229    {
    230        const TVariable *baseInstance           = BuiltInVariable::angle_BaseInstance();
    231        const TType &type                       = baseInstance->getType();
    232        const TIntermSymbol *baseInstanceSymbol = new TIntermSymbol(baseInstance);
    233 
    234        // AngleInternal variables don't get collected
    235        if (shouldCollect)
    236        {
    237            uniformBaseInstance.name       = kEmulatedGLBaseInstanceName.data();
    238            uniformBaseInstance.mappedName = kEmulatedGLBaseInstanceName.data();
    239            uniformBaseInstance.type       = GLVariableType(type);
    240            uniformBaseInstance.precision  = GLVariablePrecision(type);
    241            uniformBaseInstance.staticUse =
    242                symbolTable->isStaticallyUsed(*builtInVariableBaseInstance);
    243            uniformBaseInstance.active        = true;
    244            uniformBaseInstance.binding       = type.getLayoutQualifier().binding;
    245            uniformBaseInstance.location      = type.getLayoutQualifier().location;
    246            uniformBaseInstance.offset        = type.getLayoutQualifier().offset;
    247            uniformBaseInstance.rasterOrdered = type.getLayoutQualifier().rasterOrdered;
    248            uniformBaseInstance.readonly      = type.getMemoryQualifier().readonly;
    249            uniformBaseInstance.writeonly     = type.getMemoryQualifier().writeonly;
    250            addBaseInstance                   = true;
    251        }
    252 
    253        DeclareGlobalVariable(root, baseInstance);
    254        if (!ReplaceVariableWithTyped(compiler, root, builtInVariableBaseInstance,
    255                                      baseInstanceSymbol))
    256        {
    257            return false;
    258        }
    259    }
    260 
    261    // Make sure the order in uniforms is the same as the traverse order
    262    if (addBaseInstance)
    263    {
    264        uniforms->push_back(uniformBaseInstance);
    265    }
    266    if (addBaseVertex)
    267    {
    268        uniforms->push_back(uniformBaseVertex);
    269    }
    270 
    271    return true;
    272 }
    273 
    274 }  // namespace sh