/*
 * Copyright 2022 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/graphite/dawn/DawnGraphicsPipeline.h"

#include "include/gpu/graphite/TextureInfo.h"
#include "include/gpu/graphite/dawn/DawnGraphiteTypes.h"
#include "include/private/SkLog.h"
#include "include/private/SkTArray.h"
#include "src/core/SkTBlockList.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/SkSLToBackend.h"
#include "src/gpu/Swizzle.h"
#include "src/gpu/graphite/Attribute.h"
#include "src/gpu/graphite/ContextUtils.h"
#include "src/gpu/graphite/GraphicsPipelineDesc.h"
#include "src/gpu/graphite/RenderPassDesc.h"
#include "src/gpu/graphite/RendererProvider.h"
#include "src/gpu/graphite/ShaderInfo.h"
#include "src/gpu/graphite/TextureInfoPriv.h"
#include "src/gpu/graphite/ThreadSafeResourceProvider.h"
#include "src/gpu/graphite/UniformManager.h"
#include "src/gpu/graphite/dawn/DawnCaps.h"
#include "src/gpu/graphite/dawn/DawnErrorChecker.h"
#include "src/gpu/graphite/dawn/DawnGraphiteUtils.h"
#include "src/gpu/graphite/dawn/DawnResourceProvider.h"
#include "src/gpu/graphite/dawn/DawnSampler.h"
#include "src/gpu/graphite/dawn/DawnSharedContext.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/SkSLUtil.h"
#include "src/sksl/ir/SkSLProgram.h"

#include <atomic>

using namespace skia_private;

namespace skgpu::graphite {

namespace {

inline wgpu::VertexFormat attribute_type_to_dawn(VertexAttribType type) {
    switch (type) {
        case VertexAttribType::kFloat:
            return wgpu::VertexFormat::Float32;
        case VertexAttribType::kFloat2:
            return wgpu::VertexFormat::Float32x2;
        case VertexAttribType::kFloat3:
            return wgpu::VertexFormat::Float32x3;
        case VertexAttribType::kFloat4:
            return wgpu::VertexFormat::Float32x4;
        case VertexAttribType::kHalf2:
            return wgpu::VertexFormat::Float16x2;
        case VertexAttribType::kHalf4:
            return wgpu::VertexFormat::Float16x4;
        case VertexAttribType::kInt2:
            return wgpu::VertexFormat::Sint32x2;
        case VertexAttribType::kInt3:
            return wgpu::VertexFormat::Sint32x3;
        case VertexAttribType::kInt4:
            return wgpu::VertexFormat::Sint32x4;
        case VertexAttribType::kUInt2:
            return wgpu::VertexFormat::Uint32x2;
        case VertexAttribType::kByte2:
            return wgpu::VertexFormat::Sint8x2;
        case VertexAttribType::kByte4:
            return wgpu::VertexFormat::Sint8x4;
        case VertexAttribType::kUByte2:
            return wgpu::VertexFormat::Uint8x2;
        case VertexAttribType::kUByte4:
            return wgpu::VertexFormat::Uint8x4;
        case VertexAttribType::kUByte4_norm:
            return wgpu::VertexFormat::Unorm8x4;
        case VertexAttribType::kShort2:
            return wgpu::VertexFormat::Sint16x2;
        case VertexAttribType::kShort4:
            return wgpu::VertexFormat::Sint16x4;
        case VertexAttribType::kUShort2:
            return wgpu::VertexFormat::Uint16x2;
        case VertexAttribType::kUShort2_norm:
            return wgpu::VertexFormat::Unorm16x2;
        case VertexAttribType::kInt:
            return wgpu::VertexFormat::Sint32;
        case VertexAttribType::kUInt:
            return wgpu::VertexFormat::Uint32;
        case VertexAttribType::kUShort4_norm:
            return wgpu::VertexFormat::Unorm16x4;
        case VertexAttribType::kHalf:
        case VertexAttribType::kByte:
        case VertexAttribType::kUByte:
        case VertexAttribType::kUByte_norm:
        case VertexAttribType::kUShort_norm:
            // Not supported.
            break;
    }
    SkUNREACHABLE;
}

wgpu::CompareFunction compare_op_to_dawn(CompareOp op) {
    switch (op) {
        case CompareOp::kAlways:
            return wgpu::CompareFunction::Always;
        case CompareOp::kNever:
            return wgpu::CompareFunction::Never;
        case CompareOp::kGreater:
            return wgpu::CompareFunction::Greater;
        case CompareOp::kGEqual:
            return wgpu::CompareFunction::GreaterEqual;
        case CompareOp::kLess:
            return wgpu::CompareFunction::Less;
        case CompareOp::kLEqual:
            return wgpu::CompareFunction::LessEqual;
        case CompareOp::kEqual:
            return wgpu::CompareFunction::Equal;
        case CompareOp::kNotEqual:
            return wgpu::CompareFunction::NotEqual;
    }
    SkUNREACHABLE;
}

wgpu::StencilOperation stencil_op_to_dawn(StencilOp op) {
    switch (op) {
        case StencilOp::kKeep:
            return wgpu::StencilOperation::Keep;
        case StencilOp::kZero:
            return wgpu::StencilOperation::Zero;
        case StencilOp::kReplace:
            return wgpu::StencilOperation::Replace;
        case StencilOp::kInvert:
            return wgpu::StencilOperation::Invert;
        case StencilOp::kIncWrap:
            return wgpu::StencilOperation::IncrementWrap;
        case StencilOp::kDecWrap:
            return wgpu::StencilOperation::DecrementWrap;
        case StencilOp::kIncClamp:
            return wgpu::StencilOperation::IncrementClamp;
        case StencilOp::kDecClamp:
            return wgpu::StencilOperation::DecrementClamp;
    }
    SkUNREACHABLE;
}

wgpu::StencilFaceState stencil_face_to_dawn(DepthStencilSettings::Face face) {
    wgpu::StencilFaceState state;
    state.compare = compare_op_to_dawn(face.fCompareOp);
    state.failOp = stencil_op_to_dawn(face.fStencilFailOp);
    state.depthFailOp = stencil_op_to_dawn(face.fDepthFailOp);
    state.passOp = stencil_op_to_dawn(face.fDepthStencilPassOp);
    return state;
}

size_t create_vertex_attributes(SkSpan<const Attribute> attrs,
                                int shaderLocationOffset,
                                TArray<wgpu::VertexAttribute>* out) {
    SkASSERT(out && out->empty());
    out->resize(attrs.size());
    size_t vertexAttributeOffset = 0;
    int attributeIndex = 0;
    for (const auto& attr : attrs) {
        wgpu::VertexAttribute& vertexAttribute =  (*out)[attributeIndex];
        vertexAttribute.format = attribute_type_to_dawn(attr.cpuType());
        vertexAttribute.offset = vertexAttributeOffset;
        vertexAttribute.shaderLocation = shaderLocationOffset + attributeIndex;
        vertexAttributeOffset += attr.sizeAlign4();
        attributeIndex++;
    }
    return vertexAttributeOffset;
}

// TODO: share this w/ Ganesh dawn backend?
static wgpu::BlendFactor blend_coeff_to_dawn_blend(const DawnCaps& caps, skgpu::BlendCoeff coeff) {
#if defined(__EMSCRIPTEN__)
#define VALUE_IF_DSB_OR_ZERO(VALUE) wgpu::BlendFactor::Zero
#else
#define VALUE_IF_DSB_OR_ZERO(VALUE) \
    ((caps.shaderCaps()->fDualSourceBlendingSupport) ? (VALUE) : wgpu::BlendFactor::Zero)
#endif
    switch (coeff) {
        case skgpu::BlendCoeff::kZero:
            return wgpu::BlendFactor::Zero;
        case skgpu::BlendCoeff::kOne:
            return wgpu::BlendFactor::One;
        case skgpu::BlendCoeff::kSC:
            return wgpu::BlendFactor::Src;
        case skgpu::BlendCoeff::kISC:
            return wgpu::BlendFactor::OneMinusSrc;
        case skgpu::BlendCoeff::kDC:
            return wgpu::BlendFactor::Dst;
        case skgpu::BlendCoeff::kIDC:
            return wgpu::BlendFactor::OneMinusDst;
        case skgpu::BlendCoeff::kSA:
            return wgpu::BlendFactor::SrcAlpha;
        case skgpu::BlendCoeff::kISA:
            return wgpu::BlendFactor::OneMinusSrcAlpha;
        case skgpu::BlendCoeff::kDA:
            return wgpu::BlendFactor::DstAlpha;
        case skgpu::BlendCoeff::kIDA:
            return wgpu::BlendFactor::OneMinusDstAlpha;
        case skgpu::BlendCoeff::kConstC:
            return wgpu::BlendFactor::Constant;
        case skgpu::BlendCoeff::kIConstC:
            return wgpu::BlendFactor::OneMinusConstant;
        case skgpu::BlendCoeff::kS2C:
            return VALUE_IF_DSB_OR_ZERO(wgpu::BlendFactor::Src1);
        case skgpu::BlendCoeff::kIS2C:
            return VALUE_IF_DSB_OR_ZERO(wgpu::BlendFactor::OneMinusSrc1);
        case skgpu::BlendCoeff::kS2A:
            return VALUE_IF_DSB_OR_ZERO(wgpu::BlendFactor::Src1Alpha);
        case skgpu::BlendCoeff::kIS2A:
            return VALUE_IF_DSB_OR_ZERO(wgpu::BlendFactor::OneMinusSrc1Alpha);
        case skgpu::BlendCoeff::kIllegal:
            return wgpu::BlendFactor::Zero;
    }
    SkUNREACHABLE;
#undef VALUE_IF_DSB_OR_ZERO
}

static wgpu::BlendFactor blend_coeff_to_dawn_blend_for_alpha(const DawnCaps& caps,
                                                             skgpu::BlendCoeff coeff) {
    switch (coeff) {
        // Force all srcColor used in alpha slot to alpha version.
        case skgpu::BlendCoeff::kSC:
            return wgpu::BlendFactor::SrcAlpha;
        case skgpu::BlendCoeff::kISC:
            return wgpu::BlendFactor::OneMinusSrcAlpha;
        case skgpu::BlendCoeff::kDC:
            return wgpu::BlendFactor::DstAlpha;
        case skgpu::BlendCoeff::kIDC:
            return wgpu::BlendFactor::OneMinusDstAlpha;
        default:
            return blend_coeff_to_dawn_blend(caps, coeff);
    }
}

// TODO: share this w/ Ganesh Metal backend?
static wgpu::BlendOperation blend_equation_to_dawn_blend_op(skgpu::BlendEquation equation) {
    static const wgpu::BlendOperation gTable[] = {
            wgpu::BlendOperation::Add,              // skgpu::BlendEquation::kAdd
            wgpu::BlendOperation::Subtract,         // skgpu::BlendEquation::kSubtract
            wgpu::BlendOperation::ReverseSubtract,  // skgpu::BlendEquation::kReverseSubtract
    };
    static_assert(std::size(gTable) == (int)skgpu::BlendEquation::kFirstAdvanced);
    static_assert(0 == (int)skgpu::BlendEquation::kAdd);
    static_assert(1 == (int)skgpu::BlendEquation::kSubtract);
    static_assert(2 == (int)skgpu::BlendEquation::kReverseSubtract);

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

struct AsyncPipelineCreationBase {
    AsyncPipelineCreationBase(const UniqueKey& key) : fKey(key) {}

    wgpu::RenderPipeline fRenderPipeline;
    std::string fErrorMessage;
    std::atomic<bool> fFinished = false;
    UniqueKey fKey; // for logging the wait to resolve a Pipeline future in dawnRenderPipeline
#if SK_HISTOGRAMS_ENABLED
    // We need these three for the Graphite.PipelineCreationTimes.* histograms (cf.
    // log_pipeline_creation)
    skgpu::StdSteadyClock::time_point fStartTime;
    bool fFromPrecompile;
    bool fAsynchronous = false;
#endif
};

void log_pipeline_creation(const AsyncPipelineCreationBase* apcb) {
#if SK_HISTOGRAMS_ENABLED
    [[maybe_unused]] static constexpr int kBucketCount = 100;
    [[maybe_unused]] static constexpr int kOneSecInUS = 1000000;

    SkASSERT(apcb->fFinished);

    if (!apcb->fRenderPipeline) {
        // A null fRenderPipeline means Pipeline creation failed
        return; // TODO: log failures to their own UMA stat
    }

    [[maybe_unused]] auto micros_since = [](skgpu::StdSteadyClock::time_point start) {
        skgpu::StdSteadyClock::duration elapsed = skgpu::StdSteadyClock::now() - start;
        return std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
    };

    if (apcb->fFromPrecompile) {
        SkASSERT(!apcb->fAsynchronous);     // precompile is done synchronously on a thread
        SK_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
            "Graphite.PipelineCreationTimes.Precompile",
            micros_since(apcb->fStartTime),
            /* minUSec= */ 1,
            /* maxUSec= */ kOneSecInUS,
            kBucketCount);
    } else if (apcb->fAsynchronous) {
        SK_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
            "Graphite.PipelineCreationTimes.Asynchronous",
            micros_since(apcb->fStartTime),
            /* minUSec= */ 1,
            /* maxUSec= */ kOneSecInUS,
            kBucketCount);
    } else {
        SK_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
            "Graphite.PipelineCreationTimes.Synchronous",
            micros_since(apcb->fStartTime),
            /* minUSec= */ 1,
            /* maxUSec= */ kOneSecInUS,
            kBucketCount);
    }
