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

#include "src/gpu/graphite/vk/VulkanRenderPass.h"

#include "include/gpu/graphite/vk/VulkanGraphiteTypes.h"
#include "src/gpu/graphite/RenderPassDesc.h"
#include "src/gpu/graphite/Texture.h"
#include "src/gpu/graphite/vk/VulkanCommandBuffer.h"
#include "src/gpu/graphite/vk/VulkanGraphiteUtils.h"
#include "src/gpu/graphite/vk/VulkanSharedContext.h"
#include "src/gpu/graphite/vk/VulkanTexture.h"

#include <limits>

namespace skgpu::graphite {

static constexpr uint32_t kColorFormatOffset = 0;
static constexpr uint32_t kDepthStencilFormatOffset = kColorFormatOffset + 8;
static constexpr uint32_t kSampleCountOffset = kDepthStencilFormatOffset + 8;
static constexpr uint32_t kColorLoadOpOffset = kSampleCountOffset + kNumSampleKeyBits;
static constexpr uint32_t kColorStoreOpOffset = kColorLoadOpOffset + 2;
static constexpr uint32_t kResolveLoadOpOffset = kColorStoreOpOffset + 1;
static constexpr uint32_t kResolveStoreOpOffset = kResolveLoadOpOffset + 2;
static constexpr uint32_t kMSRTTOffset = kResolveStoreOpOffset + 1;

static constexpr uint32_t kFormatMask = 0xFF;
static constexpr uint32_t kSampleCountMask = 0x7;
static constexpr uint32_t kLoadOpMask = 0x3;
static constexpr uint32_t kStoreOpMask = 0x1;
static constexpr uint32_t kMSRTTMask = 0x1;

uint32_t VulkanRenderPass::GetRenderPassKey(const RenderPassDesc& originalRenderPassDesc,
                                            bool compatibleForPipelineKey) {
    const RenderPassDesc renderPassDesc =
            compatibleForPipelineKey ? MakePipelineCompatibleRenderPass(originalRenderPassDesc)
                                     : originalRenderPassDesc;
    const AttachmentDesc color = renderPassDesc.fColorAttachment;
    const AttachmentDesc resolve = renderPassDesc.fColorResolveAttachment;
    const AttachmentDesc depthStencil = renderPassDesc.fDepthStencilAttachment;

    const bool hasResolveAttachment = resolve.fFormat != TextureFormat::kUnsupported;
    const bool isMultisampledRenderToSingleSampled =
            RenderPassDescWillImplicitlyLoadMSAA(renderPassDesc);
    // Silence warning about unused variable in release builds.
    (void)hasResolveAttachment;

    // Current assumptions in the render pass desc, allowing us to create a smaller key:
    SkASSERT(color.fFormat != TextureFormat::kUnsupported);
    SkASSERT(!hasResolveAttachment || resolve.fFormat == color.fFormat);
    SkASSERT(depthStencil.fFormat == TextureFormat::kUnsupported ||
             depthStencil.fSampleCount == color.fSampleCount);
    SkASSERT(depthStencil.fFormat == TextureFormat::kUnsupported ||
             depthStencil.fLoadOp == LoadOp::kClear);
    SkASSERT(depthStencil.fFormat == TextureFormat::kUnsupported ||
             depthStencil.fStoreOp == StoreOp::kDiscard);
    SkASSERT(!hasResolveAttachment || resolve.fSampleCount == SampleCount::k1);
    SkASSERT(color.fSampleCount == renderPassDesc.fSampleCount ||
             isMultisampledRenderToSingleSampled);
    SkASSERT(!hasResolveAttachment || color.fLoadOp == LoadOp::kDiscard ||
             color.fLoadOp == LoadOp::kClear);
    SkASSERT(!hasResolveAttachment || resolve.fLoadOp == LoadOp::kDiscard ||
             resolve.fLoadOp == LoadOp::kLoad);
    SkASSERT(!hasResolveAttachment || color.fStoreOp == StoreOp::kDiscard);

    // The following information uniquely defines the render pass:
    //
    // Color format (CF): TextureFormat, fits in 6 bits
    // Depth/stencil format (DSF): TextureFormat, fits in 6 bits
    // Sample count (M): SampleToKey(count), fits in 3 bits
    // Color load op (L): LoadOp, fits in 2 bits
    // Color store op (S): StoreOp, fits in 1 bit
    // Whether multisampled data s loaded from resolve attachment: fits in 1 bit
    // Whether rendering multisampled->single-sampled (MSRTSS): fits in 1 bit
    //
    // Note that technically, renderable color formats can fit in 5 bits and depth/stencil formats
    // in 3 bits if more packing is needed.
    //
    // Depth/stencil load op is always kClear, and store op is always kDiscard.
    // Color load op is either found in fColorAttachment if no resolve attachment, or can be derived
    // from a combination of the load ops specified in the color and resolve attachments:
    //   * If color attachment is kClear, load op is kClear
    //   * Otherwise, if resolve attachment is kLoad, load op is kLoad
    //   * Otherwise, it's kDiscard
    // Color store op is either found in fColorAttachment if no resolve attachment, or it's found in
    // fColorResolveAttachment.
    //
    // There are currently lots of free bits, so with regards to load/store ops, we don't try too
    // hard to pack things.  Including the color and resolve's load and store ops obviates the need
    // to store a "load MSAA from resolve" bit.  The format of the key is thus:
    //
    //       LSB                                                         MSB
    //       +----+-----+---+---+---+------------+------------+--------+---+
    //       | CF | DSF | M | L | S | L(resolve) | S(resolve) | MSRTSS | 0 |
    //       +----+-----+---+---+---+------------+------------+--------+---+
    //  bits   8     8    3   2   1       2            1           1     6
    //
    static_assert(static_cast<uint32_t>(TextureFormat::kLast) < (1 << 8));
    static_assert(static_cast<uint32_t>(LoadOp::kLast) < (1 << 2));
    static_assert(static_cast<uint32_t>(StoreOp::kLast) < (1 << 1));

    const uint32_t key =
            (static_cast<uint32_t>(color.fFormat) << kColorFormatOffset) |
            (static_cast<uint32_t>(depthStencil.fFormat) << kDepthStencilFormatOffset) |
            (SamplesToKey(renderPassDesc.fSampleCount) << kSampleCountOffset) |
            (static_cast<uint32_t>(color.fLoadOp) << kColorLoadOpOffset) |
            (static_cast<uint32_t>(color.fStoreOp) << kColorStoreOpOffset) |
            (static_cast<uint32_t>(resolve.fLoadOp) << kResolveLoadOpOffset) |
            (static_cast<uint32_t>(resolve.fStoreOp) << kResolveStoreOpOffset) |
            (static_cast<uint32_t>(isMultisampledRenderToSingleSampled) << kMSRTTOffset);

    return key;
}

void VulkanRenderPass::ExtractRenderPassDesc(uint32_t key,
                                             Swizzle writeSwizzle,
                                             DstReadStrategy dstReadStrategy,
                                             RenderPassDesc* renderPassDesc) {
    // See comment in GetRenderPassKey() describing the format of the key.
    const TextureFormat colorFormat =
            SkTo<TextureFormat>((key >> kColorFormatOffset) & kFormatMask);
    const TextureFormat depthStencilFormat =
            SkTo<TextureFormat>((key >> kDepthStencilFormatOffset) & kFormatMask);
    const SampleCount sampleCount = KeyToSamples((key >> kSampleCountOffset) & kSampleCountMask);
    const LoadOp colorLoadOp = SkTo<LoadOp>((key >> kColorLoadOpOffset) & kLoadOpMask);
    const StoreOp colorStoreOp = SkTo<StoreOp>((key >> kColorStoreOpOffset) & kStoreOpMask);
    const LoadOp resolveLoadOp = SkTo<LoadOp>((key >> kResolveLoadOpOffset) & kLoadOpMask);
    const StoreOp resolveStoreOp = SkTo<StoreOp>((key >> kResolveStoreOpOffset) & kStoreOpMask);
    const bool isMultisampledRenderToSingleSampled = SkTo<bool>((key >> kMSRTTOffset) & kMSRTTMask);

    // Relationship between render pass sample count, attachment's sample counts and resolve
    // attachments:
    //
    //                  | RP Samples == 1 | RP Samples > 1 && MSRTSS | RP Samples > 1 && !MSRTSS |
    //                  +-----------------+--------------------------+---------------------------+
    //  Has Resolve?    |       No        |            No            |           Yes             |
    //                  +-----------------+--------------------------+---------------------------+
    //  Resolve Format  |   Unsupported   |       Unsupported        |       Color Format        |
    //                  +-----------------+--------------------------+---------------------------+
    //  Color Samples   | RP Samples (1)  |            1             |        RP Samples         |
    //                  +-----------------+--------------------------+---------------------------+
    //  D/S Samples     | RP Samples (1)  |            1             |        RP Samples         |
    //                  +-----------------+--------------------------+---------------------------+
    //
    // The color and resolve attachment's load/store op are already stored in the key. For
    // depth/stencil, load op is always Clear and store op is always Discard.
    const SampleCount attachmentSamples = isMultisampledRenderToSingleSampled ? SampleCount::k1
                                                                              : sampleCount;

    *renderPassDesc = {};
    renderPassDesc->fColorAttachment = {colorFormat, colorLoadOp, colorStoreOp, attachmentSamples};
    renderPassDesc->fDepthStencilAttachment = {
            depthStencilFormat, LoadOp::kClear, StoreOp::kDiscard, attachmentSamples};
    if (attachmentSamples > SampleCount::k1 && !isMultisampledRenderToSingleSampled) {
        renderPassDesc->fColorResolveAttachment = {colorFormat,
                                                   resolveLoadOp,
                                                   resolveStoreOp,
                                                   SampleCount::k1};
    }
    renderPassDesc->fSampleCount = sampleCount;
    renderPassDesc->fWriteSwizzle = writeSwizzle;
    renderPassDesc->fDstReadStrategy = dstReadStrategy;
}

namespace {

template <typename AttachmentDescription>
void setup_vk_attachment_description(AttachmentDescription* outAttachment,
                                     const AttachmentDesc& desc,
                                     const AttachmentDescription& defaultAttachmentDescription,
                                     bool isColor) {
    static_assert((int) LoadOp::kLoad     == (int) VK_ATTACHMENT_LOAD_OP_LOAD);
    static_assert((int) LoadOp::kClear    == (int) VK_ATTACHMENT_LOAD_OP_CLEAR);
    static_assert((int) LoadOp::kDiscard  == (int) VK_ATTACHMENT_LOAD_OP_DONT_CARE);
    static_assert((int) StoreOp::kStore   == (int) VK_ATTACHMENT_STORE_OP_STORE);
    static_assert((int) StoreOp::kDiscard == (int) VK_ATTACHMENT_STORE_OP_DONT_CARE);

    VkAttachmentLoadOp vkLoadOp = static_cast<VkAttachmentLoadOp>(desc.fLoadOp);
    VkAttachmentStoreOp vkStoreOp = static_cast<VkAttachmentStoreOp>(desc.fStoreOp);

    *outAttachment = defaultAttachmentDescription;
    outAttachment->format = TextureFormatToVkFormat(desc.fFormat);
    outAttachment->samples = SampleCountToVkSampleCount(desc.fSampleCount);

    outAttachment->loadOp = vkLoadOp;
    outAttachment->storeOp = vkStoreOp;
    if (isColor) {
        outAttachment->initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
        outAttachment->finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
        outAttachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
        outAttachment->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
    } else {
        outAttachment->initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
        outAttachment->finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
        outAttachment->stencilLoadOp = vkLoadOp;
        outAttachment->stencilStoreOp = vkStoreOp;
    }
}

template <typename AttachmentDescription, typename AttachmentReference>
void populate_attachment_refs(const RenderPassDesc& renderPassDesc,
                              bool needLoadMSAAFromResolveSubpass,
                              skia_private::TArray<AttachmentDescription>& descs,
                              AttachmentReference& colorRef,
                              AttachmentReference& resolveRef,
                              AttachmentReference& resolveLoadInputRef,
                              AttachmentReference& depthStencilRef,
                              const AttachmentDescription& defaultAttachmentDescription) {
    // Note: See assumptions regarding RenderPassDesc structure in AddToKey().
    const AttachmentDesc color = renderPassDesc.fColorAttachment;
    const AttachmentDesc resolve = renderPassDesc.fColorResolveAttachment;
    const AttachmentDesc depthStencil = renderPassDesc.fDepthStencilAttachment;
    SkASSERT(color.fFormat != TextureFormat::kUnsupported);
    // If MSAA data needs to be loaded from the resolve attachment, there must be a resolve
    // attachment!
    SkASSERT(!needLoadMSAAFromResolveSubpass || resolve.fFormat != TextureFormat::kUnsupported);

    // If reading from the dst as an input attachment, we must use VK_IMAGE_LAYOUT_GENERAL
    // for the color attachment description. Use a general image layout for all renderpasses to
    // support this.
    //
    // As long as the initial/final layouts are VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, the
    // choice of the VK_IMAGE_LAYOUT_GENERAL for the subpass layout is efficient; the few GPUs
    // that treat VK_IMAGE_LAYOUT_GENERAL differently recognize this pattern and keep the
    // internal layout optimal.
    colorRef.layout = VK_IMAGE_LAYOUT_GENERAL;
    colorRef.attachment = descs.size();
    AttachmentDescription& vkColorAttachDesc = descs.push_back();
    setup_vk_attachment_description(&vkColorAttachDesc,
                                    color,
                                    defaultAttachmentDescription,
                                    /*isColor=*/true);

    if (resolve.fFormat != TextureFormat::kUnsupported) {
        resolveRef.attachment = descs.size();
        resolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
        if (needLoadMSAAFromResolveSubpass) {
            resolveLoadInputRef.attachment = resolveRef.attachment;
            // The resolve attachment is used as input attachment in the first subpass.  In that
            // subpass, it is only read from so the layout could have been read-only.  To avoid
            // special-casing this input attachment though, the VK_IMAGE_LAYOUT_GENERAL layout
            // is used like with the color attachment.  This is no less efficient than the
            // read-only layout when specified on the attachment ref.
            resolveLoadInputRef.layout = VK_IMAGE_LAYOUT_GENERAL;
        } else {
            resolveLoadInputRef.attachment = VK_ATTACHMENT_UNUSED;
        }

        AttachmentDescription& vkResolveAttachDesc = descs.push_back();
        setup_vk_attachment_description(&vkResolveAttachDesc,
                                        resolve,
                                        defaultAttachmentDescription,
                                        /*isColor=*/true);
    } else {
        resolveRef.attachment = resolveLoadInputRef.attachment = VK_ATTACHMENT_UNUSED;
    }

    if (depthStencil.fFormat != TextureFormat::kUnsupported) {
        depthStencilRef.attachment = descs.size();
        depthStencilRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

        AttachmentDescription& vkDepthStencilAttachDesc = descs.push_back();
        setup_vk_attachment_description(&vkDepthStencilAttachDesc,
                                        depthStencil,
                                        defaultAttachmentDescription,
                                        /*isColor=*/false);
    } else {
        depthStencilRef.attachment = VK_ATTACHMENT_UNUSED;
    }
}

template <typename SubpassDependency, typename SubpassDependencyArray>
void populate_subpass_dependencies(const VulkanSharedContext* context,
                                   SubpassDependencyArray& deps,
                                   bool needLoadMSAAFromResolveSubpass,
                                   const SubpassDependency& defaultSubpassDependency) {
    const int mainSubpassIdx = needLoadMSAAFromResolveSubpass ? 1 : 0;

    // Adding a single subpass self-dependency for color attachments is basically free, so apply
    // one to every RenderPass which has an input attachment on the main subpass. This is useful
    // because it means that as we perform draw calls, if we encounter a draw that uses a blend
    // operation requiring a dst read, we can avoid having to switch RenderPasses.

    const bool hasRasterizationOrderColorAttachmentAccess =
            context->vulkanCaps().supportsRasterizationOrderColorAttachmentAccess();
    const bool hasNonCoherentAdvancedBlend = context->vulkanCaps().blendEquationSupport() ==
                                             Caps::BlendEquationSupport::kAdvancedNoncoherent;

    if (!hasRasterizationOrderColorAttachmentAccess || hasNonCoherentAdvancedBlend) {
        SubpassDependency& selfDependency = deps.push_back();
        selfDependency = defaultSubpassDependency;
        selfDependency.srcSubpass = mainSubpassIdx;
        selfDependency.dstSubpass = mainSubpassIdx;
        selfDependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
        selfDependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
        selfDependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
        selfDependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
        selfDependency.dstAccessMask = 0;

        if (!hasRasterizationOrderColorAttachmentAccess) {
            selfDependency.dstStageMask |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
            selfDependency.dstAccessMask |= VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
        }
        if (hasNonCoherentAdvancedBlend) {
            selfDependency.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT;
        }
    }

    // If loading MSAA from resolve, enforce that subpass goes first with a subpass dependency.
    if (needLoadMSAAFromResolveSubpass) {
        SubpassDependency& dependency = deps.push_back();
        dependency = defaultSubpassDependency;
        dependency.srcSubpass = 0;
        dependency.dstSubpass = mainSubpassIdx;
        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;
    }
}

template <typename SubpassDescription, typename AttachmentReference>
void populate_main_subpass_desc(const VulkanCaps& caps,
                                SubpassDescription& mainSubpassDesc,
                                const AttachmentReference& colorRef,
                                const AttachmentReference& resolveRef,
                                const AttachmentReference& depthStencilRef) {
    mainSubpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
    // In the main subpass, the input attachment is the color attachment.  We could have excluded
    // this attachment if unused, but always assigning it to be the color attachment even when
    // unused allows for compatible-only renderpasses to be shared for pipelines that do read from
    // the dst and those that do not.
    mainSubpassDesc.inputAttachmentCount = 1;
    mainSubpassDesc.pInputAttachments = &colorRef;
    mainSubpassDesc.colorAttachmentCount = 1;
    mainSubpassDesc.pColorAttachments = &colorRef;
    mainSubpassDesc.pResolveAttachments = &resolveRef;
    mainSubpassDesc.pDepthStencilAttachment = &depthStencilRef;
}

void populate_subpass_descs(const VulkanCaps& caps,
                            skia_private::TArray<VkSubpassDescription>& descs,
                            const VkAttachmentReference& colorRef,
                            const VkAttachmentReference& resolveRef,
                            const VkAttachmentReference& resolveLoadInputRef,
                            const VkAttachmentReference& depthStencilRef) {
    // If loading MSAA from resolve, add the additional subpass to do so.
    if (resolveLoadInputRef.attachment != VK_ATTACHMENT_UNUSED) {
        VkSubpassDescription& loadSubpassDesc = descs.push_back();
        loadSubpassDesc = {};
        loadSubpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
        loadSubpassDesc.inputAttachmentCount = 1;
        loadSubpassDesc.pInputAttachments = &resolveLoadInputRef;
        loadSubpassDesc.colorAttachmentCount = 1;
        loadSubpassDesc.pColorAttachments = &colorRef;
    }

    VkSubpassDescription& mainSubpassDesc = descs.push_back();
    mainSubpassDesc = {};
    populate_main_subpass_desc(caps, mainSubpassDesc, colorRef, resolveRef, depthStencilRef);

    if (caps.supportsRasterizationOrderColorAttachmentAccess()) {
        for (VkSubpassDescription& desc : descs) {
            desc.flags = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT;
        }
    }
}

} // anonymous namespace

sk_sp<VulkanRenderPass> VulkanRenderPass::Make(const VulkanSharedContext* context,
                                               const RenderPassDesc& renderPassDesc) {
    const bool needLoadMSAAFromResolveSubpass =
            RenderPassDescWillLoadMSAAFromResolve(renderPassDesc);
    const bool isMultisampledRenderToSingleSampled =
            RenderPassDescWillImplicitlyLoadMSAA(renderPassDesc);

    VkResult result;
    VkRenderPass renderPass = VK_NULL_HANDLE;

    // VK_EXT_multisampled_render_to_single_sampled usage requires vkCreateRenderPass2.
    if (isMultisampledRenderToSingleSampled) {
        // Set up attachment descriptions + references. Declare them before having a helper populate
        // their values so we can reference them later during RP creation.
        SkASSERT(renderPassDesc.fColorResolveAttachment.fFormat == TextureFormat::kUnsupported);
        SkASSERT(!needLoadMSAAFromResolveSubpass);

        VkAttachmentDescription2 defaultAttachmentDescription = {};
        defaultAttachmentDescription.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2;

        VkAttachmentReference2 defaultAttachmentReference = {};
        defaultAttachmentReference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2;
        defaultAttachmentReference.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;

        skia_private::TArray<VkAttachmentDescription2> attachmentDescs;
        VkAttachmentReference2 colorRef = defaultAttachmentReference;
        VkAttachmentReference2 resolveRef = defaultAttachmentReference;
        VkAttachmentReference2 resolveLoadInputRef = defaultAttachmentReference;
        VkAttachmentReference2 depthStencilRef = defaultAttachmentReference;
        depthStencilRef.aspectMask =
                GetVkImageAspectFlags(renderPassDesc.fDepthStencilAttachment.fFormat);

        populate_attachment_refs(renderPassDesc,
                                 /*needLoadMSAAFromResolveSubpass=*/false,
                                 attachmentDescs,
                                 colorRef,
                                 resolveRef,
                                 resolveLoadInputRef,
                                 depthStencilRef,
                                 defaultAttachmentDescription);
        SkASSERT(resolveLoadInputRef.attachment == VK_ATTACHMENT_UNUSED);

        // Assemble subpass information before creating the renderpass. Each renderpass has at least
        // one subpass dependency (self-dependency for reading the dst texture).
        VkSubpassDescription2 mainSubpassDesc = {};
        mainSubpassDesc.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2;
        populate_main_subpass_desc(
                context->vulkanCaps(), mainSubpassDesc, colorRef, resolveRef, depthStencilRef);

        // Enable multisampled render to single-sampled with the render pass's sample count.
        VkMultisampledRenderToSingleSampledInfoEXT msrtss = {};
        msrtss.sType = VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT;
        msrtss.multisampledRenderToSingleSampledEnable = VK_TRUE;
        msrtss.rasterizationSamples = SampleCountToVkSampleCount(renderPassDesc.fSampleCount);
        AddToPNextChain(&mainSubpassDesc, &msrtss);

        // Depth/stencil resolve needs additional configuration (even though Graphite always
        // discards depth/stencil).
        SkASSERT(renderPassDesc.fDepthStencilAttachment.fStoreOp == StoreOp::kDiscard);
        VkSubpassDescriptionDepthStencilResolve dsResolve = {};
        dsResolve.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE;
        dsResolve.depthResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
        dsResolve.stencilResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
        AddToPNextChain(&mainSubpassDesc, &dsResolve);

        VkSubpassDependency2 defaultSubpassDependency = {};
        defaultSubpassDependency.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2;

        skia_private::STArray<1, VkSubpassDependency2> dependencies;
        populate_subpass_dependencies(context,
                                      dependencies,
                                      /*needLoadMSAAFromResolveSubpass=*/false,
                                      defaultSubpassDependency);

        // Create VkRenderPass
        VkRenderPassCreateInfo2 renderPassInfo = {};
        renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2;
        renderPassInfo.subpassCount = 1;
        renderPassInfo.pSubpasses = &mainSubpassDesc;
        renderPassInfo.dependencyCount = dependencies.size();
        renderPassInfo.pDependencies = dependencies.data();
        renderPassInfo.attachmentCount = attachmentDescs.size();
        renderPassInfo.pAttachments = attachmentDescs.data();

        VULKAN_CALL_RESULT(
                context,
                result,
                CreateRenderPass2(context->device(), &renderPassInfo, nullptr, &renderPass));
    } else {
        // Same thing as above, but using Vulkan 1.0 render pass API.  Practically every usable
        // driver supports VK_KHR_create_renderpass2, but that is not yet a minimum requirement of
        // Graphite.
        skia_private::TArray<VkAttachmentDescription> attachmentDescs;
        VkAttachmentReference colorRef = {};
        VkAttachmentReference resolveRef = {};
        VkAttachmentReference resolveLoadInputRef = {};
        VkAttachmentReference depthStencilRef = {};
        populate_attachment_refs(renderPassDesc,
                                 needLoadMSAAFromResolveSubpass,
                                 attachmentDescs,
                                 colorRef,
                                 resolveRef,
                                 resolveLoadInputRef,
                                 depthStencilRef,
                                 /*defaultAttachmentDescription=*/{});

        // If loading MSAA from resolve, an extra subpass and an additional dependency is needed.
        skia_private::STArray<2, VkSubpassDescription> subpassDescs;
        populate_subpass_descs(context->vulkanCaps(),
                               subpassDescs,
                               colorRef,
                               resolveRef,
                               resolveLoadInputRef,
                               depthStencilRef);
        skia_private::STArray<2, VkSubpassDependency> dependencies;
        populate_subpass_dependencies(context,
                                      dependencies,
                                      needLoadMSAAFromResolveSubpass,
                                      /*defaultSubpassDependency=*/VkSubpassDependency{});

        // Create VkRenderPass
        VkRenderPassCreateInfo renderPassInfo = {};
        renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
        renderPassInfo.subpassCount = subpassDescs.size();
        renderPassInfo.pSubpasses = subpassDescs.begin();
        renderPassInfo.dependencyCount = dependencies.size();
        renderPassInfo.pDependencies = dependencies.data();
        renderPassInfo.attachmentCount = attachmentDescs.size();
        renderPassInfo.pAttachments = attachmentDescs.data();

        VULKAN_CALL_RESULT(
                context,
                result,
                CreateRenderPass(context->device(), &renderPassInfo, nullptr, &renderPass));
    }

    if (result != VK_SUCCESS) {
        return nullptr;
    }
    VkExtent2D granularity;
    VULKAN_CALL(context->interface(), GetRenderAreaGranularity(context->device(),
                                                               renderPass,
                                                               &granularity));
    return sk_sp<VulkanRenderPass>(new VulkanRenderPass(context, renderPass, granularity));
}

VulkanRenderPass::VulkanRenderPass(const VulkanSharedContext* context,
                                   VkRenderPass renderPass,
                                   VkExtent2D granularity)
        : Resource(context,
                   Ownership::kOwned,
                   /*gpuMemorySize=*/0,
                   /*reusableRequiresPurgeable=*/false)
        , fSharedContext(context)
        , fRenderPass(renderPass)
        , fGranularity(granularity) {}

void VulkanRenderPass::freeGpuData() {
    VULKAN_CALL(fSharedContext->interface(),
                DestroyRenderPass(fSharedContext->device(), fRenderPass, nullptr));
}

}  // namespace skgpu::graphite
