// Copyright 2019 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 "dawn/native/BindGroupLayout.h"
#include "dawn/tests/unittests/validation/ValidationTest.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

using testing::Not;

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

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

        utils::ComboRenderPipelineDescriptor descriptor;
        descriptor.layout = nullptr;
        descriptor.vertex.module = vsModule;
        descriptor.cFragment.module = fsModule;
        descriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;

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

// Test that GetBindGroupLayout returns the same object for the same index
// and for matching layouts.
TEST_F(GetBindGroupLayoutTests, EquivalentBGLs) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        struct S {
            pos : vec4f
        }
        @group(0) @binding(0) var<uniform> uniform0 : S;
        @group(1) @binding(0) var<uniform> uniform1 : S;

        @vertex fn main() -> @builtin(position) vec4f {
            var pos : vec4f = uniform0.pos;
            pos = uniform1.pos;
            return vec4f();
        })");

    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        struct S2 {
            pos : vec4f
        }
        @group(2) @binding(0) var<uniform> uniform2 : S2;

        struct S3 {
            pos : mat4x4<f32>
        }
        @group(3) @binding(0) var<storage, read_write> storage3 : S3;

        @fragment fn main() {
            var pos_u : vec4f = uniform2.pos;
            var pos_s : mat4x4<f32> = storage3.pos;
        })");

    utils::ComboRenderPipelineDescriptor descriptor;
    descriptor.layout = nullptr;
    descriptor.vertex.module = vsModule;
    descriptor.cFragment.module = fsModule;
    descriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;

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

    // A fully equivalent layout is returned for the same index.
    EXPECT_THAT(pipeline.GetBindGroupLayout(0), BindGroupLayoutEq(pipeline.GetBindGroupLayout(0)));

    // Matching bind group layouts at different indices are fully equivalent.
    EXPECT_THAT(pipeline.GetBindGroupLayout(0), BindGroupLayoutEq(pipeline.GetBindGroupLayout(1)));

    // BGLs with different bindings types are different.
    EXPECT_THAT(pipeline.GetBindGroupLayout(2),
                Not(BindGroupLayoutEq(pipeline.GetBindGroupLayout(3))));

    // BGLs with different visibilities are different.
    EXPECT_THAT(pipeline.GetBindGroupLayout(0),
                Not(BindGroupLayoutEq(pipeline.GetBindGroupLayout(2))));
}

// Test that default BindGroupLayouts cannot be used in the creation of a new PipelineLayout
TEST_F(GetBindGroupLayoutTests, DefaultBindGroupLayoutPipelineCompatibility) {
    wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
        struct S {
            pos : vec4f
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @fragment fn main() {
            var pos : vec4f = uniforms.pos;
        })");

    ASSERT_DEVICE_ERROR(utils::MakePipelineLayout(device, {pipeline.GetBindGroupLayout(0)}));
}

