//
// Copyright 2013 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.
//

// PixelTransfer11.cpp:
//   Implementation for buffer-to-texture and texture-to-buffer copies.
//   Used to implement pixel transfers from unpack and to pack buffers.
//

#include "libANGLE/renderer/d3d/d3d11/PixelTransfer11.h"

#include "libANGLE/Buffer.h"
#include "libANGLE/Context.h"
#include "libANGLE/Texture.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
#include "libANGLE/renderer/d3d/d3d11/Context11.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"

// Precompiled shaders
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h"

namespace rx
{

PixelTransfer11::PixelTransfer11(Renderer11 *renderer)
    : mRenderer(renderer),
      mResourcesLoaded(false),
      mBufferToTextureVS(),
      mBufferToTextureGS(),
      mParamsConstantBuffer(),
      mCopyRasterizerState(),
      mCopyDepthStencilState()
{}

PixelTransfer11::~PixelTransfer11() {}

angle::Result PixelTransfer11::loadResources(const gl::Context *context)
{
    if (mResourcesLoaded)
    {
        return angle::Result::Continue;
    }

    D3D11_RASTERIZER_DESC rasterDesc;
    rasterDesc.FillMode              = D3D11_FILL_SOLID;
    rasterDesc.CullMode              = D3D11_CULL_NONE;
    rasterDesc.FrontCounterClockwise = FALSE;
    rasterDesc.DepthBias             = 0;
    rasterDesc.SlopeScaledDepthBias  = 0.0f;
    rasterDesc.DepthBiasClamp        = 0.0f;
    rasterDesc.DepthClipEnable       = TRUE;
    rasterDesc.ScissorEnable         = FALSE;
    rasterDesc.MultisampleEnable     = FALSE;
    rasterDesc.AntialiasedLineEnable = FALSE;

    Context11 *context11 = GetImplAs<Context11>(context);

    ANGLE_TRY(mRenderer->allocateResource(context11, rasterDesc, &mCopyRasterizerState));

    D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
    depthStencilDesc.DepthEnable                  = true;
    depthStencilDesc.DepthWriteMask               = D3D11_DEPTH_WRITE_MASK_ALL;
    depthStencilDesc.DepthFunc                    = D3D11_COMPARISON_ALWAYS;
    depthStencilDesc.StencilEnable                = FALSE;
    depthStencilDesc.StencilReadMask              = D3D11_DEFAULT_STENCIL_READ_MASK;
    depthStencilDesc.StencilWriteMask             = D3D11_DEFAULT_STENCIL_WRITE_MASK;
    depthStencilDesc.FrontFace.StencilFailOp      = D3D11_STENCIL_OP_KEEP;
    depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
    depthStencilDesc.FrontFace.StencilPassOp      = D3D11_STENCIL_OP_KEEP;
    depthStencilDesc.FrontFace.StencilFunc        = D3D11_COMPARISON_ALWAYS;
    depthStencilDesc.BackFace.StencilFailOp       = D3D11_STENCIL_OP_KEEP;
    depthStencilDesc.BackFace.StencilDepthFailOp  = D3D11_STENCIL_OP_KEEP;
    depthStencilDesc.BackFace.StencilPassOp       = D3D11_STENCIL_OP_KEEP;
    depthStencilDesc.BackFace.StencilFunc         = D3D11_COMPARISON_ALWAYS;

    ANGLE_TRY(mRenderer->allocateResource(context11, depthStencilDesc, &mCopyDepthStencilState));

    D3D11_BUFFER_DESC constantBufferDesc   = {};
    constantBufferDesc.ByteWidth           = roundUp<UINT>(sizeof(CopyShaderParams), 32u);
    constantBufferDesc.Usage               = D3D11_USAGE_DYNAMIC;
    constantBufferDesc.BindFlags           = D3D11_BIND_CONSTANT_BUFFER;
    constantBufferDesc.CPUAccessFlags      = D3D11_CPU_ACCESS_WRITE;
    constantBufferDesc.MiscFlags           = 0;
    constantBufferDesc.StructureByteStride = 0;

    ANGLE_TRY(mRenderer->allocateResource(context11, constantBufferDesc, &mParamsConstantBuffer));
    mParamsConstantBuffer.setDebugName("PixelTransfer11 constant buffer");

    // init shaders
    ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_VS_BufferToTexture),
                                          &mBufferToTextureVS));
    mBufferToTextureVS.setDebugName("BufferToTexture VS");

    ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_GS_BufferToTexture),
                                          &mBufferToTextureGS));
    mBufferToTextureGS.setDebugName("BufferToTexture GS");

    ANGLE_TRY(buildShaderMap(context));

    StructZero(&mParamsData);

    mResourcesLoaded = true;

    return angle::Result::Continue;
}

