blob: 6e09c785a459026a8088226efb54a4d43439928c [file] [log] [blame]
//
// 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/vulkan/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(!(node->getOp() == EOpCallBuiltInFunction &&
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