// Bind groups created from different default pipelines' GetBindGroupLayout aren't compatible, even
// if they appear to be the same.
TEST_F(GetBindGroupLayoutTests, DefaultBindGroupLayoutDifferentPipelines) {
    wgpu::RenderPipeline pipeline1 = RenderPipelineFromFragmentShader(R"(
        struct S {
            pos : vec4f
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @fragment fn main() {
            var pos : vec4f = uniforms.pos + 1;
        })");
    wgpu::RenderPipeline pipeline2 = RenderPipelineFromFragmentShader(R"(
        struct S {
            pos : vec4f
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @fragment fn main() {
            var pos : vec4f = uniforms.pos + 2;
        })");

    constexpr uint64_t kBufferSize = 16u;
    wgpu::BufferDescriptor bufferDescriptor;
    bufferDescriptor.size = kBufferSize;
    bufferDescriptor.usage = wgpu::BufferUsage::Uniform;
    wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);

    wgpu::BindGroup bg = utils::MakeBindGroup(device, pipeline2.GetBindGroupLayout(0),
                                              {{0, buffer, 0, kBufferSize}});

    constexpr uint32_t kTextureSize = 4u;
    utils::BasicRenderPass renderPass =
        utils::CreateBasicRenderPass(device, kTextureSize, kTextureSize);
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    wgpu::RenderPassEncoder rp = encoder.BeginRenderPass(&renderPass.renderPassInfo);
    rp.SetPipeline(pipeline1);
    rp.SetBindGroup(0, bg);
    rp.Draw(1);
    rp.End();
    ASSERT_DEVICE_ERROR(encoder.Finish());
}

// Bind groups created from the exact same default pipelines' GetBindGroupLayout aren't compatible.
TEST_F(GetBindGroupLayoutTests, DefaultBindGroupLayoutSamePipelines) {
    wgpu::RenderPipeline pipeline1 = RenderPipelineFromFragmentShader(R"(
        struct S {
            pos : vec4f
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @fragment fn main() {
            var pos : vec4f = uniforms.pos + 1;
        })");
    wgpu::RenderPipeline pipeline2 = RenderPipelineFromFragmentShader(R"(
        struct S {
            pos : vec4f
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @fragment fn main() {
            var pos : vec4f = uniforms.pos + 1;
        })");

    constexpr uint64_t kBufferSize = 16u;
    wgpu::BufferDescriptor bufferDescriptor;
    bufferDescriptor.size = kBufferSize;
    bufferDescriptor.usage = wgpu::BufferUsage::Uniform;
    wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);

    wgpu::BindGroup bg = utils::MakeBindGroup(device, pipeline2.GetBindGroupLayout(0),
                                              {{0, buffer, 0, kBufferSize}});

    constexpr uint32_t kTextureSize = 4u;
    utils::BasicRenderPass renderPass =
        utils::CreateBasicRenderPass(device, kTextureSize, kTextureSize);
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    wgpu::RenderPassEncoder rp = encoder.BeginRenderPass(&renderPass.renderPassInfo);
    rp.SetPipeline(pipeline1);
    rp.SetBindGroup(0, bg);
    rp.Draw(1);
    rp.End();
    ASSERT_DEVICE_ERROR(encoder.Finish());
}

// Test that getBindGroupLayout defaults are correct
// - shader stage visibility is the stage that adds the binding.
// - dynamic offsets is false
TEST_F(GetBindGroupLayoutTests, DefaultShaderStageAndDynamicOffsets) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
        struct S {
            pos : vec4f
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @fragment fn main() {
            var pos : vec4f = uniforms.pos;
        })");

    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.buffer.type = wgpu::BufferBindingType::Uniform;
    binding.buffer.minBindingSize = 4 * sizeof(float);

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

    // Check that an otherwise compatible bind group layout is not fully equivalent to  one created
    // as part of a default pipeline layout, but cache equivalent.
    {
        binding.buffer.hasDynamicOffset = false;
        binding.visibility = wgpu::ShaderStage::Fragment;
        wgpu::BindGroupLayout bgl = device.CreateBindGroupLayout(&desc);
        EXPECT_THAT(bgl, BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
        EXPECT_THAT(bgl, Not(BindGroupLayoutEq(pipeline.GetBindGroupLayout(0))));
    }

    // Check that any change in visibility doesn't match.
    binding.visibility = wgpu::ShaderStage::Vertex;
    EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                Not(BindGroupLayoutEq(pipeline.GetBindGroupLayout(0))));

    binding.visibility = wgpu::ShaderStage::Compute;
    EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                Not(BindGroupLayoutEq(pipeline.GetBindGroupLayout(0))));

    // Check that any change in hasDynamicOffsets doesn't match.
    binding.buffer.hasDynamicOffset = true;
    binding.visibility = wgpu::ShaderStage::Fragment;
    EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                Not(BindGroupLayoutEq(pipeline.GetBindGroupLayout(0))));
}

