//
// Copyright 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.
//
// ShaderStorageBlockFunctionHLSL: Wrapper functions for RWByteAddressBuffer Load/Store functions.
//

#include "compiler/translator/ShaderStorageBlockFunctionHLSL.h"

#include "common/utilities.h"
#include "compiler/translator/UtilsHLSL.h"
#include "compiler/translator/blocklayout.h"
#include "compiler/translator/blocklayoutHLSL.h"
#include "compiler/translator/util.h"

namespace sh
{

// static
void ShaderStorageBlockFunctionHLSL::OutputSSBOLoadFunctionBody(
    TInfoSinkBase &out,
    const ShaderStorageBlockFunction &ssboFunction)
{
    const char *convertString;
    switch (ssboFunction.type.getBasicType())
    {
        case EbtFloat:
            convertString = "asfloat(";
            break;
        case EbtInt:
            convertString = "asint(";
            break;
        case EbtUInt:
            convertString = "asuint(";
            break;
        case EbtBool:
            convertString = "asint(";
            break;
        default:
            UNREACHABLE();
            return;
    }

    size_t bytesPerComponent =
        gl::VariableComponentSize(gl::VariableComponentType(GLVariableType(ssboFunction.type)));
    out << "    " << ssboFunction.typeString << " result";
    if (ssboFunction.type.isScalar())
    {
        size_t offset = ssboFunction.swizzleOffsets[0] * bytesPerComponent;
        out << " = " << convertString << "buffer.Load(loc + " << offset << "));\n ";
    }
    else if (ssboFunction.type.isVector())
    {
        if (ssboFunction.rowMajor || !ssboFunction.isDefaultSwizzle)
        {
            size_t componentStride = bytesPerComponent;
            if (ssboFunction.rowMajor)
            {
                componentStride = ssboFunction.matrixStride;
            }

            out << " = {";
            for (const int offset : ssboFunction.swizzleOffsets)
            {
                size_t offsetInBytes = offset * componentStride;
                out << convertString << "buffer.Load(loc + " << offsetInBytes << ")),";
            }
            out << "};\n";
        }
        else
        {
            out << " = " << convertString << "buffer.Load" << ssboFunction.type.getNominalSize()
                << "(loc));\n";
        }
    }
    else if (ssboFunction.type.isMatrix())
    {
        if (ssboFunction.rowMajor)
        {
            out << ";";
            out << "    float" << ssboFunction.type.getRows() << "x" << ssboFunction.type.getCols()
                << " tmp_ = {";
            for (int rowIndex = 0; rowIndex < ssboFunction.type.getRows(); rowIndex++)
            {
                out << "asfloat(buffer.Load" << ssboFunction.type.getCols() << "(loc + "
                    << rowIndex * ssboFunction.matrixStride << ")), ";
            }
            out << "};\n";
            out << "    result = transpose(tmp_);\n";
        }
        else
        {
            out << " = {";
            for (int columnIndex = 0; columnIndex < ssboFunction.type.getCols(); columnIndex++)
            {
                out << "asfloat(buffer.Load" << ssboFunction.type.getRows() << "(loc + "
                    << columnIndex * ssboFunction.matrixStride << ")), ";
            }
            out << "};\n";
        }
    }
    else
    {
        // TODO(jiajia.qin@intel.com): Process all possible return types. http://anglebug.com/1951
        out << ";\n";
    }

    out << "    return result;\n";
    return;
}

// static
void ShaderStorageBlockFunctionHLSL::OutputSSBOStoreFunctionBody(
    TInfoSinkBase &out,
    const ShaderStorageBlockFunction &ssboFunction)
{
    size_t bytesPerComponent =
        gl::VariableComponentSize(gl::VariableComponentType(GLVariableType(ssboFunction.type)));
    if (ssboFunction.type.isScalar())
    {
        size_t offset = ssboFunction.swizzleOffsets[0] * bytesPerComponent;
        if (ssboFunction.type.getBasicType() == EbtBool)
        {
            out << "    buffer.Store(loc + " << offset << ", uint(value));\n";
        }
        else
        {
            out << "    buffer.Store(loc + " << offset << ", asuint(value));\n";
        }
    }
    else if (ssboFunction.type.isVector())
    {
        out << "    uint" << ssboFunction.type.getNominalSize() << " _value;\n";
        if (ssboFunction.type.getBasicType() == EbtBool)
        {
            out << "    _value = uint" << ssboFunction.type.getNominalSize() << "(value);\n";
        }
        else
        {
            out << "    _value = asuint(value);\n";
        }

        if (ssboFunction.rowMajor || !ssboFunction.isDefaultSwizzle)
        {
            size_t componentStride = bytesPerComponent;
            if (ssboFunction.rowMajor)
            {
                componentStride = ssboFunction.matrixStride;
            }
            const TVector<int> &swizzleOffsets = ssboFunction.swizzleOffsets;
            for (int index = 0; index < static_cast<int>(swizzleOffsets.size()); index++)
            {
                size_t offsetInBytes = swizzleOffsets[index] * componentStride;
                out << "buffer.Store(loc + " << offsetInBytes << ", _value[" << index << "]);\n";
            }
        }
        else
        {
            out << "    buffer.Store" << ssboFunction.type.getNominalSize() << "(loc, _value);\n";
        }
    }
    else if (ssboFunction.type.isMatrix())
    {
        if (ssboFunction.rowMajor)
        {
            out << "    float" << ssboFunction.type.getRows() << "x" << ssboFunction.type.getCols()
                << " tmp_ = transpose(value);\n";
            for (int rowIndex = 0; rowIndex < ssboFunction.type.getRows(); rowIndex++)
            {
                out << "    buffer.Store" << ssboFunction.type.getCols() << "(loc + "
                    << rowIndex * ssboFunction.matrixStride << ", asuint(tmp_[" << rowIndex
                    << "]));\n";
            }
        }
        else
        {
            for (int columnIndex = 0; columnIndex < ssboFunction.type.getCols(); columnIndex++)
            {
                out << "    buffer.Store" << ssboFunction.type.getRows() << "(loc + "
                    << columnIndex * ssboFunction.matrixStride << ", asuint(value[" << columnIndex
                    << "]));\n";
            }
        }
    }
    else
    {
        // TODO(jiajia.qin@intel.com): Process all possible return types. http://anglebug.com/1951
    }
}

// static
void ShaderStorageBlockFunctionHLSL::OutputSSBOLengthFunctionBody(TInfoSinkBase &out,
                                                                  int unsizedArrayStride)
{
    out << "    uint dim = 0;\n";
    out << "    buffer.GetDimensions(dim);\n";
    out << "    return int((dim - loc)/uint(" << unsizedArrayStride << "));\n";
}

// static
void ShaderStorageBlockFunctionHLSL::OutputSSBOAtomicMemoryFunctionBody(
    TInfoSinkBase &out,
    const ShaderStorageBlockFunction &ssboFunction)
{
    out << "    " << ssboFunction.typeString << " original_value;\n";
    switch (ssboFunction.method)
    {
        case SSBOMethod::ATOMIC_ADD:
            out << "    buffer.InterlockedAdd(loc, value, original_value);\n";
            break;
        case SSBOMethod::ATOMIC_MIN:
            out << "    buffer.InterlockedMin(loc, value, original_value);\n";
            break;
        case SSBOMethod::ATOMIC_MAX:
            out << "    buffer.InterlockedMax(loc, value, original_value);\n";
            break;
        case SSBOMethod::ATOMIC_AND:
            out << "    buffer.InterlockedAnd(loc, value, original_value);\n";
            break;
        case SSBOMethod::ATOMIC_OR:
            out << "    buffer.InterlockedOr(loc, value, original_value);\n";
            break;
        case SSBOMethod::ATOMIC_XOR:
            out << "    buffer.InterlockedXor(loc, value, original_value);\n";
            break;
        case SSBOMethod::ATOMIC_EXCHANGE:
            out << "    buffer.InterlockedExchange(loc, value, original_value);\n";
            break;
        case SSBOMethod::ATOMIC_COMPSWAP:
            out << "    buffer.InterlockedCompareExchange(loc, compare_value, value, "
                   "original_value);\n";
            break;
        default:
            UNREACHABLE();
    }
    out << "    return original_value;\n";
}

bool ShaderStorageBlockFunctionHLSL::ShaderStorageBlockFunction::operator<(
    const ShaderStorageBlockFunction &rhs) const
{
    return functionName < rhs.functionName;
}

TString ShaderStorageBlockFunctionHLSL::registerShaderStorageBlockFunction(
    const TType &type,
    SSBOMethod method,
    TLayoutBlockStorage storage,
    bool rowMajor,
    int matrixStride,
    int unsizedArrayStride,
    TIntermSwizzle *swizzleNode)
{
    ShaderStorageBlockFunction ssboFunction;
    ssboFunction.typeString = TypeString(type);
    ssboFunction.method     = method;
    switch (method)
    {
        case SSBOMethod::LOAD:
            ssboFunction.functionName = "_Load_";
            break;
        case SSBOMethod::STORE:
            ssboFunction.functionName = "_Store_";
            break;
        case SSBOMethod::LENGTH:
            ssboFunction.unsizedArrayStride = unsizedArrayStride;
            ssboFunction.functionName       = "_Length_" + str(unsizedArrayStride);
            mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
            return ssboFunction.functionName;
        case SSBOMethod::ATOMIC_ADD:
            ssboFunction.functionName = "_ssbo_atomicAdd_" + ssboFunction.typeString;
            mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
            return ssboFunction.functionName;
        case SSBOMethod::ATOMIC_MIN:
            ssboFunction.functionName = "_ssbo_atomicMin_" + ssboFunction.typeString;
            mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
            return ssboFunction.functionName;
        case SSBOMethod::ATOMIC_MAX:
            ssboFunction.functionName = "_ssbo_atomicMax_" + ssboFunction.typeString;
            mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
            return ssboFunction.functionName;
        case SSBOMethod::ATOMIC_AND:
            ssboFunction.functionName = "_ssbo_atomicAnd_" + ssboFunction.typeString;
            mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
            return ssboFunction.functionName;
        case SSBOMethod::ATOMIC_OR:
            ssboFunction.functionName = "_ssbo_atomicOr_" + ssboFunction.typeString;
            mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
            return ssboFunction.functionName;
        case SSBOMethod::ATOMIC_XOR:
            ssboFunction.functionName = "_ssbo_atomicXor_" + ssboFunction.typeString;
            mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
            return ssboFunction.functionName;
        case SSBOMethod::ATOMIC_EXCHANGE:
            ssboFunction.functionName = "_ssbo_atomicExchange_" + ssboFunction.typeString;
            mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
            return ssboFunction.functionName;
        case SSBOMethod::ATOMIC_COMPSWAP:
            ssboFunction.functionName = "_ssbo_atomicCompSwap_" + ssboFunction.typeString;
            mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
            return ssboFunction.functionName;
        default:
            UNREACHABLE();
    }

    ssboFunction.functionName += ssboFunction.typeString;
    ssboFunction.type = type;
    if (swizzleNode != nullptr)
    {
        ssboFunction.swizzleOffsets   = swizzleNode->getSwizzleOffsets();
        ssboFunction.isDefaultSwizzle = false;
    }
    else
    {
        if (ssboFunction.type.getNominalSize() > 1)
        {
            for (int index = 0; index < ssboFunction.type.getNominalSize(); index++)
            {
                ssboFunction.swizzleOffsets.push_back(index);
            }
        }
        else
        {
            ssboFunction.swizzleOffsets.push_back(0);
        }

        ssboFunction.isDefaultSwizzle = true;
    }
    ssboFunction.rowMajor     = rowMajor;
    ssboFunction.matrixStride = matrixStride;
    ssboFunction.functionName += "_" + TString(getBlockStorageString(storage));

    if (rowMajor)
    {
        ssboFunction.functionName += "_rm_";
    }
    else
    {
        ssboFunction.functionName += "_cm_";
    }

    for (const int offset : ssboFunction.swizzleOffsets)
    {
        switch (offset)
        {
            case 0:
                ssboFunction.functionName += "x";
                break;
            case 1:
                ssboFunction.functionName += "y";
                break;
            case 2:
                ssboFunction.functionName += "z";
                break;
            case 3:
                ssboFunction.functionName += "w";
                break;
            default:
                UNREACHABLE();
        }
    }

    mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
    return ssboFunction.functionName;
}

void ShaderStorageBlockFunctionHLSL::shaderStorageBlockFunctionHeader(TInfoSinkBase &out)
{
    for (const ShaderStorageBlockFunction &ssboFunction : mRegisteredShaderStorageBlockFunctions)
    {
        switch (ssboFunction.method)
        {
            case SSBOMethod::LOAD:
            {
                // Function header
                out << ssboFunction.typeString << " " << ssboFunction.functionName
                    << "(RWByteAddressBuffer buffer, uint loc)\n";
                out << "{\n";
                OutputSSBOLoadFunctionBody(out, ssboFunction);
                break;
            }
            case SSBOMethod::STORE:
            {
                // Function header
                out << "void " << ssboFunction.functionName
                    << "(RWByteAddressBuffer buffer, uint loc, " << ssboFunction.typeString
                    << " value)\n";
                out << "{\n";
                OutputSSBOStoreFunctionBody(out, ssboFunction);
                break;
            }
            case SSBOMethod::LENGTH:
            {
                out << "int " << ssboFunction.functionName
                    << "(RWByteAddressBuffer buffer, uint loc)\n";
                out << "{\n";
                OutputSSBOLengthFunctionBody(out, ssboFunction.unsizedArrayStride);
                break;
            }
            case SSBOMethod::ATOMIC_ADD:
            case SSBOMethod::ATOMIC_MIN:
            case SSBOMethod::ATOMIC_MAX:
            case SSBOMethod::ATOMIC_AND:
            case SSBOMethod::ATOMIC_OR:
            case SSBOMethod::ATOMIC_XOR:
            case SSBOMethod::ATOMIC_EXCHANGE:
            {
                out << ssboFunction.typeString << " " << ssboFunction.functionName
                    << "(RWByteAddressBuffer buffer, uint loc, " << ssboFunction.typeString
                    << " value)\n";
                out << "{\n";

                OutputSSBOAtomicMemoryFunctionBody(out, ssboFunction);
                break;
            }
            case SSBOMethod::ATOMIC_COMPSWAP:
            {
                out << ssboFunction.typeString << " " << ssboFunction.functionName
                    << "(RWByteAddressBuffer buffer, uint loc, " << ssboFunction.typeString
                    << " compare_value, " << ssboFunction.typeString << " value)\n";
                out << "{\n";
                OutputSSBOAtomicMemoryFunctionBody(out, ssboFunction);
                break;
            }
            default:
                UNREACHABLE();
        }

        out << "}\n"
               "\n";
    }
}

}  // namespace sh
