diff options
Diffstat (limited to '')
-rw-r--r-- | gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.cpp | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.cpp new file mode 100644 index 0000000000..ed0ba3fed8 --- /dev/null +++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.cpp @@ -0,0 +1,74 @@ +// +// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RemoveAtomicCounterBuiltins: Remove atomic counter builtins. +// + +#include "compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.h" + +#include "compiler/translator/Compiler.h" +#include "compiler/translator/tree_util/IntermTraverse.h" + +namespace sh +{ +namespace +{ + +bool IsAtomicCounterDecl(const TIntermDeclaration *node) +{ + const TIntermSequence &sequence = *(node->getSequence()); + TIntermTyped *variable = sequence.front()->getAsTyped(); + const TType &type = variable->getType(); + return type.getQualifier() == EvqUniform && type.isAtomicCounter(); +} + +// Traverser that removes all GLSL built-ins that use AtomicCounters +// Only called when the builtins are in use, but no atomic counters have been declared +class RemoveAtomicCounterBuiltinsTraverser : public TIntermTraverser +{ + public: + RemoveAtomicCounterBuiltinsTraverser() : TIntermTraverser(true, false, false) {} + + bool visitDeclaration(Visit visit, TIntermDeclaration *node) override + { + ASSERT(visit == PreVisit); + + // Active atomic counters should have been removed by RewriteAtomicCounters, and this + // traversal should not have been invoked + ASSERT(!IsAtomicCounterDecl(node)); + return false; + } + + bool visitAggregate(Visit visit, TIntermAggregate *node) override + { + if (node->getOp() == EOpMemoryBarrierAtomicCounter) + { + // Vulkan does not support atomic counters, so if this builtin finds its way here, + // we need to remove it. + TIntermSequence emptySequence; + mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node, + std::move(emptySequence)); + return true; + } + + // We shouldn't see any other builtins because they cannot be present without an active + // atomic counter, and should have been removed by RewriteAtomicCounters. If this fires, + // this traversal should not have been called. + ASSERT(!(BuiltInGroup::IsBuiltIn(node->getOp()) && + node->getFunction()->isAtomicCounterFunction())); + + return false; + } +}; + +} // anonymous namespace + +bool RemoveAtomicCounterBuiltins(TCompiler *compiler, TIntermBlock *root) +{ + RemoveAtomicCounterBuiltinsTraverser traverser; + root->traverse(&traverser); + return traverser.updateTree(compiler, root); +} +} // namespace sh |