TEST_F(GetBindGroupLayoutTests, DefaultTextureSampleType) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::BindGroupLayout filteringBGL = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment,
                  wgpu::TextureSampleType::Float},
                 {1, wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment,
                  wgpu::SamplerBindingType::Filtering}});

    wgpu::BindGroupLayout nonFilteringBGL = utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment,
                  wgpu::TextureSampleType::UnfilterableFloat},
                 {1, wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment,
                  wgpu::SamplerBindingType::Filtering}});

    wgpu::ShaderModule emptyVertexModule = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var myTexture : texture_2d<f32>;
        @group(0) @binding(1) var mySampler : sampler;
        @vertex fn main() -> @builtin(position) vec4f {
            _ = myTexture;
            _ = mySampler;
            return vec4f();
        })");

    wgpu::ShaderModule textureLoadVertexModule = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var myTexture : texture_2d<f32>;
        @group(0) @binding(1) var mySampler : sampler;
        @vertex fn main() -> @builtin(position) vec4f {
            _ = textureLoad(myTexture, vec2i(), 0);
            _ = mySampler;
            return vec4f();
        })");

    wgpu::ShaderModule textureSampleVertexModule = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var myTexture : texture_2d<f32>;
        @group(0) @binding(1) var mySampler : sampler;
        @vertex fn main() -> @builtin(position) vec4f {
            _ = textureSampleLevel(myTexture, mySampler, vec2f(), 0.0);
            return vec4f();
        })");

    wgpu::ShaderModule unusedTextureFragmentModule = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var myTexture : texture_2d<f32>;
        @group(0) @binding(1) var mySampler : sampler;
        @fragment fn main() {
            _ = myTexture;
            _ = mySampler;
        })");

    wgpu::ShaderModule textureLoadFragmentModule = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var myTexture : texture_2d<f32>;
        @group(0) @binding(1) var mySampler : sampler;
        @fragment fn main() {
            _ = textureLoad(myTexture, vec2i(), 0);
            _ = mySampler;
        })");

    wgpu::ShaderModule textureSampleFragmentModule = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var myTexture : texture_2d<f32>;
        @group(0) @binding(1) var mySampler : sampler;
        @fragment fn main() {
            _ = textureSample(myTexture, mySampler, vec2f());
        })");

    auto BGLFromModules = [this](wgpu::ShaderModule vertexModule,
                                 wgpu::ShaderModule fragmentModule) {
        utils::ComboRenderPipelineDescriptor descriptor;
        descriptor.vertex.module = vertexModule;
        descriptor.cFragment.module = fragmentModule;
        descriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;
        return device.CreateRenderPipeline(&descriptor).GetBindGroupLayout(0);
    };

    // Textures not used default to non-filtering
    {
        wgpu::BindGroupLayout bgl = BGLFromModules(emptyVertexModule, unusedTextureFragmentModule);
        EXPECT_THAT(bgl, BindGroupLayoutCacheEq(nonFilteringBGL));
        EXPECT_THAT(bgl, Not(BindGroupLayoutCacheEq(filteringBGL)));
    }

    // Textures used with textureLoad default to non-filtering
    {
        wgpu::BindGroupLayout bgl = BGLFromModules(emptyVertexModule, textureLoadFragmentModule);
        EXPECT_THAT(bgl, BindGroupLayoutCacheEq(nonFilteringBGL));
        EXPECT_THAT(bgl, Not(BindGroupLayoutCacheEq(filteringBGL)));
    }

    // Textures used with textureLoad on both stages default to non-filtering
    {
        wgpu::BindGroupLayout bgl =
            BGLFromModules(textureLoadVertexModule, textureLoadFragmentModule);
        EXPECT_THAT(bgl, BindGroupLayoutCacheEq(nonFilteringBGL));
        EXPECT_THAT(bgl, Not(BindGroupLayoutCacheEq(filteringBGL)));
    }

    // Textures used with textureSample default to filtering
    {
        wgpu::BindGroupLayout bgl = BGLFromModules(emptyVertexModule, textureSampleFragmentModule);
        EXPECT_THAT(bgl, Not(BindGroupLayoutCacheEq(nonFilteringBGL)));
        EXPECT_THAT(bgl, BindGroupLayoutCacheEq(filteringBGL));
    }
    {
        wgpu::BindGroupLayout bgl =
            BGLFromModules(textureSampleVertexModule, unusedTextureFragmentModule);
        EXPECT_THAT(bgl, Not(BindGroupLayoutCacheEq(nonFilteringBGL)));
        EXPECT_THAT(bgl, BindGroupLayoutCacheEq(filteringBGL));
    }

    // Textures used with both textureLoad and textureSample default to filtering
    {
        wgpu::BindGroupLayout bgl =
            BGLFromModules(textureLoadVertexModule, textureSampleFragmentModule);
        EXPECT_THAT(bgl, Not(BindGroupLayoutCacheEq(nonFilteringBGL)));
        EXPECT_THAT(bgl, BindGroupLayoutCacheEq(filteringBGL));
    }
    {
        wgpu::BindGroupLayout bgl =
            BGLFromModules(textureSampleVertexModule, textureLoadFragmentModule);
        EXPECT_THAT(bgl, Not(BindGroupLayoutCacheEq(nonFilteringBGL)));
        EXPECT_THAT(bgl, BindGroupLayoutCacheEq(filteringBGL));
    }
}

// Test GetBindGroupLayout works with a compute pipeline
TEST_F(GetBindGroupLayoutTests, ComputePipeline) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::ShaderModule csModule = utils::CreateShaderModule(device, R"(
        struct S {
            pos : vec4f
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @compute @workgroup_size(1) fn main() {
            var pos : vec4f = uniforms.pos;
        })");

    wgpu::ComputePipelineDescriptor descriptor;
    descriptor.layout = nullptr;
    descriptor.compute.module = csModule;

    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&descriptor);

    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.buffer.type = wgpu::BufferBindingType::Uniform;
    binding.visibility = wgpu::ShaderStage::Compute;
    binding.buffer.hasDynamicOffset = false;
    binding.buffer.minBindingSize = 4 * sizeof(float);

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

    // The pipeline bind group should be cache equivalent, but not fully equivalent since it was
    // default created by the pipeline.
    wgpu::BindGroupLayout bgl = device.CreateBindGroupLayout(&desc);
    EXPECT_THAT(bgl, Not(BindGroupLayoutEq(pipeline.GetBindGroupLayout(0))));
    EXPECT_THAT(bgl, BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
}

