// 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 <vector>

#include "dawn/common/Constants.h"
#include "dawn/tests/unittests/validation/ValidationTest.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

class DynamicBindingArrayTests : public ValidationTest {
  protected:
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        return {wgpu::FeatureName::ChromiumExperimentalBindless};
    }

    // Helper similar to utils::MakeBindGroupLayout but that adds a dynamic array.
    wgpu::BindGroupLayout MakeBindGroupLayout(
        wgpu::DynamicBindingKind kind,
        uint32_t dynamicArrayStart = 0,
        std::initializer_list<utils::BindingLayoutEntryInitializationHelper> entriesInitializer =
            {}) {
        std::vector<wgpu::BindGroupLayoutEntry> entries;
        for (const utils::BindingLayoutEntryInitializationHelper& entry : entriesInitializer) {
            entries.push_back(entry);
        }

        wgpu::BindGroupLayoutDynamicBindingArray dynamic;
        dynamic.dynamicArray.kind = kind;
        dynamic.dynamicArray.start = dynamicArrayStart;

        wgpu::BindGroupLayoutDescriptor descriptor;
        descriptor.nextInChain = &dynamic;
        descriptor.entryCount = entries.size();
        descriptor.entries = entries.data();
        return device.CreateBindGroupLayout(&descriptor);
    }

    // Helper similar to utils::MakeBindGroup but that adds a dynamic array.
    wgpu::BindGroup MakeBindGroup(
        const wgpu::BindGroupLayout& layout,
        uint32_t dynamicArraySize,
        std::initializer_list<utils::BindingInitializationHelper> entriesInitializer) {
        std::vector<wgpu::BindGroupEntry> entries;
        for (const utils::BindingInitializationHelper& helper : entriesInitializer) {
            entries.push_back(helper.GetAsBinding());
        }

        wgpu::BindGroupDynamicBindingArray dynamic;
        dynamic.dynamicArraySize = dynamicArraySize;

        wgpu::BindGroupDescriptor descriptor;
        descriptor.nextInChain = &dynamic;
        descriptor.layout = layout;
        descriptor.entryCount = entries.size();
        descriptor.entries = entries.data();

        return device.CreateBindGroup(&descriptor);
    }
};

class DynamicBindingArrayTests_FeatureDisabled : public ValidationTest {};

// Control case where creating a dynamic binding array layout with the feature enabled is valid.
TEST_F(DynamicBindingArrayTests, LayoutSuccessWithFeatureEnabled) {
    wgpu::BindGroupLayoutDynamicBindingArray dynamic;
    dynamic.dynamicArray.kind = wgpu::DynamicBindingKind::SampledTexture;

    wgpu::BindGroupLayoutDescriptor desc;
    desc.nextInChain = &dynamic;

    // No error is produced.
    device.CreateBindGroupLayout(&desc);
}

// Error case where creating a dynamic binding array layout with the feature disabled is an error.
TEST_F(DynamicBindingArrayTests_FeatureDisabled, LayoutErrorWithFeatureDisabled) {
    wgpu::BindGroupLayoutDynamicBindingArray dynamic;
    dynamic.dynamicArray.kind = wgpu::DynamicBindingKind::SampledTexture;

    wgpu::BindGroupLayoutDescriptor desc;
    desc.nextInChain = &dynamic;

    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
}

// Control case where creating a dynamic binding array bind group with the feature enabled is valid.
TEST_F(DynamicBindingArrayTests, GroupSuccessWithFeatureEnabled) {
    wgpu::BindGroupDynamicBindingArray dynamic;
    dynamic.dynamicArraySize = 1;

    wgpu::BindGroupDescriptor desc;
    desc.nextInChain = &dynamic;
    desc.layout = MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture);

    // No error is produced.
    device.CreateBindGroup(&desc);
}

// Error case where creating a dynamic binding array bind group with the feature disabled is an
// error.
TEST_F(DynamicBindingArrayTests_FeatureDisabled, GroupErrorWithFeatureDisabled) {
    wgpu::BindGroupDynamicBindingArray dynamic;
    dynamic.dynamicArraySize = 1;

    wgpu::BindGroupDescriptor desc;
    desc.nextInChain = &dynamic;
    desc.layout = utils::MakeBindGroupLayout(device, {});

    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&desc));
}

// Check that using DynamicArrayKind::Undefined is an error.
TEST_F(DynamicBindingArrayTests, UndefinedArrayKind) {
    wgpu::BindGroupLayoutDynamicBindingArray dynamic;

    wgpu::BindGroupLayoutDescriptor desc;
    desc.nextInChain = &dynamic;

    // Control case: SampledTexture is a valid kind.
    dynamic.dynamicArray.kind = wgpu::DynamicBindingKind::SampledTexture;
    device.CreateBindGroupLayout(&desc);

    // Error case: Undefined is invalid.
    dynamic.dynamicArray.kind = wgpu::DynamicBindingKind::Undefined;
    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
}

// Check that the start of the binding array must be less than maxBindingsPerBindGroup
TEST_F(DynamicBindingArrayTests, DynamicArrayStartLimit) {
    wgpu::BindGroupLayoutDynamicBindingArray dynamic;
    dynamic.dynamicArray.kind = wgpu::DynamicBindingKind::SampledTexture;

    wgpu::BindGroupLayoutDescriptor desc;
    desc.nextInChain = &dynamic;

    // No error is produced if we are under the limit.
    dynamic.dynamicArray.start = kMaxBindingsPerBindGroup - 1;
    device.CreateBindGroupLayout(&desc);

    // Error case if we are at the limit.
    dynamic.dynamicArray.start = kMaxBindingsPerBindGroup;
    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));

    // Error case if we are above the limit.
    dynamic.dynamicArray.start = kMaxBindingsPerBindGroup + 1;
    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
}

// Check that conflicts of binding number are not allowed between dynamic and static bindings.
TEST_F(DynamicBindingArrayTests, ConflictWithStaticBindings) {
    wgpu::BindGroupLayoutEntry entry;
    entry.binding = 0;
    entry.bindingArraySize = 0;
    entry.texture.sampleType = wgpu::TextureSampleType::Float;

    wgpu::BindGroupLayoutDynamicBindingArray dynamic;
    dynamic.dynamicArray.kind = wgpu::DynamicBindingKind::SampledTexture;
    dynamic.dynamicArray.start = 3;

    wgpu::BindGroupLayoutDescriptor desc;
    desc.nextInChain = &dynamic;
    desc.entryCount = 1;
    desc.entries = &entry;

    // Control case: the non-arrayed static binding is before the dynamic array.
    entry.binding = 2;
    entry.bindingArraySize = 1;
    device.CreateBindGroupLayout(&desc);

    // Error case: the non-arrayed static binding is after the dynamic array.
    entry.binding = 3;
    entry.bindingArraySize = 1;
    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));

    // Control case: the arrayed static binding is before the dynamic array.
    entry.binding = 0;
    entry.bindingArraySize = 3;
    device.CreateBindGroupLayout(&desc);

    // Error case: the arrayed static binding is after the dynamic array.
    entry.binding = 0;
    entry.bindingArraySize = 4;
    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
}