#endif // SK_HISTOGRAMS_ENABLED
}

} // anonymous namespace

#if defined(__EMSCRIPTEN__)
// For wasm, we don't use async compilation.
struct DawnGraphicsPipeline::AsyncPipelineCreation : public AsyncPipelineCreationBase {
    AsyncPipelineCreation(const UniqueKey& key) : AsyncPipelineCreationBase(key) {}
};
#else
struct DawnGraphicsPipeline::AsyncPipelineCreation : public AsyncPipelineCreationBase {
    AsyncPipelineCreation(const UniqueKey& key) : AsyncPipelineCreationBase(key) {}

    wgpu::Future fFuture;
};
#endif

// static
sk_sp<DawnGraphicsPipeline> DawnGraphicsPipeline::Make(
        const DawnSharedContext* sharedContext,
        const RuntimeEffectDictionary* runtimeDict,
        const UniqueKey& pipelineKey,
        const GraphicsPipelineDesc& pipelineDesc,
        const RenderPassDesc& renderPassDesc,
        SkEnumBitMask<PipelineCreationFlags> pipelineCreationFlags,
        uint32_t compilationID) {
    const DawnCaps& caps = *static_cast<const DawnCaps*>(sharedContext->caps());
    const auto& device = sharedContext->device();

    SkSL::Program::Interface vsInterface, fsInterface;

    SkSL::ProgramSettings settings;
    settings.fSharpenTextures = true;
    settings.fForceNoRTFlip = true;
    settings.fForceHighPrecision = !caps.supportsHalfPrecision();

    ShaderErrorHandler* errorHandler = caps.shaderErrorHandler();

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

    SkSL::NativeShader vsCode, fsCode;
    wgpu::ShaderModule fsModule, vsModule;

    // Some steps just render depth buffer but not color buffer, so the fragment
    // shader is null.
    UniquePaintParamsID paintID = pipelineDesc.paintParamsID();

    skia_private::TArray<SamplerDesc>* samplerDescArrPtr = nullptr;
#if !defined(__EMSCRIPTEN__)
    skia_private::TArray<SamplerDesc> samplerDescArr {};
    samplerDescArrPtr = &samplerDescArr;
#endif

    std::unique_ptr<ShaderInfo> shaderInfo =
            ShaderInfo::Make(&caps,
                             sharedContext->shaderCodeDictionary(),
                             runtimeDict,
                             renderPassDesc,
                             step,
                             paintID,
                             samplerDescArrPtr);

    const std::string& fsSkSL = shaderInfo->fragmentSkSL();
    const BlendInfo& blendInfo = shaderInfo->blendInfo();
    const int numTexturesAndSamplers = shaderInfo->numFragmentTexturesAndSamplers();

    const bool hasFragmentSkSL = !fsSkSL.empty();
    if (hasFragmentSkSL) {
        if (!skgpu::SkSLToWGSL(caps.shaderCaps(),
                               fsSkSL,
                               SkSL::ProgramKind::kGraphiteFragment,
                               settings,
                               &fsCode,
                               &fsInterface,
                               errorHandler)) {
            return {};
        }
        if (!DawnCompileWGSLShaderModule(sharedContext, shaderInfo->fsLabel().c_str(), fsCode,
                                         &fsModule, errorHandler)) {
            return {};
        }
    }

    const std::string& vsSkSL = shaderInfo->vertexSkSL();
    if (!skgpu::SkSLToWGSL(caps.shaderCaps(),
                           vsSkSL,
                           SkSL::ProgramKind::kGraphiteVertex,
                           settings,
                           &vsCode,
                           &vsInterface,
                           errorHandler)) {
        return {};
    }
    if (!DawnCompileWGSLShaderModule(sharedContext, shaderInfo->vsLabel().c_str(), vsCode,
                                     &vsModule, errorHandler)) {
        return {};
    }

    wgpu::RenderPipelineDescriptor descriptor;
    // Always set the label for pipelines, dawn may need it for tracing.
    descriptor.label = shaderInfo->pipelineLabel().c_str();

    // Fragment state
    skgpu::BlendEquation equation = blendInfo.fEquation;
    skgpu::BlendCoeff srcCoeff = blendInfo.fSrcBlend;
    skgpu::BlendCoeff dstCoeff = blendInfo.fDstBlend;
    bool blendOn = !skgpu::BlendShouldDisable(equation, srcCoeff, dstCoeff);

    wgpu::BlendState blend;
    if (blendOn) {
        blend.color.operation = blend_equation_to_dawn_blend_op(equation);
        blend.color.srcFactor = blend_coeff_to_dawn_blend(caps, srcCoeff);
        blend.color.dstFactor = blend_coeff_to_dawn_blend(caps, dstCoeff);
        blend.alpha.operation = blend_equation_to_dawn_blend_op(equation);
        blend.alpha.srcFactor = blend_coeff_to_dawn_blend_for_alpha(caps, srcCoeff);
        blend.alpha.dstFactor = blend_coeff_to_dawn_blend_for_alpha(caps, dstCoeff);
    }

    wgpu::ColorTargetState colorTarget;
    colorTarget.format = TextureFormatToDawnFormat(renderPassDesc.fColorAttachment.fFormat);
    colorTarget.blend = blendOn ? &blend : nullptr;
    colorTarget.writeMask = blendInfo.fWritesColor && hasFragmentSkSL ? wgpu::ColorWriteMask::All
                                                                      : wgpu::ColorWriteMask::None;

#if !defined(__EMSCRIPTEN__)
    const bool loadMsaaFromResolve =
            renderPassDesc.fColorResolveAttachment.fFormat != TextureFormat::kUnsupported &&
            renderPassDesc.fColorResolveAttachment.fLoadOp == LoadOp::kLoad;
    // Special case: a render pass loading resolve texture requires additional settings for the
    // pipeline to make it compatible.
    wgpu::ColorTargetStateExpandResolveTextureDawn pipelineMSAALoadResolveTextureDesc;
    if (loadMsaaFromResolve && sharedContext->dawnCaps()->loadOpAffectsMSAAPipelines()) {
        SkASSERT(device.HasFeature(wgpu::FeatureName::DawnLoadResolveTexture));
        colorTarget.nextInChain = &pipelineMSAALoadResolveTextureDesc;
        pipelineMSAALoadResolveTextureDesc.enabled = true;
    }
#endif

    wgpu::FragmentState fragment;
    // Dawn doesn't allow having a color attachment but without fragment shader, so have to use a
    // noop fragment shader, if fragment shader is null.
    fragment.module = hasFragmentSkSL ? std::move(fsModule) : sharedContext->noopFragment();
    fragment.entryPoint = "main";
    fragment.constantCount = 0;
    fragment.constants = nullptr;
    fragment.targetCount = 1;
    fragment.targets = &colorTarget;
    descriptor.fragment = &fragment;

    // Depth stencil state
    const auto& depthStencilSettings = shaderInfo->depthStencilSettings();

    TextureFormat dsFormat = renderPassDesc.fDepthStencilAttachment.fFormat;
    SkASSERT(dsFormat != TextureFormat::kUnsupported || !depthStencilSettings);

    wgpu::DepthStencilState depthStencil;
    if (dsFormat != TextureFormat::kUnsupported) {
        SkASSERT(TextureFormatIsDepthOrStencil(dsFormat));
        depthStencil.format = TextureFormatToDawnFormat(dsFormat);

        if (depthStencilSettings.depthEnabled()) {
            SkASSERT(TextureFormatHasDepth(dsFormat));
            depthStencil.depthWriteEnabled = depthStencilSettings.fDepthWriteEnabled;
            depthStencil.depthCompare = compare_op_to_dawn(depthStencilSettings.fDepthCompareOp);
        }

        if (depthStencilSettings.stencilEnabled()) {
            SkASSERT(TextureFormatHasStencil(dsFormat));
            depthStencil.stencilFront = stencil_face_to_dawn(depthStencilSettings.fFrontStencil);
            depthStencil.stencilBack = stencil_face_to_dawn(depthStencilSettings.fBackStencil);
            depthStencil.stencilReadMask = depthStencilSettings.fStencilReadMask;
            depthStencil.stencilWriteMask = depthStencilSettings.fStencilWriteMask;
            // NOTE: fStencilReferenceValue is dynamic state and set on the render encoder
        }

        descriptor.depthStencil = &depthStencil;
    }

    // Determine the BindGroupLayouts that will be used to make up the pipeline layout.
    BindGroupLayouts groupLayouts;
    // If immutable samplers are used with this pipeline, they must be included in the pipeline
    // layout and passed in to the pipline constructor for lifetime management.
    skia_private::TArray<sk_sp<DawnSampler>> immutableSamplers;
    {
        wgpu::ShaderStage storageVisibility = wgpu::ShaderStage::None;
        if (shaderInfo->vsUsesStorage()) {
            storageVisibility |= wgpu::ShaderStage::Vertex;
        }
        if (shaderInfo->fsUsesStorage()) {
            storageVisibility |= wgpu::ShaderStage::Fragment;
        }
        groupLayouts[0] = sharedContext->getUniformBuffersBindGroupLayout(storageVisibility);
        if (!groupLayouts[0]) {
            return {};
        }

        bool hasFragmentSamplers = hasFragmentSkSL && numTexturesAndSamplers > 0;
        if (hasFragmentSamplers) {
            // Check if we can optimize for the common case of a single texture + 1 dynamic sampler
            if (numTexturesAndSamplers == 2 &&
                !(samplerDescArrPtr && samplerDescArrPtr->at(0).isImmutable())) {
                groupLayouts[1] = sharedContext->getSingleTextureSamplerBindGroupLayout();
            } else {
                TArray<wgpu::BindGroupLayoutEntry> entries;
                entries.reset(numTexturesAndSamplers);

#if !defined(__EMSCRIPTEN__)
                // Static sampler layouts are passed into Dawn by address and therefore must stay
                // alive until the BindGroupLayoutDescriptor is created. So, store them outside of
                // the loop that iterates over each BindGroupLayoutEntry. Use a TBlockList so that
                // any append StaticSamplerBindingLayouts have a stable address in case we have to
                // grow the collection.
                SkTBlockList<wgpu::StaticSamplerBindingLayout, 1> staticSamplerLayouts;

                // Note that the number of samplers is equivalent to numTexturesAndSamplers / 2. So,
                // a sampler's index within any container that only pertains to sampler information
                // (as in, excludes textures) is equivalent to 1/2 of that sampler's binding index
                // within the BindGroupLayout. Assert that we have analyzed the appropriate number
                // of samplers by equating samplerDescArr size to sampler quantity.
                SkASSERT(samplerDescArrPtr && samplerDescArr.size() == numTexturesAndSamplers / 2);
                immutableSamplers.reset(samplerDescArr.size());
#endif

                for (int i = 0; i < numTexturesAndSamplers;) {
                    entries[i].binding = i;
                    entries[i].visibility = wgpu::ShaderStage::Fragment;
#if !defined(__EMSCRIPTEN__)
                    // Index of sampler information = 1/2 of cumulative texture and sampler index.
                    // If we have a non-default-initialized SamplerDesc at that index,
                    // fetch an immutable sampler that matches that description to include in the
                    // pipeline layout.
                    const SamplerDesc& samplerDesc = samplerDescArr.at(i/2);
                    if (samplerDesc.isImmutable()) {
                        DawnThreadSafeResourceProvider* resourceProvider =
                                sharedContext->threadSafeResourceProvider();
                        sk_sp<Sampler> immutableSampler =
                                resourceProvider->findOrCreateCompatibleSampler(samplerDesc);
                        if (!immutableSampler) {
                            SKIA_LOG_E("Failed to find/create immutable sampler for pipeline");
                            return {};
                        }
                        sk_sp<DawnSampler> dawnImmutableSampler = sk_ref_sp<DawnSampler>(
                                static_cast<DawnSampler*>(immutableSampler.get()));
                        SkASSERT(dawnImmutableSampler);

                        wgpu::StaticSamplerBindingLayout& immutableSamplerBinding =
                                staticSamplerLayouts.emplace_back();
                        immutableSamplerBinding.sampler = dawnImmutableSampler->dawnSampler();
                        // Static samplers sample from the subsequent texture in the BindGroupLayout
                        immutableSamplerBinding.sampledTextureBinding = i + 1;

                        immutableSamplers[i/2] = std::move(dawnImmutableSampler);
                        entries[i].nextInChain = &immutableSamplerBinding;
                    } else {
#endif
                        entries[i].sampler.type = wgpu::SamplerBindingType::Filtering;
#if !defined(__EMSCRIPTEN__)
                    }
#endif
                    ++i;

                    entries[i].binding = i;
                    entries[i].visibility = wgpu::ShaderStage::Fragment;
                    entries[i].texture.sampleType = wgpu::TextureSampleType::Float;
                    entries[i].texture.viewDimension = wgpu::TextureViewDimension::e2D;
                    entries[i].texture.multisampled = false;
                    ++i;
                }

                wgpu::BindGroupLayoutDescriptor groupLayoutDesc;
                if (sharedContext->caps()->setBackendLabels()) {
                    groupLayoutDesc.label = shaderInfo->vsLabel().c_str();
                }
                groupLayoutDesc.entryCount = entries.size();
                groupLayoutDesc.entries = entries.data();
                groupLayouts[1] = device.CreateBindGroupLayout(&groupLayoutDesc);
            }
            if (!groupLayouts[1]) {
                return {};
            }
        }

        wgpu::PipelineLayoutDescriptor layoutDesc;
        if (sharedContext->caps()->setBackendLabels()) {
            layoutDesc.label = shaderInfo->fsLabel().c_str();
        }
        layoutDesc.bindGroupLayoutCount =
            hasFragmentSamplers ? groupLayouts.size() : groupLayouts.size() - 1;
        layoutDesc.bindGroupLayouts = groupLayouts.data();
#if !defined(__EMSCRIPTEN__)
        if (sharedContext->caps()
                    ->resourceBindingRequirements()
                    .fUsePushConstantsForIntrinsicConstants) {
            layoutDesc.immediateSize = kIntrinsicUniformSize;
        }
#endif
        auto layout = device.CreatePipelineLayout(&layoutDesc);
        if (!layout) {
            return {};
        }
        descriptor.layout = std::move(layout);
    }

    // Vertex state
    std::array<wgpu::VertexBufferLayout, kNumVertexBuffers> vertexBufferLayouts;
    // Static data buffer layout
    TArray<wgpu::VertexAttribute> staticDataAttributes;
    {
        auto arrayStride = create_vertex_attributes(step->staticAttributes(),
                                                    0,
                                                    &staticDataAttributes);
        auto& layout = vertexBufferLayouts[kStaticDataBufferIndex];
        if (arrayStride) {
            layout.arrayStride = arrayStride;
            layout.stepMode = wgpu::VertexStepMode::Vertex;
            layout.attributeCount = staticDataAttributes.size();
            layout.attributes = staticDataAttributes.data();
        } else {
            layout.arrayStride = 0;
#if defined(__EMSCRIPTEN__)
            layout.stepMode = wgpu::VertexStepMode::VertexBufferNotUsed;
#else
            layout.stepMode = wgpu::VertexStepMode::Undefined;
#endif
            layout.attributeCount = 0;
            layout.attributes = nullptr;
        }
    }

    // Append data buffer layout
    TArray<wgpu::VertexAttribute> appendDataAttributes;
    {
        // Note: the shaderLocationOffset in this function call needs to be the staticAttributeSize
        auto arrayStride = create_vertex_attributes(shaderInfo->appendAttributes(),
                                                    step->staticAttributes().size(),
                                                    &appendDataAttributes);
        auto& layout = vertexBufferLayouts[kAppendDataBufferIndex];
        if (arrayStride) {
            layout.arrayStride = arrayStride;
            layout.stepMode = step->appendsVertices() ? wgpu::VertexStepMode::Vertex :
                                                        wgpu::VertexStepMode::Instance;
            layout.attributeCount = appendDataAttributes.size();
            layout.attributes = appendDataAttributes.data();
        } else {
            layout.arrayStride = 0;
#if defined(__EMSCRIPTEN__)
            layout.stepMode = wgpu::VertexStepMode::VertexBufferNotUsed;
#else
            layout.stepMode = wgpu::VertexStepMode::Undefined;
#endif
            layout.attributeCount = 0;
            layout.attributes = nullptr;
        }
    }

    auto& vertex = descriptor.vertex;
    vertex.module = std::move(vsModule);
    vertex.entryPoint = "main";
    vertex.constantCount = 0;
    vertex.constants = nullptr;
    vertex.bufferCount = vertexBufferLayouts.size();
    vertex.buffers = vertexBufferLayouts.data();

    // Other state
    descriptor.primitive.frontFace = wgpu::FrontFace::CCW;
    descriptor.primitive.cullMode = wgpu::CullMode::None;
    switch (step->primitiveType()) {
        case PrimitiveType::kTriangles:
            descriptor.primitive.topology = wgpu::PrimitiveTopology::TriangleList;
            break;
        case PrimitiveType::kTriangleStrip:
            descriptor.primitive.topology = wgpu::PrimitiveTopology::TriangleStrip;
            descriptor.primitive.stripIndexFormat = wgpu::IndexFormat::Uint16;
            break;
        case PrimitiveType::kPoints:
            descriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
            break;
    }

    // Multisampled state
    descriptor.multisample.count = (uint8_t) renderPassDesc.fSampleCount;
    descriptor.multisample.mask = 0xFFFFFFFF;
    descriptor.multisample.alphaToCoverageEnabled = false;

    const bool forPrecompilation =
            SkToBool(pipelineCreationFlags & PipelineCreationFlags::kForPrecompilation);
    // For Dawn, we want Precompilation to happen synchronously
    const bool useAsync = caps.useAsyncPipelineCreation() && !forPrecompilation;

    auto asyncCreation = std::make_unique<AsyncPipelineCreation>(pipelineKey);
#if SK_HISTOGRAMS_ENABLED
    asyncCreation->fStartTime = skgpu::StdSteadyClock::now();
    asyncCreation->fFromPrecompile = forPrecompilation;
    asyncCreation->fAsynchronous = useAsync;
#endif

    if (useAsync) {
#if defined(__EMSCRIPTEN__)
        // We shouldn't use CreateRenderPipelineAsync in wasm.
        SK_ABORT("CreateRenderPipelineAsync shouldn't be used in WASM");
#else
        asyncCreation->fFuture = device.CreateRenderPipelineAsync(
                &descriptor,
                wgpu::CallbackMode::WaitAnyOnly,
                [asyncCreationPtr = asyncCreation.get()](wgpu::CreatePipelineAsyncStatus status,
                                                         wgpu::RenderPipeline pipeline,
                                                         wgpu::StringView message) {
                    if (status != wgpu::CreatePipelineAsyncStatus::Success) {
                        asyncCreationPtr->fErrorMessage = std::string(message.data, message.length);
                        SKIA_LOG_E("Failed to create render pipeline (%d): %s",
                                    static_cast<int>(status),
                                    asyncCreationPtr->fErrorMessage.c_str());
                        // invalidate AsyncPipelineCreation pointer to signal that this pipeline has
                        // failed.
                        asyncCreationPtr->fRenderPipeline = nullptr;
                    } else {
                        asyncCreationPtr->fRenderPipeline = std::move(pipeline);
                    }

                    asyncCreationPtr->fFinished = true;

                    log_pipeline_creation(asyncCreationPtr);
                });
#endif
    } else {
        std::optional<DawnErrorChecker> errorChecker;
        if (sharedContext->dawnCaps()->allowScopedErrorChecks()) {
            errorChecker.emplace(sharedContext);
        }
        asyncCreation->fRenderPipeline = device.CreateRenderPipeline(&descriptor);
        asyncCreation->fFinished = true;

        if (errorChecker.has_value() && errorChecker->popErrorScopes() != DawnErrorType::kNoError) {
            asyncCreation->fRenderPipeline = nullptr;
        }

        // Fail ASAP for synchronous pipeline creation so it affects the Recording snap instead of
        // being detected later at insertRecording().
        if (!asyncCreation->fRenderPipeline) {
            return nullptr;
        }

        log_pipeline_creation(asyncCreation.get());
    }

    PipelineInfo pipelineInfo{ *shaderInfo, pipelineCreationFlags,
                               pipelineKey.hash(), compilationID };
#if defined(GPU_TEST_UTILS)
    pipelineInfo.fNativeVertexShader = std::move(vsCode.fText);
    pipelineInfo.fNativeFragmentShader = std::move(fsCode.fText);
#endif

    return sk_sp<DawnGraphicsPipeline>(
            new DawnGraphicsPipeline(sharedContext,
                                     pipelineInfo,
                                     shaderInfo->pipelineLabel(),
                                     std::move(asyncCreation),
                                     std::move(groupLayouts),
                                     step->primitiveType(),
                                     depthStencilSettings.fStencilReferenceValue,
                                     std::move(immutableSamplers)));
}