// Test that the binding type matches the shader.
TEST_F(GetBindGroupLayoutTests, BindingType) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.buffer.hasDynamicOffset = false;
    binding.buffer.minBindingSize = 4 * sizeof(float);
    binding.visibility = wgpu::ShaderStage::Fragment;

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

    {
        // Storage buffer binding is not supported in vertex shader.
        binding.visibility = wgpu::ShaderStage::Fragment;
        binding.buffer.type = wgpu::BufferBindingType::Storage;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            struct S {
                pos : vec4f
            }
            @group(0) @binding(0) var<storage, read_write> ssbo : S;

            @fragment fn main() {
                var pos : vec4f = ssbo.pos;
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }
    {
        binding.buffer.type = wgpu::BufferBindingType::Uniform;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            struct S {
                pos : vec4f
            }
            @group(0) @binding(0) var<uniform> uniforms : S;

            @fragment fn main() {
                var pos : vec4f = uniforms.pos;
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    {
        binding.buffer.type = wgpu::BufferBindingType::ReadOnlyStorage;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            struct S {
                pos : vec4f
            }
            @group(0) @binding(0) var<storage, read> ssbo : S;

            @fragment fn main() {
                var pos : vec4f = ssbo.pos;
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    binding.buffer.type = wgpu::BufferBindingType::BindingNotUsed;
    binding.buffer.minBindingSize = 0;
    {
        binding.texture.sampleType = wgpu::TextureSampleType::UnfilterableFloat;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_2d<f32>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    {
        binding.texture.multisampled = true;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_multisampled_2d<f32>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    binding.texture.sampleType = wgpu::TextureSampleType::BindingNotUsed;
    {
        binding.sampler.type = wgpu::SamplerBindingType::Filtering;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var mySampler: sampler;

            @fragment fn main() {
                _ = mySampler;
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }
}

// Tests that the external texture binding type matches with a texture_external declared in the
// shader.
TEST_F(GetBindGroupLayoutTests, ExternalTextureBindingType) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.visibility = wgpu::ShaderStage::Fragment;

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

    binding.nextInChain = &utils::kExternalTextureBindingLayout;
    wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myExternalTexture: texture_external;

            @fragment fn main() {
               _ = myExternalTexture;
            })");
    EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
}

// Tests that the texel buffer binding type matches with a texel_buffer declared in the shader.
TEST_F(GetBindGroupLayoutTests, TexelBufferBindingType) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::TexelBufferBindingLayout layout = {};
    layout.access = wgpu::TexelBufferAccess::ReadOnly;
    layout.format = wgpu::TextureFormat::RGBA8Uint;

    wgpu::BindGroupLayoutEntry entry = {};
    entry.binding = 0;
    entry.visibility = wgpu::ShaderStage::Fragment;
    entry.nextInChain = &layout;

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

    wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            requires texel_buffers;
            @group(0) @binding(0) var myTexelBuffer: texel_buffer<rgba8uint, read>;

            @fragment fn main() {
                _ = textureDimensions(myTexelBuffer);
            })");

    EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
}

// Test that texture view dimension matches the shader.
TEST_F(GetBindGroupLayoutTests, TextureViewDimension) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.visibility = wgpu::ShaderStage::Fragment;
    binding.texture.sampleType = wgpu::TextureSampleType::UnfilterableFloat;

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

    {
        binding.texture.viewDimension = wgpu::TextureViewDimension::e1D;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_1d<f32>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    {
        binding.texture.viewDimension = wgpu::TextureViewDimension::e2D;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_2d<f32>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));

        // viewDimension defaults to 2D, so should be cached the same.
        binding.texture.viewDimension = wgpu::TextureViewDimension::Undefined;
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    {
        binding.texture.viewDimension = wgpu::TextureViewDimension::e2DArray;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_2d_array<f32>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    {
        binding.texture.viewDimension = wgpu::TextureViewDimension::e3D;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_3d<f32>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    {
        binding.texture.viewDimension = wgpu::TextureViewDimension::Cube;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_cube<f32>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    {
        binding.texture.viewDimension = wgpu::TextureViewDimension::CubeArray;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_cube_array<f32>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }
}

// Test that storageTexture view dimension matches the shader.
TEST_F(GetBindGroupLayoutTests, StorageTextureViewDimension) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.visibility = wgpu::ShaderStage::Fragment;
    binding.storageTexture.access = wgpu::StorageTextureAccess::WriteOnly;
    binding.storageTexture.format = wgpu::TextureFormat::R32Float;

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

    {
        binding.storageTexture.viewDimension = wgpu::TextureViewDimension::e1D;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_storage_1d<r32float, write>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    {
        binding.storageTexture.viewDimension = wgpu::TextureViewDimension::e2D;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_storage_2d<r32float, write>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));

        // viewDimension defaults to 2D, so should be cached the same.
        binding.storageTexture.viewDimension = wgpu::TextureViewDimension::Undefined;
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    {
        binding.storageTexture.viewDimension = wgpu::TextureViewDimension::e2DArray;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_storage_2d_array<r32float, write>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    {
        binding.storageTexture.viewDimension = wgpu::TextureViewDimension::e3D;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_storage_3d<r32float, write>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }
}

// Test that texture component type matches the shader.
TEST_F(GetBindGroupLayoutTests, TextureComponentType) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.visibility = wgpu::ShaderStage::Fragment;

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

    {
        binding.texture.sampleType = wgpu::TextureSampleType::UnfilterableFloat;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_2d<f32>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    {
        binding.texture.sampleType = wgpu::TextureSampleType::Sint;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_2d<i32>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    {
        binding.texture.sampleType = wgpu::TextureSampleType::Uint;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            @group(0) @binding(0) var myTexture : texture_2d<u32>;

            @fragment fn main() {
                _ = textureDimensions(myTexture);
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }
}

// Test that binding= indices match.
TEST_F(GetBindGroupLayoutTests, BindingIndices) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::BindGroupLayoutEntry binding = {};
    binding.visibility = wgpu::ShaderStage::Fragment;
    binding.buffer.type = wgpu::BufferBindingType::Uniform;
    binding.buffer.hasDynamicOffset = false;
    binding.buffer.minBindingSize = 4 * sizeof(float);

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

    {
        binding.binding = 0;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            struct S {
                pos : vec4f
            }
            @group(0) @binding(0) var<uniform> uniforms : S;

            @fragment fn main() {
                var pos : vec4f = uniforms.pos;
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    {
        binding.binding = 1;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            struct S {
                pos : vec4f
            }
            @group(0) @binding(1) var<uniform> uniforms : S;

            @fragment fn main() {
                var pos : vec4f = uniforms.pos;
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    {
        binding.binding = 2;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            struct S {
                pos : vec4f
            }
            @group(0) @binding(1) var<uniform> uniforms : S;

            @fragment fn main() {
                var pos : vec4f = uniforms.pos;
            })");
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    Not(BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0))));
    }
}

// Test it is valid to have duplicate bindings in the shaders.
TEST_F(GetBindGroupLayoutTests, DuplicateBinding) {
    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        struct S {
            pos : vec4f
        }
        @group(0) @binding(0) var<uniform> uniform0 : S;
        @group(1) @binding(0) var<uniform> uniform1 : S;

        @vertex fn main() -> @builtin(position) vec4f {
            var pos : vec4f = uniform0.pos;
            pos = uniform1.pos;
            return vec4f();
        })");

    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        struct S {
            pos : vec4f
        }
        @group(1) @binding(0) var<uniform> uniforms : S;

        @fragment fn main() {
            var pos : vec4f = uniforms.pos;
        })");

    utils::ComboRenderPipelineDescriptor descriptor;
    descriptor.layout = nullptr;
    descriptor.vertex.module = vsModule;
    descriptor.cFragment.module = fsModule;
    descriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;

    device.CreateRenderPipeline(&descriptor);
}

// Test that minBufferSize is set on the BGL and that the max of the min buffer sizes is used.
TEST_F(GetBindGroupLayoutTests, MinBufferSize) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::ShaderModule vsModule4 = utils::CreateShaderModule(device, R"(
        struct S {
            pos : f32
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @vertex fn main() -> @builtin(position) vec4f {
            var pos : f32 = uniforms.pos;
            return vec4f();
        })");

    wgpu::ShaderModule vsModule64 = utils::CreateShaderModule(device, R"(
        struct S {
            pos : mat4x4<f32>
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @vertex fn main() -> @builtin(position) vec4f {
            var pos : mat4x4<f32> = uniforms.pos;
            return vec4f();
        })");

    wgpu::ShaderModule fsModule4 = utils::CreateShaderModule(device, R"(
        struct S {
            pos : f32
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @fragment fn main() {
            var pos : f32 = uniforms.pos;
        })");

    wgpu::ShaderModule fsModule64 = utils::CreateShaderModule(device, R"(
        struct S {
            pos : mat4x4<f32>
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @fragment fn main() {
            var pos : mat4x4<f32> = uniforms.pos;
        })");

    // Create BGLs with minBufferBindingSize 4 and 64.
    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.buffer.type = wgpu::BufferBindingType::Uniform;
    binding.visibility = wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Vertex;

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

    binding.buffer.minBindingSize = 4;
    wgpu::BindGroupLayout bgl4 = device.CreateBindGroupLayout(&desc);
    binding.buffer.minBindingSize = 64;
    wgpu::BindGroupLayout bgl64 = device.CreateBindGroupLayout(&desc);

    utils::ComboRenderPipelineDescriptor descriptor;
    descriptor.layout = nullptr;
    descriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;

    // Check with both stages using 4 bytes.
    {
        descriptor.vertex.module = vsModule4;
        descriptor.cFragment.module = fsModule4;
        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
        EXPECT_THAT(pipeline.GetBindGroupLayout(0), BindGroupLayoutCacheEq(bgl4));
    }

    // Check that the max is taken between 4 and 64.
    {
        descriptor.vertex.module = vsModule64;
        descriptor.cFragment.module = fsModule4;
        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
        EXPECT_THAT(pipeline.GetBindGroupLayout(0), BindGroupLayoutCacheEq(bgl64));
    }

    // Check that the order doesn't change that the max is taken.
    {
        descriptor.vertex.module = vsModule4;
        descriptor.cFragment.module = fsModule64;
        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
        EXPECT_THAT(pipeline.GetBindGroupLayout(0), BindGroupLayoutCacheEq(bgl64));
    }
}

// Test that the visibility is correctly aggregated if two stages have the exact same binding.
TEST_F(GetBindGroupLayoutTests, StageAggregation) {
    DAWN_SKIP_TEST_IF(UsesWire());

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

    wgpu::ShaderModule vsModuleSampler = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var mySampler: sampler;
        @vertex fn main() -> @builtin(position) vec4f {
            _ = mySampler;
            return vec4f();
        })");

    wgpu::ShaderModule fsModuleNoSampler = utils::CreateShaderModule(device, R"(
        @fragment fn main() {
        })");

    wgpu::ShaderModule fsModuleSampler = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var mySampler: sampler;
        @fragment fn main() {
            _ = mySampler;
        })");

    // Create BGLs with minBufferBindingSize 4 and 64.
    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.sampler.type = wgpu::SamplerBindingType::Filtering;

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

    utils::ComboRenderPipelineDescriptor descriptor;
    descriptor.layout = nullptr;
    descriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;

    // Check with only the vertex shader using the sampler
    {
        descriptor.vertex.module = vsModuleSampler;
        descriptor.cFragment.module = fsModuleNoSampler;
        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);

        binding.visibility = wgpu::ShaderStage::Vertex;
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    // Check with only the fragment shader using the sampler
    {
        descriptor.vertex.module = vsModuleNoSampler;
        descriptor.cFragment.module = fsModuleSampler;
        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);

        binding.visibility = wgpu::ShaderStage::Fragment;
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }

    // Check with both shaders using the sampler
    {
        descriptor.vertex.module = vsModuleSampler;
        descriptor.cFragment.module = fsModuleSampler;
        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);

        binding.visibility = wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Vertex;
        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }
}

// Test that a binding_array is reflected into a BGLEntry with an arraySize.
TEST_F(GetBindGroupLayoutTests, ArraySizeReflected) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::BindGroupLayoutEntry entry;
    entry.binding = 0;
    entry.visibility = wgpu::ShaderStage::Fragment;
    entry.texture.sampleType = wgpu::TextureSampleType::UnfilterableFloat;

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

    // The pipeline using binding_array
    wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
        @group(0) @binding(0) var t: binding_array<texture_2d<f32>, 3>;
        @fragment fn main() {
            _ = t[0];
        })");

    entry.bindingArraySize = 3;
    EXPECT_THAT(device.CreateBindGroupLayout(&bglDesc),
                BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    entry.bindingArraySize = 2;
    EXPECT_THAT(device.CreateBindGroupLayout(&bglDesc),
                Not(BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0))));
    entry.bindingArraySize = 1;
    EXPECT_THAT(device.CreateBindGroupLayout(&bglDesc),
                Not(BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0))));
}

