// Copyright 2017 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn/native/RenderPipeline.h"

#include "dawn/common/BitSetIterator.h"
#include "dawn/native/ChainUtils_autogen.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"
#include "dawn/native/VertexFormat.h"

#include <cmath>
#include <sstream>

namespace dawn::native {
    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        VertexFormatBaseType value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        switch (value) {
            case VertexFormatBaseType::Float:
                s->Append("Float");
                break;
            case VertexFormatBaseType::Uint:
                s->Append("Uint");
                break;
            case VertexFormatBaseType::Sint:
                s->Append("Sint");
                break;
            default:
                UNREACHABLE();
        }
        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        InterStageComponentType value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        switch (value) {
            case InterStageComponentType::Float:
                s->Append("Float");
                break;
            case InterStageComponentType::Uint:
                s->Append("Uint");
                break;
            case InterStageComponentType::Sint:
                s->Append("Sint");
                break;
            default:
                UNREACHABLE();
        }
        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        InterpolationType value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        switch (value) {
            case InterpolationType::Perspective:
                s->Append("Perspective");
                break;
            case InterpolationType::Linear:
                s->Append("Linear");
                break;
            case InterpolationType::Flat:
                s->Append("Flat");
                break;
            default:
                UNREACHABLE();
        }
        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        InterpolationSampling value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        switch (value) {
            case InterpolationSampling::None:
                s->Append("None");
                break;
            case InterpolationSampling::Center:
                s->Append("Center");
                break;
            case InterpolationSampling::Centroid:
                s->Append("Centroid");
                break;
            case InterpolationSampling::Sample:
                s->Append("Sample");
                break;
            default:
                UNREACHABLE();
        }
        return {true};
    }

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

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

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

            // No underflow is possible because the max vertex format size is smaller than
            // kMaxVertexBufferArrayStride.
            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.
            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,
            ityp::bitset<VertexAttributeLocation, kMaxVertexAttributes>* 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);

            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 {};
        }

        MaybeError ValidateVertexState(DeviceBase* device,
                                       const VertexState* descriptor,
                                       const PipelineLayoutBase* layout) {
            DAWN_INVALID_IF(descriptor->nextInChain != nullptr, "nextInChain must be nullptr.");

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

            DAWN_TRY_CONTEXT(
                ValidateProgrammableStage(device, descriptor->module, descriptor->entryPoint,
                                          descriptor->constantCount, descriptor->constants, layout,
                                          SingleShaderStage::Vertex),
                "validating vertex stage (module: %s, entryPoint: %s).", descriptor->module,
                descriptor->entryPoint);
            const EntryPointMetadata& vertexMetadata =
                descriptor->module->GetEntryPoint(descriptor->entryPoint);

            ityp::bitset<VertexAttributeLocation, kMaxVertexAttributes> 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;
            }

            // 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.
            ASSERT(totalAttributesNum <= kMaxVertexAttributes);

            // TODO(dawn:563): Specify which inputs were not used in error message.
            DAWN_INVALID_IF(!IsSubset(vertexMetadata.usedVertexInputs, attributesSetMask),
                            "Pipeline vertex stage uses vertex buffers not in the vertex state");

            return {};
        }

        MaybeError ValidatePrimitiveState(const DeviceBase* device,
                                          const PrimitiveState* descriptor) {
            DAWN_TRY(ValidateSingleSType(descriptor->nextInChain,
                                         wgpu::SType::PrimitiveDepthClampingState));
            const PrimitiveDepthClampingState* clampInfo = nullptr;
            FindInChain(descriptor->nextInChain, &clampInfo);
            if (clampInfo && !device->IsFeatureEnabled(Feature::DepthClamping)) {
                return DAWN_VALIDATION_ERROR("The depth clamping feature is not supported");
            }
            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 ValidateDepthStencilState(const DeviceBase* device,
                                             const DepthStencilState* descriptor) {
            if (descriptor->nextInChain != nullptr) {
                return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
            }

            DAWN_TRY(ValidateCompareFunction(descriptor->depthCompare));
            DAWN_TRY(ValidateCompareFunction(descriptor->stencilFront.compare));
            DAWN_TRY(ValidateStencilOperation(descriptor->stencilFront.failOp));
            DAWN_TRY(ValidateStencilOperation(descriptor->stencilFront.depthFailOp));
            DAWN_TRY(ValidateStencilOperation(descriptor->stencilFront.passOp));
            DAWN_TRY(ValidateCompareFunction(descriptor->stencilBack.compare));
            DAWN_TRY(ValidateStencilOperation(descriptor->stencilBack.failOp));
            DAWN_TRY(ValidateStencilOperation(descriptor->stencilBack.depthFailOp));
            DAWN_TRY(ValidateStencilOperation(descriptor->stencilBack.passOp));

            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(
                !format->HasDepth() && (descriptor->depthCompare != wgpu::CompareFunction::Always ||
                                        descriptor->depthWriteEnabled),
                "Depth stencil format (%s) doesn't have depth aspect while depthCompare (%s) is "
                "not %s or depthWriteEnabled (%u) is true.",
                descriptor->format, descriptor->depthCompare, wgpu::CompareFunction::Always,
                descriptor->depthWriteEnabled);

            DAWN_INVALID_IF(!format->HasStencil() && StencilTestEnabled(descriptor),
                            "Depth stencil format (%s) doesn't have stencil aspect while stencil "
                            "test or stencil write is enabled.",
                            descriptor->format);

            return {};
        }

        MaybeError ValidateMultisampleState(const MultisampleState* descriptor) {
            DAWN_INVALID_IF(descriptor->nextInChain != nullptr, "nextInChain must be nullptr.");

            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) {
            if (blendComponent.operation == wgpu::BlendOperation::Min ||
                blendComponent.operation == wgpu::BlendOperation::Max) {
                DAWN_INVALID_IF(blendComponent.srcFactor != wgpu::BlendFactor::One ||
                                    blendComponent.dstFactor != wgpu::BlendFactor::One,
                                "Blend factor is not %s when blend operation is %s.",
                                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));
            DAWN_TRY(ValidateBlendComponent(descriptor->alpha));
            DAWN_TRY(ValidateBlendComponent(descriptor->color));

            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,
            bool fragmentWritten,
            const EntryPointMetadata::FragmentOutputVariableInfo& fragmentOutputVariable) {
            DAWN_INVALID_IF(descriptor->nextInChain != nullptr, "nextInChain must be nullptr.");

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

            DAWN_TRY(ValidateColorWriteMask(descriptor->writeMask));

            const Format* format;
            DAWN_TRY_ASSIGN(format, device->GetInternalFormat(descriptor->format));
            DAWN_INVALID_IF(!format->IsColor() || !format->isRenderable,
                            "Color format (%s) is not color renderable.", descriptor->format);

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

            if (fragmentWritten) {
                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).",
                                descriptor->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, descriptor->format,
                    format->componentCount);

                if (descriptor->blend) {
                    if (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);
                    }
                }
            } else {
                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 {};
        }

        MaybeError ValidateFragmentState(DeviceBase* device,
                                         const FragmentState* descriptor,
                                         const PipelineLayoutBase* layout) {
            DAWN_INVALID_IF(descriptor->nextInChain != nullptr, "nextInChain must be nullptr.");

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

            DAWN_INVALID_IF(descriptor->targetCount > kMaxColorAttachments,
                            "Number of targets (%u) exceeds the maximum (%u).",
                            descriptor->targetCount, kMaxColorAttachments);

            const EntryPointMetadata& fragmentMetadata =
                descriptor->module->GetEntryPoint(descriptor->entryPoint);
            for (ColorAttachmentIndex i(uint8_t(0));
                 i < ColorAttachmentIndex(static_cast<uint8_t>(descriptor->targetCount)); ++i) {
                const ColorTargetState* target = &descriptor->targets[static_cast<uint8_t>(i)];
                if (target->format != wgpu::TextureFormat::Undefined) {
                    DAWN_TRY_CONTEXT(ValidateColorTargetState(
                                         device, target, fragmentMetadata.fragmentOutputsWritten[i],
                                         fragmentMetadata.fragmentOutputVariables[i]),
                                     "validating targets[%u].", static_cast<uint8_t>(i));
                } else {
                    DAWN_INVALID_IF(
                        target->blend,
                        "Color target[%u] blend state is set when the format is undefined.",
                        static_cast<uint8_t>(i));
                    DAWN_INVALID_IF(
                        target->writeMask != wgpu::ColorWriteMask::None,
                        "Color target[%u] write mask is set to (%s) when the format is undefined.",
                        static_cast<uint8_t>(i), target->writeMask);
                }
            }

            return {};
        }

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

            // TODO(dawn:563): Can this message give more details?
            DAWN_INVALID_IF(
                vertexMetadata.usedInterStageVariables != fragmentMetadata.usedInterStageVariables,
                "One or more fragment inputs and vertex outputs are not one-to-one matching");

            // TODO(dawn:802): Validate interpolation types and interpolition sampling types
            for (size_t i : IterateBitSet(vertexMetadata.usedInterStageVariables)) {
                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);
            }

            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;
        }
        UNREACHABLE();
    }

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

    MaybeError ValidateRenderPipelineDescriptor(DeviceBase* device,
                                                const RenderPipelineDescriptor* descriptor) {
        DAWN_INVALID_IF(descriptor->nextInChain != nullptr, "nextInChain must be nullptr.");

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

        DAWN_TRY_CONTEXT(ValidateVertexState(device, &descriptor->vertex, descriptor->layout),
                         "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(&descriptor->multisample),
                         "validating multisample state.");

        if (descriptor->fragment != nullptr) {
            DAWN_TRY_CONTEXT(
                ValidateFragmentState(device, descriptor->fragment, descriptor->layout),
                "validating fragment state.");

            DAWN_INVALID_IF(descriptor->fragment->targetCount == 0 && !descriptor->depthStencil,
                            "Must have at least one color or depthStencil target.");

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

        return {};
    }

    std::vector<StageAndDescriptor> GetRenderStagesAndSetDummyShader(
        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::UseDummyFragmentInVertexOnlyPipeline)) {
            InternalPipelineStore* store = device->GetInternalPipelineStore();
            // The dummy fragment shader module should already be initialized
            DAWN_ASSERT(store->dummyFragmentShader != nullptr);
            ShaderModuleBase* dummyFragmentShader = store->dummyFragmentShader.Get();
            stages.push_back(
                {SingleShaderStage::Fragment, dummyFragmentShader, "fs_empty_main", 0, nullptr});
        }
        return stages;
    }

    bool StencilTestEnabled(const DepthStencilState* depthStencil) {
        return depthStencil->stencilBack.compare != wgpu::CompareFunction::Always ||
               depthStencil->stencilBack.failOp != wgpu::StencilOperation::Keep ||
               depthStencil->stencilBack.depthFailOp != wgpu::StencilOperation::Keep ||
               depthStencil->stencilBack.passOp != wgpu::StencilOperation::Keep ||
               depthStencil->stencilFront.compare != wgpu::CompareFunction::Always ||
               depthStencil->stencilFront.failOp != wgpu::StencilOperation::Keep ||
               depthStencil->stencilFront.depthFailOp != wgpu::StencilOperation::Keep ||
               depthStencil->stencilFront.passOp != wgpu::StencilOperation::Keep;
    }

    // RenderPipelineBase

    RenderPipelineBase::RenderPipelineBase(DeviceBase* device,
                                           const RenderPipelineDescriptor* descriptor)
        : PipelineBase(device,
                       descriptor->layout,
                       descriptor->label,
                       GetRenderStagesAndSetDummyShader(device, descriptor)),
          mAttachmentState(device->GetOrCreateAttachmentState(descriptor)) {
        mVertexBufferCount = descriptor->vertex.bufferCount;
        const VertexBufferLayout* buffers = descriptor->vertex.buffers;
        for (uint8_t slot = 0; slot < mVertexBufferCount; ++slot) {
            if (buffers[slot].attributeCount == 0) {
                continue;
            }

            VertexBufferSlot typedSlot(slot);

            mVertexBufferSlotsUsed.set(typedSlot);
            mVertexBufferInfos[typedSlot].arrayStride = buffers[slot].arrayStride;
            mVertexBufferInfos[typedSlot].stepMode = buffers[slot].stepMode;
            mVertexBufferInfos[typedSlot].usedBytesInStride = 0;
            mVertexBufferInfos[typedSlot].lastStride = 0;
            switch (buffers[slot].stepMode) {
                case wgpu::VertexStepMode::Vertex:
                    mVertexBufferSlotsUsedAsVertexBuffer.set(typedSlot);
                    break;
                case wgpu::VertexStepMode::Instance:
                    mVertexBufferSlotsUsedAsInstanceBuffer.set(typedSlot);
                    break;
                default:
                    DAWN_UNREACHABLE();
            }

            for (uint32_t i = 0; i < buffers[slot].attributeCount; ++i) {
                VertexAttributeLocation location = VertexAttributeLocation(
                    static_cast<uint8_t>(buffers[slot].attributes[i].shaderLocation));
                mAttributeLocationsUsed.set(location);
                mAttributeInfos[location].shaderLocation = location;
                mAttributeInfos[location].vertexBufferSlot = typedSlot;
                mAttributeInfos[location].offset = buffers[slot].attributes[i].offset;
                mAttributeInfos[location].format = buffers[slot].attributes[i].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(buffers[slot].attributes[i].format).byteSize;
                DAWN_ASSERT(buffers[slot].attributes[i].offset <= 2048);
                uint16_t accessBoundary =
                    uint16_t(buffers[slot].attributes[i].offset) + uint16_t(formatByteSize);
                mVertexBufferInfos[typedSlot].usedBytesInStride =
                    std::max(mVertexBufferInfos[typedSlot].usedBytesInStride, accessBoundary);
                mVertexBufferInfos[typedSlot].lastStride =
                    std::max(mVertexBufferInfos[typedSlot].lastStride,
                             mAttributeInfos[location].offset + formatByteSize);
            }
        }

        mPrimitive = descriptor->primitive;
        const PrimitiveDepthClampingState* clampInfo = nullptr;
        FindInChain(mPrimitive.nextInChain, &clampInfo);
        if (clampInfo) {
            mClampDepth = clampInfo->clampDepth;
        }
        mMultisample = descriptor->multisample;

        if (mAttachmentState->HasDepthStencilAttachment()) {
            mDepthStencil = *descriptor->depthStencil;
            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.
            mDepthStencil.format = wgpu::TextureFormat::Undefined;
            mDepthStencil.depthWriteEnabled = false;
            mDepthStencil.depthCompare = wgpu::CompareFunction::Always;
            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;
            mDepthStencil.stencilReadMask = 0xff;
            mDepthStencil.stencilWriteMask = 0xff;
            mDepthStencil.depthBias = 0;
            mDepthStencil.depthBiasSlopeScale = 0.0f;
            mDepthStencil.depthBiasClamp = 0.0f;
        }

        for (ColorAttachmentIndex 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.
            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;
                mTargets[i].blend = &mTargetBlend[i];
            }
        }

        SetContentHash(ComputeContentHash());
        TrackInDevice();
    }

    RenderPipelineBase::RenderPipelineBase(DeviceBase* device) : PipelineBase(device) {
        TrackInDevice();
    }

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

    RenderPipelineBase::~RenderPipelineBase() = default;

    void RenderPipelineBase::DestroyImpl() {
        if (IsCachedReference()) {
            // Do not uncache the actual cached object if we are a blueprint.
            GetDevice()->UncacheRenderPipeline(this);
        }

        // 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
    RenderPipelineBase* RenderPipelineBase::MakeError(DeviceBase* device) {
        class ErrorRenderPipeline final : public RenderPipelineBase {
          public:
            ErrorRenderPipeline(DeviceBase* device)
                : RenderPipelineBase(device, ObjectBase::kError) {
            }

            MaybeError Initialize() override {
                UNREACHABLE();
                return {};
            }
        };

        return new ErrorRenderPipeline(device);
    }

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

    const ityp::bitset<VertexAttributeLocation, kMaxVertexAttributes>&
    RenderPipelineBase::GetAttributeLocationsUsed() const {
        ASSERT(!IsError());
        return mAttributeLocationsUsed;
    }

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

    const ityp::bitset<VertexBufferSlot, kMaxVertexBuffers>&
    RenderPipelineBase::GetVertexBufferSlotsUsed() const {
        ASSERT(!IsError());
        return mVertexBufferSlotsUsed;
    }

    const ityp::bitset<VertexBufferSlot, kMaxVertexBuffers>&
    RenderPipelineBase::GetVertexBufferSlotsUsedAsVertexBuffer() const {
        ASSERT(!IsError());
        return mVertexBufferSlotsUsedAsVertexBuffer;
    }

    const ityp::bitset<VertexBufferSlot, kMaxVertexBuffers>&
    RenderPipelineBase::GetVertexBufferSlotsUsedAsInstanceBuffer() const {
        ASSERT(!IsError());
        return mVertexBufferSlotsUsedAsInstanceBuffer;
    }

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

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

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

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

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

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

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

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

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

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

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

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

    bool RenderPipelineBase::ShouldClampDepth() const {
        ASSERT(!IsError());
        return mClampDepth;
    }

    ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments>
    RenderPipelineBase::GetColorAttachmentsMask() const {
        ASSERT(!IsError());
        return mAttachmentState->GetColorAttachmentsMask();
    }

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

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

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

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

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

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

    const AttachmentState* RenderPipelineBase::GetAttachmentState() const {
        ASSERT(!IsError());

        return mAttachmentState.Get();
    }

    bool RenderPipelineBase::WritesDepth() const {
        ASSERT(!IsError());

        return mWritesDepth;
    }

    bool RenderPipelineBase::WritesStencil() const {
        ASSERT(!IsError());

        return mWritesStencil;
    }

    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 (ColorAttachmentIndex 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(mVertexBufferSlotsUsed);
        for (VertexBufferSlot slot : IterateBitSet(mVertexBufferSlotsUsed)) {
            const VertexBufferInfo& desc = GetVertexBuffer(slot);
            recorder.Record(desc.arrayStride, desc.stepMode);
        }

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

        // 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 (ColorAttachmentIndex 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;

                ASSERT(!std::isnan(stateA.depthBiasSlopeScale));
                ASSERT(!std::isnan(stateB.depthBiasSlopeScale));
                ASSERT(!std::isnan(stateA.depthBiasClamp));
                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->mVertexBufferSlotsUsed != b->mVertexBufferSlotsUsed) {
            return false;
        }

        for (VertexBufferSlot slot : IterateBitSet(a->mVertexBufferSlotsUsed)) {
            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->mClampDepth != b->mClampDepth) {
                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
