// Copyright 2020 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 <string>

#include "dawn/tests/DawnTest.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"

namespace {
struct CreatePipelineAsyncTask {
    wgpu::ComputePipeline computePipeline = nullptr;
    wgpu::RenderPipeline renderPipeline = nullptr;
    bool isCompleted = false;
    std::string message;
};
}  // anonymous namespace

class CreatePipelineAsyncTest : public DawnTest {
  protected:
    void ValidateCreateComputePipelineAsync(CreatePipelineAsyncTask* currentTask) {
        wgpu::BufferDescriptor bufferDesc;
        bufferDesc.size = sizeof(uint32_t);
        bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
        wgpu::Buffer ssbo = device.CreateBuffer(&bufferDesc);

        wgpu::CommandBuffer commands;
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();

            while (!currentTask->isCompleted) {
                WaitABit();
            }
            ASSERT_TRUE(currentTask->message.empty());
            ASSERT_NE(nullptr, currentTask->computePipeline.Get());
            wgpu::BindGroup bindGroup =
                utils::MakeBindGroup(device, currentTask->computePipeline.GetBindGroupLayout(0),
                                     {
                                         {0, ssbo, 0, sizeof(uint32_t)},
                                     });
            pass.SetBindGroup(0, bindGroup);
            pass.SetPipeline(currentTask->computePipeline);

            pass.DispatchWorkgroups(1);
            pass.End();

            commands = encoder.Finish();
        }

        queue.Submit(1, &commands);

        constexpr uint32_t kExpected = 1u;
        EXPECT_BUFFER_U32_EQ(kExpected, ssbo, 0);
    }

    void ValidateCreateComputePipelineAsync() { ValidateCreateComputePipelineAsync(&task); }

    void ValidateCreateRenderPipelineAsync(CreatePipelineAsyncTask* currentTask) {
        constexpr wgpu::TextureFormat kRenderAttachmentFormat = wgpu::TextureFormat::RGBA8Unorm;

        wgpu::TextureDescriptor textureDescriptor;
        textureDescriptor.size = {1, 1, 1};
        textureDescriptor.format = kRenderAttachmentFormat;
        textureDescriptor.usage =
            wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
        wgpu::Texture outputTexture = device.CreateTexture(&textureDescriptor);

        utils::ComboRenderPassDescriptor renderPassDescriptor({outputTexture.CreateView()});
        renderPassDescriptor.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
        renderPassDescriptor.cColorAttachments[0].clearValue = {1.f, 0.f, 0.f, 1.f};

        wgpu::CommandBuffer commands;
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder renderPassEncoder =
                encoder.BeginRenderPass(&renderPassDescriptor);

            while (!currentTask->isCompleted) {
                WaitABit();
            }
            ASSERT_TRUE(currentTask->message.empty());
            ASSERT_NE(nullptr, currentTask->renderPipeline.Get());

            renderPassEncoder.SetPipeline(currentTask->renderPipeline);
            renderPassEncoder.Draw(1);
            renderPassEncoder.End();
            commands = encoder.Finish();
        }

        queue.Submit(1, &commands);

        EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), outputTexture, 0, 0);
    }

    void ValidateCreateRenderPipelineAsync() { ValidateCreateRenderPipelineAsync(&task); }

    void DoCreateRenderPipelineAsync(
        const utils::ComboRenderPipelineDescriptor& renderPipelineDescriptor) {
        device.CreateRenderPipelineAsync(
            &renderPipelineDescriptor,
            [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline returnPipeline,
               const char* message, void* userdata) {
                EXPECT_EQ(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_Success,
                          status);

                CreatePipelineAsyncTask* task = static_cast<CreatePipelineAsyncTask*>(userdata);
                task->renderPipeline = wgpu::RenderPipeline::Acquire(returnPipeline);
                task->isCompleted = true;
                task->message = message;
            },
            &task);
    }

    CreatePipelineAsyncTask task;
};

// Verify the basic use of CreateComputePipelineAsync works on all backends.
TEST_P(CreatePipelineAsyncTest, BasicUseOfCreateComputePipelineAsync) {
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        struct SSBO {
            value : u32
        }
        @group(0) @binding(0) var<storage, read_write> ssbo : SSBO;

        @compute @workgroup_size(1) fn main() {
            ssbo.value = 1u;
        })");
    csDesc.compute.entryPoint = "main";

    device.CreateComputePipelineAsync(
        &csDesc,
        [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline returnPipeline,
           const char* message, void* userdata) {
            EXPECT_EQ(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_Success, status);

            CreatePipelineAsyncTask* task = static_cast<CreatePipelineAsyncTask*>(userdata);
            task->computePipeline = wgpu::ComputePipeline::Acquire(returnPipeline);
            task->isCompleted = true;
            task->message = message;
        },
        &task);

    ValidateCreateComputePipelineAsync();
}

