// Copyright 2025 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <string>
#include <unordered_set>
#include <utility>
#include <variant>
#include <vector>

#include "absl/strings/str_format.h"
#include "src/dawn/common/Enumerator.h"
#include "src/dawn/common/Range.h"
#include "src/dawn/tests/DawnTest.h"
#include "src/dawn/utils/ComboRenderBundleEncoderDescriptor.h"
#include "src/dawn/utils/ComboRenderPipelineDescriptor.h"
#include "src/dawn/utils/ScopedIgnoreValidationErrors.h"
#include "src/dawn/utils/WGPUHelpers.h"
#include "src/utils/numeric.h"

namespace dawn {
namespace {

// The number of unique default samplers on D3D12, derived form ResourceTableDefaultResources.
// These necessarily take up a couple of slots in a resource table.
constexpr uint32_t kUniqueDefaultSamplers = 2;
// On D3D12, the max number of unique sampler descriptors available to the user in a ResourceTable.
constexpr uint32_t kD3D12MaxUniqueSamplers = 2048 - kUniqueDefaultSamplers;

class ResourceTableTests : public DawnTest {
  protected:
    void SetUp() override {
        DawnTest::SetUp();
        DAWN_TEST_UNSUPPORTED_IF(
            !SupportsFeatures({wgpu::FeatureName::ChromiumExperimentalSamplingResourceTable}));

        // Swiftshader doesn't support variable count descriptor sets used in draw operations. In
        // vk::DescriptorSet::ParseDescriptors it iterates over all the descriptors to prep various
        // things but iterates over the whole size defined in the vkDescriptorSetLayout instead of
        // taking into account the variable count.
        DAWN_SUPPRESS_TEST_IF(IsSwiftshader());
    }

    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        if (SupportsFeatures({wgpu::FeatureName::ChromiumExperimentalSamplingResourceTable})) {
            return {wgpu::FeatureName::ChromiumExperimentalSamplingResourceTable};
        }
        return {};
    }

    wgpu::ResourceTable MakeResourceTable(
        uint32_t size,
        std::vector<std::pair<uint32_t, wgpu::BindingResource>> resources = {}) {
        wgpu::ResourceTableDescriptor desc;
        desc.size = size;
        wgpu::ResourceTable table = device.CreateResourceTable(&desc);

        for (auto& [slot, resource] : resources) {
            EXPECT_EQ(wgpu::Status::Success, table.Update(slot, &resource));
        }

        return table;
    }

    wgpu::TextureView CreateViewForTable(const wgpu::Texture& tex) {
        wgpu::TextureViewDescriptor desc;
        desc.usage = wgpu::TextureUsage::TextureBinding;
        return tex.CreateView(&desc);
    }

    std::vector<wgpu::BindGroupEntry> MakeBindGroupEntries(
        std::vector<std::pair<uint32_t, wgpu::BindingResource>> resources) {
        std::vector<wgpu::BindGroupEntry> entries;
        for (auto& r : resources) {
            wgpu::BindGroupEntry entry;
            entry.binding = r.first;
            DAWN_ASSERT(r.second.textureView);
            entry.textureView = r.second.textureView;
            entries.push_back(entry);
        }
        return entries;
    }

    wgpu::PipelineLayout MakePipelineLayoutWithTable(std::vector<wgpu::BindGroupLayout> bgls = {},
                                                     uint32_t immediateSize = 0) {
        wgpu::PipelineLayoutResourceTable plTable;
        plTable.usesResourceTable = true;

        wgpu::PipelineLayoutDescriptor desc{
            .nextInChain = &plTable,
            .bindGroupLayoutCount = bgls.size(),
            .bindGroupLayouts = bgls.data(),
            .immediateSize = immediateSize,
        };

        return device.CreatePipelineLayout(&desc);
    }

    // Test that the `table` has resources of `wgslType` in the `expected` slots.
    // If provided, creates a bind group 1 with 'bindGroupEntries' with resources of type
    // `bindGroupWgslType`.
    void TestHasResource(wgpu::ResourceTable table,
                         std::vector<bool> expected,
                         std::string wgslType = "texture_2d<f32>",
                         std::vector<wgpu::BindGroupEntry> bindGroupEntries = {},
                         std::string bindGroupWgslType = "texture_2d<f32>") {
        ASSERT_EQ(table.GetSize(), expected.size());

        std::string shader = R"(
            enable chromium_experimental_resource_table;

            @group(0) @binding(0) var<storage, read_write> results : array<u32>;
            var<immediate> resourceCount : u32;
            @compute @workgroup_size(1) fn main() {
                for (var i = 0u; i < resourceCount; i++) {
                    results[i] = u32(hasResource<)" +
                             wgslType + R"(>(i));
                }

                referenceTextures();
            }
        )";

        // If provided, add bindings in group(1)
        if (!bindGroupEntries.empty()) {
            for (auto entry : bindGroupEntries) {
                shader += absl::StrFormat("@group(1) @binding(%1$u) var tex%1$u : %2$s;\n",
                                          entry.binding, bindGroupWgslType);
            }
            shader += "fn referenceTextures() {\n";
            for (auto entry : bindGroupEntries) {
                shader +=
                    absl::StrFormat("let d%1$u = textureDimensions(tex%1$u);\n", entry.binding);
            }
            shader += "}\n";
        } else {
            shader += "fn referenceTextures() {}\n";
        }

        // Create the test pipeline.
        wgpu::ShaderModule module = utils::CreateShaderModule(device, shader);
        wgpu::ComputePipelineDescriptor csDesc = {.compute = {
                                                      .module = module,
                                                  }};
        wgpu::ComputePipeline testPipeline = device.CreateComputePipeline(&csDesc);

        // Create the result buffer.
        wgpu::BufferDescriptor bDesc = {
            .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
            .size = sizeof(uint32_t) * expected.size(),
        };
        wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);
        wgpu::BindGroup resultBG =
            utils::MakeBindGroup(device, testPipeline.GetBindGroupLayout(0), {{0, resultBuffer}});
        uint32_t resourceCount = table.GetSize();

        wgpu::BindGroup bindGroupToHideSlots;
        if (!bindGroupEntries.empty()) {
            wgpu::BindGroupDescriptor descriptor;
            descriptor.layout = testPipeline.GetBindGroupLayout(1);
            descriptor.entryCount = checked_cast<uint32_t>(bindGroupEntries.size());
            descriptor.entries = bindGroupEntries.data();
            bindGroupToHideSlots = device.CreateBindGroup(&descriptor);
        }

        // Run the test.
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetResourceTable(table);
        pass.SetImmediates(0, &resourceCount, sizeof(resourceCount));
        pass.SetBindGroup(0, resultBG);
        if (bindGroupToHideSlots) {
            pass.SetBindGroup(1, bindGroupToHideSlots);
        }
        pass.SetPipeline(testPipeline);
        pass.DispatchWorkgroups(1);
        pass.End();

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

        // Check we have the expected results.
        std::vector<uint32_t> expectedU32;
        for (bool b : expected) {
            expectedU32.push_back(b ? 1u : 0u);
        }

        EXPECT_BUFFER_U32_RANGE_EQ(expectedU32.data(), resultBuffer, 0, expectedU32.size())
            << " for WGSL type " << wgslType;
    }

    void DoSomeWorkInSubmit() {
        wgpu::BufferDescriptor bufDesc = {
            .usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::CopySrc,
            .size = 4,
        };
        wgpu::Buffer src = device.CreateBuffer(&bufDesc);
        wgpu::Buffer dst = device.CreateBuffer(&bufDesc);

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        encoder.CopyBufferToBuffer(src, 0, dst, 0, 4);

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

    wgpu::TextureView MakeU8View(uint8_t value) {
        // Create the texture.
        wgpu::TextureDescriptor tDesc{
            .usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopyDst,
            .size = {1, 1},
            .format = wgpu::TextureFormat::R8Uint,
        };
        wgpu::Texture tex = device.CreateTexture(&tDesc);

        // Write the u8
        wgpu::TexelCopyTextureInfo srcInfo = utils::CreateTexelCopyTextureInfo(tex);
        wgpu::TexelCopyBufferLayout dstInfo = {};
        wgpu::Extent3D copySize = {1, 1, 1};
        queue.WriteTexture(&srcInfo, &value, 1, &dstInfo, &copySize);

        // Return a view to the texture.
        return tex.CreateView();
    }

    // For each table in `cases`, sets the `table` and dipatches on a compute pass encoder,
    // and validates that each `table` has a texture_2d<u32> iff the `expected` has a value, and
    // that the textures have the expected value, if any.
    struct TableAndExpected {
        wgpu::ResourceTable table;
        std::vector<std::optional<uint8_t>> expected;
    };
    void TestHasU8BindingsCompute(std::vector<TableAndExpected> cases) {
        wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
            enable chromium_experimental_resource_table;

            @group(0) @binding(0) var<storage, read_write> results : array<u32>;
            struct Immediates {
                resourceCount : u32,
                offset : u32,
            }
            var<immediate> immediates : Immediates;
            @compute @workgroup_size(1) fn main() {
                for (var i = 0u; i < immediates.resourceCount; i++) {
                    if !hasResource<texture_2d<u32>>(i) {
                        results[immediates.offset + i] = 0xBEEF;
                    } else {
                        let tex = getResource<texture_2d<u32>>(i);
                        results[immediates.offset + i] = textureLoad(tex, vec2(0), 0).x;
                    }
                }
            }
        )");

        // Make the result buffer large enough for all cases
        size_t resultSize = 0;
        for (auto& [table, expected] : cases) {
            ASSERT_EQ(table.GetSize(), expected.size());
            resultSize += expected.size();
        }

        wgpu::ComputePipelineDescriptor csDesc = {.compute = {
                                                      .module = module,
                                                  }};
        wgpu::ComputePipeline testPipeline = device.CreateComputePipeline(&csDesc);

        // Create the result buffer.
        wgpu::BufferDescriptor bDesc = {
            .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
            .size = sizeof(uint32_t) * resultSize,
        };
        wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);
        wgpu::BindGroup resultBG =
            utils::MakeBindGroup(device, testPipeline.GetBindGroupLayout(0), {{0, resultBuffer}});

        // Run the test.
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        uint32_t offset = 0;
        for (auto& [table, expected] : cases) {
            pass.SetResourceTable(table);

            uint32_t immediates[] = {table.GetSize(), offset};
            pass.SetImmediates(0, &immediates, sizeof(immediates));
            offset += expected.size();

            pass.SetBindGroup(0, resultBG);

            pass.SetPipeline(testPipeline);
            pass.DispatchWorkgroups(1);
        }
        pass.End();

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

        // Check we have the expected results.
        std::vector<uint32_t> expectedU32;
        for (auto& [_, expected] : cases) {
            for (auto optValue : expected) {
                expectedU32.push_back(optValue ? *optValue : 0xBEEFu);
            }
        }

        EXPECT_BUFFER_U32_RANGE_EQ(expectedU32.data(), resultBuffer, 0, expectedU32.size());
    }

    // For each table in `cases`, sets the `table` and dipatches on a render pass/bundle encoder,
    // and validates that each `table` has a texture_2d<u32> iff the `expected` has a value, and
    // that the textures have the expected value, if any.
    void TestHasU8BindingsRender(std::vector<TableAndExpected> cases, bool useRenderBundles) {
        wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
            enable chromium_experimental_resource_table;

            @vertex fn vs() -> @builtin(position) vec4f {
                return vec4f(0, 0, 0.5, 0.5);
            }

            @group(0) @binding(0) var<storage, read_write> results : array<u32>;
            struct Immediates {
                resourceCount : u32,
                offset : u32,
            }
            var<immediate> immediates : Immediates;

            @fragment fn main() -> @location(0) vec4f {
                for (var i = 0u; i < immediates.resourceCount; i++) {
                    if !hasResource<texture_2d<u32>>(i) {
                        results[immediates.offset + i] = 0xBEEF;
                    } else {
                        let tex = getResource<texture_2d<u32>>(i);
                        results[immediates.offset + i] = textureLoad(tex, vec2(0), 0).x;
                    }
                }
                return vec4();
            }
        )");

        // Make the result buffer large enough for all cases
        size_t resultSize = 0;
        for (auto& [table, expected] : cases) {
            ASSERT_EQ(table.GetSize(), expected.size());
            resultSize += expected.size();
        }

        wgpu::BindGroupLayout resultBGL = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage}});

        wgpu::RenderPipeline testPipeline;
        {
            utils::ComboRenderPipelineDescriptor desc;
            desc.layout = MakePipelineLayoutWithTable({resultBGL}, 8);
            desc.vertex.module = module;
            desc.cFragment.module = module;
            desc.primitive.topology = wgpu::PrimitiveTopology::PointList;
            testPipeline = device.CreateRenderPipeline(&desc);
        }

        // Create the result buffer.
        wgpu::BufferDescriptor bDesc = {
            .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
            .size = sizeof(uint32_t) * resultSize,
        };
        wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);
        wgpu::BindGroup resultBG = utils::MakeBindGroup(device, resultBGL, {{0, resultBuffer}});

        // Run the test.
        auto rp = utils::CreateBasicRenderPass(device, 1, 1);
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&rp.renderPassInfo);

        if (useRenderBundles) {
            utils::ComboRenderBundleEncoderDescriptor desc = {};
            desc.colorFormatCount = 1;
            desc.cColorFormats[0] = rp.colorFormat;
            wgpu::RenderBundleEncoder rbe = device.CreateRenderBundleEncoder(&desc);

            uint32_t offset = 0;
            for (auto& [table, expected] : cases) {
                uint32_t immediates[] = {table.GetSize(), offset};
                rbe.SetResourceTable(table);
                rbe.SetImmediates(0, &immediates, sizeof(immediates));
                rbe.SetBindGroup(0, resultBG);
                rbe.SetPipeline(testPipeline);
                rbe.Draw(1);
                offset += expected.size();
            }

            wgpu::RenderBundle bundle = rbe.Finish();
            pass.ExecuteBundles(1, &bundle);
        } else {
            uint32_t offset = 0;
            for (auto& [table, expected] : cases) {
                uint32_t immediates[] = {table.GetSize(), offset};
                pass.SetResourceTable(table);
                pass.SetImmediates(0, &immediates, sizeof(immediates));
                pass.SetBindGroup(0, resultBG);
                pass.SetPipeline(testPipeline);
                pass.Draw(1);
                offset += expected.size();
            }
        }
        pass.End();

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

        // Check we have the expected results.
        std::vector<uint32_t> expectedU32;
        for (auto& [_, expected] : cases) {
            for (auto optValue : expected) {
                expectedU32.push_back(optValue ? *optValue : 0xBEEFu);
            }
        }

        EXPECT_BUFFER_U32_RANGE_EQ(expectedU32.data(), resultBuffer, 0, expectedU32.size());
    }

    // Convenience that tests cases using compute, render, and render bundle encoders
    void TestHasU8BindingsAll(std::vector<TableAndExpected> cases) {
        TestHasU8BindingsCompute(cases);
        TestHasU8BindingsRender(cases, true);
        TestHasU8BindingsRender(cases, false);
    }

    // Convenience for single table
    void TestHasU8BindingsAll(wgpu::ResourceTable table,
                              std::vector<std::optional<uint8_t>> expected) {
        TestHasU8BindingsAll({{table, expected}});
    }

    // Creates a sampler by address mode
    wgpu::Sampler CreateSampler(wgpu::AddressMode mode,
                                wgpu::CompareFunction compare = wgpu::CompareFunction::Undefined) {
        wgpu::SamplerDescriptor descriptor = {};
        descriptor.addressModeU = mode;
        descriptor.addressModeV = mode;
        descriptor.addressModeW = mode;
        descriptor.compare = compare;
        return device.CreateSampler(&descriptor);
    }

    // Creates a 2x2 checkerboard texture, with red in the top left and bottom right corners, green
    // in the other two.
    wgpu::Texture CreateCheckerboardTexture() {
        wgpu::TextureDescriptor descriptor;
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.size = {2, 2};
        descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
        descriptor.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::TextureBinding;
        auto texture = device.CreateTexture(&descriptor);

        const uint32_t rowPixels = kTextureBytesPerRowAlignment / sizeof(utils::RGBA8);
        std::array<utils::RGBA8, rowPixels * 2> pixels;
        pixels[0] = pixels[rowPixels + 1] = utils::RGBA8::kRed;
        pixels[1] = pixels[rowPixels] = utils::RGBA8::kGreen;

        wgpu::TexelCopyTextureInfo srcInfo =
            utils::CreateTexelCopyTextureInfo(texture, 0, {0, 0, 0});
        wgpu::TexelCopyBufferLayout dstInfo = {};
        dstInfo.bytesPerRow = kTextureBytesPerRowAlignment;
        wgpu::Extent3D copySize = {2, 2, 1};
        queue.WriteTexture(&srcInfo, pixels.data(), pixels.size() * sizeof(utils::RGBA8), &dstInfo,
                           &copySize);

        return texture;
    }

    wgpu::Texture CreateColorTexture(utils::RGBA8 color) {
        wgpu::TextureDescriptor descriptor;
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.size = {1, 1};
        descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
        descriptor.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::TextureBinding;
        auto texture = device.CreateTexture(&descriptor);

        const uint32_t rowPixels = kTextureBytesPerRowAlignment / sizeof(utils::RGBA8);
        std::array<utils::RGBA8, rowPixels> pixels;
        pixels[0] = color;

        wgpu::TexelCopyTextureInfo srcInfo =
            utils::CreateTexelCopyTextureInfo(texture, 0, {0, 0, 0});
        wgpu::TexelCopyBufferLayout dstInfo = {};
        dstInfo.bytesPerRow = kTextureBytesPerRowAlignment;
        wgpu::Extent3D copySize = {1, 1, 1};
        queue.WriteTexture(&srcInfo, pixels.data(), pixels.size() * sizeof(utils::RGBA8), &dstInfo,
                           &copySize);

        return texture;
    }

    wgpu::Sampler CreateUniqueSampler(uint32_t i) {
        // Make samplers unique by making one of the values different for each
        wgpu::SamplerDescriptor descriptor;
        descriptor.lodMinClamp = (i + 1) / 1000.0f;
        return device.CreateSampler(&descriptor);
    }
};

