tor-browser

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

AggregateAssignStructsInSSBOs.cpp (2572B)


      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/AggregateAssignStructsInSSBOs.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 AggregateAssignStructsInSSBOsTraverser : public TIntermTraverser
     22 {
     23  public:
     24    AggregateAssignStructsInSSBOsTraverser(TSymbolTable *symbolTable)
     25        : TIntermTraverser(true, false, false, symbolTable)
     26    {}
     27 
     28  protected:
     29    bool visitBinary(Visit visit, TIntermBinary *node) override
     30    {
     31        // Replace all assignments to structs in SSBOs with field-by-field asignments.
     32        // TODO(anglebug.com/7362): 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        const TStructure *s;
     36        if (node->getOp() != EOpAssign)
     37        {
     38            return true;
     39        }
     40        else if (!IsInShaderStorageBlock(node->getLeft()))
     41        {
     42            return true;
     43        }
     44        else if (!(s = node->getLeft()->getType().getStruct()))
     45        {
     46            return true;
     47        }
     48        ASSERT(node->getRight()->getType().getStruct() == s);
     49        auto *block = new TIntermBlock();
     50        for (int i = 0; i < static_cast<int>(s->fields().size()); ++i)
     51        {
     52            auto *left   = new TIntermBinary(EOpIndexDirectStruct, node->getLeft()->deepCopy(),
     53                                             CreateIndexNode(i));
     54            auto *right  = new TIntermBinary(EOpIndexDirectStruct, node->getRight()->deepCopy(),
     55                                             CreateIndexNode(i));
     56            auto *assign = new TIntermBinary(TOperator::EOpAssign, left, right);
     57            block->appendStatement(assign);
     58        }
     59 
     60        queueReplacement(block, OriginalNode::IS_DROPPED);
     61        return false;
     62    }
     63 };
     64 
     65 }  // namespace
     66 
     67 bool AggregateAssignStructsInSSBOs(TCompiler *compiler,
     68                                   TIntermBlock *root,
     69                                   TSymbolTable *symbolTable)
     70 {
     71    AggregateAssignStructsInSSBOsTraverser traverser(symbolTable);
     72    root->traverse(&traverser);
     73    return traverser.updateTree(compiler, root);
     74 }
     75 
     76 }  // namespace sh