Path: blob/main_old/src/compiler/translator/AtomicCounterFunctionHLSL.cpp
1693 views
//1// Copyright 2018 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// AtomicCounterFunctionHLSL: Class for writing implementation of atomic counter functions into HLSL6// output.7//89#include "compiler/translator/AtomicCounterFunctionHLSL.h"1011#include "compiler/translator/Common.h"12#include "compiler/translator/ImmutableStringBuilder.h"13#include "compiler/translator/InfoSink.h"14#include "compiler/translator/IntermNode.h"1516namespace sh17{1819namespace20{21constexpr ImmutableString kAtomicCounter("atomicCounter");22constexpr ImmutableString kAtomicCounterIncrement("atomicCounterIncrement");23constexpr ImmutableString kAtomicCounterDecrement("atomicCounterDecrement");24constexpr ImmutableString kAtomicCounterBaseName("_acbase_");25} // namespace2627AtomicCounterFunctionHLSL::AtomicCounterFunctionHLSL(bool forceResolution)28: mForceResolution(forceResolution)29{}3031ImmutableString AtomicCounterFunctionHLSL::useAtomicCounterFunction(const ImmutableString &name)32{33// The largest string that will be create created is "_acbase_increment" or "_acbase_decrement"34ImmutableStringBuilder hlslFunctionNameSB(kAtomicCounterBaseName.length() +35strlen("increment"));36hlslFunctionNameSB << kAtomicCounterBaseName;3738AtomicCounterFunction atomicMethod;39if (kAtomicCounter == name)40{41atomicMethod = AtomicCounterFunction::LOAD;42hlslFunctionNameSB << "load";43}44else if (kAtomicCounterIncrement == name)45{46atomicMethod = AtomicCounterFunction::INCREMENT;47hlslFunctionNameSB << "increment";48}49else if (kAtomicCounterDecrement == name)50{51atomicMethod = AtomicCounterFunction::DECREMENT;52hlslFunctionNameSB << "decrement";53}54else55{56atomicMethod = AtomicCounterFunction::INVALID;57UNREACHABLE();58}5960ImmutableString hlslFunctionName(hlslFunctionNameSB);61mAtomicCounterFunctions[hlslFunctionName] = atomicMethod;6263return hlslFunctionName;64}6566void AtomicCounterFunctionHLSL::atomicCounterFunctionHeader(TInfoSinkBase &out)67{68for (auto &atomicFunction : mAtomicCounterFunctions)69{70out << "uint " << atomicFunction.first71<< "(in RWByteAddressBuffer counter, int address)\n"72"{\n"73" uint ret;\n";7475switch (atomicFunction.second)76{77case AtomicCounterFunction::INCREMENT:78out << " counter.InterlockedAdd(address, 1u, ret);\n";79break;80case AtomicCounterFunction::DECREMENT:81out << " counter.InterlockedAdd(address, 0u - 1u, ret);\n"82" ret -= 1u;\n"; // atomicCounterDecrement is a post-decrement op83break;84case AtomicCounterFunction::LOAD:85out << " ret = counter.Load(address);\n";86break;87default:88UNREACHABLE();89break;90}9192if (mForceResolution && atomicFunction.second != AtomicCounterFunction::LOAD)93{94out << " if (ret == 0) {\n"95" ret = 0 - ret;\n"96" }\n";97}9899out << " return ret;\n"100"}\n\n";101}102}103104ImmutableString getAtomicCounterNameForBinding(int binding)105{106std::stringstream counterName = sh::InitializeStream<std::stringstream>();107counterName << kAtomicCounterBaseName << binding;108return ImmutableString(counterName.str());109}110111} // namespace sh112113114