// Test that creating resource tables doesn't crash in backends.
TEST_P(ResourceTableTests, ResourceTableCreation) {
    // Creating an empty resource table.
    MakeResourceTable(0);

    // Creating a resource table with a few entries.
    MakeResourceTable(36);

    // Creating a resource table with the maximum number of entries.
    MakeResourceTable(kMaxResourceTableSize);
}

// Test that creating pipeline layouts with resources tables doesn't crash in backends.
TEST_P(ResourceTableTests, PipelineLayoutWithResourceTableCreation) {
    // Make layouts with no BGLs with / without immediates.
    MakePipelineLayoutWithTable({}, 0);
    MakePipelineLayoutWithTable({}, 4);

    // Make layouts with one BGL, with / without immediates.
    wgpu::BindGroupLayout testBgl = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Uniform}});
    MakePipelineLayoutWithTable({testBgl}, 0);
    MakePipelineLayoutWithTable({testBgl}, 4);

    // Make layouts with max BGLs (3 because the resource tables "consumes" one bind group), with /
    // without immediates.
    MakePipelineLayoutWithTable({testBgl, testBgl, testBgl}, 0);
    MakePipelineLayoutWithTable({testBgl, testBgl, testBgl}, 4);
}

// Test that creating pipelines that use resource tables doesn't crash in backends.
TEST_P(ResourceTableTests, ShaderWithResourceTableCreation) {
    wgpu::ComputePipelineDescriptor csDesc;

    // Test compiling a pipeline using only the resource table.
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;
        @compute @workgroup_size(1) fn main() {
            _ = hasResource<texture_2d<f32>>(0);
        }
    )");
    device.CreateComputePipeline(&csDesc);

    // Test compiling a pipeline using the resource table and a bindgroup.
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;
        @group(0) @binding(0) var t0 : texture_2d<f32>;
        @compute @workgroup_size(1) fn main() {
            _ = hasResource<texture_2d<f32>>(0);
            _ = t0;
        }
    )");
    device.CreateComputePipeline(&csDesc);

    // Test compiling a pipeline using the resource table and many bindgroup.
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;
        @group(0) @binding(0) var t0 : texture_2d<f32>;
        @group(1) @binding(0) var t1 : texture_2d<f32>;
        @group(2) @binding(0) var t2 : texture_2d<f32>;
        @compute @workgroup_size(1) fn main() {
            _ = hasResource<texture_2d<f32>>(0);
            _ = t0;
            _ = t1;
            _ = t2;
        }
    )");
    device.CreateComputePipeline(&csDesc);
}

// Test that creating resource tables of different sizes doesn't end up reusing incorrectly sized
// allocations.
TEST_P(ResourceTableTests, RecyclingDoesntReuseTooSmallAllocation) {
    for (uint32_t i = 0; i < 10; i++) {
        MakeResourceTable(i);

        // Wait to ensure some deallocation happens and has a chance to cause incorrect recycling.
        WaitForAllOperations();
    }
}

// Test WGSL `hasResource` reflects the state of the resource table.
TEST_P(ResourceTableTests, HasResourceOneTexture) {
    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::StorageBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::RGBA8Unorm,
    };
    wgpu::Texture tex = device.CreateTexture(&tDesc);

    wgpu::ResourceTable table =
        MakeResourceTable(3, {{1, {.textureView = CreateViewForTable(tex)}}});
    auto bge = MakeBindGroupEntries({{0, {.textureView = tex.CreateView()}}});

    // Table bound textures are visible by default
    TestHasResource(table, {false, true, false}, "texture_2d<f32>");

    // If the texture is also in a bind group as writable, it hides the same texture in the table
    TestHasResource(table, {false, false, false}, "texture_2d<f32>", bge,
                    "texture_storage_2d<rgba8unorm, write>");

    // But if it's bound as readonly, it doesn't hide it
    TestHasResource(table, {false, true, false}, "texture_2d<f32>", bge, "texture_2d<f32>");
}

// Test WGSL `hasResource` reflects the state of the resource table.
TEST_P(ResourceTableTests, HasResourceFilterableToUnfilterable) {
    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R8Unorm,
    };
    wgpu::Texture tex = device.CreateTexture(&tDesc);

    wgpu::ResourceTable table = MakeResourceTable(3, {{1, {.textureView = tex.CreateView()}}});

    TestHasResource(table, {false, true, false}, "texture_2d<f32>");
}

// Test that calling texture.Destroy() implicitly hides it.
// TODO(crbug.com/530981418): Add similar test for EndAccess
TEST_P(ResourceTableTests, HasResourceOneTextureDestroy) {
    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R8Unorm,
    };
    wgpu::Texture tex = device.CreateTexture(&tDesc);

    wgpu::ResourceTable table = MakeResourceTable(3, {{1, {.textureView = tex.CreateView()}}});

    // Has one valid entry
    TestHasResource(table, {false, true, false});

    // After texture destruction it has the no more valid entries.
    tex.Destroy();
    TestHasResource(table, {false, false, false});
}

// Test that a texture used multiple times in the same table has its availability correctly updated.
TEST_P(ResourceTableTests, HasResourceSameTextureMultipleTimes) {
    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::StorageBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::RGBA8Unorm,
    };
    wgpu::Texture tex = device.CreateTexture(&tDesc);

    wgpu::ResourceTable table =
        MakeResourceTable(4, {
                                 {1, {.textureView = CreateViewForTable(tex)}},
                                 {3, {.textureView = CreateViewForTable(tex)}},
                             });

    auto bge = MakeBindGroupEntries({{0, {.textureView = tex.CreateView()}}});

    // Table bound textures are visible by default
    TestHasResource(table, {false, true, false, true});

    // If the texture is also in a bind group as writable, it hides the same texture in the table
    TestHasResource(table, {false, false, false, false}, "texture_2d<f32>", bge,
                    "texture_storage_2d<rgba8unorm, write>");

    // But if it's bound as readonly, it doesn't hide it
    TestHasResource(table, {false, true, false, true}, "texture_2d<f32>", bge, "texture_2d<f32>");
}

// Test that updating a table with an already destroyed texture works, but doesn't show that entry
// as available.
// TODO(crbug.com/530981418): Add similar test for EndAccess
TEST_P(ResourceTableTests, HasResourceUpdateWithTextureAlreadyDestroyed) {
    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R8Unorm,
    };
    wgpu::Texture tex = device.CreateTexture(&tDesc);
    tex.Destroy();

    wgpu::ResourceTable table = MakeResourceTable(1, {{0, {.textureView = tex.CreateView()}}});

    TestHasResource(table, {false});
}

// Test that a texture used in multiple resource tables has its availability correctly updated.
// TODO(crbug.com/522749739): Add similar test for EndAccess
TEST_P(ResourceTableTests, HasResourceSameTextureMultipleTables) {
    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R8Unorm,
    };
    wgpu::Texture tex = device.CreateTexture(&tDesc);

    wgpu::ResourceTable table1 = MakeResourceTable(3, {{1, {.textureView = tex.CreateView()}}});
    wgpu::ResourceTable table2 = MakeResourceTable(1, {{0, {.textureView = tex.CreateView()}}});

    // Table bound textures are visible by default
    TestHasResource(table1, {false, true, false});
    TestHasResource(table2, {true});

    // After destroying one table, the other still has the texture available.
    table1.Destroy();
    TestHasResource(table2, {true});
}

