// Copyright 2017 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 <limits>
#include <tuple>
#include <utility>
#include <vector>

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

namespace dawn {
namespace {

class BindGroupValidationTest : public ValidationTest {
  public:
    wgpu::Texture CreateTexture(wgpu::TextureUsage usage,
                                wgpu::TextureFormat format,
                                uint32_t layerCount) {
        wgpu::TextureDescriptor descriptor;
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.size = {kWidth, kHeight, layerCount};
        descriptor.sampleCount = 1;
        descriptor.mipLevelCount = 1;
        descriptor.usage = usage;
        descriptor.format = format;

        return device.CreateTexture(&descriptor);
    }

    void SetUp() override {
        ValidationTest::SetUp();

        // Create objects to use as resources inside test bind groups.
        {
            wgpu::BufferDescriptor descriptor;
            descriptor.size = 1024;
            descriptor.usage = wgpu::BufferUsage::Uniform;
            mUBO = device.CreateBuffer(&descriptor);
        }
        {
            wgpu::BufferDescriptor descriptor;
            descriptor.size = 1024;
            descriptor.usage = wgpu::BufferUsage::Storage;
            mSSBO = device.CreateBuffer(&descriptor);
        }
        {
            mSampler = device.CreateSampler();
        }
        {
            mSampledTexture =
                CreateTexture(wgpu::TextureUsage::TextureBinding, kDefaultTextureFormat, 1);
            mSampledTextureView = mSampledTexture.CreateView();

            wgpu::ExternalTextureDescriptor externalTextureDesc =
                CreateDefaultExternalTextureDescriptor();
            externalTextureDesc.plane0 = mSampledTextureView;
            mExternalTexture = device.CreateExternalTexture(&externalTextureDesc);
            mExternalTextureBindingEntry.externalTexture = mExternalTexture;
        }
    }

  protected:
    wgpu::ExternalTextureDescriptor CreateDefaultExternalTextureDescriptor() {
        wgpu::ExternalTextureDescriptor desc;
        desc.yuvToRgbConversionMatrix = mPlaceholderConstantArray.data();
        desc.gamutConversionMatrix = mPlaceholderConstantArray.data();
        desc.srcTransferFunctionParameters = mPlaceholderConstantArray.data();
        desc.dstTransferFunctionParameters = mPlaceholderConstantArray.data();
        desc.cropSize = {kWidth, kHeight};
        desc.apparentSize = {kWidth, kHeight};
        return desc;
    }

    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        return {wgpu::FeatureName::Depth32FloatStencil8};
    }

    void DoTextureSampleTypeTest(bool success,
                                 wgpu::TextureFormat format,
                                 wgpu::TextureSampleType sampleType,
                                 wgpu::TextureAspect aspect = wgpu::TextureAspect::All) {
        wgpu::BindGroupLayout layout =
            utils::MakeBindGroupLayout(device, {{0, wgpu::ShaderStage::Fragment, sampleType}});

        wgpu::TextureDescriptor descriptor;
        descriptor.size = {4, 4, 1};
        descriptor.usage = wgpu::TextureUsage::TextureBinding;
        descriptor.format = format;

        wgpu::TextureViewDescriptor viewDescriptor;
        viewDescriptor.aspect = aspect;
        wgpu::TextureView view = device.CreateTexture(&descriptor).CreateView(&viewDescriptor);

        if (success) {
            utils::MakeBindGroup(device, layout, {{0, view}});
        } else {
            ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, view}}));
        }
    }

    wgpu::Buffer mUBO;
    wgpu::Buffer mSSBO;
    wgpu::Sampler mSampler;
    wgpu::Texture mSampledTexture;
    wgpu::TextureView mSampledTextureView;
    wgpu::ExternalTextureBindingEntry mExternalTextureBindingEntry;

    static constexpr wgpu::TextureFormat kDefaultTextureFormat = wgpu::TextureFormat::RGBA8Unorm;

  private:
    uint32_t kWidth = 16;
    uint32_t kHeight = 16;
    wgpu::ExternalTexture mExternalTexture;
    std::array<float, 12> mPlaceholderConstantArray;
};

// Test the validation of BindGroupDescriptor::nextInChain
TEST_F(BindGroupValidationTest, InvalidChain) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {});

    wgpu::BindGroupDescriptor descriptor;
    descriptor.layout = layout;
    descriptor.entryCount = 0;
    descriptor.entries = nullptr;

    // Control case: check that nextInChain = nullptr is valid
    descriptor.nextInChain = nullptr;
    device.CreateBindGroup(&descriptor);

    // Check that nextInChain != nullptr is an error.
    wgpu::ChainedStruct chainedDescriptor;
    chainedDescriptor.sType = wgpu::SType(0u);
    descriptor.nextInChain = &chainedDescriptor;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
}

// Check constraints on entryCount
TEST_F(BindGroupValidationTest, EntryCountMismatch) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering}});

    // Control case: check that a descriptor with one binding is ok
    utils::MakeBindGroup(device, layout, {{0, mSampler}});

    // Check that entryCount != layout.entryCount fails.
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {}));
}

// Check constraints on BindGroupEntry::binding
TEST_F(BindGroupValidationTest, WrongBindings) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering}});

    // Control case: check that a descriptor with a binding matching the layout's is ok
    utils::MakeBindGroup(device, layout, {{0, mSampler}});

    // Check that binding must be present in the layout
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{1, mSampler}}));
}

// Check that the same binding cannot be set twice
TEST_F(BindGroupValidationTest, BindingSetTwice) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering},
                 {1, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering}});

    // Control case: check that different bindings work
    utils::MakeBindGroup(device, layout, {{0, mSampler}, {1, mSampler}});

    // Check that setting the same binding twice is invalid
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, mSampler}, {0, mSampler}}));
}

// Check that a binding past kMaxBindingsPerBindGroup - 1 results in a validation error. This is a
// regression test for https://issues.chromium.org/492390076
TEST_F(BindGroupValidationTest, BindingPastMaxBindingsPerGroup) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering}});

    // Control case: check that a descriptor with one binding is ok
    utils::MakeBindGroup(device, layout, {{0, mSampler}});

    // Error case: binding is not in the layout.
    ASSERT_DEVICE_ERROR(
        utils::MakeBindGroup(device, layout, {{kMaxBindingsPerBindGroup, mSampler}}));
}

// Check that a sampler binding must contain exactly one sampler
TEST_F(BindGroupValidationTest, SamplerBindingType) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering}});

    wgpu::BindGroupEntry binding;
    binding.binding = 0;
    binding.sampler = nullptr;
    binding.textureView = nullptr;
    binding.buffer = nullptr;
    binding.offset = 0;
    binding.size = 0;

    wgpu::BindGroupDescriptor descriptor;
    descriptor.layout = layout;
    descriptor.entryCount = 1;
    descriptor.entries = &binding;

    // Not setting anything fails
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));

    // Control case: setting just the sampler works
    binding.sampler = mSampler;
    device.CreateBindGroup(&descriptor);

    // Setting the texture view as well is an error
    binding.textureView = mSampledTextureView;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
    binding.textureView = nullptr;

    // Setting the buffer as well is an error
    binding.buffer = mUBO;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
    binding.buffer = nullptr;

    // Setting the external texture view as well is an error
    binding.nextInChain = &mExternalTextureBindingEntry;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
    binding.nextInChain = nullptr;

    // Setting the sampler to an error sampler is an error.
    {
        wgpu::SamplerDescriptor samplerDesc;
        samplerDesc.minFilter = static_cast<wgpu::FilterMode>(0xFFFFFFFF);

        wgpu::Sampler errorSampler;
        ASSERT_DEVICE_ERROR(errorSampler = device.CreateSampler(&samplerDesc));

        binding.sampler = errorSampler;
        ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
        binding.sampler = nullptr;
    }
}

// Check that a texture binding must contain exactly a texture view
TEST_F(BindGroupValidationTest, TextureBindingType) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}});

    wgpu::BindGroupEntry binding;
    binding.binding = 0;
    binding.sampler = nullptr;
    binding.textureView = nullptr;
    binding.buffer = nullptr;
    binding.offset = 0;
    binding.size = 0;

    wgpu::BindGroupDescriptor descriptor;
    descriptor.layout = layout;
    descriptor.entryCount = 1;
    descriptor.entries = &binding;

    // Not setting anything fails
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));

    // Control case: setting just the texture view works
    binding.textureView = mSampledTextureView;
    device.CreateBindGroup(&descriptor);

    // Setting the sampler as well is an error
    binding.sampler = mSampler;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
    binding.sampler = nullptr;

    // Setting the buffer as well is an error
    binding.buffer = mUBO;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
    binding.buffer = nullptr;

    // Setting the external texture view as well is an error
    binding.nextInChain = &mExternalTextureBindingEntry;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
    binding.nextInChain = nullptr;

    // Setting the texture view to an error texture view is an error.
    {
        wgpu::TextureViewDescriptor viewDesc;
        viewDesc.format = kDefaultTextureFormat;
        viewDesc.dimension = wgpu::TextureViewDimension::e2D;
        viewDesc.baseMipLevel = 0;
        viewDesc.mipLevelCount = 0;
        viewDesc.baseArrayLayer = 0;
        viewDesc.arrayLayerCount = 1000;

        wgpu::TextureView errorView;
        ASSERT_DEVICE_ERROR(errorView = mSampledTexture.CreateView(&viewDesc));

        binding.textureView = errorView;
        ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
        binding.textureView = nullptr;
    }
}

// Check that a buffer binding must contain exactly a buffer
TEST_F(BindGroupValidationTest, BufferBindingType) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Uniform}});

    wgpu::BindGroupEntry binding;
    binding.binding = 0;
    binding.sampler = nullptr;
    binding.textureView = nullptr;
    binding.buffer = nullptr;
    binding.offset = 0;
    binding.size = 1024;

    wgpu::BindGroupDescriptor descriptor;
    descriptor.layout = layout;
    descriptor.entryCount = 1;
    descriptor.entries = &binding;

    // Not setting anything fails
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));

    // Control case: setting just the buffer works
    binding.buffer = mUBO;
    device.CreateBindGroup(&descriptor);

    // Setting the texture view as well is an error
    binding.textureView = mSampledTextureView;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
    binding.textureView = nullptr;

    // Setting the sampler as well is an error
    binding.sampler = mSampler;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
    binding.sampler = nullptr;

    // Setting the external texture view as well is an error
    binding.nextInChain = &mExternalTextureBindingEntry;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
    binding.nextInChain = nullptr;

    // Setting the buffer to an error buffer is an error.
    {
        wgpu::BufferDescriptor bufferDesc;
        bufferDesc.size = 1024;
        bufferDesc.usage = static_cast<wgpu::BufferUsage>(0xFFFFFFFF);

        wgpu::Buffer errorBuffer;
        ASSERT_DEVICE_ERROR(errorBuffer = device.CreateBuffer(&bufferDesc));

        binding.buffer = errorBuffer;
        ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
        binding.buffer = nullptr;
    }
}

// Check that an external texture binding must contain either exactly an external texture or a
// texture view.
TEST_F(BindGroupValidationTest, ExternalTextureBindingType) {
    // Create an external texture
    wgpu::Texture texture =
        CreateTexture(wgpu::TextureUsage::TextureBinding, kDefaultTextureFormat, 1);
    wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
    externalDesc.plane0 = texture.CreateView();
    wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(&externalDesc);

    // Create a bind group layout for a single external texture
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});

    wgpu::BindGroupEntry binding;
    binding.binding = 0;
    binding.sampler = nullptr;
    binding.textureView = nullptr;
    binding.buffer = nullptr;
    binding.offset = 0;
    binding.size = 0;

    wgpu::BindGroupDescriptor descriptor;
    descriptor.layout = layout;
    descriptor.entryCount = 1;
    descriptor.entries = &binding;

    wgpu::ExternalTextureBindingEntry externalBindingEntry;
    externalBindingEntry.externalTexture = externalTexture;

    // Not setting anything fails
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));

    for (bool bindTextureViewOnly : {false, true}) {
        binding.textureView = nullptr;
        binding.nextInChain = nullptr;

        if (bindTextureViewOnly) {
            // Control case: setting just the texture view works
            binding.textureView = mSampledTextureView;
            device.CreateBindGroup(&descriptor);
        } else {
            // Control case: setting just the external texture works
            binding.nextInChain = &externalBindingEntry;
            device.CreateBindGroup(&descriptor);
        }

        // Setting the sampler as well is an error
        binding.sampler = mSampler;
        ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
        binding.sampler = nullptr;

        // Setting the buffer as well is an error
        binding.buffer = mUBO;
        ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
        binding.buffer = nullptr;

        // Setting the external texture to an error external texture is an error.
        {
            wgpu::Texture errorTexture =
                CreateTexture(wgpu::TextureUsage::TextureBinding, wgpu::TextureFormat::R8Unorm, 1);
            wgpu::ExternalTextureDescriptor errorExternalDescriptor =
                CreateDefaultExternalTextureDescriptor();
            errorExternalDescriptor.plane0 = errorTexture.CreateView();

            wgpu::ExternalTexture errorExternalTexture;
            ASSERT_DEVICE_ERROR(errorExternalTexture =
                                    device.CreateExternalTexture(&errorExternalDescriptor));

            wgpu::ExternalTextureBindingEntry errorExternalBindingEntry;
            errorExternalBindingEntry.externalTexture = errorExternalTexture;

            binding.nextInChain = &errorExternalBindingEntry;
            ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
            binding.nextInChain = nullptr;
        }

        if (!bindTextureViewOnly) {
            // Setting the texture view as well is an error
            binding.nextInChain = &externalBindingEntry;
            binding.textureView = mSampledTextureView;
            ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
            binding.nextInChain = nullptr;
            binding.textureView = nullptr;

            // Setting an external texture with another external texture chained is an error.
            wgpu::ExternalTexture externalTexture2 = device.CreateExternalTexture(&externalDesc);
            wgpu::ExternalTextureBindingEntry externalBindingEntry2;
            externalBindingEntry2.externalTexture = externalTexture2;

            externalBindingEntry.nextInChain = &externalBindingEntry2;
            ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
            externalBindingEntry.nextInChain = nullptr;
        }
    }
}

// Test that an external texture entry must not have more chained structs
TEST_F(BindGroupValidationTest, ExternalTextureAdditionalChain) {
    // Create an external texture
    wgpu::Texture texture =
        CreateTexture(wgpu::TextureUsage::TextureBinding, kDefaultTextureFormat, 1);
    wgpu::ExternalTextureDescriptor externalDesc = CreateDefaultExternalTextureDescriptor();
    externalDesc.plane0 = texture.CreateView();
    wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(&externalDesc);

    // Create a bind group layout for a single external texture
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});

    // Prepare
    wgpu::ExternalTextureBindingEntry externalBindingEntry;
    externalBindingEntry.externalTexture = externalTexture;

    wgpu::BindGroupEntry binding;
    binding.binding = 0;
    binding.nextInChain = &externalBindingEntry;

    wgpu::BindGroupDescriptor bgDesc;
    bgDesc.layout = layout;
    bgDesc.entryCount = 1;
    bgDesc.entries = &binding;

    // Success case, having only the ExternalTextureBindingEntry is valid.
    device.CreateBindGroup(&bgDesc);

    // Error case, adding more to the chain produces an error.
    wgpu::BufferDescriptor bufferDesc;
    bufferDesc.size = 256;
    bufferDesc.usage = wgpu::BufferUsage::TexelBuffer;
    wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc);

    wgpu::TexelBufferViewDescriptor viewDesc = {};
    viewDesc.format = wgpu::TextureFormat::R32Uint;
    viewDesc.offset = 0;
    viewDesc.size = 4;
    wgpu::TexelBufferView view = buffer.CreateTexelView(&viewDesc);

    wgpu::TexelBufferBindingEntry texelEntry = {};
    texelEntry.texelBufferView = view;

    externalBindingEntry.nextInChain = &texelEntry;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&bgDesc));
}

// Check that a texture binding must have the correct usage
TEST_F(BindGroupValidationTest, TextureUsage) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}});

    // Control case: setting a sampleable texture view works.
    utils::MakeBindGroup(device, layout, {{0, mSampledTextureView}});

    // Make an render attachment texture and try to set it for a SampledTexture binding
    {
        wgpu::Texture outputTexture =
            CreateTexture(wgpu::TextureUsage::RenderAttachment, wgpu::TextureFormat::RGBA8Unorm, 1);
        wgpu::TextureView outputTextureView = outputTexture.CreateView();
        ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, outputTextureView}}));
    }

    // Make a sampled/render attachment texture and a view without sampling and attempt to bind it
    {
        wgpu::Texture outputTexture =
            CreateTexture(wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding,
                          wgpu::TextureFormat::RGBA8Unorm, 1);
        wgpu::TextureViewDescriptor viewDescriptor;
        viewDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
        viewDescriptor.dimension = wgpu::TextureViewDimension::e2D;
        viewDescriptor.baseMipLevel = 0;
        viewDescriptor.mipLevelCount = 1;
        viewDescriptor.baseArrayLayer = 0;
        viewDescriptor.arrayLayerCount = 1;
        viewDescriptor.usage = wgpu::TextureUsage::RenderAttachment;

        wgpu::TextureView outputTextureView = outputTexture.CreateView(&viewDescriptor);
        ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, outputTextureView}}));
    }
}

// Check that a storage texture binding must have the correct usage
TEST_F(BindGroupValidationTest, StorageTextureUsage) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly,
                  wgpu::TextureFormat::RGBA8Uint}});

    wgpu::TextureDescriptor descriptor;
    descriptor.dimension = wgpu::TextureDimension::e2D;
    descriptor.size = {16, 16, 1};
    descriptor.sampleCount = 1;
    descriptor.mipLevelCount = 1;
    descriptor.usage = wgpu::TextureUsage::StorageBinding;
    descriptor.format = wgpu::TextureFormat::RGBA8Uint;

    wgpu::TextureView view = device.CreateTexture(&descriptor).CreateView();

    // Control case: setting a storage texture view works.
    utils::MakeBindGroup(device, layout, {{0, view}});

    // Sampled texture is invalid with storage buffer binding
    descriptor.usage = wgpu::TextureUsage::TextureBinding;
    descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
    view = device.CreateTexture(&descriptor).CreateView();
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, view}}));

    // Multisampled texture is invalid with storage buffer binding
    // Regression case for crbug.com/dawn/614 where this hit an DAWN_ASSERT.
    descriptor.sampleCount = 4;
    descriptor.usage |= wgpu::TextureUsage::RenderAttachment;
    view = device.CreateTexture(&descriptor).CreateView();
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, view}}));
}

