tor-browser

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

RewriteSampleMaskVariable.cpp (6909B)


      1 //
      2 // Copyright 2020 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 // RewriteSampleMaskVariable.cpp: Find any references to gl_SampleMask and gl_SampleMaskIn, and
      7 // rewrite it with ANGLESampleMask or ANGLESampleMaskIn.
      8 //
      9 
     10 #include "compiler/translator/tree_util/RewriteSampleMaskVariable.h"
     11 
     12 #include "common/bitset_utils.h"
     13 #include "common/debug.h"
     14 #include "common/utilities.h"
     15 #include "compiler/translator/Compiler.h"
     16 #include "compiler/translator/SymbolTable.h"
     17 #include "compiler/translator/tree_util/BuiltIn.h"
     18 #include "compiler/translator/tree_util/IntermNode_util.h"
     19 #include "compiler/translator/tree_util/IntermTraverse.h"
     20 #include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
     21 
     22 namespace sh
     23 {
     24 namespace
     25 {
     26 constexpr int kMaxIndexForSampleMaskVar = 0;
     27 constexpr int kFullSampleMask           = 0xFFFFFFFF;
     28 
     29 // Traverse the tree and collect the redeclaration and replace all non constant index references of
     30 // gl_SampleMask or gl_SampleMaskIn with constant index references
     31 class GLSampleMaskRelatedReferenceTraverser : public TIntermTraverser
     32 {
     33  public:
     34    GLSampleMaskRelatedReferenceTraverser(const TIntermSymbol **redeclaredSymOut,
     35                                          const ImmutableString &targetStr)
     36        : TIntermTraverser(true, false, false),
     37          mRedeclaredSym(redeclaredSymOut),
     38          mTargetStr(targetStr)
     39    {
     40        *mRedeclaredSym = nullptr;
     41    }
     42 
     43    bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
     44    {
     45        // If gl_SampleMask is redeclared, we need to collect its information
     46        const TIntermSequence &sequence = *(node->getSequence());
     47 
     48        if (sequence.size() != 1)
     49        {
     50            return true;
     51        }
     52 
     53        TIntermTyped *variable = sequence.front()->getAsTyped();
     54        TIntermSymbol *symbol  = variable->getAsSymbolNode();
     55        if (symbol == nullptr || symbol->getName() != mTargetStr)
     56        {
     57            return true;
     58        }
     59 
     60        *mRedeclaredSym = symbol;
     61 
     62        return true;
     63    }
     64 
     65    bool visitBinary(Visit visit, TIntermBinary *node) override
     66    {
     67        TOperator op = node->getOp();
     68        if (op != EOpIndexDirect && op != EOpIndexIndirect)
     69        {
     70            return true;
     71        }
     72        TIntermSymbol *left = node->getLeft()->getAsSymbolNode();
     73        if (!left)
     74        {
     75            return true;
     76        }
     77        if (left->getName() != mTargetStr)
     78        {
     79            return true;
     80        }
     81        const TConstantUnion *constIdx = node->getRight()->getConstantValue();
     82        if (!constIdx)
     83        {
     84            if (node->getRight()->hasSideEffects())
     85            {
     86                insertStatementInParentBlock(node->getRight());
     87            }
     88 
     89            queueReplacementWithParent(node, node->getRight(),
     90                                       CreateIndexNode(kMaxIndexForSampleMaskVar),
     91                                       OriginalNode::IS_DROPPED);
     92        }
     93 
     94        return true;
     95    }
     96 
     97  private:
     98    const TIntermSymbol **mRedeclaredSym;
     99    const ImmutableString mTargetStr;
    100 };
    101 
    102 }  // anonymous namespace
    103 
    104 [[nodiscard]] bool RewriteSampleMask(TCompiler *compiler,
    105                                     TIntermBlock *root,
    106                                     TSymbolTable *symbolTable,
    107                                     const TIntermTyped *numSamplesUniform)
    108 {
    109    const TIntermSymbol *redeclaredGLSampleMask = nullptr;
    110    GLSampleMaskRelatedReferenceTraverser indexTraverser(&redeclaredGLSampleMask,
    111                                                         ImmutableString("gl_SampleMask"));
    112 
    113    root->traverse(&indexTraverser);
    114    if (!indexTraverser.updateTree(compiler, root))
    115    {
    116        return false;
    117    }
    118 
    119    // Retrieve gl_SampleMask variable reference
    120    // Search user redeclared it first
    121    const TVariable *glSampleMaskVar = nullptr;
    122    if (redeclaredGLSampleMask)
    123    {
    124        glSampleMaskVar = &redeclaredGLSampleMask->variable();
    125    }
    126    else
    127    {
    128        // User defined not found, find in built-in table
    129        glSampleMaskVar = static_cast<const TVariable *>(symbolTable->findBuiltIn(
    130            ImmutableString("gl_SampleMask"), compiler->getShaderVersion()));
    131    }
    132    if (!glSampleMaskVar)
    133    {
    134        return false;
    135    }
    136 
    137    // Current ANGLE assumes that the maximum number of samples is less than or equal to
    138    // VK_SAMPLE_COUNT_32_BIT. So, the size of gl_SampleMask array is always one.
    139    const unsigned int arraySizeOfSampleMask = glSampleMaskVar->getType().getOutermostArraySize();
    140    ASSERT(arraySizeOfSampleMask == 1);
    141 
    142    TIntermSymbol *glSampleMaskSymbol = new TIntermSymbol(glSampleMaskVar);
    143 
    144    // if (ANGLEUniforms.numSamples == 1)
    145    // {
    146    //     gl_SampleMask[0] = int(0xFFFFFFFF);
    147    // }
    148    TIntermConstantUnion *singleSampleCount = CreateUIntNode(1);
    149    TIntermBinary *equalTo =
    150        new TIntermBinary(EOpEqual, numSamplesUniform->deepCopy(), singleSampleCount);
    151 
    152    TIntermBlock *trueBlock = new TIntermBlock();
    153 
    154    TIntermBinary *sampleMaskVar = new TIntermBinary(EOpIndexDirect, glSampleMaskSymbol->deepCopy(),
    155                                                     CreateIndexNode(kMaxIndexForSampleMaskVar));
    156    TIntermConstantUnion *fullSampleMask = CreateIndexNode(kFullSampleMask);
    157    TIntermBinary *assignment = new TIntermBinary(EOpAssign, sampleMaskVar, fullSampleMask);
    158 
    159    trueBlock->appendStatement(assignment);
    160 
    161    TIntermIfElse *multiSampleOrNot = new TIntermIfElse(equalTo, trueBlock, nullptr);
    162 
    163    return RunAtTheEndOfShader(compiler, root, multiSampleOrNot, symbolTable);
    164 }
    165 
    166 [[nodiscard]] bool RewriteSampleMaskIn(TCompiler *compiler,
    167                                       TIntermBlock *root,
    168                                       TSymbolTable *symbolTable)
    169 {
    170    const TIntermSymbol *redeclaredGLSampleMaskIn = nullptr;
    171    GLSampleMaskRelatedReferenceTraverser indexTraverser(&redeclaredGLSampleMaskIn,
    172                                                         ImmutableString("gl_SampleMaskIn"));
    173 
    174    root->traverse(&indexTraverser);
    175    if (!indexTraverser.updateTree(compiler, root))
    176    {
    177        return false;
    178    }
    179 
    180    // Retrieve gl_SampleMaskIn variable reference
    181    const TVariable *glSampleMaskInVar = nullptr;
    182    glSampleMaskInVar                  = static_cast<const TVariable *>(
    183        symbolTable->findBuiltIn(ImmutableString("gl_SampleMaskIn"), compiler->getShaderVersion()));
    184    if (!glSampleMaskInVar)
    185    {
    186        return false;
    187    }
    188 
    189    // Current ANGLE assumes that the maximum number of samples is less than or equal to
    190    // VK_SAMPLE_COUNT_32_BIT. So, the size of gl_SampleMask array is always one.
    191    const unsigned int arraySizeOfSampleMaskIn =
    192        glSampleMaskInVar->getType().getOutermostArraySize();
    193    ASSERT(arraySizeOfSampleMaskIn == 1);
    194 
    195    return true;
    196 }
    197 
    198 }  // namespace sh