// Copyright 2017 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 "dawn/native/RenderPipeline.h"

#include <algorithm>
#include <cmath>

#include "dawn/common/BitSetIterator.h"
#include "dawn/common/Enumerator.h"
#include "dawn/common/ityp_span.h"
#include "dawn/native/ChainUtils.h"
#include "dawn/native/CommandValidation.h"
#include "dawn/native/Commands.h"
#include "dawn/native/Device.h"
#include "dawn/native/InternalPipelineStore.h"
#include "dawn/native/ObjectContentHasher.h"
#include "dawn/native/ObjectType_autogen.h"
#include "dawn/native/ValidationUtils_autogen.h"

namespace dawn::native {

static constexpr std::array<VertexFormatInfo, 32> sVertexFormatTable = {{
    //
    {wgpu::VertexFormat::Undefined, 0, 0, VertexFormatBaseType::Float},

    {wgpu::VertexFormat::Uint8x2, 2, 2, VertexFormatBaseType::Uint},
    {wgpu::VertexFormat::Uint8x4, 4, 4, VertexFormatBaseType::Uint},
    {wgpu::VertexFormat::Sint8x2, 2, 2, VertexFormatBaseType::Sint},
    {wgpu::VertexFormat::Sint8x4, 4, 4, VertexFormatBaseType::Sint},
    {wgpu::VertexFormat::Unorm8x2, 2, 2, VertexFormatBaseType::Float},
    {wgpu::VertexFormat::Unorm8x4, 4, 4, VertexFormatBaseType::Float},
    {wgpu::VertexFormat::Snorm8x2, 2, 2, VertexFormatBaseType::Float},
    {wgpu::VertexFormat::Snorm8x4, 4, 4, VertexFormatBaseType::Float},

    {wgpu::VertexFormat::Uint16x2, 4, 2, VertexFormatBaseType::Uint},
    {wgpu::VertexFormat::Uint16x4, 8, 4, VertexFormatBaseType::Uint},
    {wgpu::VertexFormat::Sint16x2, 4, 2, VertexFormatBaseType::Sint},
    {wgpu::VertexFormat::Sint16x4, 8, 4, VertexFormatBaseType::Sint},
    {wgpu::VertexFormat::Unorm16x2, 4, 2, VertexFormatBaseType::Float},
    {wgpu::VertexFormat::Unorm16x4, 8, 4, VertexFormatBaseType::Float},
    {wgpu::VertexFormat::Snorm16x2, 4, 2, VertexFormatBaseType::Float},
    {wgpu::VertexFormat::Snorm16x4, 8, 4, VertexFormatBaseType::Float},
    {wgpu::VertexFormat::Float16x2, 4, 2, VertexFormatBaseType::Float},
    {wgpu::VertexFormat::Float16x4, 8, 4, VertexFormatBaseType::Float},

    {wgpu::VertexFormat::Float32, 4, 1, VertexFormatBaseType::Float},
    {wgpu::VertexFormat::Float32x2, 8, 2, VertexFormatBaseType::Float},
    {wgpu::VertexFormat::Float32x3, 12, 3, VertexFormatBaseType::Float},
    {wgpu::VertexFormat::Float32x4, 16, 4, VertexFormatBaseType::Float},
    {wgpu::VertexFormat::Uint32, 4, 1, VertexFormatBaseType::Uint},
    {wgpu::VertexFormat::Uint32x2, 8, 2, VertexFormatBaseType::Uint},
    {wgpu::VertexFormat::Uint32x3, 12, 3, VertexFormatBaseType::Uint},
    {wgpu::VertexFormat::Uint32x4, 16, 4, VertexFormatBaseType::Uint},
    {wgpu::VertexFormat::Sint32, 4, 1, VertexFormatBaseType::Sint},
    {wgpu::VertexFormat::Sint32x2, 8, 2, VertexFormatBaseType::Sint},
    {wgpu::VertexFormat::Sint32x3, 12, 3, VertexFormatBaseType::Sint},
    {wgpu::VertexFormat::Sint32x4, 16, 4, VertexFormatBaseType::Sint},
    {wgpu::VertexFormat::Unorm10_10_10_2, 4, 4, VertexFormatBaseType::Float},
    //
}};

const VertexFormatInfo& GetVertexFormatInfo(wgpu::VertexFormat format) {
    DAWN_ASSERT(format != wgpu::VertexFormat::Undefined);
    DAWN_ASSERT(static_cast<uint32_t>(format) < sVertexFormatTable.size());
    DAWN_ASSERT(sVertexFormatTable[static_cast<uint32_t>(format)].format == format);
    return sVertexFormatTable[static_cast<uint32_t>(format)];
}

// Helper functions
namespace {
MaybeError ValidateVertexAttribute(DeviceBase* device,
                                   const VertexAttribute* attribute,
                                   const EntryPointMetadata& metadata,
                                   uint64_t vertexBufferStride,
                                   VertexAttributeMask* attributesSetMask) {
    DAWN_TRY(ValidateVertexFormat(attribute->format));
    const VertexFormatInfo& formatInfo = GetVertexFormatInfo(attribute->format);

    uint32_t maxVertexAttributes = device->GetLimits().v1.maxVertexAttributes;
    DAWN_INVALID_IF(
        attribute->shaderLocation >= maxVertexAttributes,
        "Attribute shader location (%u) exceeds the maximum number of vertex attributes "
        "(%u).",
        attribute->shaderLocation, maxVertexAttributes);

    VertexAttributeLocation location(static_cast<uint8_t>(attribute->shaderLocation));

    // No underflow is possible because the max vertex format size is smaller than
    // kMaxVertexBufferArrayStride.
    DAWN_ASSERT(kMaxVertexBufferArrayStride >= formatInfo.byteSize);
    DAWN_INVALID_IF(
        attribute->offset > kMaxVertexBufferArrayStride - formatInfo.byteSize,
        "Attribute offset (%u) with format %s (size: %u) doesn't fit in the maximum vertex "
        "buffer stride (%u).",
        attribute->offset, attribute->format, formatInfo.byteSize, kMaxVertexBufferArrayStride);

    // No overflow is possible because the offset is already validated to be less
    // than kMaxVertexBufferArrayStride.
    DAWN_ASSERT(attribute->offset < kMaxVertexBufferArrayStride);
    DAWN_INVALID_IF(
        vertexBufferStride > 0 && attribute->offset + formatInfo.byteSize > vertexBufferStride,
        "Attribute offset (%u) with format %s (size: %u) doesn't fit in the vertex buffer "
        "stride (%u).",
        attribute->offset, attribute->format, formatInfo.byteSize, vertexBufferStride);

    DAWN_INVALID_IF(attribute->offset % std::min(4u, formatInfo.byteSize) != 0,
                    "Attribute offset (%u) in not a multiple of %u.", attribute->offset,
                    std::min(4u, formatInfo.byteSize));

    DAWN_INVALID_IF(metadata.usedVertexInputs[location] &&
                        formatInfo.baseType != metadata.vertexInputBaseTypes[location],
                    "Attribute base type (%s) does not match the "
                    "shader's base type (%s) in location (%u).",
                    formatInfo.baseType, metadata.vertexInputBaseTypes[location],
                    attribute->shaderLocation);

    DAWN_INVALID_IF((*attributesSetMask)[location],
                    "Attribute shader location (%u) is used more than once.",
                    attribute->shaderLocation);

    attributesSetMask->set(location);
    return {};
}

MaybeError ValidateVertexBufferLayout(DeviceBase* device,
                                      const VertexBufferLayout* buffer,
                                      const EntryPointMetadata& metadata,
                                      VertexAttributeMask* attributesSetMask) {
    DAWN_TRY(ValidateVertexStepMode(buffer->stepMode));
    DAWN_INVALID_IF(buffer->arrayStride > kMaxVertexBufferArrayStride,
                    "Vertex buffer arrayStride (%u) is larger than the maximum array stride (%u).",
                    buffer->arrayStride, kMaxVertexBufferArrayStride);

    DAWN_INVALID_IF(buffer->arrayStride % 4 != 0,
                    "Vertex buffer arrayStride (%u) is not a multiple of 4.", buffer->arrayStride);

    DAWN_INVALID_IF(
        buffer->stepMode == wgpu::VertexStepMode::VertexBufferNotUsed && buffer->attributeCount > 0,
        "attributeCount (%u) is not zero although vertex buffer stepMode is %s.",
        buffer->attributeCount, wgpu::VertexStepMode::VertexBufferNotUsed);

    for (uint32_t i = 0; i < buffer->attributeCount; ++i) {
        DAWN_TRY_CONTEXT(ValidateVertexAttribute(device, &buffer->attributes[i], metadata,
                                                 buffer->arrayStride, attributesSetMask),
                         "validating attributes[%u].", i);
    }

    return {};
}

ResultOrError<ShaderModuleEntryPoint> ValidateVertexState(
    DeviceBase* device,
    const VertexState* descriptor,
    const PipelineLayoutBase* layout,
    wgpu::PrimitiveTopology primitiveTopology) {
    DAWN_INVALID_IF(descriptor->nextInChain != nullptr, "nextInChain must be nullptr.");

    const CombinedLimits& limits = device->GetLimits();

    DAWN_INVALID_IF(descriptor->bufferCount > limits.v1.maxVertexBuffers,
                    "Vertex buffer count (%u) exceeds the maximum number of vertex buffers (%u).",
                    descriptor->bufferCount, limits.v1.maxVertexBuffers);

    ShaderModuleEntryPoint entryPoint;
    DAWN_TRY_ASSIGN_CONTEXT(
        entryPoint,
        ValidateProgrammableStage(device, descriptor->module, descriptor->entryPoint,
                                  descriptor->constantCount, descriptor->constants, layout,
                                  SingleShaderStage::Vertex),
        "validating vertex stage (%s, entryPoint: %s).", descriptor->module,
        descriptor->entryPoint);
    const EntryPointMetadata& vertexMetadata = descriptor->module->GetEntryPoint(entryPoint.name);
    if (primitiveTopology == wgpu::PrimitiveTopology::PointList) {
        DAWN_INVALID_IF(
            vertexMetadata.totalInterStageShaderComponents + 1 >
                limits.v1.maxInterStageShaderComponents,
            "Total vertex output components count (%u) exceeds the maximum (%u) when primitive "
            "topology is %s as another component is implicitly used for the point size.",
            vertexMetadata.totalInterStageShaderComponents,
            limits.v1.maxInterStageShaderComponents - 1, primitiveTopology);
    }

    VertexAttributeMask attributesSetMask;
    uint32_t totalAttributesNum = 0;
    for (uint32_t i = 0; i < descriptor->bufferCount; ++i) {
        DAWN_TRY_CONTEXT(ValidateVertexBufferLayout(device, &descriptor->buffers[i], vertexMetadata,
                                                    &attributesSetMask),
                         "validating buffers[%u].", i);
        totalAttributesNum += descriptor->buffers[i].attributeCount;
    }

    if (device->IsCompatibilityMode() &&
        (vertexMetadata.usesVertexIndex || vertexMetadata.usesInstanceIndex)) {
        uint32_t totalEffectiveAttributesNum = totalAttributesNum +
                                               (vertexMetadata.usesVertexIndex ? 1 : 0) +
                                               (vertexMetadata.usesInstanceIndex ? 1 : 0);
        DAWN_INVALID_IF(totalEffectiveAttributesNum > limits.v1.maxVertexAttributes,
                        "Attribute count (%u) exceeds the maximum number of attributes (%u) as "
                        "@builtin(vertex_index) and @builtin(instance_index) each use an attribute "
                        "in compatibility mode.",
                        totalEffectiveAttributesNum, limits.v1.maxVertexAttributes);
    }

    // Every vertex attribute has a member called shaderLocation, and there are some
    // requirements for shaderLocation: 1) >=0, 2) values are different across different
    // attributes, 3) can't exceed kMaxVertexAttributes. So it can ensure that total
    // attribute number never exceed kMaxVertexAttributes.
    DAWN_ASSERT(totalAttributesNum <= kMaxVertexAttributes);

    // Validate that attributes used by the VertexState are in the shader using bitmask operations
    // but try to be helpful by finding one missing attribute to surface in the error message
    if (!IsSubset(vertexMetadata.usedVertexInputs, attributesSetMask)) {
        const VertexAttributeMask missingAttributes =
            vertexMetadata.usedVertexInputs & ~attributesSetMask;
        DAWN_ASSERT(missingAttributes.any());

        VertexAttributeLocation firstMissing = ityp::Sub(
            GetHighestBitIndexPlusOne(missingAttributes), VertexAttributeLocation(uint8_t(1)));
        return DAWN_VALIDATION_ERROR(
            "Vertex attribute slot %u used in (%s, %s) is not present in the "
            "VertexState.",
            uint8_t(firstMissing), descriptor->module, &entryPoint);
    }

    return entryPoint;
}

MaybeError ValidatePrimitiveState(const DeviceBase* device, const PrimitiveState* rawDescriptor) {
    UnpackedPtr<PrimitiveState> descriptor;
    DAWN_TRY_ASSIGN(descriptor, ValidateAndUnpack(rawDescriptor));
    const auto* depthClipControl = descriptor.Get<PrimitiveDepthClipControl>();
    DAWN_INVALID_IF(depthClipControl && !device->HasFeature(Feature::DepthClipControl),
                    "%s is not supported", wgpu::FeatureName::DepthClipControl);
    DAWN_TRY(ValidatePrimitiveTopology(descriptor->topology));
    DAWN_TRY(ValidateIndexFormat(descriptor->stripIndexFormat));
    DAWN_TRY(ValidateFrontFace(descriptor->frontFace));
    DAWN_TRY(ValidateCullMode(descriptor->cullMode));

    // Pipeline descriptors must have stripIndexFormat == undefined if they are using
    // non-strip topologies.
    if (!IsStripPrimitiveTopology(descriptor->topology)) {
        DAWN_INVALID_IF(descriptor->stripIndexFormat != wgpu::IndexFormat::Undefined,
                        "StripIndexFormat (%s) is not undefined when using a non-strip primitive "
                        "topology (%s).",
                        descriptor->stripIndexFormat, descriptor->topology);
    }

    return {};
}

MaybeError ValidateStencilFaceUnused(StencilFaceState face) {
    DAWN_INVALID_IF((face.compare != wgpu::CompareFunction::Always) &&
                        (face.compare != wgpu::CompareFunction::Undefined),
                    "compare (%s) is defined and not %s.", face.compare,
                    wgpu::CompareFunction::Always);
    DAWN_INVALID_IF((face.failOp != wgpu::StencilOperation::Keep) &&
                        (face.failOp != wgpu::StencilOperation::Undefined),
                    "failOp (%s) is defined and not %s.", face.failOp,
                    wgpu::StencilOperation::Keep);
    DAWN_INVALID_IF((face.depthFailOp != wgpu::StencilOperation::Keep) &&
                        (face.depthFailOp != wgpu::StencilOperation::Undefined),
                    "depthFailOp (%s) is defined and not %s.", face.depthFailOp,
                    wgpu::StencilOperation::Keep);
    DAWN_INVALID_IF((face.passOp != wgpu::StencilOperation::Keep) &&
                        (face.passOp != wgpu::StencilOperation::Undefined),
                    "passOp (%s) is defined and not %s.", face.passOp,
                    wgpu::StencilOperation::Keep);
    return {};
}

MaybeError ValidateDepthStencilState(const DeviceBase* device,
                                     const DepthStencilState* descriptor) {
    DAWN_TRY_CONTEXT(ValidateCompareFunction(descriptor->depthCompare),
                     "validating depth compare function");
    DAWN_TRY_CONTEXT(ValidateCompareFunction(descriptor->stencilFront.compare),
                     "validating stencil front compare function");
    DAWN_TRY_CONTEXT(ValidateStencilOperation(descriptor->stencilFront.failOp),
                     "validating stencil front fail operation");
    DAWN_TRY_CONTEXT(ValidateStencilOperation(descriptor->stencilFront.depthFailOp),
                     "validating stencil front depth fail operation");
    DAWN_TRY_CONTEXT(ValidateStencilOperation(descriptor->stencilFront.passOp),
                     "validating stencil front pass operation");
    DAWN_TRY_CONTEXT(ValidateCompareFunction(descriptor->stencilBack.compare),
                     "validating stencil back compare function");
    DAWN_TRY_CONTEXT(ValidateStencilOperation(descriptor->stencilBack.failOp),
                     "validating stencil back fail operation");
    DAWN_TRY_CONTEXT(ValidateStencilOperation(descriptor->stencilBack.depthFailOp),
                     "validating stencil back depth fail operation");
    DAWN_TRY_CONTEXT(ValidateStencilOperation(descriptor->stencilBack.passOp),
                     "validating stencil back pass operation");

    const Format* format;
    DAWN_TRY_ASSIGN(format, device->GetInternalFormat(descriptor->format));
    DAWN_INVALID_IF(!format->HasDepthOrStencil() || !format->isRenderable,
                    "Depth stencil format (%s) is not depth-stencil renderable.",
                    descriptor->format);

    DAWN_INVALID_IF(
        std::isnan(descriptor->depthBiasSlopeScale) || std::isnan(descriptor->depthBiasClamp),
        "Either depthBiasSlopeScale (%f) or depthBiasClamp (%f) is NaN.",
        descriptor->depthBiasSlopeScale, descriptor->depthBiasClamp);

    DAWN_INVALID_IF(device->IsCompatibilityMode() && descriptor->depthBiasClamp != 0.0f,
                    "depthBiasClamp (%f) is not zero as required in compatibility mode.",
                    descriptor->depthBiasClamp);

    DAWN_INVALID_IF(
        format->HasDepth() && descriptor->depthCompare == wgpu::CompareFunction::Undefined &&
            (descriptor->depthWriteEnabled ||
             descriptor->stencilFront.depthFailOp != wgpu::StencilOperation::Keep ||
             descriptor->stencilBack.depthFailOp != wgpu::StencilOperation::Keep),
        "Depth stencil format (%s) has a depth aspect and depthCompare is %s while it's actually "
        "used by depthWriteEnabled (%u), or stencil front depth fail operation (%s), or "
        "stencil back depth fail operation (%s).",
        descriptor->format, wgpu::CompareFunction::Undefined, descriptor->depthWriteEnabled,
        descriptor->stencilFront.depthFailOp, descriptor->stencilBack.depthFailOp);

    UnpackedPtr<DepthStencilState> unpacked;
    DAWN_TRY_ASSIGN(unpacked, ValidateAndUnpack(descriptor));
    if (const auto* depthWriteDefined = unpacked.Get<DepthStencilStateDepthWriteDefinedDawn>()) {
        DAWN_INVALID_IF(
            format->HasDepth() && !depthWriteDefined->depthWriteDefined,
            "Depth stencil format (%s) has a depth aspect and depthWriteEnabled is undefined.",
            descriptor->format);
    }

    DAWN_INVALID_IF(
        !format->HasDepth() && descriptor->depthCompare != wgpu::CompareFunction::Always &&
            descriptor->depthCompare != wgpu::CompareFunction::Undefined,
        "Depth stencil format (%s) doesn't have depth aspect while depthCompare (%s) is "
        "neither %s nor %s.",
        descriptor->format, descriptor->depthCompare, wgpu::CompareFunction::Always,
        wgpu::CompareFunction::Undefined);

    DAWN_INVALID_IF(
        !format->HasDepth() && descriptor->depthWriteEnabled,
        "Depth stencil format (%s) doesn't have depth aspect while depthWriteEnabled (%u) is true.",
        descriptor->format, descriptor->depthWriteEnabled);

    if (!format->HasStencil()) {
        DAWN_TRY_CONTEXT(ValidateStencilFaceUnused(descriptor->stencilFront),
                         "validating that stencilFront doesn't use stencil when the depth-stencil "
                         "format (%s) doesn't have a stencil aspect.",
                         descriptor->format);
        DAWN_TRY_CONTEXT(ValidateStencilFaceUnused(descriptor->stencilBack),
                         "validating that stencilBack doesn't use stencil when the depth-stencil "
                         "format (%s) doesn't have a stencil aspect.",
                         descriptor->format);
    }

    return {};
}

MaybeError ValidateMultisampleState(const DeviceBase* device, const MultisampleState* descriptor) {
    DAWN_INVALID_IF(!IsValidSampleCount(descriptor->count),
                    "Multisample count (%u) is not supported.", descriptor->count);

    DAWN_INVALID_IF(descriptor->alphaToCoverageEnabled && descriptor->count <= 1,
                    "Multisample count (%u) must be > 1 when alphaToCoverage is enabled.",
                    descriptor->count);

    return {};
}

MaybeError ValidateBlendComponent(BlendComponent blendComponent, bool dualSourceBlendingEnabled) {
    if (!dualSourceBlendingEnabled) {
        DAWN_INVALID_IF(blendComponent.srcFactor == wgpu::BlendFactor::Src1 ||
                            blendComponent.srcFactor == wgpu::BlendFactor::OneMinusSrc1 ||
                            blendComponent.srcFactor == wgpu::BlendFactor::Src1Alpha ||
                            blendComponent.srcFactor == wgpu::BlendFactor::OneMinusSrc1Alpha,
                        "Source blend factor is %s while dualSourceBlending is not enabled.",
                        blendComponent.srcFactor);

        DAWN_INVALID_IF(blendComponent.dstFactor == wgpu::BlendFactor::Src1 ||
                            blendComponent.dstFactor == wgpu::BlendFactor::OneMinusSrc1 ||
                            blendComponent.dstFactor == wgpu::BlendFactor::Src1Alpha ||
                            blendComponent.dstFactor == wgpu::BlendFactor::OneMinusSrc1Alpha,
                        "Destination blend factor is %s while dualSourceBlending is not enabled.",
                        blendComponent.dstFactor);
    }

    if (blendComponent.operation == wgpu::BlendOperation::Min ||
        blendComponent.operation == wgpu::BlendOperation::Max) {
        DAWN_INVALID_IF(
            (blendComponent.srcFactor != wgpu::BlendFactor::One) &&
                (blendComponent.srcFactor != wgpu::BlendFactor::Undefined),
            "Source blend factor (%s) is defined and not %s when blend operation is %s.",
            blendComponent.srcFactor, wgpu::BlendFactor::One, blendComponent.operation);
        DAWN_INVALID_IF(
            (blendComponent.dstFactor != wgpu::BlendFactor::One) &&
                (blendComponent.dstFactor != wgpu::BlendFactor::Undefined),
            "Destination blend factor (%s) is defined and not %s when blend operation is %s.",
            blendComponent.dstFactor, wgpu::BlendFactor::One, blendComponent.operation);
    }

    return {};
}

MaybeError ValidateBlendState(DeviceBase* device, const BlendState* descriptor) {
    DAWN_TRY(ValidateBlendOperation(descriptor->alpha.operation));
    DAWN_TRY(ValidateBlendFactor(descriptor->alpha.srcFactor));
    DAWN_TRY(ValidateBlendFactor(descriptor->alpha.dstFactor));
    DAWN_TRY(ValidateBlendOperation(descriptor->color.operation));
    DAWN_TRY(ValidateBlendFactor(descriptor->color.srcFactor));
    DAWN_TRY(ValidateBlendFactor(descriptor->color.dstFactor));

    bool dualSourceBlendingEnabled = device->HasFeature(Feature::DualSourceBlending);
    DAWN_TRY(ValidateBlendComponent(descriptor->alpha, dualSourceBlendingEnabled));
    DAWN_TRY(ValidateBlendComponent(descriptor->color, dualSourceBlendingEnabled));

    return {};
}

bool BlendFactorContainsSrcAlpha(const wgpu::BlendFactor& blendFactor) {
    return blendFactor == wgpu::BlendFactor::SrcAlpha ||
           blendFactor == wgpu::BlendFactor::OneMinusSrcAlpha ||
           blendFactor == wgpu::BlendFactor::SrcAlphaSaturated;
}

MaybeError ValidateColorTargetState(
    DeviceBase* device,
    const ColorTargetState& descriptor,
    const Format* format,
    bool fragmentWritten,
    const EntryPointMetadata::FragmentRenderAttachmentInfo& fragmentOutputVariable,
    const MultisampleState& multisample) {
    UnpackedPtr<ColorTargetState> unpacked;
    DAWN_TRY_ASSIGN(unpacked, ValidateAndUnpack(&descriptor));
    if (unpacked.Get<ColorTargetStateExpandResolveTextureDawn>()) {
        DAWN_INVALID_IF(!device->HasFeature(Feature::DawnLoadResolveTexture),
                        "The ColorTargetStateExpandResolveTextureDawn struct is used while the "
                        "%s feature is not enabled.",
                        ToAPI(Feature::DawnLoadResolveTexture));

        DAWN_INVALID_IF(
            multisample.count <= 1,
            "The ColorTargetStateExpandResolveTextureDawn struct is used while multisample count "
            "(%u) is not > 1.",
            multisample.count);
    }

    if (descriptor.blend) {
        DAWN_TRY_CONTEXT(ValidateBlendState(device, descriptor.blend), "validating blend state.");
    }

    DAWN_TRY(ValidateColorWriteMask(descriptor.writeMask));
    DAWN_INVALID_IF(!format->IsColor() || !format->isRenderable,
                    "Color format (%s) is not color renderable.", format->format);

    DAWN_INVALID_IF(
        descriptor.blend &&
            !(format->GetAspectInfo(Aspect::Color).supportedSampleTypes & SampleTypeBit::Float),
        "Blending is enabled but color format (%s) is not blendable.", format->format);

    if (!fragmentWritten) {
        DAWN_INVALID_IF(
            descriptor.writeMask != wgpu::ColorWriteMask::None,
            "Color target has no corresponding fragment stage output but writeMask (%s) is "
            "not zero.",
            descriptor.writeMask);
        return {};
    }

    DAWN_INVALID_IF(
        fragmentOutputVariable.baseType != format->GetAspectInfo(Aspect::Color).baseType,
        "Color format (%s) base type (%s) doesn't match the fragment "
        "module output type (%s).",
        format->format, format->GetAspectInfo(Aspect::Color).baseType,
        fragmentOutputVariable.baseType);

    DAWN_INVALID_IF(fragmentOutputVariable.componentCount < format->componentCount,
                    "The fragment stage has fewer output components (%u) than the color format "
                    "(%s) component count (%u).",
                    fragmentOutputVariable.componentCount, format->format, format->componentCount);

    if (descriptor.blend && fragmentOutputVariable.componentCount < 4u) {
        // No alpha channel output, make sure there's no alpha involved in the blending operation.
        DAWN_INVALID_IF(BlendFactorContainsSrcAlpha(descriptor.blend->color.srcFactor) ||
                            BlendFactorContainsSrcAlpha(descriptor.blend->color.dstFactor),
                        "Color blending srcFactor (%s) or dstFactor (%s) is reading alpha "
                        "but it is missing from fragment output.",
                        descriptor.blend->color.srcFactor, descriptor.blend->color.dstFactor);
    }

    return {};
}

MaybeError ValidateFramebufferInput(
    DeviceBase* device,
    const Format* format,
    const EntryPointMetadata::FragmentRenderAttachmentInfo& inputVar) {
    DAWN_INVALID_IF(inputVar.baseType != format->GetAspectInfo(Aspect::Color).baseType,
                    "Color format (%s) base type (%s) doesn't match the fragment "
                    "module input type (%s).",
                    format->format, format->GetAspectInfo(Aspect::Color).baseType,
                    inputVar.baseType);
    DAWN_INVALID_IF(inputVar.componentCount != format->componentCount,
                    "The fragment stage number of input components (%u) doesn't match the color "
                    "format (%s) component count (%u).",
                    inputVar.componentCount, format->format, format->componentCount);
    return {};
}

MaybeError ValidateColorTargetStatesMatch(ColorAttachmentIndex firstColorTargetIndex,
                                          const ColorTargetState* const firstColorTargetState,
                                          ColorAttachmentIndex targetIndex,
                                          const ColorTargetState* target) {
    DAWN_INVALID_IF(firstColorTargetState->writeMask != target->writeMask,
                    "targets[%u].writeMask (%s) does not match targets[%u].writeMask (%s).",
                    targetIndex, target->writeMask, firstColorTargetIndex,
                    firstColorTargetState->writeMask);
    if (!firstColorTargetState->blend) {
        DAWN_INVALID_IF(target->blend,
                        "targets[%u].blend has a blend state but targets[%u].blend does not.",
                        targetIndex, firstColorTargetIndex);
    } else {
        DAWN_INVALID_IF(!target->blend,
                        "targets[%u].blend has a blend state but targets[%u].blend does not.",
                        firstColorTargetIndex, targetIndex);

        const BlendState& currBlendState = *target->blend;
        const BlendState& firstBlendState = *firstColorTargetState->blend;

        DAWN_INVALID_IF(
            firstBlendState.color.operation != currBlendState.color.operation,
            "targets[%u].color.operation (%s) does not match targets[%u].color.operation (%s).",
            firstColorTargetIndex, firstBlendState.color.operation, targetIndex,
            currBlendState.color.operation);
        DAWN_INVALID_IF(
            firstBlendState.color.srcFactor != currBlendState.color.srcFactor,
            "targets[%u].color.srcFactor (%s) does not match targets[%u].color.srcFactor (%s).",
            firstColorTargetIndex, firstBlendState.color.srcFactor, targetIndex,
            currBlendState.color.srcFactor);
        DAWN_INVALID_IF(
            firstBlendState.color.dstFactor != currBlendState.color.dstFactor,
            "targets[%u].color.dstFactor (%s) does not match targets[%u].color.dstFactor (%s).",
            firstColorTargetIndex, firstBlendState.color.dstFactor, targetIndex,
            currBlendState.color.dstFactor);
        DAWN_INVALID_IF(
            firstBlendState.alpha.operation != currBlendState.alpha.operation,
            "targets[%u].alpha.operation (%s) does not match targets[%u].alpha.operation (%s).",
            firstColorTargetIndex, firstBlendState.alpha.operation, targetIndex,
            currBlendState.alpha.operation);
        DAWN_INVALID_IF(
            firstBlendState.alpha.srcFactor != currBlendState.alpha.srcFactor,
            "targets[%u].alpha.srcFactor (%s) does not match targets[%u].alpha.srcFactor (%s).",
            firstColorTargetIndex, firstBlendState.alpha.srcFactor, targetIndex,
            currBlendState.alpha.srcFactor);
        DAWN_INVALID_IF(
            firstBlendState.alpha.dstFactor != currBlendState.alpha.dstFactor,
            "targets[%u].alpha.dstFactor (%s) does not match targets[%u].alpha.dstFactor (%s).",
            firstColorTargetIndex, firstBlendState.alpha.dstFactor, targetIndex,
            currBlendState.alpha.dstFactor);
    }
    return {};
}

ResultOrError<ShaderModuleEntryPoint> ValidateFragmentState(DeviceBase* device,
                                                            const FragmentState* descriptor,
                                                            const PipelineLayoutBase* layout,
                                                            const DepthStencilState* depthStencil,
                                                            const MultisampleState& multisample) {
    DAWN_INVALID_IF(descriptor->nextInChain != nullptr, "nextInChain must be nullptr.");

    ShaderModuleEntryPoint entryPoint;
    DAWN_TRY_ASSIGN_CONTEXT(
        entryPoint,
        ValidateProgrammableStage(device, descriptor->module, descriptor->entryPoint,
                                  descriptor->constantCount, descriptor->constants, layout,
                                  SingleShaderStage::Fragment),
        "validating fragment stage (%s, entryPoint: %s).", descriptor->module,
        descriptor->entryPoint);

    const EntryPointMetadata& fragmentMetadata = descriptor->module->GetEntryPoint(entryPoint.name);

    if (fragmentMetadata.usesFragDepth) {
        DAWN_INVALID_IF(depthStencil == nullptr,
                        "Depth stencil state is not present when fragment stage (%s, %s) is "
                        "writing to frag_depth.",
                        descriptor->module, &entryPoint);
        const Format* depthStencilFormat;
        DAWN_TRY_ASSIGN(depthStencilFormat, device->GetInternalFormat(depthStencil->format));
        DAWN_INVALID_IF(!depthStencilFormat->HasDepth(),
                        "Depth stencil state format (%s) has no depth aspect when fragment stage "
                        "(%s, %s) is "
                        "writing to frag_depth.",
                        depthStencil->format, descriptor->module, &entryPoint);
    }

    uint32_t maxColorAttachments = device->GetLimits().v1.maxColorAttachments;
    DAWN_INVALID_IF(descriptor->targetCount > maxColorAttachments,
                    "Number of targets (%u) exceeds the maximum (%u).", descriptor->targetCount,
                    maxColorAttachments);
    auto targets =
        ityp::SpanFromUntyped<ColorAttachmentIndex>(descriptor->targets, descriptor->targetCount);

    ColorAttachmentMask targetMask;
    for (auto [i, target] : Enumerate(targets)) {
        if (target.format == wgpu::TextureFormat::Undefined) {
            DAWN_INVALID_IF(target.blend,
                            "Color target[%u] blend state is set when the format is undefined.", i);
        } else {
            targetMask.set(i);
        }
    }

    ColorAttachmentFormats colorAttachmentFormats;
    for (auto i : IterateBitSet(targetMask)) {
        const Format* format;
        DAWN_TRY_ASSIGN(format, device->GetInternalFormat(targets[i].format));

        DAWN_TRY_CONTEXT(ValidateColorTargetState(
                             device, targets[i], format, fragmentMetadata.fragmentOutputMask[i],
                             fragmentMetadata.fragmentOutputVariables[i], multisample),
                         "validating targets[%u] framebuffer output.", i);
        colorAttachmentFormats.push_back(&device->GetValidInternalFormat(targets[i].format));

        if (fragmentMetadata.fragmentInputMask[i]) {
            DAWN_TRY_CONTEXT(ValidateFramebufferInput(device, format,
                                                      fragmentMetadata.fragmentInputVariables[i]),
                             "validating targets[%u]'s framebuffer input.", i);
        }
    }

    auto extraFramebufferInputs = fragmentMetadata.fragmentInputMask & ~targetMask;
    DAWN_INVALID_IF(
        extraFramebufferInputs.any(),
        "Framebuffer input at index %u is used without a corresponding color target state.",
        uint8_t(ityp::Sub(GetHighestBitIndexPlusOne(extraFramebufferInputs),
                          ColorAttachmentIndex(uint8_t(1)))));

    DAWN_TRY(ValidateColorAttachmentBytesPerSample(device, colorAttachmentFormats));

    if (multisample.alphaToCoverageEnabled) {
        DAWN_INVALID_IF(fragmentMetadata.usesSampleMaskOutput,
                        "alphaToCoverageEnabled is true when the sample_mask builtin is a "
                        "pipeline output of fragment stage of %s.",
                        descriptor->module);

        DAWN_INVALID_IF(descriptor->targetCount == 0 ||
                            descriptor->targets[0].format == wgpu::TextureFormat::Undefined,
                        "alphaToCoverageEnabled is true when color target[0] is not present.");

        const Format* format;
        DAWN_TRY_ASSIGN(format, device->GetInternalFormat(descriptor->targets[0].format));
        DAWN_INVALID_IF(
            !format->HasAlphaChannel(),
            "alphaToCoverageEnabled is true when target[0].format (%s) has no alpha channel.",
            format->format);
    }

    if (device->IsCompatibilityMode()) {
        DAWN_INVALID_IF(
            fragmentMetadata.usesSampleMaskOutput,
            "sample_mask is not supported in compatibility mode in the fragment stage (%s, %s)",
            descriptor->module, &entryPoint);

        DAWN_INVALID_IF(
            fragmentMetadata.usesSampleIndex,
            "sample_index is not supported in compatibility mode in the fragment stage (%s, %s)",
            descriptor->module, &entryPoint);

        // Check that all the color target states match.
        ColorAttachmentIndex firstColorTargetIndex{};
        const ColorTargetState* firstColorTargetState = nullptr;
        for (auto i : IterateBitSet(targetMask)) {
            if (!firstColorTargetState) {
                firstColorTargetState = &targets[i];
                firstColorTargetIndex = i;
                continue;
            }

            DAWN_TRY_CONTEXT(ValidateColorTargetStatesMatch(firstColorTargetIndex,
                                                            firstColorTargetState, i, &targets[i]),
                             "validating targets in compatibility mode.");
        }
    }

    return entryPoint;
}

MaybeError ValidateInterStageMatching(DeviceBase* device,
                                      const VertexState& vertexState,
                                      const ShaderModuleEntryPoint& vertexEntryPoint,
                                      const FragmentState& fragmentState,
                                      const ShaderModuleEntryPoint& fragmentEntryPoint) {
    const EntryPointMetadata& vertexMetadata =
        vertexState.module->GetEntryPoint(vertexEntryPoint.name);
    const EntryPointMetadata& fragmentMetadata =
        fragmentState.module->GetEntryPoint(fragmentEntryPoint.name);

    size_t maxInterStageShaderVariables = device->GetLimits().v1.maxInterStageShaderVariables;
    DAWN_ASSERT(vertexMetadata.usedInterStageVariables.size() == maxInterStageShaderVariables);
    DAWN_ASSERT(fragmentMetadata.usedInterStageVariables.size() == maxInterStageShaderVariables);
    for (size_t i = 0; i < maxInterStageShaderVariables; ++i) {
        if (!vertexMetadata.usedInterStageVariables[i]) {
            if (fragmentMetadata.usedInterStageVariables[i]) {
                return DAWN_VALIDATION_ERROR(
                    "The fragment input at location %u doesn't have a corresponding vertex output.",
                    i);
            }
            continue;
        }

        // It is valid that fragment output is a subset of vertex input
        if (!fragmentMetadata.usedInterStageVariables[i]) {
            continue;
        }
        const auto& vertexOutputInfo = vertexMetadata.interStageVariables[i];
        const auto& fragmentInputInfo = fragmentMetadata.interStageVariables[i];
        DAWN_INVALID_IF(
            vertexOutputInfo.baseType != fragmentInputInfo.baseType,
            "The base type (%s) of the vertex output at location %u is different from the "
            "base type (%s) of the fragment input at location %u.",
            vertexOutputInfo.baseType, i, fragmentInputInfo.baseType, i);

        DAWN_INVALID_IF(vertexOutputInfo.componentCount != fragmentInputInfo.componentCount,
                        "The component count (%u) of the vertex output at location %u is different "
                        "from the component count (%u) of the fragment input at location %u.",
                        vertexOutputInfo.componentCount, i, fragmentInputInfo.componentCount, i);

        DAWN_INVALID_IF(
            vertexOutputInfo.interpolationType != fragmentInputInfo.interpolationType,
            "The interpolation type (%s) of the vertex output at location %u is different "
            "from the interpolation type (%s) of the fragment input at location %u.",
            vertexOutputInfo.interpolationType, i, fragmentInputInfo.interpolationType, i);

        DAWN_INVALID_IF(
            vertexOutputInfo.interpolationSampling != fragmentInputInfo.interpolationSampling,
            "The interpolation sampling (%s) of the vertex output at location %u is "
            "different from the interpolation sampling (%s) of the fragment input at "
            "location %u.",
            vertexOutputInfo.interpolationSampling, i, fragmentInputInfo.interpolationSampling, i);

        DAWN_INVALID_IF(device->IsCompatibilityMode() &&
                            vertexOutputInfo.interpolationType == InterpolationType::Linear,
                        "The interpolation type (%s) of the vertex output at location %u is not "
                        "supported in compatibility mode",
                        vertexOutputInfo.interpolationType, i);

        DAWN_INVALID_IF(device->IsCompatibilityMode() &&
                            vertexOutputInfo.interpolationSampling == InterpolationSampling::Sample,
                        "The interpolation sampling (%s) of the vertex output at location %u is "
                        "not supported in compatibility mode",
                        vertexOutputInfo.interpolationSampling, i);
    }

    return {};
}
}  // anonymous namespace

// Helper functions
size_t IndexFormatSize(wgpu::IndexFormat format) {
    switch (format) {
        case wgpu::IndexFormat::Uint16:
            return sizeof(uint16_t);
        case wgpu::IndexFormat::Uint32:
            return sizeof(uint32_t);
        case wgpu::IndexFormat::Undefined:
            break;
    }
    DAWN_UNREACHABLE();
}

bool IsStripPrimitiveTopology(wgpu::PrimitiveTopology primitiveTopology) {
    return primitiveTopology == wgpu::PrimitiveTopology::LineStrip ||
           primitiveTopology == wgpu::PrimitiveTopology::TriangleStrip;
}

MaybeError ValidateRenderPipelineDescriptor(DeviceBase* device,
                                            const RenderPipelineDescriptor* descriptor) {
    UnpackedPtr<RenderPipelineDescriptor> unpacked;
    DAWN_TRY_ASSIGN(unpacked, ValidateAndUnpack(descriptor));

    if (descriptor->layout != nullptr) {
        DAWN_TRY(device->ValidateObject(descriptor->layout));
    }

    ShaderModuleEntryPoint vertexEntryPoint;
    DAWN_TRY_ASSIGN_CONTEXT(vertexEntryPoint,
                            ValidateVertexState(device, &descriptor->vertex, descriptor->layout,
                                                descriptor->primitive.topology),
                            "validating vertex state.");

    DAWN_TRY_CONTEXT(ValidatePrimitiveState(device, &descriptor->primitive),
                     "validating primitive state.");

    if (descriptor->depthStencil) {
        DAWN_TRY_CONTEXT(ValidateDepthStencilState(device, descriptor->depthStencil),
                         "validating depthStencil state.");
    }

    DAWN_TRY_CONTEXT(ValidateMultisampleState(device, &descriptor->multisample),
                     "validating multisample state.");

    DAWN_INVALID_IF(
        descriptor->multisample.alphaToCoverageEnabled && descriptor->fragment == nullptr,
        "alphaToCoverageEnabled is true when fragment state is not present.");

    if (descriptor->fragment != nullptr) {
        ShaderModuleEntryPoint fragmentEntryPoint;
        DAWN_TRY_ASSIGN_CONTEXT(
            fragmentEntryPoint,
            ValidateFragmentState(device, descriptor->fragment, descriptor->layout,
                                  descriptor->depthStencil, descriptor->multisample),
            "validating fragment state.");

        bool hasStorageAttachments =
            descriptor->layout != nullptr && descriptor->layout->HasAnyStorageAttachments();
        DAWN_INVALID_IF(descriptor->fragment->targetCount == 0 && !descriptor->depthStencil &&
                            !hasStorageAttachments,
                        "No attachment was specified (color, depth-stencil or other).");

        DAWN_TRY(ValidateInterStageMatching(device, descriptor->vertex, vertexEntryPoint,
                                            *(descriptor->fragment), fragmentEntryPoint));
    }

    return {};
}

std::vector<StageAndDescriptor> GetRenderStagesAndSetPlaceholderShader(
    DeviceBase* device,
    const RenderPipelineDescriptor* descriptor) {
    std::vector<StageAndDescriptor> stages;
    stages.push_back({SingleShaderStage::Vertex, descriptor->vertex.module,
                      descriptor->vertex.entryPoint, descriptor->vertex.constantCount,
                      descriptor->vertex.constants});
    if (descriptor->fragment != nullptr) {
        stages.push_back({SingleShaderStage::Fragment, descriptor->fragment->module,
                          descriptor->fragment->entryPoint, descriptor->fragment->constantCount,
                          descriptor->fragment->constants});
    } else if (device->IsToggleEnabled(Toggle::UsePlaceholderFragmentInVertexOnlyPipeline)) {
        InternalPipelineStore* store = device->GetInternalPipelineStore();
        // The placeholder fragment shader module should already be initialized
        DAWN_ASSERT(store->placeholderFragmentShader != nullptr);
        ShaderModuleBase* placeholderFragmentShader = store->placeholderFragmentShader.Get();
        stages.push_back(
            {SingleShaderStage::Fragment, placeholderFragmentShader, "fs_empty_main", 0, nullptr});
    }
    return stages;
}

// RenderPipelineBase

RenderPipelineBase::RenderPipelineBase(DeviceBase* device,
                                       const UnpackedPtr<RenderPipelineDescriptor>& descriptor)
    : PipelineBase(device,
                   descriptor->layout,
                   descriptor->label,
                   GetRenderStagesAndSetPlaceholderShader(device, *descriptor)),
      mAttachmentState(device->GetOrCreateAttachmentState(descriptor, GetLayout())) {
    mVertexBufferCount = descriptor->vertex.bufferCount;

    auto buffers =
        ityp::SpanFromUntyped<VertexBufferSlot>(descriptor->vertex.buffers, mVertexBufferCount);
    for (auto [slot, bufferOrig] : Enumerate(buffers)) {
        // Skip unused slots
        if (bufferOrig.stepMode == wgpu::VertexStepMode::VertexBufferNotUsed) {
            continue;
        }

        // Make a local copy with defaulting applied, before copying the
        // now-defaulted values into mVertexBufferInfos.
        VertexBufferLayout buffer = bufferOrig.WithTrivialFrontendDefaults();

        mVertexBuffersUsed.set(slot);
        mVertexBufferInfos[slot].arrayStride = buffer.arrayStride;
        mVertexBufferInfos[slot].stepMode = buffer.stepMode;
        mVertexBufferInfos[slot].usedBytesInStride = 0;
        mVertexBufferInfos[slot].lastStride = 0;
        switch (buffer.stepMode) {
            case wgpu::VertexStepMode::Vertex:
                mVertexBuffersUsedAsVertexBuffer.set(slot);
                break;
            case wgpu::VertexStepMode::Instance:
                mVertexBuffersUsedAsInstanceBuffer.set(slot);
                break;
            case wgpu::VertexStepMode::VertexBufferNotUsed:
            case wgpu::VertexStepMode::Undefined:
                DAWN_UNREACHABLE();
        }

        auto attributes = ityp::SpanFromUntyped<size_t>(buffer.attributes, buffer.attributeCount);
        for (auto [i, attribute] : Enumerate(attributes)) {
            VertexAttributeLocation location =
                VertexAttributeLocation(static_cast<uint8_t>(attribute.shaderLocation));

            mAttributeLocationsUsed.set(location);
            mAttributeInfos[location].shaderLocation = location;
            mAttributeInfos[location].vertexBufferSlot = slot;
            mAttributeInfos[location].offset = attribute.offset;
            mAttributeInfos[location].format = attribute.format;
            // Compute the access boundary of this attribute by adding attribute format size to
            // attribute offset. Although offset is in uint64_t, such sum must be no larger than
            // maxVertexBufferArrayStride (2048), which is promised by the GPUVertexBufferLayout
            // validation of creating render pipeline. Therefore, calculating in uint16_t will
            // cause no overflow.
            uint32_t formatByteSize = GetVertexFormatInfo(attribute.format).byteSize;
            DAWN_ASSERT(attribute.offset <= 2048);
            uint16_t accessBoundary = uint16_t(attribute.offset) + uint16_t(formatByteSize);
            mVertexBufferInfos[slot].usedBytesInStride =
                std::max(mVertexBufferInfos[slot].usedBytesInStride, accessBoundary);
            mVertexBufferInfos[slot].lastStride =
                std::max(mVertexBufferInfos[slot].lastStride,
                         mAttributeInfos[location].offset + formatByteSize);
        }
    }

    mPrimitive = descriptor->primitive.WithTrivialFrontendDefaults();
    UnpackedPtr<PrimitiveState> unpackedPrimitive = Unpack(&mPrimitive);
    if (auto* depthClipControl = unpackedPrimitive.Get<PrimitiveDepthClipControl>()) {
        mUnclippedDepth = depthClipControl->unclippedDepth;
    }

    mMultisample = descriptor->multisample;

    if (mAttachmentState->HasDepthStencilAttachment()) {
        mDepthStencil = descriptor->depthStencil->WithTrivialFrontendDefaults();

        // Reify depth option for stencil-only formats
        const Format& format = device->GetValidInternalFormat(mDepthStencil.format);
        if (!format.HasDepth()) {
            mDepthStencil.depthWriteEnabled = false;
            mDepthStencil.depthCompare = wgpu::CompareFunction::Always;
        }
        if (format.HasDepth() && mDepthStencil.depthCompare == wgpu::CompareFunction::Undefined &&
            !mDepthStencil.depthWriteEnabled &&
            mDepthStencil.stencilFront.depthFailOp == wgpu::StencilOperation::Keep &&
            mDepthStencil.stencilBack.depthFailOp == wgpu::StencilOperation::Keep) {
            mDepthStencil.depthCompare = wgpu::CompareFunction::Always;
        }
        mWritesDepth = mDepthStencil.depthWriteEnabled;
        if (mDepthStencil.stencilWriteMask) {
            if ((mPrimitive.cullMode != wgpu::CullMode::Front &&
                 (mDepthStencil.stencilFront.failOp != wgpu::StencilOperation::Keep ||
                  mDepthStencil.stencilFront.depthFailOp != wgpu::StencilOperation::Keep ||
                  mDepthStencil.stencilFront.passOp != wgpu::StencilOperation::Keep)) ||
                (mPrimitive.cullMode != wgpu::CullMode::Back &&
                 (mDepthStencil.stencilBack.failOp != wgpu::StencilOperation::Keep ||
                  mDepthStencil.stencilBack.depthFailOp != wgpu::StencilOperation::Keep ||
                  mDepthStencil.stencilBack.passOp != wgpu::StencilOperation::Keep))) {
                mWritesStencil = true;
            }
        }
    } else {
        // These default values below are useful for backends to fill information.
        // The values indicate that depth and stencil test are disabled when backends
        // set their own depth stencil states/descriptors according to the values in
        // mDepthStencil.
        // - Most defaults come from the dawn::native::DepthStencilState definition.
        mDepthStencil = {};
        // - depthCompare is nullable for validation purposes but should default to Always.
        mDepthStencil.depthCompare = wgpu::CompareFunction::Always;
    }

    for (auto i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) {
        // Vertex-only render pipeline have no color attachment. For a render pipeline with
        // color attachments, there must be a valid FragmentState.
        DAWN_ASSERT(descriptor->fragment != nullptr);
        const ColorTargetState* target = &descriptor->fragment->targets[static_cast<uint8_t>(i)];
        mTargets[i] = *target;

        if (target->blend != nullptr) {
            mTargetBlend[i] = target->blend->WithTrivialFrontendDefaults();
            mTargets[i].blend = &mTargetBlend[i];
        }
    }

    if (HasStage(SingleShaderStage::Fragment)) {
        mUsesFragDepth = GetStage(SingleShaderStage::Fragment).metadata->usesFragDepth;
    }

    if (HasStage(SingleShaderStage::Vertex)) {
        mUsesVertexIndex = GetStage(SingleShaderStage::Vertex).metadata->usesVertexIndex;
        mUsesInstanceIndex = GetStage(SingleShaderStage::Vertex).metadata->usesInstanceIndex;
    }

    SetContentHash(ComputeContentHash());
    GetObjectTrackingList()->Track(this);

    // Initialize the cache key to include the cache type and device information.
    StreamIn(&mCacheKey, CacheKey::Type::RenderPipeline, device->GetCacheKey());
}

RenderPipelineBase::RenderPipelineBase(DeviceBase* device,
                                       ObjectBase::ErrorTag tag,
                                       const char* label)
    : PipelineBase(device, tag, label) {}

RenderPipelineBase::~RenderPipelineBase() = default;

void RenderPipelineBase::DestroyImpl() {
    Uncache();

    // Remove reference to the attachment state so that we don't have lingering references to
    // it preventing it from being uncached in the device.
    mAttachmentState = nullptr;
}

// static
Ref<RenderPipelineBase> RenderPipelineBase::MakeError(DeviceBase* device, const char* label) {
    class ErrorRenderPipeline final : public RenderPipelineBase {
      public:
        explicit ErrorRenderPipeline(DeviceBase* device, const char* label)
            : RenderPipelineBase(device, ObjectBase::kError, label) {}

        MaybeError InitializeImpl() override {
            DAWN_UNREACHABLE();
            return {};
        }
    };

    return AcquireRef(new ErrorRenderPipeline(device, label));
}

ObjectType RenderPipelineBase::GetType() const {
    return ObjectType::RenderPipeline;
}

const VertexAttributeMask& RenderPipelineBase::GetAttributeLocationsUsed() const {
    DAWN_ASSERT(!IsError());
    return mAttributeLocationsUsed;
}

const VertexAttributeInfo& RenderPipelineBase::GetAttribute(
    VertexAttributeLocation location) const {
    DAWN_ASSERT(!IsError());
    DAWN_ASSERT(mAttributeLocationsUsed[location]);
    return mAttributeInfos[location];
}

const VertexBufferMask& RenderPipelineBase::GetVertexBuffersUsed() const {
    DAWN_ASSERT(!IsError());
    return mVertexBuffersUsed;
}

const VertexBufferMask& RenderPipelineBase::GetVertexBuffersUsedAsVertexBuffer() const {
    DAWN_ASSERT(!IsError());
    return mVertexBuffersUsedAsVertexBuffer;
}

const VertexBufferMask& RenderPipelineBase::GetVertexBuffersUsedAsInstanceBuffer() const {
    DAWN_ASSERT(!IsError());
    return mVertexBuffersUsedAsInstanceBuffer;
}

const VertexBufferInfo& RenderPipelineBase::GetVertexBuffer(VertexBufferSlot slot) const {
    DAWN_ASSERT(!IsError());
    DAWN_ASSERT(mVertexBuffersUsed[slot]);
    return mVertexBufferInfos[slot];
}

uint32_t RenderPipelineBase::GetVertexBufferCount() const {
    DAWN_ASSERT(!IsError());
    return mVertexBufferCount;
}

const ColorTargetState* RenderPipelineBase::GetColorTargetState(
    ColorAttachmentIndex attachmentSlot) const {
    DAWN_ASSERT(!IsError());
    DAWN_ASSERT(attachmentSlot < mTargets.size());
    return &mTargets[attachmentSlot];
}

const DepthStencilState* RenderPipelineBase::GetDepthStencilState() const {
    DAWN_ASSERT(!IsError());
    return &mDepthStencil;
}

bool RenderPipelineBase::UsesStencil() const {
    return mDepthStencil.stencilBack.compare != wgpu::CompareFunction::Always ||
           mDepthStencil.stencilBack.failOp != wgpu::StencilOperation::Keep ||
           mDepthStencil.stencilBack.depthFailOp != wgpu::StencilOperation::Keep ||
           mDepthStencil.stencilBack.passOp != wgpu::StencilOperation::Keep ||
           mDepthStencil.stencilFront.compare != wgpu::CompareFunction::Always ||
           mDepthStencil.stencilFront.failOp != wgpu::StencilOperation::Keep ||
           mDepthStencil.stencilFront.depthFailOp != wgpu::StencilOperation::Keep ||
           mDepthStencil.stencilFront.passOp != wgpu::StencilOperation::Keep;
}

wgpu::PrimitiveTopology RenderPipelineBase::GetPrimitiveTopology() const {
    DAWN_ASSERT(!IsError());
    return mPrimitive.topology;
}

wgpu::IndexFormat RenderPipelineBase::GetStripIndexFormat() const {
    DAWN_ASSERT(!IsError());
    return mPrimitive.stripIndexFormat;
}

wgpu::CullMode RenderPipelineBase::GetCullMode() const {
    DAWN_ASSERT(!IsError());
    return mPrimitive.cullMode;
}

wgpu::FrontFace RenderPipelineBase::GetFrontFace() const {
    DAWN_ASSERT(!IsError());
    return mPrimitive.frontFace;
}

bool RenderPipelineBase::IsDepthBiasEnabled() const {
    DAWN_ASSERT(!IsError());
    return mDepthStencil.depthBias != 0 || mDepthStencil.depthBiasSlopeScale != 0;
}

int32_t RenderPipelineBase::GetDepthBias() const {
    DAWN_ASSERT(!IsError());
    return mDepthStencil.depthBias;
}

float RenderPipelineBase::GetDepthBiasSlopeScale() const {
    DAWN_ASSERT(!IsError());
    return mDepthStencil.depthBiasSlopeScale;
}

float RenderPipelineBase::GetDepthBiasClamp() const {
    DAWN_ASSERT(!IsError());
    return mDepthStencil.depthBiasClamp;
}

bool RenderPipelineBase::HasUnclippedDepth() const {
    DAWN_ASSERT(!IsError());
    return mUnclippedDepth;
}

ColorAttachmentMask RenderPipelineBase::GetColorAttachmentsMask() const {
    DAWN_ASSERT(!IsError());
    return mAttachmentState->GetColorAttachmentsMask();
}

bool RenderPipelineBase::HasDepthStencilAttachment() const {
    DAWN_ASSERT(!IsError());
    return mAttachmentState->HasDepthStencilAttachment();
}

wgpu::TextureFormat RenderPipelineBase::GetColorAttachmentFormat(
    ColorAttachmentIndex attachment) const {
    DAWN_ASSERT(!IsError());
    return mTargets[attachment].format;
}

wgpu::TextureFormat RenderPipelineBase::GetDepthStencilFormat() const {
    DAWN_ASSERT(!IsError());
    DAWN_ASSERT(mAttachmentState->HasDepthStencilAttachment());
    return mDepthStencil.format;
}

uint32_t RenderPipelineBase::GetSampleCount() const {
    DAWN_ASSERT(!IsError());
    return mAttachmentState->GetSampleCount();
}

uint32_t RenderPipelineBase::GetSampleMask() const {
    DAWN_ASSERT(!IsError());
    return mMultisample.mask;
}

bool RenderPipelineBase::IsAlphaToCoverageEnabled() const {
    DAWN_ASSERT(!IsError());
    return mMultisample.alphaToCoverageEnabled;
}

const AttachmentState* RenderPipelineBase::GetAttachmentState() const {
    DAWN_ASSERT(!IsError());
    return mAttachmentState.Get();
}

bool RenderPipelineBase::WritesDepth() const {
    DAWN_ASSERT(!IsError());
    return mWritesDepth;
}

bool RenderPipelineBase::WritesStencil() const {
    DAWN_ASSERT(!IsError());
    return mWritesStencil;
}

bool RenderPipelineBase::UsesFragDepth() const {
    DAWN_ASSERT(!IsError());
    return mUsesFragDepth;
}

bool RenderPipelineBase::UsesVertexIndex() const {
    DAWN_ASSERT(!IsError());
    return mUsesVertexIndex;
}

bool RenderPipelineBase::UsesInstanceIndex() const {
    DAWN_ASSERT(!IsError());
    return mUsesInstanceIndex;
}

size_t RenderPipelineBase::ComputeContentHash() {
    ObjectContentHasher recorder;

    // Record modules and layout
    recorder.Record(PipelineBase::ComputeContentHash());

    // Hierarchically record the attachment state.
    // It contains the attachments set, texture formats, and sample count.
    recorder.Record(mAttachmentState->GetContentHash());

    // Record attachments
    for (auto i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) {
        const ColorTargetState& desc = *GetColorTargetState(i);
        recorder.Record(desc.writeMask);
        if (desc.blend != nullptr) {
            recorder.Record(desc.blend->color.operation, desc.blend->color.srcFactor,
                            desc.blend->color.dstFactor);
            recorder.Record(desc.blend->alpha.operation, desc.blend->alpha.srcFactor,
                            desc.blend->alpha.dstFactor);
        }
    }

    if (mAttachmentState->HasDepthStencilAttachment()) {
        const DepthStencilState& desc = mDepthStencil;
        recorder.Record(desc.depthWriteEnabled, desc.depthCompare);
        recorder.Record(desc.stencilReadMask, desc.stencilWriteMask);
        recorder.Record(desc.stencilFront.compare, desc.stencilFront.failOp,
                        desc.stencilFront.depthFailOp, desc.stencilFront.passOp);
        recorder.Record(desc.stencilBack.compare, desc.stencilBack.failOp,
                        desc.stencilBack.depthFailOp, desc.stencilBack.passOp);
        recorder.Record(desc.depthBias, desc.depthBiasSlopeScale, desc.depthBiasClamp);
    }

    // Record vertex state
    recorder.Record(mAttributeLocationsUsed);
    for (VertexAttributeLocation location : IterateBitSet(mAttributeLocationsUsed)) {
        const VertexAttributeInfo& desc = GetAttribute(location);
        recorder.Record(desc.shaderLocation, desc.vertexBufferSlot, desc.offset, desc.format);
    }

    recorder.Record(mVertexBuffersUsed);
    for (VertexBufferSlot slot : IterateBitSet(mVertexBuffersUsed)) {
        const VertexBufferInfo& desc = GetVertexBuffer(slot);
        recorder.Record(desc.arrayStride, desc.stepMode);
    }

    // Record primitive state
    recorder.Record(mPrimitive.topology, mPrimitive.stripIndexFormat, mPrimitive.frontFace,
                    mPrimitive.cullMode, mUnclippedDepth);

    // Record multisample state
    // Sample count hashed as part of the attachment state
    recorder.Record(mMultisample.mask, mMultisample.alphaToCoverageEnabled);

    return recorder.GetContentHash();
}

bool RenderPipelineBase::EqualityFunc::operator()(const RenderPipelineBase* a,
                                                  const RenderPipelineBase* b) const {
    // Check the layout and shader stages.
    if (!PipelineBase::EqualForCache(a, b)) {
        return false;
    }

    // Check the attachment state.
    // It contains the attachments set, texture formats, and sample count.
    if (a->mAttachmentState.Get() != b->mAttachmentState.Get()) {
        return false;
    }

    if (a->mAttachmentState.Get() != nullptr) {
        for (auto i : IterateBitSet(a->mAttachmentState->GetColorAttachmentsMask())) {
            const ColorTargetState& descA = *a->GetColorTargetState(i);
            const ColorTargetState& descB = *b->GetColorTargetState(i);
            if (descA.writeMask != descB.writeMask) {
                return false;
            }
            if ((descA.blend == nullptr) != (descB.blend == nullptr)) {
                return false;
            }
            if (descA.blend != nullptr) {
                if (descA.blend->color.operation != descB.blend->color.operation ||
                    descA.blend->color.srcFactor != descB.blend->color.srcFactor ||
                    descA.blend->color.dstFactor != descB.blend->color.dstFactor) {
                    return false;
                }
                if (descA.blend->alpha.operation != descB.blend->alpha.operation ||
                    descA.blend->alpha.srcFactor != descB.blend->alpha.srcFactor ||
                    descA.blend->alpha.dstFactor != descB.blend->alpha.dstFactor) {
                    return false;
                }
            }
        }

        // Check depth/stencil state
        if (a->mAttachmentState->HasDepthStencilAttachment()) {
            const DepthStencilState& stateA = a->mDepthStencil;
            const DepthStencilState& stateB = b->mDepthStencil;

            DAWN_ASSERT(!std::isnan(stateA.depthBiasSlopeScale));
            DAWN_ASSERT(!std::isnan(stateB.depthBiasSlopeScale));
            DAWN_ASSERT(!std::isnan(stateA.depthBiasClamp));
            DAWN_ASSERT(!std::isnan(stateB.depthBiasClamp));

            if (stateA.depthWriteEnabled != stateB.depthWriteEnabled ||
                stateA.depthCompare != stateB.depthCompare ||
                stateA.depthBias != stateB.depthBias ||
                stateA.depthBiasSlopeScale != stateB.depthBiasSlopeScale ||
                stateA.depthBiasClamp != stateB.depthBiasClamp) {
                return false;
            }
            if (stateA.stencilFront.compare != stateB.stencilFront.compare ||
                stateA.stencilFront.failOp != stateB.stencilFront.failOp ||
                stateA.stencilFront.depthFailOp != stateB.stencilFront.depthFailOp ||
                stateA.stencilFront.passOp != stateB.stencilFront.passOp) {
                return false;
            }
            if (stateA.stencilBack.compare != stateB.stencilBack.compare ||
                stateA.stencilBack.failOp != stateB.stencilBack.failOp ||
                stateA.stencilBack.depthFailOp != stateB.stencilBack.depthFailOp ||
                stateA.stencilBack.passOp != stateB.stencilBack.passOp) {
                return false;
            }
            if (stateA.stencilReadMask != stateB.stencilReadMask ||
                stateA.stencilWriteMask != stateB.stencilWriteMask) {
                return false;
            }
        }
    }

    // Check vertex state
    if (a->mAttributeLocationsUsed != b->mAttributeLocationsUsed) {
        return false;
    }

    for (VertexAttributeLocation loc : IterateBitSet(a->mAttributeLocationsUsed)) {
        const VertexAttributeInfo& descA = a->GetAttribute(loc);
        const VertexAttributeInfo& descB = b->GetAttribute(loc);
        if (descA.shaderLocation != descB.shaderLocation ||
            descA.vertexBufferSlot != descB.vertexBufferSlot || descA.offset != descB.offset ||
            descA.format != descB.format) {
            return false;
        }
    }

    if (a->mVertexBuffersUsed != b->mVertexBuffersUsed) {
        return false;
    }

    for (VertexBufferSlot slot : IterateBitSet(a->mVertexBuffersUsed)) {
        const VertexBufferInfo& descA = a->GetVertexBuffer(slot);
        const VertexBufferInfo& descB = b->GetVertexBuffer(slot);
        if (descA.arrayStride != descB.arrayStride || descA.stepMode != descB.stepMode) {
            return false;
        }
    }

    // Check primitive state
    {
        const PrimitiveState& stateA = a->mPrimitive;
        const PrimitiveState& stateB = b->mPrimitive;
        if (stateA.topology != stateB.topology ||
            stateA.stripIndexFormat != stateB.stripIndexFormat ||
            stateA.frontFace != stateB.frontFace || stateA.cullMode != stateB.cullMode ||
            a->mUnclippedDepth != b->mUnclippedDepth) {
            return false;
        }
    }

    // Check multisample state
    {
        const MultisampleState& stateA = a->mMultisample;
        const MultisampleState& stateB = b->mMultisample;
        // Sample count already checked as part of the attachment state.
        if (stateA.mask != stateB.mask ||
            stateA.alphaToCoverageEnabled != stateB.alphaToCoverageEnabled) {
            return false;
        }
    }

    return true;
}

}  // namespace dawn::native