// Check that a texture must have the correct sample type
TEST_F(BindGroupValidationTest, TextureSampleType) {
    // Test that RGBA8Unorm is only compatible with float/unfilterable-float.
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureSampleType::Float);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::RGBA8Unorm,
                            wgpu::TextureSampleType::UnfilterableFloat);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureSampleType::Depth);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureSampleType::Uint);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureSampleType::Sint);

    // Test that float32 formats are only compatible with unfilterable-float (without the
    // float32-filterable feature enabled).
    for (const auto f32Format : {wgpu::TextureFormat::R32Float, wgpu::TextureFormat::RG32Float,
                                 wgpu::TextureFormat::RGBA32Float}) {
        DoTextureSampleTypeTest(false, f32Format, wgpu::TextureSampleType::Float);
        DoTextureSampleTypeTest(true, f32Format, wgpu::TextureSampleType::UnfilterableFloat);
        DoTextureSampleTypeTest(false, f32Format, wgpu::TextureSampleType::Depth);
        DoTextureSampleTypeTest(false, f32Format, wgpu::TextureSampleType::Uint);
        DoTextureSampleTypeTest(false, f32Format, wgpu::TextureSampleType::Sint);
    }

    // Test that Depth16Unorm is only compatible with depth/unfilterable-float.
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth16Unorm,
                            wgpu::TextureSampleType::Float);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::Depth16Unorm,
                            wgpu::TextureSampleType::UnfilterableFloat);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::Depth16Unorm,
                            wgpu::TextureSampleType::Depth);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth16Unorm,
                            wgpu::TextureSampleType::Uint);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth16Unorm,
                            wgpu::TextureSampleType::Sint);

    // Test that Depth24Plus is only compatible with depth/unfilterable-float.
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth24Plus,
                            wgpu::TextureSampleType::Float);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::Depth24Plus,
                            wgpu::TextureSampleType::UnfilterableFloat);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::Depth24Plus, wgpu::TextureSampleType::Depth);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth24Plus, wgpu::TextureSampleType::Uint);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth24Plus, wgpu::TextureSampleType::Sint);

    // Test that Depth24PlusStencil8 with depth aspect is only compatible with
    // depth/unfilterable-float.
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth24PlusStencil8,
                            wgpu::TextureSampleType::Float, wgpu::TextureAspect::DepthOnly);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::Depth24PlusStencil8,
                            wgpu::TextureSampleType::UnfilterableFloat,
                            wgpu::TextureAspect::DepthOnly);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::Depth24PlusStencil8,
                            wgpu::TextureSampleType::Depth, wgpu::TextureAspect::DepthOnly);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth24PlusStencil8,
                            wgpu::TextureSampleType::Uint, wgpu::TextureAspect::DepthOnly);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth24PlusStencil8,
                            wgpu::TextureSampleType::Sint, wgpu::TextureAspect::DepthOnly);

    // Test that Depth24PlusStencil8 with stencil aspect is only compatible with uint.
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth24PlusStencil8,
                            wgpu::TextureSampleType::Float, wgpu::TextureAspect::StencilOnly);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth24PlusStencil8,
                            wgpu::TextureSampleType::UnfilterableFloat,
                            wgpu::TextureAspect::StencilOnly);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth24PlusStencil8,
                            wgpu::TextureSampleType::Depth, wgpu::TextureAspect::StencilOnly);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::Depth24PlusStencil8,
                            wgpu::TextureSampleType::Uint, wgpu::TextureAspect::StencilOnly);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth24PlusStencil8,
                            wgpu::TextureSampleType::Sint, wgpu::TextureAspect::StencilOnly);

    // Test that Depth32Float is only compatible with depth/unfilterable-float.
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth32Float,
                            wgpu::TextureSampleType::Float);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::Depth32Float,
                            wgpu::TextureSampleType::UnfilterableFloat);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::Depth32Float,
                            wgpu::TextureSampleType::Depth);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth32Float,
                            wgpu::TextureSampleType::Uint);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth32Float,
                            wgpu::TextureSampleType::Sint);

    // Test that Depth32FloatStencil8 with depth aspect is only compatible with
    // depth/unfilterable-float.
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth32FloatStencil8,
                            wgpu::TextureSampleType::Float, wgpu::TextureAspect::DepthOnly);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::Depth32FloatStencil8,
                            wgpu::TextureSampleType::UnfilterableFloat,
                            wgpu::TextureAspect::DepthOnly);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::Depth32FloatStencil8,
                            wgpu::TextureSampleType::Depth, wgpu::TextureAspect::DepthOnly);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth32FloatStencil8,
                            wgpu::TextureSampleType::Uint, wgpu::TextureAspect::DepthOnly);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth32FloatStencil8,
                            wgpu::TextureSampleType::Sint, wgpu::TextureAspect::DepthOnly);

    // Test that Depth32FloatStencil8 with stencil aspect is only compatible with uint.
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth32FloatStencil8,
                            wgpu::TextureSampleType::Float, wgpu::TextureAspect::StencilOnly);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth32FloatStencil8,
                            wgpu::TextureSampleType::UnfilterableFloat,
                            wgpu::TextureAspect::StencilOnly);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth32FloatStencil8,
                            wgpu::TextureSampleType::Depth, wgpu::TextureAspect::StencilOnly);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::Depth32FloatStencil8,
                            wgpu::TextureSampleType::Uint, wgpu::TextureAspect::StencilOnly);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::Depth32FloatStencil8,
                            wgpu::TextureSampleType::Sint, wgpu::TextureAspect::StencilOnly);

    // Test that RG8Uint is only compatible with uint.
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::RG8Uint, wgpu::TextureSampleType::Float);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::RG8Uint,
                            wgpu::TextureSampleType::UnfilterableFloat);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::RG8Uint, wgpu::TextureSampleType::Depth);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::RG8Uint, wgpu::TextureSampleType::Uint);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::RG8Uint, wgpu::TextureSampleType::Sint);

    // Test that R16Sint is only compatible with sint.
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::R16Sint, wgpu::TextureSampleType::Float);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::R16Sint,
                            wgpu::TextureSampleType::UnfilterableFloat);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::R16Sint, wgpu::TextureSampleType::Depth);
    DoTextureSampleTypeTest(false, wgpu::TextureFormat::R16Sint, wgpu::TextureSampleType::Uint);
    DoTextureSampleTypeTest(true, wgpu::TextureFormat::R16Sint, wgpu::TextureSampleType::Sint);
}

class BindGroupValidationTest_Float32Filterable : public BindGroupValidationTest {
  protected:
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        return {wgpu::FeatureName::Float32Filterable};
    }
};

// Checks that float32 texture formats have the correct sample type when float32-filterable feature
// enabled.
TEST_F(BindGroupValidationTest_Float32Filterable, TextureSampleType) {
    // With the feature enabled, float32 formats should be compatible with both float and
    // unfilterable-float.
    for (const auto f32Format : {wgpu::TextureFormat::R32Float, wgpu::TextureFormat::RG32Float,
                                 wgpu::TextureFormat::RGBA32Float}) {
        DoTextureSampleTypeTest(true, f32Format, wgpu::TextureSampleType::Float);
        DoTextureSampleTypeTest(true, f32Format, wgpu::TextureSampleType::UnfilterableFloat);
        DoTextureSampleTypeTest(false, f32Format, wgpu::TextureSampleType::Depth);
        DoTextureSampleTypeTest(false, f32Format, wgpu::TextureSampleType::Uint);
        DoTextureSampleTypeTest(false, f32Format, wgpu::TextureSampleType::Sint);
    }
}

// Test which depth-stencil formats are allowed to be sampled (all).
TEST_F(BindGroupValidationTest, SamplingDepthStencilTexture) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Depth}});

    wgpu::TextureDescriptor desc;
    desc.size = {1, 1, 1};
    desc.usage = wgpu::TextureUsage::TextureBinding;

    // Depth32Float is allowed to be sampled.
    {
        desc.format = wgpu::TextureFormat::Depth32Float;
        wgpu::Texture texture = device.CreateTexture(&desc);

        utils::MakeBindGroup(device, layout, {{0, texture.CreateView()}});
    }

    // Depth24Plus is allowed to be sampled.
    {
        desc.format = wgpu::TextureFormat::Depth24Plus;
        wgpu::Texture texture = device.CreateTexture(&desc);

        utils::MakeBindGroup(device, layout, {{0, texture.CreateView()}});
    }

    // Depth24PlusStencil8 is allowed to be sampled, if the depth or stencil aspect is selected.
    {
        desc.format = wgpu::TextureFormat::Depth24PlusStencil8;
        wgpu::Texture texture = device.CreateTexture(&desc);
        wgpu::TextureViewDescriptor viewDesc = {};

        viewDesc.aspect = wgpu::TextureAspect::DepthOnly;
        utils::MakeBindGroup(device, layout, {{0, texture.CreateView(&viewDesc)}});

        layout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Uint}});

        viewDesc.aspect = wgpu::TextureAspect::StencilOnly;
        utils::MakeBindGroup(device, layout, {{0, texture.CreateView(&viewDesc)}});
    }
}

// Check that a texture must have the correct dimension
TEST_F(BindGroupValidationTest, TextureDimension) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}});

    // Control case: setting a 2D texture view works.
    utils::MakeBindGroup(device, layout, {{0, mSampledTextureView}});

    // Make a 2DArray texture and try to set it to a 2D binding.
    wgpu::Texture arrayTexture =
        CreateTexture(wgpu::TextureUsage::TextureBinding, wgpu::TextureFormat::RGBA8Uint, 2);
    wgpu::TextureView arrayTextureView = arrayTexture.CreateView();

    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, arrayTextureView}}));
}

// Check that a storage texture binding must have a texture view with a mipLevelCount of 1
TEST_F(BindGroupValidationTest, StorageTextureViewLayerCount) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly,
                  wgpu::TextureFormat::RGBA8Uint}});

    wgpu::TextureDescriptor descriptor;
    descriptor.dimension = wgpu::TextureDimension::e2D;
    descriptor.size = {16, 16, 1};
    descriptor.sampleCount = 1;
    descriptor.mipLevelCount = 1;
    descriptor.usage = wgpu::TextureUsage::StorageBinding;
    descriptor.format = wgpu::TextureFormat::RGBA8Uint;

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

    descriptor.mipLevelCount = 3;
    wgpu::Texture textureMip = device.CreateTexture(&descriptor);

    // Control case: setting a storage texture view on a texture with only one mip level works
    {
        wgpu::TextureView view = textureNoMip.CreateView();
        utils::MakeBindGroup(device, layout, {{0, view}});
    }

    // Setting a storage texture view with mipLevelCount=1 on a texture of multiple mip levels is
    // valid
    {
        wgpu::TextureViewDescriptor viewDesc = {};
        viewDesc.aspect = wgpu::TextureAspect::All;
        viewDesc.dimension = wgpu::TextureViewDimension::e2D;
        viewDesc.format = wgpu::TextureFormat::RGBA8Uint;
        viewDesc.baseMipLevel = 0;
        viewDesc.mipLevelCount = 1;

        // Setting texture view with lod 0 is valid
        wgpu::TextureView view = textureMip.CreateView(&viewDesc);
        utils::MakeBindGroup(device, layout, {{0, view}});

        // Setting texture view with other lod is also valid
        viewDesc.baseMipLevel = 2;
        view = textureMip.CreateView(&viewDesc);
        utils::MakeBindGroup(device, layout, {{0, view}});
    }

    // Texture view with mipLevelCount > 1 is invalid
    {
        wgpu::TextureViewDescriptor viewDesc = {};
        viewDesc.aspect = wgpu::TextureAspect::All;
        viewDesc.dimension = wgpu::TextureViewDimension::e2D;
        viewDesc.format = wgpu::TextureFormat::RGBA8Uint;
        viewDesc.baseMipLevel = 0;
        viewDesc.mipLevelCount = 2;

        // Setting texture view with lod 0 and 1 is invalid
        wgpu::TextureView view = textureMip.CreateView(&viewDesc);
        ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, view}}));

        // Setting texture view with lod 1 and 2 is invalid
        viewDesc.baseMipLevel = 1;
        view = textureMip.CreateView(&viewDesc);
        ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, view}}));
    }
}

// Check that a UBO must have the correct usage
TEST_F(BindGroupValidationTest, BufferUsageUBO) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Uniform}});

    // Control case: using a buffer with the uniform usage works
    utils::MakeBindGroup(device, layout, {{0, mUBO, 0, 256}});

    // Using a buffer without the uniform usage fails
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, mSSBO, 0, 256}}));
}

// Check that a SSBO must have the correct usage
TEST_F(BindGroupValidationTest, BufferUsageSSBO) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage}});

    // Control case: using a buffer with the storage usage works
    utils::MakeBindGroup(device, layout, {{0, mSSBO, 0, 256}});

    // Using a buffer without the storage usage fails
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, mUBO, 0, 256}}));
}

// Check that a readonly SSBO must have the correct usage
TEST_F(BindGroupValidationTest, BufferUsageReadonlySSBO) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::ReadOnlyStorage}});

    // Control case: using a buffer with the storage usage works
    utils::MakeBindGroup(device, layout, {{0, mSSBO, 0, 256}});

    // Using a buffer without the storage usage fails
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, mUBO, 0, 256}}));
}

// Check that a resolve buffer with internal storge usage cannot be used as SSBO
TEST_F(BindGroupValidationTest, BufferUsageQueryResolve) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage}});

    // Control case: using a buffer with the storage usage works
    utils::MakeBindGroup(device, layout, {{0, mSSBO, 0, 256}});

    // Using a resolve buffer with the internal storage usage fails
    wgpu::BufferDescriptor descriptor;
    descriptor.size = 1024;
    descriptor.usage = wgpu::BufferUsage::QueryResolve;
    wgpu::Buffer buffer = device.CreateBuffer(&descriptor);
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, buffer, 0, 256}}));
}

// Tests constraints on the buffer offset for bind groups.
TEST_F(BindGroupValidationTest, BufferOffsetAlignment) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform},
                });

    // Check that offset 0 is valid
    utils::MakeBindGroup(device, layout, {{0, mUBO, 0, 512}});

    // Check that offset 256 (aligned) is valid
    utils::MakeBindGroup(device, layout, {{0, mUBO, 256, 256}});

    // Check cases where unaligned buffer offset is invalid
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, mUBO, 1, 256}}));
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, mUBO, 128, 256}}));
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, mUBO, 255, 256}}));
}

// Tests constraints on the texture for MultisampledTexture bindings
TEST_F(BindGroupValidationTest, MultisampledTexture) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::UnfilterableFloat,
                  wgpu::TextureViewDimension::e2D, true}});

    wgpu::BindGroupEntry binding;
    binding.binding = 0;
    binding.sampler = nullptr;
    binding.textureView = nullptr;
    binding.buffer = nullptr;
    binding.offset = 0;
    binding.size = 0;

    wgpu::BindGroupDescriptor descriptor;
    descriptor.layout = layout;
    descriptor.entryCount = 1;
    descriptor.entries = &binding;

    // Not setting anything fails
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));

    // Control case: setting a multisampled 2D texture works
    wgpu::TextureDescriptor textureDesc;
    textureDesc.sampleCount = 4;
    textureDesc.usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment;
    textureDesc.dimension = wgpu::TextureDimension::e2D;
    textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    textureDesc.size = {1, 1, 1};
    wgpu::Texture msTexture = device.CreateTexture(&textureDesc);

    binding.textureView = msTexture.CreateView();
    device.CreateBindGroup(&descriptor);
    binding.textureView = nullptr;

    // Error case: setting a single sampled 2D texture is an error.
    binding.textureView = mSampledTextureView;
    ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
    binding.textureView = nullptr;
}

// Tests dafault offset and size of bind group entry work as expected
TEST_F(BindGroupValidationTest, BufferBindingDefaultOffsetAndSize) {
    wgpu::BufferDescriptor bufferDesc;
    bufferDesc.size = 768;  // 768 = 256 x 3
    bufferDesc.usage = wgpu::BufferUsage::Uniform;
    wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc);

    bufferDesc.size = 260;
    wgpu::Buffer bufferSized260 = device.CreateBuffer(&bufferDesc);
    bufferDesc.size = 256;
    wgpu::Buffer bufferSized256 = device.CreateBuffer(&bufferDesc);

    // Create a layout requiring minimium buffer binding size of 260
    wgpu::BufferBindingLayout bufferBindingLayout;
    bufferBindingLayout.type = wgpu::BufferBindingType::Uniform;
    bufferBindingLayout.hasDynamicOffset = false;
    bufferBindingLayout.minBindingSize = 260;

    wgpu::BindGroupLayoutEntry bindGroupLayoutEntry;
    bindGroupLayoutEntry.binding = 0;
    bindGroupLayoutEntry.visibility = wgpu::ShaderStage::Vertex;
    bindGroupLayoutEntry.buffer = bufferBindingLayout;

    wgpu::BindGroupLayoutDescriptor bindGroupLayoutDescriptor;
    bindGroupLayoutDescriptor.entryCount = 1;
    bindGroupLayoutDescriptor.entries = &bindGroupLayoutEntry;
    wgpu::BindGroupLayout layout = device.CreateBindGroupLayout(&bindGroupLayoutDescriptor);

    // Default offset should be 0
    {
        wgpu::BindGroupEntry binding;
        binding.binding = 0;
        binding.sampler = nullptr;
        binding.textureView = nullptr;
        binding.buffer = buffer;
        // binding.offset omitted.
        binding.size = 768;

        wgpu::BindGroupDescriptor bgDesc;
        bgDesc.layout = layout;
        bgDesc.entryCount = 1;
        bgDesc.entries = &binding;

        // Offset 0 and size 768 should work.
        device.CreateBindGroup(&bgDesc);

        // Offset 0 and size 260 should work.
        binding.size = 260;
        device.CreateBindGroup(&bgDesc);

        // Offset 0 and size 256 go smaller than minBindingSize and validation error.
        binding.size = 256;
        ASSERT_DEVICE_ERROR(device.CreateBindGroup(&bgDesc));

        // Offset 0 and size 769 should be OOB and validation error.
        binding.size = 769;
        ASSERT_DEVICE_ERROR(device.CreateBindGroup(&bgDesc));
    }

    // Default size should be whole size - offset
    {
        wgpu::BindGroupEntry binding;
        binding.binding = 0;
        binding.sampler = nullptr;
        binding.textureView = nullptr;
        binding.buffer = buffer;
        binding.offset = 0;
        // binding.size omitted

        wgpu::BindGroupDescriptor bgDesc;
        bgDesc.layout = layout;
        bgDesc.entryCount = 1;
        bgDesc.entries = &binding;

        // Offset 0 and default size = 768 should work.
        device.CreateBindGroup(&bgDesc);

        // Offset 256 and default size = 512 should work.
        binding.offset = 256;
        device.CreateBindGroup(&bgDesc);

        // Offset 512 and default size = 256 go smaller than minBindingSize and validation error.
        binding.offset = 512;
        ASSERT_DEVICE_ERROR(device.CreateBindGroup(&bgDesc));

        // Offset 1024 should be OOB and validation error.
        binding.offset = 1024;
        ASSERT_DEVICE_ERROR(device.CreateBindGroup(&bgDesc));
    }

    // Both offset and size are default, should be offset = 0 and size = whole size
    {
        wgpu::BindGroupEntry binding;
        binding.binding = 0;
        binding.sampler = nullptr;
        binding.textureView = nullptr;
        binding.buffer = buffer;
        // binding.offset omitted
        // binding.size omitted

        wgpu::BindGroupDescriptor bgDesc;
        bgDesc.layout = layout;
        bgDesc.entryCount = 1;
        bgDesc.entries = &binding;

        // Offset 0 and default size = 768 should work.
        device.CreateBindGroup(&bgDesc);

        // Use a buffer with size 260, offset 0 and default size = 260 should work.
        binding.buffer = bufferSized260;
        device.CreateBindGroup(&bgDesc);

        // Use a buffer with size 256, offset 0 and default size = 256 go smaller than
        // minBindingSize and validation error.
        binding.buffer = bufferSized256;
        ASSERT_DEVICE_ERROR(device.CreateBindGroup(&bgDesc));
    }
}

// Tests constraints to be sure the buffer binding fits in the buffer
TEST_F(BindGroupValidationTest, BufferBindingOOB) {
    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform},
                });

    wgpu::BufferDescriptor descriptor;
    descriptor.size = 1024;
    descriptor.usage = wgpu::BufferUsage::Uniform;
    wgpu::Buffer buffer = device.CreateBuffer(&descriptor);

    // Success case, touching the start of the buffer works
    utils::MakeBindGroup(device, layout, {{0, buffer, 0, 256}});

    // Success case, touching the end of the buffer works
    utils::MakeBindGroup(device, layout, {{0, buffer, 3 * 256, 256}});

    // Error case, zero size is invalid.
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, buffer, 1024, 0}}));

    // Success case, touching the full buffer works
    utils::MakeBindGroup(device, layout, {{0, buffer, 0, 1024}});
    utils::MakeBindGroup(device, layout, {{0, buffer, 0, wgpu::kWholeSize}});

    // Success case, whole size causes the rest of the buffer to be used but not beyond.
    utils::MakeBindGroup(device, layout, {{0, buffer, 256, wgpu::kWholeSize}});

    // Error case, offset is OOB
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, buffer, 256 * 5, 0}}));

    // Error case, size is OOB
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, buffer, 0, 256 * 5}}));

    // Error case, offset+size is OOB
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, buffer, 1024, 256}}));

    // Error case, offset+size overflows to be 0
    ASSERT_DEVICE_ERROR(
        utils::MakeBindGroup(device, layout, {{0, buffer, 256, uint32_t(0) - uint32_t(256)}}));
}

// Tests constraints to be sure the uniform buffer binding isn't too large
TEST_F(BindGroupValidationTest, MaxUniformBufferBindingSize) {
    const auto& supportedLimits = GetSupportedLimits();

    wgpu::BufferDescriptor descriptor;
    descriptor.size = 2 * supportedLimits.maxUniformBufferBindingSize;
    descriptor.usage = wgpu::BufferUsage::Uniform | wgpu::BufferUsage::Storage;
    wgpu::Buffer buffer = device.CreateBuffer(&descriptor);

    wgpu::BindGroupLayout uniformLayout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform}});

    // Success case, this is exactly the limit
    utils::MakeBindGroup(device, uniformLayout,
                         {{0, buffer, 0, supportedLimits.maxUniformBufferBindingSize}});

    wgpu::BindGroupLayout doubleUniformLayout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform},
                 {1, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform}});

    // Success case, individual bindings don't exceed the limit
    utils::MakeBindGroup(device, doubleUniformLayout,
                         {{0, buffer, 0, supportedLimits.maxUniformBufferBindingSize},
                          {1, buffer, supportedLimits.maxUniformBufferBindingSize,
                           supportedLimits.maxUniformBufferBindingSize}});

    // Error case, this is above the limit
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(
        device, uniformLayout, {{0, buffer, 0, supportedLimits.maxUniformBufferBindingSize + 1}}));

    // Making sure the constraint doesn't apply to storage buffers
    wgpu::BindGroupLayout readonlyStorageLayout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::ReadOnlyStorage}});
    wgpu::BindGroupLayout storageLayout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage}});

    // Success case, storage buffer can still be created.
    utils::MakeBindGroup(device, readonlyStorageLayout,
                         {{0, buffer, 0, 2 * supportedLimits.maxUniformBufferBindingSize}});
    utils::MakeBindGroup(device, storageLayout,
                         {{0, buffer, 0, 2 * supportedLimits.maxUniformBufferBindingSize}});
}

