/*
 * 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/VulkanGraphicsPipeline.h"

#include "include/gpu/ShaderErrorHandler.h"
#include "include/gpu/graphite/TextureInfo.h"
#include "include/private/SkAttributes.h"
#include "include/private/SkLog.h"
#include "src/core/SkSLTypeShared.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/SkSLToBackend.h"
#include "src/gpu/graphite/Attribute.h"
#include "src/gpu/graphite/ContextUtils.h"
#include "src/gpu/graphite/GraphicsPipelineDesc.h"
#include "src/gpu/graphite/RenderPassDesc.h"
#include "src/gpu/graphite/RendererProvider.h"
#include "src/gpu/graphite/ResourceTypes.h"
#include "src/gpu/graphite/RuntimeEffectDictionary.h"
#include "src/gpu/graphite/ShaderInfo.h"
#include "src/gpu/graphite/vk/VulkanCaps.h"
#include "src/gpu/graphite/vk/VulkanGraphicsPipeline.h"
#include "src/gpu/graphite/vk/VulkanRenderPass.h"
#include "src/gpu/graphite/vk/VulkanResourceProvider.h"
#include "src/gpu/graphite/vk/VulkanSharedContext.h"
#include "src/gpu/graphite/vk/VulkanSpirvTransforms.h"
#include "src/gpu/vk/VulkanUtilsPriv.h"
#include "src/sksl/SkSLProgramKind.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/ir/SkSLProgram.h"
#include "src/utils/SkShaderUtils.h"

namespace skgpu::graphite {

static inline VkFormat attrib_type_to_vkformat(VertexAttribType type) {
    switch (type) {
        case VertexAttribType::kFloat:
            return VK_FORMAT_R32_SFLOAT;
        case VertexAttribType::kFloat2:
            return VK_FORMAT_R32G32_SFLOAT;
        case VertexAttribType::kFloat3:
            return VK_FORMAT_R32G32B32_SFLOAT;
        case VertexAttribType::kFloat4:
            return VK_FORMAT_R32G32B32A32_SFLOAT;
        case VertexAttribType::kHalf:
            return VK_FORMAT_R16_SFLOAT;
        case VertexAttribType::kHalf2:
            return VK_FORMAT_R16G16_SFLOAT;
        case VertexAttribType::kHalf4:
            return VK_FORMAT_R16G16B16A16_SFLOAT;
        case VertexAttribType::kInt2:
            return VK_FORMAT_R32G32_SINT;
        case VertexAttribType::kInt3:
            return VK_FORMAT_R32G32B32_SINT;
        case VertexAttribType::kInt4:
            return VK_FORMAT_R32G32B32A32_SINT;
        case VertexAttribType::kUInt2:
            return VK_FORMAT_R32G32_UINT;
        case VertexAttribType::kByte:
            return VK_FORMAT_R8_SINT;
        case VertexAttribType::kByte2:
            return VK_FORMAT_R8G8_SINT;
        case VertexAttribType::kByte4:
            return VK_FORMAT_R8G8B8A8_SINT;
        case VertexAttribType::kUByte:
            return VK_FORMAT_R8_UINT;
        case VertexAttribType::kUByte2:
            return VK_FORMAT_R8G8_UINT;
        case VertexAttribType::kUByte4:
            return VK_FORMAT_R8G8B8A8_UINT;
        case VertexAttribType::kUByte_norm:
            return VK_FORMAT_R8_UNORM;
        case VertexAttribType::kUByte4_norm:
            return VK_FORMAT_R8G8B8A8_UNORM;
        case VertexAttribType::kShort2:
            return VK_FORMAT_R16G16_SINT;
        case VertexAttribType::kShort4:
            return VK_FORMAT_R16G16B16A16_SINT;
        case VertexAttribType::kUShort2:
            return VK_FORMAT_R16G16_UINT;
        case VertexAttribType::kUShort2_norm:
            return VK_FORMAT_R16G16_UNORM;
        case VertexAttribType::kInt:
            return VK_FORMAT_R32_SINT;
        case VertexAttribType::kUInt:
            return VK_FORMAT_R32_UINT;
        case VertexAttribType::kUShort_norm:
            return VK_FORMAT_R16_UNORM;
        case VertexAttribType::kUShort4_norm:
            return VK_FORMAT_R16G16B16A16_UNORM;
    }
    SK_ABORT("Unknown vertex attrib type");
}

// A helper to derive the vertex input state either for version 1 or 2 of the Vulkan structs.
template <typename VertexInputBindingDescription, typename VertexInputAttributeDescription>
static void get_vertex_input_state(
        VkVertexInputRate appendVertexRate,
        const SkSpan<const Attribute>& staticAttrs,
        const SkSpan<const Attribute>& appendAttrs,
        skia_private::STArray<2, VertexInputBindingDescription>& bindingDescs,
        skia_private::STArray<16, VertexInputAttributeDescription>& attributeDescs,
        const VertexInputBindingDescription& defaultBindingDesc,
        const VertexInputAttributeDescription& defaultAttributeDesc) {
    int attribIndex = 0;
    size_t staticAttributeOffset = 0;
    for (auto attrib : staticAttrs) {
        VertexInputAttributeDescription vkAttrib = defaultAttributeDesc;
        vkAttrib.location = attribIndex++;
        vkAttrib.binding = VulkanGraphicsPipeline::kStaticDataBufferIndex;
        vkAttrib.format = attrib_type_to_vkformat(attrib.cpuType());
        vkAttrib.offset = staticAttributeOffset;
        staticAttributeOffset += attrib.sizeAlign4();
        attributeDescs.push_back(vkAttrib);
    }

    size_t appendAttributeOffset = 0;
    for (auto attrib : appendAttrs) {
        VertexInputAttributeDescription vkAttrib = defaultAttributeDesc;
        vkAttrib.location = attribIndex++;
        vkAttrib.binding = VulkanGraphicsPipeline::kAppendDataBufferIndex;
        vkAttrib.format = attrib_type_to_vkformat(attrib.cpuType());
        vkAttrib.offset = appendAttributeOffset;
        appendAttributeOffset += attrib.sizeAlign4();
        attributeDescs.push_back(vkAttrib);
    }

    if (!staticAttrs.empty()) {
        VertexInputBindingDescription vkBinding = defaultBindingDesc;
        vkBinding.binding = VulkanGraphicsPipeline::kStaticDataBufferIndex;
        vkBinding.stride = (uint32_t)staticAttributeOffset;
        vkBinding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
        bindingDescs.push_back(vkBinding);
    }
    if (!appendAttrs.empty()) {
        VertexInputBindingDescription vkBinding = defaultBindingDesc;
        vkBinding.binding = VulkanGraphicsPipeline::kAppendDataBufferIndex;
        vkBinding.stride = (uint32_t)appendAttributeOffset;
        vkBinding.inputRate = appendVertexRate;
        bindingDescs.push_back(vkBinding);
    }
}

static void setup_vertex_input_state(
        VkVertexInputRate appendVertexRate,
        const SkSpan<const Attribute>& staticAttrs,
        const SkSpan<const Attribute>& appendAttrs,
        VkPipelineVertexInputStateCreateInfo* vertexInputInfo,
        skia_private::STArray<2, VkVertexInputBindingDescription>& bindingDescs,
        skia_private::STArray<16, VkVertexInputAttributeDescription>& attributeDescs) {
    // Setup attribute & binding descriptions
    get_vertex_input_state(appendVertexRate,
                           staticAttrs,
                           appendAttrs,
                           bindingDescs,
                           attributeDescs,
                           /*defaultBindingDesc=*/{},
                           /*defaultAttributeDesc=*/{});

    *vertexInputInfo = {};
    vertexInputInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
    vertexInputInfo->vertexBindingDescriptionCount = bindingDescs.size();
    vertexInputInfo->pVertexBindingDescriptions = bindingDescs.begin();
    vertexInputInfo->vertexAttributeDescriptionCount = attributeDescs.size();
    vertexInputInfo->pVertexAttributeDescriptions = attributeDescs.begin();
}

static VkPrimitiveTopology primitive_type_to_vk_topology(PrimitiveType primitiveType) {
    switch (primitiveType) {
        case PrimitiveType::kTriangles:
            return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
        case PrimitiveType::kTriangleStrip:
            return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
        case PrimitiveType::kPoints:
            return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
    }
    SkUNREACHABLE;
}

static void setup_input_assembly_state(const Caps& caps,
                                       PrimitiveType primitiveType,
                                       VkPipelineInputAssemblyStateCreateInfo* inputAssemblyInfo) {
    *inputAssemblyInfo = {};
    inputAssemblyInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
    inputAssemblyInfo->primitiveRestartEnable = VK_FALSE;
    if (caps.useBasicDynamicState()) {
        // Note: when topology is dynamic state, the topology _class_ still needs to be specified.
        inputAssemblyInfo->topology = primitiveType == PrimitiveType::kPoints
                                              ? VK_PRIMITIVE_TOPOLOGY_POINT_LIST
                                              : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
    } else {
        inputAssemblyInfo->topology = primitive_type_to_vk_topology(primitiveType);
    }
}

