/*
 * Copyright 2022 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/VulkanGraphiteUtils.h"

#include "include/core/SkContext.h"
#include "include/core/SkStream.h"
#include "include/gpu/ShaderErrorHandler.h"
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/ContextOptions.h"
#include "include/gpu/graphite/vk/VulkanGraphiteContext.h"
#include "include/gpu/vk/VulkanBackendContext.h"
#include "src/core/SkContextPriv.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/graphite/ContextPriv.h"
#include "src/gpu/graphite/RenderPassDesc.h"
#include "src/gpu/graphite/TextureFormat.h"
#include "src/gpu/graphite/vk/VulkanCaps.h"
#include "src/gpu/graphite/vk/VulkanQueueManager.h"
#include "src/gpu/graphite/vk/VulkanSampler.h"
#include "src/gpu/graphite/vk/VulkanSharedContext.h"
#include "src/sksl/SkSLProgramSettings.h"

namespace SkContexts {

// Creates a context wrapping a Graphite GPU backend with Vulkan
std::unique_ptr<SkContext> MakeGraphite(const skgpu::VulkanBackendContext& vkContext,
                                        const SkContextOptions& contextOptions,
                                        const skgpu::graphite::ContextOptions& graphiteOptions) {
    auto context = skgpu::graphite::ContextFactory::MakeVulkan(vkContext, graphiteOptions);
    if (!context) {
        return nullptr;
    }
    return SkContextCtorAccessor::MakeContext(
            contextOptions, skgpu::graphite::ContextPriv::AsGPUContext(std::move(context)));
}

}  // namespace SkContexts

namespace skgpu::graphite::ContextFactory {

std::unique_ptr<Context> MakeVulkan(const VulkanBackendContext& backendContext,
                                    const ContextOptions& options) {
    sk_sp<SharedContext> sharedContext = VulkanSharedContext::Make(backendContext, options);
    if (!sharedContext) {
        return nullptr;
    }

    std::unique_ptr<QueueManager> queueManager(new VulkanQueueManager(backendContext.fQueue,
                                                                      sharedContext.get()));
    if (!queueManager) {
        return nullptr;
    }

    return ContextCtorAccessor::MakeContext(std::move(sharedContext),
                                            std::move(queueManager),
                                            options);
}

} // namespace skgpu::graphite::ContextFactory

namespace skgpu::graphite {

VkShaderModule CreateVulkanShaderModule(const VulkanSharedContext* context,
                                        const SkSL::NativeShader& spirv,
                                        VkShaderStageFlagBits stage) {
    TRACE_EVENT0("skia.shaders", "InstallVkShaderModule");
    VkShaderModuleCreateInfo moduleCreateInfo = {};
    moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
    moduleCreateInfo.codeSize = spirv.fBinary.size() * sizeof(uint32_t);
    moduleCreateInfo.pCode = spirv.fBinary.data();

    VkShaderModule shaderModule;
    VkResult result;
    VULKAN_CALL_RESULT(context,
                       result,
                       CreateShaderModule(context->device(),
                                          &moduleCreateInfo,
                                          /*const VkAllocationCallbacks*=*/nullptr,
                                          &shaderModule));
    if (result != VK_SUCCESS) {
        SKIA_LOG_E("Failed to create VkShaderModule");
        return VK_NULL_HANDLE;
    }
    return shaderModule;
}