// Tests constraints to be sure the storage buffer binding isn't too large
TEST_F(BindGroupValidationTest, MaxStorageBufferBindingSize) {
    const auto& supportedLimits = GetSupportedLimits();

    wgpu::BufferDescriptor descriptor;
    descriptor.size = 2 * supportedLimits.maxStorageBufferBindingSize;
    descriptor.usage = wgpu::BufferUsage::Storage;
    wgpu::Buffer buffer = device.CreateBuffer(&descriptor);

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

    // Success case, this is exactly the limit
    utils::MakeBindGroup(device, uniformLayout,
                         {{0, buffer, 0, supportedLimits.maxStorageBufferBindingSize}});

    // Success case, this is one less than the limit (check it is not an alignment constraint)
    utils::MakeBindGroup(device, uniformLayout,
                         {{0, buffer, 0, supportedLimits.maxStorageBufferBindingSize - 4}});

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

    // Success case, individual bindings don't exceed the limit
    utils::MakeBindGroup(device, doubleUniformLayout,
                         {{0, buffer, 0, supportedLimits.maxStorageBufferBindingSize},
                          {1, buffer, supportedLimits.maxStorageBufferBindingSize,
                           supportedLimits.maxStorageBufferBindingSize}});

    // Error case, this is above the limit
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(
        device, uniformLayout, {{0, buffer, 0, supportedLimits.maxStorageBufferBindingSize + 4}}));
}

// Test constraints to be sure the effective storage and read-only storage buffer binding size must
// be a multiple of 4.
TEST_F(BindGroupValidationTest, EffectiveStorageBufferBindingSize) {
    wgpu::BufferDescriptor descriptor;
    descriptor.size = 262;
    descriptor.usage = wgpu::BufferUsage::Storage;
    wgpu::Buffer buffer = device.CreateBuffer(&descriptor);

    constexpr std::array<wgpu::BufferBindingType, 2> kStorageBufferBindingTypes = {
        {wgpu::BufferBindingType::Storage, wgpu::BufferBindingType::ReadOnlyStorage}};

    for (wgpu::BufferBindingType bufferBindingType : kStorageBufferBindingTypes) {
        wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Compute, bufferBindingType}});

        // Error case, as the effective buffer binding size (262) isn't a multiple of 4.
        {
            constexpr uint32_t kOffset = 0;
            ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, buffer, kOffset}}));
        }

        // Error case, as the effective buffer binding size (6) isn't a multiple of 4.
        {
            constexpr uint32_t kOffset = 256;
            ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, buffer, kOffset}}));
        }

        // Error case, as the effective buffer binding size (2) isn't a multiple of 4.
        {
            constexpr uint32_t kOffset = 0;
            constexpr uint32_t kBindingSize = 2;
            ASSERT_DEVICE_ERROR(
                utils::MakeBindGroup(device, layout, {{0, buffer, kOffset, kBindingSize}}));
        }

        // Success case, as the effective buffer binding size (4) is a multiple of 4.
        {
            constexpr uint32_t kOffset = 0;
            constexpr uint32_t kBindingSize = 4;
            utils::MakeBindGroup(device, layout, {{0, buffer, kOffset, kBindingSize}});
        }
    }
}

// Test making that all the bindings for an BGL with bindingArraySize must be specified.
TEST_F(BindGroupValidationTest, AllArrayElementsMustBeSpecified) {
    // Create the BGL with three entries for the array.
    wgpu::BindGroupLayoutEntry entry;
    entry.binding = 1;
    entry.visibility = wgpu::ShaderStage::Fragment;
    entry.bindingArraySize = 3;
    entry.texture.sampleType = wgpu::TextureSampleType::Float;

    wgpu::BindGroupLayoutDescriptor bglDesc;
    bglDesc.entryCount = 1;
    bglDesc.entries = &entry;
    wgpu::BindGroupLayout bgl = device.CreateBindGroupLayout(&bglDesc);

    // The texture used for the test.
    wgpu::TextureDescriptor tDesc;
    tDesc.size = {1, 1};
    tDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    tDesc.usage = wgpu::TextureUsage::TextureBinding;
    wgpu::Texture t = device.CreateTexture(&tDesc);

    // Success case, making a BindGroup with all three entries
    utils::MakeBindGroup(device, bgl,
                         {
                             {1, t.CreateView()},
                             {2, t.CreateView()},
                             {3, t.CreateView()},
                         });

    // Error case, one element is missing
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, bgl,
                                             {
                                                 {1, t.CreateView()},
                                                 {3, t.CreateView()},
                                             }));
}

// Test what happens when the layout is an error.
TEST_F(BindGroupValidationTest, ErrorLayout) {
    wgpu::BindGroupLayout goodLayout = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform},
                });

    wgpu::BindGroupLayout errorLayout;
    ASSERT_DEVICE_ERROR(
        errorLayout = utils::MakeBindGroupLayout(
            device, {
                        {0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform},
                        {0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform},
                    }));

    // Control case, creating with the good layout works
    utils::MakeBindGroup(device, goodLayout, {{0, mUBO, 0, 256}});

    // Creating with an error layout fails
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, errorLayout, {{0, mUBO, 0, 256}}));
}

class BindGroupLayoutValidationTest : public ValidationTest {
  public:
    wgpu::BindGroupLayout MakeBindGroupLayout(wgpu::BindGroupLayoutEntry* binding, uint32_t count) {
        wgpu::BindGroupLayoutDescriptor descriptor;
        descriptor.entryCount = count;
        descriptor.entries = binding;
        return device.CreateBindGroupLayout(&descriptor);
    }

    void TestCreateBindGroupLayout(wgpu::BindGroupLayoutEntry* binding,
                                   uint32_t count,
                                   bool expected) {
        wgpu::BindGroupLayoutDescriptor descriptor;

        descriptor.entryCount = count;
        descriptor.entries = binding;

        if (!expected) {
            ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&descriptor));
        } else {
            device.CreateBindGroupLayout(&descriptor);
        }
    }

    void TestCreatePipelineLayout(wgpu::BindGroupLayout* bgl, uint32_t count, bool expected) {
        wgpu::PipelineLayoutDescriptor descriptor;

        descriptor.bindGroupLayoutCount = count;
        descriptor.bindGroupLayouts = bgl;

        if (!expected) {
            ASSERT_DEVICE_ERROR(device.CreatePipelineLayout(&descriptor));
        } else {
            device.CreatePipelineLayout(&descriptor);
        }
    }
};

// Tests setting storage buffer and readonly storage buffer bindings in vertex and fragment shader.
TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutStorageBindingsInVertexShader) {
    // Checks that storage buffer binding is not supported in vertex shader.
    ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Storage}}));

    utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::ReadOnlyStorage}});

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

    utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::ReadOnlyStorage}});
}

// Tests setting that bind group layout bindings numbers may be very large.
TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutEntryMax) {
    // Check that up to kMaxBindingsPerBindGroup-1 is valid.
    utils::MakeBindGroupLayout(device, {{kMaxBindingsPerBindGroup - 1, wgpu::ShaderStage::Vertex,
                                         wgpu::BufferBindingType::Uniform}});

    // But after is an error.
    ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
        device,
        {{kMaxBindingsPerBindGroup, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform}}));
}

// This test verifies that the BindGroupLayout bindings are correctly validated, even if the
// binding ids are out-of-order.
TEST_F(BindGroupLayoutValidationTest, BindGroupEntry) {
    utils::MakeBindGroupLayout(device,
                               {
                                   {1, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform},
                                   {0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform},
                               });
}

// Check that dynamic = true is only allowed buffer bindings.
TEST_F(BindGroupLayoutValidationTest, DynamicAndTypeCompatibility) {
    utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Uniform, true},
                });

    utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage, true},
                });

    utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::ReadOnlyStorage, true},
                });
}

// Test that it is invalid to create a BGL with more than one binding type set.
TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutEntryTooManySet) {
    wgpu::BindGroupLayoutEntry entry = {};
    entry.binding = 0;
    entry.visibility = wgpu::ShaderStage::Fragment;
    entry.buffer.type = wgpu::BufferBindingType::Uniform;
    entry.sampler.type = wgpu::SamplerBindingType::Filtering;

    wgpu::BindGroupLayoutDescriptor descriptor;
    descriptor.entryCount = 1;
    descriptor.entries = &entry;
    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&descriptor),
                        testing::HasSubstr("had more than one of"));
}

// Test that it is invalid to create a BGL with none one of buffer,
// sampler, texture, storageTexture, or externalTexture set.
TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutEntryNoneSet) {
    wgpu::BindGroupLayoutEntry entry = {};

    wgpu::BindGroupLayoutDescriptor descriptor;
    descriptor.entryCount = 1;
    descriptor.entries = &entry;
    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&descriptor),
                        testing::HasSubstr("had none of"));
}

// This test verifies that visibility of bindings in BindGroupLayout can be none
TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutVisibilityNone) {
    utils::MakeBindGroupLayout(device,
                               {
                                   {0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform},
                               });

    wgpu::BindGroupLayoutEntry entry;
    entry.binding = 0;
    entry.visibility = wgpu::ShaderStage::None;
    entry.buffer.type = wgpu::BufferBindingType::Uniform;
    wgpu::BindGroupLayoutDescriptor descriptor;
    descriptor.entryCount = 1;
    descriptor.entries = &entry;
    device.CreateBindGroupLayout(&descriptor);
}

// This test verifies that binding with none visibility in bind group layout can be supported in
// bind group
TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutVisibilityNoneExpectsBindGroupEntry) {
    wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform},
                    {1, wgpu::ShaderStage::None, wgpu::BufferBindingType::Uniform},
                });
    wgpu::BufferDescriptor descriptor;
    descriptor.size = 4;
    descriptor.usage = wgpu::BufferUsage::Uniform;
    wgpu::Buffer buffer = device.CreateBuffer(&descriptor);

    utils::MakeBindGroup(device, bgl, {{0, buffer}, {1, buffer}});

    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, bgl, {{0, buffer}}));
}

#define BGLEntryType(...) \
    utils::BindingLayoutEntryInitializationHelper(0, wgpu::ShaderStage::Compute, __VA_ARGS__)

TEST_F(BindGroupLayoutValidationTest, PerStageLimits) {
    struct TestInfo {
        uint32_t maxCount;
        wgpu::BindGroupLayoutEntry entry;
        wgpu::BindGroupLayoutEntry otherEntry;
    };

    const auto& limits = GetSupportedLimits();

    std::array<TestInfo, 7> kTestInfos = {
        TestInfo{limits.maxSampledTexturesPerShaderStage,
                 BGLEntryType(wgpu::TextureSampleType::Float),
                 BGLEntryType(wgpu::BufferBindingType::Uniform)},
        TestInfo{limits.maxSamplersPerShaderStage,
                 BGLEntryType(wgpu::SamplerBindingType::Filtering),
                 BGLEntryType(wgpu::BufferBindingType::Uniform)},
        TestInfo{limits.maxSamplersPerShaderStage,
                 BGLEntryType(wgpu::SamplerBindingType::Comparison),
                 BGLEntryType(wgpu::BufferBindingType::Uniform)},
        TestInfo{limits.maxStorageBuffersPerShaderStage,
                 BGLEntryType(wgpu::BufferBindingType::Storage),
                 BGLEntryType(wgpu::BufferBindingType::Uniform)},
        TestInfo{
            limits.maxStorageTexturesPerShaderStage,
            BGLEntryType(wgpu::StorageTextureAccess::WriteOnly, wgpu::TextureFormat::RGBA8Unorm),
            BGLEntryType(wgpu::BufferBindingType::Uniform)},
        TestInfo{limits.maxUniformBuffersPerShaderStage,
                 BGLEntryType(wgpu::BufferBindingType::Uniform),
                 BGLEntryType(wgpu::TextureSampleType::Float)},
        // External textures use multiple bindings (3 sampled textures, 1 sampler, 1 uniform buffer)
        // that count towards the per stage binding limits. The number of external textures are
        // currently restricted by the maximum number of sampled textures.
        TestInfo{limits.maxSampledTexturesPerShaderStage / kSampledTexturesPerExternalTexture,
                 BGLEntryType(&utils::kExternalTextureBindingLayout),
                 BGLEntryType(wgpu::BufferBindingType::Uniform)}};

    for (TestInfo info : kTestInfos) {
        wgpu::BindGroupLayout bgl[2];
        std::vector<utils::BindingLayoutEntryInitializationHelper> maxBindings;

        for (uint32_t i = 0; i < info.maxCount; ++i) {
            wgpu::BindGroupLayoutEntry entry = info.entry;
            entry.binding = i;
            maxBindings.push_back(entry);
        }

        // Creating with the maxes works.
        bgl[0] = MakeBindGroupLayout(maxBindings.data(), maxBindings.size());

        // Adding an extra binding of a different type works.
        {
            std::vector<utils::BindingLayoutEntryInitializationHelper> bindings = maxBindings;
            wgpu::BindGroupLayoutEntry entry = info.otherEntry;
            entry.binding = info.maxCount;
            bindings.push_back(entry);
            MakeBindGroupLayout(bindings.data(), bindings.size());
        }

        // Adding an extra binding of the maxed type in a different stage works
        {
            std::vector<utils::BindingLayoutEntryInitializationHelper> bindings = maxBindings;
            wgpu::BindGroupLayoutEntry entry = info.entry;
            entry.binding = info.maxCount;
            entry.visibility = wgpu::ShaderStage::Fragment;
            bindings.push_back(entry);
            MakeBindGroupLayout(bindings.data(), bindings.size());
        }

        // Adding an extra binding of the maxed type and stage exceeds the per stage limit.
        {
            std::vector<utils::BindingLayoutEntryInitializationHelper> bindings = maxBindings;
            wgpu::BindGroupLayoutEntry entry = info.entry;
            entry.binding = info.maxCount;
            bindings.push_back(entry);
            ASSERT_DEVICE_ERROR(MakeBindGroupLayout(bindings.data(), bindings.size()));
        }

        // Creating a pipeline layout from the valid BGL works.
        TestCreatePipelineLayout(bgl, 1, true);

        // Adding an extra binding of a different type in a different BGL works
        bgl[1] = utils::MakeBindGroupLayout(device, {info.otherEntry});
        TestCreatePipelineLayout(bgl, 2, true);

        {
            // Adding an extra binding of the maxed type in a different stage works
            wgpu::BindGroupLayoutEntry entry = info.entry;
            entry.visibility = wgpu::ShaderStage::Fragment;
            bgl[1] = utils::MakeBindGroupLayout(device, {entry});
            TestCreatePipelineLayout(bgl, 2, true);
        }

        // Adding an extra binding of the maxed type in a different BGL exceeds the per stage limit.
        bgl[1] = utils::MakeBindGroupLayout(device, {info.entry});
        TestCreatePipelineLayout(bgl, 2, false);
    }
}

// External textures require multiple binding slots (3 sampled texture, 1 uniform buffer, 1
// sampler), so ensure that these count towards the limit when combined non-external texture
// bindings.
TEST_F(BindGroupLayoutValidationTest, PerStageLimitsWithExternalTexture) {
    struct TestInfo {
        uint32_t maxCount;
        uint32_t bindingsPerExternalTexture;
        wgpu::BindGroupLayoutEntry entry;
        wgpu::BindGroupLayoutEntry otherEntry;
    };

    const auto& limits = GetSupportedLimits();

    std::array<TestInfo, 3> kTestInfos = {
        TestInfo{limits.maxSampledTexturesPerShaderStage, kSampledTexturesPerExternalTexture,
                 BGLEntryType(wgpu::TextureSampleType::Float),
                 BGLEntryType(wgpu::BufferBindingType::Uniform)},
        TestInfo{limits.maxSamplersPerShaderStage, kSamplersPerExternalTexture,
                 BGLEntryType(wgpu::SamplerBindingType::Filtering),
                 BGLEntryType(wgpu::BufferBindingType::Uniform)},
        TestInfo{limits.maxUniformBuffersPerShaderStage, kUniformsPerExternalTexture,
                 BGLEntryType(wgpu::BufferBindingType::Uniform),
                 BGLEntryType(wgpu::TextureSampleType::Float)},
    };

    for (TestInfo info : kTestInfos) {
        wgpu::BindGroupLayout bgl[2];
        std::vector<utils::BindingLayoutEntryInitializationHelper> maxBindings;

        // Create an external texture binding layout entry
        wgpu::BindGroupLayoutEntry firstEntry = BGLEntryType(&utils::kExternalTextureBindingLayout);
        firstEntry.binding = 0;
        maxBindings.push_back(firstEntry);

        // Create the other bindings such that we reach the max bindings per stage when including
        // the external texture.
        for (uint32_t i = 1; i <= info.maxCount - info.bindingsPerExternalTexture; ++i) {
            wgpu::BindGroupLayoutEntry entry = info.entry;
            entry.binding = i;
            maxBindings.push_back(entry);
        }

        // Ensure that creation without the external texture works.
        bgl[0] = MakeBindGroupLayout(maxBindings.data(), maxBindings.size());

        // Adding an extra binding of a different type works.
        {
            std::vector<utils::BindingLayoutEntryInitializationHelper> bindings = maxBindings;
            wgpu::BindGroupLayoutEntry entry = info.otherEntry;
            entry.binding = info.maxCount;
            bindings.push_back(entry);
            MakeBindGroupLayout(bindings.data(), bindings.size());
        }

        // Adding an extra binding of the maxed type in a different stage works
        {
            std::vector<utils::BindingLayoutEntryInitializationHelper> bindings = maxBindings;
            wgpu::BindGroupLayoutEntry entry = info.entry;
            entry.binding = info.maxCount;
            entry.visibility = wgpu::ShaderStage::Fragment;
            bindings.push_back(entry);
            MakeBindGroupLayout(bindings.data(), bindings.size());
        }

        // Adding an extra binding of the maxed type and stage exceeds the per stage limit.
        {
            std::vector<utils::BindingLayoutEntryInitializationHelper> bindings = maxBindings;
            wgpu::BindGroupLayoutEntry entry = info.entry;
            entry.binding = info.maxCount;
            bindings.push_back(entry);
            ASSERT_DEVICE_ERROR(MakeBindGroupLayout(bindings.data(), bindings.size()));
        }

        // Creating a pipeline layout from the valid BGL works.
        TestCreatePipelineLayout(bgl, 1, true);

        // Adding an extra binding of a different type in a different BGL works
        bgl[1] = utils::MakeBindGroupLayout(device, {info.otherEntry});
        TestCreatePipelineLayout(bgl, 2, true);

        {
            // Adding an extra binding of the maxed type in a different stage works
            wgpu::BindGroupLayoutEntry entry = info.entry;
            entry.visibility = wgpu::ShaderStage::Fragment;
            bgl[1] = utils::MakeBindGroupLayout(device, {entry});
            TestCreatePipelineLayout(bgl, 2, true);
        }

        // Adding an extra binding of the maxed type in a different BGL exceeds the per stage limit.
        bgl[1] = utils::MakeBindGroupLayout(device, {info.entry});
        TestCreatePipelineLayout(bgl, 2, false);
    }
}