// Test that a binding_array is reflected into an entry with the max of both sizes
TEST_F(GetBindGroupLayoutTests, ArraySizeTwoStages) {
    DAWN_SKIP_TEST_IF(UsesWire());

    // A BGL with arraySize = 3
    wgpu::BindGroupLayoutEntry entry;
    entry.binding = 0;
    entry.visibility = wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment;
    entry.bindingArraySize = 3;
    entry.texture.sampleType = wgpu::TextureSampleType::UnfilterableFloat;

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

    // The pipeline using binding_array, with differing binding_array sizes. VS = 3, FS = 2
    {
        wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
            @group(0) @binding(0) var vs_t: binding_array<texture_2d<f32>, 3>;
            @vertex fn vs() -> @builtin(position) vec4f {
                _ = vs_t[0];
                return vec4(0);
            }

            @group(0) @binding(0) var fs_t: binding_array<texture_2d<f32>, 2>;
            @fragment fn fs() {
                _ = fs_t[0];
            })");

        utils::ComboRenderPipelineDescriptor descriptor;
        descriptor.layout = nullptr;
        descriptor.vertex.module = module;
        descriptor.cFragment.module = module;
        descriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;

        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
        EXPECT_THAT(device.CreateBindGroupLayout(&bglDesc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }
    // The pipeline using binding_array, with differing binding_array sizes. VS = 2, FS = 3
    {
        wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
            @group(0) @binding(0) var vs_t: binding_array<texture_2d<f32>, 2>;
            @vertex fn vs() -> @builtin(position) vec4f {
                _ = vs_t[0];
                return vec4(0);
            }

            @group(0) @binding(0) var fs_t: binding_array<texture_2d<f32>, 3>;
            @fragment fn fs() {
                _ = fs_t[0];
            })");

        utils::ComboRenderPipelineDescriptor descriptor;
        descriptor.layout = nullptr;
        descriptor.vertex.module = module;
        descriptor.cFragment.module = module;
        descriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;

        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
        EXPECT_THAT(device.CreateBindGroupLayout(&bglDesc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }
    // The pipeline using binding_array, with differing binding_array sizes. VS = 3, FS = NotArrayed
    {
        wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
            @group(0) @binding(0) var vs_t: binding_array<texture_2d<f32>, 3>;
            @vertex fn vs() -> @builtin(position) vec4f {
                _ = vs_t[0];
                return vec4(0);
            }

            @group(0) @binding(0) var fs_t: texture_2d<f32>;
            @fragment fn fs() {
                _ = fs_t;
            })");

        utils::ComboRenderPipelineDescriptor descriptor;
        descriptor.layout = nullptr;
        descriptor.vertex.module = module;
        descriptor.cFragment.module = module;
        descriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;

        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
        EXPECT_THAT(device.CreateBindGroupLayout(&bglDesc),
                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
    }
}

// Test it is invalid to have conflicting binding types in the shaders.
TEST_F(GetBindGroupLayoutTests, ConflictingBindingType) {
    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        struct S {
            pos : vec4f
        }
        @group(0) @binding(0) var<uniform> ubo : S;

        @vertex fn main() -> @builtin(position) vec4f {
            var pos : vec4f = ubo.pos;
            return vec4f();
        })");

    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        struct S {
            pos : vec4f
        }
        @group(0) @binding(0) var<storage, read_write> ssbo : S;

        @fragment fn main() {
            var pos : vec4f = ssbo.pos;
        })");

    utils::ComboRenderPipelineDescriptor descriptor;
    descriptor.layout = nullptr;
    descriptor.vertex.module = vsModule;
    descriptor.cFragment.module = fsModule;

    ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
}