// This is a regression test for a bug on the member "entryPoint" of FlatComputePipelineDescriptor.
TEST_P(CreatePipelineAsyncTest, ReleaseEntryPointAfterCreatComputePipelineAsync) {
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        struct SSBO {
            value : u32
        }
        @group(0) @binding(0) var<storage, read_write> ssbo : SSBO;

        @compute @workgroup_size(1) fn main() {
            ssbo.value = 1u;
        })");

    std::string entryPoint = "main";

    csDesc.compute.entryPoint = entryPoint.c_str();

    device.CreateComputePipelineAsync(
        &csDesc,
        [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline returnPipeline,
           const char* message, void* userdata) {
            EXPECT_EQ(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_Success, status);

            CreatePipelineAsyncTask* task = static_cast<CreatePipelineAsyncTask*>(userdata);
            task->computePipeline = wgpu::ComputePipeline::Acquire(returnPipeline);
            task->isCompleted = true;
            task->message = message;
        },
        &task);

    entryPoint = "";
    ValidateCreateComputePipelineAsync();
}

// Verify CreateComputePipelineAsync() works as expected when there is any error that happens during
// the creation of the compute pipeline. The SPEC requires that during the call of
// CreateComputePipelineAsync() any error won't be forwarded to the error scope / unhandled error
// callback.
TEST_P(CreatePipelineAsyncTest, CreateComputePipelineFailed) {
    DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("skip_validation"));

    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        struct SSBO {
            value : u32
        }
        @group(0) @binding(0) var<storage, read_write> ssbo : SSBO;

        @compute @workgroup_size(1) fn main() {
            ssbo.value = 1u;
        })");
    csDesc.compute.entryPoint = "main0";

    device.CreateComputePipelineAsync(
        &csDesc,
        [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline returnPipeline,
           const char* message, void* userdata) {
            EXPECT_EQ(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_Error, status);

            CreatePipelineAsyncTask* task = static_cast<CreatePipelineAsyncTask*>(userdata);
            task->computePipeline = wgpu::ComputePipeline::Acquire(returnPipeline);
            task->isCompleted = true;
            task->message = message;
        },
        &task);

    while (!task.isCompleted) {
        WaitABit();
    }

    ASSERT_FALSE(task.message.empty());
    ASSERT_EQ(nullptr, task.computePipeline.Get());
}

// Verify the basic use of CreateRenderPipelineAsync() works on all backends.
TEST_P(CreatePipelineAsyncTest, BasicUseOfCreateRenderPipelineAsync) {
    constexpr wgpu::TextureFormat kRenderAttachmentFormat = wgpu::TextureFormat::RGBA8Unorm;

    utils::ComboRenderPipelineDescriptor renderPipelineDescriptor;
    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        @vertex fn main() -> @builtin(position) vec4<f32> {
            return vec4<f32>(0.0, 0.0, 0.0, 1.0);
        })");
    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        @fragment fn main() -> @location(0) vec4<f32> {
            return vec4<f32>(0.0, 1.0, 0.0, 1.0);
        })");
    renderPipelineDescriptor.vertex.module = vsModule;
    renderPipelineDescriptor.cFragment.module = fsModule;
    renderPipelineDescriptor.cTargets[0].format = kRenderAttachmentFormat;
    renderPipelineDescriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;

    DoCreateRenderPipelineAsync(renderPipelineDescriptor);

    ValidateCreateRenderPipelineAsync();
}

