/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "src/gpu/ganesh/vk/GrVkRenderPass.h"

#include "src/gpu/KeyBuilder.h"
#include "src/gpu/ganesh/GrProcessor.h"
#include "src/gpu/ganesh/vk/GrVkFramebuffer.h"
#include "src/gpu/ganesh/vk/GrVkGpu.h"
#include "src/gpu/ganesh/vk/GrVkRenderTarget.h"
#include "src/gpu/ganesh/vk/GrVkUtil.h"

typedef GrVkRenderPass::AttachmentsDescriptor::AttachmentDesc AttachmentDesc;

void setup_vk_attachment_description(VkAttachmentDescription* attachment,
                                     const AttachmentDesc& desc,
                                     VkImageLayout startLayout,
                                     VkImageLayout endLayout) {
    attachment->flags = 0;
    attachment->format = desc.fFormat;
    SkAssertResult(GrSampleCountToVkSampleCount(desc.fSamples, &attachment->samples));
    switch (startLayout) {
        case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
        case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
        case VK_IMAGE_LAYOUT_GENERAL:
            attachment->loadOp = desc.fLoadStoreOps.fLoadOp;
            attachment->storeOp = desc.fLoadStoreOps.fStoreOp;
            attachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
            attachment->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
            break;
        case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
            attachment->loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
            attachment->storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
            attachment->stencilLoadOp = desc.fLoadStoreOps.fLoadOp;
            attachment->stencilStoreOp = desc.fLoadStoreOps.fStoreOp;
            break;
        default:
            SK_ABORT("Unexpected attachment layout");
    }

    attachment->initialLayout = startLayout;
    attachment->finalLayout = endLayout == VK_IMAGE_LAYOUT_UNDEFINED ? startLayout : endLayout;
}

GrVkRenderPass* GrVkRenderPass::CreateSimple(GrVkGpu* gpu,
                                             AttachmentsDescriptor* attachmentsDescriptor,
                                             AttachmentFlags attachmentFlags,
                                             SelfDependencyFlags selfDepFlags,
                                             LoadFromResolve loadFromResolve) {
    static const GrVkRenderPass::LoadStoreOps kBasicLoadStoreOps(VK_ATTACHMENT_LOAD_OP_LOAD,
                                                                 VK_ATTACHMENT_STORE_OP_STORE);
    switch (loadFromResolve) {
        case LoadFromResolve::kNo:
            return Create(gpu, attachmentFlags, attachmentsDescriptor, kBasicLoadStoreOps,
                          kBasicLoadStoreOps, kBasicLoadStoreOps, selfDepFlags, loadFromResolve);
        case LoadFromResolve::kLoad: {
            static const GrVkRenderPass::LoadStoreOps kDiscardLoadStoreOps(
                    VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE);
            return Create(gpu, attachmentFlags, attachmentsDescriptor, kDiscardLoadStoreOps,
                          kBasicLoadStoreOps, kBasicLoadStoreOps, selfDepFlags, loadFromResolve);
        }
    }
    SkUNREACHABLE;
}

GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
                                       const GrVkRenderPass& compatibleRenderPass,
                                       const LoadStoreOps& colorOp,
                                       const LoadStoreOps& resolveOp,
                                       const LoadStoreOps& stencilOp) {
    AttachmentFlags attachmentFlags = compatibleRenderPass.fAttachmentFlags;
    AttachmentsDescriptor attachmentsDescriptor = compatibleRenderPass.fAttachmentsDescriptor;
    SelfDependencyFlags selfDepFlags = compatibleRenderPass.fSelfDepFlags;
    LoadFromResolve loadFromResolve = compatibleRenderPass.fLoadFromResolve;
    return Create(gpu, attachmentFlags, &attachmentsDescriptor, colorOp, resolveOp, stencilOp,
                  selfDepFlags, loadFromResolve);
}

GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
                                       AttachmentFlags attachmentFlags,
                                       AttachmentsDescriptor* attachmentsDescriptor,
                                       const LoadStoreOps& colorOp,
                                       const LoadStoreOps& resolveOp,
                                       const LoadStoreOps& stencilOp,
                                       SelfDependencyFlags selfDepFlags,
                                       LoadFromResolve loadFromResolve) {
    SkASSERT(!SkToBool(selfDepFlags & SelfDependencyFlags::kForNonCoherentAdvBlend) ||
             gpu->caps()->advancedBlendEquationSupport());
    SkASSERT(!SkToBool(selfDepFlags & SelfDependencyFlags::kForInputAttachment) ||
             gpu->caps()->textureBarrierSupport());

    // If we have a resolve attachment, we will always do a resolve into it. Thus it doesn't make
    // sense not to store the resolve attachment at the end of the render pass.
    //
    // Currently today (when not using discardable msaa images) we load and store the the msaa image
    // and then use the copy resolve command to handle the resolving. If instead we moved to doing
    // the resolving at the end of the last render pass, we would probably want a separate flag
    // for having a resolve attachment versus actually doing the resolving. This would allow us to
    // use the same VkPiplines for render passes where we resolve and those we don't since each will
    // always have the resolve attachment. The actual resolving or not does not affect render pass
    // compatibility if there is only one sub pass, just the presence of the attachment or not.
    SkASSERT(!SkToBool(attachmentFlags & kResolve_AttachmentFlag) ||
             resolveOp.fStoreOp == VK_ATTACHMENT_STORE_OP_STORE);

    SkASSERT(loadFromResolve == LoadFromResolve::kNo ||
             (SkToBool(attachmentFlags & kColor_AttachmentFlag) &&
              SkToBool(attachmentFlags & kResolve_AttachmentFlag)));

#ifdef SK_DEBUG
    if (loadFromResolve == LoadFromResolve::kLoad) {
        // If we are loading the resolve image into the msaa color attachment then we should not be
        // loading or storing the msaa attachment. Additionally we need to make sure we are loading
        // the resolve so it can be copied into the msaa color attachment.
        SkASSERT(colorOp.fLoadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE);
        SkASSERT(colorOp.fStoreOp == VK_ATTACHMENT_STORE_OP_DONT_CARE);
        SkASSERT(resolveOp.fLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD);
    }
#endif

    uint32_t numAttachments = attachmentsDescriptor->fAttachmentCount;
    // Attachment descriptions to be set on the render pass
    SkTArray<VkAttachmentDescription> attachments(numAttachments);
    attachments.reset(numAttachments);
    memset(attachments.begin(), 0, numAttachments * sizeof(VkAttachmentDescription));

    // Refs to attachments on the render pass (as described by the VkAttachmentDescription above),
    // that are used by the subpass.
    VkAttachmentReference colorRef;
    VkAttachmentReference resolveRef;
    VkAttachmentReference resolveLoadInputRef;
    VkAttachmentReference stencilRef;
    uint32_t currentAttachment = 0;

    // Go through each of the attachment types (color, stencil) and set the necessary
    // on the various Vk structs.
    VkSubpassDescription subpassDescs[2];
    memset(subpassDescs, 0, 2*sizeof(VkSubpassDescription));
    const int mainSubpass = loadFromResolve == LoadFromResolve::kLoad ? 1 : 0;
    VkSubpassDescription& subpassDescMain = subpassDescs[mainSubpass];
    subpassDescMain.flags = 0;
    subpassDescMain.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
    subpassDescMain.inputAttachmentCount = 0;
    subpassDescMain.pInputAttachments = nullptr;
    subpassDescMain.pResolveAttachments = nullptr;

    uint32_t clearValueCount = 0;

    VkSubpassDependency dependencies[2];
    int currentDependency = 0;

    if (attachmentFlags & kColor_AttachmentFlag) {
        // set up color attachment
        bool needsGeneralLayout = SkToBool(selfDepFlags & SelfDependencyFlags::kForInputAttachment);
        VkImageLayout layout = needsGeneralLayout ? VK_IMAGE_LAYOUT_GENERAL
                                                  : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

        attachmentsDescriptor->fColor.fLoadStoreOps = colorOp;

        setup_vk_attachment_description(&attachments[currentAttachment],
                                        attachmentsDescriptor->fColor,
                                        layout, layout);
        // setup subpass use of attachment
        colorRef.attachment = currentAttachment++;
        colorRef.layout = layout;
        subpassDescMain.colorAttachmentCount = 1;

        if (selfDepFlags != SelfDependencyFlags::kNone) {
            VkSubpassDependency& dependency = dependencies[currentDependency++];
            dependency.srcSubpass = mainSubpass;
            dependency.dstSubpass = mainSubpass;
            dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
            dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
            dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
            dependency.dstStageMask = 0;
            dependency.dstAccessMask = 0;

            if (selfDepFlags & SelfDependencyFlags::kForNonCoherentAdvBlend) {
                // If we have coherent support we shouldn't be needing a self dependency
                SkASSERT(!gpu->caps()->advancedCoherentBlendEquationSupport());
                dependency.dstStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
                dependency.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT;
            }
            if (selfDepFlags & SelfDependencyFlags::kForInputAttachment) {
                SkASSERT(gpu->vkCaps().maxInputAttachmentDescriptors());

                subpassDescMain.inputAttachmentCount = 1;
                subpassDescMain.pInputAttachments = &colorRef;

                dependency.dstStageMask |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
                dependency.dstAccessMask |= VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
            }
        }

        if (VK_ATTACHMENT_LOAD_OP_CLEAR == colorOp.fLoadOp) {
            clearValueCount = colorRef.attachment + 1;
        }
    } else {
        // I don't think there should ever be a time where we don't have a color attachment
        SkASSERT(false);
        SkASSERT(selfDepFlags == SelfDependencyFlags::kNone);
        colorRef.attachment = VK_ATTACHMENT_UNUSED;
        colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
        subpassDescMain.colorAttachmentCount = 0;
    }

    subpassDescMain.pColorAttachments = &colorRef;

    if (attachmentFlags & kResolve_AttachmentFlag) {
        attachmentsDescriptor->fResolve.fLoadStoreOps = resolveOp;

        VkImageLayout layout = loadFromResolve == LoadFromResolve::kLoad
                                       ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
                                       : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

        setup_vk_attachment_description(&attachments[currentAttachment],
                                        attachmentsDescriptor->fResolve,
                                        layout,
                                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);

        // setup main subpass use of attachment
        resolveRef.attachment = currentAttachment++;
        resolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

        subpassDescMain.pResolveAttachments = &resolveRef;

        // Setup the load subpass and set subpass dependendcies
        if (loadFromResolve == LoadFromResolve::kLoad) {
            resolveLoadInputRef.attachment = resolveRef.attachment;
            resolveLoadInputRef.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;

            // The load subpass will always be the first
            VkSubpassDescription& subpassDescLoad = subpassDescs[0];
            subpassDescLoad.flags = 0;
            subpassDescLoad.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
            subpassDescLoad.inputAttachmentCount = 1;
            subpassDescLoad.pInputAttachments = &resolveLoadInputRef;
            subpassDescLoad.colorAttachmentCount = 1;
            subpassDescLoad.pColorAttachments = &colorRef;
            subpassDescLoad.pResolveAttachments = nullptr;
            subpassDescLoad.pDepthStencilAttachment = nullptr;
            subpassDescLoad.preserveAttachmentCount = 0;
            subpassDescLoad.pPreserveAttachments = nullptr;

            VkSubpassDependency& dependency = dependencies[currentDependency++];
            dependency.srcSubpass = 0;
            dependency.dstSubpass = mainSubpass;
            dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
            dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
            dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
            dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
            dependency.dstAccessMask =
                    VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
        }
    }


    if (attachmentFlags & kStencil_AttachmentFlag) {
        // set up stencil attachment
        attachmentsDescriptor->fStencil.fLoadStoreOps = stencilOp;
        setup_vk_attachment_description(&attachments[currentAttachment],
                                        attachmentsDescriptor->fStencil,
                                        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
        // setup subpass use of attachment
        stencilRef.attachment = currentAttachment++;
        stencilRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
        if (VK_ATTACHMENT_LOAD_OP_CLEAR == stencilOp.fLoadOp) {
            clearValueCount = std::max(clearValueCount, stencilRef.attachment + 1);
        }
    } else {
        stencilRef.attachment = VK_ATTACHMENT_UNUSED;
        stencilRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
    }
    subpassDescMain.pDepthStencilAttachment = &stencilRef;

    subpassDescMain.preserveAttachmentCount = 0;
    subpassDescMain.pPreserveAttachments = nullptr;

    SkASSERT(numAttachments == currentAttachment);

    uint32_t subpassCount = loadFromResolve == LoadFromResolve::kLoad ? 2 : 1;

    // Create the VkRenderPass compatible with the attachment descriptions above
    VkRenderPassCreateInfo createInfo;
    memset(&createInfo, 0, sizeof(VkRenderPassCreateInfo));
    createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
    createInfo.pNext = nullptr;
    createInfo.flags = 0;
    createInfo.attachmentCount = numAttachments;
    createInfo.pAttachments = attachments.begin();
    createInfo.subpassCount = subpassCount;
    createInfo.pSubpasses = subpassDescs;
    createInfo.dependencyCount = currentDependency;
    createInfo.pDependencies = dependencies;

    VkResult result;
    VkRenderPass renderPass;
    GR_VK_CALL_RESULT(gpu, result, CreateRenderPass(gpu->device(),
                                                    &createInfo,
                                                    nullptr,
                                                    &renderPass));
    if (result != VK_SUCCESS) {
        return nullptr;
    }

    VkExtent2D granularity;
    // Get granularity for this render pass
    GR_VK_CALL(gpu->vkInterface(), GetRenderAreaGranularity(gpu->device(),
                                                            renderPass,
                                                            &granularity));

    return new GrVkRenderPass(gpu, renderPass, attachmentFlags, *attachmentsDescriptor,
                              selfDepFlags, loadFromResolve, granularity, clearValueCount);
}

GrVkRenderPass::GrVkRenderPass(const GrVkGpu* gpu, VkRenderPass renderPass, AttachmentFlags flags,
                               const AttachmentsDescriptor& descriptor,
                               SelfDependencyFlags selfDepFlags,
                               LoadFromResolve loadFromResolve,
                               const VkExtent2D& granularity, uint32_t clearValueCount)
        : INHERITED(gpu)
        , fRenderPass(renderPass)
        , fAttachmentFlags(flags)
        , fAttachmentsDescriptor(descriptor)
        , fSelfDepFlags(selfDepFlags)
        , fLoadFromResolve(loadFromResolve)
        , fGranularity(granularity)
        , fClearValueCount(clearValueCount) {
}

void GrVkRenderPass::freeGPUData() const {
    if (!(fAttachmentFlags & kExternal_AttachmentFlag)) {
        GR_VK_CALL(fGpu->vkInterface(), DestroyRenderPass(fGpu->device(), fRenderPass, nullptr));
    }
}

bool GrVkRenderPass::colorAttachmentIndex(uint32_t* index) const {
    *index = fColorAttachmentIndex;
    if ((fAttachmentFlags & kColor_AttachmentFlag) ||
        (fAttachmentFlags & kExternal_AttachmentFlag)) {
        return true;
    }
    return false;
}

// Works under the assumption that stencil attachment will always be after the color and resolve
// attachments.
bool GrVkRenderPass::stencilAttachmentIndex(uint32_t* index) const {
    *index = 0;
    if (fAttachmentFlags & kColor_AttachmentFlag) {
        ++(*index);
    }
    if (fAttachmentFlags & kStencil_AttachmentFlag) {
        return true;
    }
    return false;
}

bool GrVkRenderPass::isCompatible(const AttachmentsDescriptor& desc,
                                  const AttachmentFlags& flags,
                                  SelfDependencyFlags selfDepFlags,
                                  LoadFromResolve loadFromResolve) const {
    SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
    if (flags != fAttachmentFlags) {
        return false;
    }

    if (fAttachmentFlags & kColor_AttachmentFlag) {
        if (!fAttachmentsDescriptor.fColor.isCompatible(desc.fColor)) {
            return false;
        }
    }
    if (fAttachmentFlags & kResolve_AttachmentFlag) {
        if (!fAttachmentsDescriptor.fResolve.isCompatible(desc.fResolve)) {
            return false;
        }
    }
    if (fAttachmentFlags & kStencil_AttachmentFlag) {
        if (!fAttachmentsDescriptor.fStencil.isCompatible(desc.fStencil)) {
            return false;
        }
    }

    if (fSelfDepFlags != selfDepFlags) {
        return false;
    }

    if (fLoadFromResolve != loadFromResolve) {
        return false;
    }

    return true;
}

bool GrVkRenderPass::isCompatible(GrVkRenderTarget* target,
                                  SelfDependencyFlags selfDepFlags,
                                  LoadFromResolve loadFromResolve) const {
    SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));

    AttachmentsDescriptor desc;
    AttachmentFlags flags;
    target->getAttachmentsDescriptor(&desc, &flags, this->hasResolveAttachment(),
                                     this->hasStencilAttachment());

    return this->isCompatible(desc, flags, selfDepFlags, loadFromResolve);
}