// Test it is invalid to have conflicting binding texture multisampling in the shaders.
TEST_F(GetBindGroupLayoutTests, ConflictingBindingTextureMultisampling) {
    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var myTexture : texture_2d<f32>;

        @vertex fn main() -> @builtin(position) vec4f {
            _ = textureDimensions(myTexture);
            return vec4f();
        })");

    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var myTexture : texture_multisampled_2d<f32>;

        @fragment fn main() {
            _ = textureDimensions(myTexture);
        })");

    utils::ComboRenderPipelineDescriptor descriptor;
    descriptor.layout = nullptr;
    descriptor.vertex.module = vsModule;
    descriptor.cFragment.module = fsModule;

    ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
}

// Test it is invalid to have conflicting binding texture dimension in the shaders.
TEST_F(GetBindGroupLayoutTests, ConflictingBindingViewDimension) {
    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var myTexture : texture_2d<f32>;

        @vertex fn main() -> @builtin(position) vec4f {
            _ = textureDimensions(myTexture);
            return vec4f();
        })");

    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var myTexture : texture_3d<f32>;

        @fragment fn main() {
            _ = textureDimensions(myTexture);
        })");

    utils::ComboRenderPipelineDescriptor descriptor;
    descriptor.layout = nullptr;
    descriptor.vertex.module = vsModule;
    descriptor.cFragment.module = fsModule;

    ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
}

