// Copyright 2018 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/dawn/native/vulkan/RenderPipelineVk.h"

#include <string>
#include <utility>
#include <vector>

#include "src/dawn/native/CreatePipelineAsyncEvent.h"
#include "src/dawn/native/vulkan/DeviceVk.h"
#include "src/dawn/native/vulkan/FencedDeleter.h"
#include "src/dawn/native/vulkan/ImmediatesLayoutVk.h"
#include "src/dawn/native/vulkan/PipelineCacheVk.h"
#include "src/dawn/native/vulkan/PipelineLayoutVk.h"
#include "src/dawn/native/vulkan/RenderPassCache.h"
#include "src/dawn/native/vulkan/ShaderModuleVk.h"
#include "src/dawn/native/vulkan/TextureVk.h"
#include "src/dawn/native/vulkan/UtilsVulkan.h"
#include "src/dawn/native/vulkan/VulkanError.h"
#include "src/dawn/platform/metrics/HistogramMacros.h"

namespace dawn::native::vulkan {

namespace {

VkVertexInputRate VulkanInputRate(wgpu::VertexStepMode stepMode) {
    switch (stepMode) {
        case wgpu::VertexStepMode::Vertex:
            return VK_VERTEX_INPUT_RATE_VERTEX;
        case wgpu::VertexStepMode::Instance:
            return VK_VERTEX_INPUT_RATE_INSTANCE;
        case wgpu::VertexStepMode::Undefined:
            break;
    }
    DAWN_UNREACHABLE();
}

VkFormat VulkanVertexFormat(wgpu::VertexFormat format) {
    switch (format) {
        case wgpu::VertexFormat::Uint8:
            return VK_FORMAT_R8_UINT;
        case wgpu::VertexFormat::Uint8x2:
            return VK_FORMAT_R8G8_UINT;
        case wgpu::VertexFormat::Uint8x4:
            return VK_FORMAT_R8G8B8A8_UINT;
        case wgpu::VertexFormat::Sint8:
            return VK_FORMAT_R8_SINT;
        case wgpu::VertexFormat::Sint8x2:
            return VK_FORMAT_R8G8_SINT;
        case wgpu::VertexFormat::Sint8x4:
            return VK_FORMAT_R8G8B8A8_SINT;
        case wgpu::VertexFormat::Unorm8:
            return VK_FORMAT_R8_UNORM;
        case wgpu::VertexFormat::Unorm8x2:
            return VK_FORMAT_R8G8_UNORM;
        case wgpu::VertexFormat::Unorm8x4:
            return VK_FORMAT_R8G8B8A8_UNORM;
        case wgpu::VertexFormat::Snorm8:
            return VK_FORMAT_R8_SNORM;
        case wgpu::VertexFormat::Snorm8x2:
            return VK_FORMAT_R8G8_SNORM;
        case wgpu::VertexFormat::Snorm8x4:
            return VK_FORMAT_R8G8B8A8_SNORM;
        case wgpu::VertexFormat::Uint16:
            return VK_FORMAT_R16_UINT;
        case wgpu::VertexFormat::Uint16x2:
            return VK_FORMAT_R16G16_UINT;
        case wgpu::VertexFormat::Uint16x4:
            return VK_FORMAT_R16G16B16A16_UINT;
        case wgpu::VertexFormat::Sint16:
            return VK_FORMAT_R16_SINT;
        case wgpu::VertexFormat::Sint16x2:
            return VK_FORMAT_R16G16_SINT;
        case wgpu::VertexFormat::Sint16x4:
            return VK_FORMAT_R16G16B16A16_SINT;
        case wgpu::VertexFormat::Unorm16:
            return VK_FORMAT_R16_UNORM;
        case wgpu::VertexFormat::Unorm16x2:
            return VK_FORMAT_R16G16_UNORM;
        case wgpu::VertexFormat::Unorm16x4:
            return VK_FORMAT_R16G16B16A16_UNORM;
        case wgpu::VertexFormat::Snorm16:
            return VK_FORMAT_R16_SNORM;
        case wgpu::VertexFormat::Snorm16x2:
            return VK_FORMAT_R16G16_SNORM;
        case wgpu::VertexFormat::Snorm16x4:
            return VK_FORMAT_R16G16B16A16_SNORM;
        case wgpu::VertexFormat::Float16:
            return VK_FORMAT_R16_SFLOAT;
        case wgpu::VertexFormat::Float16x2:
            return VK_FORMAT_R16G16_SFLOAT;
        case wgpu::VertexFormat::Float16x4:
            return VK_FORMAT_R16G16B16A16_SFLOAT;
        case wgpu::VertexFormat::Float32:
            return VK_FORMAT_R32_SFLOAT;
        case wgpu::VertexFormat::Float32x2:
            return VK_FORMAT_R32G32_SFLOAT;
        case wgpu::VertexFormat::Float32x3:
            return VK_FORMAT_R32G32B32_SFLOAT;
        case wgpu::VertexFormat::Float32x4:
            return VK_FORMAT_R32G32B32A32_SFLOAT;
        case wgpu::VertexFormat::Uint32:
            return VK_FORMAT_R32_UINT;
        case wgpu::VertexFormat::Uint32x2:
            return VK_FORMAT_R32G32_UINT;
        case wgpu::VertexFormat::Uint32x3:
            return VK_FORMAT_R32G32B32_UINT;
        case wgpu::VertexFormat::Uint32x4:
            return VK_FORMAT_R32G32B32A32_UINT;
        case wgpu::VertexFormat::Sint32:
            return VK_FORMAT_R32_SINT;
        case wgpu::VertexFormat::Sint32x2:
            return VK_FORMAT_R32G32_SINT;
        case wgpu::VertexFormat::Sint32x3:
            return VK_FORMAT_R32G32B32_SINT;
        case wgpu::VertexFormat::Sint32x4:
            return VK_FORMAT_R32G32B32A32_SINT;
        case wgpu::VertexFormat::Unorm10_10_10_2:
            return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
        case wgpu::VertexFormat::Unorm8x4BGRA:
            return VK_FORMAT_B8G8R8A8_UNORM;
        default:
            DAWN_UNREACHABLE();
    }
}

VkPrimitiveTopology VulkanPrimitiveTopology(wgpu::PrimitiveTopology topology) {
    switch (topology) {
        case wgpu::PrimitiveTopology::PointList:
            return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
        case wgpu::PrimitiveTopology::LineList:
            return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
        case wgpu::PrimitiveTopology::LineStrip:
            return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
        case wgpu::PrimitiveTopology::TriangleList:
            return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
        case wgpu::PrimitiveTopology::TriangleStrip:
            return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
        case wgpu::PrimitiveTopology::Undefined:
            break;
    }
    DAWN_UNREACHABLE();
}

bool ShouldEnablePrimitiveRestart(wgpu::PrimitiveTopology topology) {
    // Primitive restart is always enabled in WebGPU but Vulkan validation rules ask that
    // primitive restart be only enabled on primitive topologies that support restarting.
    switch (topology) {
        case wgpu::PrimitiveTopology::PointList:
        case wgpu::PrimitiveTopology::LineList:
        case wgpu::PrimitiveTopology::TriangleList:
            return false;
        case wgpu::PrimitiveTopology::LineStrip:
        case wgpu::PrimitiveTopology::TriangleStrip:
            return true;
        case wgpu::PrimitiveTopology::Undefined:
            break;
    }
    DAWN_UNREACHABLE();
}

VkFrontFace VulkanFrontFace(wgpu::FrontFace face) {
    switch (face) {
        case wgpu::FrontFace::CCW:
            return VK_FRONT_FACE_COUNTER_CLOCKWISE;
        case wgpu::FrontFace::CW:
            return VK_FRONT_FACE_CLOCKWISE;
        case wgpu::FrontFace::Undefined:
            break;
    }
    DAWN_UNREACHABLE();
}

VkCullModeFlagBits VulkanCullMode(wgpu::CullMode mode) {
    switch (mode) {
        case wgpu::CullMode::None:
            return VK_CULL_MODE_NONE;
        case wgpu::CullMode::Front:
            return VK_CULL_MODE_FRONT_BIT;
        case wgpu::CullMode::Back:
            return VK_CULL_MODE_BACK_BIT;
        case wgpu::CullMode::Undefined:
            break;
    }
    DAWN_UNREACHABLE();
}

VkBlendFactor VulkanBlendFactor(wgpu::BlendFactor factor) {
    switch (factor) {
        case wgpu::BlendFactor::Zero:
            return VK_BLEND_FACTOR_ZERO;
        case wgpu::BlendFactor::One:
            return VK_BLEND_FACTOR_ONE;
        case wgpu::BlendFactor::Src:
            return VK_BLEND_FACTOR_SRC_COLOR;
        case wgpu::BlendFactor::OneMinusSrc:
            return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
        case wgpu::BlendFactor::SrcAlpha:
            return VK_BLEND_FACTOR_SRC_ALPHA;
        case wgpu::BlendFactor::OneMinusSrcAlpha:
            return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
        case wgpu::BlendFactor::Dst:
            return VK_BLEND_FACTOR_DST_COLOR;
        case wgpu::BlendFactor::OneMinusDst:
            return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
        case wgpu::BlendFactor::DstAlpha:
            return VK_BLEND_FACTOR_DST_ALPHA;
        case wgpu::BlendFactor::OneMinusDstAlpha:
            return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
        case wgpu::BlendFactor::SrcAlphaSaturated:
            return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
        case wgpu::BlendFactor::Constant:
            return VK_BLEND_FACTOR_CONSTANT_COLOR;
        case wgpu::BlendFactor::OneMinusConstant:
            return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
        case wgpu::BlendFactor::Src1:
            return VK_BLEND_FACTOR_SRC1_COLOR;
        case wgpu::BlendFactor::OneMinusSrc1:
            return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
        case wgpu::BlendFactor::Src1Alpha:
            return VK_BLEND_FACTOR_SRC1_ALPHA;
        case wgpu::BlendFactor::OneMinusSrc1Alpha:
            return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
        case wgpu::BlendFactor::Undefined:
            break;
    }
    DAWN_UNREACHABLE();
}

VkBlendOp VulkanBlendOperation(wgpu::BlendOperation operation) {
    switch (operation) {
        case wgpu::BlendOperation::Add:
            return VK_BLEND_OP_ADD;
        case wgpu::BlendOperation::Subtract:
            return VK_BLEND_OP_SUBTRACT;
        case wgpu::BlendOperation::ReverseSubtract:
            return VK_BLEND_OP_REVERSE_SUBTRACT;
        case wgpu::BlendOperation::Min:
            return VK_BLEND_OP_MIN;
        case wgpu::BlendOperation::Max:
            return VK_BLEND_OP_MAX;
        case wgpu::BlendOperation::Undefined:
            break;
    }
    DAWN_UNREACHABLE();
}

VkColorComponentFlags VulkanColorWriteMask(wgpu::ColorWriteMask mask,
                                           bool isDeclaredInFragmentShader) {
    // Vulkan and Dawn color write masks match, static assert it and return the mask
    static_assert(static_cast<VkColorComponentFlagBits>(wgpu::ColorWriteMask::Red) ==
                  VK_COLOR_COMPONENT_R_BIT);
    static_assert(static_cast<VkColorComponentFlagBits>(wgpu::ColorWriteMask::Green) ==
                  VK_COLOR_COMPONENT_G_BIT);
    static_assert(static_cast<VkColorComponentFlagBits>(wgpu::ColorWriteMask::Blue) ==
                  VK_COLOR_COMPONENT_B_BIT);
    static_assert(static_cast<VkColorComponentFlagBits>(wgpu::ColorWriteMask::Alpha) ==
                  VK_COLOR_COMPONENT_A_BIT);

    // According to Vulkan SPEC (Chapter 14.3): "The input values to blending or color
    // attachment writes are undefined for components which do not correspond to a fragment
    // shader outputs", we set the color write mask to 0 to prevent such undefined values
    // being written into the color attachments.
    return isDeclaredInFragmentShader ? static_cast<VkColorComponentFlags>(mask)
                                      : static_cast<VkColorComponentFlags>(0);
}

VkPipelineColorBlendAttachmentState ComputeColorDesc(const ColorTargetState* state,
                                                     bool isDeclaredInFragmentShader) {
    VkPipelineColorBlendAttachmentState attachment;
    attachment.blendEnable = state->blend != nullptr ? VK_TRUE : VK_FALSE;
    if (attachment.blendEnable) {
        attachment.srcColorBlendFactor = VulkanBlendFactor(state->blend->color.srcFactor);
        attachment.dstColorBlendFactor = VulkanBlendFactor(state->blend->color.dstFactor);
        attachment.colorBlendOp = VulkanBlendOperation(state->blend->color.operation);
        attachment.srcAlphaBlendFactor = VulkanBlendFactor(state->blend->alpha.srcFactor);
        attachment.dstAlphaBlendFactor = VulkanBlendFactor(state->blend->alpha.dstFactor);
        attachment.alphaBlendOp = VulkanBlendOperation(state->blend->alpha.operation);
    } else {
        // Swiftshader's Vulkan implementation appears to expect these values to be valid
        // even when blending is not enabled.
        attachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
        attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
        attachment.colorBlendOp = VK_BLEND_OP_ADD;
        attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
        attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
        attachment.alphaBlendOp = VK_BLEND_OP_ADD;
    }
    attachment.colorWriteMask = VulkanColorWriteMask(state->writeMask, isDeclaredInFragmentShader);
    return attachment;
}

VkStencilOp VulkanStencilOp(wgpu::StencilOperation op) {
    switch (op) {
        case wgpu::StencilOperation::Keep:
            return VK_STENCIL_OP_KEEP;
        case wgpu::StencilOperation::Zero:
            return VK_STENCIL_OP_ZERO;
        case wgpu::StencilOperation::Replace:
            return VK_STENCIL_OP_REPLACE;
        case wgpu::StencilOperation::IncrementClamp:
            return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
        case wgpu::StencilOperation::DecrementClamp:
            return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
        case wgpu::StencilOperation::Invert:
            return VK_STENCIL_OP_INVERT;
        case wgpu::StencilOperation::IncrementWrap:
            return VK_STENCIL_OP_INCREMENT_AND_WRAP;
        case wgpu::StencilOperation::DecrementWrap:
            return VK_STENCIL_OP_DECREMENT_AND_WRAP;
        case wgpu::StencilOperation::Undefined:
            break;
    }
    DAWN_UNREACHABLE();
}

uint16_t PackStencilOpState(VkStencilOpState state, VkBool32 enabled) {
    // Both VkStencilOp and VkCompareOp have values ranging from 0-7, so they fit in 3 bits.
    // So we can encode the full dynamic stencil state in 12 bits.
    DAWN_ASSERT(static_cast<uint32_t>(state.failOp) < 8);
    DAWN_ASSERT(static_cast<uint32_t>(state.passOp) < 8);
    DAWN_ASSERT(static_cast<uint32_t>(state.depthFailOp) < 8);
    DAWN_ASSERT(static_cast<uint32_t>(state.compareOp) < 8);
    uint16_t packed = state.failOp | state.passOp << 3 | state.depthFailOp << 6 |
                      state.compareOp << 9 |
                      (enabled ? 0x8000 : 0);  // Set high bit if stencil is enabled.
    return packed;
}

VkStencilOpState UnpackStencilOpState(uint16_t packed) {
    VkStencilOpState state = {
        .failOp = static_cast<VkStencilOp>(packed & 0x0007),
        .passOp = static_cast<VkStencilOp>((packed >> 3) & 0x0007),
        .depthFailOp = static_cast<VkStencilOp>((packed >> 6) & 0x0007),
        .compareOp = static_cast<VkCompareOp>((packed >> 9) & 0x0007),
        .compareMask = 0,
        .writeMask = 0,
        .reference = 0,
    };
    return state;
}

VkPrimitiveTopology GetTopologyClass(VkPrimitiveTopology topology) {
    switch (topology) {
        case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
            return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
        case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
        case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
            return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
        case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
        case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
            return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
        default:
            DAWN_UNREACHABLE();
            return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
    }
}

}  // anonymous namespace

// static
Ref<RenderPipeline> RenderPipeline::CreateUninitialized(
    Device* device,
    const UnpackedPtr<RenderPipelineDescriptor>& descriptor) {
    return AcquireRef(new RenderPipeline(device, descriptor));
}

MaybeError RenderPipeline::InitializeImpl() {
    // Gather list of internal immediates used by this pipeline
    if ((NeedsPixelCenterPolyfill() || UsesFragDepth()) && !HasUnclippedDepth()) {
        mImmediateMask |= GetImmediateBlockBits(offsetof(RenderImmediates, clampFragDepth),
                                                sizeof(ClampFragDepthArgs));
    }

    if (GetDevice()->NeedsStaticSamplerForExternalTexture() && GetLayout()->HasExternalTextures()) {
        DAWN_ASSERT(!GetLayout()->HasAPIStaticSamplers());
        mRequiresSpecialization = true;
    }

    // The cache key is only used for storing VkPipelineCache objects in BlobStore. That's not
    // done with the monolithic pipeline cache so it's unnecessary work and memory usage.
    bool buildCacheKey =
        !GetDevice()->GetTogglesState().IsEnabled(Toggle::VulkanMonolithicPipelineCache);

    Specialization specialization = {.layout = {
                                         .pushConstantBytes = ToPushConstantBytes(mImmediateMask),
                                     }};
    if (UsesFramebufferFetch()) {
        specialization.layout.framebufferFetchAttachmentCount =
            AttachmentCount(GetColorAttachmentsMask());
    }

    SpecializationResult r;
    DAWN_TRY_ASSIGN(r, InitializeSpecialization(specialization, buildCacheKey));
    mHandles = {.pipeline = r.pipeline->Get(), .layout = r.layout->Get()};

    mSpecializations->emplace(std::move(specialization), std::move(r));

    return {};
}

ResultOrError<PipelineHandles> RenderPipeline::GetOrCreateSpecializedHandle(
    Specialization&& specializationIn) {
    Specialization specialization = specializationIn;
    specialization.layout.pushConstantBytes = ToPushConstantBytes(mImmediateMask);
    if (UsesFramebufferFetch()) {
        specialization.layout.framebufferFetchAttachmentCount =
            AttachmentCount(GetColorAttachmentsMask());
    }

    if (auto specialized =
            mSpecializations.ConstUse([&](auto specializations) -> std::optional<PipelineHandles> {
                if (auto it = specializations->find(specialization); it != specializations->end()) {
                    return PipelineHandles{.pipeline = it->second.pipeline->Get(),
                                           .layout = it->second.layout->Get()};
                }
                return std::nullopt;
            });
        specialized) {
        return *specialized;
    }

    // Do no make a new cache key, so that the VkPipelineCache from InitializeImpl is used for all
    // specializations.
    SpecializationResult r;
    DAWN_TRY_ASSIGN(r, InitializeSpecialization(specialization, /*buildCacheKey=*/false));

    return mSpecializations.Use([&](auto specializations) -> ResultOrError<PipelineHandles> {
        auto handles = PipelineHandles{.pipeline = r.pipeline->Get(), .layout = r.layout->Get()};

        auto [it, inserted] = specializations->insert({specialization, r});
        if (!inserted) {
            return PipelineHandles{.pipeline = it->second.pipeline->Get(),
                                   .layout = it->second.layout->Get()};
        }
        return handles;
    });
}

ResultOrError<RenderPipeline::SpecializationResult> RenderPipeline::InitializeSpecialization(
    const Specialization& specialization,
    bool buildCacheKey) {
    Device* device = ToBackend(GetDevice());
    PipelineLayout* layout = ToBackend(GetLayout());

    if (buildCacheKey) {
        // Vulkan devices need cache UUID field to be serialized into pipeline cache keys.
        StreamIn(&mCacheKey, device->GetDeviceInfo().properties.pipelineCacheUUID);
    }

    SpecializationResult result;
    DAWN_TRY_ASSIGN(result.layout,
                    layout->GetOrCreateVkLayoutObject(std::move(specialization.layout)));

    // There are at most 2 shader stages in render pipeline, i.e. vertex and fragment
    std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages;
    uint32_t stageCount = 0;

    auto AddShaderStage = [&](const ShaderModule::CompileParameters& compileParams) -> MaybeError {
        ShaderModule::ModuleAndSpirv moduleAndSpirv;
        DAWN_TRY_ASSIGN(moduleAndSpirv,
                        ToBackend(compileParams.stage->module)->GetHandleAndSpirv(compileParams));
        mHasInputAttachment = mHasInputAttachment || moduleAndSpirv.hasInputAttachment;
        if (buildCacheKey) {
            // Record cache key for each shader since it will become inaccessible later on.
            StreamIn(&mCacheKey, moduleAndSpirv.spirv);
        }

        VkPipelineShaderStageCreateInfo* shaderStage = &shaderStages[stageCount];
        shaderStage->module = moduleAndSpirv.module;
        shaderStage->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
        shaderStage->pNext = nullptr;
        shaderStage->flags = 0;
        shaderStage->pSpecializationInfo = nullptr;
        shaderStage->stage = VulkanShaderStage(compileParams.stage->metadata->stage);
        // string_view returned by GetIsolatedEntryPointName() points to a null-terminated string.
        shaderStage->pName = device->GetIsolatedEntryPointName().data();

        if (device->GetDeviceInfo().HasExt(DeviceExt::SubgroupSizeControl) &&
            shaderStage->stage == VK_SHADER_STAGE_FRAGMENT_BIT) {
            // This is required to ensure SubgroupSize is reported as the actual size of the
            // subgroups (even if some invocations may be disabled). This becomes unnecessary with
            // SPIR-V 1.6.
            shaderStage->flags |= VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT;
        }

        stageCount++;
        return {};
    };

    std::optional<uint32_t> pixelCenterPolyfillLocation = std::nullopt;
    if (NeedsPixelCenterPolyfill()) {
        const EntryPointMetadata* vtx = GetStage(SingleShaderStage::Vertex).metadata;
        for (size_t i = 0; i < vtx->usedInterStageVariables.size(); ++i) {
            if (vtx->usedInterStageVariables[i] == false) {
                pixelCenterPolyfillLocation = uint32_t(i);
                break;
            }
        }
        if (!pixelCenterPolyfillLocation.has_value()) {
            return DAWN_INTERNAL_ERROR(
                "unable to find a free vertex location for the pixel center polyfill");
        }

        if (HasStage(SingleShaderStage::Fragment)) {
            const EntryPointMetadata* frag = GetStage(SingleShaderStage::Fragment).metadata;
            // Because the fragment stage must be a subset of the vertex stage, if the value was
            // free in the vertex stage it _must_ be free in the fragment stage.
            DAWN_ASSERT(frag->usedInterStageVariables[pixelCenterPolyfillLocation.value()] ==
                        false);
        }
    }

    // Add the vertex stage that's always present.
    DAWN_TRY(AddShaderStage({
        .stage = &GetStage(SingleShaderStage::Vertex),
        .layout = layout,
        .immediateMask = GetImmediateMask(),
        .ycbcrExternalTextures = &specialization.ycbcrExternalTextures,
        .polyfillPixelCenter = pixelCenterPolyfillLocation,
        .emitPointSize = GetPrimitiveTopology() == wgpu::PrimitiveTopology::PointList,
        .pipelineUsesFramebufferFetch = UsesFramebufferFetch(),
    }));

    // Add the fragment stage if present.
    if (GetStageMask() & wgpu::ShaderStage::Fragment) {
        DAWN_TRY(AddShaderStage({
            .stage = &GetStage(SingleShaderStage::Fragment),
            .layout = layout,
            .immediateMask = GetImmediateMask(),
            .ycbcrExternalTextures = &specialization.ycbcrExternalTextures,
            .polyfillPixelCenter = pixelCenterPolyfillLocation,
            .pipelineUsesFramebufferFetch = UsesFramebufferFetch(),
            .needsMultisampledFramebufferFetch = UseSampleRateShading() && UsesFramebufferFetch(),
        }));
    }

    PipelineVertexInputStateCreateInfoTemporaryAllocations tempAllocations{};
    VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo =
        ComputeVertexInputDesc(&tempAllocations);

    VkPipelineInputAssemblyStateCreateInfo inputAssembly;
    inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
    inputAssembly.pNext = nullptr;
    inputAssembly.flags = 0;
    inputAssembly.topology = VulkanPrimitiveTopology(GetPrimitiveTopology());
    inputAssembly.primitiveRestartEnable =
        ShouldEnablePrimitiveRestart(GetPrimitiveTopology()) ? VK_TRUE : VK_FALSE;

    // A placeholder viewport/scissor info. The validation layers force us to provide at least
    // one scissor and one viewport here, even if we choose to make them dynamic.
    VkViewport viewportDesc;
    viewportDesc.x = 0.0f;
    viewportDesc.y = 0.0f;
    viewportDesc.width = 1.0f;
    viewportDesc.height = 1.0f;
    viewportDesc.minDepth = 0.0f;
    viewportDesc.maxDepth = 1.0f;
    VkRect2D scissorRect;
    scissorRect.offset.x = 0;
    scissorRect.offset.y = 0;
    scissorRect.extent.width = 1;
    scissorRect.extent.height = 1;
    VkPipelineViewportStateCreateInfo viewport;
    viewport.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
    viewport.pNext = nullptr;
    viewport.flags = 0;
    viewport.viewportCount = 1;
    viewport.pViewports = &viewportDesc;
    viewport.scissorCount = 1;
    viewport.pScissors = &scissorRect;

    VkPipelineRasterizationStateCreateInfo rasterization;
    rasterization.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    rasterization.pNext = nullptr;
    rasterization.flags = 0;
    rasterization.depthClampEnable = HasUnclippedDepth() ? VK_TRUE : VK_FALSE;
    rasterization.rasterizerDiscardEnable = VK_FALSE;
    rasterization.polygonMode = VK_POLYGON_MODE_FILL;
    rasterization.cullMode = VulkanCullMode(GetCullMode());
    rasterization.frontFace = VulkanFrontFace(GetFrontFace());
    rasterization.depthBiasEnable = IsDepthBiasEnabled() ? VK_TRUE : VK_FALSE;
    rasterization.depthBiasConstantFactor = GetDepthBias();
    rasterization.depthBiasClamp = GetDepthBiasClamp();
    rasterization.depthBiasSlopeFactor = GetDepthBiasSlopeScale();
    rasterization.lineWidth = 1.0f;

    VkPipelineMultisampleStateCreateInfo multisample;
    multisample.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
    multisample.pNext = nullptr;
    multisample.flags = 0;
    multisample.rasterizationSamples = VulkanSampleCount(GetSampleCount());
    multisample.sampleShadingEnable = UsesFramebufferFetch() ? VK_TRUE : VK_FALSE;
    multisample.minSampleShading = 1.0f;
    // VkPipelineMultisampleStateCreateInfo.pSampleMask is an array of length
    // ceil(rasterizationSamples / 32) and since we're passing a single uint32_t
    // we have to assert that this length is indeed 1.
    DAWN_ASSERT(multisample.rasterizationSamples <= 32);
    VkSampleMask sampleMask = GetSampleMask();
    multisample.pSampleMask = &sampleMask;
    multisample.alphaToCoverageEnable = IsAlphaToCoverageEnabled() ? VK_TRUE : VK_FALSE;
    multisample.alphaToOneEnable = VK_FALSE;

    VkPipelineDepthStencilStateCreateInfo depthStencilState = ComputeDepthStencilDesc();

    VkPipelineColorBlendStateCreateInfo colorBlend;
    // colorBlend may hold pointers to elements in colorBlendAttachments, so it must have a
    // definition scope as same as colorBlend
    PerColorAttachment<VkPipelineColorBlendAttachmentState> colorBlendAttachments;
    if (GetStageMask() & wgpu::ShaderStage::Fragment) {
        // Initialize the "blend state info" that will be chained in the "create info" from the
        // data pre-computed in the ColorState
        for (auto& blend : colorBlendAttachments) {
            blend.blendEnable = VK_FALSE;
            blend.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
            blend.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
            blend.colorBlendOp = VK_BLEND_OP_ADD;
            blend.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
            blend.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
            blend.alphaBlendOp = VK_BLEND_OP_ADD;
            blend.colorWriteMask = 0;
        }

        const auto& fragmentOutputMask =
            GetStage(SingleShaderStage::Fragment).metadata->fragmentOutputMask;
        auto highestColorAttachmentIndexPlusOne =
            GetHighestBitIndexPlusOne(GetColorAttachmentsMask());
        for (auto i : GetColorAttachmentsMask()) {
            const ColorTargetState* target = GetColorTargetState(i);
            colorBlendAttachments[i] = ComputeColorDesc(target, fragmentOutputMask[i]);
        }

        colorBlend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
        colorBlend.pNext = nullptr;
        colorBlend.flags = 0;

        if (GetStage(SingleShaderStage::Fragment).metadata->fragmentInputMask.any()) {
            colorBlend.flags |=
                VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT;
        }

        // LogicOp isn't supported so we disable it.
        colorBlend.logicOpEnable = VK_FALSE;
        colorBlend.logicOp = VK_LOGIC_OP_CLEAR;
        colorBlend.attachmentCount = static_cast<uint8_t>(highestColorAttachmentIndexPlusOne);
        colorBlend.pAttachments = colorBlendAttachments.data();
        // The blend constant is always dynamic so we fill in a placeholder value
        colorBlend.blendConstants[0] = 0.0f;
        colorBlend.blendConstants[1] = 0.0f;
        colorBlend.blendConstants[2] = 0.0f;
        colorBlend.blendConstants[3] = 0.0f;
    }

    // Tag all state as dynamic but stencil masks and depth bias.
    const uint32_t kMaxDynamicStates = 14;
    absl::InlinedVector<VkDynamicState, kMaxDynamicStates> dynamicStates = {
        VK_DYNAMIC_STATE_VIEWPORT,     VK_DYNAMIC_STATE_SCISSOR,
        VK_DYNAMIC_STATE_LINE_WIDTH,   VK_DYNAMIC_STATE_BLEND_CONSTANTS,
        VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_REFERENCE,
    };

    // If ExtendedDynamicState is available tag several other states as dynamic.
    // The states will be ignored by CreateGraphicsPipelines, but they are reset to a constant value
    // here (0 where possible) to ensure the Vulkan cache key is compatible between pipelines.
    if (device->IsToggleEnabled(Toggle::VulkanUseExtendedDynamicState)) {
        dynamicStates.push_back(VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT);
        mDynamicState.primitiveTopology = inputAssembly.topology;
        // TODO(463893795): Look into using dynamicPrimitiveTopologyUnrestricted from
        // VK_EXT_extended_dynamic_state3 to remove the requirement that this needs to be set to the
        // same topology class (point/line/triangle) as the dynamic state it will be used with.
        inputAssembly.topology = GetTopologyClass(inputAssembly.topology);

        dynamicStates.push_back(VK_DYNAMIC_STATE_CULL_MODE_EXT);
        mDynamicState.cullMode = rasterization.cullMode;
        rasterization.cullMode = VK_CULL_MODE_NONE;

        dynamicStates.push_back(VK_DYNAMIC_STATE_FRONT_FACE_EXT);
        mDynamicState.frontFace = rasterization.frontFace;
        rasterization.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;

        dynamicStates.push_back(VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT);
        mDynamicState.depthTestEnable = depthStencilState.depthTestEnable;
        depthStencilState.depthTestEnable = VK_FALSE;

        dynamicStates.push_back(VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT);
        mDynamicState.depthWriteEnable = depthStencilState.depthWriteEnable;
        depthStencilState.depthWriteEnable = VK_FALSE;

        dynamicStates.push_back(VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT);
        mDynamicState.depthCompareOp = depthStencilState.depthCompareOp;
        depthStencilState.depthCompareOp = VK_COMPARE_OP_NEVER;

        dynamicStates.push_back(VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT);
        mDynamicState.stencilTestEnable = depthStencilState.stencilTestEnable;
        depthStencilState.stencilTestEnable = VK_FALSE;

        dynamicStates.push_back(VK_DYNAMIC_STATE_STENCIL_OP_EXT);
        mDynamicState.packedFrontStencil =
            PackStencilOpState(depthStencilState.front, depthStencilState.stencilTestEnable);
        depthStencilState.front.failOp = VK_STENCIL_OP_KEEP;
        depthStencilState.front.passOp = VK_STENCIL_OP_KEEP;
        depthStencilState.front.depthFailOp = VK_STENCIL_OP_KEEP;
        depthStencilState.front.compareOp = VK_COMPARE_OP_NEVER;

        mDynamicState.packedBackStencil =
            PackStencilOpState(depthStencilState.back, depthStencilState.stencilTestEnable);
        depthStencilState.back.failOp = VK_STENCIL_OP_KEEP;
        depthStencilState.back.passOp = VK_STENCIL_OP_KEEP;
        depthStencilState.back.depthFailOp = VK_STENCIL_OP_KEEP;
        depthStencilState.back.compareOp = VK_COMPARE_OP_NEVER;
    }

    VkPipelineDynamicStateCreateInfo dynamic;
    dynamic.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
    dynamic.pNext = nullptr;
    dynamic.flags = 0;
    dynamic.dynamicStateCount = dynamicStates.size();
    dynamic.pDynamicStates = dynamicStates.data();

    // The create info chains in a bunch of things created on the stack here or inside state
    // objects.
    VkGraphicsPipelineCreateInfo createInfo;
    createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
    createInfo.pNext = nullptr;
    createInfo.flags = 0;
    createInfo.stageCount = stageCount;
    createInfo.pStages = shaderStages.data();
    createInfo.pVertexInputState = &vertexInputCreateInfo;
    createInfo.pInputAssemblyState = &inputAssembly;
    createInfo.pTessellationState = nullptr;
    createInfo.pViewportState = &viewport;
    createInfo.pRasterizationState = &rasterization;
    createInfo.pMultisampleState = &multisample;
    createInfo.pDepthStencilState = &depthStencilState;
    createInfo.pColorBlendState =
        (GetStageMask() & wgpu::ShaderStage::Fragment) ? &colorBlend : nullptr;
    createInfo.pDynamicState = &dynamic;
    createInfo.layout = result.layout->Get();
    createInfo.basePipelineHandle = VkPipeline{};
    createInfo.basePipelineIndex = -1;
    PNextChainBuilder createInfoChain(&createInfo);

    RenderPassCache::RenderPassInfo renderPassInfo;
    VkPipelineRenderingCreateInfoKHR pipelineRenderingCreateInfo;
    PerColorAttachment<VkFormat> colorAttachmentFormats;

    if (device->GetRenderPassType() == VulkanRenderPassType::DynamicRendering) {
        // Dynamic rendering doesn't need a VkRenderPass object, just a description of the
        // attachments formats that will be used with this pipeline.
        VkRenderPass nullRenderPass = VK_NULL_HANDLE;
        createInfo.renderPass = nullRenderPass;

        createInfoChain.Add(&pipelineRenderingCreateInfo,
                            VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR);

        pipelineRenderingCreateInfo.viewMask = 0;
        pipelineRenderingCreateInfo.colorAttachmentCount = 0;
        pipelineRenderingCreateInfo.depthAttachmentFormat = VK_FORMAT_UNDEFINED;
        pipelineRenderingCreateInfo.stencilAttachmentFormat = VK_FORMAT_UNDEFINED;

        // Initialize all potential color attachment formats to undefined, which allows the
        // attachments to be sparse.
        colorAttachmentFormats.fill(VK_FORMAT_UNDEFINED);

        // Set the formats of the color attachments in use.
        ColorAttachmentMask attachmentMask = GetColorAttachmentsMask();
        for (auto i : attachmentMask) {
            colorAttachmentFormats[i] = VulkanImageFormat(device, GetColorAttachmentFormat(i));
        }

        pipelineRenderingCreateInfo.colorAttachmentCount =
            static_cast<uint32_t>(GetHighestBitIndexPlusOne(attachmentMask));
        pipelineRenderingCreateInfo.pColorAttachmentFormats = colorAttachmentFormats.data();

        // Set the formats of the depth/stencil attachment.
        if (HasDepthStencilAttachment()) {
            wgpu::TextureFormat dsFormat = GetDepthStencilFormat();
            const Format& internalFormat = device->GetValidInternalFormat(dsFormat);
            VkFormat vkDsFormat = VulkanImageFormat(device, dsFormat);

            if (internalFormat.HasDepth()) {
                pipelineRenderingCreateInfo.depthAttachmentFormat = vkDsFormat;
            }
            if (internalFormat.HasStencil()) {
                pipelineRenderingCreateInfo.stencilAttachmentFormat = vkDsFormat;
            }
        }
    } else {
        // Get a VkRenderPass that matches the attachment formats for this pipeline.
        // VkRenderPass compatibility rules let us provide placeholder data for a bunch of
        // arguments. Load and store ops are all equivalent, though we still specify
        // ExpandResolveTexture as that controls the use of input attachments. Single subpass
        // VkRenderPasses are compatible irrespective of resolve attachments being used, but for
        // ExpandResolveTexture that uses two subpasses we need to specify which attachments will
        // be resolved.
        RenderPassCacheQuery query;
        ColorAttachmentMask resolveMask =
            GetAttachmentState()->GetExpandResolveInfo().resolveTargetsMask;
        ColorAttachmentMask expandResolveMask =
            GetAttachmentState()->GetExpandResolveInfo().attachmentsToExpandResolve;

        for (auto i : GetColorAttachmentsMask()) {
            wgpu::LoadOp colorLoadOp = wgpu::LoadOp::Load;
            bool hasResolveTarget = resolveMask.test(i);

            if (expandResolveMask.test(i)) {
                // ExpandResolveTexture will use 2 subpasses in a render pass so we have to create
                // an appropriate query.
                colorLoadOp = wgpu::LoadOp::ExpandResolveTexture;
            }
            // This bool should match the value used in the final RenderPass, but we don't have the
            // appropriate MSRTSS values exposed here. Issue can be safely ignored, though.
            // See comments on skipped message VUID-vkCmdDraw-renderPass-02684 in BackendVk.cpp.
            bool renderToSingleSample = false;
            query.SetColor(i, GetColorAttachmentFormat(i), colorLoadOp, wgpu::StoreOp::Store,
                           hasResolveTarget, renderToSingleSample);
        }

        if (HasDepthStencilAttachment()) {
            query.SetDepthStencil(GetDepthStencilFormat(), wgpu::LoadOp::Load, wgpu::StoreOp::Store,
                                  false, wgpu::LoadOp::Load, wgpu::StoreOp::Store, false);
        }

        query.SetSampleCount(GetSampleCount());

        if (buildCacheKey) {
            StreamIn(&mCacheKey, query);
        }
        DAWN_TRY_ASSIGN(renderPassInfo, device->GetRenderPassCache()->GetRenderPass(query));

        createInfo.renderPass = renderPassInfo.renderPass;
    }

    // - If the pipeline uses input attachments in shader, currently this is only used by
    //   ExpandResolveTexture subpass, hence we need to set the subpass to 0.
    // - Otherwise, the pipeline will operate on the main subpass.
    // - TODO(42240662): Add explicit way to specify subpass instead of implicitly deducing based on
    // mHasInputAttachment.
    //   That also means mHasInputAttachment would be removed in future.
    createInfo.subpass = mHasInputAttachment ? 0 : renderPassInfo.mainSubpass;

    // If possible, specify where exactly robustness should be added in the pipeline. This is
    // necessary because when bindless is enabled and robustBufferAccessUpdateAfterBind is false, we
    // must only set robust buffer access on vertexInputs.
    VkPipelineRobustnessCreateInfo robustnessCreateInfo;
    if (device->GetDeviceInfo().HasExt(DeviceExt::PipelineRobustness)) {
        createInfoChain.Add(&robustnessCreateInfo,
                            VK_STRUCTURE_TYPE_PIPELINE_ROBUSTNESS_CREATE_INFO);

        // Without any specific toggle only vertex inputs can be made robust enough for WebGPU.
        robustnessCreateInfo.vertexInputs =
            VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS;
        robustnessCreateInfo.uniformBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED;
        robustnessCreateInfo.storageBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED;
        robustnessCreateInfo.images = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED;

        if (device->IsToggleEnabled(Toggle::VulkanUseBufferRobustAccess2)) {
            // Uniform buffers are checked with WebGPU validation and don't need robustness.
            robustnessCreateInfo.storageBuffers =
                VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2;
        }
        if (device->IsToggleEnabled(Toggle::VulkanUseImageRobustAccess2)) {
            robustnessCreateInfo.images =
                VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2;
        }
    }

    // Record cache key information now since createInfo is not stored. Only store for the noop
    // specialization created in InitializeImpl so that future specializations use the same pipeline
    // cache, and may reuse the VkPipeline when they happen to be the same on the driver side.
    if (buildCacheKey) {
        StreamIn(&mCacheKey, createInfo, layout->GetCacheKey());
    }

    // Try to see if we have anything in the blob cache.
    platform::metrics::DawnHistogramTimer cacheTimer(GetDevice()->GetPlatform());
    Ref<PipelineCache> cache = ToBackend(GetDevice()->GetOrCreatePipelineCache(GetCacheKey()));
    VkPipeline pipeline;
    DAWN_TRY(
        CheckVkSuccess(device->fn.CreateGraphicsPipelines(device->GetVkDevice(), cache->GetHandle(),
                                                          1, &createInfo, nullptr, &*pipeline),
                       "CreateGraphicsPipelines"));
    result.pipeline = AcquireRef(new RefCountedVkHandle<VkPipeline>(device, pipeline));
    cacheTimer.RecordMicroseconds(cache->CacheHit() ? "Vulkan.CreateGraphicsPipelines.CacheHit"
                                                    : "Vulkan.CreateGraphicsPipelines.CacheMiss");

    DAWN_TRY(cache->DidCompilePipeline());

    SetLabelImpl();

    for (uint32_t i = 0; i < stageCount; ++i) {
        device->fn.DestroyShaderModule(device->GetVkDevice(), shaderStages[i].module, nullptr);
    }

    return result;
}

#define SetDynamicState(function, state)                       \
    if (!prevState || prevState->state != mDynamicState.state) \
    device->fn.function(commands, mDynamicState.state)

void RenderPipeline::ApplyDynamicState(VkCommandBuffer& commands,
                                       const RenderPipeline* prevPipeline) const {
    Device* device = ToBackend(GetDevice());

    // If Dynamic state is enabled, apply state changes between this pipeline and the previous one.
    if (device->IsToggleEnabled(Toggle::VulkanUseExtendedDynamicState)) {
        const RenderPipeline::DynamicState* prevState = nullptr;
        if (prevPipeline) {
            prevState = &prevPipeline->mDynamicState;
        }

        SetDynamicState(CmdSetPrimitiveTopologyEXT, primitiveTopology);
        SetDynamicState(CmdSetCullModeEXT, cullMode);
        SetDynamicState(CmdSetFrontFaceEXT, frontFace);
        SetDynamicState(CmdSetDepthTestEnableEXT, depthTestEnable);
        SetDynamicState(CmdSetDepthWriteEnableEXT, depthWriteEnable);
        SetDynamicState(CmdSetDepthCompareOpEXT, depthCompareOp);
        SetDynamicState(CmdSetStencilTestEnableEXT, stencilTestEnable);

        if (mDynamicState.stencilTestEnable) {
            if (!prevState || prevState->packedFrontStencil != mDynamicState.packedFrontStencil) {
                VkStencilOpState stencilOp = UnpackStencilOpState(mDynamicState.packedFrontStencil);
                device->fn.CmdSetStencilOpEXT(commands, VK_STENCIL_FACE_FRONT_BIT, stencilOp.failOp,
                                              stencilOp.passOp, stencilOp.depthFailOp,
                                              stencilOp.compareOp);
            }

            if (!prevState || prevState->packedBackStencil != mDynamicState.packedBackStencil) {
                VkStencilOpState stencilOp = UnpackStencilOpState(mDynamicState.packedBackStencil);
                device->fn.CmdSetStencilOpEXT(commands, VK_STENCIL_FACE_BACK_BIT, stencilOp.failOp,
                                              stencilOp.passOp, stencilOp.depthFailOp,
                                              stencilOp.compareOp);
            }
        }
    }
}

#undef SetDynamicState

void RenderPipeline::SetLabelImpl() {
    SetDebugName(ToBackend(GetDevice()), mHandles.pipeline, "Dawn_RenderPipeline", GetLabel());
}

VkPipelineVertexInputStateCreateInfo RenderPipeline::ComputeVertexInputDesc(
    PipelineVertexInputStateCreateInfoTemporaryAllocations* tempAllocations) {
    // Fill in the "binding info" that will be chained in the create info
    uint32_t bindingCount = 0;
    for (VertexBufferSlot slot : GetVertexBuffersUsed()) {
        const VertexBufferInfo& bindingInfo = GetVertexBuffer(slot);

        VkVertexInputBindingDescription* bindingDesc = &tempAllocations->bindings[bindingCount];
        bindingDesc->binding = static_cast<uint8_t>(slot);
        bindingDesc->stride = bindingInfo.arrayStride;
        bindingDesc->inputRate = VulkanInputRate(bindingInfo.stepMode);

        bindingCount++;
    }

    // Fill in the "attribute info" that will be chained in the create info
    uint32_t attributeCount = 0;
    for (VertexAttributeLocation loc : GetAttributeLocationsUsed()) {
        const VertexAttributeInfo& attributeInfo = GetAttribute(loc);

        VkVertexInputAttributeDescription* attributeDesc =
            &tempAllocations->attributes[attributeCount];
        attributeDesc->location = static_cast<uint8_t>(loc);
        attributeDesc->binding = static_cast<uint8_t>(attributeInfo.vertexBufferSlot);
        attributeDesc->format = VulkanVertexFormat(attributeInfo.format);
        attributeDesc->offset = attributeInfo.offset;

        attributeCount++;
    }

    // Build the create info
    VkPipelineVertexInputStateCreateInfo createInfo;
    createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
    createInfo.pNext = nullptr;
    createInfo.flags = 0;
    createInfo.vertexBindingDescriptionCount = bindingCount;
    createInfo.pVertexBindingDescriptions = tempAllocations->bindings.data();
    createInfo.vertexAttributeDescriptionCount = attributeCount;
    createInfo.pVertexAttributeDescriptions = tempAllocations->attributes.data();
    return createInfo;
}

VkPipelineDepthStencilStateCreateInfo RenderPipeline::ComputeDepthStencilDesc() {
    const DepthStencilState* descriptor = GetDepthStencilState();

    VkPipelineDepthStencilStateCreateInfo depthStencilState;
    depthStencilState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
    depthStencilState.pNext = nullptr;
    depthStencilState.flags = 0;

    // Depth writes only occur if depth is enabled
    depthStencilState.depthTestEnable =
        (descriptor->depthCompare == wgpu::CompareFunction::Always &&
         descriptor->depthWriteEnabled != wgpu::OptionalBool::True)
            ? VK_FALSE
            : VK_TRUE;
    depthStencilState.depthWriteEnable =
        descriptor->depthWriteEnabled == wgpu::OptionalBool::True ? VK_TRUE : VK_FALSE;
    depthStencilState.depthCompareOp = ToVulkanCompareOp(descriptor->depthCompare);
    depthStencilState.depthBoundsTestEnable = VK_FALSE;
    depthStencilState.minDepthBounds = 0.0f;
    depthStencilState.maxDepthBounds = 1.0f;

    depthStencilState.stencilTestEnable = UsesStencil() ? VK_TRUE : VK_FALSE;

    depthStencilState.front.failOp = VulkanStencilOp(descriptor->stencilFront.failOp);
    depthStencilState.front.passOp = VulkanStencilOp(descriptor->stencilFront.passOp);
    depthStencilState.front.depthFailOp = VulkanStencilOp(descriptor->stencilFront.depthFailOp);
    depthStencilState.front.compareOp = ToVulkanCompareOp(descriptor->stencilFront.compare);

    depthStencilState.back.failOp = VulkanStencilOp(descriptor->stencilBack.failOp);
    depthStencilState.back.passOp = VulkanStencilOp(descriptor->stencilBack.passOp);
    depthStencilState.back.depthFailOp = VulkanStencilOp(descriptor->stencilBack.depthFailOp);
    depthStencilState.back.compareOp = ToVulkanCompareOp(descriptor->stencilBack.compare);

    // Dawn doesn't have separate front and back stencil masks.
    depthStencilState.front.compareMask = descriptor->stencilReadMask;
    depthStencilState.back.compareMask = descriptor->stencilReadMask;
    depthStencilState.front.writeMask = descriptor->stencilWriteMask;
    depthStencilState.back.writeMask = descriptor->stencilWriteMask;

    // The stencil reference is always dynamic
    depthStencilState.front.reference = 0;
    depthStencilState.back.reference = 0;

    return depthStencilState;
}

RenderPipeline::~RenderPipeline() = default;

void RenderPipeline::DestroyImpl(DestroyReason reason) {
    RenderPipelineBase::DestroyImpl(reason);

    mSpecializations->clear();

    // Handles were owned by refs in mSpecializations that were just deleted.
    mHandles = {};
}

bool RenderPipeline::NeedsPixelCenterPolyfill() const {
    return UseSampleRateShading() && UsesFragPosition();
}

bool RenderPipeline::RequiresSpecialization() const {
    return mRequiresSpecialization;
}

VkPipeline RenderPipeline::GetHandle() const {
    DAWN_ASSERT(mHandles.pipeline != VK_NULL_HANDLE);
    return mHandles.pipeline;
}

VkPipelineLayout RenderPipeline::GetVkLayout() const {
    DAWN_ASSERT(mHandles.layout != nullptr);
    return mHandles.layout;
}

}  // namespace dawn::native::vulkan
