//
// Copyright 2017 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.
//
// ImageFunctionHLSL: Class for writing implementations of ESSL image functions into HLSL output.
//

#include "compiler/translator/ImageFunctionHLSL.h"
#include "compiler/translator/ImmutableStringBuilder.h"
#include "compiler/translator/UtilsHLSL.h"

namespace sh
{

// static
ImmutableString ImageFunctionHLSL::GetImageReference(
    TInfoSinkBase &out,
    const ImageFunctionHLSL::ImageFunction &imageFunction)
{
    static const ImmutableString kImageIndexStr("[index]");
    if (imageFunction.readonly)
    {
        static const ImmutableString kReadonlyImagesStr("readonlyImages");
        ImmutableString suffix(
            TextureGroupSuffix(imageFunction.image, imageFunction.imageInternalFormat));
        out << "    const uint index = imageIndex - readonlyImageIndexOffset" << suffix.data()
            << ";\n";
        ImmutableStringBuilder imageRefBuilder(kReadonlyImagesStr.length() + suffix.length() +
                                               kImageIndexStr.length());
        imageRefBuilder << kReadonlyImagesStr << suffix << kImageIndexStr;
        return imageRefBuilder;
    }
    else
    {
        static const ImmutableString kImagesStr("images");
        ImmutableString suffix(
            RWTextureGroupSuffix(imageFunction.image, imageFunction.imageInternalFormat));
        out << "    const uint index = imageIndex - imageIndexOffset" << suffix.data() << ";\n";
        ImmutableStringBuilder imageRefBuilder(kImagesStr.length() + suffix.length() +
                                               kImageIndexStr.length());
        imageRefBuilder << kImagesStr << suffix << kImageIndexStr;
        return imageRefBuilder;
    }
}

void ImageFunctionHLSL::OutputImageFunctionArgumentList(
    TInfoSinkBase &out,
    const ImageFunctionHLSL::ImageFunction &imageFunction)
{
    out << "uint imageIndex";

    if (imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::LOAD ||
        imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::STORE)
    {
        switch (imageFunction.image)
        {
            case EbtImage2D:
            case EbtIImage2D:
            case EbtUImage2D:
                out << ", int2 p";
                break;
            case EbtImage3D:
            case EbtIImage3D:
            case EbtUImage3D:
            case EbtImageCube:
            case EbtIImageCube:
            case EbtUImageCube:
            case EbtImage2DArray:
            case EbtIImage2DArray:
            case EbtUImage2DArray:
                out << ", int3 p";
                break;
            default:
                UNREACHABLE();
        }

        if (imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::STORE)
        {
            switch (imageFunction.image)
            {
                case EbtImage2D:
                case EbtImage3D:
                case EbtImageCube:
                case EbtImage2DArray:
                    out << ", float4 data";
                    break;
                case EbtIImage2D:
                case EbtIImage3D:
                case EbtIImageCube:
                case EbtIImage2DArray:
                    out << ", int4 data";
                    break;
                case EbtUImage2D:
                case EbtUImage3D:
                case EbtUImageCube:
                case EbtUImage2DArray:
                    out << ", uint4 data";
                    break;
                default:
                    UNREACHABLE();
            }
        }
    }
}

// static
void ImageFunctionHLSL::OutputImageSizeFunctionBody(
    TInfoSinkBase &out,
    const ImageFunctionHLSL::ImageFunction &imageFunction,
    const ImmutableString &imageReference)
{
    if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
        IsImageCube(imageFunction.image))
    {
        // "depth" stores either the number of layers in an array texture or 3D depth
        out << "    uint width; uint height; uint depth;\n"
            << "    " << imageReference << ".GetDimensions(width, height, depth);\n";
    }
    else if (IsImage2D(imageFunction.image))
    {
        out << "    uint width; uint height;\n"
            << "    " << imageReference << ".GetDimensions(width, height);\n";
    }
    else
        UNREACHABLE();

    if (strcmp(imageFunction.getReturnType(), "int3") == 0)
    {
        out << "    return int3(width, height, depth);\n";
    }
    else
    {
        out << "    return int2(width, height);\n";
    }
}

// static
void ImageFunctionHLSL::OutputImageLoadFunctionBody(
    TInfoSinkBase &out,
    const ImageFunctionHLSL::ImageFunction &imageFunction,
    const ImmutableString &imageReference)
{
    if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
        IsImageCube(imageFunction.image))
    {
        out << "    return " << imageReference << "[uint3(p.x, p.y, p.z)];\n";
    }
    else if (IsImage2D(imageFunction.image))
    {
        out << "    return " << imageReference << "[uint2(p.x, p.y)];\n";
    }
    else
        UNREACHABLE();
}

// static
void ImageFunctionHLSL::OutputImageStoreFunctionBody(
    TInfoSinkBase &out,
    const ImageFunctionHLSL::ImageFunction &imageFunction,
    const ImmutableString &imageReference)
{
    if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
        IsImage2D(imageFunction.image) || IsImageCube(imageFunction.image))
    {
        out << "    " << imageReference << "[p] = data;\n";
    }
    else
        UNREACHABLE();
}