// Test that texture availabililty is controlled per-texture.
TEST_P(ResourceTableTests, HasResourceMultipleTexturesTable) {
    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::StorageBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::RGBA8Unorm,
    };
    wgpu::Texture tex0 = device.CreateTexture(&tDesc);
    wgpu::Texture tex1 = device.CreateTexture(&tDesc);

    wgpu::ResourceTable table =
        MakeResourceTable(2, {
                                 {0, {.textureView = CreateViewForTable(tex0)}},
                                 {1, {.textureView = CreateViewForTable(tex1)}},
                             });
    auto bge0 = MakeBindGroupEntries({{5, {.textureView = tex0.CreateView()}}});
    auto bge1 = MakeBindGroupEntries({{6, {.textureView = tex1.CreateView()}}});
    auto bgeBoth = MakeBindGroupEntries(
        {{5, {.textureView = tex0.CreateView()}}, {6, {.textureView = tex1.CreateView()}}});

    // Both visible by default
    TestHasResource(table, {true, true}, "texture_2d<f32>");

    // Both hidden if both are writable in bindgroup
    TestHasResource(table, {false, false}, "texture_2d<f32>", bgeBoth,
                    "texture_storage_2d<rgba8unorm, write>");

    // First hidden if first is writable in bindgroup
    TestHasResource(table, {false, true}, "texture_2d<f32>", bge0,
                    "texture_storage_2d<rgba8unorm, write>");

    // Second hidden if second is writable in bindgroup
    TestHasResource(table, {true, false}, "texture_2d<f32>", bge1,
                    "texture_storage_2d<rgba8unorm, write>");

    // Both visible if both are readonly in bindgroup
    TestHasResource(table, {true, true}, "texture_2d<f32>", bgeBoth, "texture_2d<f32>");
}

// Test that writing to a texture in a render pass implicitly hides it in the resource table.
// TODO(crbug.com/522749739): TestHasResource is used to test this with compute shaders. Consider
// making TestHasResource test both for compute and render passes.
TEST_P(ResourceTableTests, ImplicitHidingRender) {
    // TODO(https://issues.chromium.org/issues/530631417): Fails on PowerVR DXT-48-1536
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        @vertex fn main(@builtin(vertex_index) VertexIndex : u32) -> @builtin(position) vec4f {
            var pos = array<vec2f, 3>(
                vec2f(-1.0, -1.0),
                vec2f(3.0, -1.0),
                vec2f(-1.0, 3.0)
            );
            return vec4f(pos[VertexIndex], 0.0, 1.0);
        }
    )");

    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;

        @group(0) @binding(0) var<storage, read_write> results : array<u32>;

        @fragment fn main() -> @location(0) u32 {
            let hasRead = hasResource<texture_2d<u32>>(0);
            results[0] = u32(hasRead);
            return 0u;
        }
    )");

    utils::ComboRenderPipelineDescriptor descriptor;
    descriptor.vertex.module = vsModule;
    descriptor.cFragment.module = fsModule;
    descriptor.cFragment.targetCount = 1;
    descriptor.cTargets[0].format = wgpu::TextureFormat::R32Uint;
    descriptor.layout = nullptr;

    wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);

    // Create textures.
    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment |
                 wgpu::TextureUsage::CopyDst,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R32Uint,
    };
    wgpu::Texture texA = device.CreateTexture(&tDesc);
    wgpu::Texture texB = device.CreateTexture(&tDesc);

    // Create result buffer.
    wgpu::BufferDescriptor bDesc = {
        .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
        .size = 1 * sizeof(uint32_t),
    };
    wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);

    // Create resource table containing texA.
    wgpu::ResourceTable table =
        MakeResourceTable(1, {{0, {.textureView = CreateViewForTable(texA)}}});

    auto draw = [&](wgpu::Texture writeToTexture, bool expectHasResource) {
        wgpu::BindGroup bg = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                                  {
                                                      {0, resultBuffer},
                                                  });

        wgpu::RenderPassColorAttachment attachment = {
            .view = writeToTexture.CreateView(),
            .loadOp = wgpu::LoadOp::Clear,
            .storeOp = wgpu::StoreOp::Store,
            .clearValue = {0, 0, 0, 0},
        };
        wgpu::RenderPassDescriptor rpDesc = {
            .colorAttachmentCount = 1,
            .colorAttachments = &attachment,
        };

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&rpDesc);
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(0, bg);
        pass.SetResourceTable(table);
        pass.Draw(3);
        pass.End();
        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);

        uint32_t expected[] = {expectHasResource ? 1u : 0u};
        EXPECT_BUFFER_U32_RANGE_EQ(expected, resultBuffer, 0, 1);
    };

    // Read texA, write texB (different textures), hasResource(texA) should return true
    draw(texB, true);

    // Read texA, write texA (same texture), hasResource(texA) should return false (hidden)
    draw(texA, false);
}

// Test that we can hide a resource for one dispatch (using a storage texture write)
// and dynamically unhide it for the next dispatch (by removing the storage write)
// all within a single compute pass.
TEST_P(ResourceTableTests, ImplicitHidingComputeMidPass) {
    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;

        @group(0) @binding(0) var<storage, read_write> results : array<u32>;
        @group(0) @binding(1) var writeTex : texture_storage_2d<r32uint, write>;
        @group(0) @binding(2) var<uniform> dispatchIndex : u32;

        @compute @workgroup_size(1) fn main() {
            let hasRead = hasResource<texture_2d<u32>>(0);
            results[dispatchIndex] = u32(hasRead);
            if (dispatchIndex == 0u) {
                textureStore(writeTex, vec2u(0, 0), vec4u(123, 0, 0, 0));
            }
        }
    )");

    wgpu::ComputePipelineDescriptor csDesc = {.compute = {
                                                  .module = module,
                                              }};
    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&csDesc);

    // Create textures.
    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::StorageBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R32Uint,
    };
    wgpu::Texture texA = device.CreateTexture(&tDesc);
    wgpu::Texture texB = device.CreateTexture(&tDesc);

    // Create result buffer (4 elements: [hasRead0, val0, hasRead1, val1]).
    wgpu::BufferDescriptor bDesc = {
        .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
        .size = 2 * sizeof(uint32_t),
    };
    wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);

    // Create uniform buffers for dispatch indices.
    wgpu::Buffer dispatchIndex0 =
        utils::CreateBufferFromData(device, wgpu::BufferUsage::Uniform, {0u});
    wgpu::Buffer dispatchIndex1 =
        utils::CreateBufferFromData(device, wgpu::BufferUsage::Uniform, {1u});

    // Create resource table containing texA.
    wgpu::ResourceTable table =
        MakeResourceTable(1, {{0, {.textureView = CreateViewForTable(texA)}}});

    // Create bind groups.
    // bg0 writes to texA (causes hiding)
    wgpu::BindGroup bg0 = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                               {
                                                   {0, resultBuffer},
                                                   {1, texA.CreateView()},
                                                   {2, dispatchIndex0},
                                               });
    // bg1 writes to texB instead of texA (causes unhiding of texA)
    wgpu::BindGroup bg1 = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                               {
                                                   {0, resultBuffer},
                                                   {1, texB.CreateView()},
                                                   {2, dispatchIndex1},
                                               });

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
    pass.SetPipeline(pipeline);
    pass.SetResourceTable(table);

    // Dispatch 1: texA is bound for writing, should be hidden.
    pass.SetBindGroup(0, bg0);
    pass.DispatchWorkgroups(1);

    // Dispatch 2: texA is no longer bound for writing, should be unhidden.
    pass.SetBindGroup(0, bg1);
    pass.DispatchWorkgroups(1);

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

    uint32_t expected[] = {
        0,  // hidden
        1   // visible
    };
    EXPECT_BUFFER_U32_RANGE_EQ(expected, resultBuffer, 0, 2);
}

// Test that writing to a texture as a render attachment hides it for the entire render pass,
// and changing bind groups mid-pass does NOT unhide it.
// TODO(crbug.com/522749739): Also test writing to a depth attachment, including depthReadOnly.
TEST_P(ResourceTableTests, ImplicitHidingRenderMidPass) {
    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        @vertex fn main(@builtin(vertex_index) VertexIndex : u32) -> @builtin(position) vec4f {
            var pos = array<vec2f, 3>(
                vec2f(-1.0, -1.0),
                vec2f(3.0, -1.0),
                vec2f(-1.0, 3.0)
            );
            return vec4f(pos[VertexIndex], 0.0, 1.0);
        }
    )");

    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;

        @group(0) @binding(0) var<storage, read_write> results : array<u32>;
        @group(0) @binding(1) var<uniform> drawIndex : u32;
        @group(0) @binding(2) var writeTex : texture_storage_2d<r32uint, write>;

        @fragment fn main() -> @location(0) u32 {
            let hasRead = hasResource<texture_2d<u32>>(0);
            results[drawIndex] = u32(hasRead);
            if (drawIndex == 0u) {
                textureStore(writeTex, vec2u(0, 0), vec4u(123, 0, 0, 0));
            }
            return 0u;
        }
    )");

    utils::ComboRenderPipelineDescriptor desc;
    desc.vertex.module = vsModule;
    desc.cFragment.module = fsModule;
    desc.cFragment.targetCount = 1;
    desc.cTargets[0].format = wgpu::TextureFormat::R32Uint;
    wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&desc);

    // Create textures.
    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::StorageBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R32Uint,
    };
    wgpu::Texture texA = device.CreateTexture(&tDesc);
    wgpu::Texture texB = device.CreateTexture(&tDesc);

    // Create result buffer.
    wgpu::BufferDescriptor bDesc = {
        .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
        .size = 2 * sizeof(uint32_t),
    };
    wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);

    // Create uniform buffers for draw indices.
    wgpu::Buffer drawIndex0 = utils::CreateBufferFromData(device, wgpu::BufferUsage::Uniform, {0u});
    wgpu::Buffer drawIndex1 = utils::CreateBufferFromData(device, wgpu::BufferUsage::Uniform, {1u});

    // Create resource table containing texA.
    wgpu::ResourceTable table =
        MakeResourceTable(1, {{0, {.textureView = CreateViewForTable(texA)}}});

    // Create bind groups.
    // bg0 writes to texA (causes hiding)
    wgpu::BindGroup bg0 = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                               {
                                                   {0, resultBuffer},
                                                   {1, drawIndex0},
                                                   {2, texA.CreateView()},
                                               });
    // bg1 writes to texB instead of texA
    wgpu::BindGroup bg1 = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                               {
                                                   {0, resultBuffer},
                                                   {1, drawIndex1},
                                                   {2, texB.CreateView()},
                                               });

    utils::BasicRenderPass rp =
        utils::CreateBasicRenderPass(device, 1, 1, wgpu::TextureFormat::R32Uint);

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&rp.renderPassInfo);
    pass.SetPipeline(pipeline);
    pass.SetResourceTable(table);

    // Draw 1: writes to texA. texA should be hidden.
    pass.SetBindGroup(0, bg0);
    pass.Draw(3);

    // Draw 2: does not write to texA. But because it's a render pass, texA must remain hidden.
    pass.SetBindGroup(0, bg1);
    pass.Draw(3);

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

    uint32_t expected[] = {
        0,  // hidden
        0   // still hidden
    };
    EXPECT_BUFFER_U32_RANGE_EQ(expected, resultBuffer, 0, 2);
}

constexpr auto kWgslSampledTextureTypes = std::array{
    "texture_1d<f32>",
    "texture_1d<i32>",
    "texture_1d<u32>",
    "texture_2d<f32>",
    "texture_2d<i32>",
    "texture_2d<u32>",
    "texture_2d_array<f32>",
    "texture_2d_array<i32>",
    "texture_2d_array<u32>",
    "texture_cube<f32>",
    "texture_cube<i32>",
    "texture_cube<u32>",
    "texture_cube_array<f32>",
    "texture_cube_array<i32>",
    "texture_cube_array<u32>",
    "texture_3d<f32>",
    "texture_3d<i32>",
    "texture_3d<u32>",

    "texture_multisampled_2d<f32>",
    "texture_multisampled_2d<i32>",
    "texture_multisampled_2d<u32>",

    "texture_depth_2d",
    "texture_depth_2d_array",
    "texture_depth_cube",
    "texture_depth_cube_array",
    "texture_depth_multisampled_2d",

    "sampler",
    "sampler_comparison",
};

struct ResourceDescForTypeIDCase {
    // Set of all WGSL types that can be validly bound to the underlying resource described by
    // `desc`.
    std::unordered_set<std::string_view> wgslTypes;

    struct TextureDesc {
        wgpu::TextureFormat format;
        wgpu::TextureDimension dimension;
        wgpu::TextureViewDimension viewDimension = wgpu::TextureViewDimension::Undefined;
        uint32_t sampleCount = 1;
        wgpu::TextureAspect viewAspect = wgpu::TextureAspect::All;
    };
    struct SamplerDesc {
        bool filtering = false;
        bool comparison = false;
    };
    // The descriptor used to create the resource
    std::variant<TextureDesc, SamplerDesc> desc;

