Edit

kc3-lang/angle/src/compiler/translator/AtomicCounterFunctionHLSL.cpp

Branch :

  • Show log

    Commit

  • Author : Brandon Jones
    Date : 2018-10-23 14:36:47
    Hash : 4a22f4b0
    Message : ES31: Add atomic_uint support to HLSL translator This is the first commit in a series to enable atomic counter buffers. Adds support for atomic counters to the GLSL->HLSL translator using RWByteAddressBuffer. Bug: angleproject:1729 Test: angle_end2end_tests Change-Id: I3b7e08f9256dc9bdbcc02ad8910040f2bc14aeac Reviewed-on: https://chromium-review.googlesource.com/c/1291329 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>

  • src/compiler/translator/AtomicCounterFunctionHLSL.cpp
  • //
    // Copyright (c) 2018 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.
    //
    // AtomicCounterFunctionHLSL: Class for writing implementation of atomic counter functions into HLSL
    // output.
    //
    
    #include "compiler/translator/AtomicCounterFunctionHLSL.h"
    
    #include "compiler/translator/ImmutableStringBuilder.h"
    #include "compiler/translator/InfoSink.h"
    #include "compiler/translator/IntermNode.h"
    
    namespace sh
    {
    
    namespace
    {
    constexpr ImmutableString kAtomicCounter("atomicCounter");
    constexpr ImmutableString kAtomicCounterIncrement("atomicCounterIncrement");
    constexpr ImmutableString kAtomicCounterDecrement("atomicCounterDecrement");
    constexpr ImmutableString kAtomicCounterBaseName("_acbase_");
    }  // namespace
    
    ImmutableString AtomicCounterFunctionHLSL::useAtomicCounterFunction(const ImmutableString &name)
    {
        // The largest string that will be create created is "_acbase_increment" or "_acbase_decrement"
        ImmutableStringBuilder hlslFunctionNameSB(kAtomicCounterBaseName.length() +
                                                  strlen("increment"));
        hlslFunctionNameSB << kAtomicCounterBaseName;
    
        AtomicCounterFunction atomicMethod;
        if (kAtomicCounter == name)
        {
            atomicMethod = AtomicCounterFunction::LOAD;
            hlslFunctionNameSB << "load";
        }
        else if (kAtomicCounterIncrement == name)
        {
            atomicMethod = AtomicCounterFunction::INCREMENT;
            hlslFunctionNameSB << "increment";
        }
        else if (kAtomicCounterDecrement == name)
        {
            atomicMethod = AtomicCounterFunction::DECREMENT;
            hlslFunctionNameSB << "decrement";
        }
        else
        {
            atomicMethod = AtomicCounterFunction::INVALID;
            UNREACHABLE();
        }
    
        ImmutableString hlslFunctionName(hlslFunctionNameSB);
        mAtomicCounterFunctions[hlslFunctionName] = atomicMethod;
    
        return hlslFunctionName;
    }
    
    void AtomicCounterFunctionHLSL::atomicCounterFunctionHeader(TInfoSinkBase &out)
    {
        for (auto &atomicFunction : mAtomicCounterFunctions)
        {
            out << "uint " << atomicFunction.first
                << "(in RWByteAddressBuffer counter, int address)\n"
                   "{\n";
            switch (atomicFunction.second)
            {
                case AtomicCounterFunction::INCREMENT:
                case AtomicCounterFunction::DECREMENT:
                    out << "    uint ret;\n"
                           "    counter.InterlockedAdd(address, ";
                    if (atomicFunction.second == AtomicCounterFunction::DECREMENT)
                    {
                        out << "0u - ";
                    }
                    out << "1u, ret);\n"
                        << "    return ret;\n";
                    break;
                case AtomicCounterFunction::LOAD:
                    out << "    return counter.Load(address);\n";
                    break;
                default:
                    UNREACHABLE();
                    break;
            }
            out << "}\n\n";
        }
    }
    
    ImmutableString getAtomicCounterNameForBinding(int binding)
    {
        std::stringstream counterName;
        counterName << kAtomicCounterBaseName << binding;
        return ImmutableString(counterName.str());
    }
    
    }  // namespace sh