// 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 "tests/unittests/validation/ValidationTest.h"

#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/WGPUHelpers.h"

namespace {

    class ResourceUsageTrackingTest : public ValidationTest {
      protected:
        wgpu::Buffer CreateBuffer(uint64_t size, wgpu::BufferUsage usage) {
            wgpu::BufferDescriptor descriptor;
            descriptor.size = size;
            descriptor.usage = usage;

            return device.CreateBuffer(&descriptor);
        }

        wgpu::Texture CreateTexture(wgpu::TextureUsage usage) {
            wgpu::TextureDescriptor descriptor;
            descriptor.dimension = wgpu::TextureDimension::e2D;
            descriptor.size = {1, 1, 1};
            descriptor.sampleCount = 1;
            descriptor.mipLevelCount = 1;
            descriptor.usage = usage;
            descriptor.format = kFormat;

            return device.CreateTexture(&descriptor);
        }

        // Note that it is valid to bind any bind groups for indices that the pipeline doesn't use.
        // We create a no-op render or compute pipeline without any bindings, and set bind groups
        // in the caller, so it is always correct for binding validation between bind groups and
        // pipeline. But those bind groups in caller can be used for validation for other purposes.
        wgpu::RenderPipeline CreateNoOpRenderPipeline() {
            wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
                [[stage(vertex)]] fn main() -> [[builtin(position)]] vec4<f32> {
                    return vec4<f32>();
                })");

            wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
                [[stage(fragment)]] fn main() {
                })");
            utils::ComboRenderPipelineDescriptor pipelineDescriptor;
            pipelineDescriptor.vertex.module = vsModule;
            pipelineDescriptor.cFragment.module = fsModule;
            pipelineDescriptor.layout = utils::MakeBasicPipelineLayout(device, nullptr);
            return device.CreateRenderPipeline(&pipelineDescriptor);
        }

        wgpu::ComputePipeline CreateNoOpComputePipeline(std::vector<wgpu::BindGroupLayout> bgls) {
            wgpu::ShaderModule csModule = utils::CreateShaderModule(device, R"(
                [[stage(compute)]] fn main() {
                })");
            wgpu::ComputePipelineDescriptor pipelineDescriptor;
            pipelineDescriptor.layout = utils::MakePipelineLayout(device, std::move(bgls));
            pipelineDescriptor.compute.module = csModule;
            pipelineDescriptor.compute.entryPoint = "main";
            return device.CreateComputePipeline(&pipelineDescriptor);
        }

        static constexpr wgpu::TextureFormat kFormat = wgpu::TextureFormat::RGBA8Unorm;
    };

    // Test that using a single buffer in multiple read usages in the same pass is allowed.
    TEST_F(ResourceUsageTrackingTest, BufferWithMultipleReadUsage) {
        // Test render pass
        {
            // Create a buffer, and use the buffer as both vertex and index buffer.
            wgpu::Buffer buffer =
                CreateBuffer(4, wgpu::BufferUsage::Vertex | wgpu::BufferUsage::Index);

            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetIndexBuffer(buffer, wgpu::IndexFormat::Uint32);
            pass.SetVertexBuffer(0, buffer);
            pass.EndPass();
            encoder.Finish();
        }

        // Test compute pass
        {
            // Create buffer and bind group
            wgpu::Buffer buffer =
                CreateBuffer(4, wgpu::BufferUsage::Uniform | wgpu::BufferUsage::Storage);

            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Uniform},
                 {1, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::ReadOnlyStorage}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, buffer}, {1, buffer}});

            // Use the buffer as both uniform and readonly storage buffer in compute pass.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetBindGroup(0, bg);
            pass.EndPass();
            encoder.Finish();
        }
    }

    // Test that it is invalid to use the same buffer as both readable and writable in the same
    // render pass. It is invalid in the same dispatch in compute pass.
    TEST_F(ResourceUsageTrackingTest, BufferWithReadAndWriteUsage) {
        // test render pass
        {
            // Create buffer and bind group
            wgpu::Buffer buffer =
                CreateBuffer(4, wgpu::BufferUsage::Storage | wgpu::BufferUsage::Index);

            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, buffer}});

            // It is invalid to use the buffer as both index and storage in render pass
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetIndexBuffer(buffer, wgpu::IndexFormat::Uint32);
            pass.SetBindGroup(0, bg);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // test compute pass
        {
            // Create buffer and bind group
            wgpu::Buffer buffer = CreateBuffer(512, wgpu::BufferUsage::Storage);

            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage},
                 {1, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::ReadOnlyStorage}});
            wgpu::BindGroup bg =
                utils::MakeBindGroup(device, bgl, {{0, buffer, 0, 4}, {1, buffer, 256, 4}});

            // Create a no-op compute pipeline
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({bgl});

            // It is valid to use the buffer as both storage and readonly storage in a single
            // compute pass if dispatch command is not called.
            {
                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
                wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
                pass.SetBindGroup(0, bg);
                pass.EndPass();
                encoder.Finish();
            }

            // It is invalid to use the buffer as both storage and readonly storage in a single
            // dispatch.
            {
                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
                wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
                pass.SetPipeline(cp);
                pass.SetBindGroup(0, bg);
                pass.Dispatch(1);
                pass.EndPass();
                ASSERT_DEVICE_ERROR(encoder.Finish());
            }
        }
    }

    // Test the use of a buffer as a storage buffer multiple times in the same synchronization
    // scope.
    TEST_F(ResourceUsageTrackingTest, BufferUsedAsStorageMultipleTimes) {
        // Create buffer and bind group
        wgpu::Buffer buffer = CreateBuffer(512, wgpu::BufferUsage::Storage);

        wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute,
                      wgpu::BufferBindingType::Storage},
                     {1, wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute,
                      wgpu::BufferBindingType::Storage}});
        wgpu::BindGroup bg =
            utils::MakeBindGroup(device, bgl, {{0, buffer, 0, 4}, {1, buffer, 256, 4}});

        // test render pass
        {
            // It is valid to use multiple storage usages on the same buffer in render pass
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetBindGroup(0, bg);
            pass.EndPass();
            encoder.Finish();
        }

        // test compute pass
        {
            // It is valid to use multiple storage usages on the same buffer in a dispatch
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({bgl});

            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetPipeline(cp);
            pass.SetBindGroup(0, bg);
            pass.Dispatch(1);
            pass.EndPass();
            encoder.Finish();
        }
    }

    // Test that using the same buffer as both readable and writable in different passes is allowed
    TEST_F(ResourceUsageTrackingTest, BufferWithReadAndWriteUsageInDifferentPasses) {
        // Test render pass
        {
            // Create buffers that will be used as index and storage buffers
            wgpu::Buffer buffer0 =
                CreateBuffer(4, wgpu::BufferUsage::Storage | wgpu::BufferUsage::Index);
            wgpu::Buffer buffer1 =
                CreateBuffer(4, wgpu::BufferUsage::Storage | wgpu::BufferUsage::Index);

            // Create bind groups to use the buffer as storage
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroup bg0 = utils::MakeBindGroup(device, bgl, {{0, buffer0}});
            wgpu::BindGroup bg1 = utils::MakeBindGroup(device, bgl, {{0, buffer1}});

            // Use these two buffers as both index and storage in different render passes
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);

            wgpu::RenderPassEncoder pass0 = encoder.BeginRenderPass(&dummyRenderPass);
            pass0.SetIndexBuffer(buffer0, wgpu::IndexFormat::Uint32);
            pass0.SetBindGroup(0, bg1);
            pass0.EndPass();

            wgpu::RenderPassEncoder pass1 = encoder.BeginRenderPass(&dummyRenderPass);
            pass1.SetIndexBuffer(buffer1, wgpu::IndexFormat::Uint32);
            pass1.SetBindGroup(0, bg0);
            pass1.EndPass();

            encoder.Finish();
        }

        // Test compute pass
        {
            // Create buffer and bind groups that will be used as storage and uniform bindings
            wgpu::Buffer buffer =
                CreateBuffer(4, wgpu::BufferUsage::Storage | wgpu::BufferUsage::Uniform);

            wgpu::BindGroupLayout bgl0 = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Uniform}});
            wgpu::BindGroup bg0 = utils::MakeBindGroup(device, bgl0, {{0, buffer}});
            wgpu::BindGroup bg1 = utils::MakeBindGroup(device, bgl1, {{0, buffer}});

            // Use the buffer as both storage and uniform in different compute passes
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();

            wgpu::ComputePassEncoder pass0 = encoder.BeginComputePass();
            pass0.SetBindGroup(0, bg0);
            pass0.EndPass();

            wgpu::ComputePassEncoder pass1 = encoder.BeginComputePass();
            pass1.SetBindGroup(1, bg1);
            pass1.EndPass();

            encoder.Finish();
        }

        // Test render pass and compute pass mixed together with resource dependency.
        {
            // Create buffer and bind groups that will be used as storage and uniform bindings
            wgpu::Buffer buffer = CreateBuffer(4, wgpu::BufferUsage::Storage);

            wgpu::BindGroupLayout bgl0 = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::ReadOnlyStorage}});
            wgpu::BindGroup bg0 = utils::MakeBindGroup(device, bgl0, {{0, buffer}});
            wgpu::BindGroup bg1 = utils::MakeBindGroup(device, bgl1, {{0, buffer}});

            // Use the buffer as storage and uniform in render pass and compute pass respectively
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();

            wgpu::ComputePassEncoder pass0 = encoder.BeginComputePass();
            pass0.SetBindGroup(0, bg0);
            pass0.EndPass();

            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass1 = encoder.BeginRenderPass(&dummyRenderPass);
            pass1.SetBindGroup(1, bg1);
            pass1.EndPass();

            encoder.Finish();
        }
    }

    // Test that it is invalid to use the same buffer as both readable and writable in different
    // draws in a single render pass. But it is valid in different dispatches in a single compute
    // pass.
    TEST_F(ResourceUsageTrackingTest, BufferWithReadAndWriteUsageInDifferentDrawsOrDispatches) {
        // Test render pass
        {
            // Create a buffer and a bind group
            wgpu::Buffer buffer =
                CreateBuffer(4, wgpu::BufferUsage::Storage | wgpu::BufferUsage::Index);
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, buffer}});

            // Create a no-op render pipeline.
            wgpu::RenderPipeline rp = CreateNoOpRenderPipeline();

            // It is not allowed to use the same buffer as both readable and writable in different
            // draws within the same render pass.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetPipeline(rp);

            pass.SetIndexBuffer(buffer, wgpu::IndexFormat::Uint32);
            pass.Draw(3);

            pass.SetBindGroup(0, bg);
            pass.Draw(3);

            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // test compute pass
        {
            // Create a buffer and bind groups
            wgpu::Buffer buffer = CreateBuffer(4, wgpu::BufferUsage::Storage);

            wgpu::BindGroupLayout bgl0 = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::ReadOnlyStorage}});
            wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroup bg0 = utils::MakeBindGroup(device, bgl0, {{0, buffer}});
            wgpu::BindGroup bg1 = utils::MakeBindGroup(device, bgl1, {{0, buffer}});

            // Create a no-op compute pipeline.
            wgpu::ComputePipeline cp0 = CreateNoOpComputePipeline({bgl0});
            wgpu::ComputePipeline cp1 = CreateNoOpComputePipeline({bgl1});

            // It is valid to use the same buffer as both readable and writable in different
            // dispatches within the same compute pass.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();

            pass.SetPipeline(cp0);
            pass.SetBindGroup(0, bg0);
            pass.Dispatch(1);

            pass.SetPipeline(cp1);
            pass.SetBindGroup(0, bg1);
            pass.Dispatch(1);

            pass.EndPass();
            encoder.Finish();
        }
    }

    // Test that it is invalid to use the same buffer as both readable and writable in a single
    // draw or dispatch.
    TEST_F(ResourceUsageTrackingTest, BufferWithReadAndWriteUsageInSingleDrawOrDispatch) {
        // Test render pass
        {
            // Create a buffer and a bind group
            wgpu::Buffer buffer =
                CreateBuffer(4, wgpu::BufferUsage::Storage | wgpu::BufferUsage::Index);
            wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroup writeBG = utils::MakeBindGroup(device, writeBGL, {{0, buffer}});

            // Create a no-op render pipeline.
            wgpu::RenderPipeline rp = CreateNoOpRenderPipeline();

            // It is invalid to use the same buffer as both readable and writable usages in a single
            // draw
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetPipeline(rp);

            pass.SetIndexBuffer(buffer, wgpu::IndexFormat::Uint32);
            pass.SetBindGroup(0, writeBG);
            pass.Draw(3);

            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // test compute pass
        {
            // Create a buffer and bind groups
            wgpu::Buffer buffer = CreateBuffer(4, wgpu::BufferUsage::Storage);

            wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::ReadOnlyStorage}});
            wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroup readBG = utils::MakeBindGroup(device, readBGL, {{0, buffer}});
            wgpu::BindGroup writeBG = utils::MakeBindGroup(device, writeBGL, {{0, buffer}});

            // Create a no-op compute pipeline.
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({readBGL, writeBGL});

            // It is invalid to use the same buffer as both readable and writable usages in a single
            // dispatch
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetPipeline(cp);

            pass.SetBindGroup(0, readBG);
            pass.SetBindGroup(1, writeBG);
            pass.Dispatch(1);

            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }
    }

    // Test that using the same buffer as copy src/dst and writable/readable usage is allowed.
    TEST_F(ResourceUsageTrackingTest, BufferCopyAndBufferUsageInPass) {
        // Create buffers that will be used as both a copy src/dst buffer and a storage buffer
        wgpu::Buffer bufferSrc =
            CreateBuffer(4, wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc);
        wgpu::Buffer bufferDst =
            CreateBuffer(4, wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopyDst);

        // Create the bind group to use the buffer as storage
        wgpu::BindGroupLayout bgl0 = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage}});
        wgpu::BindGroup bg0 = utils::MakeBindGroup(device, bgl0, {{0, bufferSrc}});
        wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::ReadOnlyStorage}});
        wgpu::BindGroup bg1 = utils::MakeBindGroup(device, bgl1, {{0, bufferDst}});

        // Use the buffer as both copy src and storage in render pass
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            encoder.CopyBufferToBuffer(bufferSrc, 0, bufferDst, 0, 4);
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetBindGroup(0, bg0);
            pass.EndPass();
            encoder.Finish();
        }

        // Use the buffer as both copy dst and readonly storage in compute pass
        {
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({bgl1});

            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            encoder.CopyBufferToBuffer(bufferSrc, 0, bufferDst, 0, 4);

            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetBindGroup(0, bg1);
            pass.SetPipeline(cp);
            pass.Dispatch(1);
            pass.EndPass();

            encoder.Finish();
        }
    }

    // Test that all index buffers and vertex buffers take effect even though some buffers are
    // not used because they are overwritten by another consecutive call.
    TEST_F(ResourceUsageTrackingTest, BufferWithMultipleSetIndexOrVertexBuffer) {
        // Create buffers that will be used as both vertex and index buffer.
        wgpu::Buffer buffer0 = CreateBuffer(
            4, wgpu::BufferUsage::Vertex | wgpu::BufferUsage::Index | wgpu::BufferUsage::Storage);
        wgpu::Buffer buffer1 =
            CreateBuffer(4, wgpu::BufferUsage::Vertex | wgpu::BufferUsage::Index);

        wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage}});
        wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, buffer0}});

        DummyRenderPass dummyRenderPass(device);

        // Set index buffer twice. The second one overwrites the first one. No buffer is used as
        // both read and write in the same pass. But the overwritten index buffer (buffer0) still
        // take effect during resource tracking.
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetIndexBuffer(buffer0, wgpu::IndexFormat::Uint32);
            pass.SetIndexBuffer(buffer1, wgpu::IndexFormat::Uint32);
            pass.SetBindGroup(0, bg);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // Set index buffer twice. The second one overwrites the first one. buffer0 is used as both
        // read and write in the same pass
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetIndexBuffer(buffer1, wgpu::IndexFormat::Uint32);
            pass.SetIndexBuffer(buffer0, wgpu::IndexFormat::Uint32);
            pass.SetBindGroup(0, bg);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // Set vertex buffer on the same index twice. The second one overwrites the first one. No
        // buffer is used as both read and write in the same pass. But the overwritten vertex buffer
        // (buffer0) still take effect during resource tracking.
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetVertexBuffer(0, buffer0);
            pass.SetVertexBuffer(0, buffer1);
            pass.SetBindGroup(0, bg);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // Set vertex buffer on the same index twice. The second one overwrites the first one.
        // buffer0 is used as both read and write in the same pass
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetVertexBuffer(0, buffer1);
            pass.SetVertexBuffer(0, buffer0);
            pass.SetBindGroup(0, bg);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }
    }

    // Test that all consecutive SetBindGroup()s take effect even though some bind groups are not
    // used because they are overwritten by a consecutive call.
    TEST_F(ResourceUsageTrackingTest, BufferWithMultipleSetBindGroupsOnSameIndex) {
        // test render pass
        {
            // Create buffers that will be used as index and storage buffers
            wgpu::Buffer buffer0 =
                CreateBuffer(4, wgpu::BufferUsage::Storage | wgpu::BufferUsage::Index);
            wgpu::Buffer buffer1 =
                CreateBuffer(4, wgpu::BufferUsage::Storage | wgpu::BufferUsage::Index);

            // Create the bind group to use the buffer as storage
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroup bg0 = utils::MakeBindGroup(device, bgl, {{0, buffer0}});
            wgpu::BindGroup bg1 = utils::MakeBindGroup(device, bgl, {{0, buffer1}});

            DummyRenderPass dummyRenderPass(device);

            // Set bind group on the same index twice. The second one overwrites the first one.
            // No buffer is used as both read and write in the same pass. But the overwritten
            // bind group still take effect during resource tracking.
            {
                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
                wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
                pass.SetIndexBuffer(buffer0, wgpu::IndexFormat::Uint32);
                pass.SetBindGroup(0, bg0);
                pass.SetBindGroup(0, bg1);
                pass.EndPass();
                ASSERT_DEVICE_ERROR(encoder.Finish());
            }

            // Set bind group on the same index twice. The second one overwrites the first one.
            // buffer0 is used as both read and write in the same pass
            {
                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
                wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
                pass.SetIndexBuffer(buffer0, wgpu::IndexFormat::Uint32);
                pass.SetBindGroup(0, bg1);
                pass.SetBindGroup(0, bg0);
                pass.EndPass();
                ASSERT_DEVICE_ERROR(encoder.Finish());
            }
        }

        // test compute pass
        {
            // Create buffers that will be used as readonly and writable storage buffers
            wgpu::Buffer buffer0 = CreateBuffer(512, wgpu::BufferUsage::Storage);
            wgpu::Buffer buffer1 = CreateBuffer(4, wgpu::BufferUsage::Storage);

            // Create the bind group to use the buffer as storage
            wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::ReadOnlyStorage}});
            wgpu::BindGroup writeBG0 = utils::MakeBindGroup(device, writeBGL, {{0, buffer0, 0, 4}});
            wgpu::BindGroup readBG0 = utils::MakeBindGroup(device, readBGL, {{0, buffer0, 256, 4}});
            wgpu::BindGroup readBG1 = utils::MakeBindGroup(device, readBGL, {{0, buffer1, 0, 4}});

            // Create a no-op compute pipeline.
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({writeBGL, readBGL});

            // Set bind group against the same index twice. The second one overwrites the first one.
            // Then no buffer is used as both read and write in the same dispatch. But the
            // overwritten bind group still take effect.
            {
                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
                wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
                pass.SetBindGroup(0, writeBG0);
                pass.SetBindGroup(1, readBG0);
                pass.SetBindGroup(1, readBG1);
                pass.SetPipeline(cp);
                pass.Dispatch(1);
                pass.EndPass();
                encoder.Finish();
            }

            // Set bind group against the same index twice. The second one overwrites the first one.
            // Then buffer0 is used as both read and write in the same dispatch
            {
                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
                wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
                pass.SetBindGroup(0, writeBG0);
                pass.SetBindGroup(1, readBG1);
                pass.SetBindGroup(1, readBG0);
                pass.SetPipeline(cp);
                pass.Dispatch(1);
                pass.EndPass();
                ASSERT_DEVICE_ERROR(encoder.Finish());
            }
        }
    }

    // Test that it is invalid to have resource usage conflicts even when all bindings are not
    // visible to the programmable pass where it is used.
    TEST_F(ResourceUsageTrackingTest, BufferUsageConflictBetweenInvisibleStagesInBindGroup) {
        wgpu::Buffer buffer = CreateBuffer(4, wgpu::BufferUsage::Storage);

        // Test render pass for bind group. The conflict of readonly storage and storage usage
        // doesn't reside in render related stages at all
        {
            // Create a bind group whose bindings are not visible in render pass
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage},
                         {1, wgpu::ShaderStage::None, wgpu::BufferBindingType::ReadOnlyStorage}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, buffer}, {1, buffer}});

            // These two bindings are invisible in render pass. But we still track these bindings.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetBindGroup(0, bg);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // Test compute pass for bind group. The conflict of readonly storage and storage usage
        // doesn't reside in compute related stage at all
        {
            // Create a bind group whose bindings are not visible in compute pass
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::ReadOnlyStorage},
                         {1, wgpu::ShaderStage::None, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, buffer}, {1, buffer}});

            // Create a no-op compute pipeline.
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({bgl});

            // These two bindings are invisible in the dispatch. But we still track these bindings.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetPipeline(cp);
            pass.SetBindGroup(0, bg);
            pass.Dispatch(1);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }
    }

    // Test that it is invalid to have resource usage conflicts even when one of the bindings is not
    // visible to the programmable pass where it is used.
    TEST_F(ResourceUsageTrackingTest, BufferUsageConflictWithInvisibleStageInBindGroup) {
        // Test render pass for bind group and index buffer. The conflict of storage and index
        // buffer usage resides between fragment stage and compute stage. But the compute stage
        // binding is not visible in render pass.
        {
            wgpu::Buffer buffer =
                CreateBuffer(4, wgpu::BufferUsage::Storage | wgpu::BufferUsage::Index);
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, buffer}});

            // Buffer usage in compute stage in bind group conflicts with index buffer. And binding
            // for compute stage is not visible in render pass. But we still track this binding.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetIndexBuffer(buffer, wgpu::IndexFormat::Uint32);
            pass.SetBindGroup(0, bg);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // Test compute pass for bind group. The conflict of readonly storage and storage buffer
        // usage resides between compute stage and fragment stage. But the fragment stage binding is
        // not visible in the dispatch.
        {
            wgpu::Buffer buffer = CreateBuffer(4, wgpu::BufferUsage::Storage);
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::ReadOnlyStorage},
                         {1, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, buffer}, {1, buffer}});

            // Create a no-op compute pipeline.
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({bgl});

            // Buffer usage in compute stage conflicts with buffer usage in fragment stage. And
            // binding for fragment stage is not visible in the dispatch. But we still track this
            // invisible binding.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetPipeline(cp);
            pass.SetBindGroup(0, bg);
            pass.Dispatch(1);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }
    }

    // Test that it is invalid to have resource usage conflicts even when one of the bindings is not
    // used in the pipeline.
    TEST_F(ResourceUsageTrackingTest, BufferUsageConflictWithUnusedPipelineBindings) {
        wgpu::Buffer buffer = CreateBuffer(4, wgpu::BufferUsage::Storage);

        // Test render pass for bind groups with unused bindings. The conflict of readonly storage
        // and storage usages resides in different bind groups, although some bindings may not be
        // used because its bind group layout is not designated in pipeline layout.
        {
            // Create bind groups. The bindings are visible for render pass.
            wgpu::BindGroupLayout bgl0 = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::ReadOnlyStorage}});
            wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroup bg0 = utils::MakeBindGroup(device, bgl0, {{0, buffer}});
            wgpu::BindGroup bg1 = utils::MakeBindGroup(device, bgl1, {{0, buffer}});

            // Create a passthrough render pipeline with a readonly buffer
            wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
                [[stage(vertex)]] fn main() -> [[builtin(position)]] vec4<f32> {
                    return vec4<f32>();
                })");

            wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
                [[block]] struct RBuffer {
                    value : f32;
                };
                [[group(0), binding(0)]] var<storage, read> rBuffer : RBuffer;
                [[stage(fragment)]] fn main() {
                })");
            utils::ComboRenderPipelineDescriptor pipelineDescriptor;
            pipelineDescriptor.vertex.module = vsModule;
            pipelineDescriptor.cFragment.module = fsModule;
            pipelineDescriptor.layout = utils::MakeBasicPipelineLayout(device, &bgl0);
            wgpu::RenderPipeline rp = device.CreateRenderPipeline(&pipelineDescriptor);

            // Resource in bg1 conflicts with resources used in bg0. However, bindings in bg1 is
            // not used in pipeline. But we still track this binding.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetBindGroup(0, bg0);
            pass.SetBindGroup(1, bg1);
            pass.SetPipeline(rp);
            pass.Draw(3);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // Test that an unused bind group is not used to detect conflicts between bindings in
        // compute passes.
        {
            // Create bind groups. The bindings are visible for compute pass.
            wgpu::BindGroupLayout bgl0 = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::ReadOnlyStorage}});
            wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage}});
            wgpu::BindGroup bg0 = utils::MakeBindGroup(device, bgl0, {{0, buffer}});
            wgpu::BindGroup bg1 = utils::MakeBindGroup(device, bgl1, {{0, buffer}});

            // Create a compute pipeline with only one of the two BGLs.
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({bgl0});

            // Resource in bg1 conflicts with resources used in bg0. However, the binding in bg1 is
            // not used in pipeline so no error is produced in the dispatch.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetBindGroup(0, bg0);
            pass.SetBindGroup(1, bg1);
            pass.SetPipeline(cp);
            pass.Dispatch(1);
            pass.EndPass();
            encoder.Finish();
        }
    }

    // Test that using a single texture in multiple read usages in the same pass is allowed.
    TEST_F(ResourceUsageTrackingTest, TextureWithMultipleReadUsages) {
        // Create a texture that will be used as both sampled and readonly storage texture
        wgpu::Texture texture =
            CreateTexture(wgpu::TextureUsage::Sampled | wgpu::TextureUsage::Storage);
        wgpu::TextureView view = texture.CreateView();

        // Create a bind group to use the texture as sampled and readonly storage bindings
        wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute,
                      wgpu::TextureSampleType::Float},
                     {1, wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute,
                      wgpu::StorageTextureAccess::ReadOnly, kFormat}});
        wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}, {1, view}});

        // Test render pass
        {
            // Use the texture as both sampled and readonly storage in the same render pass
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetBindGroup(0, bg);
            pass.EndPass();
            encoder.Finish();
        }

        // Test compute pass
        {
            // Use the texture as both sampled and readonly storage in the same compute pass
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({bgl});

            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetBindGroup(0, bg);
            pass.SetPipeline(cp);
            pass.Dispatch(1);
            pass.EndPass();
            encoder.Finish();
        }
    }

    // Test that it is invalid to use the same texture as both readable and writable in the same
    // render pass. It is invalid in the same dispatch in compute pass.
    TEST_F(ResourceUsageTrackingTest, TextureWithReadAndWriteUsage) {
        // Test render pass
        {
            // Create a texture
            wgpu::Texture texture =
                CreateTexture(wgpu::TextureUsage::Sampled | wgpu::TextureUsage::RenderAttachment);
            wgpu::TextureView view = texture.CreateView();

            // Create a bind group to use the texture as sampled binding
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Vertex, wgpu::TextureSampleType::Float}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}});

            // Create a render pass to use the texture as a render target
            utils::ComboRenderPassDescriptor renderPass({view});

            // It is invalid to use the texture as both sampled and render target in the same pass
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
            pass.SetBindGroup(0, bg);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // Test compute pass
        {
            // Create a texture
            wgpu::Texture texture =
                CreateTexture(wgpu::TextureUsage::Sampled | wgpu::TextureUsage::Storage);
            wgpu::TextureView view = texture.CreateView();

            // Create a bind group to use the texture as sampled and writeonly bindings
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float},
                 {1, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}, {1, view}});

            // Create a no-op compute pipeline
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({bgl});

            // It is valid to use the texture as both sampled and writeonly storage in a single
            // compute pass if dispatch command is not called.
            {
                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
                wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
                pass.SetBindGroup(0, bg);
                pass.EndPass();
                encoder.Finish();
            }

            // It is invalid to use the texture as both sampled and writeonly storage in a single
            // dispatch
            {
                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
                wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
                pass.SetPipeline(cp);
                pass.SetBindGroup(0, bg);
                pass.Dispatch(1);
                pass.EndPass();
                ASSERT_DEVICE_ERROR(encoder.Finish());
            }
        }
    }

    // Test using multiple writable usages on the same texture in a single pass/dispatch
    TEST_F(ResourceUsageTrackingTest, TextureWithMultipleWriteUsage) {
        // Test render pass
        {
            // Create a texture
            wgpu::Texture texture =
                CreateTexture(wgpu::TextureUsage::Storage | wgpu::TextureUsage::RenderAttachment);
            wgpu::TextureView view = texture.CreateView();

            // Create a bind group to use the texture as writeonly storage binding
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}});

            // It is invalid to use the texture as both writeonly storage and render target in
            // the same pass
            {
                utils::ComboRenderPassDescriptor renderPass({view});

                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
                wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
                pass.SetBindGroup(0, bg);
                pass.EndPass();
                ASSERT_DEVICE_ERROR(encoder.Finish());
            }

            // It is valid to use multiple writeonly storage usages on the same texture in render
            // pass
            {
                wgpu::BindGroup bg1 = utils::MakeBindGroup(device, bgl, {{0, view}});

                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
                DummyRenderPass dummyRenderPass(device);
                wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
                pass.SetBindGroup(0, bg);
                pass.SetBindGroup(1, bg1);
                pass.EndPass();
                encoder.Finish();
            }
        }

        // Test compute pass
        {
            // Create a texture
            wgpu::Texture texture = CreateTexture(wgpu::TextureUsage::Storage);
            wgpu::TextureView view = texture.CreateView();

            // Create a bind group to use the texture as sampled and writeonly bindings
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat},
                 {1, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}, {1, view}});

            // Create a no-op compute pipeline
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({bgl});

            // It is valid to use the texture as multiple writeonly storage usages in a single
            // dispatch
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetPipeline(cp);
            pass.SetBindGroup(0, bg);
            pass.Dispatch(1);
            pass.EndPass();
            encoder.Finish();
        }
    }

    // Test that using the same texture as both readable and writable in different passes is
    // allowed
    TEST_F(ResourceUsageTrackingTest, TextureWithReadAndWriteUsageInDifferentPasses) {
        // Test render pass
        {
            // Create textures that will be used as both a sampled texture and a render target
            wgpu::Texture t0 =
                CreateTexture(wgpu::TextureUsage::Sampled | wgpu::TextureUsage::RenderAttachment);
            wgpu::TextureView v0 = t0.CreateView();
            wgpu::Texture t1 =
                CreateTexture(wgpu::TextureUsage::Sampled | wgpu::TextureUsage::RenderAttachment);
            wgpu::TextureView v1 = t1.CreateView();

            // Create bind groups to use the texture as sampled
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Vertex, wgpu::TextureSampleType::Float}});
            wgpu::BindGroup bg0 = utils::MakeBindGroup(device, bgl, {{0, v0}});
            wgpu::BindGroup bg1 = utils::MakeBindGroup(device, bgl, {{0, v1}});

            // Create render passes that will use the textures as render attachments
            utils::ComboRenderPassDescriptor renderPass0({v1});
            utils::ComboRenderPassDescriptor renderPass1({v0});

            // Use the textures as both sampled and render attachments in different passes
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();

            wgpu::RenderPassEncoder pass0 = encoder.BeginRenderPass(&renderPass0);
            pass0.SetBindGroup(0, bg0);
            pass0.EndPass();

            wgpu::RenderPassEncoder pass1 = encoder.BeginRenderPass(&renderPass1);
            pass1.SetBindGroup(0, bg1);
            pass1.EndPass();

            encoder.Finish();
        }

        // Test compute pass
        {
            // Create a texture that will be used storage texture
            wgpu::Texture texture = CreateTexture(wgpu::TextureUsage::Storage);
            wgpu::TextureView view = texture.CreateView();

            // Create bind groups to use the texture as readonly and writeonly bindings
            wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat}});
            wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
            wgpu::BindGroup readBG = utils::MakeBindGroup(device, readBGL, {{0, view}});
            wgpu::BindGroup writeBG = utils::MakeBindGroup(device, writeBGL, {{0, view}});

            // Use the textures as both readonly and writeonly storages in different passes
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();

            wgpu::ComputePassEncoder pass0 = encoder.BeginComputePass();
            pass0.SetBindGroup(0, readBG);
            pass0.EndPass();

            wgpu::ComputePassEncoder pass1 = encoder.BeginComputePass();
            pass1.SetBindGroup(0, writeBG);
            pass1.EndPass();

            encoder.Finish();
        }

        // Test compute pass and render pass mixed together with resource dependency
        {
            // Create a texture that will be used a storage texture
            wgpu::Texture texture = CreateTexture(wgpu::TextureUsage::Storage);
            wgpu::TextureView view = texture.CreateView();

            // Create bind groups to use the texture as readonly and writeonly bindings
            wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
            wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly, kFormat}});
            wgpu::BindGroup writeBG = utils::MakeBindGroup(device, writeBGL, {{0, view}});
            wgpu::BindGroup readBG = utils::MakeBindGroup(device, readBGL, {{0, view}});

            // Use the texture as writeonly and readonly storage in compute pass and render
            // pass respectively
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();

            wgpu::ComputePassEncoder pass0 = encoder.BeginComputePass();
            pass0.SetBindGroup(0, writeBG);
            pass0.EndPass();

            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass1 = encoder.BeginRenderPass(&dummyRenderPass);
            pass1.SetBindGroup(0, readBG);
            pass1.EndPass();

            encoder.Finish();
        }
    }

    // Test that it is invalid to use the same texture as both readable and writable in different
    // draws in a single render pass. But it is valid in different dispatches in a single compute
    // pass.
    TEST_F(ResourceUsageTrackingTest, TextureWithReadAndWriteUsageOnDifferentDrawsOrDispatches) {
        // Create a texture that will be used both as a sampled texture and a storage texture
        wgpu::Texture texture =
            CreateTexture(wgpu::TextureUsage::Sampled | wgpu::TextureUsage::Storage);
        wgpu::TextureView view = texture.CreateView();

        // Test render pass
        {
            // Create bind groups to use the texture as sampled and writeonly storage bindings
            wgpu::BindGroupLayout sampledBGL = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}});
            wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
            wgpu::BindGroup sampledBG = utils::MakeBindGroup(device, sampledBGL, {{0, view}});
            wgpu::BindGroup writeBG = utils::MakeBindGroup(device, writeBGL, {{0, view}});

            // Create a no-op render pipeline.
            wgpu::RenderPipeline rp = CreateNoOpRenderPipeline();

            // It is not allowed to use the same texture as both readable and writable in different
            // draws within the same render pass.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetPipeline(rp);

            pass.SetBindGroup(0, sampledBG);
            pass.Draw(3);

            pass.SetBindGroup(0, writeBG);
            pass.Draw(3);

            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // Test compute pass
        {
            // Create bind groups to use the texture as readonly and writeonly storage bindings
            wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat}});
            wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
            wgpu::BindGroup readBG = utils::MakeBindGroup(device, readBGL, {{0, view}});
            wgpu::BindGroup writeBG = utils::MakeBindGroup(device, writeBGL, {{0, view}});

            // Create a no-op compute pipeline.
            wgpu::ComputePipeline readCp = CreateNoOpComputePipeline({readBGL});
            wgpu::ComputePipeline writeCp = CreateNoOpComputePipeline({writeBGL});

            // It is valid to use the same texture as both readable and writable in different
            // dispatches within the same compute pass.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();

            pass.SetPipeline(readCp);
            pass.SetBindGroup(0, readBG);
            pass.Dispatch(1);

            pass.SetPipeline(writeCp);
            pass.SetBindGroup(0, writeBG);
            pass.Dispatch(1);

            pass.EndPass();
            encoder.Finish();
        }
    }

    // Test that it is invalid to use the same texture as both readable and writable in a single
    // draw or dispatch.
    TEST_F(ResourceUsageTrackingTest, TextureWithReadAndWriteUsageInSingleDrawOrDispatch) {
        // Create a texture that will be used both as a sampled texture and a storage texture
        wgpu::Texture texture =
            CreateTexture(wgpu::TextureUsage::Sampled | wgpu::TextureUsage::Storage);
        wgpu::TextureView view = texture.CreateView();

        // Test render pass
        {
            // Create the bind group to use the texture as sampled and writeonly storage bindings
            wgpu::BindGroupLayout sampledBGL = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}});
            wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
            wgpu::BindGroup sampledBG = utils::MakeBindGroup(device, sampledBGL, {{0, view}});
            wgpu::BindGroup writeBG = utils::MakeBindGroup(device, writeBGL, {{0, view}});

            // Create a no-op render pipeline.
            wgpu::RenderPipeline rp = CreateNoOpRenderPipeline();

            // It is invalid to use the same texture as both readable and writable usages in a
            // single draw
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetPipeline(rp);

            pass.SetBindGroup(0, sampledBG);
            pass.SetBindGroup(1, writeBG);
            pass.Draw(3);

            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // Test compute pass
        {
            // Create the bind group to use the texture as readonly and writeonly storage bindings
            wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat}});
            wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
            wgpu::BindGroup readBG = utils::MakeBindGroup(device, readBGL, {{0, view}});
            wgpu::BindGroup writeBG = utils::MakeBindGroup(device, writeBGL, {{0, view}});

            // Create a no-op compute pipeline.
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({readBGL, writeBGL});

            // It is invalid to use the same texture as both readable and writable usages in a
            // single dispatch
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetPipeline(cp);

            pass.SetBindGroup(0, readBG);
            pass.SetBindGroup(1, writeBG);
            pass.Dispatch(1);

            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }
    }

    // Test that using a single texture as copy src/dst and writable/readable usage in pass is
    // allowed.
    TEST_F(ResourceUsageTrackingTest, TextureCopyAndTextureUsageInPass) {
        // Create textures that will be used as both a sampled texture and a render target
        wgpu::Texture texture0 = CreateTexture(wgpu::TextureUsage::CopySrc);
        wgpu::Texture texture1 =
            CreateTexture(wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled |
                          wgpu::TextureUsage::RenderAttachment);
        wgpu::TextureView view0 = texture0.CreateView();
        wgpu::TextureView view1 = texture1.CreateView();

        wgpu::ImageCopyTexture srcView = utils::CreateImageCopyTexture(texture0, 0, {0, 0, 0});
        wgpu::ImageCopyTexture dstView = utils::CreateImageCopyTexture(texture1, 0, {0, 0, 0});
        wgpu::Extent3D copySize = {1, 1, 1};

        // Use the texture as both copy dst and render attachment in render pass
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            encoder.CopyTextureToTexture(&srcView, &dstView, &copySize);
            utils::ComboRenderPassDescriptor renderPass({view1});
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
            pass.EndPass();
            encoder.Finish();
        }

        // Use the texture as both copy dst and readable usage in compute pass
        {
            // Create the bind group to use the texture as sampled
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view1}});

            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({bgl});

            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            encoder.CopyTextureToTexture(&srcView, &dstView, &copySize);
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetBindGroup(0, bg);
            pass.SetPipeline(cp);
            pass.Dispatch(1);
            pass.EndPass();
            encoder.Finish();
        }
    }

    // Test that all consecutive SetBindGroup()s take effect even though some bind groups are not
    // used because they are overwritten by a consecutive call.
    TEST_F(ResourceUsageTrackingTest, TextureWithMultipleSetBindGroupsOnSameIndex) {
        // Test render pass
        {
            // Create textures that will be used as both a sampled texture and a render target
            wgpu::Texture texture0 =
                CreateTexture(wgpu::TextureUsage::Sampled | wgpu::TextureUsage::RenderAttachment);
            wgpu::TextureView view0 = texture0.CreateView();
            wgpu::Texture texture1 =
                CreateTexture(wgpu::TextureUsage::Sampled | wgpu::TextureUsage::RenderAttachment);
            wgpu::TextureView view1 = texture1.CreateView();

            // Create the bind group to use the texture as sampled
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Vertex, wgpu::TextureSampleType::Float}});
            wgpu::BindGroup bg0 = utils::MakeBindGroup(device, bgl, {{0, view0}});
            wgpu::BindGroup bg1 = utils::MakeBindGroup(device, bgl, {{0, view1}});

            // Create the render pass that will use the texture as an render attachment
            utils::ComboRenderPassDescriptor renderPass({view0});

            // Set bind group on the same index twice. The second one overwrites the first one.
            // No texture is used as both sampled and render attachment in the same pass. But the
            // overwritten texture still take effect during resource tracking.
            {
                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
                wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
                pass.SetBindGroup(0, bg0);
                pass.SetBindGroup(0, bg1);
                pass.EndPass();
                ASSERT_DEVICE_ERROR(encoder.Finish());
            }

            // Set bind group on the same index twice. The second one overwrites the first one.
            // texture0 is used as both sampled and render attachment in the same pass
            {
                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
                wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
                pass.SetBindGroup(0, bg1);
                pass.SetBindGroup(0, bg0);
                pass.EndPass();
                ASSERT_DEVICE_ERROR(encoder.Finish());
            }
        }

        // Test compute pass
        {
            // Create a texture that will be used both as storage texture
            wgpu::Texture texture0 = CreateTexture(wgpu::TextureUsage::Storage);
            wgpu::TextureView view0 = texture0.CreateView();
            wgpu::Texture texture1 = CreateTexture(wgpu::TextureUsage::Storage);
            wgpu::TextureView view1 = texture1.CreateView();

            // Create the bind group to use the texture as readonly and writeonly bindings
            wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});

            wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat}});

            wgpu::BindGroup writeBG0 = utils::MakeBindGroup(device, writeBGL, {{0, view0}});
            wgpu::BindGroup readBG0 = utils::MakeBindGroup(device, readBGL, {{0, view0}});
            wgpu::BindGroup readBG1 = utils::MakeBindGroup(device, readBGL, {{0, view1}});

            // Create a no-op compute pipeline.
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({writeBGL, readBGL});

            // Set bind group on the same index twice. The second one overwrites the first one.
            // No texture is used as both readonly and writeonly storage in the same dispatch so
            // there are no errors.
            {
                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
                wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
                pass.SetBindGroup(0, writeBG0);
                pass.SetBindGroup(1, readBG0);
                pass.SetBindGroup(1, readBG1);
                pass.SetPipeline(cp);
                pass.Dispatch(1);
                pass.EndPass();
                encoder.Finish();
            }

            // Set bind group on the same index twice. The second one overwrites the first one.
            // texture0 is used as both writeonly and readonly storage in the same dispatch, which
            // is an error.
            {
                wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
                wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
                pass.SetBindGroup(0, writeBG0);
                pass.SetBindGroup(1, readBG1);
                pass.SetBindGroup(1, readBG0);
                pass.SetPipeline(cp);
                pass.Dispatch(1);
                pass.EndPass();
                ASSERT_DEVICE_ERROR(encoder.Finish());
            }
        }
    }

    // Test that it is invalid to have resource usage conflicts even when all bindings are not
    // visible to the programmable pass where it is used.
    TEST_F(ResourceUsageTrackingTest, TextureUsageConflictBetweenInvisibleStagesInBindGroup) {
        // Create texture and texture view
        wgpu::Texture texture = CreateTexture(wgpu::TextureUsage::Storage);
        wgpu::TextureView view = texture.CreateView();

        // Test render pass for bind group. The conflict of readonly storage and writeonly storage
        // usage doesn't reside in render related stages at all
        {
            // Create a bind group whose bindings are not visible in render pass
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat},
                 {1, wgpu::ShaderStage::None, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}, {1, view}});

            // These two bindings are invisible in render pass. But we still track these bindings.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetBindGroup(0, bg);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // Test compute pass for bind group. The conflict of readonly storage and writeonly storage
        // usage doesn't reside in compute related stage at all
        {
            // Create a bind group whose bindings are not visible in compute pass
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly, kFormat},
                 {1, wgpu::ShaderStage::None, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}, {1, view}});

            // Create a no-op compute pipeline.
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({bgl});

            // These two bindings are invisible in compute pass. But we still track these bindings.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetPipeline(cp);
            pass.SetBindGroup(0, bg);
            pass.Dispatch(1);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }
    }

    // Test that it is invalid to have resource usage conflicts even when one of the bindings is not
    // visible to the programmable pass where it is used.
    TEST_F(ResourceUsageTrackingTest, TextureUsageConflictWithInvisibleStageInBindGroup) {
        // Create texture and texture view
        wgpu::Texture texture =
            CreateTexture(wgpu::TextureUsage::Storage | wgpu::TextureUsage::RenderAttachment);
        wgpu::TextureView view = texture.CreateView();

        // Test render pass
        {
            // Create the render pass that will use the texture as an render attachment
            utils::ComboRenderPassDescriptor renderPass({view});

            // Create a bind group which use the texture as readonly storage in compute stage
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::ReadOnly, kFormat}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}});

            // Texture usage in compute stage in bind group conflicts with render target. And
            // binding for compute stage is not visible in render pass. But we still track this
            // binding.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
            pass.SetBindGroup(0, bg);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // Test compute pass
        {
            // Create a bind group which contains both fragment and compute stages
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device,
                {{0, wgpu::ShaderStage::Fragment, wgpu::StorageTextureAccess::ReadOnly, kFormat},
                 {1, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly, kFormat}});
            wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}, {1, view}});

            // Create a no-op compute pipeline.
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({bgl});

            // Texture usage in compute stage conflicts with texture usage in fragment stage. And
            // binding for fragment stage is not visible in compute pass. But we still track this
            // invisible binding.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetPipeline(cp);
            pass.SetBindGroup(0, bg);
            pass.Dispatch(1);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }
    }

    // Test that it is invalid to have resource usage conflicts even when one of the bindings is not
    // used in the pipeline.
    TEST_F(ResourceUsageTrackingTest, TextureUsageConflictWithUnusedPipelineBindings) {
        // Create texture and texture view
        wgpu::Texture texture = CreateTexture(wgpu::TextureUsage::Storage);
        wgpu::TextureView view = texture.CreateView();

        // Create bind groups.
        wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute,
                      wgpu::StorageTextureAccess::ReadOnly, kFormat}});
        wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute,
                      wgpu::StorageTextureAccess::WriteOnly, kFormat}});
        wgpu::BindGroup readBG = utils::MakeBindGroup(device, readBGL, {{0, view}});
        wgpu::BindGroup writeBG = utils::MakeBindGroup(device, writeBGL, {{0, view}});

        // Test render pass
        {
            // Create a passthrough render pipeline with a readonly storage texture
            wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
                [[stage(vertex)]] fn main() -> [[builtin(position)]] vec4<f32> {
                    return vec4<f32>();
                })");

            wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
                [[group(0), binding(0)]] var tex : texture_storage_2d<rgba8unorm, read>;
                [[stage(fragment)]] fn main() {
                })");
            utils::ComboRenderPipelineDescriptor pipelineDescriptor;
            pipelineDescriptor.vertex.module = vsModule;
            pipelineDescriptor.cFragment.module = fsModule;
            pipelineDescriptor.layout = utils::MakeBasicPipelineLayout(device, &readBGL);
            wgpu::RenderPipeline rp = device.CreateRenderPipeline(&pipelineDescriptor);

            // Texture binding in readBG conflicts with texture binding in writeBG. The binding
            // in writeBG is not used in pipeline. But we still track this binding.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetBindGroup(0, readBG);
            pass.SetBindGroup(1, writeBG);
            pass.SetPipeline(rp);
            pass.Draw(3);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // Test compute pass
        {
            wgpu::ComputePipeline cp = CreateNoOpComputePipeline({readBGL});

            // Texture binding in readBG conflicts with texture binding in writeBG. The binding
            // in writeBG is not used in pipeline's layout so it isn't an error.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetBindGroup(0, readBG);
            pass.SetBindGroup(1, writeBG);
            pass.SetPipeline(cp);
            pass.Dispatch(1);
            pass.EndPass();
            encoder.Finish();
        }
    }

    // Test that using an indirect buffer is disallowed with a writable usage (like storage) but
    // allowed with a readable usage (like readonly storage).
    TEST_F(ResourceUsageTrackingTest, IndirectBufferWithReadOrWriteStorage) {
        wgpu::Buffer buffer =
            CreateBuffer(20, wgpu::BufferUsage::Indirect | wgpu::BufferUsage::Storage);

        wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::ReadOnlyStorage}});
        wgpu::BindGroupLayout writeBGL = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage}});

        wgpu::BindGroup readBG = utils::MakeBindGroup(device, readBGL, {{0, buffer}});
        wgpu::BindGroup writeBG = utils::MakeBindGroup(device, writeBGL, {{0, buffer}});

        // Test pipelines
        wgpu::RenderPipeline rp = CreateNoOpRenderPipeline();
        wgpu::ComputePipeline readCp = CreateNoOpComputePipeline({readBGL});
        wgpu::ComputePipeline writeCp = CreateNoOpComputePipeline({writeBGL});

        // Test that indirect + readonly is allowed in the same render pass.
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetPipeline(rp);
            pass.SetBindGroup(0, readBG);
            pass.DrawIndirect(buffer, 0);
            pass.EndPass();
            encoder.Finish();
        }

        // Test that indirect + writable is disallowed in the same render pass.
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            DummyRenderPass dummyRenderPass(device);
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&dummyRenderPass);
            pass.SetPipeline(rp);
            pass.SetBindGroup(0, writeBG);
            pass.DrawIndirect(buffer, 0);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        // Test that indirect + readonly is allowed in the same dispatch
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetPipeline(readCp);
            pass.SetBindGroup(0, readBG);
            pass.DispatchIndirect(buffer, 0);
            pass.EndPass();
            encoder.Finish();
        }

        // Test that indirect + writable is disallowed in the same dispatch
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetPipeline(writeCp);
            pass.SetBindGroup(0, writeBG);
            pass.DispatchIndirect(buffer, 0);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }
    }

    // TODO (yunchao.he@intel.com):
    //
    //	* Add tests for multiple encoders upon the same resource simultaneously. This situation fits
    //	some cases like VR, multi-threading, etc.
    //
    //	* Add tests for bundle

}  // anonymous namespace