// Check that the layout must have a dynamic array, even if the dynamicArraySize is 0.
TEST_F(DynamicBindingArrayTests, LayoutNoDynamicArray) {
    wgpu::BindGroupDynamicBindingArray dynamic;

    wgpu::BindGroupDescriptor desc;
    desc.nextInChain = &dynamic;

    // Control case: dynamicArraySize = 1 is valid with a layout with a dynamic binding array.
    dynamic.dynamicArraySize = 1;
    desc.layout = MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture);
    device.CreateBindGroup(&desc);

    // Control case: dynamicArraySize = 0 is valid with a layout with a dynamic binding array.
    dynamic.dynamicArraySize = 0;
    device.CreateBindGroup(&desc);

    // Error case: dynamicArraySize > 0 requires the layout to have a dynamic binding array.
    dynamic.dynamicArraySize = 1;
    desc.layout = utils::MakeBindGroupLayout(device, {});
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&desc));

    // Error case: dynamicArraySize = 0 requires the layout to have a dynamic binding array.
    dynamic.dynamicArraySize = 1;
    desc.layout = utils::MakeBindGroupLayout(device, {});
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&desc));
}

// Check that the dynamic array size must be below the limit.
TEST_F(DynamicBindingArrayTests, DynamicArraySizeLimit) {
    wgpu::BindGroupLayoutDynamicBindingArray layoutDynamic;
    layoutDynamic.dynamicArray.kind = wgpu::DynamicBindingKind::SampledTexture;
    wgpu::BindGroupLayoutDescriptor layoutDesc;
    layoutDesc.nextInChain = &layoutDynamic;

    wgpu::BindGroupDynamicBindingArray dynamic;
    wgpu::BindGroupDescriptor desc;
    desc.nextInChain = &dynamic;
    desc.layout = device.CreateBindGroupLayout(&layoutDesc);

    // Control case: reaching the limit is valid.
    dynamic.dynamicArraySize = kMaxDynamicBindingArraySize;
    device.CreateBindGroup(&desc);

    // Error case: going above the limit isn't.
    dynamic.dynamicArraySize = kMaxDynamicBindingArraySize + 1;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&desc));
}

// Check that a dynamic array counts as one additional storage buffer when checking against limits.
TEST_F(DynamicBindingArrayTests, UsesOneStorageBufferTowardsLimit) {
    const uint32_t maxStorageBuffers = deviceLimits.maxStorageBuffersPerShaderStage;
    std::vector<wgpu::BindGroupLayoutEntry> storageBufferEntries(maxStorageBuffers);
    for (size_t i = 0; i < storageBufferEntries.size(); i++) {
        storageBufferEntries[i].buffer.type = wgpu::BufferBindingType::ReadOnlyStorage;
        storageBufferEntries[i].visibility =
            wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute;
        storageBufferEntries[i].binding = i;
    }

    wgpu::BindGroupLayoutDynamicBindingArray layoutDynamic;
    layoutDynamic.dynamicArray.kind = wgpu::DynamicBindingKind::SampledTexture;
    layoutDynamic.dynamicArray.start = maxStorageBuffers + 3;
    wgpu::BindGroupLayoutDescriptor layoutDesc;
    layoutDesc.nextInChain = &layoutDynamic;
    layoutDesc.entries = storageBufferEntries.data();

    // Success case: exactly maxStorageBuffers are used (1 for the dynamic array, max - 1 for the
    // the static bindings).
    layoutDesc.entryCount = maxStorageBuffers - 1;
    device.CreateBindGroupLayout(&layoutDesc);

    // Error case: the dynamic binding array storage buffer make the layout go over the limit.
    layoutDesc.entryCount = maxStorageBuffers;
    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&layoutDesc));
}

// Check that the dynamic array size must be below the limit.
TEST_F(DynamicBindingArrayTests, DynamicArrayRequiresASize) {
    wgpu::BindGroupLayoutDynamicBindingArray layoutDynamic;
    layoutDynamic.dynamicArray.kind = wgpu::DynamicBindingKind::SampledTexture;
    wgpu::BindGroupLayoutDescriptor layoutDesc;
    layoutDesc.nextInChain = &layoutDynamic;

    wgpu::BindGroupDynamicBindingArray dynamic;
    dynamic.dynamicArraySize = 0;
    wgpu::BindGroupDescriptor desc;
    desc.layout = device.CreateBindGroupLayout(&layoutDesc);

    // Control case: a size, even of 0 is valid.
    desc.nextInChain = &dynamic;
    device.CreateBindGroup(&desc);

    // Error case: an unspecified size is invalid.
    desc.nextInChain = nullptr;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&desc));
}

// Check that specifying an entry that's neither a known static one or a dynamic one is an error.
TEST_F(DynamicBindingArrayTests, EntryNeitherStaticNorDynamic) {
    // Create a layout with a static entry at 0 and a dynamic binding array starting at 2.
    wgpu::BindGroupLayoutDynamicBindingArray layoutDynamic;
    layoutDynamic.dynamicArray.kind = wgpu::DynamicBindingKind::SampledTexture;
    layoutDynamic.dynamicArray.start = 2;
    wgpu::BindGroupLayoutEntry layoutEntry;
    layoutEntry.binding = 0;
    layoutEntry.texture.sampleType = wgpu::TextureSampleType::Float;
    wgpu::BindGroupLayoutDescriptor layoutDesc;
    layoutDesc.nextInChain = &layoutDynamic;
    layoutDesc.entryCount = 1;
    layoutDesc.entries = &layoutEntry;

    // Create the texture to put in the bind group.
    wgpu::TextureDescriptor tDesc;
    tDesc.size = {1, 1};
    tDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    tDesc.usage = wgpu::TextureUsage::TextureBinding;
    wgpu::Texture texture = device.CreateTexture(&tDesc);

    // Create a bind group on that layout with one or two static entries for 0/1.
    wgpu::BindGroupDynamicBindingArray dynamic;
    dynamic.dynamicArraySize = 10;
    wgpu::BindGroupEntry entries[2];
    entries[0].binding = 0;
    entries[0].textureView = texture.CreateView();
    entries[1].binding = 1;
    entries[1].textureView = texture.CreateView();
    wgpu::BindGroupDescriptor desc;
    desc.nextInChain = &dynamic;
    desc.layout = device.CreateBindGroupLayout(&layoutDesc);
    desc.entries = entries;

    // Control case: specifying only entry 0 which is in the layout is valid.
    desc.entryCount = 1;
    device.CreateBindGroup(&desc);

    // Error case: specifying entry 1 which is not in the layout is an error.
    desc.entryCount = 2;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&desc));
}