static VkStencilOp stencil_op_to_vk_stencil_op(StencilOp op) {
    static const VkStencilOp gTable[] = {
        VK_STENCIL_OP_KEEP,                 // kKeep
        VK_STENCIL_OP_ZERO,                 // kZero
        VK_STENCIL_OP_REPLACE,              // kReplace
        VK_STENCIL_OP_INVERT,               // kInvert
        VK_STENCIL_OP_INCREMENT_AND_WRAP,   // kIncWrap
        VK_STENCIL_OP_DECREMENT_AND_WRAP,   // kDecWrap
        VK_STENCIL_OP_INCREMENT_AND_CLAMP,  // kIncClamp
        VK_STENCIL_OP_DECREMENT_AND_CLAMP,  // kDecClamp
    };
    static_assert(std::size(gTable) == kStencilOpCount);
    static_assert(0 == (int)StencilOp::kKeep);
    static_assert(1 == (int)StencilOp::kZero);
    static_assert(2 == (int)StencilOp::kReplace);
    static_assert(3 == (int)StencilOp::kInvert);
    static_assert(4 == (int)StencilOp::kIncWrap);
    static_assert(5 == (int)StencilOp::kDecWrap);
    static_assert(6 == (int)StencilOp::kIncClamp);
    static_assert(7 == (int)StencilOp::kDecClamp);
    SkASSERT(op < (StencilOp)kStencilOpCount);
    return SK_UNSAFE_TODO(gTable[(int)op]);
}

static VkCompareOp compare_op_to_vk_compare_op(CompareOp op) {
    static const VkCompareOp gTable[] = {
        VK_COMPARE_OP_ALWAYS,              // kAlways
        VK_COMPARE_OP_NEVER,               // kNever
        VK_COMPARE_OP_GREATER,             // kGreater
        VK_COMPARE_OP_GREATER_OR_EQUAL,    // kGEqual
        VK_COMPARE_OP_LESS,                // kLess
        VK_COMPARE_OP_LESS_OR_EQUAL,       // kLEqual
        VK_COMPARE_OP_EQUAL,               // kEqual
        VK_COMPARE_OP_NOT_EQUAL,           // kNotEqual
    };
    static_assert(std::size(gTable) == kCompareOpCount);
    static_assert(0 == (int)CompareOp::kAlways);
    static_assert(1 == (int)CompareOp::kNever);
    static_assert(2 == (int)CompareOp::kGreater);
    static_assert(3 == (int)CompareOp::kGEqual);
    static_assert(4 == (int)CompareOp::kLess);
    static_assert(5 == (int)CompareOp::kLEqual);
    static_assert(6 == (int)CompareOp::kEqual);
    static_assert(7 == (int)CompareOp::kNotEqual);
    SkASSERT(op < (CompareOp)kCompareOpCount);

    return SK_UNSAFE_TODO(gTable[(int)op]);
}

static void setup_stencil_op_state(VkStencilOpState* opState,
                                   const StencilSettings::Face& face,
                                   uint32_t referenceValue,
                                   uint32_t readMask,
                                   uint32_t writeMask) {
    opState->failOp = stencil_op_to_vk_stencil_op(face.fStencilFailOp);
    opState->passOp = stencil_op_to_vk_stencil_op(face.fDepthStencilPassOp);
    opState->depthFailOp = stencil_op_to_vk_stencil_op(face.fDepthFailOp);
    opState->compareOp = compare_op_to_vk_compare_op(face.fCompareOp);
    opState->compareMask = readMask;
    // Note: On some old ARM driver versions, dynamic state for stencil write mask doesn't work
    // correctly in the presence of discard or alpha to coverage, if the static state provided
    // when creating the pipeline has a value of 0.  However, both alphaToCoverageEnable and
    // rasterizerDiscardEnable are always false in Graphite, so no driver bug workaround is
    // necessary at the moment.
    opState->writeMask = writeMask;
    opState->reference = referenceValue;
}

static void setup_depth_stencil_state(const Caps& caps,
                                      const DepthStencilSettings& depthStencilSettings,
                                      VkPipelineDepthStencilStateCreateInfo* stencilInfo) {
    *stencilInfo = {};
    stencilInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
    if (!caps.useBasicDynamicState()) {
        const auto& [depthSettings, stencilSettings] = depthStencilSettings;

        stencilInfo->depthTestEnable = depthSettings.enabled();
        stencilInfo->depthWriteEnable = depthSettings.fWriteEnabled;
        stencilInfo->depthCompareOp = compare_op_to_vk_compare_op(depthSettings.fCompareOp);

        stencilInfo->stencilTestEnable = stencilSettings.enabled();
        if (stencilInfo->stencilTestEnable) {
            setup_stencil_op_state(&stencilInfo->front,
                                   stencilSettings.fFrontFace,
                                   stencilSettings.fReferenceValue,
                                   stencilSettings.fReadMask,
                                   stencilSettings.fWriteMask);
            setup_stencil_op_state(&stencilInfo->back,
                                   stencilSettings.fBackFace,
                                   stencilSettings.fReferenceValue,
                                   stencilSettings.fReadMask,
                                   stencilSettings.fWriteMask);
        }

        stencilInfo->depthBoundsTestEnable = VK_FALSE;
        stencilInfo->minDepthBounds = 0.0f;
        stencilInfo->maxDepthBounds = 1.0f;
    }
}

static void setup_viewport_scissor_state(VkPipelineViewportStateCreateInfo* viewportInfo) {
    *viewportInfo = {};
    viewportInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;

    // The viewport and scissor are set dyanmically with draw pass commands
    viewportInfo->viewportCount = 1;
    viewportInfo->scissorCount = 1;

    SkASSERT(viewportInfo->viewportCount == viewportInfo->scissorCount);
}

static void setup_multisample_state(SampleCount sampleCount,
                                    VkPipelineMultisampleStateCreateInfo* multisampleInfo) {
    *multisampleInfo = {};
    multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
    multisampleInfo->rasterizationSamples = SampleCountToVkSampleCount(sampleCount);
    multisampleInfo->sampleShadingEnable = VK_FALSE;
    multisampleInfo->minSampleShading = 0.0f;
    multisampleInfo->pSampleMask = nullptr;
    multisampleInfo->alphaToCoverageEnable = VK_FALSE;
    multisampleInfo->alphaToOneEnable = VK_FALSE;
}

static VkBlendFactor blend_coeff_to_vk_blend(skgpu::BlendCoeff coeff) {
    switch (coeff) {
        case skgpu::BlendCoeff::kZero:
            return VK_BLEND_FACTOR_ZERO;
        case skgpu::BlendCoeff::kOne:
            return VK_BLEND_FACTOR_ONE;
        case skgpu::BlendCoeff::kSC:
            return VK_BLEND_FACTOR_SRC_COLOR;
        case skgpu::BlendCoeff::kISC:
            return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
        case skgpu::BlendCoeff::kDC:
            return VK_BLEND_FACTOR_DST_COLOR;
        case skgpu::BlendCoeff::kIDC:
            return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
        case skgpu::BlendCoeff::kSA:
            return VK_BLEND_FACTOR_SRC_ALPHA;
        case skgpu::BlendCoeff::kISA:
            return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
        case skgpu::BlendCoeff::kDA:
            return VK_BLEND_FACTOR_DST_ALPHA;
        case skgpu::BlendCoeff::kIDA:
            return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
        case skgpu::BlendCoeff::kConstC:
            return VK_BLEND_FACTOR_CONSTANT_COLOR;
        case skgpu::BlendCoeff::kIConstC:
            return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
        case skgpu::BlendCoeff::kS2C:
            return VK_BLEND_FACTOR_SRC1_COLOR;
        case skgpu::BlendCoeff::kIS2C:
            return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
        case skgpu::BlendCoeff::kS2A:
            return VK_BLEND_FACTOR_SRC1_ALPHA;
        case skgpu::BlendCoeff::kIS2A:
            return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
        case skgpu::BlendCoeff::kIllegal:
            return VK_BLEND_FACTOR_ZERO;
    }
    SkUNREACHABLE;
}