// Check that dynamic buffer numbers exceed maximum value in one bind group layout.
TEST_F(BindGroupLayoutValidationTest, DynamicBufferNumberLimit) {
    wgpu::BindGroupLayout bgl[2];
    std::vector<wgpu::BindGroupLayoutEntry> maxUniformDB;
    std::vector<wgpu::BindGroupLayoutEntry> maxStorageDB;
    std::vector<wgpu::BindGroupLayoutEntry> maxReadonlyStorageDB;

    const auto& limits = GetSupportedLimits();

    // In this test, we use all the same shader stage. Ensure that this does not exceed the
    // per-stage limit.
    DAWN_ASSERT(limits.maxDynamicUniformBuffersPerPipelineLayout <=
                limits.maxUniformBuffersPerShaderStage);
    DAWN_ASSERT(limits.maxDynamicStorageBuffersPerPipelineLayout <=
                limits.maxStorageBuffersPerShaderStage);

    for (uint32_t i = 0; i < limits.maxDynamicUniformBuffersPerPipelineLayout; ++i) {
        maxUniformDB.push_back(utils::BindingLayoutEntryInitializationHelper(
            i, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Uniform, true));
    }

    for (uint32_t i = 0; i < limits.maxDynamicStorageBuffersPerPipelineLayout; ++i) {
        maxStorageDB.push_back(utils::BindingLayoutEntryInitializationHelper(
            i, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage, true));
    }

    for (uint32_t i = 0; i < limits.maxDynamicStorageBuffersPerPipelineLayout; ++i) {
        maxReadonlyStorageDB.push_back(utils::BindingLayoutEntryInitializationHelper(
            i, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::ReadOnlyStorage, true));
    }

    // Test creating with the maxes works
    {
        bgl[0] = MakeBindGroupLayout(maxUniformDB.data(), maxUniformDB.size());
        TestCreatePipelineLayout(bgl, 1, true);

        bgl[0] = MakeBindGroupLayout(maxStorageDB.data(), maxStorageDB.size());
        TestCreatePipelineLayout(bgl, 1, true);

        bgl[0] = MakeBindGroupLayout(maxReadonlyStorageDB.data(), maxReadonlyStorageDB.size());
        TestCreatePipelineLayout(bgl, 1, true);
    }

    // The following tests exceed the per-pipeline layout limits. We use the Fragment stage to
    // ensure we don't hit the per-stage limit.

    // Check dynamic uniform buffers exceed maximum in pipeline layout.
    {
        bgl[0] = MakeBindGroupLayout(maxUniformDB.data(), maxUniformDB.size());
        bgl[1] = utils::MakeBindGroupLayout(
            device, {
                        {0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Uniform, true},
                    });

        TestCreatePipelineLayout(bgl, 2, false);
    }

    // Check dynamic storage buffers exceed maximum in pipeline layout
    {
        bgl[0] = MakeBindGroupLayout(maxStorageDB.data(), maxStorageDB.size());
        bgl[1] = utils::MakeBindGroupLayout(
            device, {
                        {0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Storage, true},
                    });

        TestCreatePipelineLayout(bgl, 2, false);
    }

    // Check dynamic readonly storage buffers exceed maximum in pipeline layout
    {
        bgl[0] = MakeBindGroupLayout(maxReadonlyStorageDB.data(), maxReadonlyStorageDB.size());
        bgl[1] = utils::MakeBindGroupLayout(
            device,
            {
                {0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::ReadOnlyStorage, true},
            });

        TestCreatePipelineLayout(bgl, 2, false);
    }

    // Check dynamic storage buffers + dynamic readonly storage buffers exceed maximum storage
    // buffers in pipeline layout
    {
        bgl[0] = MakeBindGroupLayout(maxStorageDB.data(), maxStorageDB.size());
        bgl[1] = utils::MakeBindGroupLayout(
            device,
            {
                {0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::ReadOnlyStorage, true},
            });

        TestCreatePipelineLayout(bgl, 2, false);
    }

    // Check dynamic uniform buffers exceed maximum in bind group layout.
    {
        maxUniformDB.push_back(utils::BindingLayoutEntryInitializationHelper(
            limits.maxDynamicUniformBuffersPerPipelineLayout, wgpu::ShaderStage::Fragment,
            wgpu::BufferBindingType::Uniform, true));
        TestCreateBindGroupLayout(maxUniformDB.data(), maxUniformDB.size(), false);
    }

    // Check dynamic storage buffers exceed maximum in bind group layout.
    {
        maxStorageDB.push_back(utils::BindingLayoutEntryInitializationHelper(
            limits.maxDynamicStorageBuffersPerPipelineLayout, wgpu::ShaderStage::Fragment,
            wgpu::BufferBindingType::Storage, true));
        TestCreateBindGroupLayout(maxStorageDB.data(), maxStorageDB.size(), false);
    }

    // Check dynamic readonly storage buffers exceed maximum in bind group layout.
    {
        maxReadonlyStorageDB.push_back(utils::BindingLayoutEntryInitializationHelper(
            limits.maxDynamicStorageBuffersPerPipelineLayout, wgpu::ShaderStage::Fragment,
            wgpu::BufferBindingType::ReadOnlyStorage, true));
        TestCreateBindGroupLayout(maxReadonlyStorageDB.data(), maxReadonlyStorageDB.size(), false);
    }
}

// Test that multisampled textures must be 2D sampled textures
TEST_F(BindGroupLayoutValidationTest, MultisampledTextureViewDimension) {
    // Multisampled 2D texture works.
    utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::UnfilterableFloat,
                     wgpu::TextureViewDimension::e2D, true},
                });

    // Multisampled 2D (defaulted) texture works.
    utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::UnfilterableFloat,
                     wgpu::TextureViewDimension::Undefined, true},
                });

    // Multisampled 2D array texture is invalid.
    ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::UnfilterableFloat,
                     wgpu::TextureViewDimension::e2DArray, true},
                }));

    // Multisampled cube texture is invalid.
    ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::UnfilterableFloat,
                     wgpu::TextureViewDimension::Cube, true},
                }));

    // Multisampled cube array texture is invalid.
    ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::UnfilterableFloat,
                     wgpu::TextureViewDimension::CubeArray, true},
                }));

    // Multisampled 3D texture is invalid.
    ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::UnfilterableFloat,
                     wgpu::TextureViewDimension::e3D, true},
                }));

    // Multisampled 1D texture is invalid.
    ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::UnfilterableFloat,
                     wgpu::TextureViewDimension::e1D, true},
                }));
}

// Test that multisampled texture bindings are valid
TEST_F(BindGroupLayoutValidationTest, MultisampledTextureSampleType) {
    // Multisampled float sample type is not supported.
    ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float,
                     wgpu::TextureViewDimension::e2D, true},
                }));

    // Multisampled unfilterable float sample type works.
    utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::UnfilterableFloat,
                     wgpu::TextureViewDimension::e2D, true},
                });

    // Multisampled uint sample type works.
    utils::MakeBindGroupLayout(device,
                               {
                                   {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Uint,
                                    wgpu::TextureViewDimension::e2D, true},
                               });

    // Multisampled sint sample type works.
    utils::MakeBindGroupLayout(device,
                               {
                                   {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Sint,
                                    wgpu::TextureViewDimension::e2D, true},
                               });

    // Multisampled depth sample type works.
    utils::MakeBindGroupLayout(device,
                               {
                                   {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Depth,
                                    wgpu::TextureViewDimension::e2D, true},
                               });
}

// Tests that creating a bind group layout with a valid static sampler raises an error
// if the required feature is not enabled.
TEST_F(BindGroupLayoutValidationTest, StaticSamplerNotSupportedWithoutFeatureEnabled) {
    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
    staticSamplerBinding.sampler = device.CreateSampler();
    binding.nextInChain = &staticSamplerBinding;

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

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

// Control case for a valid use of bindingArraySize
TEST_F(BindGroupLayoutValidationTest, ArraySizeSuccess) {
    for (uint32_t bindingArraySize : {0, 1, 2}) {
        wgpu::BindGroupLayoutEntry entry;
        entry.binding = 0;
        entry.visibility = wgpu::ShaderStage::Fragment;
        entry.bindingArraySize = bindingArraySize;
        entry.texture.sampleType = wgpu::TextureSampleType::Float;

        wgpu::BindGroupLayoutDescriptor desc;
        desc.entryCount = 1;
        desc.entries = &entry;
        device.CreateBindGroupLayout(&desc);
    }
}

class BindGroupLayoutArraySizeDisabledValidationTest : public BindGroupValidationTest {
  protected:
    std::vector<const char*> GetEnabledToggles() override {
        return {"disable_bind_group_layout_entry_array_size"};
    }
};

// Check that using bindingArraySize > 1 is disallowed by the toggle.
TEST_F(BindGroupLayoutArraySizeDisabledValidationTest, ArraySizeDisabled) {
    wgpu::BindGroupLayoutEntry entry;
    entry.binding = 0;
    entry.visibility = wgpu::ShaderStage::Fragment;
    entry.texture.sampleType = wgpu::TextureSampleType::Float;

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

    entry.bindingArraySize = 0;
    device.CreateBindGroupLayout(&desc);

    entry.bindingArraySize = 1;
    device.CreateBindGroupLayout(&desc);

    entry.bindingArraySize = 2;
    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
}

// Check that using a binding_array statically in an entry point is disabled.
TEST_F(BindGroupLayoutArraySizeDisabledValidationTest, BindingArrayDisabled) {
    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var textures : binding_array<texture_2d<f32>, 3>;
        @fragment fn fs() -> @location(0) u32 {
            let _ = textures[0];
            return 0;
        }
    )"));

    // Even an array of size 1 is an error.
    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var textures : binding_array<texture_2d<f32>, 1>;
        @fragment fn fs() -> @location(0) u32 {
            let _ = textures[0];
            return 0;
        }
    )"));
}

// Check that using bindingArraySize > 1 is only allowed for sampled textures.
TEST_F(BindGroupLayoutValidationTest, ArraySizeAllowedBindingTypes) {
    // Sampled texture
    {
        wgpu::BindGroupLayoutEntry entry;
        entry.binding = 0;
        entry.visibility = wgpu::ShaderStage::Fragment;
        entry.texture.sampleType = wgpu::TextureSampleType::Float;

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

        // Success case
        entry.bindingArraySize = 1;
        device.CreateBindGroupLayout(&desc);
        // Success case
        entry.bindingArraySize = 2;
        device.CreateBindGroupLayout(&desc);
    }

    // Uniform buffer
    {
        wgpu::BindGroupLayoutEntry entry;
        entry.binding = 0;
        entry.visibility = wgpu::ShaderStage::Fragment;
        entry.buffer.type = wgpu::BufferBindingType::Uniform;

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

        // Success case
        entry.bindingArraySize = 1;
        device.CreateBindGroupLayout(&desc);
        // Error case
        entry.bindingArraySize = 2;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
    }

    // Storage buffer
    {
        wgpu::BindGroupLayoutEntry entry;
        entry.binding = 0;
        entry.visibility = wgpu::ShaderStage::Fragment;
        entry.buffer.type = wgpu::BufferBindingType::Uniform;

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

        // Success case
        entry.bindingArraySize = 1;
        device.CreateBindGroupLayout(&desc);
        // Error case
        entry.bindingArraySize = 2;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
    }

    // Storage texture
    {
        wgpu::BindGroupLayoutEntry entry;
        entry.binding = 0;
        entry.visibility = wgpu::ShaderStage::Fragment;
        entry.storageTexture.format = wgpu::TextureFormat::R32Uint;
        entry.storageTexture.access = wgpu::StorageTextureAccess::ReadOnly;

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

        // Success case
        entry.bindingArraySize = 1;
        device.CreateBindGroupLayout(&desc);
        // Error case
        entry.bindingArraySize = 2;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
    }

    // Sampler
    {
        wgpu::BindGroupLayoutEntry entry;
        entry.binding = 0;
        entry.visibility = wgpu::ShaderStage::Fragment;
        entry.sampler.type = wgpu::SamplerBindingType::Filtering;

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

        // Success case
        entry.bindingArraySize = 1;
        device.CreateBindGroupLayout(&desc);
        // Error case
        entry.bindingArraySize = 2;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
    }
}

// Check that binding + bindingArraySize must fit in maxBindingsPerBindGroup
TEST_F(BindGroupLayoutValidationTest, ArrayEndPastMaxBindingsPerBindGroup) {
    wgpu::BindGroupLayoutEntry entry;
    entry.binding = kMaxBindingsPerBindGroup - 1;
    entry.visibility = wgpu::ShaderStage::Fragment;
    entry.texture.sampleType = wgpu::TextureSampleType::Float;

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

    // Success case, bindingArraySize is 1 so the last used binding is maxBindingsPerBindGroup
    entry.bindingArraySize = 1;
    device.CreateBindGroupLayout(&desc);

    // Error case, bindingArraySize is 2 so we go past maxBindingsPerBindGroup
    entry.bindingArraySize = 2;
    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
}

// Check that binding+bindingArraySize overflowing is caught by some validation.
TEST_F(BindGroupLayoutValidationTest, ArraySizePlusBindingOverflow) {
    wgpu::BindGroupLayoutEntry entry;
    entry.binding = 3;
    entry.visibility = wgpu::ShaderStage::Fragment;
    entry.bindingArraySize = std::numeric_limits<uint32_t>::max();
    entry.texture.sampleType = wgpu::TextureSampleType::Float;

    wgpu::BindGroupLayoutDescriptor desc;
    desc.entryCount = 1;
    desc.entries = &entry;
    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
}

// Check that bindingArraySize is taken into account when looking for duplicate bindings.
TEST_F(BindGroupLayoutValidationTest, ArraySizeDuplicateBindings) {
    const uint32_t kPlaceholderBinding = 42;  // will be replaced before each check.

    // Check single entry, then an array that overlaps it.
    {
        wgpu::BindGroupLayoutEntry entries[2] = {
            {
                .binding = kPlaceholderBinding,
                .visibility = wgpu::ShaderStage::Fragment,
                .texture = {.sampleType = wgpu::TextureSampleType::Float},
            },
            {
                .binding = 1,
                .visibility = wgpu::ShaderStage::Fragment,
                .bindingArraySize = 3,
                .texture = {.sampleType = wgpu::TextureSampleType::Float},
            },
        };
        wgpu::BindGroupLayoutDescriptor desc;
        desc.entryCount = 2;
        desc.entries = entries;

        // Success cases, 0 and 4 are not in [1, 4)
        entries[0].binding = 0;
        device.CreateBindGroupLayout(&desc);
        entries[0].binding = 4;
        device.CreateBindGroupLayout(&desc);

        // Error cases, 1, 2, 3 are in [1, 4)
        entries[0].binding = 1;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
        entries[0].binding = 2;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
        entries[0].binding = 3;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
    }

    // Check an array, then a single entry that goes in it.
    {
        wgpu::BindGroupLayoutEntry entries[2] = {
            {
                .binding = 1,
                .visibility = wgpu::ShaderStage::Fragment,
                .bindingArraySize = 3,
                .texture = {.sampleType = wgpu::TextureSampleType::Float},
            },
            {
                .binding = kPlaceholderBinding,
                .visibility = wgpu::ShaderStage::Fragment,
                .texture = {.sampleType = wgpu::TextureSampleType::Float},
            },
        };
        wgpu::BindGroupLayoutDescriptor desc;
        desc.entryCount = 2;
        desc.entries = entries;

        // Success cases, 0 and 4 are not in [1, 4)
        entries[1].binding = 0;
        device.CreateBindGroupLayout(&desc);
        entries[1].binding = 4;
        device.CreateBindGroupLayout(&desc);

        // Error cases, 1, 2, 3 are in [1, 4)
        entries[1].binding = 1;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
        entries[1].binding = 2;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
        entries[1].binding = 3;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
    }

    // Check two arrays that overlap
    {
        wgpu::BindGroupLayoutEntry entries[2] = {
            {
                .binding = kPlaceholderBinding,
                .visibility = wgpu::ShaderStage::Fragment,
                .bindingArraySize = 3,
                .texture = {.sampleType = wgpu::TextureSampleType::Float},
            },
            {
                .binding = 3,
                .visibility = wgpu::ShaderStage::Fragment,
                .bindingArraySize = 3,
                .texture = {.sampleType = wgpu::TextureSampleType::Float},
            },
        };
        wgpu::BindGroupLayoutDescriptor desc;
        desc.entryCount = 2;
        desc.entries = entries;

        // Success cases, 0 and 6 make the arrays not overlap
        entries[0].binding = 0;
        device.CreateBindGroupLayout(&desc);
        entries[0].binding = 6;
        device.CreateBindGroupLayout(&desc);

        // Error cases, 1, 2, 3, 4, 5 make the arrays overlap
        entries[0].binding = 1;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
        entries[0].binding = 2;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
        entries[0].binding = 3;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
        entries[0].binding = 4;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
        entries[0].binding = 5;
        ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
    }
}

// Check that bindingArraySize counts towards the binding limits.
TEST_F(BindGroupLayoutValidationTest, ArraySizeCountsTowardsLimit) {
    wgpu::BindGroupLayoutEntry entries[2] = {
        {
            .binding = 1,
            .visibility = wgpu::ShaderStage::Fragment,
            .bindingArraySize = 0,
            .texture = {.sampleType = wgpu::TextureSampleType::Float},
        },
        {
            .binding = 0,
            .visibility = wgpu::ShaderStage::Fragment,
            .texture = {.sampleType = wgpu::TextureSampleType::Float},
        },
    };
    wgpu::BindGroupLayoutDescriptor desc;
    desc.entryCount = 2;
    desc.entries = entries;

    const auto& limits = GetSupportedLimits();

    // Success case: we are just at the limit with the bindingArraySize.
    entries[0].bindingArraySize = limits.maxSampledTexturesPerShaderStage - 1;
    device.CreateBindGroupLayout(&desc);

    // Error case: we are just above the limit with the bindingArraySize.
    entries[0].bindingArraySize = limits.maxSampledTexturesPerShaderStage;
    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
}

// Test that only bindingArraySize = 0/1 is allowed for external textures
TEST_F(BindGroupLayoutValidationTest, ExternalTextureWithArraySize) {
    wgpu::ExternalTextureBindingLayout externalTextureLayout = {};

    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.nextInChain = &externalTextureLayout;

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

    // Success case
    binding.bindingArraySize = 0;
    device.CreateBindGroupLayout(&desc);

    // Success case
    binding.bindingArraySize = 1;
    device.CreateBindGroupLayout(&desc);

    // Error case
    binding.bindingArraySize = 2;
    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
}

class BindGroupLayoutWithStaticSamplersValidationTest : public BindGroupLayoutValidationTest {
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        return {wgpu::FeatureName::StaticSamplers};
    }
};

// Tests that creating a bind group layout with a valid static sampler succeeds if the
// required feature is enabled.
TEST_F(BindGroupLayoutWithStaticSamplersValidationTest, StaticSamplerSupportedWhenFeatureEnabled) {
    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
    staticSamplerBinding.sampler = device.CreateSampler();
    binding.nextInChain = &staticSamplerBinding;

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

    device.CreateBindGroupLayout(&desc);
}

// Tests that creating a bind group layout with a static sampler that has an
// invalid sampler object fails.
TEST_F(BindGroupLayoutWithStaticSamplersValidationTest, StaticSamplerWithInvalidSamplerObject) {
    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};

    wgpu::SamplerDescriptor samplerDesc;
    samplerDesc.minFilter = static_cast<wgpu::FilterMode>(0xFFFFFFFF);

    wgpu::Sampler errorSampler;
    ASSERT_DEVICE_ERROR(errorSampler = device.CreateSampler(&samplerDesc));

    staticSamplerBinding.sampler = errorSampler;
    binding.nextInChain = &staticSamplerBinding;

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

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

// Verifies that creation of a bind group with no entry for a static sampler
// succeeds.
TEST_F(BindGroupLayoutWithStaticSamplersValidationTest, CreateBindGroupWithStaticSamplerSupported) {
    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
    staticSamplerBinding.sampler = device.CreateSampler();
    binding.nextInChain = &staticSamplerBinding;

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

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

    wgpu::BindGroupDescriptor descriptor;
    descriptor.layout = layout;
    descriptor.entryCount = 0;

    device.CreateBindGroup(&descriptor);
}

// Verifies that creation of a correctly-specified bind group for a layout that
// has a static sampler and a sampler succeeds.
TEST_F(BindGroupLayoutWithStaticSamplersValidationTest,
       CreateBindGroupWithStaticSamplerAndSamplerSupported) {
    std::vector<wgpu::BindGroupLayoutEntry> entries;

    wgpu::BindGroupLayoutEntry binding0 = {};
    binding0.binding = 0;
    wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
    staticSamplerBinding.sampler = device.CreateSampler();
    binding0.nextInChain = &staticSamplerBinding;
    entries.push_back(binding0);

    wgpu::BindGroupLayoutEntry binding1 = {};
    binding1.binding = 1;
    binding1.sampler.type = wgpu::SamplerBindingType::Filtering;
    entries.push_back(binding1);

    wgpu::BindGroupLayoutDescriptor desc = {};
    desc.entryCount = 2;
    desc.entries = entries.data();

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

    wgpu::SamplerDescriptor samplerDesc;
    samplerDesc.minFilter = wgpu::FilterMode::Linear;
    utils::MakeBindGroup(device, layout, {{1, device.CreateSampler(&samplerDesc)}});
}

// Verifies that creation of a correctly-specified bind group for a layout that
// has a sampler and a static sampler succeeds.
TEST_F(BindGroupLayoutWithStaticSamplersValidationTest,
       CreateBindGroupWithSamplerAndStaticSamplerSupported) {
    std::vector<wgpu::BindGroupLayoutEntry> entries;

    wgpu::BindGroupLayoutEntry binding0 = {};
    binding0.binding = 0;
    binding0.sampler.type = wgpu::SamplerBindingType::Filtering;
    entries.push_back(binding0);

    wgpu::BindGroupLayoutEntry binding1 = {};
    binding1.binding = 1;
    wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
    staticSamplerBinding.sampler = device.CreateSampler();
    binding1.nextInChain = &staticSamplerBinding;
    entries.push_back(binding1);

    wgpu::BindGroupLayoutDescriptor desc = {};
    desc.entryCount = 2;
    desc.entries = entries.data();

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

    wgpu::SamplerDescriptor samplerDesc;
    samplerDesc.minFilter = wgpu::FilterMode::Linear;
    utils::MakeBindGroup(device, layout, {{0, device.CreateSampler(&samplerDesc)}});
}