// Check that even when the bind group has a dynamic binding array, forgetting a static entry is an
// error.
TEST_F(DynamicBindingArrayTests, MissingStaticEntry) {
    // Create a layout with a static entry at 0 and a dynamic binding array starting at 1.
    wgpu::BindGroupLayoutDynamicBindingArray layoutDynamic;
    layoutDynamic.dynamicArray.kind = wgpu::DynamicBindingKind::SampledTexture;
    layoutDynamic.dynamicArray.start = 1;
    wgpu::BindGroupLayoutEntry layoutEntry;
    layoutEntry.binding = 0;
    layoutEntry.texture.sampleType = wgpu::TextureSampleType::Float;
    wgpu::BindGroupLayoutDescriptor layoutDesc;
    layoutDesc.nextInChain = &layoutDynamic;
    layoutDesc.entryCount = 1;
    layoutDesc.entries = &layoutEntry;

    // Create the texture to put in the bind group.
    wgpu::TextureDescriptor tDesc;
    tDesc.size = {1, 1};
    tDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    tDesc.usage = wgpu::TextureUsage::TextureBinding;
    wgpu::Texture texture = device.CreateTexture(&tDesc);

    // Create a bind group on that layout with or without a static entry at binding 0.
    wgpu::BindGroupDynamicBindingArray dynamic;
    dynamic.dynamicArraySize = 10;
    wgpu::BindGroupEntry entry;
    entry.binding = 0;
    entry.textureView = texture.CreateView();
    wgpu::BindGroupDescriptor desc;
    desc.nextInChain = &dynamic;
    desc.layout = device.CreateBindGroupLayout(&layoutDesc);
    desc.entries = &entry;

    // Control case: static entry 0 is specified.
    desc.entryCount = 1;
    device.CreateBindGroup(&desc);

    // Error case: static entry 0 is missing, which is an error.
    desc.entryCount = 0;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&desc));
}

// Check that dynamic entries must be in bounds of the dynamic binding array.
TEST_F(DynamicBindingArrayTests, BindingPastDynamicArray) {
    // Create a layout with a static entry at 0 and a dynamic binding array starting at 1.
    wgpu::BindGroupLayoutDynamicBindingArray layoutDynamic;
    layoutDynamic.dynamicArray.kind = wgpu::DynamicBindingKind::SampledTexture;
    layoutDynamic.dynamicArray.start = 2;
    wgpu::BindGroupLayoutDescriptor layoutDesc;
    layoutDesc.nextInChain = &layoutDynamic;

    // Create the texture to put in the bind group.
    wgpu::TextureDescriptor tDesc;
    tDesc.size = {1, 1};
    tDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    tDesc.usage = wgpu::TextureUsage::TextureBinding;
    wgpu::Texture texture = device.CreateTexture(&tDesc);

    // Create a bind group on that layout with an entry at binding 11 or 12.
    wgpu::BindGroupDynamicBindingArray dynamic;
    dynamic.dynamicArraySize = 10;
    wgpu::BindGroupEntry entry;
    entry.textureView = texture.CreateView();
    wgpu::BindGroupDescriptor desc;
    desc.nextInChain = &dynamic;
    desc.layout = device.CreateBindGroupLayout(&layoutDesc);
    desc.entries = &entry;
    desc.entryCount = 1;

    // Control case: entry is exactly at the end of the dynamic binding array.
    entry.binding = 11;
    device.CreateBindGroup(&desc);

    // Error case: entry is past the end of the dynamic binding array, which is an error.
    entry.binding = 12;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&desc));
}

// Check that dynamic entries must not conflict.
TEST_F(DynamicBindingArrayTests, DynamicEntryConflict) {
    wgpu::BindGroupLayoutDynamicBindingArray layoutDynamic;
    layoutDynamic.dynamicArray.kind = wgpu::DynamicBindingKind::SampledTexture;
    wgpu::BindGroupLayoutDescriptor layoutDesc;
    layoutDesc.nextInChain = &layoutDynamic;

    // Create the texture to put in the bind group.
    wgpu::TextureDescriptor tDesc;
    tDesc.size = {1, 1};
    tDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    tDesc.usage = wgpu::TextureUsage::TextureBinding;
    wgpu::Texture texture = device.CreateTexture(&tDesc);

    // Create a bind group on that layout with one or two static entries for 0/1.
    wgpu::BindGroupDynamicBindingArray dynamic;
    dynamic.dynamicArraySize = 10;
    wgpu::BindGroupEntry entries[2];
    entries[0].textureView = texture.CreateView();
    entries[1].textureView = texture.CreateView();
    wgpu::BindGroupDescriptor desc;
    desc.nextInChain = &dynamic;
    desc.layout = device.CreateBindGroupLayout(&layoutDesc);
    desc.entryCount = 2;
    desc.entries = entries;

    // Control case: dynamic entries have different binding indices.
    entries[0].binding = 0;
    entries[1].binding = 1;
    device.CreateBindGroup(&desc);

    // Error case: dynamic entries have the same binding index, which is an error.
    entries[0].binding = 0;
    entries[1].binding = 0;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&desc));
}

// Check that dynamic binding arrays are not allowed in combination with an external texture in the
// static bindings part.
// TODO(https://issues.chromium.org/435251399): Remove this constraint that's only a workaround
// while prototyping.
TEST_F(DynamicBindingArrayTests, NotAllowedWithExternalTextures) {
    // Control case, static buffer binding + dynamic binding array is allowed.
    MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture, 5,
                        {{
                            0,
                            wgpu::ShaderStage::Fragment,
                            wgpu::BufferBindingType::Uniform,
                        }});

    // Error case, static buffer binding + dynamic binding array is an error.
    ASSERT_DEVICE_ERROR(MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture, 5,
                                            {{
                                                0,
                                                wgpu::ShaderStage::Fragment,
                                                &utils::kExternalTextureBindingLayout,
                                            }}));
}

