//
// Copyright 2016 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.
//
// ContextVk.cpp:
//    Implements the class methods for ContextVk.
//

#include "libANGLE/renderer/vulkan/ContextVk.h"

#include "common/bitset_utils.h"
#include "common/debug.h"
#include "libANGLE/Program.h"
#include "libANGLE/renderer/vulkan/BufferVk.h"
#include "libANGLE/renderer/vulkan/CompilerVk.h"
#include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/DeviceVk.h"
#include "libANGLE/renderer/vulkan/FenceNVVk.h"
#include "libANGLE/renderer/vulkan/FenceSyncVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h"
#include "libANGLE/renderer/vulkan/ImageVk.h"
#include "libANGLE/renderer/vulkan/ProgramVk.h"
#include "libANGLE/renderer/vulkan/QueryVk.h"
#include "libANGLE/renderer/vulkan/RenderbufferVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
#include "libANGLE/renderer/vulkan/SamplerVk.h"
#include "libANGLE/renderer/vulkan/ShaderVk.h"
#include "libANGLE/renderer/vulkan/TextureVk.h"
#include "libANGLE/renderer/vulkan/TransformFeedbackVk.h"
#include "libANGLE/renderer/vulkan/VertexArrayVk.h"
#include "libANGLE/renderer/vulkan/formatutilsvk.h"

namespace rx
{

ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
    : ContextImpl(state), mRenderer(renderer), mCurrentDrawMode(GL_NONE)
{
}

ContextVk::~ContextVk()
{
    invalidateCurrentPipeline();
}

gl::Error ContextVk::initialize()
{
    return gl::NoError();
}

gl::Error ContextVk::flush()
{
    UNIMPLEMENTED();
    return gl::Error(GL_INVALID_OPERATION);
}

gl::Error ContextVk::finish()
{
    UNIMPLEMENTED();
    return gl::Error(GL_INVALID_OPERATION);
}

gl::Error ContextVk::initPipeline()
{
    ASSERT(!mCurrentPipeline.valid());

    VkDevice device       = mRenderer->getDevice();
    const auto &state     = mState.getState();
    const auto &programGL = state.getProgram();
    const auto &vao       = state.getVertexArray();
    const auto &attribs   = vao->getVertexAttributes();
    const auto &bindings  = vao->getVertexBindings();
    const auto &programVk = GetImplAs<ProgramVk>(programGL);
    const auto *drawFBO   = state.getDrawFramebuffer();
    FramebufferVk *vkFBO  = GetImplAs<FramebufferVk>(drawFBO);

    // { vertex, fragment }
    VkPipelineShaderStageCreateInfo shaderStages[2];

    shaderStages[0].sType               = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
    shaderStages[0].pNext               = nullptr;
    shaderStages[0].flags               = 0;
    shaderStages[0].stage               = VK_SHADER_STAGE_VERTEX_BIT;
    shaderStages[0].module              = programVk->getLinkedVertexModule().getHandle();
    shaderStages[0].pName               = "main";
    shaderStages[0].pSpecializationInfo = nullptr;

    shaderStages[1].sType               = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
    shaderStages[1].pNext               = nullptr;
    shaderStages[1].flags               = 0;
    shaderStages[1].stage               = VK_SHADER_STAGE_FRAGMENT_BIT;
    shaderStages[1].module              = programVk->getLinkedFragmentModule().getHandle();
    shaderStages[1].pName               = "main";
    shaderStages[1].pSpecializationInfo = nullptr;

    // Process vertex attributes
    // TODO(jmadill): Caching with dirty bits.
    std::vector<VkVertexInputBindingDescription> vertexBindings;
    std::vector<VkVertexInputAttributeDescription> vertexAttribs;

    for (auto attribIndex : programGL->getActiveAttribLocationsMask())
    {
        const auto &attrib  = attribs[attribIndex];
        const auto &binding = bindings[attrib.bindingIndex];
        if (attrib.enabled)
        {
            VkVertexInputBindingDescription bindingDesc;
            bindingDesc.binding = static_cast<uint32_t>(vertexBindings.size());
            bindingDesc.stride  = static_cast<uint32_t>(gl::ComputeVertexAttributeTypeSize(attrib));
            bindingDesc.inputRate =
                (binding.divisor > 0 ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX);

            gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib);

            VkVertexInputAttributeDescription attribDesc;
            attribDesc.binding  = bindingDesc.binding;
            attribDesc.format   = vk::GetNativeVertexFormat(vertexFormatType);
            attribDesc.location = static_cast<uint32_t>(attribIndex);
            attribDesc.offset =
                static_cast<uint32_t>(ComputeVertexAttributeOffset(attrib, binding));

            vertexBindings.push_back(bindingDesc);
            vertexAttribs.push_back(attribDesc);
        }
        else
        {
            UNIMPLEMENTED();
        }
    }