void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea,
                                                   const gl::Extents &destSize,
                                                   GLenum internalFormat,
                                                   const gl::PixelUnpackState &unpack,
                                                   unsigned int offset,
                                                   CopyShaderParams *parametersOut)
{
    StructZero(parametersOut);

    float texelCenterX = 0.5f / static_cast<float>(destSize.width);
    float texelCenterY = 0.5f / static_cast<float>(destSize.height);

    unsigned int bytesPerPixel  = gl::GetSizedInternalFormatInfo(internalFormat).pixelBytes;
    unsigned int alignmentBytes = static_cast<unsigned int>(unpack.alignment);
    unsigned int alignmentPixels =
        (alignmentBytes <= bytesPerPixel ? 1 : alignmentBytes / bytesPerPixel);

    parametersOut->FirstPixelOffset = offset / bytesPerPixel;
    parametersOut->PixelsPerRow =
        static_cast<unsigned int>((unpack.rowLength > 0) ? unpack.rowLength : destArea.width);
    parametersOut->RowStride    = roundUp(parametersOut->PixelsPerRow, alignmentPixels);
    parametersOut->RowsPerSlice = static_cast<unsigned int>(destArea.height);
    parametersOut->PositionOffset[0] =
        texelCenterX + (destArea.x / float(destSize.width)) * 2.0f - 1.0f;
    parametersOut->PositionOffset[1] =
        texelCenterY + ((destSize.height - destArea.y - 1) / float(destSize.height)) * 2.0f - 1.0f;
    parametersOut->PositionScale[0] = 2.0f / static_cast<float>(destSize.width);
    parametersOut->PositionScale[1] = -2.0f / static_cast<float>(destSize.height);
    parametersOut->FirstSlice       = destArea.z;
}