std::optional<VkImageMemoryBarrier> CreateVulkanImageMemoryBarrier(
        const VulkanSharedContext& sharedContext,
        VkImage image,
        const VulkanTextureInfo& textureInfo,
        VkImageLayout currentLayout,
        uint32_t currentQueueIndex,
        VkImageLayout newLayout,
        VkAccessFlags dstAccessMask,
        uint32_t newQueueFamilyIndex) {
    SkASSERT(newLayout == currentLayout ||
             (VK_IMAGE_LAYOUT_UNDEFINED != newLayout &&
              VK_IMAGE_LAYOUT_PREINITIALIZED != newLayout));

#ifdef SK_DEBUG
    if (textureInfo.fSharingMode == VK_SHARING_MODE_CONCURRENT) {
        if (newQueueFamilyIndex == VK_QUEUE_FAMILY_IGNORED) {
            SkASSERT(currentQueueIndex == VK_QUEUE_FAMILY_IGNORED ||
                     currentQueueIndex == VK_QUEUE_FAMILY_EXTERNAL ||
                     currentQueueIndex == VK_QUEUE_FAMILY_FOREIGN_EXT);
        } else {
            SkASSERT(newQueueFamilyIndex == VK_QUEUE_FAMILY_EXTERNAL ||
                     newQueueFamilyIndex == VK_QUEUE_FAMILY_FOREIGN_EXT);
            SkASSERT(currentQueueIndex == VK_QUEUE_FAMILY_IGNORED);
        }
    } else {
        SkASSERT(textureInfo.fSharingMode == VK_SHARING_MODE_EXCLUSIVE);
        if (newQueueFamilyIndex == VK_QUEUE_FAMILY_IGNORED ||
            currentQueueIndex == sharedContext.queueIndex()) {
            SkASSERT(currentQueueIndex == VK_QUEUE_FAMILY_IGNORED ||
                     currentQueueIndex == VK_QUEUE_FAMILY_EXTERNAL ||
                     currentQueueIndex == VK_QUEUE_FAMILY_FOREIGN_EXT ||
                     currentQueueIndex == sharedContext.queueIndex());
        } else if (newQueueFamilyIndex == VK_QUEUE_FAMILY_EXTERNAL ||
                   newQueueFamilyIndex == VK_QUEUE_FAMILY_FOREIGN_EXT) {
            SkASSERT(currentQueueIndex == VK_QUEUE_FAMILY_IGNORED ||
                     currentQueueIndex == sharedContext.queueIndex());
        }
    }
#endif

    if (textureInfo.fSharingMode == VK_SHARING_MODE_EXCLUSIVE) {
        if (newQueueFamilyIndex == VK_QUEUE_FAMILY_IGNORED) {
            newQueueFamilyIndex = sharedContext.queueIndex();
        }
        if (currentQueueIndex == VK_QUEUE_FAMILY_IGNORED) {
            currentQueueIndex = sharedContext.queueIndex();
        }
    }

    // If the old and new layout are the same and the layout is a read only layout, there is no need
    // to put in a barrier unless we also need to switch queues.
    if (newLayout == currentLayout && currentQueueIndex == newQueueFamilyIndex &&
        (VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL == currentLayout ||
         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == currentLayout ||
         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == currentLayout)) {
        return std::nullopt;
    }

    VkAccessFlags srcAccessMask =
            VkImageLayoutToSrcAccessMask(currentLayout, textureInfo.fImageUsageFlags);

    return VkImageMemoryBarrier{
        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                       // sType
        nullptr,                                                      // pNext
        srcAccessMask,                                                // srcAccessMask
        dstAccessMask,                                                // dstAccessMask
        currentLayout,                                                // oldLayout
        newLayout,                                                    // newLayout
        currentQueueIndex,                                            // srcQueueFamilyIndex
        newQueueFamilyIndex,                                          // dstQueueFamilyIndex
        image,                                                        // image
        { textureInfo.fAspectMask, 0, VK_REMAINING_MIP_LEVELS, 0, 1 } // subresourceRange
    };
}