    // TODO(jmadill): Validate with ASSERT against physical device limits/caps?
    VkPipelineVertexInputStateCreateInfo vertexInputState;
    vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
    vertexInputState.pNext = nullptr;
    vertexInputState.flags = 0;
    vertexInputState.vertexBindingDescriptionCount   = static_cast<uint32_t>(vertexBindings.size());
    vertexInputState.pVertexBindingDescriptions      = vertexBindings.data();
    vertexInputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexAttribs.size());
    vertexInputState.pVertexAttributeDescriptions    = vertexAttribs.data();

    VkPipelineInputAssemblyStateCreateInfo inputAssemblyState;
    inputAssemblyState.sType    = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
    inputAssemblyState.pNext    = nullptr;
    inputAssemblyState.flags    = 0;
    inputAssemblyState.topology = gl_vk::GetPrimitiveTopology(mCurrentDrawMode);
    inputAssemblyState.primitiveRestartEnable = VK_FALSE;

    const gl::Rectangle &viewportGL = state.getViewport();
    VkViewport viewportVk;
    viewportVk.x        = static_cast<float>(viewportGL.x);
    viewportVk.y        = static_cast<float>(viewportGL.y);
    viewportVk.width    = static_cast<float>(viewportGL.width);
    viewportVk.height   = static_cast<float>(viewportGL.height);
    viewportVk.minDepth = state.getNearPlane();
    viewportVk.maxDepth = state.getFarPlane();

    // TODO(jmadill): Scissor.
    VkRect2D scissorVk;
    scissorVk.offset.x      = viewportGL.x;
    scissorVk.offset.y      = viewportGL.y;
    scissorVk.extent.width  = viewportGL.width;
    scissorVk.extent.height = viewportGL.height;

    VkPipelineViewportStateCreateInfo viewportState;
    viewportState.sType         = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
    viewportState.pNext         = nullptr;
    viewportState.flags         = 0;
    viewportState.viewportCount = 1;
    viewportState.pViewports    = &viewportVk;
    viewportState.scissorCount  = 1;
    viewportState.pScissors     = &scissorVk;

    // TODO(jmadill): Extra rasterizer state features.
    VkPipelineRasterizationStateCreateInfo rasterState;
    rasterState.sType            = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    rasterState.pNext            = nullptr;
    rasterState.flags            = 0;
    rasterState.depthClampEnable = VK_FALSE;
    rasterState.rasterizerDiscardEnable = VK_FALSE;
    rasterState.polygonMode             = VK_POLYGON_MODE_FILL;
    rasterState.cullMode                = gl_vk::GetCullMode(state.getRasterizerState());
    rasterState.frontFace               = gl_vk::GetFrontFace(state.getRasterizerState().frontFace);
    rasterState.depthBiasEnable         = VK_FALSE;
    rasterState.depthBiasConstantFactor = 0.0f;
    rasterState.depthBiasClamp          = 0.0f;
    rasterState.depthBiasSlopeFactor    = 0.0f;
    rasterState.lineWidth               = state.getLineWidth();

    // TODO(jmadill): Multisample state.
    VkPipelineMultisampleStateCreateInfo multisampleState;
    multisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
    multisampleState.pNext = nullptr;
    multisampleState.flags = 0;
    multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
    multisampleState.sampleShadingEnable  = VK_FALSE;
    multisampleState.minSampleShading     = 0.0f;
    multisampleState.pSampleMask          = nullptr;
    multisampleState.alphaToCoverageEnable = VK_FALSE;
    multisampleState.alphaToOneEnable      = VK_FALSE;

    // TODO(jmadill): Depth/stencil state.

    // TODO(jmadill): Blend state/MRT.
    VkPipelineColorBlendAttachmentState blendAttachmentState;
    blendAttachmentState.blendEnable         = VK_FALSE;
    blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
    blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
    blendAttachmentState.colorBlendOp        = VK_BLEND_OP_ADD;
    blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
    blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
    blendAttachmentState.alphaBlendOp        = VK_BLEND_OP_ADD;
    blendAttachmentState.colorWriteMask = (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
                                           VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);

    VkPipelineColorBlendStateCreateInfo blendState;
    blendState.sType             = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
    blendState.pNext             = 0;
    blendState.flags             = 0;
    blendState.logicOpEnable     = VK_FALSE;
    blendState.logicOp           = VK_LOGIC_OP_CLEAR;
    blendState.attachmentCount   = 1;
    blendState.pAttachments      = &blendAttachmentState;
    blendState.blendConstants[0] = 0.0f;
    blendState.blendConstants[1] = 0.0f;
    blendState.blendConstants[2] = 0.0f;
    blendState.blendConstants[3] = 0.0f;

    // TODO(jmadill): Dynamic state.
    vk::RenderPass *renderPass = nullptr;
    ANGLE_TRY_RESULT(vkFBO->getRenderPass(device), renderPass);
    ASSERT(renderPass && renderPass->valid());

    vk::PipelineLayout *pipelineLayout = nullptr;
    ANGLE_TRY_RESULT(programVk->getPipelineLayout(device), pipelineLayout);
    ASSERT(pipelineLayout && pipelineLayout->valid());

    VkGraphicsPipelineCreateInfo pipelineInfo;
    pipelineInfo.sType               = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
    pipelineInfo.pNext               = nullptr;
    pipelineInfo.flags               = 0;
    pipelineInfo.stageCount          = 2;
    pipelineInfo.pStages             = shaderStages;
    pipelineInfo.pVertexInputState   = &vertexInputState;
    pipelineInfo.pInputAssemblyState = &inputAssemblyState;
    pipelineInfo.pTessellationState  = nullptr;
    pipelineInfo.pViewportState      = &viewportState;
    pipelineInfo.pRasterizationState = &rasterState;
    pipelineInfo.pMultisampleState   = &multisampleState;
    pipelineInfo.pDepthStencilState  = nullptr;
    pipelineInfo.pColorBlendState    = &blendState;
    pipelineInfo.pDynamicState       = nullptr;
    pipelineInfo.layout              = pipelineLayout->getHandle();
    pipelineInfo.renderPass          = renderPass->getHandle();
    pipelineInfo.subpass             = 0;
    pipelineInfo.basePipelineHandle  = VK_NULL_HANDLE;
    pipelineInfo.basePipelineIndex   = 0;

    vk::Pipeline newPipeline;
    ANGLE_TRY(newPipeline.initGraphics(device, pipelineInfo));

    mCurrentPipeline.retain(device, std::move(newPipeline));

    return gl::NoError();
}