// Verify the render pipeline created with CreateRenderPipelineAsync() still works when the entry
// points are released after the creation of the render pipeline.
TEST_P(CreatePipelineAsyncTest, ReleaseEntryPointsAfterCreateRenderPipelineAsync) {
    constexpr wgpu::TextureFormat kRenderAttachmentFormat = wgpu::TextureFormat::RGBA8Unorm;

    utils::ComboRenderPipelineDescriptor renderPipelineDescriptor;
    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        @vertex fn main() -> @builtin(position) vec4<f32> {
            return vec4<f32>(0.0, 0.0, 0.0, 1.0);
        })");
    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        @fragment fn main() -> @location(0) vec4<f32> {
            return vec4<f32>(0.0, 1.0, 0.0, 1.0);
        })");
    renderPipelineDescriptor.vertex.module = vsModule;
    renderPipelineDescriptor.cFragment.module = fsModule;
    renderPipelineDescriptor.cTargets[0].format = kRenderAttachmentFormat;
    renderPipelineDescriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;

    std::string vertexEntryPoint = "main";
    std::string fragmentEntryPoint = "main";
    renderPipelineDescriptor.vertex.entryPoint = vertexEntryPoint.c_str();
    renderPipelineDescriptor.cFragment.entryPoint = fragmentEntryPoint.c_str();

    DoCreateRenderPipelineAsync(renderPipelineDescriptor);

    vertexEntryPoint = "";
    fragmentEntryPoint = "";

    wgpu::TextureDescriptor textureDescriptor;
    textureDescriptor.size = {1, 1, 1};
    textureDescriptor.format = kRenderAttachmentFormat;
    textureDescriptor.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
    wgpu::Texture outputTexture = device.CreateTexture(&textureDescriptor);

    utils::ComboRenderPassDescriptor renderPassDescriptor({outputTexture.CreateView()});
    renderPassDescriptor.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
    renderPassDescriptor.cColorAttachments[0].clearValue = {1.f, 0.f, 0.f, 1.f};

    wgpu::CommandBuffer commands;
    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder renderPassEncoder = encoder.BeginRenderPass(&renderPassDescriptor);

        while (!task.isCompleted) {
            WaitABit();
        }
        ASSERT_TRUE(task.message.empty());
        ASSERT_NE(nullptr, task.renderPipeline.Get());

        renderPassEncoder.SetPipeline(task.renderPipeline);
        renderPassEncoder.Draw(1);
        renderPassEncoder.End();
        commands = encoder.Finish();
    }

    queue.Submit(1, &commands);

    EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), outputTexture, 0, 0);
}

// Verify CreateRenderPipelineAsync() works as expected when there is any error that happens during
// the creation of the render pipeline. The SPEC requires that during the call of
// CreateRenderPipelineAsync() any error won't be forwarded to the error scope / unhandled error
// callback.
TEST_P(CreatePipelineAsyncTest, CreateRenderPipelineFailed) {
    DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("skip_validation"));

    constexpr wgpu::TextureFormat kRenderAttachmentFormat = wgpu::TextureFormat::Depth32Float;

    utils::ComboRenderPipelineDescriptor renderPipelineDescriptor;
    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        @vertex fn main() -> @builtin(position) vec4<f32> {
            return vec4<f32>(0.0, 0.0, 0.0, 1.0);
        })");
    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        @fragment fn main() -> @location(0) vec4<f32> {
            return vec4<f32>(0.0, 1.0, 0.0, 1.0);
        })");
    renderPipelineDescriptor.vertex.module = vsModule;
    renderPipelineDescriptor.cFragment.module = fsModule;
    renderPipelineDescriptor.cTargets[0].format = kRenderAttachmentFormat;
    renderPipelineDescriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;

    device.CreateRenderPipelineAsync(
        &renderPipelineDescriptor,
        [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline returnPipeline,
           const char* message, void* userdata) {
            EXPECT_EQ(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_Error, status);

            CreatePipelineAsyncTask* task = static_cast<CreatePipelineAsyncTask*>(userdata);
            task->renderPipeline = wgpu::RenderPipeline::Acquire(returnPipeline);
            task->isCompleted = true;
            task->message = message;
        },
        &task);

    while (!task.isCompleted) {
        WaitABit();
    }

    ASSERT_FALSE(task.message.empty());
    ASSERT_EQ(nullptr, task.computePipeline.Get());
}

// Verify there is no error when the device is released before the callback of
// CreateComputePipelineAsync() is called.
TEST_P(CreatePipelineAsyncTest, ReleaseDeviceBeforeCallbackOfCreateComputePipelineAsync) {
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        @compute @workgroup_size(1) fn main() {
        })");
    csDesc.compute.entryPoint = "main";

    device.CreateComputePipelineAsync(
        &csDesc,
        [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline returnPipeline,
           const char* message, void* userdata) {
            EXPECT_EQ(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_DeviceDestroyed,
                      status);

            CreatePipelineAsyncTask* task = static_cast<CreatePipelineAsyncTask*>(userdata);
            task->computePipeline = wgpu::ComputePipeline::Acquire(returnPipeline);
            task->isCompleted = true;
            task->message = message;
        },
        &task);
}