// Test it is invalid to have conflicting binding texture component type in the shaders.
TEST_F(GetBindGroupLayoutTests, ConflictingBindingTextureComponentType) {
    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var myTexture : texture_2d<f32>;

        @vertex fn main() -> @builtin(position) vec4f {
            _ = textureDimensions(myTexture);
            return vec4f();
        })");

    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var myTexture : texture_2d<i32>;

        @fragment fn main() {
            _ = textureDimensions(myTexture);
        })");

    utils::ComboRenderPipelineDescriptor descriptor;
    descriptor.layout = nullptr;
    descriptor.vertex.module = vsModule;
    descriptor.cFragment.module = fsModule;

    ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
}

// Test it is an error to query an out of range bind group layout.
TEST_F(GetBindGroupLayoutTests, OutOfRangeIndex) {
    ASSERT_DEVICE_ERROR(RenderPipelineFromFragmentShader(R"(
        @fragment fn main() {
        })")
                            .GetBindGroupLayout(kMaxBindGroups));

    ASSERT_DEVICE_ERROR(RenderPipelineFromFragmentShader(R"(
        @fragment fn main() {
        })")
                            .GetBindGroupLayout(kMaxBindGroups + 1));
}

// Test that unused indices return the empty bind group layout if less than the maximum number of
// bind groups, an error otherwise.
TEST_F(GetBindGroupLayoutTests, UnusedIndex) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
        struct S {
            pos : vec4f
        }
        @group(0) @binding(0) var<uniform> uniforms0 : S;
        @group(2) @binding(0) var<uniform> uniforms2 : S;

        @fragment fn main() {
            var pos : vec4f = uniforms0.pos;
            pos = uniforms2.pos;
        })");

    wgpu::BindGroupLayoutDescriptor desc = {};
    desc.entryCount = 0;
    desc.entries = nullptr;

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

    EXPECT_THAT(pipeline.GetBindGroupLayout(0),
                Not(BindGroupLayoutCacheEq(emptyBindGroupLayout)));  // Used
    EXPECT_THAT(pipeline.GetBindGroupLayout(1),
                BindGroupLayoutCacheEq(emptyBindGroupLayout));  // Not used
    EXPECT_THAT(pipeline.GetBindGroupLayout(2),
                Not(BindGroupLayoutCacheEq(emptyBindGroupLayout)));  // Used
    EXPECT_THAT(pipeline.GetBindGroupLayout(3),
                BindGroupLayoutCacheEq(emptyBindGroupLayout));  // Past last defined BGL

    // Equal to kMaxBindGroups, error!
    ASSERT_DEVICE_ERROR(pipeline.GetBindGroupLayout(kMaxBindGroups));
}

// Test that after explicitly creating a pipeline with a pipeline layout, calling
// GetBindGroupLayout reflects the same bind group layouts.
TEST_F(GetBindGroupLayoutTests, Reflection) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::BindGroupLayoutEntry binding = {};
    binding.binding = 0;
    binding.buffer.type = wgpu::BufferBindingType::Uniform;
    binding.visibility = wgpu::ShaderStage::Vertex;

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

    wgpu::BindGroupLayout bindGroupLayout = device.CreateBindGroupLayout(&bglDesc);

    wgpu::PipelineLayoutDescriptor pipelineLayoutDesc = {};
    pipelineLayoutDesc.bindGroupLayoutCount = 1;
    pipelineLayoutDesc.bindGroupLayouts = &bindGroupLayout;

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

    wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
        struct S {
            pos : vec4f
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @vertex fn main() -> @builtin(position) vec4f {
            var pos : vec4f = uniforms.pos;
            return vec4f();
        })");

    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        @fragment fn main() {
        })");

    utils::ComboRenderPipelineDescriptor pipelineDesc;
    pipelineDesc.layout = pipelineLayout;
    pipelineDesc.vertex.module = vsModule;
    pipelineDesc.cFragment.module = fsModule;
    pipelineDesc.cTargets[0].writeMask = wgpu::ColorWriteMask::None;

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

    EXPECT_THAT(pipeline.GetBindGroupLayout(0), BindGroupLayoutEq(bindGroupLayout));
}