DawnGraphicsPipeline::DawnGraphicsPipeline(
        const skgpu::graphite::SharedContext* sharedContext,
        const PipelineInfo& pipelineInfo,
        std::string_view pipelineLabel,
        std::unique_ptr<AsyncPipelineCreation> asyncCreationInfo,
        BindGroupLayouts groupLayouts,
        PrimitiveType primitiveType,
        uint32_t refValue,
        skia_private::TArray<sk_sp<DawnSampler>> immutableSamplers)
    : GraphicsPipeline(sharedContext, pipelineInfo, pipelineLabel)
    , fAsyncPipelineCreation(std::move(asyncCreationInfo))
    , fGroupLayouts(std::move(groupLayouts))
    , fPrimitiveType(primitiveType)
    , fStencilReferenceValue(refValue)
    , fImmutableSamplers(std::move(immutableSamplers)) {
    // Update the newly-created underlying GPU object's label to match the Resource's
    this->synchronizeBackendLabel();
}

DawnGraphicsPipeline::~DawnGraphicsPipeline() {
    this->freeGpuData();
}

void DawnGraphicsPipeline::freeGpuData() {
    // Wait for async creation to finish before we can destroy this object.
    (void)this->dawnRenderPipeline();
    fAsyncPipelineCreation = nullptr;
}