angle::Result PixelTransfer11::copyBufferToTexture(const gl::Context *context,
                                                   const gl::PixelUnpackState &unpack,
                                                   unsigned int offset,
                                                   RenderTargetD3D *destRenderTarget,
                                                   GLenum destinationFormat,
                                                   GLenum sourcePixelsType,
                                                   const gl::Box &destArea)
{
    ANGLE_TRY(loadResources(context));

    gl::Extents destSize = destRenderTarget->getExtents();

    ASSERT(destArea.x >= 0 && destArea.x + destArea.width <= destSize.width && destArea.y >= 0 &&
           destArea.y + destArea.height <= destSize.height && destArea.z >= 0 &&
           destArea.z + destArea.depth <= destSize.depth);

    const gl::Buffer &sourceBuffer =
        *context->getState().getTargetBuffer(gl::BufferBinding::PixelUnpack);

    ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat));

    const d3d11::PixelShader *pixelShader = findBufferToTexturePS(destinationFormat);
    ASSERT(pixelShader);

    // The SRV must be in the proper read format, which may be different from the destination format
    // EG: for half float data, we can load full precision floats with implicit conversion
    GLenum unsizedFormat = gl::GetUnsizedFormat(destinationFormat);
    const gl::InternalFormat &sourceglFormatInfo =
        gl::GetInternalFormatInfo(unsizedFormat, sourcePixelsType);

    const d3d11::Format &sourceFormatInfo = d3d11::Format::Get(
        sourceglFormatInfo.sizedInternalFormat, mRenderer->getRenderer11DeviceCaps());
    DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat;
    ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN);
    Buffer11 *bufferStorage11                  = GetAs<Buffer11>(sourceBuffer.getImplementation());
    const d3d11::ShaderResourceView *bufferSRV = nullptr;
    ANGLE_TRY(bufferStorage11->getSRV(context, srvFormat, &bufferSRV));
    ASSERT(bufferSRV != nullptr);

    const d3d11::RenderTargetView &textureRTV =
        GetAs<RenderTarget11>(destRenderTarget)->getRenderTargetView();
    ASSERT(textureRTV.valid());

    CopyShaderParams shaderParams;
    setBufferToTextureCopyParams(destArea, destSize, sourceglFormatInfo.sizedInternalFormat, unpack,
                                 offset, &shaderParams);

    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();

    // Are we doing a 2D or 3D copy?
    const auto *geometryShader   = ((destSize.depth > 1) ? &mBufferToTextureGS : nullptr);
    StateManager11 *stateManager = mRenderer->getStateManager();

    stateManager->setDrawShaders(&mBufferToTextureVS, geometryShader, pixelShader);
    stateManager->setShaderResource(gl::ShaderType::Fragment, 0, bufferSRV);
    stateManager->setInputLayout(nullptr);
    stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);

    stateManager->setSingleVertexBuffer(nullptr, 0, 0);
    stateManager->setSimpleBlendState(nullptr);
    stateManager->setDepthStencilState(&mCopyDepthStencilState, 0xFFFFFFFF);
    stateManager->setRasterizerState(&mCopyRasterizerState);

    stateManager->setRenderTarget(textureRTV.get(), nullptr);

    if (!StructEquals(mParamsData, shaderParams))
    {
        d3d11::SetBufferData(deviceContext, mParamsConstantBuffer.get(), shaderParams);
        mParamsData = shaderParams;
    }

    stateManager->setVertexConstantBuffer(0, &mParamsConstantBuffer);

    // Set the viewport
    stateManager->setSimpleViewport(destSize);

    UINT numPixels = (destArea.width * destArea.height * destArea.depth);
    deviceContext->Draw(numPixels, 0);

    return angle::Result::Continue;
}

angle::Result PixelTransfer11::buildShaderMap(const gl::Context *context)
{
    d3d11::PixelShader bufferToTextureFloat;
    d3d11::PixelShader bufferToTextureInt;
    d3d11::PixelShader bufferToTextureUint;

    Context11 *context11 = GetImplAs<Context11>(context);

    ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_PS_BufferToTexture_4F),
                                          &bufferToTextureFloat));
    ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_PS_BufferToTexture_4I),
                                          &bufferToTextureInt));
    ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_PS_BufferToTexture_4UI),
                                          &bufferToTextureUint));

    bufferToTextureFloat.setDebugName("BufferToTexture RGBA ps");
    bufferToTextureInt.setDebugName("BufferToTexture RGBA-I ps");
    bufferToTextureUint.setDebugName("BufferToTexture RGBA-UI ps");

    mBufferToTexturePSMap[GL_FLOAT]        = std::move(bufferToTextureFloat);
    mBufferToTexturePSMap[GL_INT]          = std::move(bufferToTextureInt);
    mBufferToTexturePSMap[GL_UNSIGNED_INT] = std::move(bufferToTextureUint);

    return angle::Result::Continue;
}

const d3d11::PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const
{
    GLenum componentType = gl::GetSizedInternalFormatInfo(internalFormat).componentType;
    if (componentType == GL_SIGNED_NORMALIZED || componentType == GL_UNSIGNED_NORMALIZED)
    {
        componentType = GL_FLOAT;
    }

    auto shaderMapIt = mBufferToTexturePSMap.find(componentType);
    return (shaderMapIt == mBufferToTexturePSMap.end() ? nullptr : &shaderMapIt->second);
}

}  // namespace rx