// Verify there is no error when the device is released before the callback of
// CreateRenderPipelineAsync() is called.
TEST_P(CreatePipelineAsyncTest, ReleaseDeviceBeforeCallbackOfCreateRenderPipelineAsync) {
    utils::ComboRenderPipelineDescriptor renderPipelineDescriptor;
    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        @vertex fn main() -> @builtin(position) vec4<f32> {
            return vec4<f32>(0.0, 0.0, 0.0, 1.0);
        })");
    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        @fragment fn main() -> @location(0) vec4<f32> {
            return vec4<f32>(0.0, 1.0, 0.0, 1.0);
        })");
    renderPipelineDescriptor.vertex.module = vsModule;
    renderPipelineDescriptor.cFragment.module = fsModule;
    renderPipelineDescriptor.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
    renderPipelineDescriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;

    device.CreateRenderPipelineAsync(
        &renderPipelineDescriptor,
        [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline returnPipeline,
           const char* message, void* userdata) {
            EXPECT_EQ(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_DeviceDestroyed,
                      status);

            CreatePipelineAsyncTask* task = static_cast<CreatePipelineAsyncTask*>(userdata);
            task->renderPipeline = wgpu::RenderPipeline::Acquire(returnPipeline);
            task->isCompleted = true;
            task->message = message;
        },
        &task);
}

// Verify there is no error when the device is destroyed before the callback of
// CreateComputePipelineAsync() is called.
TEST_P(CreatePipelineAsyncTest, DestroyDeviceBeforeCallbackOfCreateComputePipelineAsync) {
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        @compute @workgroup_size(1) fn main() {
        })");
    csDesc.compute.entryPoint = "main";

    device.CreateComputePipelineAsync(
        &csDesc,
        [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline returnPipeline,
           const char* message, void* userdata) {
            EXPECT_EQ(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_DeviceDestroyed,
                      status);

            CreatePipelineAsyncTask* task = static_cast<CreatePipelineAsyncTask*>(userdata);
            task->computePipeline = wgpu::ComputePipeline::Acquire(returnPipeline);
            task->isCompleted = true;
            task->message = message;
        },
        &task);
    DestroyDevice();
}

// Verify there is no error when the device is destroyed before the callback of
// CreateRenderPipelineAsync() is called.
TEST_P(CreatePipelineAsyncTest, DestroyDeviceBeforeCallbackOfCreateRenderPipelineAsync) {
    utils::ComboRenderPipelineDescriptor renderPipelineDescriptor;
    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        @vertex fn main() -> @builtin(position) vec4<f32> {
            return vec4<f32>(0.0, 0.0, 0.0, 1.0);
        })");
    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        @fragment fn main() -> @location(0) vec4<f32> {
            return vec4<f32>(0.0, 1.0, 0.0, 1.0);
        })");
    renderPipelineDescriptor.vertex.module = vsModule;
    renderPipelineDescriptor.cFragment.module = fsModule;
    renderPipelineDescriptor.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
    renderPipelineDescriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;

    device.CreateRenderPipelineAsync(
        &renderPipelineDescriptor,
        [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline returnPipeline,
           const char* message, void* userdata) {
            EXPECT_EQ(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_DeviceDestroyed,
                      status);

            CreatePipelineAsyncTask* task = static_cast<CreatePipelineAsyncTask*>(userdata);
            task->renderPipeline = wgpu::RenderPipeline::Acquire(returnPipeline);
            task->isCompleted = true;
            task->message = message;
        },
        &task);
    DestroyDevice();
}

// Verify the code path of CreateComputePipelineAsync() to directly return the compute pipeline
// object from cache works correctly.
TEST_P(CreatePipelineAsyncTest, CreateSameComputePipelineTwice) {
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        struct SSBO {
            value : u32
        }
        @group(0) @binding(0) var<storage, read_write> ssbo : SSBO;

        @compute @workgroup_size(1) fn main() {
            ssbo.value = 1u;
        })");
    csDesc.compute.entryPoint = "main";

    auto callback = [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline returnPipeline,
                       const char* message, void* userdata) {
        EXPECT_EQ(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_Success, status);

        CreatePipelineAsyncTask* task = static_cast<CreatePipelineAsyncTask*>(userdata);
        task->computePipeline = wgpu::ComputePipeline::Acquire(returnPipeline);
        task->isCompleted = true;
        task->message = message;
    };

    // Create a pipeline object and save it into anotherTask.computePipeline.
    CreatePipelineAsyncTask anotherTask;
    device.CreateComputePipelineAsync(&csDesc, callback, &anotherTask);
    while (!anotherTask.isCompleted) {
        WaitABit();
    }
    ASSERT_TRUE(anotherTask.message.empty());
    ASSERT_NE(nullptr, anotherTask.computePipeline.Get());

    // Create another pipeline object task.comnputepipeline with the same compute pipeline
    // descriptor used in the creation of anotherTask.computePipeline. This time the pipeline
    // object should be directly got from the pipeline object cache.
    device.CreateComputePipelineAsync(&csDesc, callback, &task);
    ValidateCreateComputePipelineAsync();
}