    // Create a view for a texture for this case.
    wgpu::TextureView CreateTestView(const wgpu::Device& device) {
        auto& d = std::get<TextureDesc>(desc);

        wgpu::TextureDescriptor tDesc = {
            .usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopySrc,
            .dimension = d.dimension,
            .size = {1, 1, 1},
            .format = d.format,
            .sampleCount = d.sampleCount,
        };
        if (d.viewDimension == wgpu::TextureViewDimension::Cube ||
            d.viewDimension == wgpu::TextureViewDimension::CubeArray) {
            tDesc.size.depthOrArrayLayers = 6;
        }
        if (d.sampleCount != 1) {
            tDesc.usage |= wgpu::TextureUsage::RenderAttachment;
        }

        wgpu::TextureViewDescriptor vDesc{
            .dimension = d.viewDimension,
            .aspect = d.viewAspect,
            .usage = wgpu::TextureUsage::TextureBinding,
        };

        wgpu::Texture texture = device.CreateTexture(&tDesc);
        return texture.CreateView(&vDesc);
    }

    // Create a sampler for this case.
    wgpu::Sampler CreateTestSampler(const wgpu::Device& device) {
        auto& d = std::get<SamplerDesc>(desc);

        wgpu::SamplerDescriptor sDesc{};
        if (d.filtering) {
            sDesc.magFilter = wgpu::FilterMode::Linear;
            sDesc.minFilter = wgpu::FilterMode::Linear;
            sDesc.mipmapFilter = wgpu::MipmapFilterMode::Linear;
        }
        if (d.comparison) {
            sDesc.compare = wgpu::CompareFunction::Less;
        }
        return device.CreateSampler(&sDesc);
    }
};