// Check that DynamicBindingKind::SampledTexture must be a texture entry.
TEST_F(DynamicBindingArrayTests, SampledTextureKindRequiresTexture) {
    wgpu::BindGroupLayoutDynamicBindingArray layoutDynamic;
    layoutDynamic.dynamicArray.kind = wgpu::DynamicBindingKind::SampledTexture;
    wgpu::BindGroupLayoutDescriptor layoutDesc;
    layoutDesc.nextInChain = &layoutDynamic;

    // Create the texture to put in the bind group.
    wgpu::TextureDescriptor tDesc;
    tDesc.size = {1, 1};
    tDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    tDesc.usage = wgpu::TextureUsage::TextureBinding;
    wgpu::Texture texture = device.CreateTexture(&tDesc);

    // Create the buffer to put in the bind group.
    wgpu::BufferDescriptor bDesc;
    bDesc.size = 4;
    bDesc.usage = wgpu::BufferUsage::Storage;
    wgpu::Buffer buffer = device.CreateBuffer(&bDesc);

    // Create a bind group on that layout with one or two static entries for 0/1.
    wgpu::BindGroupDynamicBindingArray dynamic;
    dynamic.dynamicArraySize = 10;
    wgpu::BindGroupDescriptor desc;
    desc.nextInChain = &dynamic;
    desc.layout = device.CreateBindGroupLayout(&layoutDesc);
    desc.entryCount = 1;

    // Control case: entry is a texture, which is valid.
    wgpu::BindGroupEntry textureEntry;
    textureEntry.binding = 0;
    textureEntry.textureView = texture.CreateView();
    desc.entries = &textureEntry;
    device.CreateBindGroup(&desc);

    // Error case: entry is a buffer, which is an error.
    wgpu::BindGroupEntry bufferEntry;
    bufferEntry.binding = 0;
    bufferEntry.buffer = buffer;
    desc.entries = &bufferEntry;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&desc));
}

// Check that the view must have only the TextureBinding usage for DynamicKind::SampledTexture.
TEST_F(DynamicBindingArrayTests, SampledTextureKindRequiresTextureBindingOnlyView) {
    wgpu::BindGroupLayout layout = MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture);

    wgpu::TextureDescriptor tDesc{
        .usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding |
                 wgpu::TextureUsage::StorageBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R32Uint,
    };
    wgpu::Texture tex = device.CreateTexture(&tDesc);

    // Control case: limiting the usage to TextureBinding is valid to add to SampledTexture.
    {
        wgpu::TextureViewDescriptor vDesc{
            .usage = wgpu::TextureUsage::TextureBinding,
        };
        wgpu::TextureView view = tex.CreateView(&vDesc);
        MakeBindGroup(layout, 1, {{0, view}});
    }

    // Error case: having unrelated usages in the view is not allowed. RenderAttachment case.
    {
        wgpu::TextureViewDescriptor vDesc{
            .usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment,
        };
        wgpu::TextureView view = tex.CreateView(&vDesc);
        ASSERT_DEVICE_ERROR(MakeBindGroup(layout, 1, {{0, view}}));
    }

    // Error case: having unrelated usages in the view is not allowed. StorageBinding case.
    {
        wgpu::TextureViewDescriptor vDesc{
            .usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::StorageBinding,
        };
        wgpu::TextureView view = tex.CreateView(&vDesc);
        ASSERT_DEVICE_ERROR(MakeBindGroup(layout, 1, {{0, view}}));
    }

    // Error case: the defaulted texture usages don't contain TextureBinding.
    {
        wgpu::TextureDescriptor tDesc2 = tDesc;
        tDesc2.usage = wgpu::TextureUsage::CopyDst;
        wgpu::TextureView view = device.CreateTexture(&tDesc2).CreateView();
        ASSERT_DEVICE_ERROR(MakeBindGroup(layout, 1, {{0, view}}));
    }
}

// Check that the view must have a single aspect for DynamicKind::SampledTexture.
TEST_F(DynamicBindingArrayTests, SampledTextureKindRequiresSingleAspect) {
    wgpu::BindGroupLayout layout = MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture);

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

    // Success case, only the depth aspect is selected.
    {
        wgpu::TextureViewDescriptor vDesc{
            .aspect = wgpu::TextureAspect::DepthOnly,
        };
        wgpu::TextureView view = tex.CreateView(&vDesc);
        MakeBindGroup(layout, 1, {{0, view}});
    }

    // Success case, only the stencil aspect is selected.
    {
        wgpu::TextureViewDescriptor vDesc{
            .aspect = wgpu::TextureAspect::StencilOnly,
        };
        wgpu::TextureView view = tex.CreateView(&vDesc);
        MakeBindGroup(layout, 1, {{0, view}});
    }

    // Error case: both aspects are selected.
    {
        wgpu::TextureView view = tex.CreateView();
        ASSERT_DEVICE_ERROR(MakeBindGroup(layout, 1, {{0, view}}));
    }
}

// Test that it is an error to call .Destroy() on a bind group without a dynamic array.
TEST_F(DynamicBindingArrayTests, DestroyDisallowedOnStaticOnlyBindGroup) {
    // Create an empty dynamic bind group.
    wgpu::BindGroupLayout layoutDynamic =
        MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture);
    wgpu::BindGroup bgDynamic = MakeBindGroup(layoutDynamic, 0, {});

    // Create a static only bind group.
    wgpu::BindGroupLayout staticLayout = utils::MakeBindGroupLayout(device, {});
    wgpu::BindGroup bgStatic = utils::MakeBindGroup(device, staticLayout, {});

    // Success case: calling .Destroy() on a dynamic array bind group is valid.
    bgDynamic.Destroy();
    // Calling it multiple times is even valid!
    bgDynamic.Destroy();

    // Error case: calling .Destroy() on a static only bind group is an error.
    ASSERT_DEVICE_ERROR(bgStatic.Destroy());
}

// Test that it is an error to call .Destroy() on an error bind group. This is a regression test for
// an issues where doing so was triggering an ASSERT.
TEST_F(DynamicBindingArrayTests, DestroyOnErrorBindGroup) {
    // Create an error bind group.
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Uniform}});
    wgpu::BindGroup bg;
    ASSERT_DEVICE_ERROR(bg = utils::MakeBindGroup(device, layout, {}));

    ASSERT_DEVICE_ERROR(bg.Destroy());
}

// Test that using a destroyed dynamic binding array in a render pass in a submit is an error.
TEST_F(DynamicBindingArrayTests, DestroyedDynamicBindingArrayUsedInRenderPass) {
    // Create an empty dynamic bind group.
    wgpu::BindGroupLayout layout = MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture);
    wgpu::BindGroup bg = MakeBindGroup(layout, 0, {});

    for (bool destroy : {false, true}) {
        if (destroy) {
            bg.Destroy();
        }

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        auto rp = utils::CreateBasicRenderPass(device, 1, 1, wgpu::TextureFormat::RGBA8Unorm);
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&rp.renderPassInfo);
        pass.SetBindGroup(0, bg);
        pass.End();

        wgpu::CommandBuffer commands = encoder.Finish();
        if (destroy) {
            ASSERT_DEVICE_ERROR(device.GetQueue().Submit(1, &commands));
        } else {
            device.GetQueue().Submit(1, &commands);
        }
    }
}

// Test that using a destroyed dynamic binding array in a compute pass in a submit is an error.
TEST_F(DynamicBindingArrayTests, DestroyedDynamicBindingArrayUsedInComputePass) {
    // Create an empty dynamic bind group.
    wgpu::BindGroupLayout layout = MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture);
    wgpu::BindGroup bg = MakeBindGroup(layout, 0, {});

    for (bool destroy : {false, true}) {
        if (destroy) {
            bg.Destroy();
        }

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetBindGroup(0, bg);
        pass.End();

        wgpu::CommandBuffer commands = encoder.Finish();
        if (destroy) {
            ASSERT_DEVICE_ERROR(device.GetQueue().Submit(1, &commands));
        } else {
            device.GetQueue().Submit(1, &commands);
        }
    }
}