gl::Error ContextVk::drawArrays(GLenum mode, GLint first, GLsizei count)
{
    if (mode != mCurrentDrawMode)
    {
        invalidateCurrentPipeline();
        mCurrentDrawMode = mode;
    }

    if (!mCurrentPipeline.valid())
    {
        ANGLE_TRY(initPipeline());
        ASSERT(mCurrentPipeline.valid());
    }

    VkDevice device       = mRenderer->getDevice();
    const auto &state     = mState.getState();
    const auto &programGL = state.getProgram();
    const auto &vao       = state.getVertexArray();
    const auto &attribs   = vao->getVertexAttributes();
    const auto &bindings  = vao->getVertexBindings();
    const auto *drawFBO   = state.getDrawFramebuffer();
    FramebufferVk *vkFBO  = GetImplAs<FramebufferVk>(drawFBO);
    Serial queueSerial    = mRenderer->getCurrentQueueSerial();

    // Process vertex attributes
    // TODO(jmadill): Caching with dirty bits.
    std::vector<VkBuffer> vertexHandles;
    std::vector<VkDeviceSize> vertexOffsets;

    for (auto attribIndex : programGL->getActiveAttribLocationsMask())
    {
        const auto &attrib  = attribs[attribIndex];
        const auto &binding = bindings[attrib.bindingIndex];
        if (attrib.enabled)
        {
            // TODO(jmadill): Offset handling.
            gl::Buffer *bufferGL = binding.buffer.get();
            ASSERT(bufferGL);
            BufferVk *bufferVk = GetImplAs<BufferVk>(bufferGL);
            vertexHandles.push_back(bufferVk->getVkBuffer().getHandle());
            vertexOffsets.push_back(0);

            bufferVk->setQueueSerial(queueSerial);
        }
        else
        {
            UNIMPLEMENTED();
        }
    }

    vk::CommandBuffer *commandBuffer = nullptr;
    ANGLE_TRY(mRenderer->getStartedCommandBuffer(&commandBuffer));
    ANGLE_TRY(vkFBO->beginRenderPass(device, commandBuffer, queueSerial, state));

    commandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mCurrentPipeline);
    commandBuffer->bindVertexBuffers(0, vertexHandles, vertexOffsets);
    commandBuffer->draw(count, 1, first, 0);
    commandBuffer->endRenderPass();

    return gl::NoError();
}