std::vector<ResourceDescForTypeIDCase> MakeDescForTypeIDCases() {
    std::vector<ResourceDescForTypeIDCase> cases;

    using TextureDesc = ResourceDescForTypeIDCase::TextureDesc;
    using SamplerDesc = ResourceDescForTypeIDCase::SamplerDesc;

    // Regular 1D textures.
    cases.push_back({.wgslTypes = {{"texture_1d<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA8Unorm,
                         .dimension = wgpu::TextureDimension::e1D,
                     }});
    cases.push_back({.wgslTypes = {{"texture_1d<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Float,
                         .dimension = wgpu::TextureDimension::e1D,
                     }});
    cases.push_back({.wgslTypes = {{"texture_1d<i32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Sint,
                         .dimension = wgpu::TextureDimension::e1D,
                     }});
    cases.push_back({.wgslTypes = {{"texture_1d<u32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Uint,
                         .dimension = wgpu::TextureDimension::e1D,
                     }});

    // Regular 2D textures.
    cases.push_back({.wgslTypes = {{"texture_2d<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA8Unorm,
                         .dimension = wgpu::TextureDimension::e2D,
                     }});
    cases.push_back({.wgslTypes = {{"texture_2d<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Float,
                         .dimension = wgpu::TextureDimension::e2D,
                     }});
    cases.push_back({.wgslTypes = {{"texture_2d<i32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Sint,
                         .dimension = wgpu::TextureDimension::e2D,
                     }});
    cases.push_back({.wgslTypes = {{"texture_2d<u32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Uint,
                         .dimension = wgpu::TextureDimension::e2D,
                     }});

    // Regular 2D array textures.
    cases.push_back({.wgslTypes = {{"texture_2d_array<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA8Unorm,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::e2DArray,
                     }});
    cases.push_back({.wgslTypes = {{"texture_2d_array<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Float,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::e2DArray,
                     }});
    cases.push_back({.wgslTypes = {{"texture_2d_array<i32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Sint,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::e2DArray,
                     }});
    cases.push_back({.wgslTypes = {{"texture_2d_array<u32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Uint,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::e2DArray,
                     }});

    // Regular cube textures.
    cases.push_back({.wgslTypes = {{"texture_cube<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA8Unorm,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::Cube,
                     }});
    cases.push_back({.wgslTypes = {{"texture_cube<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Float,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::Cube,
                     }});
    cases.push_back({.wgslTypes = {{"texture_cube<i32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Sint,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::Cube,
                     }});
    cases.push_back({.wgslTypes = {{"texture_cube<u32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Uint,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::Cube,
                     }});

    // Regular cube array textures.
    cases.push_back({.wgslTypes = {{"texture_cube_array<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA8Unorm,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::CubeArray,
                     }});
    cases.push_back({.wgslTypes = {{"texture_cube_array<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Float,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::CubeArray,
                     }});
    cases.push_back({.wgslTypes = {{"texture_cube_array<i32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Sint,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::CubeArray,
                     }});
    cases.push_back({.wgslTypes = {{"texture_cube_array<u32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Uint,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::CubeArray,
                     }});

    // Regular 3d textures.
    cases.push_back({.wgslTypes = {{"texture_3d<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA8Unorm,
                         .dimension = wgpu::TextureDimension::e3D,
                     }});
    cases.push_back({.wgslTypes = {{"texture_3d<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Float,
                         .dimension = wgpu::TextureDimension::e3D,
                     }});
    cases.push_back({.wgslTypes = {{"texture_3d<i32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Sint,
                         .dimension = wgpu::TextureDimension::e3D,
                     }});
    cases.push_back({.wgslTypes = {{"texture_3d<u32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA32Uint,
                         .dimension = wgpu::TextureDimension::e3D,
                     }});

    // Color multisampled textures.
    cases.push_back({.wgslTypes = {{"texture_multisampled_2d<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA8Unorm,
                         .dimension = wgpu::TextureDimension::e2D,
                         .sampleCount = 4,
                     }});
    cases.push_back({.wgslTypes = {{"texture_multisampled_2d<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA16Float,
                         .dimension = wgpu::TextureDimension::e2D,
                         .sampleCount = 4,
                     }});
    cases.push_back({.wgslTypes = {{"texture_multisampled_2d<i32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA16Sint,
                         .dimension = wgpu::TextureDimension::e2D,
                         .sampleCount = 4,
                     }});
    cases.push_back({.wgslTypes = {{"texture_multisampled_2d<u32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::RGBA16Uint,
                         .dimension = wgpu::TextureDimension::e2D,
                         .sampleCount = 4,
                     }});

    // Depth textures (including multisampled).
    cases.push_back({.wgslTypes = {{"texture_depth_2d"}, {"texture_2d<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::Depth32Float,
                         .dimension = wgpu::TextureDimension::e2D,
                     }});
    cases.push_back({.wgslTypes = {{"texture_depth_2d_array"}, {"texture_2d_array<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::Depth32Float,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::e2DArray,
                     }});
    cases.push_back({.wgslTypes = {{"texture_depth_cube"}, {"texture_cube<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::Depth32Float,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::Cube,
                     }});
    cases.push_back({.wgslTypes = {{"texture_depth_cube_array"}, {"texture_cube_array<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::Depth32Float,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::CubeArray,
                     }});
    cases.push_back({.wgslTypes = {{"texture_depth_multisampled_2d"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::Depth32Float,
                         .dimension = wgpu::TextureDimension::e2D,
                         .sampleCount = 4,
                     }});

    // Stencil textures can be used as 2D.
    cases.push_back({.wgslTypes = {{"texture_2d<u32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::Stencil8,
                         .dimension = wgpu::TextureDimension::e2D,
                     }});
    cases.push_back({.wgslTypes = {{"texture_2d_array<u32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::Stencil8,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::e2DArray,
                     }});
    cases.push_back({.wgslTypes = {{"texture_cube<u32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::Stencil8,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::Cube,
                     }});
    cases.push_back({.wgslTypes = {{"texture_cube_array<u32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::Stencil8,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewDimension = wgpu::TextureViewDimension::CubeArray,
                     }});

    // Depth-stencil textures with only one aspect selected.
    cases.push_back({.wgslTypes = {{"texture_depth_2d"}, {"texture_2d<f32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::Depth24PlusStencil8,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewAspect = wgpu::TextureAspect::DepthOnly,
                     }});
    cases.push_back({.wgslTypes = {{"texture_2d<u32>"}},
                     .desc = TextureDesc{
                         .format = wgpu::TextureFormat::Depth24PlusStencil8,
                         .dimension = wgpu::TextureDimension::e2D,
                         .viewAspect = wgpu::TextureAspect::StencilOnly,
                     }});

    // Non-filtering sampler
    cases.push_back({
        .wgslTypes = {{"sampler"}},
        .desc = SamplerDesc{},
    });
    // Filtering sampler
    cases.push_back({
        .wgslTypes = {{"sampler"}},
        .desc =
            SamplerDesc{
                .filtering = true,
            },
    });
    // Comparison sampler
    cases.push_back({
        .wgslTypes = {{"sampler_comparison"}},
        .desc =
            SamplerDesc{
                .comparison = true,
            },
    });

    return cases;
}

// Test that hasResource() works as expected for all supported resources in WGSL.
TEST_P(ResourceTableTests, HasResourceCompatibilityAllTypes) {
    // We rely on RGBA32Float being unfilterable for this test so that we can test both filterable /
    // unfilterable float without needing any additional extensions.
    DAWN_ASSERT(!device.HasFeature(wgpu::FeatureName::Float32Filterable));

    auto cases = MakeDescForTypeIDCases();

    // Make a resource table with all of our test texture views.
    wgpu::ResourceTable table = MakeResourceTable(cases.size());
    for (auto [i, c] : Enumerate(cases)) {
        if (std::holds_alternative<ResourceDescForTypeIDCase::TextureDesc>(c.desc)) {
            wgpu::BindingResource resource = {.textureView = c.CreateTestView(device)};
            EXPECT_EQ(wgpu::Status::Success, table.Update(i, &resource));
        } else if (std::holds_alternative<ResourceDescForTypeIDCase::SamplerDesc>(c.desc)) {
            wgpu::BindingResource resource = {.sampler = c.CreateTestSampler(device)};
            EXPECT_EQ(wgpu::Status::Success, table.Update(i, &resource));
        }
    }

    // Test hasResource returning for each of the supported WGSL types, against each resource.
    for (auto wgslType : kWgslSampledTextureTypes) {
        std::vector<bool> expected;
        expected.reserve(cases.size());
        for (auto& c : cases) {
            // The reasons wgslTypes is a vector is because some textures can be
            // both filterable and non-filterable, so hasResource will return true for both types on
            // the one table entry with such a texture.
            expected.push_back(c.wgslTypes.contains(wgslType));
        }

        TestHasResource(table, expected, wgslType);
    }
}

// Test that calling hasResource() with values outside of the resource table size returns false.
TEST_P(ResourceTableTests, HasResourceOOBIsFalse) {
    // Create the test pipeline
    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;

        @group(0) @binding(0) var<storage, read_write> result : array<u32, 4>;
        var<immediate> resourceCount : u32;
        @compute @workgroup_size(1) fn getArrayLengths() {
            result[0] = u32(hasResource<texture_2d<f32>>(resourceCount - 1));
            result[1] = u32(hasResource<texture_2d<f32>>(resourceCount));

            // Check against all the slots where the default resources are.
            var result2 = 0u;
            for (var i = 1u; i < 100; i++) {
                result2 += u32(hasResource<texture_2d<f32>>(resourceCount + i));
            }
            result[2] = result2;

            result[3] = u32(hasResource<texture_2d<f32>>(resourceCount + 10000000));
        }
    )");
    wgpu::ComputePipelineDescriptor csDesc = {.compute = {
                                                  .module = module,
                                              }};
    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&csDesc);

    // Create the test resource table.
    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R8Unorm,
    };
    wgpu::Texture tex = device.CreateTexture(&tDesc);

    wgpu::ResourceTable table = MakeResourceTable(3, {
                                                         {0, {.textureView = tex.CreateView()}},
                                                         {1, {.textureView = tex.CreateView()}},
                                                         {2, {.textureView = tex.CreateView()}},
                                                     });

    // Create the other test resources.
    wgpu::BufferDescriptor bDesc = {
        .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
        .size = 4 * sizeof(uint32_t),
    };
    wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);
    wgpu::BindGroup resultBG =
        utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, resultBuffer}});
    uint32_t resourceCount = table.GetSize();

    // Run the test and check results are the expected ones.
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
    pass.SetResourceTable(table);
    pass.SetImmediates(0, &resourceCount, sizeof(resourceCount));
    pass.SetBindGroup(0, resultBG);
    pass.SetPipeline(pipeline);
    pass.DispatchWorkgroups(1);
    pass.End();

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

    EXPECT_BUFFER_U32_EQ(1, resultBuffer, 0);
    EXPECT_BUFFER_U32_EQ(0, resultBuffer, 4);
    EXPECT_BUFFER_U32_EQ(0, resultBuffer, 8);
    EXPECT_BUFFER_U32_EQ(0, resultBuffer, 12);
}

// Check that the default bindings are of size 1 and filled with zeroes. This is not an exhaustive
// test (that's for the CTS) but tries to check a few different interesting cases (MS, DS, Cube, 2D
// array).
TEST_P(ResourceTableTests, DefaultBindingsAreZeroAndSizeOne) {
    // TODO(crbug.com/385158827): Fails on older WARP 10.0.19041.5794
    DAWN_SUPPRESS_TEST_IF(IsWARP());

    // Create the test pipeline
    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;

        @group(0) @binding(0) var<storage, read_write> error : u32;
        @group(0) @binding(1) var s : sampler;

        var<private> checkIndex = 0u;
        fn check(b : bool) {
            if (!b && error == 0) {
                error = 1 + checkIndex;
            }
            checkIndex++;
        }

        @compute @workgroup_size(1) fn checkDefault() {
            // Default texture_2d<f32>
            {
                check(!hasResource<texture_2d<f32>>(0));
                let t = getResource<texture_2d<f32>>(0);
                check(all(textureDimensions(t) == vec2(1)));
                check(textureNumLevels(t) == 1);
                check(all(textureLoad(t, vec2(0), 0) == vec4(0, 0, 0, 1)));
            }

            // Default texture_multisampled_2d
            {
                check(!hasResource<texture_multisampled_2d<u32>>(0));
                let t = getResource<texture_multisampled_2d<u32>>(0);
                check(all(textureDimensions(t) == vec2(1)));
                check(textureNumSamples(t) == 4);
                check(all(textureLoad(t, vec2(0), 0) == vec4(0, 0, 0, 1)));
            }

            // Default texture_depth_cube
            {
                check(!hasResource<texture_depth_cube>(0));
                let t = getResource<texture_depth_cube>(0);
                check(all(textureDimensions(t) == vec2(1)));
                check(textureNumLevels(t) == 1);
                check(textureSampleLevel(t, s, vec3(0), 0) == 0);
            }

            // Default texture_2d_array<i32>
            {
                check(!hasResource<texture_2d_array<i32>>(0));
                let t = getResource<texture_2d_array<i32>>(0);
                check(all(textureDimensions(t) == vec2(1)));
                check(textureNumLevels(t) == 1);
                check(textureNumLayers(t) == 1);
                check(all(textureLoad(t, vec2(0), 0, 0) == vec4(0, 0, 0, 1)));
            }
        }
    )");
    wgpu::ComputePipelineDescriptor csDesc = {.compute = {
                                                  .module = module,
                                              }};
    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&csDesc);

    // Create the test resources.
    wgpu::BufferDescriptor bDesc = {
        .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
        .size = sizeof(uint32_t),
    };
    wgpu::Buffer errorBuffer = device.CreateBuffer(&bDesc);

    wgpu::BindGroup bg = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                              {
                                                  {0, errorBuffer},
                                                  {1, device.CreateSampler()},
                                              });
    wgpu::ResourceTable table = MakeResourceTable(0);

    // Run the test and check results are the expected ones.
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
    pass.SetResourceTable(table);
    pass.SetBindGroup(0, bg);
    pass.SetPipeline(pipeline);
    pass.DispatchWorkgroups(1);
    pass.End();

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

    EXPECT_BUFFER_U32_EQ(0, errorBuffer, 0);
}

// Test that a resource table texture can be sampled by a resource table sampler.
TEST_P(ResourceTableTests, Sampler) {
    // TODO(https://issues.chromium.org/issues/490066027): Fails on Mali G78
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());

    // Create a 1x1 texture with a single red pixel.
    wgpu::TextureDescriptor texDesc;
    texDesc.size = {1, 1};
    texDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    texDesc.usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopyDst;
    wgpu::Texture texture = device.CreateTexture(&texDesc);

    const utils::RGBA8 red = utils::RGBA8::kRed;
    wgpu::TexelCopyTextureInfo srcInfo = utils::CreateTexelCopyTextureInfo(texture, 0, {0, 0, 0});
    wgpu::TexelCopyBufferLayout dstInfo = {};
    wgpu::Extent3D copySize = {1, 1, 1};
    queue.WriteTexture(&srcInfo, &red, sizeof(red), &dstInfo, &copySize);

    wgpu::Sampler sampler = device.CreateSampler();

    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;

        @vertex fn vs() -> @builtin(position) vec4f {
            return vec4f(0, 0, 0.5, 0.5);
        }

        @fragment fn fs() -> @location(0) vec4f {
            let s = getResource<sampler>(0);
            let t = getResource<texture_2d<f32>>(1);
            return textureSample(t, s, vec2f(0.5, 0.5));
        }
    )");

    // Create the pipeline.
    utils::ComboRenderPipelineDescriptor pDesc;
    pDesc.vertex.module = module;
    pDesc.cFragment.module = module;
    pDesc.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
    pDesc.primitive.topology = wgpu::PrimitiveTopology::PointList;
    wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pDesc);

    wgpu::ResourceTable table = MakeResourceTable(2, {
                                                         {0, {.sampler = sampler}},
                                                         {1, {.textureView = texture.CreateView()}},
                                                     });

    // Create a 1x1 render target to verify the result.
    utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);

    // Render.
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
    pass.SetPipeline(pipeline);
    pass.SetResourceTable(table);
    pass.Draw(1);
    pass.End();
    wgpu::CommandBuffer commands = encoder.Finish();
    queue.Submit(1, &commands);

    // Verify the result is red.
    EXPECT_PIXEL_RGBA8_EQ(red, renderPass.color, 0, 0);
}

// Test that a resource table texture can be sampled by multiple resource table samplers.
TEST_P(ResourceTableTests, MultipleSamplers) {
    // TODO(https://issues.chromium.org/issues/490066027): Fails on Mali G78
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());
    // TODO(https://crbug.com/510904606): Fails on LLVMPipe
    DAWN_SUPPRESS_TEST_IF(IsMesaSoftware());

    struct Case {
        size_t tableSize;
        uint32_t samplerIndex0;
        uint32_t samplerIndex1;
        uint32_t samplerIndex2;
        uint32_t textureIndex;
    };
    constexpr auto kMax = kMaxResourceTableSize;
    Case cases[] = {
        {4, 0, 1, 2, 3},
        {2048, 2048 - 1, 2048 - 2, 2048 - 3, 2048 - 4},
        {kMax, kMax - 1, kMax - 2, kMax - 3, kMax - 4},
        {2048, 2048 / 4 * 1 - 1, 2048 / 4 * 2 - 1, 2048 / 4 * 3 - 1, 2048 / 4 * 4 - 1},
        {kMax, kMax / 4 * 1 - 1, kMax / 4 * 2 - 1, kMax / 4 * 3 - 1, kMax / 4 * 4 - 1},
    };

    for (auto c : cases) {
        wgpu::ShaderModule module =
            utils::CreateShaderModule(device, absl::StrFormat(R"(
            enable chromium_experimental_resource_table;

            @group(0) @binding(0) var<storage, read_write> results : array<vec4f>;

            @vertex fn vs() -> @builtin(position) vec4f {
                return vec4f(0, 0, 0.5, 0.5);
            }

            @fragment fn fs() -> @location(0) vec4f {
                let samplerRepeat = getResource<sampler>(%u);
                let samplerMirror = getResource<sampler>(%u);
                let samplerClamp = getResource<sampler>(%u);
                let t = getResource<texture_2d<f32>>(%u);

                results[0] = textureSample(t, samplerRepeat, vec2f(1, 0));
                results[1] = textureSample(t, samplerRepeat, vec2f(1.5, 0));

                results[2] = textureSample(t, samplerMirror, vec2f(1, 0));
                results[3] = textureSample(t, samplerMirror, vec2f(1.5, 0));

                results[4] = textureSample(t, samplerClamp, vec2f(1, 0));
                results[5] = textureSample(t, samplerClamp, vec2f(1.5, 0));

                return vec4f(0);
            }
        )",
                                                              c.samplerIndex0, c.samplerIndex1,
                                                              c.samplerIndex2, c.textureIndex));

        // Create the pipeline.
        utils::ComboRenderPipelineDescriptor pDesc;
        pDesc.vertex.module = module;
        pDesc.cFragment.module = module;
        pDesc.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
        pDesc.primitive.topology = wgpu::PrimitiveTopology::PointList;
        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pDesc);

        // Create the texture
        wgpu::Texture texture = CreateCheckerboardTexture();

        // Create 3 samplers
        wgpu::Sampler samplerRepeat = CreateSampler(wgpu::AddressMode::Repeat);
        wgpu::Sampler samplerMirror = CreateSampler(wgpu::AddressMode::MirrorRepeat);
        wgpu::Sampler samplerClamp = CreateSampler(wgpu::AddressMode::ClampToEdge);

        // Create the result buffer resource
        wgpu::BufferDescriptor bDesc = {
            .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
            .size = sizeof(float) * 4 * 6,  // 6 vec4fs
        };
        wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);
        wgpu::BindGroup resultBG =
            utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, resultBuffer}});

        // Create resource table and add the samplers and texture view to it
        wgpu::ResourceTable table = MakeResourceTable(
            c.tableSize, {
                             {c.samplerIndex0, {.sampler = samplerRepeat}},
                             {c.samplerIndex1, {.sampler = samplerMirror}},
                             {c.samplerIndex2, {.sampler = samplerClamp}},
                             {c.textureIndex, {.textureView = texture.CreateView()}},
                         });

        utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(0, resultBG);
        pass.SetResourceTable(table);
        pass.Draw(1);
        pass.End();
        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);

        float expectedGreen[4] = {0.0, 1.0, 0.0, 1.0};
        float expectedRed[4] = {1.0, 0.0, 0.0, 1.0};

        // repeat: 1,0 -> red, 1.5,0 -> green
        EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedRed, resultBuffer, 0 * 4 * sizeof(float), 4);
        EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedGreen, resultBuffer, 1 * 4 * sizeof(float), 4);

        // mirror: 1,0 -> green, 1.5,0 -> red
        EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedGreen, resultBuffer, 2 * 4 * sizeof(float), 4);
        EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedRed, resultBuffer, 3 * 4 * sizeof(float), 4);

        // clamp: 1,0 -> green, 1.5,0 -> green
        EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedGreen, resultBuffer, 4 * 4 * sizeof(float), 4);
        EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedGreen, resultBuffer, 5 * 4 * sizeof(float), 4);
    }
}

// Test that default samplers are correctly created, and accessed when an invalid index it provided.
TEST_P(ResourceTableTests, UseDefaultSamplers) {
    // TODO(https://issues.chromium.org/issues/490066027): Fails on Mali G78
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());

    auto CreateDepthTexture = [&]() {
        wgpu::TextureDescriptor descriptor;
        // descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.size = {1, 1};
        descriptor.format = wgpu::TextureFormat::Depth24Plus;
        descriptor.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::TextureBinding;
        return device.CreateTexture(&descriptor);
    };

    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;

        @group(0) @binding(0) var<storage, read_write> results : array<vec4f>;

        @vertex fn vs() -> @builtin(position) vec4f {
            return vec4f(0, 0, 0.5, 0.5);
        }

        @fragment fn fs() -> @location(0) vec4f {
            let t = getResource<texture_2d<f32>>(0);
            let dt = getResource<texture_depth_2d>(1);

            let samplerNonFiltering = getResource<sampler>(2);
            let samplerFiltering = getResource<sampler>(3);
            let samplerComparison = getResource<sampler_comparison>(4);

            results[0] = textureSample(t, samplerNonFiltering, vec2f(0.5, 0.5));
            results[1] = textureSample(t, samplerNonFiltering, vec2f(0.6, 0.6));

            results[2] = textureSample(t, samplerFiltering, vec2f(0.5, 0.5));
            results[3] = textureSample(t, samplerFiltering, vec2f(0.6, 0.6));

            let c = textureSampleCompare(dt, samplerComparison, vec2f(0.5, 0.5), 0.5);
            results[4] = vec4f(c, 42.0f, c, 83.5f);

            return vec4f(0);
        }
    )");

    // Create the pipeline.
    utils::ComboRenderPipelineDescriptor pDesc;
    pDesc.vertex.module = module;
    pDesc.cFragment.module = module;
    pDesc.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
    pDesc.primitive.topology = wgpu::PrimitiveTopology::PointList;
    wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pDesc);

    // Create the textures
    wgpu::Texture colorTexture = CreateCheckerboardTexture();
    wgpu::Texture depthTexture = CreateDepthTexture();

    // Create the result buffer resource
    wgpu::BufferDescriptor bDesc = {
        .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
        .size = sizeof(float) * 4 * 5,  // 5 vec4fs
    };
    wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);
    wgpu::BindGroup resultBG =
        utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, resultBuffer}});

    // Create resource table and only textures to it, no samplers, so that the default
    // samplers get used
    wgpu::ResourceTable table =
        MakeResourceTable(10, {
                                  {0, {.textureView = colorTexture.CreateView()}},
                                  {1, {.textureView = depthTexture.CreateView()}},
                              });

    utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
    pass.SetPipeline(pipeline);
    pass.SetBindGroup(0, resultBG);
    pass.SetResourceTable(table);
    pass.Draw(1);
    pass.End();
    wgpu::CommandBuffer commands = encoder.Finish();
    queue.Submit(1, &commands);

    float expectedRed[4] = {1.0, 0.0, 0.0, 1.0};
    float expectedGreen[4] = {1.0, 0.0, 0.0, 1.0};

    // The default non-filtering sampler should return red at (0.5, 0.5), and green at (0.6, 0.6)
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedRed, resultBuffer, 0 * 4 * sizeof(float), 4);
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedGreen, resultBuffer, 1 * 4 * sizeof(float), 4);

    // The default filtering sampler is actually a non-filtering one, so should return the same
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedRed, resultBuffer, 2 * 4 * sizeof(float), 4);
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedGreen, resultBuffer, 3 * 4 * sizeof(float), 4);

    // The comparison sampler is an 'always' one, so it should return 1.0, which the shader returns
    // in two of the vector elements.
    float expectedCompare[4] = {1.0, 42.0, 1.0, 83.5};
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedCompare, resultBuffer, 4 * 4 * sizeof(float), 4);
}