// Verifies that creating a bind group with an entry for a static sampler causes
// an error.
TEST_F(BindGroupLayoutWithStaticSamplersValidationTest,
       EntryForStaticSamplerInBindGroupCausesError) {
    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
    staticSamplerBinding.sampler = device.CreateSampler();
    binding.nextInChain = &staticSamplerBinding;

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

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

    wgpu::SamplerDescriptor samplerDesc;
    samplerDesc.minFilter = wgpu::FilterMode::Linear;
    ASSERT_DEVICE_ERROR(
        utils::MakeBindGroup(device, layout, {{0, device.CreateSampler(&samplerDesc)}}));
}

// Verifies that creation of a bind group with the correct number of entries for a layout that has a
// sampler and a static sampler raises an error if the entry is specified at the
// index of the static sampler rather than that of the sampler.
TEST_F(BindGroupLayoutWithStaticSamplersValidationTest,
       CorrectNumberOfEntriesButEntryForStaticSamplerAtSecondIndexInBindGroupCausesError) {
    std::vector<wgpu::BindGroupLayoutEntry> entries;

    wgpu::BindGroupLayoutEntry binding0 = {};
    binding0.binding = 0;
    binding0.sampler.type = wgpu::SamplerBindingType::Filtering;
    entries.push_back(binding0);

    wgpu::BindGroupLayoutEntry binding1 = {};
    binding1.binding = 1;
    wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
    staticSamplerBinding.sampler = device.CreateSampler();
    binding1.nextInChain = &staticSamplerBinding;
    entries.push_back(binding1);

    wgpu::BindGroupLayoutDescriptor desc = {};
    desc.entryCount = 2;
    desc.entries = entries.data();

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

    wgpu::SamplerDescriptor samplerDesc;
    samplerDesc.minFilter = wgpu::FilterMode::Linear;
    ASSERT_DEVICE_ERROR(
        utils::MakeBindGroup(device, layout, {{1, device.CreateSampler(&samplerDesc)}}));
}

// Verifies that creation of a bind group with the correct number of entries for a layout that has a
// static sampler and a sampler raises an error if the entry is specified at the
// index of the static sampler rather than that of the sampler.
TEST_F(BindGroupLayoutWithStaticSamplersValidationTest,
       CorrectNumberOfEntriesButEntryForStaticSamplerInBindGroupCausesError) {
    std::vector<wgpu::BindGroupLayoutEntry> entries;

    wgpu::BindGroupLayoutEntry binding0 = {};
    binding0.binding = 0;
    wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
    staticSamplerBinding.sampler = device.CreateSampler();
    binding0.nextInChain = &staticSamplerBinding;
    entries.push_back(binding0);

    wgpu::BindGroupLayoutEntry binding1 = {};
    binding1.binding = 1;
    binding1.sampler.type = wgpu::SamplerBindingType::Filtering;
    entries.push_back(binding1);

    wgpu::BindGroupLayoutDescriptor desc = {};
    desc.entryCount = 2;
    desc.entries = entries.data();

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

    wgpu::SamplerDescriptor samplerDesc;
    samplerDesc.minFilter = wgpu::FilterMode::Linear;
    ASSERT_DEVICE_ERROR(
        utils::MakeBindGroup(device, layout, {{0, device.CreateSampler(&samplerDesc)}}));
}

// Test that only bindingArraySize = 0/1 is allowed for static samplers
TEST_F(BindGroupLayoutWithStaticSamplersValidationTest, StaticSamplerWithArraySize) {
    wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
    staticSamplerBinding.sampler = device.CreateSampler();

    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.nextInChain = &staticSamplerBinding;

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

    // Success case
    binding.bindingArraySize = 0;
    device.CreateBindGroupLayout(&desc);

    // Success case
    binding.bindingArraySize = 1;
    device.CreateBindGroupLayout(&desc);

    // Error case
    binding.bindingArraySize = 2;
    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
}

// Test that the BGL visibility of a static sampler contain the shader's stage.
TEST_F(BindGroupLayoutWithStaticSamplersValidationTest, BGLVisibilityContainsShaderStage) {
    // Set up the static sampler binding but don't create the BGL yet.
    wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
    staticSamplerBinding.sampler = device.CreateSampler();

    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.nextInChain = &staticSamplerBinding;

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

    // Set up the compute pipeline but don't create it yet.
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var s : sampler;
        @compute @workgroup_size(1) fn main() {
            _ = s;
        }
    )");

    // Success case, the BGL contains compute.
    binding.visibility = wgpu::ShaderStage::Compute;
    wgpu::BindGroupLayout bglCompute = device.CreateBindGroupLayout(&desc);
    csDesc.layout = utils::MakeBasicPipelineLayout(device, &bglCompute);
    device.CreateComputePipeline(&csDesc);

    // Error case, the BGL doesn't contains compute.
    binding.visibility = wgpu::ShaderStage::Fragment;
    wgpu::BindGroupLayout bglFragment = device.CreateBindGroupLayout(&desc);
    csDesc.layout = utils::MakeBasicPipelineLayout(device, &bglFragment);
    ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&csDesc));
}

// Test that the BGL comparisoness for static sampler must match the shader.
TEST_F(BindGroupLayoutWithStaticSamplersValidationTest, BGLComparisonessMatchesShader) {
    // Set up the static sampler binding but don't create the BGL yet.
    wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};

    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.visibility = wgpu::ShaderStage::Compute;
    binding.nextInChain = &staticSamplerBinding;

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

    // Set up the compute pipeline but don't create it yet.
    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var s : sampler;
        @compute @workgroup_size(1) fn main() {
            _ = s;
        }
    )");

    // Success case, the BGL contains a non-comparison sampler, like the shader.
    staticSamplerBinding.sampler = device.CreateSampler();
    wgpu::BindGroupLayout bglCompute = device.CreateBindGroupLayout(&desc);
    csDesc.layout = utils::MakeBasicPipelineLayout(device, &bglCompute);
    device.CreateComputePipeline(&csDesc);

    // Error case, the BGL contains a comparison sampler unlike the shader.
    wgpu::SamplerDescriptor comparisonDesc = {};
    comparisonDesc.compare = wgpu::CompareFunction::Never;
    staticSamplerBinding.sampler = device.CreateSampler(&comparisonDesc);
    wgpu::BindGroupLayout bglFragment = device.CreateBindGroupLayout(&desc);
    csDesc.layout = utils::MakeBasicPipelineLayout(device, &bglFragment);
    ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&csDesc));
}

constexpr uint32_t kBindingSize = 8;

class SetBindGroupValidationTest : public ValidationTest {
  public:
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        return {wgpu::FeatureName::StaticSamplers};
    }

    void SetUp() override {
        ValidationTest::SetUp();

        mBindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                      wgpu::BufferBindingType::Uniform, true},
                     {1, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                      wgpu::BufferBindingType::Uniform, false},
                     {2, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                      wgpu::BufferBindingType::Storage, true},
                     {3, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                      wgpu::BufferBindingType::ReadOnlyStorage, true}});
        mMinUniformBufferOffsetAlignment = GetSupportedLimits().minUniformBufferOffsetAlignment;
        mBufferSize = 3 * mMinUniformBufferOffsetAlignment + 8;
    }

    wgpu::Buffer CreateBuffer(uint64_t bufferSize, wgpu::BufferUsage usage) {
        wgpu::BufferDescriptor bufferDescriptor;
        bufferDescriptor.size = bufferSize;
        bufferDescriptor.usage = usage;

        return device.CreateBuffer(&bufferDescriptor);
    }

    wgpu::BindGroupLayout mBindGroupLayout;

    wgpu::RenderPipeline CreateRenderPipeline() {
        wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
                @vertex fn main() -> @builtin(position) vec4f {
                    return vec4f();
                })");

        wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
                struct S {
                    value : vec2f
                }

                @group(0) @binding(0) var<uniform> uBufferDynamic : S;
                @group(0) @binding(1) var<uniform> uBuffer : S;
                @group(0) @binding(2) var<storage, read_write> sBufferDynamic : S;
                @group(0) @binding(3) var<storage, read> sReadonlyBufferDynamic : S;

                @fragment fn main() {
                })");

        utils::ComboRenderPipelineDescriptor pipelineDescriptor;
        pipelineDescriptor.vertex.module = vsModule;
        pipelineDescriptor.cFragment.module = fsModule;
        pipelineDescriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;
        wgpu::PipelineLayout pipelineLayout =
            utils::MakeBasicPipelineLayout(device, &mBindGroupLayout);
        pipelineDescriptor.layout = pipelineLayout;
        return device.CreateRenderPipeline(&pipelineDescriptor);
    }

    wgpu::ComputePipeline CreateComputePipeline() {
        wgpu::ShaderModule csModule = utils::CreateShaderModule(device, R"(
                struct S {
                    value : vec2f
                }

                @group(0) @binding(0) var<uniform> uBufferDynamic : S;
                @group(0) @binding(1) var<uniform> uBuffer : S;
                @group(0) @binding(2) var<storage, read_write> sBufferDynamic : S;
                @group(0) @binding(3) var<storage, read> sReadonlyBufferDynamic : S;

                @compute @workgroup_size(4, 4, 1) fn main() {
                })");

        wgpu::PipelineLayout pipelineLayout =
            utils::MakeBasicPipelineLayout(device, &mBindGroupLayout);

        wgpu::ComputePipelineDescriptor csDesc;
        csDesc.layout = pipelineLayout;
        csDesc.compute.module = csModule;

        return device.CreateComputePipeline(&csDesc);
    }

    wgpu::BindGroup CreateAllTypesBindGroup(uint32_t bindingSize) {
        wgpu::Buffer uniformBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Uniform);
        wgpu::Buffer storageBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Storage);
        wgpu::Buffer readonlyStorageBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Storage);
        return utils::MakeBindGroup(device, mBindGroupLayout,
                                    {{0, uniformBuffer, 0, bindingSize},
                                     {1, uniformBuffer, 0, bindingSize},
                                     {2, storageBuffer, 0, bindingSize},
                                     {3, readonlyStorageBuffer, 0, bindingSize}});
    }

    void TestRenderPassBindGroup(wgpu::BindGroup bindGroup,
                                 uint32_t* offsets,
                                 uint32_t count,
                                 bool expectation) {
        wgpu::RenderPipeline renderPipeline = CreateRenderPipeline();
        PlaceholderRenderPass renderPass(device);

        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.SetPipeline(renderPipeline);
        if (bindGroup != nullptr) {
            renderPassEncoder.SetBindGroup(0, bindGroup, count, offsets);
        }
        renderPassEncoder.Draw(3);
        renderPassEncoder.End();
        if (!expectation) {
            ASSERT_DEVICE_ERROR(commandEncoder.Finish());
        } else {
            commandEncoder.Finish();
        }
    }

    void TestComputePassBindGroup(wgpu::BindGroup bindGroup,
                                  uint32_t* offsets,
                                  uint32_t count,
                                  bool expectation) {
        wgpu::ComputePipeline computePipeline = CreateComputePipeline();

        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder computePassEncoder = commandEncoder.BeginComputePass();
        computePassEncoder.SetPipeline(computePipeline);
        if (bindGroup != nullptr) {
            computePassEncoder.SetBindGroup(0, bindGroup, count, offsets);
        }
        computePassEncoder.DispatchWorkgroups(1);
        computePassEncoder.End();
        if (!expectation) {
            ASSERT_DEVICE_ERROR(commandEncoder.Finish());
        } else {
            commandEncoder.Finish();
        }
    }

  protected:
    uint32_t mMinUniformBufferOffsetAlignment;
    uint64_t mBufferSize;
};

// This is the test case that should work.
TEST_F(SetBindGroupValidationTest, Basic) {
    // Set up the bind group.
    wgpu::BindGroup bindGroup = CreateAllTypesBindGroup(kBindingSize);

    std::array<uint32_t, 3> offsets = {512, 256, 0};

    TestRenderPassBindGroup(bindGroup, offsets.data(), 3, true);

    TestComputePassBindGroup(bindGroup, offsets.data(), 3, true);
}

// Draw/dispatch with a bind group missing is invalid
TEST_F(SetBindGroupValidationTest, MissingBindGroup) {
    TestRenderPassBindGroup(nullptr, nullptr, 0, false);
    TestComputePassBindGroup(nullptr, nullptr, 0, false);
}

// Unset the bind group required by current pipeline is invalid.
TEST_F(SetBindGroupValidationTest, UnsetBindGroupWhenNeeded) {
    // Set up the bind group.
    wgpu::BindGroup bindGroup = CreateAllTypesBindGroup(kBindingSize);

    std::array<uint32_t, 3> offsets = {512, 256, 0};

    // render pass case
    {
        wgpu::RenderPipeline renderPipeline = CreateRenderPipeline();
        PlaceholderRenderPass renderPass(device);

        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.SetPipeline(renderPipeline);
        renderPassEncoder.SetBindGroup(0, bindGroup, offsets.size(), offsets.data());
        // Unset the bind group which is required by the current pipeline.
        renderPassEncoder.SetBindGroup(0, nullptr);
        renderPassEncoder.Draw(3);
        renderPassEncoder.End();
        ASSERT_DEVICE_ERROR(commandEncoder.Finish());
    }

    // compute pass case
    {
        wgpu::ComputePipeline computePipeline = CreateComputePipeline();

        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder computePassEncoder = commandEncoder.BeginComputePass();
        computePassEncoder.SetPipeline(computePipeline);
        computePassEncoder.SetBindGroup(0, bindGroup, offsets.size(), offsets.data());
        // The pipeline in compute pass requires an appropriate bindgroup, which is missing.
        computePassEncoder.SetBindGroup(0, nullptr);
        computePassEncoder.DispatchWorkgroups(1);
        computePassEncoder.End();
        ASSERT_DEVICE_ERROR(commandEncoder.Finish());
    }
}

// Regression test for the validation aspect caching not being invalidated when unsetting a
// bind group.
TEST_F(SetBindGroupValidationTest, UnsetInvalidatesBindGroupValidationCache) {
    // Set up the bind group.
    wgpu::BindGroup bindGroup = CreateAllTypesBindGroup(kBindingSize);

    std::array<uint32_t, 3> offsets = {512, 256, 0};

    // Render pass case
    {
        wgpu::RenderPipeline renderPipeline = CreateRenderPipeline();
        PlaceholderRenderPass renderPass(device);

        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.SetPipeline(renderPipeline);
        renderPassEncoder.SetBindGroup(0, bindGroup, 3, offsets.data());
        renderPassEncoder.Draw(3);
        // Unset the bindgroup after draw. The bindgroup might be cached by the previous draw.
        renderPassEncoder.SetBindGroup(0, nullptr);
        renderPassEncoder.Draw(3);
        renderPassEncoder.End();
        ASSERT_DEVICE_ERROR(commandEncoder.Finish());
    }

    // Compute pass case
    {
        wgpu::ComputePipeline computePipeline = CreateComputePipeline();

        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder computePassEncoder = commandEncoder.BeginComputePass();
        computePassEncoder.SetPipeline(computePipeline);
        computePassEncoder.SetBindGroup(0, bindGroup, 3, offsets.data());
        computePassEncoder.DispatchWorkgroups(1);
        // Unset the bindgroup after dispatch. The bindgroup might be cached by the previous
        // dispatch.
        computePassEncoder.SetBindGroup(0, nullptr);
        computePassEncoder.DispatchWorkgroups(1);
        computePassEncoder.End();
        ASSERT_DEVICE_ERROR(commandEncoder.Finish());
    }
}

// Setting bind group after a draw / dispatch should re-verify the layout is compatible
TEST_F(SetBindGroupValidationTest, VerifyGroupIfChangedAfterAction) {
    // Set up the bind group
    wgpu::Buffer uniformBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Uniform);
    wgpu::Buffer storageBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Storage);
    wgpu::Buffer readonlyStorageBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Storage);
    wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, mBindGroupLayout,
                                                     {{0, uniformBuffer, 0, kBindingSize},
                                                      {1, uniformBuffer, 0, kBindingSize},
                                                      {2, storageBuffer, 0, kBindingSize},
                                                      {3, readonlyStorageBuffer, 0, kBindingSize}});

    std::array<uint32_t, 3> offsets = {512, 256, 0};

    // Set up bind group that is incompatible
    wgpu::BindGroupLayout invalidLayout = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                  wgpu::BufferBindingType::Storage}});
    wgpu::BindGroup invalidGroup =
        utils::MakeBindGroup(device, invalidLayout, {{0, storageBuffer, 0, kBindingSize}});

    {
        wgpu::ComputePipeline computePipeline = CreateComputePipeline();
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder computePassEncoder = commandEncoder.BeginComputePass();
        computePassEncoder.SetPipeline(computePipeline);
        computePassEncoder.SetBindGroup(0, bindGroup, 3, offsets.data());
        computePassEncoder.DispatchWorkgroups(1);
        computePassEncoder.SetBindGroup(0, invalidGroup, 0, nullptr);
        computePassEncoder.DispatchWorkgroups(1);
        computePassEncoder.End();
        ASSERT_DEVICE_ERROR(commandEncoder.Finish());
    }
    {
        wgpu::RenderPipeline renderPipeline = CreateRenderPipeline();
        PlaceholderRenderPass renderPass(device);

        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.SetPipeline(renderPipeline);
        renderPassEncoder.SetBindGroup(0, bindGroup, 3, offsets.data());
        renderPassEncoder.Draw(3);
        renderPassEncoder.SetBindGroup(0, invalidGroup, 0, nullptr);
        renderPassEncoder.Draw(3);
        renderPassEncoder.End();
        ASSERT_DEVICE_ERROR(commandEncoder.Finish());
    }
}

// Test cases that test dynamic offsets count mismatch with bind group layout.
TEST_F(SetBindGroupValidationTest, DynamicOffsetsMismatch) {
    // Set up bind group.
    wgpu::BindGroup bindGroup = CreateAllTypesBindGroup(kBindingSize);

    // Number of offsets mismatch.
    std::array<uint32_t, 4> mismatchOffsets = {768, 512, 256, 0};

    TestRenderPassBindGroup(bindGroup, mismatchOffsets.data(), 1, false);
    TestRenderPassBindGroup(bindGroup, mismatchOffsets.data(), 2, false);
    TestRenderPassBindGroup(bindGroup, mismatchOffsets.data(), 4, false);

    TestComputePassBindGroup(bindGroup, mismatchOffsets.data(), 1, false);
    TestComputePassBindGroup(bindGroup, mismatchOffsets.data(), 2, false);
    TestComputePassBindGroup(bindGroup, mismatchOffsets.data(), 4, false);
}

// Test cases that test dynamic offsets not aligned
TEST_F(SetBindGroupValidationTest, DynamicOffsetsNotAligned) {
    // Set up bind group.
    wgpu::BindGroup bindGroup = CreateAllTypesBindGroup(kBindingSize);

    // Dynamic offsets are not aligned.
    std::array<uint32_t, 3> notAlignedOffsets = {512, 128, 0};

    TestRenderPassBindGroup(bindGroup, notAlignedOffsets.data(), 3, false);

    TestComputePassBindGroup(bindGroup, notAlignedOffsets.data(), 3, false);
}

// Test cases that test dynamic uniform buffer out of bound situation.
TEST_F(SetBindGroupValidationTest, OffsetOutOfBoundDynamicUniformBuffer) {
    // Set up bind group.
    wgpu::BindGroup bindGroup = CreateAllTypesBindGroup(kBindingSize);

    // Dynamic offset + offset is larger than buffer size.
    std::array<uint32_t, 3> overFlowOffsets = {1024, 256, 0};

    TestRenderPassBindGroup(bindGroup, overFlowOffsets.data(), 3, false);

    TestComputePassBindGroup(bindGroup, overFlowOffsets.data(), 3, false);
}

// Test cases that test dynamic storage buffer out of bound situation.
TEST_F(SetBindGroupValidationTest, OffsetOutOfBoundDynamicStorageBuffer) {
    // Set up bind group.
    wgpu::BindGroup bindGroup = CreateAllTypesBindGroup(kBindingSize);

    // Dynamic offset + offset is larger than buffer size.
    std::array<uint32_t, 3> overFlowOffsets = {0, 256, 1024};

    TestRenderPassBindGroup(bindGroup, overFlowOffsets.data(), 3, false);

    TestComputePassBindGroup(bindGroup, overFlowOffsets.data(), 3, false);
}

// Test cases that test dynamic uniform buffer out of bound situation because of binding size.
TEST_F(SetBindGroupValidationTest, BindingSizeOutOfBoundDynamicUniformBuffer) {
    // Set up bind group, but binding size is larger than (mBufferSize - DynamicOffset).
    constexpr uint32_t kLargeBindingSize = kBindingSize + 4u;
    wgpu::BindGroup bindGroup = CreateAllTypesBindGroup(kLargeBindingSize);

    // c + offset isn't larger than buffer size.
    // But with binding size, it will trigger OOB error.
    std::array<uint32_t, 3> offsets = {768, 256, 0};

    TestRenderPassBindGroup(bindGroup, offsets.data(), 3, false);

    TestComputePassBindGroup(bindGroup, offsets.data(), 3, false);
}