VkPipelineStageFlags VkImageLayoutToPipelineSrcStageFlags(const VkImageLayout layout,
                                                          const VulkanCaps& caps) {
    if (VK_IMAGE_LAYOUT_GENERAL == layout) {
        return VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
    } else if (VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == layout ||
               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == layout) {
        return VK_PIPELINE_STAGE_TRANSFER_BIT;
    } else if (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == layout) {
        return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    } else if (VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL == layout ||
               VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL == layout) {
        return VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
    } else if (VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == layout) {
        return caps.shaderReadOnlySrcStageMask();
    } else if (VK_IMAGE_LAYOUT_PREINITIALIZED == layout) {
        return VK_PIPELINE_STAGE_HOST_BIT;
    } else if (VK_IMAGE_LAYOUT_PRESENT_SRC_KHR == layout) {
        return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    }

    SkASSERT(VK_IMAGE_LAYOUT_UNDEFINED == layout);
    return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
}

VkAccessFlags VkImageLayoutToSrcAccessMask(const VkImageLayout layout,
                                           VkImageUsageFlags usageFlags) {
    // We can only directly access the host memory if we are in preinitialized or general layout,
    // and the image is linear. However, device access to images written by the host happens after
    // vkQueueSubmit, which implicitly makes host writes _visible_ to the device, i.e.
    // VK_ACCESS_HOST_WRITE_BIT is unnecessary. Host data is made _available_ to the device via
    // vkFlushMappedMemoryRanges.
    VkAccessFlags flags = 0;
    if (VK_IMAGE_LAYOUT_GENERAL == layout) {
        flags = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
                VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
                VK_ACCESS_TRANSFER_WRITE_BIT;
        if (usageFlags & VK_IMAGE_USAGE_STORAGE_BIT) {
            flags |= VK_ACCESS_SHADER_WRITE_BIT;
        }
    } else if (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == layout) {
        flags = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    } else if (VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL == layout) {
        flags = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
    } else if (VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == layout) {
        flags = VK_ACCESS_TRANSFER_WRITE_BIT;
    } else if (VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == layout ||
               VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == layout ||
               VK_IMAGE_LAYOUT_PRESENT_SRC_KHR == layout ||
               VK_IMAGE_LAYOUT_PREINITIALIZED == layout) {
        // There are no writes that need to be made available
        flags = 0;
    }
    return flags;
}

void DescriptorDataToVkDescSetLayout(const VulkanSharedContext* ctxt,
                                     const SkSpan<const DescriptorData>& requestedDescriptors,
                                     VkDescriptorSetLayout* outLayout) {
    // If requestedDescriptors is empty, that simply means we should create an empty placeholder
    // layout that doesn't actually contain any descriptors.
    constexpr int32_t kInlineCount = 16;
    skia_private::STArray<kInlineCount, VkDescriptorSetLayoutBinding> bindingLayouts;
    for (size_t i = 0; i < requestedDescriptors.size(); i++) {
        if (requestedDescriptors[i].fCount != 0) {
            const DescriptorData& currDescriptor = requestedDescriptors[i];
            VkDescriptorSetLayoutBinding& layoutBinding = bindingLayouts.push_back();
            layoutBinding = {};
            layoutBinding.binding = currDescriptor.fBindingIndex;
            layoutBinding.descriptorType = DsTypeEnumToVkDs(currDescriptor.fType);
            layoutBinding.descriptorCount = currDescriptor.fCount;
            layoutBinding.stageFlags =
                    PipelineStageFlagsToVkShaderStageFlags(currDescriptor.fPipelineStageFlags);
            layoutBinding.pImmutableSamplers = currDescriptor.fImmutableSampler
                    ? (static_cast<const VulkanSampler*>(
                            currDescriptor.fImmutableSampler))->constVkSamplerPtr()
                    : nullptr;
        }
    }

    VkDescriptorSetLayoutCreateInfo layoutCreateInfo = {};
    layoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
    layoutCreateInfo.bindingCount = bindingLayouts.size();
    layoutCreateInfo.pBindings = bindingLayouts.data();

    VkResult result;
    VULKAN_CALL_RESULT(
            ctxt,
            result,
            CreateDescriptorSetLayout(ctxt->device(), &layoutCreateInfo, nullptr, outLayout));
    if (result != VK_SUCCESS) {
        SkDebugf("Failed to create VkDescriptorSetLayout\n");
        outLayout = VK_NULL_HANDLE;
    }
}