bool GrVkRenderPass::isCompatible(const GrVkRenderPass& renderPass) const {
    SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
    return this->isCompatible(renderPass.fAttachmentsDescriptor, renderPass.fAttachmentFlags,
                              renderPass.fSelfDepFlags, renderPass.fLoadFromResolve);
}

bool GrVkRenderPass::isCompatibleExternalRP(VkRenderPass renderPass) const {
    SkASSERT(fAttachmentFlags & kExternal_AttachmentFlag);
    return fRenderPass == renderPass;
}

bool GrVkRenderPass::equalLoadStoreOps(const LoadStoreOps& colorOps,
                                       const LoadStoreOps& resolveOps,
                                       const LoadStoreOps& stencilOps) const {
    SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
    if (fAttachmentFlags & kColor_AttachmentFlag) {
        if (fAttachmentsDescriptor.fColor.fLoadStoreOps != colorOps) {
            return false;
        }
    }
    if (fAttachmentFlags & kResolve_AttachmentFlag) {
        if (fAttachmentsDescriptor.fResolve.fLoadStoreOps != resolveOps) {
            return false;
        }
    }
    if (fAttachmentFlags & kStencil_AttachmentFlag) {
        if (fAttachmentsDescriptor.fStencil.fLoadStoreOps != stencilOps) {
            return false;
        }
    }
    return true;
}