gl::Error ContextVk::drawArraysInstanced(GLenum mode,
                                         GLint first,
                                         GLsizei count,
                                         GLsizei instanceCount)
{
    UNIMPLEMENTED();
    return gl::Error(GL_INVALID_OPERATION);
}

gl::Error ContextVk::drawElements(GLenum mode,
                                  GLsizei count,
                                  GLenum type,
                                  const void *indices,
                                  const gl::IndexRange &indexRange)
{
    UNIMPLEMENTED();
    return gl::Error(GL_INVALID_OPERATION);
}

gl::Error ContextVk::drawElementsInstanced(GLenum mode,
                                           GLsizei count,
                                           GLenum type,
                                           const void *indices,
                                           GLsizei instances,
                                           const gl::IndexRange &indexRange)
{
    UNIMPLEMENTED();
    return gl::Error(GL_INVALID_OPERATION);
}

gl::Error ContextVk::drawRangeElements(GLenum mode,
                                       GLuint start,
                                       GLuint end,
                                       GLsizei count,
                                       GLenum type,
                                       const void *indices,
                                       const gl::IndexRange &indexRange)
{
    return gl::NoError();
}

VkDevice ContextVk::getDevice() const
{
    return mRenderer->getDevice();
}

vk::Error ContextVk::getStartedCommandBuffer(vk::CommandBuffer **commandBufferOut)
{
    return mRenderer->getStartedCommandBuffer(commandBufferOut);
}

vk::Error ContextVk::submitCommands(vk::CommandBuffer *commandBuffer)
{
    setQueueSerial(mRenderer->getCurrentQueueSerial());
    ANGLE_TRY(mRenderer->submitCommandBuffer(commandBuffer));
    return vk::NoError();
}

gl::Error ContextVk::drawArraysIndirect(GLenum mode, const void *indirect)
{
    UNIMPLEMENTED();
    return gl::InternalError() << "DrawArraysIndirect hasn't been implemented for vulkan backend.";
}