// Test cases that test dynamic storage buffer out of bound situation because of binding size.
TEST_F(SetBindGroupValidationTest, BindingSizeOutOfBoundDynamicStorageBuffer) {
    constexpr uint32_t kLargeBindingSize = kBindingSize + 4u;
    wgpu::BindGroup bindGroup = CreateAllTypesBindGroup(kLargeBindingSize);

    // Dynamic offset + offset isn't larger than buffer size.
    // But with binding size, it will trigger OOB error.
    std::array<uint32_t, 3> offsets = {0, 256, 768};

    TestRenderPassBindGroup(bindGroup, offsets.data(), 3, false);

    TestComputePassBindGroup(bindGroup, offsets.data(), 3, false);
}

// Regression test for crbug.com/dawn/408 where dynamic offsets were applied in the wrong order.
// Dynamic offsets should be applied in increasing order of binding number.
TEST_F(SetBindGroupValidationTest, DynamicOffsetOrder) {
    // Note: The order of the binding numbers of the bind group and bind group layout are
    // intentionally different and not in increasing order.
    // This test uses both storage and uniform buffers to ensure buffer bindings are sorted first by
    // binding number before type.
    wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
        device, {
                    {3, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::ReadOnlyStorage, true},
                    {0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::ReadOnlyStorage, true},
                    {2, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Uniform, true},
                });

    // Create buffers which are 3x, 2x, and 1x the size of the minimum buffer offset, plus 4 bytes
    // to spare (to avoid zero-sized bindings). We will offset the bindings so they reach the very
    // end of the buffer. Any mismatch applying too-large of an offset to a smaller buffer will hit
    // the out-of-bounds condition during validation.
    wgpu::Buffer buffer3x =
        CreateBuffer(3 * mMinUniformBufferOffsetAlignment + 4, wgpu::BufferUsage::Storage);
    wgpu::Buffer buffer2x =
        CreateBuffer(2 * mMinUniformBufferOffsetAlignment + 4, wgpu::BufferUsage::Storage);
    wgpu::Buffer buffer1x =
        CreateBuffer(1 * mMinUniformBufferOffsetAlignment + 4, wgpu::BufferUsage::Uniform);
    wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, bgl,
                                                     {
                                                         {0, buffer3x, 0, 4},
                                                         {3, buffer2x, 0, 4},
                                                         {2, buffer1x, 0, 4},
                                                     });

    std::array<uint32_t, 3> offsets;
    {
        // Base case works.
        offsets = {/* binding 0 */ 0,
                   /* binding 2 */ 0,
                   /* binding 3 */ 0};
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder computePassEncoder = commandEncoder.BeginComputePass();
        computePassEncoder.SetBindGroup(0, bindGroup, offsets.size(), offsets.data());
        computePassEncoder.End();
        commandEncoder.Finish();
    }
    {
        // Offset the first binding to touch the end of the buffer. Should succeed.
        // Will fail if the offset is applied to the first or second bindings since their buffers
        // are too small.
        offsets = {/* binding 0 */ 3 * mMinUniformBufferOffsetAlignment,
                   /* binding 2 */ 0,
                   /* binding 3 */ 0};
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder computePassEncoder = commandEncoder.BeginComputePass();
        computePassEncoder.SetBindGroup(0, bindGroup, offsets.size(), offsets.data());
        computePassEncoder.End();
        commandEncoder.Finish();
    }
    {
        // Offset the second binding to touch the end of the buffer. Should succeed.
        offsets = {/* binding 0 */ 0,
                   /* binding 2 */ 1 * mMinUniformBufferOffsetAlignment,
                   /* binding 3 */ 0};
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder computePassEncoder = commandEncoder.BeginComputePass();
        computePassEncoder.SetBindGroup(0, bindGroup, offsets.size(), offsets.data());
        computePassEncoder.End();
        commandEncoder.Finish();
    }
    {
        // Offset the third binding to touch the end of the buffer. Should succeed.
        // Will fail if the offset is applied to the second binding since its buffer
        // is too small.
        offsets = {/* binding 0 */ 0,
                   /* binding 2 */ 0,
                   /* binding 3 */ 2 * mMinUniformBufferOffsetAlignment};
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder computePassEncoder = commandEncoder.BeginComputePass();
        computePassEncoder.SetBindGroup(0, bindGroup, offsets.size(), offsets.data());
        computePassEncoder.End();
        commandEncoder.Finish();
    }
    {
        // Offset each binding to touch the end of their buffer. Should succeed.
        offsets = {/* binding 0 */ 3 * mMinUniformBufferOffsetAlignment,
                   /* binding 2 */ 1 * mMinUniformBufferOffsetAlignment,
                   /* binding 3 */ 2 * mMinUniformBufferOffsetAlignment};
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder computePassEncoder = commandEncoder.BeginComputePass();
        computePassEncoder.SetBindGroup(0, bindGroup, offsets.size(), offsets.data());
        computePassEncoder.End();
        commandEncoder.Finish();
    }
}

// Test that an error is produced (and no ASSERTs fired) when using an error bindgroup in
// SetBindGroup
TEST_F(SetBindGroupValidationTest, ErrorBindGroup) {
    // Bindgroup creation fails because not all bindings are specified.
    wgpu::BindGroup bindGroup;
    ASSERT_DEVICE_ERROR(bindGroup = utils::MakeBindGroup(device, mBindGroupLayout, {}));

    TestRenderPassBindGroup(bindGroup, nullptr, 0, false);

    TestComputePassBindGroup(bindGroup, nullptr, 0, false);
}

// Test validation of the bindgroup slot for OOB.
TEST_F(SetBindGroupValidationTest, BindGroupSlotBoundary) {
    wgpu::BindGroupLayout emptyBGL = utils::MakeBindGroupLayout(device, {});
    wgpu::BindGroup emptyBindGroup = utils::MakeBindGroup(device, emptyBGL, {});

    PlaceholderRenderPass renderPass(device);

    auto TestIndex = [this, renderPass](wgpu::BindGroup bg, uint32_t i, bool valid) {
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder cp = encoder.BeginComputePass();
            cp.SetBindGroup(i, bg);
            cp.End();
            if (valid) {
                encoder.Finish();
            } else {
                ASSERT_DEVICE_ERROR(encoder.Finish());
            }
        }

        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder rp = encoder.BeginRenderPass(&renderPass);
            rp.SetBindGroup(i, bg);
            rp.End();
            if (valid) {
                encoder.Finish();
            } else {
                ASSERT_DEVICE_ERROR(encoder.Finish());
            }
        }

        {
            utils::ComboRenderBundleEncoderDescriptor renderBundleDesc = {};
            renderBundleDesc.colorFormatCount = 1;
            renderBundleDesc.cColorFormats[0] = wgpu::TextureFormat::RGBA8Unorm;
            wgpu::RenderBundleEncoder rb = device.CreateRenderBundleEncoder(&renderBundleDesc);
            rb.SetBindGroup(i, bg);
            if (valid) {
                rb.Finish();
            } else {
                ASSERT_DEVICE_ERROR(rb.Finish());
            }
        }
    };

    // Base
    TestIndex(emptyBindGroup, 0, true);
    // Set the last bind group slot is valid
    TestIndex(emptyBindGroup, kMaxBindGroups - 1, true);
    // Set pass the last bind group slot is invalid
    TestIndex(emptyBindGroup, kMaxBindGroups, false);

    // Unset the slot which is not set before is valid
    TestIndex(nullptr, 0, true);
    // Unset the last bind group slot is valid
    TestIndex(nullptr, kMaxBindGroups - 1, true);
    // Unset pass the last bind group slot is invalid
    TestIndex(nullptr, kMaxBindGroups, false);
}

// Test that dynamic offset count must be zero when unsetting a bindgroup.
TEST_F(SetBindGroupValidationTest, UnsetWithDynamicOffsetIsInvalid) {
    auto TestDynamicOffsetCount = [this](uint32_t count, uint32_t* offsets, bool valid) {
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder cp = encoder.BeginComputePass();
            cp.SetBindGroup(0, nullptr, count, offsets);
            cp.End();
            if (valid) {
                encoder.Finish();
            } else {
                ASSERT_DEVICE_ERROR(encoder.Finish());
            }
        }

        {
            PlaceholderRenderPass renderPass(device);
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder rp = encoder.BeginRenderPass(&renderPass);
            rp.SetBindGroup(0, nullptr, count, offsets);
            rp.End();
            if (valid) {
                encoder.Finish();
            } else {
                ASSERT_DEVICE_ERROR(encoder.Finish());
            }
        }

        {
            utils::ComboRenderBundleEncoderDescriptor renderBundleDesc = {};
            renderBundleDesc.colorFormatCount = 1;
            renderBundleDesc.cColorFormats[0] = wgpu::TextureFormat::RGBA8Unorm;
            wgpu::RenderBundleEncoder rb = device.CreateRenderBundleEncoder(&renderBundleDesc);
            rb.SetBindGroup(0, nullptr, count, offsets);
            if (valid) {
                rb.Finish();
            } else {
                ASSERT_DEVICE_ERROR(rb.Finish());
            }
        }
    };

    std::array<uint32_t, 2> offsets = {256, 0};

    // When unsetting bindgroup, it is invalid if dynamicOffsetsCount > 0.
    TestDynamicOffsetCount(2, offsets.data(), false);

    // When unsetting bindgroup, it is valid if dynamicOffsets is non-null and dynamicOffsetsCount
    // is 0.
    TestDynamicOffsetCount(0, offsets.data(), true);
}

// Test that a pipeline with empty bindgroups layouts doesn't need empty bindgroups to be set.
TEST_F(SetBindGroupValidationTest, EmptyBindGroupsAreNotRequired) {
    wgpu::BindGroupLayout emptyBGL = utils::MakeBindGroupLayout(device, {});
    wgpu::PipelineLayout pl =
        utils::MakePipelineLayout(device, {emptyBGL, emptyBGL, emptyBGL, emptyBGL});

    wgpu::ComputePipelineDescriptor pipelineDesc;
    pipelineDesc.layout = pl;
    pipelineDesc.compute.module = utils::CreateShaderModule(device, R"(
        @compute @workgroup_size(1) fn main() {
        }
    )");
    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&pipelineDesc);

    wgpu::BindGroup emptyBindGroup = utils::MakeBindGroup(device, emptyBGL, {});

    // Setting 4 empty bindgroups works.
    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(0, emptyBindGroup);
        pass.SetBindGroup(1, emptyBindGroup);
        pass.SetBindGroup(2, emptyBindGroup);
        pass.SetBindGroup(3, emptyBindGroup);
        pass.DispatchWorkgroups(1);
        pass.End();
        encoder.Finish();
    }

    // Setting only the first three empty bindgroups also works.
    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(0, emptyBindGroup);
        pass.SetBindGroup(1, emptyBindGroup);
        pass.SetBindGroup(2, emptyBindGroup);
        pass.DispatchWorkgroups(1);
        pass.End();
        encoder.Finish();
    }

    // Mixedly setting and unsetting empty bindgroups also works.
    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(1, emptyBindGroup);
        pass.SetBindGroup(3, emptyBindGroup);
        pass.DispatchWorkgroups(1);
        pass.End();
        encoder.Finish();
    }
}

// Test that a static sampler is valid to access from a shader module.
TEST_F(SetBindGroupValidationTest, StaticSamplerAccessedFromShader) {
    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.visibility = wgpu::ShaderStage::Compute;
    wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
    staticSamplerBinding.sampler = device.CreateSampler();
    binding.nextInChain = &staticSamplerBinding;

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

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

    wgpu::PipelineLayout pl = utils::MakePipelineLayout(device, {layout});

    wgpu::ComputePipelineDescriptor pipelineDesc;
    pipelineDesc.layout = pl;
    pipelineDesc.compute.module = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var s : sampler;
        @compute @workgroup_size(1) fn main() {
            _ = s;
        }
    )");
    device.CreateComputePipeline(&pipelineDesc);
}

// Test that a static sampler cannot be accessed from a shader module as a
// non-sampler variable type.
TEST_F(SetBindGroupValidationTest, StaticSamplerAccessedFromShaderAsNonSamplerTypeCausesError) {
    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.visibility = wgpu::ShaderStage::Compute;
    wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
    staticSamplerBinding.sampler = device.CreateSampler();
    binding.nextInChain = &staticSamplerBinding;

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

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

    wgpu::PipelineLayout pl = utils::MakePipelineLayout(device, {layout});

    wgpu::ComputePipelineDescriptor pipelineDesc;
    pipelineDesc.layout = pl;
    pipelineDesc.compute.module = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var t : texture_2d<f32>;
        @compute @workgroup_size(1) fn main() {
            _ = textureDimensions(t);
        }
    )");
    ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&pipelineDesc));
}

class SetBindGroupPersistenceValidationTest : public ValidationTest {
  protected:
    void SetUp() override {
        ValidationTest::SetUp();

        mVsModule = utils::CreateShaderModule(device, R"(
                @vertex fn main() -> @builtin(position) vec4f {
                    return vec4f();
                })");

        mBufferSize = 3 * GetSupportedLimits().minUniformBufferOffsetAlignment + 8;
    }

    wgpu::Buffer CreateBuffer(uint64_t bufferSize, wgpu::BufferUsage usage) {
        wgpu::BufferDescriptor bufferDescriptor;
        bufferDescriptor.size = bufferSize;
        bufferDescriptor.usage = usage;

        return device.CreateBuffer(&bufferDescriptor);
    }

    // Generates bind group layouts and a pipeline from a 2D list of binding types.
    std::tuple<std::vector<wgpu::BindGroupLayout>, wgpu::RenderPipeline> SetUpLayoutsAndPipeline(
        std::vector<std::vector<wgpu::BufferBindingType>> layouts) {
        std::vector<wgpu::BindGroupLayout> bindGroupLayouts(layouts.size());

        // Iterate through the desired bind group layouts.
        for (uint32_t l = 0; l < layouts.size(); ++l) {
            const auto& layout = layouts[l];
            std::vector<wgpu::BindGroupLayoutEntry> bindings(layout.size());

            // Iterate through binding types and populate a list of BindGroupLayoutEntrys.
            for (uint32_t b = 0; b < layout.size(); ++b) {
                bindings[b] = utils::BindingLayoutEntryInitializationHelper(
                    b, wgpu::ShaderStage::Fragment, layout[b]);
            }

            // Create the bind group layout.
            wgpu::BindGroupLayoutDescriptor bglDescriptor;
            bglDescriptor.entryCount = bindings.size();
            bglDescriptor.entries = bindings.data();
            bindGroupLayouts[l] = device.CreateBindGroupLayout(&bglDescriptor);
        }

        // Create a pipeline layout from the list of bind group layouts.
        wgpu::PipelineLayoutDescriptor pipelineLayoutDescriptor;
        pipelineLayoutDescriptor.bindGroupLayoutCount = bindGroupLayouts.size();
        pipelineLayoutDescriptor.bindGroupLayouts = bindGroupLayouts.data();

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

        std::stringstream ss;
        ss << "struct S { value : vec2f }";

        // Build a shader which has bindings that match the pipeline layout.
        for (uint32_t l = 0; l < layouts.size(); ++l) {
            const auto& layout = layouts[l];

            for (uint32_t b = 0; b < layout.size(); ++b) {
                wgpu::BufferBindingType binding = layout[b];
                ss << "@group(" << l << ") @binding(" << b << ") ";
                switch (binding) {
                    case wgpu::BufferBindingType::Storage:
                        ss << "var<storage, read_write> set" << l << "_binding" << b << " : S;";
                        break;
                    case wgpu::BufferBindingType::Uniform:
                        ss << "var<uniform> set" << l << "_binding" << b << " : S;";
                        break;
                    default:
                        DAWN_UNREACHABLE();
                }
            }
        }

        ss << "@fragment fn main() {}";

        wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, ss.str().c_str());

        utils::ComboRenderPipelineDescriptor pipelineDescriptor;
        pipelineDescriptor.vertex.module = mVsModule;
        pipelineDescriptor.cFragment.module = fsModule;
        pipelineDescriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;
        pipelineDescriptor.layout = pipelineLayout;
        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDescriptor);

        return std::make_tuple(bindGroupLayouts, pipeline);
    }

  protected:
    uint32_t mBufferSize;

  private:
    wgpu::ShaderModule mVsModule;
};

// Test it is valid to set bind groups before setting the pipeline.
TEST_F(SetBindGroupPersistenceValidationTest, BindGroupBeforePipeline) {
    auto [bindGroupLayouts, pipeline] = SetUpLayoutsAndPipeline({{
        {{
            wgpu::BufferBindingType::Uniform,
            wgpu::BufferBindingType::Uniform,
        }},
        {{
            wgpu::BufferBindingType::Storage,
            wgpu::BufferBindingType::Uniform,
        }},
    }});

    wgpu::Buffer uniformBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Uniform);
    wgpu::Buffer storageBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Storage);

    wgpu::BindGroup bindGroup0 = utils::MakeBindGroup(
        device, bindGroupLayouts[0],
        {{0, uniformBuffer, 0, kBindingSize}, {1, uniformBuffer, 0, kBindingSize}});

    wgpu::BindGroup bindGroup1 = utils::MakeBindGroup(
        device, bindGroupLayouts[1],
        {{0, storageBuffer, 0, kBindingSize}, {1, uniformBuffer, 0, kBindingSize}});

    PlaceholderRenderPass renderPass(device);
    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);

    renderPassEncoder.SetBindGroup(0, bindGroup0);
    renderPassEncoder.SetBindGroup(1, bindGroup1);
    renderPassEncoder.SetPipeline(pipeline);
    renderPassEncoder.Draw(3);

    renderPassEncoder.End();
    commandEncoder.Finish();
}

// Dawn does not have a concept of bind group inheritance though the backing APIs may.
// Test that it is valid to draw with bind groups that are not "inherited". They persist
// after a pipeline change.
TEST_F(SetBindGroupPersistenceValidationTest, NotVulkanInheritance) {
    auto [bindGroupLayoutsA, pipelineA] = SetUpLayoutsAndPipeline({{
        {{
            wgpu::BufferBindingType::Uniform,
            wgpu::BufferBindingType::Storage,
        }},
        {{
            wgpu::BufferBindingType::Uniform,
            wgpu::BufferBindingType::Uniform,
        }},
    }});

    auto [bindGroupLayoutsB, pipelineB] = SetUpLayoutsAndPipeline({{
        {{
            wgpu::BufferBindingType::Storage,
            wgpu::BufferBindingType::Uniform,
        }},
        {{
            wgpu::BufferBindingType::Uniform,
            wgpu::BufferBindingType::Uniform,
        }},
    }});

    wgpu::Buffer uniformBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Uniform);
    wgpu::Buffer storageBuffer = CreateBuffer(mBufferSize, wgpu::BufferUsage::Storage);

    wgpu::BindGroup bindGroupA0 = utils::MakeBindGroup(
        device, bindGroupLayoutsA[0],
        {{0, uniformBuffer, 0, kBindingSize}, {1, storageBuffer, 0, kBindingSize}});

    wgpu::BindGroup bindGroupA1 = utils::MakeBindGroup(
        device, bindGroupLayoutsA[1],
        {{0, uniformBuffer, 0, kBindingSize}, {1, uniformBuffer, 0, kBindingSize}});

    wgpu::BindGroup bindGroupB0 = utils::MakeBindGroup(
        device, bindGroupLayoutsB[0],
        {{0, storageBuffer, 0, kBindingSize}, {1, uniformBuffer, 0, kBindingSize}});

    PlaceholderRenderPass renderPass(device);
    wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
    wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);

    renderPassEncoder.SetPipeline(pipelineA);
    renderPassEncoder.SetBindGroup(0, bindGroupA0);
    renderPassEncoder.SetBindGroup(1, bindGroupA1);
    renderPassEncoder.Draw(3);

    renderPassEncoder.SetPipeline(pipelineB);
    renderPassEncoder.SetBindGroup(0, bindGroupB0);
    // This draw is valid.
    // Bind group 1 persists even though it is not "inherited".
    renderPassEncoder.Draw(3);

    renderPassEncoder.End();
    commandEncoder.Finish();
}

class BindGroupLayoutCompatibilityTest : public ValidationTest {
  public:
    wgpu::Buffer CreateBuffer(uint64_t bufferSize, wgpu::BufferUsage usage) {
        wgpu::BufferDescriptor bufferDescriptor;
        bufferDescriptor.size = bufferSize;
        bufferDescriptor.usage = usage;

        return device.CreateBuffer(&bufferDescriptor);
    }

    wgpu::RenderPipeline CreateFSRenderPipeline(
        const char* fsShader,
        std::vector<wgpu::BindGroupLayout> bindGroupLayout) {
        wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
                @vertex fn main() -> @builtin(position) vec4f {
                    return vec4f();
                })");

        wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, fsShader);

        wgpu::PipelineLayoutDescriptor descriptor;
        descriptor.bindGroupLayoutCount = bindGroupLayout.size();
        descriptor.bindGroupLayouts = bindGroupLayout.data();
        utils::ComboRenderPipelineDescriptor pipelineDescriptor;
        pipelineDescriptor.vertex.module = vsModule;
        pipelineDescriptor.cFragment.module = fsModule;
        pipelineDescriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;
        wgpu::PipelineLayout pipelineLayout = device.CreatePipelineLayout(&descriptor);
        pipelineDescriptor.layout = pipelineLayout;
        return device.CreateRenderPipeline(&pipelineDescriptor);
    }

    wgpu::RenderPipeline CreateRenderPipeline(std::vector<wgpu::BindGroupLayout> bindGroupLayouts) {
        return CreateFSRenderPipeline(R"(
            struct S {
                value : vec2f
            }

            @group(0) @binding(0) var<storage, read_write> sBufferDynamic : S;
            @group(1) @binding(0) var<storage, read> sReadonlyBufferDynamic : S;

            @fragment fn main() {
                var val : vec2f = sBufferDynamic.value;
                val = sReadonlyBufferDynamic.value;
            })",
                                      std::move(bindGroupLayouts));
    }

    wgpu::ComputePipeline CreateComputePipeline(
        const char* shader,
        std::vector<wgpu::BindGroupLayout> bindGroupLayout) {
        wgpu::ShaderModule csModule = utils::CreateShaderModule(device, shader);

        wgpu::PipelineLayoutDescriptor descriptor;
        descriptor.bindGroupLayoutCount = bindGroupLayout.size();
        descriptor.bindGroupLayouts = bindGroupLayout.data();
        wgpu::PipelineLayout pipelineLayout = device.CreatePipelineLayout(&descriptor);

        wgpu::ComputePipelineDescriptor csDesc;
        csDesc.layout = pipelineLayout;
        csDesc.compute.module = csModule;

        return device.CreateComputePipeline(&csDesc);
    }

    wgpu::ComputePipeline CreateComputePipeline(
        std::vector<wgpu::BindGroupLayout> bindGroupLayouts) {
        return CreateComputePipeline(R"(
            struct S {
                value : vec2f
            }

            @group(0) @binding(0) var<storage, read_write> sBufferDynamic : S;
            @group(1) @binding(0) var<storage, read> sReadonlyBufferDynamic : S;

            @compute @workgroup_size(4, 4, 1) fn main() {
                var val : vec2f = sBufferDynamic.value;
                val = sReadonlyBufferDynamic.value;
            })",
                                     std::move(bindGroupLayouts));
    }
};

// Test that it is invalid to pass a writable storage buffer in the pipeline layout when the shader
// uses the binding as a readonly storage buffer.
TEST_F(BindGroupLayoutCompatibilityTest, RWStorageInBGLWithROStorageInShader) {
    // Set up the bind group layout.
    wgpu::BindGroupLayout bgl0 = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                  wgpu::BufferBindingType::Storage}});
    wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                  wgpu::BufferBindingType::Storage}});

    ASSERT_DEVICE_ERROR(CreateRenderPipeline({bgl0, bgl1}));

    ASSERT_DEVICE_ERROR(CreateComputePipeline({bgl0, bgl1}));
}

// Test that it is invalid to pass a readonly storage buffer in the pipeline layout when the shader
// uses the binding as a writable storage buffer.
TEST_F(BindGroupLayoutCompatibilityTest, ROStorageInBGLWithRWStorageInShader) {
    // Set up the bind group layout.
    wgpu::BindGroupLayout bgl0 = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                  wgpu::BufferBindingType::ReadOnlyStorage}});
    wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                  wgpu::BufferBindingType::ReadOnlyStorage}});

    ASSERT_DEVICE_ERROR(CreateRenderPipeline({bgl0, bgl1}));

    ASSERT_DEVICE_ERROR(CreateComputePipeline({bgl0, bgl1}));
}

TEST_F(BindGroupLayoutCompatibilityTest, TextureViewDimension) {
    constexpr char kTexture2DShaderFS[] = R"(
        @group(0) @binding(0) var myTexture : texture_2d<f32>;
        @fragment fn main() {
            _ = textureDimensions(myTexture);
        })";
    constexpr char kTexture2DShaderCS[] = R"(
        @group(0) @binding(0) var myTexture : texture_2d<f32>;
        @compute @workgroup_size(1) fn main() {
            _ = textureDimensions(myTexture);
        })";

    // Render: Test that 2D texture with 2D view dimension works
    CreateFSRenderPipeline(
        kTexture2DShaderFS,
        {utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float,
                      wgpu::TextureViewDimension::e2D}})});

    // Render: Test that 2D texture with 2D array view dimension is invalid
    ASSERT_DEVICE_ERROR(CreateFSRenderPipeline(
        kTexture2DShaderFS,
        {utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float,
                      wgpu::TextureViewDimension::e2DArray}})}));

    // Compute: Test that 2D texture with 2D view dimension works
    CreateComputePipeline(
        kTexture2DShaderCS,
        {utils::MakeBindGroupLayout(device,
                                    {{0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float,
                                      wgpu::TextureViewDimension::e2D}})});

    // Compute: Test that 2D texture with 2D array view dimension is invalid
    ASSERT_DEVICE_ERROR(CreateComputePipeline(
        kTexture2DShaderCS,
        {utils::MakeBindGroupLayout(device,
                                    {{0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float,
                                      wgpu::TextureViewDimension::e2DArray}})}));

    constexpr char kTexture2DArrayShaderFS[] = R"(
        @group(0) @binding(0) var myTexture : texture_2d_array<f32>;
        @fragment fn main() {
            _ = textureDimensions(myTexture);
        })";
    constexpr char kTexture2DArrayShaderCS[] = R"(
        @group(0) @binding(0) var myTexture : texture_2d_array<f32>;
        @compute @workgroup_size(1) fn main() {
            _ = textureDimensions(myTexture);
        })";

    // Render: Test that 2D texture array with 2D array view dimension works
    CreateFSRenderPipeline(
        kTexture2DArrayShaderFS,
        {utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float,
                      wgpu::TextureViewDimension::e2DArray}})});

    // Render: Test that 2D texture array with 2D view dimension is invalid
    ASSERT_DEVICE_ERROR(CreateFSRenderPipeline(
        kTexture2DArrayShaderFS,
        {utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float,
                      wgpu::TextureViewDimension::e2D}})}));

    // Compute: Test that 2D texture array with 2D array view dimension works
    CreateComputePipeline(
        kTexture2DArrayShaderCS,
        {utils::MakeBindGroupLayout(device,
                                    {{0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float,
                                      wgpu::TextureViewDimension::e2DArray}})});

    // Compute: Test that 2D texture array with 2D view dimension is invalid
    ASSERT_DEVICE_ERROR(CreateComputePipeline(
        kTexture2DArrayShaderCS,
        {utils::MakeBindGroupLayout(device,
                                    {{0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float,
                                      wgpu::TextureViewDimension::e2D}})}));
}

// Test that a bgl with an external texture is compatible with texture_external in a shader and that
// an error is returned when the binding in the shader does not match.
TEST_F(BindGroupLayoutCompatibilityTest, ExternalTextureBindGroupLayoutCompatibility) {
    wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});

    // Test that an external texture binding works with a texture_external in the shader.
    CreateFSRenderPipeline(R"(
            @group(0) @binding(0) var myExternalTexture: texture_external;
            @fragment fn main() {
                _ = myExternalTexture;
            })",
                           {bgl});

    // Test that an external texture binding doesn't work with a texture_2d<f32> in the shader.
    ASSERT_DEVICE_ERROR(CreateFSRenderPipeline(R"(
            @group(0) @binding(0) var myTexture: texture_2d<f32>;
            @fragment fn main() {
                _ = myTexture;
            })",
                                               {bgl}));
}

// Test that the ExternalTexture in the BGL must have visibility that's a superset of the shader.
TEST_F(BindGroupLayoutCompatibilityTest, ExternalTextureLayoutVisibility) {
    const char shader[] = R"(
        @group(0) @binding(0) var myExternalTexture: texture_external;
        @fragment fn main() {
            _ = myExternalTexture;
        })";

    // Success case, visibility in the BGL contains Fragment.
    wgpu::BindGroupLayout bglFragment = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});
    CreateFSRenderPipeline(shader, {bglFragment});

    // Error case, visibility in the BGL doesn't have Fragment.
    wgpu::BindGroupLayout bglCompute = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute, &utils::kExternalTextureBindingLayout}});
    ASSERT_DEVICE_ERROR(CreateFSRenderPipeline(shader, {bglCompute}));
}

// Test that a BGL is compatible with a pipeline if a binding's array size is at least as big as the
// shader's binding_array's size.
TEST_F(BindGroupLayoutCompatibilityTest, ArraySizeCompatibility) {
    wgpu::BindGroupLayoutEntry entry;
    entry.binding = 0;
    entry.visibility = wgpu::ShaderStage::Fragment;
    entry.texture.sampleType = wgpu::TextureSampleType::Float;

    wgpu::BindGroupLayoutDescriptor bglDesc;
    bglDesc.entryCount = 1;
    bglDesc.entries = &entry;
    wgpu::BindGroupLayout bglNoArray = device.CreateBindGroupLayout(&bglDesc);

    entry.bindingArraySize = 1;
    wgpu::BindGroupLayout bglArray1 = device.CreateBindGroupLayout(&bglDesc);

    entry.bindingArraySize = 2;
    wgpu::BindGroupLayout bglArray2 = device.CreateBindGroupLayout(&bglDesc);

    entry.bindingArraySize = 3;
    wgpu::BindGroupLayout bglArray3 = device.CreateBindGroupLayout(&bglDesc);

    // Test that a BGL with bindingArraySize 2 is valid for binding_array<T, 2>
    CreateFSRenderPipeline(R"(
            @group(0) @binding(0) var t : binding_array<texture_2d<f32>, 2>;
            @fragment fn main() {
                _ = t[0];
            })",
                           {bglArray2});
    // Test that a BGL with a bigger bindingArraySize is valid.
    CreateFSRenderPipeline(R"(
            @group(0) @binding(0) var t : binding_array<texture_2d<f32>, 2>;
            @fragment fn main() {
                _ = t[0];
            })",
                           {bglArray3});
    // Test that a BGL with a smaller bindingArraySize is an error.
    ASSERT_DEVICE_ERROR(CreateFSRenderPipeline(R"(
            @group(0) @binding(0) var t : binding_array<texture_2d<f32>, 2>;
            @fragment fn main() {
                _ = t[0];
            })",
                                               {bglArray1}));

    // Test that an array of size 1 BGL is valid for a single binding.
    CreateFSRenderPipeline(R"(
            @group(0) @binding(0) var t : texture_2d<f32>;
            @fragment fn main() {
                _ = t;
            })",
                           {bglArray1});
    // Test that an array of size 2 BGL is valid for a single binding at the start of the array.
    CreateFSRenderPipeline(R"(
            @group(0) @binding(0) var t : texture_2d<f32>;
            @fragment fn main() {
                _ = t;
            })",
                           {bglArray2});
    // Test that the single binding cannot be an element from the arrayed BGL except the first
    ASSERT_DEVICE_ERROR(CreateFSRenderPipeline(R"(
            @group(0) @binding(1) var t : texture_2d<f32>;
            @fragment fn main() {
                _ = t;
            })",
                                               {bglArray2}));
    // Test that a binding_array<T, 1> bindings can be fulfilled by a non-arrayed BGL.
    CreateFSRenderPipeline(R"(
            @group(0) @binding(0) var t : binding_array<texture_2d<f32>, 1>;
            @fragment fn main() {
                _ = t[0];
            })",
                           {bglNoArray});
}

class BindingsValidationTest : public BindGroupLayoutCompatibilityTest {
  public:
    void SetUp() override {
        BindGroupLayoutCompatibilityTest::SetUp();
        mBufferSize = 3 * GetSupportedLimits().minUniformBufferOffsetAlignment + 8;
    }

    void TestRenderPassBindings(const wgpu::BindGroup* bg,
                                uint32_t count,
                                wgpu::RenderPipeline pipeline,
                                bool expectation) {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        PlaceholderRenderPass PlaceholderRenderPass(device);
        wgpu::RenderPassEncoder rp = encoder.BeginRenderPass(&PlaceholderRenderPass);
        for (uint32_t i = 0; i < count; ++i) {
            rp.SetBindGroup(i, bg[i]);
        }
        rp.SetPipeline(pipeline);
        rp.Draw(3);
        rp.End();
        if (!expectation) {
            ASSERT_DEVICE_ERROR(encoder.Finish());
        } else {
            encoder.Finish();
        }
    }

    void TestComputePassBindings(const wgpu::BindGroup* bg,
                                 uint32_t count,
                                 wgpu::ComputePipeline pipeline,
                                 bool expectation) {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder cp = encoder.BeginComputePass();
        for (uint32_t i = 0; i < count; ++i) {
            cp.SetBindGroup(i, bg[i]);
        }
        cp.SetPipeline(pipeline);
        cp.DispatchWorkgroups(1);
        cp.End();
        if (!expectation) {
            ASSERT_DEVICE_ERROR(encoder.Finish());
        } else {
            encoder.Finish();
        }
    }

    uint32_t mBufferSize;
    static constexpr uint32_t kBindingNum = 3;
};

// Test that it is valid to set a pipeline layout with bindings unused by the pipeline.
TEST_F(BindingsValidationTest, PipelineLayoutWithMoreBindingsThanPipeline) {
    // Set up bind group layouts.
    wgpu::BindGroupLayout bgl0 = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                  wgpu::BufferBindingType::Storage},
                 {1, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                  wgpu::BufferBindingType::Uniform}});
    wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                  wgpu::BufferBindingType::ReadOnlyStorage}});
    wgpu::BindGroupLayout bgl2 = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                  wgpu::BufferBindingType::Storage}});

    // pipelineLayout has unused binding set (bgl2) and unused entry in a binding set (bgl0).
    CreateRenderPipeline({bgl0, bgl1, bgl2});

    CreateComputePipeline({bgl0, bgl1, bgl2});
}

// Test that it is invalid to set a pipeline layout that doesn't have all necessary bindings
// required by the pipeline.
TEST_F(BindingsValidationTest, PipelineLayoutWithFewerBindingsThanPipeline) {
    // Set up bind group layout.
    wgpu::BindGroupLayout bgl0 = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                  wgpu::BufferBindingType::Storage}});

    // missing a binding set (bgl1) in pipeline layout
    {
        ASSERT_DEVICE_ERROR(CreateRenderPipeline({bgl0}));

        ASSERT_DEVICE_ERROR(CreateComputePipeline({bgl0}));
    }

    // bgl1 is not missing, but it is empty
    {
        wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(device, {});

        ASSERT_DEVICE_ERROR(CreateRenderPipeline({bgl0, bgl1}));

        ASSERT_DEVICE_ERROR(CreateComputePipeline({bgl0, bgl1}));
    }

    // bgl1 is neither missing nor empty, but it doesn't contain the necessary binding
    {
        wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
            device, {{1, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                      wgpu::BufferBindingType::Uniform}});

        ASSERT_DEVICE_ERROR(CreateRenderPipeline({bgl0, bgl1}));

        ASSERT_DEVICE_ERROR(CreateComputePipeline({bgl0, bgl1}));
    }
}

// Test that it is valid to set bind groups whose layout is not set in the pipeline layout.
// But it's invalid to set extra entry for a given bind group's layout if that layout is set in
// the pipeline layout.
TEST_F(BindingsValidationTest, BindGroupsWithMoreBindingsThanPipelineLayout) {
    // Set up bind group layouts, buffers, bind groups, pipeline layouts and pipelines.
    std::array<wgpu::BindGroupLayout, kBindingNum + 1> bgl;
    std::array<wgpu::BindGroup, kBindingNum + 1> bg;
    std::array<wgpu::Buffer, kBindingNum + 1> buffer;
    for (uint32_t i = 0; i < kBindingNum + 1; ++i) {
        bgl[i] = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                      i == 1 ? wgpu::BufferBindingType::ReadOnlyStorage
                             : wgpu::BufferBindingType::Storage}});
        buffer[i] = CreateBuffer(mBufferSize, wgpu::BufferUsage::Storage);
        bg[i] = utils::MakeBindGroup(device, bgl[i], {{0, buffer[i]}});
    }

    // Set 3 bindings (and 3 pipeline layouts) in pipeline.
    wgpu::RenderPipeline renderPipeline = CreateRenderPipeline({bgl[0], bgl[1], bgl[2]});
    wgpu::ComputePipeline computePipeline = CreateComputePipeline({bgl[0], bgl[1], bgl[2]});

    // Comprared to pipeline layout, there is an extra bind group (bg[3])
    TestRenderPassBindings(bg.data(), kBindingNum + 1, renderPipeline, true);

    TestComputePassBindings(bg.data(), kBindingNum + 1, computePipeline, true);

    // If a bind group has entry (like bgl1_1 below) unused by the pipeline layout, it is invalid.
    // Bind groups associated layout should exactly match bind group layout if that layout is
    // set in pipeline layout.
    bgl[1] = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                  wgpu::BufferBindingType::ReadOnlyStorage},
                 {1, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                  wgpu::BufferBindingType::Uniform}});
    buffer[1] = CreateBuffer(mBufferSize, wgpu::BufferUsage::Storage | wgpu::BufferUsage::Uniform);
    bg[1] = utils::MakeBindGroup(device, bgl[1], {{0, buffer[1]}, {1, buffer[1]}});

    TestRenderPassBindings(bg.data(), kBindingNum, renderPipeline, false);

    TestComputePassBindings(bg.data(), kBindingNum, computePipeline, false);
}

// Test that it is invalid to set bind groups that don't have all necessary bindings required
// by the pipeline layout. Note that both pipeline layout and bind group have enough bindings for
// pipeline in the following test.
TEST_F(BindingsValidationTest, BindGroupsWithFewerBindingsThanPipelineLayout) {
    // Set up bind group layouts, buffers, bind groups, pipeline layouts and pipelines.
    std::array<wgpu::BindGroupLayout, kBindingNum> bgl;
    std::array<wgpu::BindGroup, kBindingNum> bg;
    std::array<wgpu::Buffer, kBindingNum> buffer;
    for (uint32_t i = 0; i < kBindingNum; ++i) {
        bgl[i] = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                      i == 1 ? wgpu::BufferBindingType::ReadOnlyStorage
                             : wgpu::BufferBindingType::Storage}});
        buffer[i] = CreateBuffer(mBufferSize, wgpu::BufferUsage::Storage);
        bg[i] = utils::MakeBindGroup(device, bgl[i], {{0, buffer[i]}});
    }

    wgpu::RenderPipeline renderPipeline = CreateRenderPipeline({bgl[0], bgl[1], bgl[2]});
    wgpu::ComputePipeline computePipeline = CreateComputePipeline({bgl[0], bgl[1], bgl[2]});

    // Compared to pipeline layout, a binding set (bgl2) related bind group is missing
    TestRenderPassBindings(bg.data(), kBindingNum - 1, renderPipeline, false);

    TestComputePassBindings(bg.data(), kBindingNum - 1, computePipeline, false);

    // bgl[2] related bind group is not missing, but its bind group is empty
    bgl[2] = utils::MakeBindGroupLayout(device, {});
    bg[2] = utils::MakeBindGroup(device, bgl[2], {});

    TestRenderPassBindings(bg.data(), kBindingNum, renderPipeline, false);

    TestComputePassBindings(bg.data(), kBindingNum, computePipeline, false);

    // bgl[2] related bind group is neither missing nor empty, but it doesn't contain the necessary
    // binding
    bgl[2] = utils::MakeBindGroupLayout(
        device, {{1, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
                  wgpu::BufferBindingType::Uniform}});
    buffer[2] = CreateBuffer(mBufferSize, wgpu::BufferUsage::Uniform);
    bg[2] = utils::MakeBindGroup(device, bgl[2], {{1, buffer[2]}});

    TestRenderPassBindings(bg.data(), kBindingNum, renderPipeline, false);

    TestComputePassBindings(bg.data(), kBindingNum, computePipeline, false);
}

class FilterabilityValidationTest : public BindGroupLayoutCompatibilityTest {};

TEST_F(FilterabilityValidationTest, FilterableBGL_UnFilterableShader_Pass) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_2d<f32, unfilterable>;

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

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float},
                });
    CreateComputePipeline(shaderSource, {bgl});
}

TEST_F(FilterabilityValidationTest, FilterableBGL_FilterableShader_Pass) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_2d<f32, filterable>;

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

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float},
                });
    CreateComputePipeline(shaderSource, {bgl});
}

TEST_F(FilterabilityValidationTest, FilterableBGL_UnknownShader_Pass) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_2d<f32>;

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

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float},
                });
    CreateComputePipeline(shaderSource, {bgl});
}

TEST_F(FilterabilityValidationTest, UnfilterableBGL_UnFilterableShader_Pass) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_2d<f32, unfilterable>;

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

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::UnfilterableFloat},
                });
    CreateComputePipeline(shaderSource, {bgl});
}

TEST_F(FilterabilityValidationTest, UnfilterableBGL_FilterableShader_Fail) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_2d<f32, filterable>;

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

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::UnfilterableFloat},
                });

    ASSERT_DEVICE_ERROR(CreateComputePipeline(shaderSource, {bgl}),
                        testing::HasSubstr("isn't compatible"));
}