void GrVkRenderPass::genKey(skgpu::KeyBuilder* b) const {
    GenKey(b, fAttachmentFlags, fAttachmentsDescriptor, fSelfDepFlags,
           fLoadFromResolve, (uint64_t)fRenderPass);
}

void GrVkRenderPass::GenKey(skgpu::KeyBuilder* b,
                            AttachmentFlags attachmentFlags,
                            const AttachmentsDescriptor& attachmentsDescriptor,
                            SelfDependencyFlags selfDepFlags,
                            LoadFromResolve loadFromResolve,
                            uint64_t externalRenderPass) {
    b->add32(attachmentFlags);
    if (attachmentFlags & kColor_AttachmentFlag) {
        b->add32(attachmentsDescriptor.fColor.fFormat);
        b->add32(attachmentsDescriptor.fColor.fSamples);
    }
    if (attachmentFlags & kResolve_AttachmentFlag) {
        b->add32(attachmentsDescriptor.fResolve.fFormat);
        b->add32(attachmentsDescriptor.fResolve.fSamples);
    }
    if (attachmentFlags & kStencil_AttachmentFlag) {
        b->add32(attachmentsDescriptor.fStencil.fFormat);
        b->add32(attachmentsDescriptor.fStencil.fSamples);
    }

    uint32_t extraFlags = (uint32_t)selfDepFlags;
    SkASSERT(extraFlags < (1 << 30));
    SkASSERT((uint32_t)loadFromResolve <= 2);
    extraFlags |= ((uint32_t)loadFromResolve << 30);

    b->add32(extraFlags);

    if (attachmentFlags & kExternal_AttachmentFlag) {
        SkASSERT(!(attachmentFlags & ~kExternal_AttachmentFlag));
        b->add32((uint32_t)(externalRenderPass & 0xFFFFFFFF));
        b->add32((uint32_t)(externalRenderPass>>32));
    }
}