VkDescriptorType DsTypeEnumToVkDs(DescriptorType type) {
    switch (type) {
        case DescriptorType::kUniformBuffer:
            return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
        case DescriptorType::kUniformBufferDynamic:
            return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
        case DescriptorType::kTextureSampler:
            return VK_DESCRIPTOR_TYPE_SAMPLER;
        case DescriptorType::kTexture:
            return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
        case DescriptorType::kCombinedTextureSampler:
            return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
        case DescriptorType::kStorageBuffer:
            return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
        case DescriptorType::kStorageBufferDynamic:
            return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
        case DescriptorType::kInputAttachment:
            return VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
        case DescriptorType::kStorageTexture:
            return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
    }
    SkUNREACHABLE;
}

#define VK_FORMAT_MAPPING(M) \
    M(TextureFormat::kR8,             VK_FORMAT_R8_UNORM)                                  \
    M(TextureFormat::kR16,            VK_FORMAT_R16_UNORM)                                 \
    M(TextureFormat::kR16F,           VK_FORMAT_R16_SFLOAT)                                \
    M(TextureFormat::kR32F,           VK_FORMAT_R32_SFLOAT)                                \
    /*TextureFormat::kA8              unsupported */                                       \
    M(TextureFormat::kRG8,            VK_FORMAT_R8G8_UNORM)                                \
    M(TextureFormat::kRG16,           VK_FORMAT_R16G16_UNORM)                              \
    M(TextureFormat::kRG16F,          VK_FORMAT_R16G16_SFLOAT)                             \
    M(TextureFormat::kRG32F,          VK_FORMAT_R32G32_SFLOAT)                             \
    M(TextureFormat::kRGB8,           VK_FORMAT_R8G8B8_UNORM)                              \
    M(TextureFormat::kBGR8,           VK_FORMAT_B8G8R8_UNORM)                              \
    M(TextureFormat::kB5_G6_R5,       VK_FORMAT_R5G6B5_UNORM_PACK16)                       \
    M(TextureFormat::kR5_G6_B5,       VK_FORMAT_B5G6R5_UNORM_PACK16)                       \
    M(TextureFormat::kRGB16,          VK_FORMAT_R16G16B16_UNORM)                           \
    M(TextureFormat::kRGB16F,         VK_FORMAT_R16G16B16_SFLOAT)                          \
    M(TextureFormat::kRGB32F,         VK_FORMAT_R32G32B32_SFLOAT)                          \
    M(TextureFormat::kRGB8_sRGB,      VK_FORMAT_R8G8B8_SRGB)                               \
    /*TextureFormat::kBGR10_XR        unsupported */                                       \
    M(TextureFormat::kRGBA8,          VK_FORMAT_R8G8B8A8_UNORM)                            \
    M(TextureFormat::kRGBA16,         VK_FORMAT_R16G16B16A16_UNORM)                        \
    M(TextureFormat::kRGBA16F,        VK_FORMAT_R16G16B16A16_SFLOAT)                       \
    M(TextureFormat::kRGBA32F,        VK_FORMAT_R32G32B32A32_SFLOAT)                       \
    M(TextureFormat::kRGB10_A2,       VK_FORMAT_A2B10G10R10_UNORM_PACK32)                  \
    M(TextureFormat::kRGBA10x6,       VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16)        \
    M(TextureFormat::kRGBA8_sRGB,     VK_FORMAT_R8G8B8A8_SRGB)                             \
    M(TextureFormat::kBGRA8,          VK_FORMAT_B8G8R8A8_UNORM)                            \
    M(TextureFormat::kBGR10_A2,       VK_FORMAT_A2R10G10B10_UNORM_PACK32)                  \
    M(TextureFormat::kBGRA8_sRGB,     VK_FORMAT_B8G8R8A8_SRGB)                             \
    M(TextureFormat::kABGR4,          VK_FORMAT_R4G4B4A4_UNORM_PACK16)                     \
    M(TextureFormat::kARGB4,          VK_FORMAT_B4G4R4A4_UNORM_PACK16)                     \
    /*TextureFormat::kBGRA10x6_XR     unsupported */                                       \
    M(TextureFormat::kRGB8_ETC2,      VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK)                   \
    M(TextureFormat::kRGB8_ETC2_sRGB, VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK)                    \
    M(TextureFormat::kRGB8_BC1,       VK_FORMAT_BC1_RGB_UNORM_BLOCK)                       \
    M(TextureFormat::kRGBA8_BC1,      VK_FORMAT_BC1_RGBA_UNORM_BLOCK)                      \
    M(TextureFormat::kRGBA8_BC1_sRGB, VK_FORMAT_BC1_RGBA_SRGB_BLOCK)                       \
    M(TextureFormat::kYUV8_P2_420,    VK_FORMAT_G8_B8R8_2PLANE_420_UNORM)                  \
    M(TextureFormat::kYUV8_P3_420,    VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM)                 \
    M(TextureFormat::kYUV10x6_P2_420, VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16) \
    M(TextureFormat::kYUV8_P2_422,    VK_FORMAT_G8_B8R8_2PLANE_422_UNORM)                  \
    M(TextureFormat::kYUV8_P3_422,    VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM)                 \
    M(TextureFormat::kYUV10x6_P2_422, VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16) \
    M(TextureFormat::kYUV8_P2_444,    VK_FORMAT_G8_B8R8_2PLANE_444_UNORM)                  \
    M(TextureFormat::kYUV8_P3_444,    VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM)                 \
    M(TextureFormat::kYUV10x6_P2_444, VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16) \
    /*TextureFormat::kExternal        VK_FORMAT_UNDEFINED w/ uint64_t sidecar */           \
    M(TextureFormat::kS8,             VK_FORMAT_S8_UINT)                                   \
    M(TextureFormat::kD16,            VK_FORMAT_D16_UNORM)                                 \
    M(TextureFormat::kD32F,           VK_FORMAT_D32_SFLOAT)                                \
    M(TextureFormat::kD24_S8,         VK_FORMAT_D24_UNORM_S8_UINT)                         \
    M(TextureFormat::kD32F_S8,        VK_FORMAT_D32_SFLOAT_S8_UINT)