// Verify creating compute pipeline with same descriptor and CreateComputePipelineAsync() at the
// same time works correctly.
TEST_P(CreatePipelineAsyncTest, CreateSameComputePipelineTwiceAtSameTime) {
    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.buffer.type = wgpu::BufferBindingType::Storage;
    binding.visibility = wgpu::ShaderStage::Compute;

    wgpu::BindGroupLayoutDescriptor desc = {};
    desc.entryCount = 1;
    desc.entries = &binding;

    wgpu::BindGroupLayout bindGroupLayout = device.CreateBindGroupLayout(&desc);

    wgpu::PipelineLayoutDescriptor pipelineLayoutDesc = {};
    pipelineLayoutDesc.bindGroupLayoutCount = 1;
    pipelineLayoutDesc.bindGroupLayouts = &bindGroupLayout;

    wgpu::PipelineLayout pipelineLayout = device.CreatePipelineLayout(&pipelineLayoutDesc);

    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.layout = pipelineLayout;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        struct SSBO {
            value : u32
        }
        @group(0) @binding(0) var<storage, read_write> ssbo : SSBO;

        @compute @workgroup_size(1) fn main() {
            ssbo.value = 1u;
        })");
    csDesc.compute.entryPoint = "main";

    auto callback = [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline returnPipeline,
                       const char* message, void* userdata) {
        EXPECT_EQ(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_Success, status);

        CreatePipelineAsyncTask* task = static_cast<CreatePipelineAsyncTask*>(userdata);
        task->computePipeline = wgpu::ComputePipeline::Acquire(returnPipeline);
        task->isCompleted = true;
        task->message = message;
    };

    // Create two pipeline objects with same descriptor.
    CreatePipelineAsyncTask anotherTask;
    device.CreateComputePipelineAsync(&csDesc, callback, &task);
    device.CreateComputePipelineAsync(&csDesc, callback, &anotherTask);

    // Verify both task.computePipeline and anotherTask.computePipeline are created correctly.
    ValidateCreateComputePipelineAsync(&anotherTask);
    ValidateCreateComputePipelineAsync(&task);

    // Verify task.computePipeline and anotherTask.computePipeline are pointing to the same Dawn
    // object.
    if (!UsesWire()) {
        EXPECT_EQ(task.computePipeline.Get(), anotherTask.computePipeline.Get());
    }
}

// Verify the basic use of CreateRenderPipelineAsync() works on all backends.
TEST_P(CreatePipelineAsyncTest, CreateSameRenderPipelineTwiceAtSameTime) {
    constexpr wgpu::TextureFormat kRenderAttachmentFormat = wgpu::TextureFormat::RGBA8Unorm;

    utils::ComboRenderPipelineDescriptor renderPipelineDescriptor;
    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        @vertex fn main() -> @builtin(position) vec4<f32> {
            return vec4<f32>(0.0, 0.0, 0.0, 1.0);
        })");
    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        @fragment fn main() -> @location(0) vec4<f32> {
            return vec4<f32>(0.0, 1.0, 0.0, 1.0);
        })");
    renderPipelineDescriptor.vertex.module = vsModule;
    renderPipelineDescriptor.cFragment.module = fsModule;
    renderPipelineDescriptor.cTargets[0].format = kRenderAttachmentFormat;
    renderPipelineDescriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;

    auto callback = [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline returnPipeline,
                       const char* message, void* userdata) {
        EXPECT_EQ(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_Success, status);

        CreatePipelineAsyncTask* task = static_cast<CreatePipelineAsyncTask*>(userdata);
        task->renderPipeline = wgpu::RenderPipeline::Acquire(returnPipeline);
        task->isCompleted = true;
        task->message = message;
    };

    // Create two render pipelines with same descriptor.
    CreatePipelineAsyncTask anotherTask;
    device.CreateRenderPipelineAsync(&renderPipelineDescriptor, callback, &task);
    device.CreateRenderPipelineAsync(&renderPipelineDescriptor, callback, &anotherTask);

    // Verify task.renderPipeline and anotherTask.renderPipeline are both created correctly.
    ValidateCreateRenderPipelineAsync(&task);
    ValidateCreateRenderPipelineAsync(&anotherTask);

    // Verify task.renderPipeline and anotherTask.renderPipeline are pointing to the same Dawn
    // object.
    if (!UsesWire()) {
        EXPECT_EQ(task.renderPipeline.Get(), anotherTask.renderPipeline.Get());
    }
}

