// 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 "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/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::TextureFormat format = wgpu::TextureFormat::RGBA8Unorm) {
            wgpu::TextureDescriptor descriptor;
            descriptor.dimension = wgpu::TextureDimension::e2D;
            descriptor.size = {1, 1, 1};
            descriptor.sampleCount = 1;
            descriptor.mipLevelCount = 1;
            descriptor.usage = usage;
            descriptor.format = format;

            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.cTargets[0].writeMask = wgpu::ColorWriteMask::None;
            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) @workgroup_size(1) 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"(
                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.cTargets[0].writeMask = wgpu::ColorWriteMask::None;
            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 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::TextureBinding |
                                                  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::TextureBinding |
                                                  wgpu::TextureUsage::StorageBinding);
            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 that it is invalid to use the same texture as both readable and writable depth/stencil
    // attachment in the same render pass. But it is valid to use it as both readable and readonly
    // depth/stencil attachment in the same render pass.
    // Note that depth/stencil attachment is a special render attachment, it can be readonly.
    TEST_F(ResourceUsageTrackingTest, TextureWithSamplingAndDepthStencilAttachment) {
        // Create a texture
        wgpu::Texture texture =
            CreateTexture(wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment,
                          wgpu::TextureFormat::Depth32Float);
        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::Fragment, wgpu::TextureSampleType::Depth}});
        wgpu::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}});

        // Create a render pass to use the texture as a render target
        utils::ComboRenderPassDescriptor passDescriptor({}, view);
        passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load;
        passDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Store;

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

        // It is valid to use the texture as both sampled and readonly depth/stencil attachment in
        // the same pass
        {
            passDescriptor.cDepthStencilAttachmentInfo.depthReadOnly = true;
            passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Undefined;
            passDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Undefined;

            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&passDescriptor);
            pass.SetBindGroup(0, bg);
            pass.EndPass();
            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::StorageBinding |
                                                  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::StorageBinding);
            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 a single subresource of a texture cannot be used as a render attachment more than
    // once in the same pass.
    TEST_F(ResourceUsageTrackingTest, TextureWithMultipleRenderAttachmentUsage) {
        // Create a texture with two array layers
        wgpu::TextureDescriptor descriptor;
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.size = {1, 1, 2};
        descriptor.usage = wgpu::TextureUsage::RenderAttachment;
        descriptor.format = kFormat;

        wgpu::Texture texture = device.CreateTexture(&descriptor);

        wgpu::TextureViewDescriptor viewDesc = {};
        viewDesc.arrayLayerCount = 1;

        wgpu::TextureView viewLayer0 = texture.CreateView(&viewDesc);

        viewDesc.baseArrayLayer = 1;
        wgpu::TextureView viewLayer1 = texture.CreateView(&viewDesc);

        // Control: It is valid to use layer0 as a render target for one attachment, and
        // layer1 as the second attachment in the same pass
        {
            utils::ComboRenderPassDescriptor renderPass({viewLayer0, viewLayer1});

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

        // Control: It is valid to use layer0 as a render target in separate passes.
        {
            utils::ComboRenderPassDescriptor renderPass({viewLayer0});

            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder pass0 = encoder.BeginRenderPass(&renderPass);
            pass0.EndPass();
            wgpu::RenderPassEncoder pass1 = encoder.BeginRenderPass(&renderPass);
            pass1.EndPass();
            encoder.Finish();
        }

        // It is invalid to use layer0 as a render target for both attachments in the same pass
        {
            utils::ComboRenderPassDescriptor renderPass({viewLayer0, viewLayer0});

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

        // It is invalid to use layer1 as a render target for both attachments in the same pass
        {
            utils::ComboRenderPassDescriptor renderPass({viewLayer1, viewLayer1});

            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
            pass.EndPass();
            ASSERT_DEVICE_ERROR(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::TextureBinding |
                                             wgpu::TextureUsage::RenderAttachment);
            wgpu::TextureView v0 = t0.CreateView();
            wgpu::Texture t1 = CreateTexture(wgpu::TextureUsage::TextureBinding |
                                             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::TextureBinding |
                                                  wgpu::TextureUsage::StorageBinding);
            wgpu::TextureView view = texture.CreateView();

            // Create bind groups to use the texture as sampled and writeonly bindings
            wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float}});
            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 sampled 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::TextureBinding |
                                                  wgpu::TextureUsage::StorageBinding);
            wgpu::TextureView view = texture.CreateView();

            // Create bind groups to use the texture as sampled 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::TextureSampleType::Float}});
            wgpu::BindGroup writeBG = utils::MakeBindGroup(device, writeBGL, {{0, view}});
            wgpu::BindGroup readBG = utils::MakeBindGroup(device, readBGL, {{0, view}});

            // Use the texture as writeonly and sampled 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::TextureBinding | wgpu::TextureUsage::StorageBinding);
        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 sampled and writeonly storage bindings
            wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float}});
            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::TextureBinding | wgpu::TextureUsage::StorageBinding);
        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 sampled and writeonly storage bindings
            wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float}});
            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::TextureBinding |
                          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::TextureBinding |
                                                   wgpu::TextureUsage::RenderAttachment);
            wgpu::TextureView view0 = texture0.CreateView();
            wgpu::Texture texture1 = CreateTexture(wgpu::TextureUsage::TextureBinding |
                                                   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::TextureBinding |
                                                   wgpu::TextureUsage::StorageBinding);
            wgpu::TextureView view0 = texture0.CreateView();
            wgpu::Texture texture1 = CreateTexture(wgpu::TextureUsage::TextureBinding);
            wgpu::TextureView view1 = texture1.CreateView();

            // Create the bind group to use the texture as sampled 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::TextureSampleType::Float}});

            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 sampled 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 sampled 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::TextureBinding | wgpu::TextureUsage::StorageBinding);
        wgpu::TextureView view = texture.CreateView();

        // Test render pass for bind group. The conflict of sampled 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::TextureSampleType::Float},
                 {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 sampled 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::TextureSampleType::Float},
                 {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::TextureBinding | wgpu::TextureUsage::StorageBinding |
                          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 sampled storage in compute stage
            wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float}});
            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::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});

            // 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::TextureBinding | wgpu::TextureUsage::StorageBinding);
        wgpu::TextureView view = texture.CreateView();

        // Create bind groups.
        wgpu::BindGroupLayout readBGL = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute,
                      wgpu::TextureSampleType::Float}});
        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 sampled 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_2d<f32>;
                @stage(fragment) fn main() {
                })");
            utils::ComboRenderPipelineDescriptor pipelineDescriptor;
            pipelineDescriptor.vertex.module = vsModule;
            pipelineDescriptor.cFragment.module = fsModule;
            pipelineDescriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;
            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
