Hash :
a2f9ad39
Author :
Date :
2020-03-09T14:28:39
Vulkan: Remove unused atomic counter builtins Atomic counters are not supported by Vulkan. Most are already converted by the RewriteAtomicCounters traversal, but that is only invoked when atomic counters are active. This CL introduces another pass that removes any atomic counter builtin that was not handled by the previous pass. It also will assert if it sees any atomic counters active, thus ensuring it is only used when needed. Test: KHR-GLES31.core.compute_shader.shared-struct Test: angle_end2end_tests.exe --gtest_filter="*AtomicCounter*" Bug: angleproject:4189 Bug: b:150310216 Change-Id: I61d10e954886dc94fede8b344f5a0ede3b689adb Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2095688 Commit-Queue: Cody Northrop <cnorthrop@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
//
// 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, 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