// Test that removing then adding a new sampler in a slot that already has a sampler of the same
// type (e.g. filterable) works as expected. This ensures, for example, that the metadata buffer
// gets an updated sampler index on D3D12.
TEST_P(ResourceTableTests, RemoveThenAddSamplerInSameSlot) {
    // TODO(https://issues.chromium.org/issues/490066027): Fails on Mali G78
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());
    // TODO(https://crbug.com/510904606): Fails on LLVMPipe
    DAWN_SUPPRESS_TEST_IF(IsMesaSoftware());

    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;

        @group(0) @binding(0) var<storage, read_write> results : array<vec4f>;

        @vertex fn vs() -> @builtin(position) vec4f {
            return vec4f(0, 0, 0.5, 0.5);
        }

        @fragment fn fs() -> @location(0) vec4f {
            let t = getResource<texture_2d<f32>>(0);
            let s = getResource<sampler>(1);

            results[0] = textureSample(t, s, vec2f(1, 0));
            results[1] = textureSample(t, s, vec2f(1.5, 0));
            return vec4f(0);
        }
    )");

    // Create the pipeline.
    utils::ComboRenderPipelineDescriptor pDesc;
    pDesc.vertex.module = module;
    pDesc.cFragment.module = module;
    pDesc.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
    pDesc.primitive.topology = wgpu::PrimitiveTopology::PointList;
    wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pDesc);

    // Create texture
    wgpu::Texture texture = CreateCheckerboardTexture();

    // Create samplers
    wgpu::Sampler samplerRepeat = CreateSampler(wgpu::AddressMode::Repeat);
    wgpu::Sampler samplerMirror = CreateSampler(wgpu::AddressMode::MirrorRepeat);

    // Create the result buffer resource
    wgpu::BufferDescriptor bDesc = {
        .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
        .size = sizeof(float) * 4 * 2,  // 2 vec4fs
    };
    wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);
    wgpu::BindGroup resultBG =
        utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, resultBuffer}});

    // Create resource table
    wgpu::ResourceTable table = MakeResourceTable(2, {
                                                         {0, {.textureView = texture.CreateView()}},
                                                     });

    utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);

    auto draw = [&]() {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(0, resultBG);
        pass.SetResourceTable(table);
        pass.Draw(1);
        pass.End();
        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);
    };

    wgpu::BindingResource res;
    float expectedGreen[4] = {0.0, 1.0, 0.0, 1.0};
    float expectedRed[4] = {1.0, 0.0, 0.0, 1.0};

    // Add repeat sampler and draw
    res = {.sampler = samplerRepeat};
    EXPECT_EQ(wgpu::Status::Success, table.Update(1, &res));
    draw();

    // repeat: 1,0 -> red, 1.5,0 -> green
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedRed, resultBuffer, 0 * 4 * sizeof(float), 4);
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedGreen, resultBuffer, 1 * 4 * sizeof(float), 4);

    // Now test removing then adding mirror sampler
    EXPECT_EQ(wgpu::Status::Success, table.RemoveBinding(1));
    WaitForAllOperations();
    res = {.sampler = samplerMirror};
    EXPECT_EQ(wgpu::Status::Success, table.Update(1, &res));
    draw();

    // mirror: 1,0 -> green, 1.5,0 -> red
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedGreen, resultBuffer, 0 * 4 * sizeof(float), 4);
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedRed, resultBuffer, 1 * 4 * sizeof(float), 4);
}

// Test that adding and removing samplers in the same slot between draws ensure that
// backends only see the effective diff (first one added to last one added).
TEST_P(ResourceTableTests, RemoveThenAddSamplerMultipleInSameSlot) {
    // TODO(https://issues.chromium.org/issues/490066027): Fails on Mali G78
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());

    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;

        @group(0) @binding(0) var<storage, read_write> results : array<vec4f>;

        @vertex fn vs() -> @builtin(position) vec4f {
            return vec4f(0, 0, 0.5, 0.5);
        }

        @fragment fn fs() -> @location(0) vec4f {
            let t = getResource<texture_2d<f32>>(0);
            let s = getResource<sampler>(1);

            results[0] = textureSample(t, s, vec2f(1, 0));
            results[1] = textureSample(t, s, vec2f(1.5, 0));
            return vec4f(0);
        }
    )");

    // Create the pipeline.
    utils::ComboRenderPipelineDescriptor pDesc;
    pDesc.vertex.module = module;
    pDesc.cFragment.module = module;
    pDesc.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
    pDesc.primitive.topology = wgpu::PrimitiveTopology::PointList;
    wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pDesc);

    // Create texture
    wgpu::Texture texture = CreateCheckerboardTexture();

    // Create samplers
    wgpu::Sampler samplerRepeat = CreateSampler(wgpu::AddressMode::Repeat);
    wgpu::Sampler samplerMirror[] = {
        // Create different types to make sure they don't get de-duped
        CreateSampler(wgpu::AddressMode::MirrorRepeat, wgpu::CompareFunction::Always),
        CreateSampler(wgpu::AddressMode::MirrorRepeat, wgpu::CompareFunction::Equal),
        CreateSampler(wgpu::AddressMode::MirrorRepeat, wgpu::CompareFunction::GreaterEqual)};
    wgpu::Sampler samplerClamp = CreateSampler(wgpu::AddressMode::ClampToEdge);

    // Create the result buffer resource
    wgpu::BufferDescriptor bDesc = {
        .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
        .size = sizeof(float) * 4 * 2,  // 2 vec4fs
    };
    wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);
    wgpu::BindGroup resultBG =
        utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, resultBuffer}});

    // Create resource table and add the samplers and texture view to it
    wgpu::ResourceTable table = MakeResourceTable(2, {
                                                         {0, {.textureView = texture.CreateView()}},
                                                     });

    utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);

    auto draw = [&]() {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(0, resultBG);
        pass.SetResourceTable(table);
        pass.Draw(1);
        pass.End();
        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);
    };

    wgpu::BindingResource res;
    float expectedGreen[4] = {0.0, 1.0, 0.0, 1.0};
    float expectedRed[4] = {1.0, 0.0, 0.0, 1.0};

    // Add repeat sampler and draw
    res = {.sampler = samplerRepeat};
    EXPECT_EQ(wgpu::Status::Success, table.Update(1, &res));
    draw();

    // repeat: 1,0 -> red, 1.5,0 -> green
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedRed, resultBuffer, 0 * 4 * sizeof(float), 4);
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedGreen, resultBuffer, 1 * 4 * sizeof(float), 4);

    // Remove then add mirror samplers
    for (auto sampler : samplerMirror) {
        EXPECT_EQ(wgpu::Status::Success, table.RemoveBinding(1));
        WaitForAllOperations();
        res = {.sampler = sampler};
        EXPECT_EQ(wgpu::Status::Success, table.Update(1, &res));
    }

    // Finally, remove and add clamp sampler
    EXPECT_EQ(wgpu::Status::Success, table.RemoveBinding(1));
    WaitForAllOperations();
    res = {.sampler = samplerClamp};
    EXPECT_EQ(wgpu::Status::Success, table.Update(1, &res));

    // Now draw. Backends should basically ignore the adding and removal of the mirror sampler.
    draw();

    // clamp: 1,0 -> green, 1.5,0 -> green
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedGreen, resultBuffer, 0 * 4 * sizeof(float), 4);
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedGreen, resultBuffer, 1 * 4 * sizeof(float), 4);
}

// Test what happens when we add more than kD3D12MaxUniqueSamplers unique samplers
TEST_P(ResourceTableTests, AddUniqueSamplersOverLimit) {
    // TODO(https://issues.chromium.org/issues/490066027): Fails on Mali G78
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());

    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;
        @compute @workgroup_size(1) fn main() {
            _ = hasResource<texture_2d<f32>>(0);
        }
    )");
    auto pipeline = device.CreateComputePipeline(&csDesc);

    auto dispatch = [&](wgpu::ResourceTable table, bool shouldSucceed = true) {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetResourceTable(table);
        pass.SetPipeline(pipeline);
        pass.DispatchWorkgroups(1);
        pass.End();
        wgpu::CommandBuffer commands = encoder.Finish();
        if (shouldSucceed) {
            queue.Submit(1, &commands);
        } else {
            ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
        }
    };

    wgpu::ResourceTable table = MakeResourceTable(2049);

    // Initial draw so that default resources are processed
    dispatch(table);

    // Add kD3D12MaxUniqueSamplers, should all succeed
    for (auto i : Range(kD3D12MaxUniqueSamplers)) {
        wgpu::BindingResource br{.sampler = CreateUniqueSampler(i)};
        EXPECT_EQ(wgpu::Status::Success, table.Update(i, &br));
    }

    dispatch(table);

    // Now add one more, should fail
    {
        wgpu::BindingResource br{.sampler = CreateUniqueSampler(kD3D12MaxUniqueSamplers)};
        EXPECT_EQ(wgpu::Status::Success, table.Update(kD3D12MaxUniqueSamplers, &br));
    }

    bool shouldSucceed = !IsD3D12();
    dispatch(table, shouldSucceed);
}

// Test that adding a sampler, draw, then remove and add a duplicate sampler and draw works. This
// tests that deduplication logic handles when no more refs are left to a sampler, and then a
// duplicate sampler is added back. On D3D12, internally this may result in a new sampler index,
// which should be fine.
TEST_P(ResourceTableTests, RemoveAddDuplicateSampler) {
    // TODO(https://issues.chromium.org/issues/490066027): Fails on Mali G78
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());

    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;
        @compute @workgroup_size(1) fn main() {
            _ = hasResource<texture_2d<f32>>(0);
        }
    )");
    auto pipeline = device.CreateComputePipeline(&csDesc);

    auto dispatch = [&](wgpu::ResourceTable table) {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetResourceTable(table);
        pass.SetPipeline(pipeline);
        pass.DispatchWorkgroups(1);
        pass.End();
        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);
    };

    wgpu::ResourceTable table = MakeResourceTable(2);

    // Initial draw so that default resources are processed
    dispatch(table);

    {
        // Add a unique sampler in slot 1
        wgpu::BindingResource br{.sampler = CreateUniqueSampler(42)};
        EXPECT_EQ(wgpu::Status::Success, table.Update(1, &br));
    }
    dispatch(table);

    {
        // Remove the sampler in slot 1
        EXPECT_EQ(wgpu::Status::Success, table.RemoveBinding(1));

        WaitForAllOperations();

        // Add another sampler in slot 0
        // This is to coax the backend into potentially assigning a different sampler index for this
        // same sampler.
        wgpu::BindingResource br{.sampler = CreateUniqueSampler(123)};
        EXPECT_EQ(wgpu::Status::Success, table.Update(0, &br));

        // Add back the origin sampler in slot 1
        wgpu::BindingResource br2{.sampler = CreateUniqueSampler(42)};
        EXPECT_EQ(wgpu::Status::Success, table.Update(1, &br2));
    }

    dispatch(table);
}

// On D3D12 the number of sampler descriptors in a GPU heap is limited to 2048. We deduplicate
// samplers, so test that we can add more than 2048 samplers to the resource table, as long as there
// are duplicates. We test this by creating a table of size 2*2048, add 2048 unique samplers in the
// first half of the table, then add the same set of sampers in the second half of the table.
TEST_P(ResourceTableTests, AddDuplicateSamplersTwice) {
    // TODO(https://issues.chromium.org/issues/490066027): Fails on Mali G78
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());

    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;
        @compute @workgroup_size(1) fn main() {
            _ = hasResource<texture_2d<f32>>(0);
        }
    )");
    auto pipeline = device.CreateComputePipeline(&csDesc);

    auto dispatch = [&](wgpu::ResourceTable table) {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetResourceTable(table);
        pass.SetPipeline(pipeline);
        pass.DispatchWorkgroups(1);
        pass.End();
        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);
    };

    // Make a table with double the max number of unique samplers on D3D12.
    wgpu::ResourceTable table = MakeResourceTable(kD3D12MaxUniqueSamplers * 2);

    // Add samplers to slots 0..kD3D12MaxUniqueSamplers-1
    for (uint32_t i : Range(kD3D12MaxUniqueSamplers)) {
        wgpu::BindingResource br{.sampler = CreateUniqueSampler(i)};
        EXPECT_EQ(wgpu::Status::Success, table.Update(i, &br));
    }

    // Draw so that the CPU to GPU sampler heap creation and copy occurs.
    dispatch(table);

    // Add the same samplers to slots kD3D12MaxUniqueSamplers..kD3D12MaxUniqueSamplers*2-1
    for (uint32_t i : Range(kD3D12MaxUniqueSamplers)) {
        wgpu::BindingResource br{.sampler = CreateUniqueSampler(i)};
        EXPECT_EQ(wgpu::Status::Success, table.Update(i + kD3D12MaxUniqueSamplers, &br));
    }

    // Draw again. If we didn't handle removal of samplers correctly, this will fail
    // for surpassing the 2048 sampler descriptor per heap limit.
    dispatch(table);
}