// Test that using a destroyed dynamic binding array in a render bundle in a submit is an error.
TEST_F(DynamicBindingArrayTests, DestroyedDynamicBindingArrayUsedInRenderBundle) {
    // Create an empty dynamic bind group.
    wgpu::BindGroupLayout layout = MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture);
    wgpu::BindGroup bg = MakeBindGroup(layout, 0, {});

    // Create the render bundle
    wgpu::TextureFormat passFormat = wgpu::TextureFormat::RGBA8Unorm;

    wgpu::RenderBundleEncoderDescriptor rbDesc;
    rbDesc.colorFormatCount = 1;
    rbDesc.colorFormats = &passFormat;

    wgpu::RenderBundleEncoder rbEncoder = device.CreateRenderBundleEncoder(&rbDesc);
    rbEncoder.SetBindGroup(0, bg);
    wgpu::RenderBundle bundle = rbEncoder.Finish();

    for (bool destroy : {false, true}) {
        if (destroy) {
            bg.Destroy();
        }

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        auto rp = utils::CreateBasicRenderPass(device, 1, 1, wgpu::TextureFormat::RGBA8Unorm);
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&rp.renderPassInfo);
        pass.ExecuteBundles(1, &bundle);
        pass.End();

        wgpu::CommandBuffer commands = encoder.Finish();
        if (destroy) {
            ASSERT_DEVICE_ERROR(device.GetQueue().Submit(1, &commands));
        } else {
            device.GetQueue().Submit(1, &commands);
        }
    }
}

// Test that using the WGSL enable requires the bindless extension.
TEST_F(DynamicBindingArrayTests_FeatureDisabled, WGSLEnableNotAllowed) {
    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;
        @group(0) @binding(0) var a : resource_binding;

        @compute @workgroup_size(1) fn main() {
            _ = hasBinding<texture_2d<f32>>(a, 42);
        }
    )"));
}

// Test that a shader using a dynamic binding array requires a layout with one.
TEST_F(DynamicBindingArrayTests, ShaderRequiresLayoutWithDynamicArray) {
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;
        @group(0) @binding(0) var a : resource_binding;

        @compute @workgroup_size(1) fn main() {
            _ = hasBinding<texture_2d<f32>>(a, 42);
        }
    )");

    // Success case, the layout has a dynamic binding array.
    wgpu::BindGroupLayout bglDynamic =
        MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture);
    csDesc.layout = utils::MakeBasicPipelineLayout(device, &bglDynamic);
    device.CreateComputePipeline(&csDesc);

    // Error case, the layout doesn't have a dynamic binding array.
    wgpu::BindGroupLayout bglStatic = utils::MakeBindGroupLayout(device, {});
    csDesc.layout = utils::MakeBasicPipelineLayout(device, &bglStatic);
    ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&csDesc));

    // Error case, the layout doesn't have a dynamic binding array (even if there is a similar
    // looking binding).
    wgpu::BindGroupLayout bglStaticWithTexture = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float}});
    csDesc.layout = utils::MakeBasicPipelineLayout(device, &bglStaticWithTexture);
    ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&csDesc));
}

// Test that it is valid to have a layout specifying a dynamic binding array with a shader that
// doesn't have one.
TEST_F(DynamicBindingArrayTests, ShaderNoDynamicArrayWithLayoutThatHasOne) {
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        @compute @workgroup_size(1) fn main() {
        }
    )");
    wgpu::BindGroupLayout bglDynamic =
        MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture);
    csDesc.layout = utils::MakeBasicPipelineLayout(device, &bglDynamic);
    device.CreateComputePipeline(&csDesc);
}

// Test that the dynamic array start must match between shader and layout.
TEST_F(DynamicBindingArrayTests, ShaderAndLayoutDynamicArrayStartMatches) {
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;
        @group(0) @binding(1) var a : resource_binding;

        @compute @workgroup_size(1) fn main() {
            _ = hasBinding<texture_2d<f32>>(a, 42);
        }
    )");

    // Success case, start of the array matches.
    wgpu::BindGroupLayout bgl1 = MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture, 1);
    csDesc.layout = utils::MakeBasicPipelineLayout(device, &bgl1);
    device.CreateComputePipeline(&csDesc);

    // Error case, layout start is before the shader's start.
    wgpu::BindGroupLayout bgl0 = MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture, 0);
    csDesc.layout = utils::MakeBasicPipelineLayout(device, &bgl0);
    ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&csDesc));

    // Error case, layout start is after the shader's start.
    wgpu::BindGroupLayout bgl2 = MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture, 2);
    csDesc.layout = utils::MakeBasicPipelineLayout(device, &bgl2);
    ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&csDesc));
}

// Test that the @binding decoration of the dynamic array must be less than maxBindingsPerBindGroup.
TEST_F(DynamicBindingArrayTests, ShaderArrayStartLessThanMaxBindingsPerBindGroup) {
    wgpu::BindGroupLayout bgl =
        MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture, kMaxBindingsPerBindGroup - 1);

    // Control case, we are just below the limit.
    {
        wgpu::ComputePipelineDescriptor csDesc;
        csDesc.compute.module = utils::CreateShaderModule(device, R"(
                enable chromium_experimental_dynamic_binding;
                @group(0) @binding()" + std::to_string(kMaxBindingsPerBindGroup - 1) +
                                                                      R"() var a : resource_binding;

                @compute @workgroup_size(1) fn main() {
                    _ = hasBinding<texture_2d<f32>>(a, 42);
                }
            )");
        csDesc.layout = utils::MakeBasicPipelineLayout(device, &bgl);
        device.CreateComputePipeline(&csDesc);
    }

    // Error case, we are above the limit.
    {
        wgpu::ComputePipelineDescriptor csDesc;
        csDesc.compute.module = utils::CreateShaderModule(device, R"(
                enable chromium_experimental_dynamic_binding;
                @group(0) @binding()" + std::to_string(kMaxBindingsPerBindGroup) +
                                                                      R"() var a : resource_binding;

                @compute @workgroup_size(1) fn main() {
                    _ = hasBinding<texture_2d<f32>>(a, 42);
                }
            )");
        csDesc.layout = utils::MakeBasicPipelineLayout(device, &bgl);
        // Two errors happen because we cannot create a layout that matches, but check that the
        // shader's validation about maxBindingsPerBindGroup is the one that's reported.
        ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&csDesc),
                            testing::HasSubstr("maxBindingsPerBindGroup"));
    }
}