// Verify calling CreateRenderPipelineAsync() with valid VertexBufferLayouts works on all backends.
TEST_P(CreatePipelineAsyncTest, CreateRenderPipelineAsyncWithVertexBufferLayouts) {
    wgpu::TextureDescriptor textureDescriptor;
    textureDescriptor.size = {1, 1, 1};
    textureDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
    textureDescriptor.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
    wgpu::Texture renderTarget = device.CreateTexture(&textureDescriptor);
    wgpu::TextureView renderTargetView = renderTarget.CreateView();

    utils::ComboRenderPassDescriptor renderPass({renderTargetView});
    {
        utils::ComboRenderPipelineDescriptor renderPipelineDescriptor;
        renderPipelineDescriptor.vertex.module = utils::CreateShaderModule(device, R"(
        struct VertexInput {
            @location(0) input0: u32,
            @location(1) input1: u32,
        }

        struct VertexOutput {
            @location(0) vertexColorOut: vec4<f32>,
            @builtin(position) position: vec4<f32>,
        }

        @vertex
        fn main(vertexInput : VertexInput) -> VertexOutput {
            var vertexOutput : VertexOutput;
            vertexOutput.position = vec4<f32>(0.0, 0.0, 0.0, 1.0);
            if (vertexInput.input0 == 1u && vertexInput.input1 == 2u) {
                vertexOutput.vertexColorOut = vec4<f32>(0.0, 1.0, 0.0, 1.0);
            } else {
                vertexOutput.vertexColorOut = vec4<f32>(1.0, 0.0, 0.0, 1.0);
            }
            return vertexOutput;
        })");
        renderPipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"(
        @fragment
        fn main(@location(0) fragColorIn : vec4<f32>) -> @location(0) vec4<f32> {
            return fragColorIn;
        })");

        renderPipelineDescriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
        renderPipelineDescriptor.cFragment.targetCount = 1;
        renderPipelineDescriptor.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;

        // Create a render pipeline with two VertexBufferLayouts
        renderPipelineDescriptor.vertex.buffers = renderPipelineDescriptor.cBuffers.data();
        renderPipelineDescriptor.vertex.bufferCount = 2;
        renderPipelineDescriptor.cBuffers[0].attributeCount = 1;
        renderPipelineDescriptor.cBuffers[0].attributes = &renderPipelineDescriptor.cAttributes[0];
        renderPipelineDescriptor.cAttributes[0].format = wgpu::VertexFormat::Uint32;
        renderPipelineDescriptor.cAttributes[0].shaderLocation = 0;
        renderPipelineDescriptor.cBuffers[1].attributeCount = 1;
        renderPipelineDescriptor.cBuffers[1].attributes = &renderPipelineDescriptor.cAttributes[1];
        renderPipelineDescriptor.cAttributes[1].format = wgpu::VertexFormat::Uint32;
        renderPipelineDescriptor.cAttributes[1].shaderLocation = 1;

        DoCreateRenderPipelineAsync(renderPipelineDescriptor);
    }

    wgpu::Buffer vertexBuffer1 = utils::CreateBufferFromData(
        device, wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::Vertex, {1u});
    wgpu::Buffer vertexBuffer2 = utils::CreateBufferFromData(
        device, wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::Vertex, {2u});

    // Do the draw call with the render pipeline
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    {
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);

        while (!task.isCompleted) {
            WaitABit();
        }
        ASSERT_TRUE(task.message.empty());
        ASSERT_NE(nullptr, task.renderPipeline.Get());
        pass.SetPipeline(task.renderPipeline);

        pass.SetVertexBuffer(0, vertexBuffer1);
        pass.SetVertexBuffer(1, vertexBuffer2);
        pass.Draw(1);
        pass.End();
    }

    wgpu::CommandBuffer commands = encoder.Finish();
    queue.Submit(1, &commands);

    // The color attachment will have the expected color when the vertex attribute values are
    // fetched correctly.
    EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderTarget, 0, 0);
}