static VkBlendOp blend_equation_to_vk_blend_op(skgpu::BlendEquation equation) {
    static const VkBlendOp gTable[] = {
        // Basic blend ops
        VK_BLEND_OP_ADD,
        VK_BLEND_OP_SUBTRACT,
        VK_BLEND_OP_REVERSE_SUBTRACT,

        // Advanced blend ops
        VK_BLEND_OP_SCREEN_EXT,
        VK_BLEND_OP_OVERLAY_EXT,
        VK_BLEND_OP_DARKEN_EXT,
        VK_BLEND_OP_LIGHTEN_EXT,
        VK_BLEND_OP_COLORDODGE_EXT,
        VK_BLEND_OP_COLORBURN_EXT,
        VK_BLEND_OP_HARDLIGHT_EXT,
        VK_BLEND_OP_SOFTLIGHT_EXT,
        VK_BLEND_OP_DIFFERENCE_EXT,
        VK_BLEND_OP_EXCLUSION_EXT,
        VK_BLEND_OP_MULTIPLY_EXT,
        VK_BLEND_OP_HSL_HUE_EXT,
        VK_BLEND_OP_HSL_SATURATION_EXT,
        VK_BLEND_OP_HSL_COLOR_EXT,
        VK_BLEND_OP_HSL_LUMINOSITY_EXT,

        // Illegal.
        VK_BLEND_OP_ADD,
    };
    static_assert(0 == (int)skgpu::BlendEquation::kAdd);
    static_assert(1 == (int)skgpu::BlendEquation::kSubtract);
    static_assert(2 == (int)skgpu::BlendEquation::kReverseSubtract);
    static_assert(3 == (int)skgpu::BlendEquation::kScreen);
    static_assert(4 == (int)skgpu::BlendEquation::kOverlay);
    static_assert(5 == (int)skgpu::BlendEquation::kDarken);
    static_assert(6 == (int)skgpu::BlendEquation::kLighten);
    static_assert(7 == (int)skgpu::BlendEquation::kColorDodge);
    static_assert(8 == (int)skgpu::BlendEquation::kColorBurn);
    static_assert(9 == (int)skgpu::BlendEquation::kHardLight);
    static_assert(10 == (int)skgpu::BlendEquation::kSoftLight);
    static_assert(11 == (int)skgpu::BlendEquation::kDifference);
    static_assert(12 == (int)skgpu::BlendEquation::kExclusion);
    static_assert(13 == (int)skgpu::BlendEquation::kMultiply);
    static_assert(14 == (int)skgpu::BlendEquation::kHSLHue);
    static_assert(15 == (int)skgpu::BlendEquation::kHSLSaturation);
    static_assert(16 == (int)skgpu::BlendEquation::kHSLColor);
    static_assert(17 == (int)skgpu::BlendEquation::kHSLLuminosity);
    static_assert(std::size(gTable) == skgpu::kBlendEquationCnt);

    SkASSERT((unsigned)equation < skgpu::kBlendEquationCnt);
    return SK_UNSAFE_TODO(gTable[(int)equation]);
}

static void setup_color_blend_state(const VulkanCaps& caps,
                                    const skgpu::BlendInfo& blendInfo,
                                    VkPipelineColorBlendStateCreateInfo* colorBlendInfo,
                                    VkPipelineColorBlendAttachmentState* attachmentState) {
    skgpu::BlendEquation equation = blendInfo.fEquation;
    skgpu::BlendCoeff srcCoeff = blendInfo.fSrcBlend;
    skgpu::BlendCoeff dstCoeff = blendInfo.fDstBlend;
    bool blendOff = skgpu::BlendShouldDisable(equation, srcCoeff, dstCoeff);

    *attachmentState = {};
    attachmentState->blendEnable = !blendOff;
    if (!blendOff) {
        attachmentState->srcColorBlendFactor = blend_coeff_to_vk_blend(srcCoeff);
        attachmentState->dstColorBlendFactor = blend_coeff_to_vk_blend(dstCoeff);
        attachmentState->colorBlendOp = blend_equation_to_vk_blend_op(equation);
        attachmentState->srcAlphaBlendFactor = blend_coeff_to_vk_blend(srcCoeff);
        attachmentState->dstAlphaBlendFactor = blend_coeff_to_vk_blend(dstCoeff);
        attachmentState->alphaBlendOp = blend_equation_to_vk_blend_op(equation);
    }

    if (!blendInfo.fWritesColor) {
        attachmentState->colorWriteMask = 0;
    } else {
        attachmentState->colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
                                          VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
    }

    *colorBlendInfo = {};
    colorBlendInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
    colorBlendInfo->logicOpEnable = VK_FALSE;
    colorBlendInfo->attachmentCount = 1;
    colorBlendInfo->pAttachments = attachmentState;
    // colorBlendInfo->blendConstants is set dynamically

    if (caps.supportsRasterizationOrderColorAttachmentAccess()) {
        colorBlendInfo->flags =
                VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT;
    }
}

static void setup_raster_state(const Caps& caps,
                               bool isWireframe,
                               VkPipelineRasterizationStateCreateInfo* rasterInfo) {
    *rasterInfo = {};
    rasterInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    rasterInfo->depthClampEnable = VK_FALSE;
    rasterInfo->rasterizerDiscardEnable = VK_FALSE;
    rasterInfo->polygonMode = isWireframe ? VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL;
    rasterInfo->cullMode = VK_CULL_MODE_NONE;
    rasterInfo->frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
    rasterInfo->depthBiasEnable = VK_FALSE;
    rasterInfo->depthBiasConstantFactor = 0.0f;
    rasterInfo->depthBiasClamp = 0.0f;
    rasterInfo->depthBiasSlopeFactor = 0.0f;
    rasterInfo->lineWidth = 1.0f;
}

static void setup_shader_stage_info(VkShaderStageFlagBits stage,
                                    VkShaderModule shaderModule,
                                    VkPipelineShaderStageCreateInfo* shaderStageInfo) {
    *shaderStageInfo = {};
    shaderStageInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
    shaderStageInfo->stage = stage;
    shaderStageInfo->module = shaderModule;
    shaderStageInfo->pName = "main";
}

static VkDescriptorSetLayout descriptor_data_to_layout(
        const VulkanSharedContext* sharedContext, const SkSpan<DescriptorData>& descriptorData) {
    // descriptorData can be empty to indicate that we should create a mock placeholder layout
    // with no descriptors.
    VkDescriptorSetLayout setLayout;
    DescriptorDataToVkDescSetLayout(sharedContext, descriptorData, &setLayout);
    if (setLayout == VK_NULL_HANDLE) {
        SKIA_LOG_E("Failed to create descriptor set layout; pipeline creation will fail.\n");
        return VK_NULL_HANDLE;
    }
    return setLayout;
}

static void destroy_desc_set_layouts(const VulkanSharedContext* sharedContext,
                                     skia_private::TArray<VkDescriptorSetLayout>& setLayouts) {
    for (int i = 0; i < setLayouts.size(); i++) {
        if (setLayouts[i] != VK_NULL_HANDLE) {
            VULKAN_CALL(sharedContext->interface(),
            DestroyDescriptorSetLayout(sharedContext->device(),
                                       setLayouts[i],
                                       nullptr));
        }
    }
}

static bool input_attachment_desc_set_layout(VkDescriptorSetLayout& outLayout,
                                             const VulkanSharedContext* sharedContext,
                                             bool mockOnly) {
    skia_private::STArray<1, DescriptorData> inputAttachmentDesc;

    if (!mockOnly) {
        inputAttachmentDesc.push_back(VulkanGraphicsPipeline::GetInputAttachmentDescriptor());
    }

    // If mockOnly is true (meaning no input attachment descriptor is actually needed), then still
    // request a mock VkDescriptorSetLayout handle by passing in the unpopulated span.
    outLayout = descriptor_data_to_layout(sharedContext, {inputAttachmentDesc});
    return outLayout != VK_NULL_HANDLE;
}

static bool uniform_desc_set_layout(VkDescriptorSetLayout& outLayout,
                                    const VulkanSharedContext* sharedContext,
                                    bool hasCombinedUniforms,
                                    SkEnumBitMask<PipelineStageFlags> storageStageFlags) {
    // Define a container with size reserved for up to kMaxNumUniformBuffers descriptors. Only add
    // DescriptorData for uniforms that actually are used and need to be included in the layout.
    skia_private::STArray<
            VulkanGraphicsPipeline::kMaxNumUniformBuffers, DescriptorData> uniformDescriptors;

    DescriptorType uniformBufferType =
            sharedContext->caps()->storageBufferSupport() ? DescriptorType::kStorageBufferDynamic
                                                          : DescriptorType::kUniformBufferDynamic;
    if (hasCombinedUniforms) {
        uniformDescriptors.push_back({
                uniformBufferType, /*count=*/1,
                VulkanGraphicsPipeline::kCombinedUniformIndex,
                PipelineStageFlags::kVertexShader | PipelineStageFlags::kFragmentShader});
    }

    if (SkToBool(storageStageFlags)) {
        DescriptorType storageType = sharedContext->caps()->storageBufferSupport()
                ? DescriptorType::kStorageBufferDynamic
                : DescriptorType::kTexture;
        uniformDescriptors.push_back({
                storageType,
                /*count=*/1,
                VulkanGraphicsPipeline::kStorageBufferIndex,
                storageStageFlags});
    }

    // If no uniforms are used, still request a mock VkDescriptorSetLayout handle by passing in the
    // unpopulated span of uniformDescriptors to descriptor set layout creation.
    outLayout = descriptor_data_to_layout(sharedContext, {uniformDescriptors});
    return true;
}