// Test that fragment output validation is for the correct entryPoint
TEST_F(GetBindGroupLayoutTests, FromCorrectEntryPoint) {
    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        struct Data {
            data : f32
        }
        @group(0) @binding(0) var<storage, read_write> data0 : Data;
        @group(0) @binding(1) var<storage, read_write> data1 : Data;

        @compute @workgroup_size(1) fn compute0() {
            data0.data = 0.0;
        }

        @compute @workgroup_size(1) fn compute1() {
            data1.data = 0.0;
        }
    )");

    wgpu::ComputePipelineDescriptor pipelineDesc;
    pipelineDesc.compute.module = module;

    // Get each entryPoint's BGL.
    pipelineDesc.compute.entryPoint = "compute0";
    wgpu::ComputePipeline pipeline0 = device.CreateComputePipeline(&pipelineDesc);
    wgpu::BindGroupLayout bgl0 = pipeline0.GetBindGroupLayout(0);

    pipelineDesc.compute.entryPoint = "compute1";
    wgpu::ComputePipeline pipeline1 = device.CreateComputePipeline(&pipelineDesc);
    wgpu::BindGroupLayout bgl1 = pipeline1.GetBindGroupLayout(0);

    // Create the buffer used in the bindgroups.
    wgpu::BufferDescriptor bufferDesc;
    bufferDesc.size = 4;
    bufferDesc.usage = wgpu::BufferUsage::Storage;
    wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc);

    // Success case, the BGL matches the descriptor for the bindgroup.
    utils::MakeBindGroup(device, bgl0, {{0, buffer}});
    utils::MakeBindGroup(device, bgl1, {{1, buffer}});

    // Error case, the BGL doesn't match the descriptor for the bindgroup.
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, bgl0, {{1, buffer}}));
    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, bgl1, {{0, buffer}}));
}

// Test that a pipeline full of explicitly empty BGLs correctly reflects them.
TEST_F(GetBindGroupLayoutTests, FullOfEmptyBGLs) {
    DAWN_SKIP_TEST_IF(UsesWire());

    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);

    EXPECT_THAT(pipeline.GetBindGroupLayout(0), BindGroupLayoutEq(emptyBGL));
    EXPECT_THAT(pipeline.GetBindGroupLayout(1), BindGroupLayoutEq(emptyBGL));
    EXPECT_THAT(pipeline.GetBindGroupLayout(2), BindGroupLayoutEq(emptyBGL));
    EXPECT_THAT(pipeline.GetBindGroupLayout(3), BindGroupLayoutEq(emptyBGL));
}

// Test that a pipeline full of explicitly null BGLs correctly reflects empty BGLs.
TEST_F(GetBindGroupLayoutTests, NullBGLs) {
    DAWN_SKIP_TEST_IF(UsesWire());

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

    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::BindGroupLayout emptyBGL = utils::MakeBindGroupLayout(device, {});
    EXPECT_THAT(pipeline.GetBindGroupLayout(0), BindGroupLayoutEq(emptyBGL));
    EXPECT_THAT(pipeline.GetBindGroupLayout(1), BindGroupLayoutEq(emptyBGL));
    EXPECT_THAT(pipeline.GetBindGroupLayout(2), BindGroupLayoutEq(emptyBGL));
    EXPECT_THAT(pipeline.GetBindGroupLayout(3), BindGroupLayoutEq(emptyBGL));
}

// Regression test for a revert where the default layout computation of a sampler used with an
// external texture would mark it unfilterable (when it needs to be filterable).
TEST_F(GetBindGroupLayoutTests, SamplerUsedWithExternalTexture) {
    DAWN_SKIP_TEST_IF(UsesWire());

    wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
        @vertex fn vs() -> @builtin(position) vec4f {
            return vec4f(0.0);
        }

        @group(0) @binding(0) var mySampler: sampler;
        @group(0) @binding(1) var myTexture: texture_external;
        @fragment fn main() -> @location(0) vec4f {
          return textureSampleBaseClampToEdge(myTexture, mySampler, vec2f(0));
        }
    )");

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

    wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
        device, {
                    {
                        0,
                        wgpu::ShaderStage::Fragment,
                        wgpu::SamplerBindingType::Filtering,
                    },
                    {1, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout},
                });
    EXPECT_THAT(pipeline.GetBindGroupLayout(0), BindGroupLayoutCacheEq(bgl));
}

// TODO(https://issues.chromium.org/487593147): Add tests for GetBindGroupLayout with explicit
// filterability and filteringness annotations. An incomplete test plan is:
//
//  - Check that explicit filteringness / filterability is correctly reflected.
//  - Check that conflicting filteringness / filterability between stages produces an error.
//  - Check that unknowns get defaulted to the other stage's explicit value (in both orders)
//  - Check that unknown samplers used with non-filterable textures become unfilterable, and that
//  the others become filtering.
//  - Check that unknown textures used with a filtering / unknown sampler become filtering.
//  - Check what happens on unknown texture/samplers only referenced and not used.

}  // anonymous namespace
}  // namespace dawn
