//
// 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   = {0};
    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