// Verify calling CreateRenderPipelineAsync() with valid depthStencilState works on all backends.
TEST_P(CreatePipelineAsyncTest, CreateRenderPipelineAsyncWithDepthStencilState) {
    wgpu::TextureDescriptor textureDescriptor;
    textureDescriptor.size = {1, 1, 1};
    textureDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
    textureDescriptor.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
    wgpu::Texture renderTarget = device.CreateTexture(&textureDescriptor);
    wgpu::TextureView renderTargetView = renderTarget.CreateView();

    textureDescriptor.format = wgpu::TextureFormat::Depth24PlusStencil8;
    wgpu::Texture depthStencilTarget = device.CreateTexture(&textureDescriptor);
    wgpu::TextureView depthStencilView = depthStencilTarget.CreateView();

    // Clear the color attachment to green and the stencil aspect of the depth stencil attachment
    // to 0.
    utils::ComboRenderPassDescriptor renderPass({renderTargetView}, depthStencilView);
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
    renderPass.cColorAttachments[0].clearValue = {0.0, 1.0, 0.0, 1.0};
    renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Clear;
    renderPass.cDepthStencilAttachmentInfo.stencilClearValue = 0u;

    wgpu::RenderPipeline pipeline;
    {
        utils::ComboRenderPipelineDescriptor renderPipelineDescriptor;
        renderPipelineDescriptor.vertex.module = utils::CreateShaderModule(device, R"(
        @vertex
        fn main() -> @builtin(position) vec4<f32> {
            return vec4<f32>(0.0, 0.0, 0.0, 1.0);
        })");
        renderPipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"(
        @fragment
        fn main() -> @location(0) vec4<f32> {
            return vec4<f32>(1.0, 0.0, 0.0, 1.0);
        })");

        renderPipelineDescriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
        renderPipelineDescriptor.cFragment.targetCount = 1;
        renderPipelineDescriptor.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;

        // Create a render pipeline with stencil compare function "Equal".
        renderPipelineDescriptor.depthStencil = &renderPipelineDescriptor.cDepthStencil;
        renderPipelineDescriptor.cDepthStencil.stencilFront.compare = wgpu::CompareFunction::Equal;

        DoCreateRenderPipelineAsync(renderPipelineDescriptor);
    }

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    {
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);

        while (!task.isCompleted) {
            WaitABit();
        }
        ASSERT_TRUE(task.message.empty());
        ASSERT_NE(nullptr, task.renderPipeline.Get());
        pass.SetPipeline(task.renderPipeline);

        // The stencil reference is set to 1, so there should be no pixel that can pass the stencil
        // test.
        pass.SetStencilReference(1);

        pass.Draw(1);
        pass.End();
    }

    wgpu::CommandBuffer commands = encoder.Finish();
    queue.Submit(1, &commands);

    // The color in the color attachment should not be changed after the draw call as no pixel can
    // pass the stencil test.
    EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderTarget, 0, 0);
}

// Verify calling CreateRenderPipelineAsync() with multisample.Count > 1 works on all backends.
TEST_P(CreatePipelineAsyncTest, CreateRenderPipelineWithMultisampleState) {
    wgpu::TextureDescriptor textureDescriptor;
    textureDescriptor.size = {1, 1, 1};
    textureDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
    textureDescriptor.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
    wgpu::Texture resolveTarget = device.CreateTexture(&textureDescriptor);
    wgpu::TextureView resolveTargetView = resolveTarget.CreateView();

    textureDescriptor.sampleCount = 4;
    wgpu::Texture renderTarget = device.CreateTexture(&textureDescriptor);
    wgpu::TextureView renderTargetView = renderTarget.CreateView();

    // Set the multi-sampled render target, its resolve target to render pass and clear color to
    // (1, 0, 0, 1).
    utils::ComboRenderPassDescriptor renderPass({renderTargetView});
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
    renderPass.cColorAttachments[0].clearValue = {1.0, 0.0, 0.0, 1.0};
    renderPass.cColorAttachments[0].resolveTarget = resolveTargetView;

    wgpu::RenderPipeline pipeline;
    {
        utils::ComboRenderPipelineDescriptor renderPipelineDescriptor;
        renderPipelineDescriptor.vertex.module = utils::CreateShaderModule(device, R"(
        @vertex
        fn main() -> @builtin(position) vec4<f32> {
            return vec4<f32>(0.0, 0.0, 0.0, 1.0);
        })");
        renderPipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"(
        @fragment
        fn main() -> @location(0) vec4<f32> {
            return vec4<f32>(0.0, 1.0, 0.0, 1.0);
        })");

        renderPipelineDescriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
        renderPipelineDescriptor.cFragment.targetCount = 1;
        renderPipelineDescriptor.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;

        // Create a render pipeline with multisample.count == 4.
        renderPipelineDescriptor.multisample.count = 4;

        DoCreateRenderPipelineAsync(renderPipelineDescriptor);
    }

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    {
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);

        while (!task.isCompleted) {
            WaitABit();
        }
        ASSERT_TRUE(task.message.empty());
        ASSERT_NE(nullptr, task.renderPipeline.Get());
        pass.SetPipeline(task.renderPipeline);

        pass.Draw(6);
        pass.End();
    }

    wgpu::CommandBuffer commands = encoder.Finish();
    queue.Submit(1, &commands);

    // The color in resolveTarget should be the expected color (0, 1, 0, 1).
    EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), resolveTarget, 0, 0);
}

