tor-browser

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

AggregateAssignArraysInSSBOs.cpp (3128B)


      1 //
      2 // Copyright 2022 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 #include "compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.h"
      8 
      9 #include "compiler/translator/StaticType.h"
     10 #include "compiler/translator/Symbol.h"
     11 #include "compiler/translator/tree_util/IntermNode_util.h"
     12 #include "compiler/translator/tree_util/IntermTraverse.h"
     13 #include "compiler/translator/util.h"
     14 
     15 namespace sh
     16 {
     17 
     18 namespace
     19 {
     20 
     21 class AggregateAssignArraysInSSBOsTraverser : public TIntermTraverser
     22 {
     23  public:
     24    AggregateAssignArraysInSSBOsTraverser(TSymbolTable *symbolTable)
     25        : TIntermTraverser(true, false, false, symbolTable)
     26    {}
     27 
     28  protected:
     29    bool visitBinary(Visit visit, TIntermBinary *node) override
     30    {
     31        // Replace all aggregate assignments to arrays in SSBOs with element-by-element assignments.
     32        // TODO(anglebug.com/7363): this implementation only works for the simple case (assignment
     33        // statement), not more complex cases such as assignment-as-expression or functions with
     34        // side effects in the RHS.
     35 
     36        if (node->getOp() != EOpAssign)
     37        {
     38            return true;
     39        }
     40        else if (!node->getLeft()->getType().isArray())
     41        {
     42            return true;
     43        }
     44        else if (!IsInShaderStorageBlock(node->getLeft()))
     45        {
     46            return true;
     47        }
     48        const TType *mediumpIndexType = StaticType::Get<EbtInt, EbpMedium, EvqTemporary, 1, 1>();
     49        auto *indexVariable           = CreateTempVariable(mSymbolTable, mediumpIndexType);
     50        auto *indexInit =
     51            CreateTempInitDeclarationNode(indexVariable, CreateZeroNode(indexVariable->getType()));
     52        auto *arraySizeNode   = CreateIndexNode(node->getOutermostArraySize());
     53        auto *indexSymbolNode = CreateTempSymbolNode(indexVariable);
     54        auto *cond = new TIntermBinary(EOpLessThan, indexSymbolNode->deepCopy(), arraySizeNode);
     55        auto *indexIncrement =
     56            new TIntermUnary(EOpPreIncrement, indexSymbolNode->deepCopy(), nullptr);
     57        auto *forLoopBody = new TIntermBlock();
     58        auto *indexedLeft =
     59            new TIntermBinary(EOpIndexDirect, node->getLeft(), indexSymbolNode->deepCopy());
     60        auto *indexedRight =
     61            new TIntermBinary(EOpIndexDirect, node->getRight(), indexSymbolNode->deepCopy());
     62        auto *assign = new TIntermBinary(TOperator::EOpAssign, indexedLeft, indexedRight);
     63        forLoopBody->appendStatement(assign);
     64        auto *forLoop =
     65            new TIntermLoop(ELoopFor, indexInit, cond, indexIncrement, EnsureBlock(forLoopBody));
     66        queueReplacement(forLoop, OriginalNode::IS_DROPPED);
     67        return false;
     68    }
     69 };
     70 
     71 }  // namespace
     72 
     73 bool AggregateAssignArraysInSSBOs(TCompiler *compiler,
     74                                  TIntermBlock *root,
     75                                  TSymbolTable *symbolTable)
     76 {
     77    AggregateAssignArraysInSSBOsTraverser traverser(symbolTable);
     78    root->traverse(&traverser);
     79    return traverser.updateTree(compiler, root);
     80 }
     81 
     82 }  // namespace sh