// Test that the @group decoration of the dynamic array must be less than maxBindGroups.
TEST_F(DynamicBindingArrayTests, ShaderArrayAtMaxBindGroups) {
    std::array<wgpu::BindGroupLayout, kMaxBindGroups> bgls;
    bgls[bgls.size() - 1] = MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture);

    wgpu::PipelineLayoutDescriptor plDesc;
    plDesc.bindGroupLayoutCount = bgls.size();
    plDesc.bindGroupLayouts = bgls.data();
    wgpu::PipelineLayout pl = device.CreatePipelineLayout(&plDesc);

    // Control case, we are just below the limit.
    {
        wgpu::ComputePipelineDescriptor csDesc;
        csDesc.compute.module =
            utils::CreateShaderModule(device,
                                      R"(
                enable chromium_experimental_dynamic_binding;
                @group()" + std::to_string(kMaxBindGroups - 1) +
                                          R"() @binding(0) var a : resource_binding;

                @compute @workgroup_size(1) fn main() {
                    _ = hasBinding<texture_2d<f32>>(a, 42);
                }
            )");
        csDesc.layout = pl;
        device.CreateComputePipeline(&csDesc);
    }

    // Error case, we are above the limit.
    {
        wgpu::ComputePipelineDescriptor csDesc;
        csDesc.compute.module =
            utils::CreateShaderModule(device,
                                      R"(
                enable chromium_experimental_dynamic_binding;
                @group()" + std::to_string(kMaxBindGroups) +
                                          R"() @binding(0) var a : resource_binding;

                @compute @workgroup_size(1) fn main() {
                    _ = hasBinding<texture_2d<f32>>(a, 42);
                }
            )");
        csDesc.layout = pl;
        // Two errors happen because we cannot create a layout that matches, but check that the
        // shader's validation about maxBindingsPerBindGroup is the one that's reported.
        ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&csDesc),
                            testing::HasSubstr("maxBindGroups"));
    }
}

// Test that the group for the dynamic binding array must be in the PipelineLayout.
TEST_F(DynamicBindingArrayTests, ShaderBindingArrayMustHaveGroupInPipelineLayout) {
    std::array<wgpu::BindGroupLayout, 3> bgls = {
        nullptr, MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture), nullptr};

    wgpu::PipelineLayoutDescriptor plDesc;
    plDesc.bindGroupLayoutCount = bgls.size();
    plDesc.bindGroupLayouts = bgls.data();

    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.layout = device.CreatePipelineLayout(&plDesc);

    // Control case, the group is in the pipeline layout.
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;
        @group(1) @binding(0) var a : resource_binding;

        @compute @workgroup_size(1) fn main() {
            _ = hasBinding<texture_2d<f32>>(a, 42);
        }
    )");
    device.CreateComputePipeline(&csDesc);

    // Error case, the group is not in the layout (@group(0) case)
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;
        @group(0) @binding(0) var a : resource_binding;

        @compute @workgroup_size(1) fn main() {
            _ = hasBinding<texture_2d<f32>>(a, 42);
        }
    )");
    ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&csDesc));

    // Error case, the group is not in the layout (@group(2) case)
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;
        @group(2) @binding(0) var a : resource_binding;

        @compute @workgroup_size(1) fn main() {
            _ = hasBinding<texture_2d<f32>>(a, 42);
        }
    )");
    ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&csDesc));
}

// Test that a shader cannot have two dynamic binding arrays on the same group.
TEST_F(DynamicBindingArrayTests, ShaderTwoDynamicArraysSameGroupIsAnError) {
    // Control case, the two dynamic binding arrays are on different groups.
    utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;
        @group(0) @binding(0) var a : resource_binding;
        @group(1) @binding(1) var b : resource_binding;

        @compute @workgroup_size(1) fn main() {
            _ = hasBinding<texture_2d<f32>>(a, 42);
            _ = hasBinding<texture_2d<f32>>(b, 42);
        }
    )");

    // Error case, the two dynamic binding arrays are on the same group.
    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;
        @group(0) @binding(0) var a : resource_binding;
        @group(0) @binding(1) var b : resource_binding;

        @compute @workgroup_size(1) fn main() {
            _ = hasBinding<texture_2d<f32>>(a, 42);
            _ = hasBinding<texture_2d<f32>>(b, 42);
        }
    )"));
}

// Test that a shader using only arrayLength on the dynamic binding array is compatible with any
// DynamicBindingKind.
TEST_F(DynamicBindingArrayTests, DynamicArrayKindWithoutTypeInfoValidWithAllLayouts) {
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;
        @group(0) @binding(0) var a : resource_binding;

        @compute @workgroup_size(1) fn main() {
            _ = arrayLength(a);
        }
    )");

    // Check that it is compatible with DynamicBindingKind::SampledTexture.
    {
        wgpu::BindGroupLayout bgl = MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture);
        csDesc.layout = utils::MakeBasicPipelineLayout(device, &bgl);
        device.CreateComputePipeline(&csDesc);
    }

    // TODO(https://crbug.com/435317394): Add tests with additional DynamicBindingKind.
}

// TODO(https://crbug.com/435317394): Add tests for an error being produced at shader module
// compilation time if it uses the same resource_binding with different DynamicArrayKinds.

// Test that BGL defaulting works with dynamic binding arrays.
TEST_F(DynamicBindingArrayTests, GetBGLSuccess) {
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.layout = nullptr;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;
        @group(0) @binding(0) var a : resource_binding;

        @compute @workgroup_size(1) fn main() {
            _ = hasBinding<texture_2d<f32>>(a, 42);
        }
    )");
    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&csDesc);

    MakeBindGroup(pipeline.GetBindGroupLayout(0), 18, {});
}

// Test that the correct array start is defaulted.
TEST_F(DynamicBindingArrayTests, GetBGLDefaultedArrayStart) {
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.layout = nullptr;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;
        @group(0) @binding(7) var a : resource_binding;

        @compute @workgroup_size(1) fn main() {
            _ = hasBinding<texture_2d<f32>>(a ,42);
        }
    )");
    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&csDesc);

    // Create the texture to use in the bind group.
    wgpu::TextureDescriptor tDesc;
    tDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    tDesc.size = {1, 1};
    tDesc.usage = wgpu::TextureUsage::TextureBinding;
    wgpu::Texture tex = device.CreateTexture(&tDesc);

    // Success case, the array starts at 7 so a texture at binding 7 and 7 + 1 is valid.
    MakeBindGroup(pipeline.GetBindGroupLayout(0), 2,
                  {
                      {7, tex.CreateView()},
                      {8, tex.CreateView()},
                  });

    // Error case, the texture is before the start of the binding array.
    ASSERT_DEVICE_ERROR(MakeBindGroup(pipeline.GetBindGroupLayout(0), 2,
                                      {
                                          {6, tex.CreateView()},
                                      }));

    // Error case, the texture is after the end of the binding array.
    ASSERT_DEVICE_ERROR(MakeBindGroup(pipeline.GetBindGroupLayout(0), 2,
                                      {
                                          {9, tex.CreateView()},
                                      }));
}