// On D3D12 the number of sampler descriptors in a GPU heap is limited to 2048. This test
// allocates a resource table larger than that, adds 2048 unique samplers, draws, removes them all,
// then adds 2048 unique samplers (different from the first set) again in different slots,
// and draws again, making sure this is supported. Effectively, this tests that the resource table
// correctly handles removal of samplers.
TEST_P(ResourceTableTests, AddAndRemoveMaxSamplersTwice) {
    // TODO(https://issues.chromium.org/issues/490066027): Fails on Mali G78
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());
    // TODO(https://issues.chromium.org/issues/512829734): Fails on Vulkan if
    // VkPhysicalDeviceLimits::maxSamplerAllocationCount <= 4K
    DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsWindows() && IsIntel());

    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;
        @compute @workgroup_size(1) fn main() {
            _ = hasResource<texture_2d<f32>>(0);
        }
    )");
    auto pipeline = device.CreateComputePipeline(&csDesc);

    auto dispatch = [&](wgpu::ResourceTable table) {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetResourceTable(table);
        pass.SetPipeline(pipeline);
        pass.DispatchWorkgroups(1);
        pass.End();
        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);
    };

    // Make a table with double the max number of samplers on D3D12.
    wgpu::ResourceTable table = MakeResourceTable(kD3D12MaxUniqueSamplers * 2);

    // Add samplers to slots 0..kD3D12MaxUniqueSamplers-1
    for (uint32_t i : Range(kD3D12MaxUniqueSamplers)) {
        // Make samplers unique by making one of the values different for each
        wgpu::BindingResource br{.sampler = CreateUniqueSampler(i)};
        EXPECT_EQ(wgpu::Status::Success, table.Update(i, &br));
    }

    // Draw so that the CPU to GPU sampler heap creation and copy occurs.
    dispatch(table);

    // Remove all samplers
    for (uint32_t i : Range(kD3D12MaxUniqueSamplers)) {
        EXPECT_EQ(wgpu::Status::Success, table.RemoveBinding(i));
    }

    // Add different samplers to slots kD3D12MaxUniqueSamplers..kD3D12MaxUniqueSamplers*2-1
    for (uint32_t i : Range(kD3D12MaxUniqueSamplers)) {
        wgpu::BindingResource br{.sampler = CreateUniqueSampler(kD3D12MaxUniqueSamplers + i)};
        EXPECT_EQ(wgpu::Status::Success, table.Update(i + kD3D12MaxUniqueSamplers, &br));
    }

    // Draw again. If we didn't handle removal of samplers correctly, this will fail
    // for surpassing the 2048 sampler descriptor per heap limit.
    dispatch(table);
}

// Test that removing then adding a texture in a slot works as expected.
TEST_P(ResourceTableTests, RemoveThenAddTextureInSameSlot) {
    // TODO(https://issues.chromium.org/issues/490066027): Fails on Mali G78
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());

    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;

        @group(0) @binding(0) var<storage, read_write> results : array<vec4f>;

        @vertex fn vs() -> @builtin(position) vec4f {
            return vec4f(0, 0, 0.5, 0.5);
        }

        @fragment fn fs() -> @location(0) vec4f {
            let t = getResource<texture_2d<f32>>(0);
            let s = getResource<sampler>(1);
            results[0] = textureSample(t, s, vec2f(0.5, 0.5));
            return vec4f(0);
        }
    )");

    // Create the pipeline.
    utils::ComboRenderPipelineDescriptor pDesc;
    pDesc.vertex.module = module;
    pDesc.cFragment.module = module;
    pDesc.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
    pDesc.primitive.topology = wgpu::PrimitiveTopology::PointList;
    wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pDesc);

    // Create textures
    wgpu::Texture textureRed = CreateColorTexture(utils::RGBA8::kRed);
    wgpu::Texture textureGreen = CreateColorTexture(utils::RGBA8::kGreen);

    // Create the result buffer resource
    wgpu::BufferDescriptor bDesc = {
        .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
        .size = sizeof(float) * 4,  // 1 vec4fs
    };
    wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);
    wgpu::BindGroup resultBG =
        utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, resultBuffer}});

    // Create resource table
    wgpu::ResourceTable table = MakeResourceTable(1);

    utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);

    auto draw = [&]() {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(0, resultBG);
        pass.SetResourceTable(table);
        pass.Draw(1);
        pass.End();
        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);
    };

    wgpu::BindingResource res;
    float expectedRed[4] = {1.0, 0.0, 0.0, 1.0};
    float expectedGreen[4] = {0.0, 1.0, 0.0, 1.0};

    // Add red texture and draw
    res = {.textureView = textureRed.CreateView()};
    EXPECT_EQ(wgpu::Status::Success, table.Update(0, &res));
    draw();
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedRed, resultBuffer, 0, 4);

    // Now test removing and adding the green texture in the same slot
    EXPECT_EQ(wgpu::Status::Success, table.RemoveBinding(0));
    WaitForAllOperations();
    res = {.textureView = textureGreen.CreateView()};
    EXPECT_EQ(wgpu::Status::Success, table.Update(0, &res));
    draw();
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedGreen, resultBuffer, 0, 4);
}

// Test that adding and removing textures in the same slot between draws ensure that
// backends only see the effective diff (first one added to last one added).
TEST_P(ResourceTableTests, RemoveThenAddTextureMultipleInSameSlot) {
    // TODO(https://issues.chromium.org/issues/490066027): Fails on Mali G78
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsARM());

    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;

        @group(0) @binding(0) var<storage, read_write> results : array<vec4f>;

        @vertex fn vs() -> @builtin(position) vec4f {
            return vec4f(0, 0, 0.5, 0.5);
        }

        @fragment fn fs() -> @location(0) vec4f {
            let t = getResource<texture_2d<f32>>(0);
            let s = getResource<sampler>(1);
            results[0] = textureSample(t, s, vec2f(0.5, 0.5));
            return vec4f(0);
        }
    )");

    // Create the pipeline.
    utils::ComboRenderPipelineDescriptor pDesc;
    pDesc.vertex.module = module;
    pDesc.cFragment.module = module;
    pDesc.cTargets[0].format = wgpu::TextureFormat::RGBA8Unorm;
    pDesc.primitive.topology = wgpu::PrimitiveTopology::PointList;
    wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pDesc);

    // Create textures
    wgpu::Texture textureRed = CreateColorTexture(utils::RGBA8::kRed);
    wgpu::Texture textureGreen = CreateColorTexture(utils::RGBA8::kGreen);
    wgpu::Texture textureBlue = CreateColorTexture(utils::RGBA8::kBlue);

    // Create the result buffer resource
    wgpu::BufferDescriptor bDesc = {
        .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
        .size = sizeof(float) * 4,  // 1 vec4fs
    };
    wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);
    wgpu::BindGroup resultBG =
        utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, resultBuffer}});

    // Create resource table
    wgpu::ResourceTable table = MakeResourceTable(1);

    utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 1, 1);

    auto draw = [&]() {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(0, resultBG);
        pass.SetResourceTable(table);
        pass.Draw(1);
        pass.End();
        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);
    };

    wgpu::BindingResource res;
    float expectedRed[4] = {1.0, 0.0, 0.0, 1.0};
    float expectedBlue[4] = {0.0, 0.0, 1.0, 1.0};

    // Add red texture and draw
    res = {.textureView = textureRed.CreateView()};
    EXPECT_EQ(wgpu::Status::Success, table.Update(0, &res));
    draw();
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedRed, resultBuffer, 0, 4);

    // Remove then add green texture (this could be done in a loop with multiple textures)
    EXPECT_EQ(wgpu::Status::Success, table.RemoveBinding(0));
    WaitForAllOperations();
    res = {.textureView = textureGreen.CreateView()};
    EXPECT_EQ(wgpu::Status::Success, table.Update(0, &res));

    // Now test removing and adding the blue texture in the same slot
    EXPECT_EQ(wgpu::Status::Success, table.RemoveBinding(0));
    WaitForAllOperations();
    res = {.textureView = textureBlue.CreateView()};
    EXPECT_EQ(wgpu::Status::Success, table.Update(0, &res));
    draw();
    EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedBlue, resultBuffer, 0, 4);
}

// Check that zero-initialization of the resources happens implicitly
TEST_P(ResourceTableTests, ImplicitZeroInit) {
    // TODO(crbug.com/385158827): Fails on older WARP 10.0.19041.5794
    DAWN_SUPPRESS_TEST_IF(IsWARP());

    // Create the pipeline reading back from the texture.
    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;

        @group(0) @binding(0) var<storage, read_write> result : u32;

        @compute @workgroup_size(1) fn readbackPixel() {
            let errorIfNotPresent = u32(!hasResource<texture_2d<u32>>(0));
            let tex = getResource<texture_2d<u32>>(0);
            let texel = textureLoad(tex, vec2u(0), 0).r;
            result = errorIfNotPresent + texel;
        }
    )");

    wgpu::ComputePipelineDescriptor csDesc = {.compute = {
                                                  .module = module,
                                              }};
    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&csDesc);

    // Create the test resource table.
    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R32Uint,
    };
    wgpu::TextureViewDescriptor vDesc{
        .usage = wgpu::TextureUsage::TextureBinding,
    };
    wgpu::Texture tex = device.CreateTexture(&tDesc);

    wgpu::ResourceTable table =
        MakeResourceTable(1, {{0, {.textureView = tex.CreateView(&vDesc)}}});

    // Create the other test resources.
    wgpu::BufferDescriptor bDesc = {
        .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
        .size = sizeof(uint32_t),
    };
    wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);

    wgpu::BindGroup bg = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                              {
                                                  {0, resultBuffer},
                                              });

    // Check that the initial zero init happens implicitly.
    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetResourceTable(table);
        pass.SetBindGroup(0, bg);
        pass.SetPipeline(pipeline);
        pass.DispatchWorkgroups(1);
        pass.End();

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

        EXPECT_BUFFER_U32_EQ(0, resultBuffer, 0);
    }

    // Use a render pass discard to mark the texture as uninitialized again. Use a LoadOp::Clear to
    // set some non-zero value in the texture which hopefully would tell us if the lazy clear didn't
    // happen.
    {
        wgpu::RenderPassColorAttachment attachment = {
            .view = tex.CreateView(),
            .loadOp = wgpu::LoadOp::Clear,
            .storeOp = wgpu::StoreOp::Discard,
            .clearValue = {.r = 1.0, .g = 0.0, .b = 0.0, .a = 0.0},
        };
        wgpu::RenderPassDescriptor rpDesc = {
            .colorAttachmentCount = 1,
            .colorAttachments = &attachment,
        };

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&rpDesc);
        pass.End();
        wgpu::CommandBuffer commands = encoder.Finish();
        device.GetQueue().Submit(1, &commands);
    }

    // Check that the zero init happens implicitly after a discard.
    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetResourceTable(table);
        pass.SetBindGroup(0, bg);
        pass.SetPipeline(pipeline);
        pass.DispatchWorkgroups(1);
        pass.End();

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

        EXPECT_BUFFER_U32_EQ(0, resultBuffer, 0);
    }
}

// Check that a resource table slot can be updated only after all commands submitted prior to
// RemoveBinding are completed.
TEST_P(ResourceTableTests, UpdateAfterRemoveRequiresGPUIsFinished) {
    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R32Uint,
    };
    wgpu::Texture tex = device.CreateTexture(&tDesc);
    wgpu::BindingResource resource{.textureView = tex.CreateView()};

    wgpu::ResourceTable table = MakeResourceTable(1);
    EXPECT_EQ(wgpu::Status::Success, table.Update(0, &resource));

    // Removing while the table is still potentially in used by the GPU is an error. But immediately
    // after we know that the GPU is finished, it is valid.
    bool updateValid = false;
    DoSomeWorkInSubmit();
    queue.OnSubmittedWorkDone(
        wgpu::CallbackMode::AllowSpontaneous,
        [&](wgpu::QueueWorkDoneStatus, wgpu::StringView) { updateValid = true; });
    EXPECT_EQ(wgpu::Status::Success, table.RemoveBinding(0));

    if (updateValid) {
        EXPECT_EQ(wgpu::Status::Success, table.Update(0, &resource));
        updateValid = false;
    } else {
        EXPECT_EQ(wgpu::Status::Error, table.Update(0, &resource));
    }

    WaitForAllOperations();

    if (updateValid) {
        EXPECT_EQ(wgpu::Status::Success, table.Update(0, &resource));
    } else {
        EXPECT_EQ(wgpu::Status::Error, table.Update(0, &resource));
    }
}