static bool texture_sampler_desc_set_layout(VkDescriptorSetLayout& outLayout,
                                            const VulkanSharedContext* sharedContext,
                                            const int numTextureSamplers,
                                            SkSpan<sk_sp<VulkanSampler>> immutableSamplers) {
    SkASSERT(numTextureSamplers >= 0);
    // The immutable sampler span size must be = the total number of texture/samplers such that
    // we can use the index of a sampler as its binding index (or we just have none, which
    // enables us to skip some of this logic entirely).
    SkASSERT(immutableSamplers.empty() ||
             SkTo<int>(immutableSamplers.size()) == numTextureSamplers);

    skia_private::TArray<DescriptorData> textureSamplerDescs(numTextureSamplers);
    for (int i = 0; i < numTextureSamplers; i++) {
        Sampler* immutableSampler = nullptr;
        if (!immutableSamplers.empty() && immutableSamplers[i]) {
            immutableSampler = immutableSamplers[i].get();
        }
        textureSamplerDescs.push_back({DescriptorType::kCombinedTextureSampler,
                                       /*count=*/1,
                                       /*bindingIdx=*/i,
                                       PipelineStageFlags::kFragmentShader,
                                       immutableSampler});
    }

    // If no texture/samplers are used, a mock VkDescriptorSetLayout handle by passing in the
    // unpopulated span of textureSamplerDescs to descriptor set layout creation.
    outLayout = descriptor_data_to_layout(sharedContext, {textureSamplerDescs});
    return outLayout != VK_NULL_HANDLE;
}

static VkPipelineLayout setup_pipeline_layout(const VulkanSharedContext* sharedContext,
                                              uint32_t pushConstantSize,
                                              VkShaderStageFlagBits pushConstantPipelineStageFlags,
                                              bool hasCombinedUniforms,
                                              SkEnumBitMask<PipelineStageFlags> storageStageFlags,
                                              int numTextureSamplers,
                                              bool loadMsaaFromResolve,
                                              SkSpan<sk_sp<VulkanSampler>> immutableSamplers) {
    // Create a container with the max anticipated amount (kMaxNumDescSets) of VkDescriptorSetLayout
    // handles which will be used to create the pipeline layout.
    skia_private::STArray<
            VulkanGraphicsPipeline::kMaxNumDescSets, VkDescriptorSetLayout> setLayouts;
    setLayouts.push_back_n(VulkanGraphicsPipeline::kMaxNumDescSets, VkDescriptorSetLayout());

    // Populate the container with actual descriptor set layout handles. Each index should contain
    // either a valid/real or a mock/placehodler layout handle. Mock VkDescriptorSetLayouts do not
    // actually contain any descriptors, but are needed as placeholders to maintain expected
    // descriptor set binding indices. This is because VK_NULL_HANDLE is a valid
    // VkDescriptorSetLayout value iff the graphicsPipelineLibrary feature is enabled, which is not
    // the case for all targeted devices (see
    // VUID-VkPipelineLayoutCreateInfo-graphicsPipelineLibrary-06753). If any of the helpers
    // encounter an error (i.e., return false), return a null VkPipelineLayout.
    if (!input_attachment_desc_set_layout(
                setLayouts[VulkanGraphicsPipeline::kDstAsInputDescSetIndex],
                sharedContext,
                /*mockOnly=*/false) || // We always add an input attachment descriptor
        !uniform_desc_set_layout(
                setLayouts[VulkanGraphicsPipeline::kUniformBufferDescSetIndex],
                sharedContext,
                hasCombinedUniforms,
                storageStageFlags) ||
        !texture_sampler_desc_set_layout(
                setLayouts[VulkanGraphicsPipeline::kTextureBindDescSetIndex],
                sharedContext,
                numTextureSamplers,
                immutableSamplers) ||
        !input_attachment_desc_set_layout(
                setLayouts[VulkanGraphicsPipeline::kLoadMsaaFromResolveInputDescSetIndex],
                sharedContext,
                /*mockOnly=*/!loadMsaaFromResolve)) { // Actual descriptor needed iff loading MSAA
        destroy_desc_set_layouts(sharedContext, setLayouts);
        return VK_NULL_HANDLE;
    }

    // Generate a pipeline layout using the now-populated descriptor set layout array
    VkPushConstantRange pushConstantRange;
    if (pushConstantSize) {
        pushConstantRange.offset = 0;
        pushConstantRange.size = pushConstantSize;
        pushConstantRange.stageFlags = pushConstantPipelineStageFlags;
    }
    VkPipelineLayoutCreateInfo layoutCreateInfo = {};
    layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
    layoutCreateInfo.setLayoutCount = setLayouts.size();
    layoutCreateInfo.pSetLayouts = setLayouts.begin();
    layoutCreateInfo.pushConstantRangeCount = pushConstantSize ? 1 : 0;
    layoutCreateInfo.pPushConstantRanges = pushConstantSize ? &pushConstantRange : nullptr;

    VkResult result;
    VkPipelineLayout layout;
    VULKAN_CALL_RESULT(sharedContext,
                       result,
                       CreatePipelineLayout(sharedContext->device(),
                                            &layoutCreateInfo,
                                            /*const VkAllocationCallbacks*=*/nullptr,
                                            &layout));

    // DescriptorSetLayouts can be deleted after the pipeline layout is created.
    destroy_desc_set_layouts(sharedContext, setLayouts);

    return result == VK_SUCCESS ? layout : VK_NULL_HANDLE;
}

static VkPipeline create_graphics_pipeline(VulkanSharedContext* sharedContext,
                                           VkGraphicsPipelineCreateInfo* pipelineCreateInfo) {
    VkPipeline vkPipeline = VK_NULL_HANDLE;
    VkResult result = VK_PIPELINE_COMPILE_REQUIRED;
    {
        TRACE_EVENT0_ALWAYS("skia.shaders", "CreateGraphicsPipeline");

        if (sharedContext->vulkanCaps().supportsPipelineCreationCacheControl()) {
            TRACE_EVENT0_ALWAYS("skia.shaders", "CreateGraphicsPipeline-CacheLookup");

            pipelineCreateInfo->flags |=
                    VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT;
            VULKAN_CALL_RESULT_NOCHECK(
                    sharedContext->interface(),
                    result,
                    CreateGraphicsPipelines(sharedContext->device(),
                                            sharedContext->getPipelineCache(),
                                            /*createInfoCount=*/ 1,
                                            pipelineCreateInfo,
                                            /*pAllocator=*/nullptr,
                                            &vkPipeline));
            sharedContext->checkVkResult(result);
        }

        if (result == VK_PIPELINE_COMPILE_REQUIRED) {
            TRACE_EVENT0_ALWAYS(
                "skia.shaders",
                TRACE_STR_STATIC(sharedContext->vulkanCaps().supportsPipelineCreationCacheControl()
                                         ? "CreateGraphicsPipeline-CompileAfterCacheMiss"
                                         : "CreateGraphicsPipeline-CacheLookupOrCompile"));

            pipelineCreateInfo->flags &=
                    ~VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT;
            VULKAN_CALL_RESULT(sharedContext,
                               result,
                               CreateGraphicsPipelines(sharedContext->device(),
                                                       sharedContext->getPipelineCache(),
                                                       /*createInfoCount=*/1,
                                                       pipelineCreateInfo,
                                                       /*pAllocator=*/nullptr,
                                                       &vkPipeline));
            if (result == VK_SUCCESS) {
                sharedContext->pipelineCompileWasRequired();
            }
        }
    }
    if (result != VK_SUCCESS) {
        SKIA_LOG_E("Failed to create pipeline. Error: %d\n", result);
        return VK_NULL_HANDLE;
    }

    return vkPipeline;
}