std::optional<std::string> DawnGraphicsPipeline::didAsyncCompilationFail() const {
    if (fAsyncPipelineCreation &&
        fAsyncPipelineCreation->fFinished &&
        !fAsyncPipelineCreation->fRenderPipeline) {
        return fAsyncPipelineCreation->fErrorMessage.empty()
                       ? "Unknown error"
                       : fAsyncPipelineCreation->fErrorMessage;
    }
    return std::nullopt;
}

const wgpu::RenderPipeline& DawnGraphicsPipeline::dawnRenderPipeline() const {
    if (!fAsyncPipelineCreation) {
        static const wgpu::RenderPipeline kNullPipeline = nullptr;
        return kNullPipeline;
    }
    if (fAsyncPipelineCreation->fFinished) {
        return fAsyncPipelineCreation->fRenderPipeline;
    }
#if defined(__EMSCRIPTEN__)
    // We shouldn't use CreateRenderPipelineAsync in wasm.
    SK_ABORT("CreateRenderPipelineAsync shouldn't be used in WASM");
#else

#if defined(SK_PIPELINE_LIFETIME_LOGGING)
    TRACE_EVENT_INSTANT2("skia.gpu",
                         TRACE_STR_STATIC("WaitBeginN"),
                         TRACE_EVENT_SCOPE_THREAD,
                         "key", fAsyncPipelineCreation->fKey.hash(),
                         "compilationID", this->getPipelineInfo().fCompilationID);
#endif

    wgpu::FutureWaitInfo waitInfo{};
    waitInfo.future = fAsyncPipelineCreation->fFuture;
    const auto& instance = static_cast<const DawnSharedContext*>(sharedContext())->instance();

    [[maybe_unused]] auto status =
            instance.WaitAny(1, &waitInfo, /*timeoutNS=*/std::numeric_limits<uint64_t>::max());
    SkASSERT(status == wgpu::WaitStatus::Success);
    SkASSERT(waitInfo.completed);

#if defined(SK_PIPELINE_LIFETIME_LOGGING)
    TRACE_EVENT_INSTANT2("skia.gpu",
                         TRACE_STR_STATIC("WaitEndN"),
                         TRACE_EVENT_SCOPE_THREAD,
                         "key", fAsyncPipelineCreation->fKey.hash(),
                         "compilationID", this->getPipelineInfo().fCompilationID);
#endif

#endif

    return fAsyncPipelineCreation->fRenderPipeline;
}

} // namespace skgpu::graphite