// Check that a resource table slot can be updated only after all commands submitted prior to
// RemoveBinding are completed.
TEST_P(ResourceTableTests, UpdateAfterRemoveRequiresGPUIsFinished_ErrorBindGroup) {
    DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("skip_validation"));

    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R32Uint,
    };
    wgpu::Texture tex = device.CreateTexture(&tDesc);
    wgpu::BindingResource resource{.textureView = tex.CreateView()};

    // Make an error resource table.
    wgpu::RenderPassMaxDrawCount maxDraw;
    maxDraw.maxDrawCount = 1000;
    wgpu::ResourceTableDescriptor desc{
        .nextInChain = &maxDraw,
        .size = 1,
    };
    wgpu::ResourceTable table;
    ASSERT_DEVICE_ERROR(table = device.CreateResourceTable(&desc));

    {
        // Ignore all validation errors for this test as they are tested in other places, and we're
        // checking immediate validation returned as a wgpu::Status and supposed to be the same for
        // valid and invalid objects.
        utils::ScopedIgnoreValidationErrors ignoreErrors(device);

        EXPECT_EQ(wgpu::Status::Success, table.Update(0, &resource));

        // Removing while the table is still potentially in used by the GPU is an error. But
        // immediately after we know that the GPU is finished, it is valid.
        bool updateValid = false;
        DoSomeWorkInSubmit();
        queue.OnSubmittedWorkDone(
            wgpu::CallbackMode::AllowSpontaneous,
            [&](wgpu::QueueWorkDoneStatus, wgpu::StringView) { updateValid = true; });
        EXPECT_EQ(wgpu::Status::Success, table.RemoveBinding(0));

        if (updateValid) {
            EXPECT_EQ(wgpu::Status::Success, table.Update(0, &resource));
            updateValid = false;
        } else {
            EXPECT_EQ(wgpu::Status::Error, table.Update(0, &resource));
        }

        WaitForAllOperations();

        if (updateValid) {
            EXPECT_EQ(wgpu::Status::Success, table.Update(0, &resource));
        } else {
            EXPECT_EQ(wgpu::Status::Error, table.Update(0, &resource));
        }
    }
}

// Check that Update and InsertBinding make the new binding visible in the resource table.
TEST_P(ResourceTableTests, UpdateAndInsertBindingMakeBindingVisible) {
    // TODO(crbug.com/385158827): Fails on older WARP 10.0.19041.5794
    DAWN_SUPPRESS_TEST_IF(IsWARP());

    wgpu::ResourceTable table = MakeResourceTable(2);

    // Before we do anything, the table has no valid entries.
    TestHasU8BindingsAll(table, {{}, {}});

    // Update makes the entry visible.
    wgpu::BindingResource resource0 = {.textureView = MakeU8View(17)};
    EXPECT_EQ(wgpu::Status::Success, table.Update(0, &resource0));
    TestHasU8BindingsAll(table, {{17}, {}});

    // InsertBinding makes the entry visible.
    wgpu::BindingResource resource1 = {.textureView = MakeU8View(42)};
    EXPECT_EQ(1u, table.InsertBinding(&resource1));
    TestHasU8BindingsAll(table, {{17}, {42}});
}

// Check that RemoveBinding instantly makes the binding not visible, both for entries added with
// Update and InsertBinding.
TEST_P(ResourceTableTests, RemoveBindingMakeBindingInvalid) {
    // TODO(crbug.com/385158827): Fails on older WARP 10.0.19041.5794
    DAWN_SUPPRESS_TEST_IF(IsWARP());

    // Fill a resource table with both Update and InsertBinding.
    wgpu::ResourceTable table = MakeResourceTable(2);

    wgpu::BindingResource resource0 = {.textureView = MakeU8View(100)};
    EXPECT_EQ(wgpu::Status::Success, table.Update(0, &resource0));

    wgpu::BindingResource resource1 = {.textureView = MakeU8View(101)};
    EXPECT_EQ(1u, table.InsertBinding(&resource1));

    // Before we remove bindings, they are all valid.
    TestHasU8BindingsAll(table, {{100}, {101}});

    // RemoveBinding immediately makes bindings invalid.
    EXPECT_EQ(wgpu::Status::Success, table.RemoveBinding(1));
    TestHasU8BindingsAll(table, {{100}, {}});
    EXPECT_EQ(wgpu::Status::Success, table.RemoveBinding(0));
    TestHasU8BindingsAll(table, {{}, {}});
}

// Check that removing a binding and adding a different one works.
TEST_P(ResourceTableTests, ReplaceBinding) {
    // TODO(crbug.com/385158827): Fails on older WARP 10.0.19041.5794
    DAWN_SUPPRESS_TEST_IF(IsWARP());

    // Create the test resource table.
    wgpu::ResourceTable table = MakeResourceTable(1);
    wgpu::BindingResource resource = {.textureView = MakeU8View(19)};
    EXPECT_EQ(wgpu::Status::Success, table.Update(0, &resource));

    // Test removing a binding that was previously there.
    TestHasU8BindingsAll(table, {{19}});
    EXPECT_EQ(wgpu::Status::Success, table.RemoveBinding(0));
    TestHasU8BindingsAll(table, {{}});

    /// Add it back a new entry, the shader should be seeing the updated entry.
    WaitForAllOperations();

    wgpu::BindingResource newResource = {.textureView = MakeU8View(23)};
    EXPECT_EQ(wgpu::Status::Success, table.Update(0, &newResource));
    TestHasU8BindingsAll(table, {{23}});
}

// Check that removing a binding and adding it back works.
TEST_P(ResourceTableTests, ReplaceWithSameBinding) {
    // TODO(crbug.com/385158827): Fails on older WARP 10.0.19041.5794
    DAWN_SUPPRESS_TEST_IF(IsWARP());

    // Create the test resource table.
    wgpu::ResourceTable table = MakeResourceTable(1);
    wgpu::BindingResource resource = {.textureView = MakeU8View(19)};
    EXPECT_EQ(wgpu::Status::Success, table.Update(0, &resource));

    // Test removing a binding that was previously there.
    TestHasU8BindingsAll(table, {{19}});
    EXPECT_EQ(wgpu::Status::Success, table.RemoveBinding(0));
    TestHasU8BindingsAll(table, {{}});

    /// Add it back a new entry, the shader should be seeing the updated entry.
    WaitForAllOperations();

    EXPECT_EQ(wgpu::Status::Success, table.Update(0, &resource));
    TestHasU8BindingsAll(table, {{19}});
}

// Check that setting multiple resource table, on per dispatch/draw/executebundle, on a single pass
// works.
TEST_P(ResourceTableTests, SinglePassMultipleResourceTables) {
    // TODO(crbug.com/385158827): Fails on older WARP 10.0.19041.5794
    DAWN_SUPPRESS_TEST_IF(IsWARP());

    std::vector<wgpu::BindingResource> resources;

    wgpu::ResourceTable table0 = MakeResourceTable(2);
    resources.push_back(wgpu::BindingResource{.textureView = MakeU8View(17)});
    EXPECT_EQ(wgpu::Status::Success, table0.Update(0, &resources.back()));
    resources.push_back(wgpu::BindingResource{.textureView = MakeU8View(18)});
    EXPECT_EQ(wgpu::Status::Success, table0.Update(1, &resources.back()));

    wgpu::ResourceTable table1 = MakeResourceTable(3);
    resources.push_back(wgpu::BindingResource{.textureView = MakeU8View(27)});
    EXPECT_EQ(wgpu::Status::Success, table1.Update(0, &resources.back()));
    // Leave slot 1 empty
    resources.push_back(wgpu::BindingResource{.textureView = MakeU8View(29)});
    EXPECT_EQ(wgpu::Status::Success, table1.Update(2, &resources.back()));

    wgpu::ResourceTable table2 = MakeResourceTable(4);
    resources.push_back(wgpu::BindingResource{.textureView = MakeU8View(37)});
    EXPECT_EQ(wgpu::Status::Success, table2.Update(0, &resources.back()));
    resources.push_back(wgpu::BindingResource{.textureView = MakeU8View(38)});
    EXPECT_EQ(wgpu::Status::Success, table2.Update(1, &resources.back()));
    // Leave slot 2 empty
    resources.push_back(wgpu::BindingResource{.textureView = MakeU8View(40)});
    EXPECT_EQ(wgpu::Status::Success, table2.Update(3, &resources.back()));

    auto case0 = TableAndExpected(table0, {{17, 18}});
    auto case1 = TableAndExpected(table1, {{27, {}, 29}});
    auto case2 = TableAndExpected(table2, {{37, 38, {}, 40}});

    TestHasU8BindingsAll({case0, case1, case2});
    TestHasU8BindingsAll({case1, case0, case2});
    TestHasU8BindingsAll({case2, case1, case0});
}

// Check that logic to dirty or reuse VkDescriptorSet takes into account the resource table in the
// Vulkan backend.
TEST_P(ResourceTableTests, SwitchUseResourceTableAndNot) {
    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_resource_table;

        @vertex fn vs() -> @builtin(position) vec4f {
            return vec4f(0, 0, 0.5, 0.5);
        }

        @group(0) @binding(0) var<storage, read_write> results : array<u32>;
        var<immediate> resultIndex : u32;

        @fragment fn yes_resource_table() -> @location(0) vec4f {
            results[resultIndex] = 10 + u32(hasResource<texture_2d<f32>>(resultIndex));
            return vec4();
        }

        @fragment fn no_resource_table() -> @location(0) vec4f {
            results[resultIndex] = 42;
            return vec4();
        }
    )");

    wgpu::BindGroupLayout resultBGL = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage}});

    wgpu::RenderPipeline resourceTablePipeline;
    {
        utils::ComboRenderPipelineDescriptor desc;
        desc.layout = MakePipelineLayoutWithTable({resultBGL}, 4);
        desc.vertex.module = module;
        desc.cFragment.module = module;
        desc.cFragment.entryPoint = "yes_resource_table";
        desc.primitive.topology = wgpu::PrimitiveTopology::PointList;
        resourceTablePipeline = device.CreateRenderPipeline(&desc);
    }

    wgpu::RenderPipeline noResourceTablePipeline;
    {
        utils::ComboRenderPipelineDescriptor desc;
        desc.layout = utils::MakeBasicPipelineLayout(device, &resultBGL, 4);
        desc.vertex.module = module;
        desc.cFragment.module = module;
        desc.cFragment.entryPoint = "no_resource_table";
        desc.primitive.topology = wgpu::PrimitiveTopology::PointList;
        noResourceTablePipeline = device.CreateRenderPipeline(&desc);
    }

    // Create the result buffer resource.
    wgpu::BufferDescriptor bDesc = {
        .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc,
        .size = sizeof(uint32_t) * 3,
    };
    wgpu::Buffer resultBuffer = device.CreateBuffer(&bDesc);
    wgpu::BindGroup resultBG = utils::MakeBindGroup(device, resultBGL, {{0, resultBuffer}});

    // Create and populate the resource table.
    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::TextureBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R32Uint,
    };
    wgpu::Texture tex = device.CreateTexture(&tDesc);

    wgpu::ResourceTable table = MakeResourceTable(0);

    // Encode render commands that switch between the two pipelines. The resultBGL index in the
    // Vulkan backend will be pushed by 1 if the pipeline uses the resource table, so we check that
    // the invalidation of VkDescriptorSet inheritance works correctly.
    uint32_t resultIndex = 0;
    auto rp = utils::CreateBasicRenderPass(device, 1, 1);
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&rp.renderPassInfo);
    pass.SetResourceTable(table);
    pass.SetBindGroup(0, resultBG);

    // Start by not using the resource table.
    pass.SetPipeline(noResourceTablePipeline);
    pass.SetImmediates(0, &resultIndex, sizeof(resultIndex));
    pass.Draw(1);
    resultIndex++;

    // Switch to using the resource table.
    pass.SetPipeline(resourceTablePipeline);
    pass.SetImmediates(0, &resultIndex, sizeof(resultIndex));
    pass.Draw(1);
    resultIndex++;

    // And back to not using it.
    pass.SetPipeline(noResourceTablePipeline);
    pass.SetImmediates(0, &resultIndex, sizeof(resultIndex));
    pass.Draw(1);
    resultIndex++;

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

    EXPECT_BUFFER_U32_EQ(42, resultBuffer, 0);
    EXPECT_BUFFER_U32_EQ(10, resultBuffer, 4);
    EXPECT_BUFFER_U32_EQ(42, resultBuffer, 8);
}

// TODO(479179409): Add tests for dynamic validation of filterability
//   - BGL has tex2d, shader has tex1d, swap in default tex1d
//   - BGL has sampler_comparison, shader has sampler, swap in sampler
//   - BGL has unfilterable texture and filtering sampler, swap sampler to non_filternig
//   - BGL has unfilterable texture, bind-less filtering sampler, swap texture
//   - bind-less unfilterable texture, BGL has filtering sampler, swap sampler

DAWN_INSTANTIATE_TEST(ResourceTableTests, D3D12Backend(), MetalBackend(), VulkanBackend());

}  // anonymous namespace
}  // namespace dawn