// Verify calling CreateRenderPipelineAsync() with valid BlendState works on all backends.
TEST_P(CreatePipelineAsyncTest, CreateRenderPipelineAsyncWithBlendState) {
    DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("disable_indexed_draw_buffers"));

    std::array<wgpu::Texture, 2> renderTargets;
    std::array<wgpu::TextureView, 2> renderTargetViews;

    {
        wgpu::TextureDescriptor textureDescriptor;
        textureDescriptor.size = {1, 1, 1};
        textureDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
        textureDescriptor.usage =
            wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;

        for (uint32_t i = 0; i < renderTargets.size(); ++i) {
            renderTargets[i] = device.CreateTexture(&textureDescriptor);
            renderTargetViews[i] = renderTargets[i].CreateView();
        }
    }

    // Prepare two color attachments
    utils::ComboRenderPassDescriptor renderPass({renderTargetViews[0], renderTargetViews[1]});
    renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
    renderPass.cColorAttachments[0].clearValue = {0.2, 0.0, 0.0, 0.2};
    renderPass.cColorAttachments[1].loadOp = wgpu::LoadOp::Clear;
    renderPass.cColorAttachments[1].clearValue = {0.0, 0.2, 0.0, 0.2};

    {
        utils::ComboRenderPipelineDescriptor renderPipelineDescriptor;
        renderPipelineDescriptor.vertex.module = utils::CreateShaderModule(device, R"(
        @vertex
        fn main() -> @builtin(position) vec4<f32> {
            return vec4<f32>(0.0, 0.0, 0.0, 1.0);
        })");
        renderPipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"(
         struct FragmentOut {
            @location(0) fragColor0 : vec4<f32>,
            @location(1) fragColor1 : vec4<f32>,
        }

        @fragment fn main() -> FragmentOut {
            var output : FragmentOut;
            output.fragColor0 = vec4<f32>(0.4, 0.0, 0.0, 0.4);
            output.fragColor1 = vec4<f32>(0.0, 1.0, 0.0, 1.0);
            return output;
        })");

        renderPipelineDescriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;

        // Create a render pipeline with blending states
        renderPipelineDescriptor.cFragment.targetCount = renderTargets.size();

        // The blend operation for the first render target is "add".
        wgpu::BlendComponent blendComponent0;
        blendComponent0.operation = wgpu::BlendOperation::Add;
        blendComponent0.srcFactor = wgpu::BlendFactor::One;
        blendComponent0.dstFactor = wgpu::BlendFactor::One;

        wgpu::BlendState blend0;
        blend0.color = blendComponent0;
        blend0.alpha = blendComponent0;

        // The blend operation for the first render target is "subtract".
        wgpu::BlendComponent blendComponent1;
        blendComponent1.operation = wgpu::BlendOperation::Subtract;
        blendComponent1.srcFactor = wgpu::BlendFactor::One;
        blendComponent1.dstFactor = wgpu::BlendFactor::One;

        wgpu::BlendState blend1;
        blend1.color = blendComponent1;
        blend1.alpha = blendComponent1;

        renderPipelineDescriptor.cTargets[0].blend = &blend0;
        renderPipelineDescriptor.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
        renderPipelineDescriptor.cTargets[1].blend = &blend1;
        renderPipelineDescriptor.cTargets[1].format = wgpu::TextureFormat::RGBA8Unorm;

        DoCreateRenderPipelineAsync(renderPipelineDescriptor);
    }

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    {
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);

        while (!task.isCompleted) {
            WaitABit();
        }
        ASSERT_TRUE(task.message.empty());
        ASSERT_NE(nullptr, task.renderPipeline.Get());
        pass.SetPipeline(task.renderPipeline);

        pass.Draw(1);
        pass.End();
    }

    wgpu::CommandBuffer commands = encoder.Finish();
    queue.Submit(1, &commands);

    // When the blend states are all set correctly, the color of renderTargets[0] should be
    // (0.6, 0, 0, 0.6) = colorAttachment0.clearValue + (0.4, 0.0, 0.0, 0.4), and the color of
    // renderTargets[1] should be (0.8, 0, 0, 0.8) = (1, 0, 0, 1) - colorAttachment1.clearValue.
    RGBA8 expected0 = {153, 0, 0, 153};
    RGBA8 expected1 = {0, 204, 0, 204};
    EXPECT_PIXEL_RGBA8_EQ(expected0, renderTargets[0], 0, 0);
    EXPECT_PIXEL_RGBA8_EQ(expected1, renderTargets[1], 0, 0);
}

DAWN_INSTANTIATE_TEST(CreatePipelineAsyncTest,
                      D3D12Backend(),
                      MetalBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      VulkanBackend());