static bool create_shaders_pipeline(VulkanSharedContext* sharedContext,
                                    VkGraphicsPipelineCreateInfo& completePipelineInfo,
                                    VkPipelineLibraryCreateInfoKHR& shadersLibraryInfo,
                                    VkGraphicsPipelineLibraryCreateInfoEXT& libraryInfo,
                                    VkPipeline* shadersPipeline) {
    // Provide state that only pertains to the shaders subset to create the library.
    VkGraphicsPipelineCreateInfo shadersPipelineCreateInfo = {};
    shadersPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
    shadersPipelineCreateInfo.flags = 0;
    shadersPipelineCreateInfo.stageCount = completePipelineInfo.stageCount;
    shadersPipelineCreateInfo.pStages = completePipelineInfo.pStages;
    shadersPipelineCreateInfo.pViewportState = completePipelineInfo.pViewportState;
    shadersPipelineCreateInfo.pRasterizationState = completePipelineInfo.pRasterizationState;
    shadersPipelineCreateInfo.pMultisampleState = completePipelineInfo.pMultisampleState;
    shadersPipelineCreateInfo.pDepthStencilState = completePipelineInfo.pDepthStencilState;
    shadersPipelineCreateInfo.pDynamicState = completePipelineInfo.pDynamicState;
    shadersPipelineCreateInfo.layout = completePipelineInfo.layout;
    shadersPipelineCreateInfo.renderPass = completePipelineInfo.renderPass;
    shadersPipelineCreateInfo.subpass = completePipelineInfo.subpass;

    if (sharedContext->vulkanCaps().supportsPipelineProtectedAccess()) {
        shadersPipelineCreateInfo.flags |= sharedContext->caps()->protectedSupport()
                                            ? VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT_EXT
                                            : VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT;
    }

    // Specify that this is the shaders subset of the pipeline.
    libraryInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT |
                        VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT;
    shadersPipelineCreateInfo.flags |= VK_PIPELINE_CREATE_LIBRARY_BIT_KHR;
    skgpu::AddToPNextChain(&shadersPipelineCreateInfo, &libraryInfo);

    *shadersPipeline = create_graphics_pipeline(sharedContext, &shadersPipelineCreateInfo);
    if (*shadersPipeline == VK_NULL_HANDLE) {
        return false;
    }

    // The complete pipeline doesn't need all the state anymore, it inherits them from the
    // shaders library.
    completePipelineInfo.stageCount = 0;
    completePipelineInfo.pStages = nullptr;
    completePipelineInfo.pViewportState = nullptr;
    completePipelineInfo.pRasterizationState = nullptr;
    completePipelineInfo.pDepthStencilState = nullptr;

    // The complete pipeline provides the vertex input and fragment output interface state.
    // It's important that these states are not built into a separate library, because some
    // drivers can generate more efficient blend code if they have information about the
    // fragment shader.
    libraryInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT |
                        VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT;
    skgpu::AddToPNextChain(&completePipelineInfo, &libraryInfo);

    // Tell the complete pipeline to link with the shaders library:
    shadersLibraryInfo.libraryCount = 1;
    shadersLibraryInfo.pLibraries = shadersPipeline;
    AddToPNextChain(&completePipelineInfo, &shadersLibraryInfo);

    return true;
}