ImmutableString ImageFunctionHLSL::ImageFunction::name() const
{
    static const ImmutableString kGlImageName("gl_image");

    ImmutableString suffix(nullptr);
    if (readonly)
    {
        suffix = ImmutableString(TextureTypeSuffix(image, imageInternalFormat));
    }
    else
    {
        suffix = ImmutableString(RWTextureTypeSuffix(image, imageInternalFormat));
    }

    ImmutableStringBuilder name(kGlImageName.length() + suffix.length() + 5u);

    name << kGlImageName << suffix;

    switch (method)
    {
        case Method::SIZE:
            name << "Size";
            break;
        case Method::LOAD:
            name << "Load";
            break;
        case Method::STORE:
            name << "Store";
            break;
        default:
            UNREACHABLE();
    }

    return name;
}

ImageFunctionHLSL::ImageFunction::DataType ImageFunctionHLSL::ImageFunction::getDataType(
    TLayoutImageInternalFormat format) const
{
    switch (format)
    {
        case EiifRGBA32F:
        case EiifRGBA16F:
        case EiifR32F:
            return ImageFunction::DataType::FLOAT4;
        case EiifRGBA32UI:
        case EiifRGBA16UI:
        case EiifRGBA8UI:
        case EiifR32UI:
            return ImageFunction::DataType::UINT4;
        case EiifRGBA32I:
        case EiifRGBA16I:
        case EiifRGBA8I:
        case EiifR32I:
            return ImageFunction::DataType::INT4;
        case EiifRGBA8:
            return ImageFunction::DataType::UNORM_FLOAT4;
        case EiifRGBA8_SNORM:
            return ImageFunction::DataType::SNORM_FLOAT4;
        default:
            UNREACHABLE();
    }

    return ImageFunction::DataType::NONE;
}

const char *ImageFunctionHLSL::ImageFunction::getReturnType() const
{
    if (method == ImageFunction::Method::SIZE)
    {
        switch (image)
        {
            case EbtImage2D:
            case EbtIImage2D:
            case EbtUImage2D:
            case EbtImageCube:
            case EbtIImageCube:
            case EbtUImageCube:
                return "int2";
            case EbtImage3D:
            case EbtIImage3D:
            case EbtUImage3D:
            case EbtImage2DArray:
            case EbtIImage2DArray:
            case EbtUImage2DArray:
                return "int3";
            default:
                UNREACHABLE();
        }
    }
    else if (method == ImageFunction::Method::LOAD)
    {
        switch (image)
        {
            case EbtImage2D:
            case EbtImage3D:
            case EbtImageCube:
            case EbtImage2DArray:
                return "float4";
            case EbtIImage2D:
            case EbtIImage3D:
            case EbtIImageCube:
            case EbtIImage2DArray:
                return "int4";
            case EbtUImage2D:
            case EbtUImage3D:
            case EbtUImageCube:
            case EbtUImage2DArray:
                return "uint4";
            default:
                UNREACHABLE();
        }
    }
    else if (method == ImageFunction::Method::STORE)
    {
        return "void";
    }
    else
    {
        UNREACHABLE();
    }
    return "";
}

bool ImageFunctionHLSL::ImageFunction::operator<(const ImageFunction &rhs) const
{
    return std::tie(image, type, method, readonly) <
           std::tie(rhs.image, rhs.type, rhs.method, rhs.readonly);
}

ImmutableString ImageFunctionHLSL::useImageFunction(const ImmutableString &name,
                                                    const TBasicType &type,
                                                    TLayoutImageInternalFormat imageInternalFormat,
                                                    bool readonly)
{
    ASSERT(IsImage(type));
    ImageFunction imageFunction;
    imageFunction.image               = type;
    imageFunction.imageInternalFormat = imageInternalFormat;
    imageFunction.readonly            = readonly;
    imageFunction.type                = imageFunction.getDataType(imageInternalFormat);

    if (name == "imageSize")
    {
        imageFunction.method = ImageFunction::Method::SIZE;
    }
    else if (name == "imageLoad")
    {
        imageFunction.method = ImageFunction::Method::LOAD;
    }
    else if (name == "imageStore")
    {
        imageFunction.method = ImageFunction::Method::STORE;
    }
    else
        UNREACHABLE();

    mUsesImage.insert(imageFunction);
    return imageFunction.name();
}

void ImageFunctionHLSL::imageFunctionHeader(TInfoSinkBase &out)
{
    for (const ImageFunction &imageFunction : mUsesImage)
    {
        // Skip to generate image2D functions here, dynamically generate these
        // functions when linking, or after dispatch or draw.
        if (IsImage2D(imageFunction.image))
        {
            mUsedImage2DFunctionNames.insert(imageFunction.name().data());
            continue;
        }
        // Function header
        out << imageFunction.getReturnType() << " " << imageFunction.name() << "(";

        OutputImageFunctionArgumentList(out, imageFunction);

        out << ")\n"
               "{\n";

        ImmutableString imageReference = GetImageReference(out, imageFunction);
        if (imageFunction.method == ImageFunction::Method::SIZE)
        {
            OutputImageSizeFunctionBody(out, imageFunction, imageReference);
        }
        else if (imageFunction.method == ImageFunction::Method::LOAD)
        {
            OutputImageLoadFunctionBody(out, imageFunction, imageReference);
        }
        else
        {
            OutputImageStoreFunctionBody(out, imageFunction, imageReference);
        }

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

}  // namespace sh