// Test that the correct array kind is defaulted.
TEST_F(DynamicBindingArrayTests, GetBGLDefaultedArrayKind) {
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.layout = nullptr;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;
        @group(0) @binding(0) var a : resource_binding;

        @compute @workgroup_size(1) fn main() {
            _ = hasBinding<texture_2d<f32>>(a, 42);
        }
    )");
    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&csDesc);

    // Create the texture to use in the bind group.
    wgpu::TextureDescriptor tDesc;
    tDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    tDesc.size = {1, 1};
    tDesc.usage = wgpu::TextureUsage::TextureBinding;
    wgpu::Texture tex = device.CreateTexture(&tDesc);

    // Success case, the BGL will have DynamicArrayKind::SampledTexture.
    MakeBindGroup(pipeline.GetBindGroupLayout(0), 1,
                  {
                      {0, tex.CreateView()},
                  });

    // TODO(https://crbug.com/435317394): Add tests for the DynamicArrayKind. It is not possible to
    // create other DynamicArrayKind than SampledTexture at the moment so we cannot test error
    // cases.
}

// Test that defaulting fails if we go above maxBindingsPerBindGroup
TEST_F(DynamicBindingArrayTests, GetBGLMaxBindingsPerGroupLimit) {
    // Control case, we are just below the limit.
    {
        wgpu::ComputePipelineDescriptor csDesc;
        csDesc.layout = nullptr;
        csDesc.compute.module = utils::CreateShaderModule(device, R"(
                enable chromium_experimental_dynamic_binding;
                @group(0) @binding()" + std::to_string(kMaxBindingsPerBindGroup - 1) +
                                                                      R"() var a : resource_binding;

                @compute @workgroup_size(1) fn main() {
                    _ = hasBinding<texture_2d<f32>>(a, 42);
                }
            )");
        device.CreateComputePipeline(&csDesc);
    }

    // Error case, we are above the limit.
    {
        wgpu::ComputePipelineDescriptor csDesc;
        csDesc.layout = nullptr;
        csDesc.compute.module = utils::CreateShaderModule(device, R"(
                enable chromium_experimental_dynamic_binding;
                @group(0) @binding()" + std::to_string(kMaxBindingsPerBindGroup) +
                                                                      R"() var a : resource_binding;

                @compute @workgroup_size(1) fn main() {
                    _ = hasBinding<texture_2d<f32>>(a, 42);
                }
            )");
        ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&csDesc));
    }
}

// Test that defaulting fails if we go above maxBindGroups
TEST_F(DynamicBindingArrayTests, GetBGLMaxBindGroupsLimit) {
    // Control case, we are just below the limit.
    {
        wgpu::ComputePipelineDescriptor csDesc;
        csDesc.layout = nullptr;
        csDesc.compute.module =
            utils::CreateShaderModule(device,
                                      R"(
                enable chromium_experimental_dynamic_binding;
                @group()" + std::to_string(kMaxBindGroups - 1) +
                                          R"() @binding(0) var a : resource_binding;

                @compute @workgroup_size(1) fn main() {
                    _ = hasBinding<texture_2d<f32>>(a, 42);
                }
            )");
        device.CreateComputePipeline(&csDesc);
    }

    // Error case, we are above the limit.
    {
        wgpu::ComputePipelineDescriptor csDesc;
        csDesc.layout = nullptr;
        csDesc.compute.module =
            utils::CreateShaderModule(device,
                                      R"(
                enable chromium_experimental_dynamic_binding;
                @group()" + std::to_string(kMaxBindGroups) +
                                          R"() @binding(0) var a : resource_binding;

                @compute @workgroup_size(1) fn main() {
                    _ = hasBinding<texture_2d<f32>>(a, 42);
                }
            )");
        ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&csDesc));
    }
}

// Test that the dynamic binding arrays start must match between stages.
TEST_F(DynamicBindingArrayTests, GetBGLArrayStartMatchesBetweenStages) {
    utils::ComboRenderPipelineDescriptor pDesc;
    pDesc.layout = nullptr;
    pDesc.vertex.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;
        @group(0) @binding(38) var a : resource_binding;

        @vertex fn vs() -> @builtin(position) vec4f {
            _ = hasBinding<texture_2d<f32>>(a, 42);
            return vec4f();
        }
    )");

    // Success case: dynamic binding arrays match between the stages.
    {
        pDesc.cFragment.module = utils::CreateShaderModule(device, R"(
            enable chromium_experimental_dynamic_binding;
            @group(0) @binding(38) var a : resource_binding;

            @fragment fn fs() -> @location(0) vec4f {
                _ = hasBinding<texture_2d<f32>>(a, 42);
                return vec4f();
            }
        )");
        device.CreateRenderPipeline(&pDesc);
    }

    // Success case: dynamic binding arrays have different starts on different groups.
    {
        pDesc.cFragment.module = utils::CreateShaderModule(device, R"(
            enable chromium_experimental_dynamic_binding;
            @group(1) @binding(3) var a : resource_binding;

            @fragment fn fs() -> @location(0) vec4f {
                _ = hasBinding<texture_2d<f32>>(a, 42);
                return vec4f();
            }
        )");
        device.CreateRenderPipeline(&pDesc);
    }

    // Error case: dynamic binding arrays have different starts on the same group.
    {
        pDesc.cFragment.module = utils::CreateShaderModule(device, R"(
            enable chromium_experimental_dynamic_binding;
            @group(0) @binding(3) var a : resource_binding;

            @fragment fn fs() -> @location(0) vec4f {
                _ = hasBinding<texture_2d<f32>>(a, 42);
                return vec4f();
            }
        )");
        ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&pDesc));
    }
}

// Test that defaulting the layout when no type information is given for the dynamic binding array
// is an error.
TEST_F(DynamicBindingArrayTests, DefaultedDynamicArrayKindMustNotBeUndefined) {
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;
        @group(0) @binding(0) var a : resource_binding;

        @compute @workgroup_size(1) fn main() {
            _ = arrayLength(a);
        }
    )");

    // Control case, explicitly giving a layout works
    wgpu::BindGroupLayout bgl = MakeBindGroupLayout(wgpu::DynamicBindingKind::SampledTexture);
    csDesc.layout = utils::MakeBasicPipelineLayout(device, &bgl);
    device.CreateComputePipeline(&csDesc);

    // Error case, defaulting the layout is not possible.
    csDesc.layout = nullptr;
    ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&csDesc));
}