using VkDynamicStateList = std::array<VkDynamicState, 22>;
static void setup_dynamic_state(const Caps& caps,
                                VkPipelineDynamicStateCreateInfo* dynamicInfo,
                                VkDynamicStateList* dynamicStates) {
    uint32_t count = 0;

    // The following state is always dynamic in Graphite
    (*dynamicStates)[count++] = VK_DYNAMIC_STATE_VIEWPORT;
    (*dynamicStates)[count++] = VK_DYNAMIC_STATE_SCISSOR;
    (*dynamicStates)[count++] = VK_DYNAMIC_STATE_BLEND_CONSTANTS;

    if (caps.useBasicDynamicState()) {
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_LINE_WIDTH;
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_DEPTH_BIAS;
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS;
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE;

        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE;
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE;
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP;
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE;
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE;
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_STENCIL_OP;
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE;

        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE;
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY;

        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_CULL_MODE;
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_FRONT_FACE;
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE;
    }
    if (caps.useVertexInputDynamicState()) {
        (*dynamicStates)[count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
    }

    // VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT and VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT are not
    // used because Graphite only sets one scissor and viewport.
    //
    // VK_DYNAMIC_STATE_LOGIC_OP_EXT and VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT are irrelevant to
    // Graphite.
    //
    // VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE is not used because it will be eventually made
    // obsolete with VK_EXT_vertex_input_dynamic_state and VK_EXT_graphics_pipeline_library.
    //
    // Dynamic state from VK_EXT_extended_dynamic_state3 is not yet used.  They _could_ be useful,
    // but very few bits are universal and lots of the interesting bits are covered by
    // VK_EXT_graphics_pipeline_library already.  Still, state like
    // VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT or VK_DYNAMIC_STATE_POLYGON_MODE_EXT could be used in
    // the future.

    SK_UNSAFE_TODO(memset(dynamicInfo, 0, sizeof(VkPipelineDynamicStateCreateInfo)));
    dynamicInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
    dynamicInfo->dynamicStateCount = count;
    dynamicInfo->pDynamicStates = dynamicStates->data();
}

VulkanProgramInfo::~VulkanProgramInfo() {
    if (fVS != VK_NULL_HANDLE) {
        VULKAN_CALL(fSharedContext->interface(),
                    DestroyShaderModule(fSharedContext->device(), fVS, nullptr));
        fVS = VK_NULL_HANDLE;
    }
    if (fFS != VK_NULL_HANDLE) {
        VULKAN_CALL(fSharedContext->interface(),
                    DestroyShaderModule(fSharedContext->device(), fFS, nullptr));
        fFS = VK_NULL_HANDLE;
    }
    if (fLayout != VK_NULL_HANDLE) {
        VULKAN_CALL(fSharedContext->interface(),
                    DestroyPipelineLayout(fSharedContext->device(), fLayout, nullptr));
        fLayout = VK_NULL_HANDLE;
    }
}

const DescriptorData& VulkanGraphicsPipeline::GetInputAttachmentDescriptor() {
    static const DescriptorData descriptor = {
            DescriptorType::kInputAttachment,
            /*count=*/1,
            /*bindingIdx=*/0,  // We only expect to encounter one input attachment
            PipelineStageFlags::kFragmentShader};
    return descriptor;
}

sk_sp<VulkanGraphicsPipeline> VulkanGraphicsPipeline::Make(
        VulkanSharedContext* sharedContext,
        const RuntimeEffectDictionary* runtimeDict,
        const UniqueKey& pipelineKey,
        const GraphicsPipelineDesc& pipelineDesc,
        const RenderPassDesc& renderPassDesc,
        SkEnumBitMask<PipelineCreationFlags> pipelineCreationFlags,
        uint32_t compilationID) {
    VulkanThreadSafeResourceProvider* threadSafeResourceProvider =
        sharedContext->threadSafeResourceProvider();

    SkSL::ProgramSettings settings;
    settings.fSharpenTextures = true;
    settings.fForceNoRTFlip = true;

    ShaderErrorHandler* errorHandler = sharedContext->caps()->shaderErrorHandler();

    const RenderStep* step = sharedContext->rendererProvider()->lookup(pipelineDesc.renderStepID());

    skia_private::TArray<SamplerDesc> descContainer {};
    std::unique_ptr<ShaderInfo> shaderInfo =
            ShaderInfo::Make(sharedContext->caps(),
                             sharedContext->shaderCodeDictionary(),
                             runtimeDict,
                             renderPassDesc,
                             step,
                             pipelineDesc.paintParamsID(),
                             &descContainer);

    if (step->staticAttributes().size() + shaderInfo->appendAttributes().size() >
        sharedContext->vulkanCaps().maxVertexAttributes()) {
        SKIA_LOG_W("Requested more than the supported number of vertex attributes");
        return nullptr;
    }

    // Populate an array of sampler ptrs where a sampler's index within the array indicates their
    // binding index within the descriptor set. Initialize all values to nullptr, which represents a
    // "regular", dynamic sampler at that index.
    skia_private::TArray<sk_sp<VulkanSampler>> immutableSamplers;
    immutableSamplers.push_back_n(shaderInfo->numFragmentTexturesAndSamplers());

    // This logic relies upon Vulkan using combined texture/sampler bindings, which is necessary for
    // ycbcr samplers per the Vulkan spec.
    SkASSERT(!sharedContext->caps()->resourceBindingRequirements().fSeparateTextureAndSamplerBinding
             && shaderInfo->numFragmentTexturesAndSamplers() == descContainer.size());
    for (int i = 0; i < descContainer.size(); i++) {
        // If a SamplerDesc is not equivalent to the default-initialized SamplerDesc, that indicates
        // the usage of an immutable sampler. That sampler desc should then be used to obtain an
        // actual immutable sampler from the resource provider and added at the proper index within
        // immutableSamplers for inclusion in the pipeline layout.
        if (descContainer.at(i) != SamplerDesc()) {
            sk_sp<Sampler> immutableSampler =
                    threadSafeResourceProvider->findOrCreateCompatibleSampler(descContainer.at(i));
            sk_sp<VulkanSampler> vulkanSampler =
                    sk_ref_sp<VulkanSampler>(static_cast<VulkanSampler*>(immutableSampler.get()));
            SkASSERT(vulkanSampler);
            immutableSamplers[i] = std::move(vulkanSampler);
        }
    }

    auto program = VulkanProgramInfo::Make(sharedContext);

    const std::string& fsSkSL = shaderInfo->fragmentSkSL();
    const bool hasFragmentSkSL = !fsSkSL.empty();
    SkSL::NativeShader vsSPIRV, fsSPIRV;
    SkSL::Program::Interface vsInterface, fsInterface;
    if (hasFragmentSkSL) {
        if (!skgpu::SkSLToSPIRV(sharedContext->caps()->shaderCaps(),
                                fsSkSL,
                                SkSL::ProgramKind::kGraphiteFragment,
                                settings,
                                &fsSPIRV,
                                &fsInterface,
                                errorHandler)) {
            return nullptr;
        }

        // Apply transformations to the fragment shader SPIR-V if needed.
        //
        // SkSL->SPIR-V compilations are relatively costly. In anticipation of caching those
        // operations, we allow certain transformations to be applied directly on to compiled
        // SPIR-V. This allows the SkSL to be compiled only once, and the SPIR-V from the cache can
        // simply be directly modified afterwards as needed. This is why transform options exist
        // independently from flags used in SkSL->SPIRV compilation.
        SPIRVTransformOptions options;
        options.fMultisampleInputLoad =
                renderPassDesc.fSampleCount > SampleCount::k1 &&
                shaderInfo->dstReadStrategy() == DstReadStrategy::kReadFromInput;
        if (options.fMultisampleInputLoad) {
            fsSPIRV = TransformSPIRV(fsSPIRV, options);
        }

        if(!program->setFragmentShader(CreateVulkanShaderModule(
                sharedContext, fsSPIRV, VK_SHADER_STAGE_FRAGMENT_BIT))) {
            return nullptr;
        }
    }

    const std::string& vsSkSL = shaderInfo->vertexSkSL();
    if (!skgpu::SkSLToSPIRV(sharedContext->caps()->shaderCaps(),
                           vsSkSL,
                           SkSL::ProgramKind::kGraphiteVertex,
                           settings,
                           &vsSPIRV,
                           &vsInterface,
                           errorHandler)) {
        return nullptr;
    }
    if (!program->setVertexShader(CreateVulkanShaderModule(
                sharedContext, vsSPIRV, VK_SHADER_STAGE_VERTEX_BIT))) {
        return nullptr;
    }

    // TODO: Query RenderPassDesc for input attachment information. For now, we only use one for
    // loading MSAA from resolve so we can simply pass in 0 when not doing that.
    if (!program->setLayout(setup_pipeline_layout(
                sharedContext,
                VulkanResourceProvider::kIntrinsicConstantSize,
                VulkanResourceProvider::kIntrinsicConstantStageFlags,
                shaderInfo->hasCombinedUniforms(),
                shaderInfo->storageBufferStages(),
                shaderInfo->numFragmentTexturesAndSamplers(),
                /*loadMsaaFromResolve=*/false,
                SkSpan<sk_sp<VulkanSampler>>(immutableSamplers)))) {
        return nullptr;
    }

    // This pipeline factory is for regular pipelines that run in the main subpass. Depending on
    // if there will be a load-MSAA subpass, the index changes. Ideally with
    // VK_dynamic_rendering_local_read, we can reuse pipelines across subpasses for layer elision.
    int subpassIndex = RenderPassDescWillLoadMSAAFromResolve(renderPassDesc) ? 1 : 0;
    VertexInputBindingDescriptions vertexBindingDescriptions;
    VertexInputAttributeDescriptions vertexAttributeDescriptions;
    VkPipeline shadersPipeline = VK_NULL_HANDLE;
    VkPipeline vkPipeline = MakePipeline(
            sharedContext,
            *program,
            subpassIndex,
            step->primitiveType(),
            step->appendsVertices() ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE,
            step->staticAttributes(),
            shaderInfo->appendAttributes(),
            vertexBindingDescriptions,
            vertexAttributeDescriptions,
            shaderInfo->depthStencilSettings(),
            shaderInfo->blendInfo(),
            renderPassDesc,
            &shadersPipeline);

    sk_sp<VulkanGraphicsPipeline> pipeline;
    if (vkPipeline) {
        PipelineInfo pipelineInfo{ *shaderInfo, pipelineCreationFlags,
                                    pipelineKey.hash(), compilationID };
#if defined(GPU_TEST_UTILS)
        pipelineInfo.fNativeVertexShader = SkShaderUtils::SpirvAsHexStream(vsSPIRV.fBinary);
        pipelineInfo.fNativeFragmentShader = SkShaderUtils::SpirvAsHexStream(fsSPIRV.fBinary);
#endif

        bool hasPaintParamAttributes = !shaderInfo->appendAttributes().empty();
        pipeline = sk_sp<VulkanGraphicsPipeline>(
                new VulkanGraphicsPipeline(sharedContext,
                                           pipelineInfo,
                                           shaderInfo->pipelineLabel(),
                                           program->releaseLayout(),
                                           vkPipeline,
                                           shadersPipeline,
                                           /*ownsPipelineLayout=*/true,
                                           std::move(immutableSamplers),
                                           step->renderStepID(),
                                           step->primitiveType(),
                                           shaderInfo->depthStencilSettings(),
                                           std::move(vertexBindingDescriptions),
                                           std::move(vertexAttributeDescriptions),
                                           hasPaintParamAttributes));
    }

    return pipeline;
}

VkPipeline VulkanGraphicsPipeline::MakePipeline(
        VulkanSharedContext* sharedContext,
        const VulkanProgramInfo& program,
        int subpassIndex,
        PrimitiveType primitiveType,
        VkVertexInputRate appendInputRate,
        SkSpan<const Attribute> staticAttrs,
        SkSpan<const Attribute> appendAttrs,
        VertexInputBindingDescriptions& vertexBindingDescriptions,
        VertexInputAttributeDescriptions& vertexAttributeDescriptions,
        const DepthStencilSettings& depthStencilSettings,
        const BlendInfo& blendInfo,
        const RenderPassDesc& renderPassDesc,
        VkPipeline* shadersPipeline) {
    SkASSERT(program.layout() && program.vs()); // but a fragment shader isn't required

    VulkanThreadSafeResourceProvider* threadSafeResourceProvider =
        sharedContext->threadSafeResourceProvider();

    VkPipelineVertexInputStateCreateInfo vertexInputInfo;
    skia_private::STArray<2, VkVertexInputBindingDescription> bindingDescs;
    skia_private::STArray<16, VkVertexInputAttributeDescription> attributeDescs;
    if (sharedContext->caps()->useVertexInputDynamicState()) {
        VkVertexInputBindingDescription2EXT defaultBindingDesc = {};
        defaultBindingDesc.sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT;
        defaultBindingDesc.divisor = 1;

        VkVertexInputAttributeDescription2EXT defaultAttributeDesc = {};
        defaultAttributeDesc.sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT;

        get_vertex_input_state(appendInputRate,
                               staticAttrs,
                               appendAttrs,
                               vertexBindingDescriptions,
                               vertexAttributeDescriptions,
                               defaultBindingDesc,
                               defaultAttributeDesc);
    } else {
        setup_vertex_input_state(appendInputRate,
                                 staticAttrs,
                                 appendAttrs,
                                 &vertexInputInfo,
                                 bindingDescs,
                                 attributeDescs);
    }

    VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo;
    setup_input_assembly_state(*sharedContext->caps(), primitiveType, &inputAssemblyInfo);

    VkPipelineDepthStencilStateCreateInfo depthStencilInfo;
    setup_depth_stencil_state(*sharedContext->caps(), depthStencilSettings, &depthStencilInfo);

    VkPipelineViewportStateCreateInfo viewportInfo;
    setup_viewport_scissor_state(&viewportInfo);

    VkPipelineMultisampleStateCreateInfo multisampleInfo;
    setup_multisample_state(renderPassDesc.fSampleCount, &multisampleInfo);

    // We will only have one color blend attachment per pipeline.
    VkPipelineColorBlendAttachmentState attachmentStates[1];
    VkPipelineColorBlendStateCreateInfo colorBlendInfo;
    setup_color_blend_state(
            sharedContext->vulkanCaps(), blendInfo, &colorBlendInfo, attachmentStates);

    VkPipelineRasterizationStateCreateInfo rasterInfo;
    // TODO: Check for wire frame mode once that is an available context option within graphite.
    setup_raster_state(*sharedContext->caps(), /*isWireframe=*/false, &rasterInfo);

    VkPipelineShaderStageCreateInfo pipelineShaderStages[2];
    setup_shader_stage_info(VK_SHADER_STAGE_VERTEX_BIT,
                            program.vs(),
                            &pipelineShaderStages[0]);
    if (program.fs()) {
        setup_shader_stage_info(VK_SHADER_STAGE_FRAGMENT_BIT,
                                program.fs(),
                                &pipelineShaderStages[1]);
    }

    VkDynamicStateList dynamicStates;
    VkPipelineDynamicStateCreateInfo dynamicInfo;
    setup_dynamic_state(*sharedContext->caps(), &dynamicInfo, &dynamicStates);

    sk_sp<VulkanRenderPass> compatibleRenderPass =
            threadSafeResourceProvider->findOrCreateRenderPass(renderPassDesc,
                                                               /*compatibleOnly=*/true);
    if (!compatibleRenderPass) {
        SKIA_LOG_E("Failed to create compatible renderpass for pipeline");
        return VK_NULL_HANDLE;
    }
    SkDEBUGCODE(int subpassCount = RenderPassDescWillLoadMSAAFromResolve(renderPassDesc) ? 2 : 1;)
    SkASSERT(subpassIndex >= 0 && subpassIndex < subpassCount);

    VkGraphicsPipelineCreateInfo pipelineCreateInfo = {};
    pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
    pipelineCreateInfo.stageCount = program.fs() ? 2 : 1;
    pipelineCreateInfo.pStages = &pipelineShaderStages[0];
    pipelineCreateInfo.pVertexInputState =
            sharedContext->caps()->useVertexInputDynamicState() ? nullptr : &vertexInputInfo;
    pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo;
    pipelineCreateInfo.pTessellationState = nullptr;
    pipelineCreateInfo.pViewportState = &viewportInfo;
    pipelineCreateInfo.pRasterizationState = &rasterInfo;
    pipelineCreateInfo.pMultisampleState = &multisampleInfo;
    pipelineCreateInfo.pDepthStencilState = &depthStencilInfo;
    pipelineCreateInfo.pColorBlendState = &colorBlendInfo;
    pipelineCreateInfo.pDynamicState = &dynamicInfo;
    pipelineCreateInfo.layout = program.layout();
    pipelineCreateInfo.renderPass = compatibleRenderPass->renderPass();
    pipelineCreateInfo.subpass = subpassIndex;
    pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
    pipelineCreateInfo.basePipelineIndex = -1;

    if (sharedContext->vulkanCaps().supportsPipelineProtectedAccess()) {
        pipelineCreateInfo.flags |= sharedContext->caps()->protectedSupport()
                                        ? VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT_EXT
                                        : VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT;
    }

    VkPipelineLibraryCreateInfoKHR shadersLibraryInfo = {};
    shadersLibraryInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR;

    VkGraphicsPipelineLibraryCreateInfoEXT libraryInfo = {};
    libraryInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT;

    if (shadersPipeline && sharedContext->caps()->usePipelineLibraries()) {
        // When using VK_EXT_graphics_pipeline_library, create the "shaders" subset of the pipeline,
        // and then create the full pipeline (with the vertex input and fragment output state)
        // immediately afterwards using the shaders library, which is a cheap operation.
        // This is typically what vendors without dynamic blend state do in their GL drivers.
        //
        // This can be further optimized by the front-end creating fewer shaders pipelines, and only
        // create multiple full pipelines out of them as needed.
        if (!create_shaders_pipeline(sharedContext,
                                     pipelineCreateInfo,
                                     shadersLibraryInfo,
                                     libraryInfo,
                                     shadersPipeline)) {
            return VK_NULL_HANDLE;
        }
    }

    return create_graphics_pipeline(sharedContext, &pipelineCreateInfo);
}

std::unique_ptr<VulkanProgramInfo> VulkanGraphicsPipeline::CreateLoadMSAAProgram(
        const VulkanSharedContext* sharedContext) {
    SkSL::ProgramSettings settings;
    settings.fForceNoRTFlip = true;
    SkSL::NativeShader vsSPIRV, fsSPIRV;
    ShaderErrorHandler* errorHandler = sharedContext->caps()->shaderErrorHandler();

    std::string vertShaderText;
    vertShaderText.append(
            // MSAA Load Program VS
            "void main() {"
                // Derive [0,1]x[0,1] coordinates from vertex ID and then scale to [-1,1] for NDC.
                "float2 position = float2(sk_VertexID >> 1, sk_VertexID & 1);"
                "sk_Position = float4(2 * position - 1, 0, 1);"
            "}");

    std::string fragShaderText;
    fragShaderText.append(
            "layout(vulkan, input_attachment_index=0, set=" +
            std::to_string(VulkanGraphicsPipeline::kLoadMsaaFromResolveInputDescSetIndex) +
            ", binding=0) subpassInput uInput;"

            // MSAA Load Program FS
            "void main() {"
                "sk_FragColor = subpassLoad(uInput);"
            "}");

    auto program = VulkanProgramInfo::Make(sharedContext);

    SkSL::Program::Interface vsInterface, fsInterface;
    if (!skgpu::SkSLToSPIRV(sharedContext->caps()->shaderCaps(),
                            vertShaderText,
                            SkSL::ProgramKind::kGraphiteVertex,
                            settings,
                            &vsSPIRV,
                            &vsInterface,
                            errorHandler)) {
        return nullptr;
    }
    if (!program->setVertexShader(CreateVulkanShaderModule(
                sharedContext, vsSPIRV, VK_SHADER_STAGE_VERTEX_BIT))) {
        return nullptr;
    }

    if (!skgpu::SkSLToSPIRV(sharedContext->caps()->shaderCaps(),
                            fragShaderText,
                            SkSL::ProgramKind::kGraphiteFragment,
                            settings,
                            &fsSPIRV,
                            &fsInterface,
                            errorHandler)) {
        return nullptr;
    }
    if (!program->setFragmentShader(CreateVulkanShaderModule(
                sharedContext, fsSPIRV, VK_SHADER_STAGE_FRAGMENT_BIT))) {
        return nullptr;
    }

    // The load msaa pipeline takes no step or paint uniforms and no instance attributes. It only
    // references one input attachment texture (which does not require a sampler) and one vertex
    // attribute (NDC position)
    skia_private::TArray<DescriptorData> inputAttachmentDescriptors(1);
    inputAttachmentDescriptors.push_back(VulkanGraphicsPipeline::GetInputAttachmentDescriptor());
    // This pipeline is used to read from the resolve attachment to a color attachment. We should
    // never require an immutable sampler for this, since that would imply that we are rendering to
    // a surface with an external format.
    if (!program->setLayout(setup_pipeline_layout(
                sharedContext,
                /*pushConstantSize=*/0,
                (VkShaderStageFlagBits)VK_SHADER_STAGE_VERTEX_BIT,
                /*hasCombinedUniforms=*/false,
                /*storageStageFlags=*/{},
                /*numTextureSamplers=*/0,
                /*loadMsaaFromResolve=*/true,
                /*immutableSamplers=*/{}))) {
        return nullptr;
    }

    return program;
}

sk_sp<VulkanGraphicsPipeline> VulkanGraphicsPipeline::MakeLoadMSAAPipeline(
        VulkanSharedContext* sharedContext,
        const VulkanProgramInfo& loadMSAAProgram,
        const RenderPassDesc& renderPassDesc) {
    // The load MSAA pipeline does not have any vertex or instance attributes, does not use the
    // depth or stencil attachments. Unlike the general Make factory, we do not destroy any of the
    // shader modules or layout. The pipeline layout will not be owned by the created
    // VulkanGraphicsPipeline either, as it's owned by the resource provider.
    SkASSERT(RenderPassDescWillLoadMSAAFromResolve(renderPassDesc));
    VertexInputBindingDescriptions vertexBindingDescriptions;
    VertexInputAttributeDescriptions vertexAttributeDescriptions;
    VkPipeline vkPipeline = MakePipeline(sharedContext,
                                         loadMSAAProgram,
                                         /*subpassIndex=*/0,  // loading to MSAA is always first
                                         PrimitiveType::kTriangleStrip,
                                         /*appendInputRate=*/{},
                                         /*staticAttrs=*/{},
                                         /*appendAttrs=*/{},
                                         vertexBindingDescriptions,
                                         vertexAttributeDescriptions,
                                         /*depthStencilSettings=*/{},
                                         /*blendInfo=*/{},
                                         renderPassDesc,
                                         /*shadersPipeline=*/nullptr);
    if (!vkPipeline) {
        return nullptr;
    }

    SkASSERT(vertexBindingDescriptions.empty());
    SkASSERT(vertexAttributeDescriptions.empty());

    std::string pipelineLabel = "LoadMSAAFromResolve + ";
    pipelineLabel += renderPassDesc.toString().c_str();
    return sk_sp<VulkanGraphicsPipeline>(
            new VulkanGraphicsPipeline(sharedContext,
                                       /*pipelineInfo=*/{},  // leave empty for an internal pipeline
                                       pipelineLabel,
                                       loadMSAAProgram.layout(),
                                       vkPipeline,
                                       /*shadersPipeline=*/VK_NULL_HANDLE,
                                       /*ownsPipelineLayout=*/false,
                                       /*immutableSamplers=*/{},
                                       RenderStep::RenderStepID::kInvalid,
                                       PrimitiveType::kTriangleStrip,
                                       /*depthStencilSettings=*/{},
                                       /*vertexBindingDescriptions=*/{},
                                       /*vertexAttributeDescriptions=*/{},
                                       /*hasPaintParamAttributes=*/false));
}

VulkanGraphicsPipeline::VulkanGraphicsPipeline(
        const VulkanSharedContext* sharedContext,
        const PipelineInfo& pipelineInfo,
        std::string_view pipelineLabel,
        VkPipelineLayout pipelineLayout,
        VkPipeline pipeline,
        VkPipeline shadersPipeline,
        bool ownsPipelineLayout,
        skia_private::TArray<sk_sp<VulkanSampler>>&& immutableSamplers,
        RenderStep::RenderStepID renderStepID,
        PrimitiveType primitiveType,
        const DepthStencilSettings& depthStencilSettings,
        VertexInputBindingDescriptions&& vertexBindingDescriptions,
        VertexInputAttributeDescriptions&& vertexAttributeDescriptions,
        bool hasPaintParamAttributes)
    : GraphicsPipeline(sharedContext, pipelineInfo, pipelineLabel)
    , fPipelineLayout(pipelineLayout)
    , fPipeline(pipeline)
    , fShadersPipeline(shadersPipeline)
    , fOwnsPipelineLayout(ownsPipelineLayout)
    , fImmutableSamplers(std::move(immutableSamplers))
    , fPrimitiveType(primitiveType)
    , fDepthStencilSettings(depthStencilSettings)
    , fRenderStepID(renderStepID)
    , fHasPaintParamAttributes(hasPaintParamAttributes)
    , fVertexBindingDescriptions(std::move(vertexBindingDescriptions))
    , fVertexAttributeDescriptions(std::move(vertexAttributeDescriptions)) {
    // Update the newly-created underlying GPU object's label to match the Resource's
    this->synchronizeBackendLabel();
}

void VulkanGraphicsPipeline::freeGpuData() {
    auto sharedCtxt = static_cast<const VulkanSharedContext*>(this->sharedContext());
    if (fShadersPipeline != VK_NULL_HANDLE) {
        VULKAN_CALL(sharedCtxt->interface(),
                    DestroyPipeline(sharedCtxt->device(), fShadersPipeline, nullptr));
    }
    if (fPipeline != VK_NULL_HANDLE) {
        VULKAN_CALL(sharedCtxt->interface(),
            DestroyPipeline(sharedCtxt->device(), fPipeline, nullptr));
    }
    if (fOwnsPipelineLayout && fPipelineLayout != VK_NULL_HANDLE) {
        VULKAN_CALL(sharedCtxt->interface(),
                    DestroyPipelineLayout(sharedCtxt->device(), fPipelineLayout, nullptr));
    }
}

void VulkanGraphicsPipeline::updateDynamicState(const VulkanSharedContext* sharedContext,
                                                VkCommandBuffer commandBuffer,
                                                const VulkanGraphicsPipeline* previous) const {
    // The front-end currently is unaware of dynamic state, so we have no choice but to calculate
    // the diff between pipelines and update the state as needed.  This is not quite so efficient,
    // but will need awareness from the front-end to optimize.
    if (sharedContext->caps()->useBasicDynamicState()) {
        // Primitive type
        const bool primitiveTypeDirty =
                previous == nullptr || previous->fPrimitiveType != fPrimitiveType;
        if (primitiveTypeDirty) {
            VULKAN_CALL(sharedContext->interface(),
                        CmdSetPrimitiveTopology(commandBuffer,
                                                primitive_type_to_vk_topology(fPrimitiveType)));
        }

        // Depth-stencil settings
        const auto& [depth, stencil] = fDepthStencilSettings;
        const auto& [pastDepth, pastStencil] =
                previous ? previous->fDepthStencilSettings
                         : std::make_pair(DepthSettings(), StencilSettings()); // ignored

        const bool depthEnabledDirty = !previous || pastDepth.enabled() != depth.enabled();
        if (depthEnabledDirty) {
            VULKAN_CALL(sharedContext->interface(),
                        CmdSetDepthTestEnable(commandBuffer, depth.enabled()));
        }
        const bool depthCompareOpDirty = !previous || pastDepth.fCompareOp != depth.fCompareOp;
        if (depthCompareOpDirty) {
            VULKAN_CALL(sharedContext->interface(),
                        CmdSetDepthCompareOp(commandBuffer,
                                             compare_op_to_vk_compare_op(depth.fCompareOp)));
        }
        const bool depthWriteDirty = !previous || pastDepth.fWriteEnabled != depth.fWriteEnabled;
        if (depthWriteDirty) {
            VULKAN_CALL(sharedContext->interface(),
                        CmdSetDepthWriteEnable(commandBuffer, depth.fWriteEnabled));
        }

        const bool stencilEnabledDirty = !previous || pastStencil.enabled() != stencil.enabled();
        if (stencilEnabledDirty) {
            VULKAN_CALL(sharedContext->interface(),
                        CmdSetStencilTestEnable(commandBuffer, stencil.enabled()));
        }

        // The rest of the stencil state only needs to be checked if we have non-default state or
        // if the test state was dirty (in which case it needs to be set back to the default).
        if (stencilEnabledDirty || stencil.enabled()) {
            // FRONT_AND_BACK
            const bool readMaskDirty = !previous || pastStencil.fReadMask != stencil.fReadMask;
            if (readMaskDirty) {
                VULKAN_CALL(sharedContext->interface(),
                            CmdSetStencilCompareMask(commandBuffer,
                                                     VK_STENCIL_FACE_FRONT_AND_BACK,
                                                     stencil.fReadMask));
            }
            const bool writeMaskDirty = !previous || pastStencil.fWriteMask != stencil.fWriteMask;
            if (writeMaskDirty) {
                VULKAN_CALL(sharedContext->interface(),
                            CmdSetStencilWriteMask(commandBuffer,
                                                   VK_STENCIL_FACE_FRONT_AND_BACK,
                                                   stencil.fWriteMask));
            }
            const bool referenceValueDirty =
                    !previous || pastStencil.fReferenceValue != stencil.fReferenceValue;
            if (referenceValueDirty) {
                VULKAN_CALL(sharedContext->interface(),
                            CmdSetStencilReference(commandBuffer,
                                                   VK_STENCIL_FACE_FRONT_AND_BACK,
                                                   stencil.fReferenceValue));
            }
\
            // FRONT-only
            const StencilSettings::Face& front = stencil.fFrontFace;
            const bool frontStencilOpsDirty = !previous || pastStencil.fFrontFace != front;
            if (frontStencilOpsDirty) {
                VULKAN_CALL(
                        sharedContext->interface(),
                        CmdSetStencilOp(commandBuffer,
                                        VK_STENCIL_FACE_FRONT_BIT,
                                        /*failOp=*/
                                        stencil_op_to_vk_stencil_op(front.fStencilFailOp),
                                        /*passOp=*/
                                        stencil_op_to_vk_stencil_op(front.fDepthStencilPassOp),
                                        /*depthFailOp=*/
                                        stencil_op_to_vk_stencil_op(front.fDepthFailOp),
                                        /*compareOp=*/
                                        compare_op_to_vk_compare_op(front.fCompareOp)));
            }

            // BACK-only
            const StencilSettings::Face& back = stencil.fBackFace;
            const bool backStencilOpsDirty = !previous || pastStencil.fBackFace != back;
            if (backStencilOpsDirty) {
                VULKAN_CALL(
                        sharedContext->interface(),
                        CmdSetStencilOp(commandBuffer,
                                        VK_STENCIL_FACE_BACK_BIT,
                                        /*failOp=*/
                                        stencil_op_to_vk_stencil_op(back.fStencilFailOp),
                                        /*passOp=*/
                                        stencil_op_to_vk_stencil_op(back.fDepthStencilPassOp),
                                        /*depthFailOp=*/
                                        stencil_op_to_vk_stencil_op(back.fDepthFailOp),
                                        /*compareOp=*/
                                        compare_op_to_vk_compare_op(back.fCompareOp)));
            }
        }
    }

    if (sharedContext->caps()->useVertexInputDynamicState()) {
        const bool vertexInputDirty =
                previous == nullptr ||
                previous->fRenderStepID != fRenderStepID ||
                fHasPaintParamAttributes || previous->fHasPaintParamAttributes;

        if (vertexInputDirty) {
            VULKAN_CALL(sharedContext->interface(),
                        CmdSetVertexInput(commandBuffer,
                                          fVertexBindingDescriptions.size(),
                                          fVertexBindingDescriptions.begin(),
                                          fVertexAttributeDescriptions.size(),
                                          fVertexAttributeDescriptions.begin()));
        }
    }
}

} // namespace skgpu::graphite