TEST_F(FilterabilityValidationTest, UnfilterableBGL_UnknownShader_Pass) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_2d<f32>;

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

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::UnfilterableFloat},
                });
    CreateComputePipeline(shaderSource, {bgl});
}

TEST_F(FilterabilityValidationTest, FilterableBGL_DepthShader_Fail) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_depth_2d;

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

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float},
                });

    ASSERT_DEVICE_ERROR(CreateComputePipeline(shaderSource, {bgl}),
                        testing::HasSubstr("isn't compatible"));
}

TEST_F(FilterabilityValidationTest, FilterableBGL_i32Shader_Fail) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_2d<i32>;

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

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float},
                });

    ASSERT_DEVICE_ERROR(CreateComputePipeline(shaderSource, {bgl}),
                        testing::HasSubstr("isn't compatible"));
}

TEST_F(FilterabilityValidationTest, FilteringBGL_FilteringShader_Pass) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_2d<f32>;
    @group(0) @binding(1) var samp : sampler<filtering>;

    @compute @workgroup_size(1) fn main() {
      _ = tex1;
      _ = samp;
    })";

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float},
                    {1, wgpu::ShaderStage::Compute, wgpu::SamplerBindingType::Filtering},
                });
    CreateComputePipeline(shaderSource, {bgl});
}

TEST_F(FilterabilityValidationTest, FilteringBGL_NonFilteringShader_Pass) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_2d<f32>;
    @group(0) @binding(1) var samp : sampler<non_filtering>;

    @compute @workgroup_size(1) fn main() {
      _ = tex1;
      _ = samp;
    })";

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float},
                    {1, wgpu::ShaderStage::Compute, wgpu::SamplerBindingType::Filtering},
                });
    CreateComputePipeline(shaderSource, {bgl});
}

TEST_F(FilterabilityValidationTest, NonFilteringBGL_NonFilteringShader_Pass) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_2d<f32>;
    @group(0) @binding(1) var samp : sampler<non_filtering>;

    @compute @workgroup_size(1) fn main() {
      _ = tex1;
      _ = samp;
    })";

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float},
                    {1, wgpu::ShaderStage::Compute, wgpu::SamplerBindingType::NonFiltering},
                });
    CreateComputePipeline(shaderSource, {bgl});
}

TEST_F(FilterabilityValidationTest, NonFilteringBGL_FilteringShader_Fail) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_2d<f32>;
    @group(0) @binding(1) var samp : sampler<filtering>;

    @compute @workgroup_size(1) fn main() {
      _ = tex1;
      _ = samp;
    })";

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float},
                    {1, wgpu::ShaderStage::Compute, wgpu::SamplerBindingType::NonFiltering},
                });

    ASSERT_DEVICE_ERROR(CreateComputePipeline(shaderSource, {bgl}),
                        testing::HasSubstr("doesn't match"));
}

TEST_F(FilterabilityValidationTest, ComparisonBGL_ComparisonShader_Pass) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_2d<f32>;
    @group(0) @binding(1) var samp : sampler_comparison;

    @compute @workgroup_size(1) fn main() {
      _ = tex1;
      _ = samp;
    })";

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float},
                    {1, wgpu::ShaderStage::Compute, wgpu::SamplerBindingType::Comparison},
                });
    CreateComputePipeline(shaderSource, {bgl});
}

TEST_F(FilterabilityValidationTest, ComparisonBGL_FilteringShader_Fail) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_2d<f32>;
    @group(0) @binding(1) var samp : sampler<filtering>;

    @compute @workgroup_size(1) fn main() {
      _ = tex1;
      _ = samp;
    })";

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float},
                    {1, wgpu::ShaderStage::Compute, wgpu::SamplerBindingType::Comparison},
                });
    ASSERT_DEVICE_ERROR(
        CreateComputePipeline(shaderSource, {bgl}),
        testing::HasSubstr("(SamplerBindingType::Filtering) doesn't match the type in the layout "
                           "(SamplerBindingType::Comparison"));
}

TEST_F(FilterabilityValidationTest, ComparisonBGL_NonFilteringShader_Fail) {
    auto shaderSource = R"(
    @group(0) @binding(0) var tex1 : texture_2d<f32>;
    @group(0) @binding(1) var samp : sampler<non_filtering>;

    @compute @workgroup_size(1) fn main() {
      _ = tex1;
      _ = samp;
    })";

    auto bgl = utils::MakeBindGroupLayout(
        device, {
                    {0, wgpu::ShaderStage::Compute, wgpu::TextureSampleType::Float},
                    {1, wgpu::ShaderStage::Compute, wgpu::SamplerBindingType::Comparison},
                });

    ASSERT_DEVICE_ERROR(
        CreateComputePipeline(shaderSource, {bgl}),
        testing::HasSubstr(
            "(SamplerBindingType::NonFiltering) doesn't match the type in the layout "
            "(SamplerBindingType::Comparison"));
}

class SamplerTypeBindingTest : public ValidationTest {
  protected:
    wgpu::RenderPipeline CreateFragmentPipeline(wgpu::BindGroupLayout* bindGroupLayout,
                                                const char* fragmentSource) {
        wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
            @vertex fn main() -> @builtin(position) vec4f {
                return vec4f();
            })");

        wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, fragmentSource);

        utils::ComboRenderPipelineDescriptor pipelineDescriptor;
        pipelineDescriptor.vertex.module = vsModule;
        pipelineDescriptor.cFragment.module = fsModule;
        pipelineDescriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;
        wgpu::PipelineLayout pipelineLayout =
            utils::MakeBasicPipelineLayout(device, bindGroupLayout);
        pipelineDescriptor.layout = pipelineLayout;
        return device.CreateRenderPipeline(&pipelineDescriptor);
    }
};

// Test that the use of sampler and comparison_sampler in the shader must match the bind group
// layout.
TEST_F(SamplerTypeBindingTest, ShaderAndBGLMatches) {
    // Test that a filtering sampler binding works with normal sampler in the shader.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering}});

        CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler;
            @fragment fn main() {
                _ = mySampler;
            })");
    }

    // Test that a non-filtering sampler binding works with normal sampler in the shader.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering}});

        CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler;
            @fragment fn main() {
                _ = mySampler;
            })");
    }

    // Test that comparison sampler binding works with comparison sampler in the shader.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Comparison}});

        CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler_comparison;
            @fragment fn main() {
                _ = mySampler;
            })");
    }

    // Test that filtering sampler binding does not work with comparison sampler in the shader.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering}});

        ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler_comparison;
            @fragment fn main() {
                _ = mySampler;
            })"));
    }

    // Test that non-filtering sampler binding does not work with comparison sampler in the shader.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering}});

        ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler_comparison;
            @fragment fn main() {
                _ = mySampler;
            })"));
    }

    // Test that comparison sampler binding does not work with normal sampler in the shader.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Comparison}});

        ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler;
            @fragment fn main() {
                _ = mySampler;
            })"));
    }

    // Test that a filtering sampler can be used to sample a float texture.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering},
                     {1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}});

        CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler;
            @group(0) @binding(1) var myTexture: texture_2d<f32>;
            @fragment fn main() {
                _ = textureSample(myTexture, mySampler, vec2f(0.0, 0.0));
            })");
    }

    // Test that a non-filtering sampler can be used to sample a float texture.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering},
                     {1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}});

        CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler;
            @group(0) @binding(1) var myTexture: texture_2d<f32>;
            @fragment fn main() {
                _ = textureSample(myTexture, mySampler, vec2f(0.0, 0.0));
            })");
    }

    // Test that a filtering sampler can not be used to sample a depth texture.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering},
                     {1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Depth}});

        ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler;
            @group(0) @binding(1) var myTexture: texture_depth_2d;
            @fragment fn main() {
                _ = textureSample(myTexture, mySampler, vec2f(0.0, 0.0));
            })"));
    }

    // Test that a non-filtering sampler can be used to sample a depth texture.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering},
                     {1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Depth}});

        CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler;
            @group(0) @binding(1) var myTexture: texture_depth_2d;
            @fragment fn main() {
                _ = textureSample(myTexture, mySampler, vec2f(0.0, 0.0));
            })");
    }

    // Test that a comparison sampler can be used to sample a depth texture.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Comparison},
                     {1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Depth}});

        CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler_comparison;
            @group(0) @binding(1) var myTexture: texture_depth_2d;
            @fragment fn main() {
                _ = textureSampleCompare(myTexture, mySampler, vec2f(0.0, 0.0), 0.0);
            })");
    }

    // Test that a filtering sampler cannot be used to sample an unfilterable-float texture.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering},
                     {1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::UnfilterableFloat}});

        ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler;
            @group(0) @binding(1) var myTexture: texture_2d<f32>;
            @fragment fn main() {
                _ = textureSample(myTexture, mySampler, vec2f(0.0, 0.0));
            })"));
    }

    // Test that a non-filtering sampler can be used to sample an unfilterable-float texture.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering},
                     {1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::UnfilterableFloat}});

        CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler;
            @group(0) @binding(1) var myTexture: texture_2d<f32>;
            @fragment fn main() {
                _ = textureSample(myTexture, mySampler, vec2f(0.0, 0.0));
            })");
    }

    // Test that a filtering sampler can not be used to sample an sint texture.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering},
                     {1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Sint}});

        ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler;
            @group(0) @binding(1) var myTexture: texture_2d<i32>;
            @fragment fn main() {
                _ = textureGather(0, myTexture, mySampler, vec2f(0.0, 0.0));
            })"));
    }

    // Test that a non-filtering sampler can be used to sample an sint texture.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering},
                     {1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Sint}});

        CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler;
            @group(0) @binding(1) var myTexture: texture_2d<i32>;
            @fragment fn main() {
                _ = textureGather(0, myTexture, mySampler, vec2f(0.0, 0.0));
            })");
    }

    // Test that a filtering sampler can not be used to sample an uint texture.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering},
                     {1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Uint}});

        ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler;
            @group(0) @binding(1) var myTexture: texture_2d<u32>;
            @fragment fn main() {
                _ = textureGather(0, myTexture, mySampler, vec2f(0.0, 0.0));
            })"));
    }

    // Test that a non-filtering sampler can be used to sample an uint texture.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering},
                     {1, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Uint}});

        CreateFragmentPipeline(&bindGroupLayout, R"(
            @group(0) @binding(0) var mySampler: sampler;
            @group(0) @binding(1) var myTexture: texture_2d<u32>;
            @fragment fn main() {
                _ = textureGather(0, myTexture, mySampler, vec2f(0.0, 0.0));
            })");
    }
}

TEST_F(SamplerTypeBindingTest, SamplerAndBindGroupMatches) {
    // Test that sampler binding works with normal sampler.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering}});

        utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler()}});
    }

    // Test that comparison sampler binding works with sampler w/ compare function.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Comparison}});

        wgpu::SamplerDescriptor desc = {};
        desc.compare = wgpu::CompareFunction::Never;
        utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}});
    }

    // Test that sampler binding does not work with sampler w/ compare function.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering}});

        wgpu::SamplerDescriptor desc;
        desc.compare = wgpu::CompareFunction::Never;
        ASSERT_DEVICE_ERROR(
            utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}}));
    }

    // Test that comparison sampler binding does not work with normal sampler.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Comparison}});

        wgpu::SamplerDescriptor desc = {};
        ASSERT_DEVICE_ERROR(
            utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}}));
    }

    // Test that filtering sampler binding works with a filtering or non-filtering sampler.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering}});

        // Test each filter member
        {
            wgpu::SamplerDescriptor desc;
            desc.minFilter = wgpu::FilterMode::Linear;
            utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}});
        }
        {
            wgpu::SamplerDescriptor desc;
            desc.magFilter = wgpu::FilterMode::Linear;
            utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}});
        }
        {
            wgpu::SamplerDescriptor desc;
            desc.mipmapFilter = wgpu::MipmapFilterMode::Linear;
            utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}});
        }

        // Test non-filtering sampler
        utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler()}});
    }

    // Test that non-filtering sampler binding does not work with a filtering sampler.
    {
        wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::NonFiltering}});

        // Test each filter member
        {
            wgpu::SamplerDescriptor desc;
            desc.minFilter = wgpu::FilterMode::Linear;
            ASSERT_DEVICE_ERROR(
                utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}}));
        }
        {
            wgpu::SamplerDescriptor desc;
            desc.magFilter = wgpu::FilterMode::Linear;
            ASSERT_DEVICE_ERROR(
                utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}}));
        }
        {
            wgpu::SamplerDescriptor desc;
            desc.mipmapFilter = wgpu::MipmapFilterMode::Linear;
            ASSERT_DEVICE_ERROR(
                utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler(&desc)}}));
        }

        // Test non-filtering sampler
        utils::MakeBindGroup(device, bindGroupLayout, {{0, device.CreateSampler()}});
    }
}

class PipelineLayoutValidationTest : public ValidationTest {};

// Test creating pipeline layout with null bind group layout works when unsafe APIs are allowed.
TEST_F(PipelineLayoutValidationTest, CreateWithNullBindGroupLayout) {
    for (uint32_t nullBGLIndex = 0; nullBGLIndex < 4; ++nullBGLIndex) {
        std::vector<wgpu::BindGroupLayout> bgls(4);
        for (uint32_t i = 0; i < 4; ++i) {
            if (i == nullBGLIndex) {
                continue;
            }
            bgls[i] = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::StorageTextureAccess::WriteOnly,
                          wgpu::TextureFormat::R32Float}});
        }
        utils::MakePipelineLayout(device, bgls);
    }
}

// Test the pipeline layout with null bind group layout must match the corresponding binding in
// shader.
TEST_F(PipelineLayoutValidationTest, ShaderMatchesPipelineLayoutWithNullBindGroupLayout) {
    for (uint32_t nullBGLIndex = 0; nullBGLIndex < 4; ++nullBGLIndex) {
        std::vector<wgpu::BindGroupLayout> bgls(4);
        for (uint32_t i = 0; i < 4; ++i) {
            if (i == nullBGLIndex) {
                continue;
            }
            bgls[i] = utils::MakeBindGroupLayout(
                device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage}});
        }
        wgpu::PipelineLayout pipelineLayout = utils::MakePipelineLayout(device, bgls);

        for (uint32_t missedGroupIndex = 0; missedGroupIndex < 4; ++missedGroupIndex) {
            std::ostringstream stream;
            for (uint32_t i = 0; i < 4; ++i) {
                if (i != missedGroupIndex) {
                    stream << "@group(" << i << ") @binding(0) var<storage, read_write> outputData"
                           << i << " : u32;\n";
                }
            }
            stream << "@compute @workgroup_size(1, 1) fn main() {\n";
            for (uint32_t i = 0; i < 4; ++i) {
                if (i != missedGroupIndex) {
                    stream << "outputData" << i << " = 1u;\n";
                }
            }
            stream << "};";
            wgpu::ComputePipelineDescriptor computePipelineDescriptor = {};
            computePipelineDescriptor.compute.module =
                utils::CreateShaderModule(device, stream.str());
            computePipelineDescriptor.layout = pipelineLayout;
            if (missedGroupIndex == nullBGLIndex) {
                device.CreateComputePipeline(&computePipelineDescriptor);
            } else {
                ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&computePipelineDescriptor));
            }
        }
    }
}

// Test the null or empty bind group layout in a pipeline layout should be ignored when we check the
// compatibility between the pipeline layout and the corresponding bind group.
TEST_F(PipelineLayoutValidationTest, BindGroupSlotWithEmptyLayoutIsNotValidated) {
    std::array<wgpu::BindGroupLayout, 2> nullOrEmptyBindGroupLayouts = {
        nullptr, utils::MakeBindGroupLayout(device, {})};

    wgpu::BindGroupLayout nonEmptyBGL = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage}});
    wgpu::BufferDescriptor bufferDescForNonEmptyBGL = {};
    bufferDescForNonEmptyBGL.size = 4;
    bufferDescForNonEmptyBGL.usage = wgpu::BufferUsage::Storage;
    wgpu::Buffer bufferForNonEmptyBGL = device.CreateBuffer(&bufferDescForNonEmptyBGL);
    wgpu::BindGroup nonEmptyBindGroup =
        utils::MakeBindGroup(device, nonEmptyBGL, {{0, bufferForNonEmptyBGL}});

    for (uint32_t nullBGLIndex = 0; nullBGLIndex < 4; ++nullBGLIndex) {
        for (wgpu::BindGroupLayout nullOrEmptyBindGroupLayout : nullOrEmptyBindGroupLayouts) {
            std::vector<wgpu::BindGroupLayout> bgls(4);
            std::vector<wgpu::BindGroup> bgs(4);

            // Create compute pipeline with null or empty bind group layout and the bind groups.
            // Note that the bind groups are all non-empty.
            for (uint32_t i = 0; i < 4; ++i) {
                if (i == nullBGLIndex) {
                    bgls[i] = nullOrEmptyBindGroupLayout;
                    bgs[i] = nonEmptyBindGroup;
                } else {
                    bgls[i] = utils::MakeBindGroupLayout(
                        device,
                        {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage}});

                    wgpu::BufferDescriptor bufferDesc = {};
                    bufferDesc.size = 4;
                    bufferDesc.usage = wgpu::BufferUsage::Storage;
                    wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc);
                    bgs[i] = utils::MakeBindGroup(device, bgls[i], {{0, buffer}});
                }
            }
            wgpu::PipelineLayout pipelineLayout = utils::MakePipelineLayout(device, bgls);

            std::ostringstream stream;
            for (uint32_t i = 0; i < 4; ++i) {
                if (i != nullBGLIndex) {
                    stream << "@group(" << i << ") @binding(0) var<storage, read_write> outputData"
                           << i << " : u32;\n";
                }
            }
            stream << "@compute @workgroup_size(1, 1) fn main() {\n";
            for (uint32_t i = 0; i < 4; ++i) {
                if (i != nullBGLIndex) {
                    stream << "outputData" << i << " = 1u;\n";
                }
            }
            stream << "};";
            wgpu::ComputePipelineDescriptor computePipelineDescriptor = {};
            computePipelineDescriptor.compute.module =
                utils::CreateShaderModule(device, stream.str());
            computePipelineDescriptor.layout = pipelineLayout;

            wgpu::ComputePipeline computePipeline =
                device.CreateComputePipeline(&computePipelineDescriptor);

            // Set pipeline and bind groups. The null or empty bind group layout in the pipeline
            // layout should be ignored in the check of the compatibility between pipeline layout
            // and the bind group when encoding `SetBindGroup()`.
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder computePass = encoder.BeginComputePass();
            for (uint32_t i = 0; i < 4; ++i) {
                computePass.SetBindGroup(i, bgs[i]);
            }
            computePass.SetPipeline(computePipeline);
            computePass.DispatchWorkgroups(1);
            computePass.End();
            wgpu::CommandBuffer cmdbuf = encoder.Finish();
            device.GetQueue().Submit(1, &cmdbuf);
        }
    }
}

// Test the empty bind group layout returned by calling `getBindGroupLayout()` on a pipeline created
// with `auto` pipeline layout cannot be used to create other pipeline layouts.
TEST_F(PipelineLayoutValidationTest, ReuseEmptyBindGroupLayoutCreatedwithAutoPipelineLayout) {
    // The empty bind group layout comes from a pipeline created with an explicit pipeline layout.
    {
        wgpu::PipelineLayout pipelineLayout = utils::MakePipelineLayout(device, {});
        wgpu::ComputePipelineDescriptor computePipelineDescriptor = {};
        computePipelineDescriptor.compute.module = utils::CreateShaderModule(device, R"(
                @compute @workgroup_size(1, 1) fn main() {})");
        computePipelineDescriptor.layout = pipelineLayout;
        wgpu::ComputePipeline computePipeline =
            device.CreateComputePipeline(&computePipelineDescriptor);

        wgpu::BindGroupLayout emptyBindGroupLayout = computePipeline.GetBindGroupLayout(3);
        std::vector<wgpu::BindGroupLayout> bindGroupLayouts = {{emptyBindGroupLayout}};
        utils::MakePipelineLayout(device, bindGroupLayouts);
    }

    // The empty bind group layout comes from a pipeline created with an 'auto' pipeline layout.
    {
        wgpu::ComputePipelineDescriptor computePipelineDescriptor = {};
        computePipelineDescriptor.compute.module = utils::CreateShaderModule(device, R"(
                @compute @workgroup_size(1, 1) fn main() {})");
        wgpu::ComputePipeline computePipeline =
            device.CreateComputePipeline(&computePipelineDescriptor);

        wgpu::BindGroupLayout emptyBindGroupLayout = computePipeline.GetBindGroupLayout(3);
        std::vector<wgpu::BindGroupLayout> bindGroupLayouts = {{emptyBindGroupLayout}};
        ASSERT_DEVICE_ERROR(utils::MakePipelineLayout(device, bindGroupLayouts));
    }
}

}  // anonymous namespace
}  // namespace dawn