gl::Error ContextVk::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
{
    UNIMPLEMENTED();
    return gl::InternalError()
           << "DrawElementsIndirect hasn't been implemented for vulkan backend.";
}

GLenum ContextVk::getResetStatus()
{
    UNIMPLEMENTED();
    return GL_NO_ERROR;
}

std::string ContextVk::getVendorString() const
{
    UNIMPLEMENTED();
    return std::string();
}

std::string ContextVk::getRendererDescription() const
{
    return mRenderer->getRendererDescription();
}

void ContextVk::insertEventMarker(GLsizei length, const char *marker)
{
    UNIMPLEMENTED();
}

void ContextVk::pushGroupMarker(GLsizei length, const char *marker)
{
    UNIMPLEMENTED();
}

void ContextVk::popGroupMarker()
{
    UNIMPLEMENTED();
}

void ContextVk::syncState(const gl::State::DirtyBits &dirtyBits)
{
    // TODO(jmadill): Vulkan dirty bits.
    if (dirtyBits.any())
    {
        invalidateCurrentPipeline();
    }
}

GLint ContextVk::getGPUDisjoint()
{
    UNIMPLEMENTED();
    return GLint();
}

GLint64 ContextVk::getTimestamp()
{
    UNIMPLEMENTED();
    return GLint64();
}

void ContextVk::onMakeCurrent(const gl::ContextState & /*data*/)
{
}

const gl::Caps &ContextVk::getNativeCaps() const
{
    return mRenderer->getNativeCaps();
}

const gl::TextureCapsMap &ContextVk::getNativeTextureCaps() const
{
    return mRenderer->getNativeTextureCaps();
}

const gl::Extensions &ContextVk::getNativeExtensions() const
{
    return mRenderer->getNativeExtensions();
}

const gl::Limitations &ContextVk::getNativeLimitations() const
{
    return mRenderer->getNativeLimitations();
}

CompilerImpl *ContextVk::createCompiler()
{
    return new CompilerVk();
}

ShaderImpl *ContextVk::createShader(const gl::ShaderState &state)
{
    return new ShaderVk(state);
}

ProgramImpl *ContextVk::createProgram(const gl::ProgramState &state)
{
    return new ProgramVk(state);
}

FramebufferImpl *ContextVk::createFramebuffer(const gl::FramebufferState &state)
{
    return FramebufferVk::CreateUserFBO(state);
}

TextureImpl *ContextVk::createTexture(const gl::TextureState &state)
{
    return new TextureVk(state);
}

RenderbufferImpl *ContextVk::createRenderbuffer()
{
    return new RenderbufferVk();
}

BufferImpl *ContextVk::createBuffer(const gl::BufferState &state)
{
    return new BufferVk(state);
}

VertexArrayImpl *ContextVk::createVertexArray(const gl::VertexArrayState &state)
{
    return new VertexArrayVk(state);
}

QueryImpl *ContextVk::createQuery(GLenum type)
{
    return new QueryVk(type);
}

FenceNVImpl *ContextVk::createFenceNV()
{
    return new FenceNVVk();
}

FenceSyncImpl *ContextVk::createFenceSync()
{
    return new FenceSyncVk();
}

TransformFeedbackImpl *ContextVk::createTransformFeedback(const gl::TransformFeedbackState &state)
{
    return new TransformFeedbackVk(state);
}

SamplerImpl *ContextVk::createSampler()
{
    return new SamplerVk();
}

std::vector<PathImpl *> ContextVk::createPaths(GLsizei)
{
    return std::vector<PathImpl *>();
}

// TODO(jmadill): Use pipeline cache.
void ContextVk::invalidateCurrentPipeline()
{
    mRenderer->enqueueGarbageOrDeleteNow(*this, mCurrentPipeline);
}

gl::Error ContextVk::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
{
    UNIMPLEMENTED();
    return gl::Error(GL_INVALID_OPERATION);
}

}  // namespace rx
