tor-browser

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

RemoveAtomicCounterBuiltins.cpp (2598B)


      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 // RemoveAtomicCounterBuiltins: Remove atomic counter builtins.
      7 //
      8 
      9 #include "compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.h"
     10 
     11 #include "compiler/translator/Compiler.h"
     12 #include "compiler/translator/tree_util/IntermTraverse.h"
     13 
     14 namespace sh
     15 {
     16 namespace
     17 {
     18 
     19 bool IsAtomicCounterDecl(const TIntermDeclaration *node)
     20 {
     21    const TIntermSequence &sequence = *(node->getSequence());
     22    TIntermTyped *variable          = sequence.front()->getAsTyped();
     23    const TType &type               = variable->getType();
     24    return type.getQualifier() == EvqUniform && type.isAtomicCounter();
     25 }
     26 
     27 // Traverser that removes all GLSL built-ins that use AtomicCounters
     28 // Only called when the builtins are in use, but no atomic counters have been declared
     29 class RemoveAtomicCounterBuiltinsTraverser : public TIntermTraverser
     30 {
     31  public:
     32    RemoveAtomicCounterBuiltinsTraverser() : TIntermTraverser(true, false, false) {}
     33 
     34    bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
     35    {
     36        ASSERT(visit == PreVisit);
     37 
     38        // Active atomic counters should have been removed by RewriteAtomicCounters, and this
     39        // traversal should not have been invoked
     40        ASSERT(!IsAtomicCounterDecl(node));
     41        return false;
     42    }
     43 
     44    bool visitAggregate(Visit visit, TIntermAggregate *node) override
     45    {
     46        if (node->getOp() == EOpMemoryBarrierAtomicCounter)
     47        {
     48            // Vulkan does not support atomic counters, so if this builtin finds its way here,
     49            // we need to remove it.
     50            TIntermSequence emptySequence;
     51            mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
     52                                            std::move(emptySequence));
     53            return true;
     54        }
     55 
     56        // We shouldn't see any other builtins because they cannot be present without an active
     57        // atomic counter, and should have been removed by RewriteAtomicCounters. If this fires,
     58        // this traversal should not have been called.
     59        ASSERT(!(BuiltInGroup::IsBuiltIn(node->getOp()) &&
     60                 node->getFunction()->isAtomicCounterFunction()));
     61 
     62        return false;
     63    }
     64 };
     65 
     66 }  // anonymous namespace
     67 
     68 bool RemoveAtomicCounterBuiltins(TCompiler *compiler, TIntermBlock *root)
     69 {
     70    RemoveAtomicCounterBuiltinsTraverser traverser;
     71    root->traverse(&traverser);
     72    return traverser.updateTree(compiler, root);
     73 }
     74 }  // namespace sh