// NOTE: For external formats, Vulkan stores the value outside of VkFormat and expects the VkFormat
// to be VK_FORMAT_UNDEFINED. The mapping functions below are unaware of this side car, so it
// maps VK_FORMAT_UNDEFINED to TextureFormat::kUnsupported (this is disambiguated explicitly by
// VulkanTextureInfo which has the full context). The reverse maps TextureFormat::kExternal to
// VK_FORMAT_UNDEFINED, as expected, although callers are responsible for passing along the actual
// external format separately.

TextureFormat VkFormatToTextureFormat(VkFormat format) {
#define M(TF, VK) case VK: return TF;
    switch(format) {
        VK_FORMAT_MAPPING(M)
        default: return TextureFormat::kUnsupported;
    }
#undef M
}
VkFormat TextureFormatToVkFormat(TextureFormat format) {
#define M(TF, VK) case TF: return VK;
    switch(format) {
        VK_FORMAT_MAPPING(M)
        default: return VK_FORMAT_UNDEFINED;
    }
#undef M
}

VkImageAspectFlags GetVkImageAspectFlags(TextureFormat format) {
    switch (format) {
        case TextureFormat::kS8:
            return VK_IMAGE_ASPECT_STENCIL_BIT;
        case TextureFormat::kD16:
            [[fallthrough]];
        case TextureFormat::kD32F:
            return VK_IMAGE_ASPECT_DEPTH_BIT;
        case TextureFormat::kD24_S8:
            [[fallthrough]];
        case TextureFormat::kD32F_S8:
            return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
        default:
            return VK_IMAGE_ASPECT_COLOR_BIT;
    }
}