// Test merging of DynamicBindingKind between VS and FS (FS typed case)
TEST_F(DynamicBindingArrayTests, MergingUnknowVSDynamicArrayKindInFS) {
    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;

        @group(0) @binding(0) var untyped : resource_binding;
        @vertex fn vs() -> @builtin(position) vec4f {
            _ = arrayLength(untyped);
            return vec4f();
        }

        @group(0) @binding(0) var typed : resource_binding;
        @fragment fn fs() -> @location(0) vec4f {
            _ = hasBinding<texture_2d<f32>>(typed, 42);
            return vec4f();
        }
    )");

    utils::ComboRenderPipelineDescriptor pDesc;
    pDesc.layout = nullptr;
    pDesc.vertex.module = module;
    pDesc.cFragment.module = module;
    wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pDesc);

    // Check that this is a DynamicBindingKind::SampledTexture dynamic binding array.
    wgpu::TextureDescriptor tDesc = {
        .usage = wgpu::TextureUsage::TextureBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::RGBA8Unorm,
    };
    wgpu::Texture tex = device.CreateTexture(&tDesc);
    MakeBindGroup(pipeline.GetBindGroupLayout(0), 1, {{0, tex.CreateView()}});
}

// Test merging of DynamicBindingKind between VS and FS (VS typed case)
TEST_F(DynamicBindingArrayTests, MergingUnknowFSDynamicArrayKindInVS) {
    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        enable chromium_experimental_dynamic_binding;

        @group(0) @binding(0) var typed : resource_binding;
        @vertex fn vs() -> @builtin(position) vec4f {
            _ = hasBinding<texture_2d<f32>>(typed, 42);
            return vec4f();
        }

        @group(0) @binding(0) var untyped : resource_binding;
        @fragment fn fs() -> @location(0) vec4f {
            _ = arrayLength(untyped);
            return vec4f();
        }
    )");

    utils::ComboRenderPipelineDescriptor pDesc;
    pDesc.layout = nullptr;
    pDesc.vertex.module = module;
    pDesc.cFragment.module = module;
    wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pDesc);

    // Check that this is a DynamicBindingKind::SampledTexture dynamic binding array.
    wgpu::TextureDescriptor tDesc = {
        .usage = wgpu::TextureUsage::TextureBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::RGBA8Unorm,
    };
    wgpu::Texture tex = device.CreateTexture(&tDesc);
    MakeBindGroup(pipeline.GetBindGroupLayout(0), 1, {{0, tex.CreateView()}});
}

// TODO(https://crbug.com/435317394): Add tests for the DynamicArrayKind defaulting / merging
// between stages. Tests to add are:
//  - Using two incompatible kinds between stages produces an error.

// Test that pinning / unpinning is valid for a simple case. This is a control for the test that
// errors are produced when the feature is not enabled.
TEST_F(DynamicBindingArrayTests, PinUnpinTextureSuccess) {
    wgpu::TextureDescriptor desc{
        .usage = wgpu::TextureUsage::TextureBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R32Float,
    };
    wgpu::Texture tex = device.CreateTexture(&desc);

    tex.Pin(wgpu::TextureUsage::TextureBinding);
    tex.Unpin();
}

// Test that calling pin/unpin is an error when the feature is not enabled.
TEST_F(DynamicBindingArrayTests_FeatureDisabled, PinUnpinTextureSuccess) {
    wgpu::TextureDescriptor desc{
        .usage = wgpu::TextureUsage::TextureBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R32Float,
    };
    wgpu::Texture tex = device.CreateTexture(&desc);

    ASSERT_DEVICE_ERROR(tex.Pin(wgpu::TextureUsage::TextureBinding));
    ASSERT_DEVICE_ERROR(tex.Unpin());
}

// Test the validation of the usage parameter of Pin.
TEST_F(DynamicBindingArrayTests, PinUnpinTextureUsageConstraint) {
    wgpu::TextureDescriptor desc{
        .size = {1, 1},
        .format = wgpu::TextureFormat::R32Float,
    };

    desc.usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopySrc |
                 wgpu::TextureUsage::StorageBinding;
    wgpu::Texture testTexture = device.CreateTexture(&desc);

    desc.usage = wgpu::TextureUsage::RenderAttachment;
    wgpu::Texture renderOnlyTexture = device.CreateTexture(&desc);

    // Control case, pinning the sampled texture to TextureBinding is valid.
    testTexture.Pin(wgpu::TextureUsage::TextureBinding);

    // Error case, pinning to a usage not in the texture is invalid.
    ASSERT_DEVICE_ERROR(renderOnlyTexture.Pin(wgpu::TextureUsage::TextureBinding));

    // Error case, pinning to an invalid usage is invalid.
    ASSERT_DEVICE_ERROR(testTexture.Pin(static_cast<wgpu::TextureUsage>(0x8000'0000)));

    // Error case, pinning must be to a shader usage.
    ASSERT_DEVICE_ERROR(testTexture.Pin(wgpu::TextureUsage::CopySrc));

    // Error case, pinning must be to a shader usage.
    // TODO(https://crbug.com/435317394): Lift this constraint and allow other shader usages.
    ASSERT_DEVICE_ERROR(testTexture.Pin(wgpu::TextureUsage::StorageBinding));
}

// Test that pinning / unpinning don't need to be balanced.
TEST_F(DynamicBindingArrayTests, PinUnpinUnbalancedIsValid) {
    wgpu::TextureDescriptor desc{
        .usage = wgpu::TextureUsage::TextureBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R32Float,
    };
    wgpu::Texture tex = device.CreateTexture(&desc);

    // Pinning right after creation is valid.
    tex.Unpin();

    // Pinning twice is valid.
    tex.Pin(wgpu::TextureUsage::TextureBinding);
    // TODO(https://crbug.com/435317394): Use a different usage here when another is valid.
    tex.Pin(wgpu::TextureUsage::TextureBinding);

    // Unpinning twice (plus one more to make sure we are unbalanced) is valid.
    tex.Unpin();
    tex.Unpin();
    tex.Unpin();
}

// Test that pinning is not allowed on a destroyed texture.
TEST_F(DynamicBindingArrayTests, PinDestroyedTextureInvalid) {
    wgpu::TextureDescriptor desc{
        .usage = wgpu::TextureUsage::TextureBinding,
        .size = {1, 1},
        .format = wgpu::TextureFormat::R32Float,
    };
    wgpu::Texture tex = device.CreateTexture(&desc);

    // Success case, pinning before Destroy() is valid.
    tex.Pin(wgpu::TextureUsage::TextureBinding);
    tex.Unpin();

    // Error case, pinning a destroyed texture is not allowed.
    tex.Destroy();
    ASSERT_DEVICE_ERROR(tex.Pin(wgpu::TextureUsage::TextureBinding));
}

// TODO(https://crbug.com/435317394): This is missing the most important part of the pinned usage
// validation: at submit time (or writeTexture and friends) we must ensure that the usages don't
// conflict with the pinned usage. However adding this validation is a bit risky for the prototyping
// of bindless as it could cause perf regressions. Instead backends will ASSERT when possible that
// no barriers are emitted for the texture while it is pinned.

}  // anonymous namespace
}  // namespace dawn