VkShaderStageFlags PipelineStageFlagsToVkShaderStageFlags(
        SkEnumBitMask<PipelineStageFlags> stageFlags) {
    VkShaderStageFlags vkStageFlags = 0;
    if (stageFlags & PipelineStageFlags::kVertexShader) {
        vkStageFlags |= VK_SHADER_STAGE_VERTEX_BIT;
    }
    if (stageFlags & PipelineStageFlags::kFragmentShader) {
        vkStageFlags |= VK_SHADER_STAGE_FRAGMENT_BIT;
    }
    if (stageFlags & PipelineStageFlags::kCompute) {
        vkStageFlags |= VK_SHADER_STAGE_COMPUTE_BIT;
    }
    return vkStageFlags;
}

VkPipelineStageFlags PipelineStageFlagsToVkPipelineStageFlags(
        SkEnumBitMask<PipelineStageFlags> stageFlags) {
    VkPipelineStageFlags vkStageFlags = 0;
    if (stageFlags & PipelineStageFlags::kVertexShader) {
        vkStageFlags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
    }
    if (stageFlags & PipelineStageFlags::kFragmentShader) {
        vkStageFlags |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
    }
    if (stageFlags & PipelineStageFlags::kCompute) {
        vkStageFlags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
    }
    return vkStageFlags;
}

bool RenderPassDescWillLoadMSAAFromResolve(const RenderPassDesc& renderPassDesc) {
    return renderPassDesc.fColorResolveAttachment.fFormat != TextureFormat::kUnsupported &&
           renderPassDesc.fColorResolveAttachment.fLoadOp == LoadOp::kLoad;
}

bool RenderPassDescWillImplicitlyLoadMSAA(const RenderPassDesc& renderPassDesc) {
    SkASSERT(renderPassDesc.fColorAttachment.fFormat != TextureFormat::kUnsupported);
    SkASSERT(renderPassDesc.fColorAttachment.fSampleCount > SampleCount::k1 ||
             renderPassDesc.fColorResolveAttachment.fFormat == TextureFormat::kUnsupported);

    return renderPassDesc.fColorAttachment.fSampleCount == SampleCount::k1 &&
           renderPassDesc.fSampleCount > SampleCount::k1;
}

RenderPassDesc MakePipelineCompatibleRenderPass(const RenderPassDesc& renderPassDesc) {
    RenderPassDesc compatible = renderPassDesc;

    // Reset all load/store ops on the attachments since those do not affect compatibility.
    // Choose a combination that is most likely to be used later by the real render pass.
    const bool hasResolve =
            renderPassDesc.fColorResolveAttachment.fFormat != TextureFormat::kUnsupported;
    const bool needLoadMSAAFromResolveSubpass =
            RenderPassDescWillLoadMSAAFromResolve(renderPassDesc);
    compatible.fColorAttachment.fLoadOp =
            needLoadMSAAFromResolveSubpass ? LoadOp::kDiscard : LoadOp::kClear;
    compatible.fColorAttachment.fStoreOp = hasResolve ? StoreOp::kDiscard : StoreOp::kStore;
    compatible.fColorResolveAttachment.fLoadOp =
            needLoadMSAAFromResolveSubpass ? LoadOp::kLoad : LoadOp::kDiscard;
    compatible.fColorResolveAttachment.fStoreOp = hasResolve ? StoreOp::kStore : StoreOp::kDiscard;
    compatible.fDepthStencilAttachment.fLoadOp = LoadOp::kClear;
    compatible.fDepthStencilAttachment.fStoreOp = StoreOp::kDiscard;

    return compatible;
}

} // namespace skgpu::graphite
