// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn/tests/unittests/validation/ValidationTest.h"

#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

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, SameObject) {
    // This test works assuming Dawn Native's object deduplication.
    // Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
    // Native.
    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);

    // The same value is returned for the same index.
    EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), pipeline.GetBindGroupLayout(0).Get());

    // Matching bind group layouts at different indices are the same object.
    EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), pipeline.GetBindGroupLayout(1).Get());

    // BGLs with different bindings types are different objects.
    EXPECT_NE(pipeline.GetBindGroupLayout(2).Get(), pipeline.GetBindGroupLayout(3).Get());

    // BGLs with different visibilities are different objects.
    EXPECT_NE(pipeline.GetBindGroupLayout(0).Get(), pipeline.GetBindGroupLayout(2).Get());
}

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

// Test that getBindGroupLayout defaults are correct
// - shader stage visibility is the stage that adds the binding.
// - dynamic offsets is false
TEST_F(GetBindGroupLayoutTests, DefaultShaderStageAndDynamicOffsets) {
    // This test works assuming Dawn Native's object deduplication.
    // Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
    // Native.
    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 doesn't match one created as part of a
    // default pipeline layout.
    binding.buffer.hasDynamicOffset = false;
    binding.visibility = wgpu::ShaderStage::Fragment;
    EXPECT_NE(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get());

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

    binding.visibility = wgpu::ShaderStage::Compute;
    EXPECT_NE(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get());

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

TEST_F(GetBindGroupLayoutTests, DefaultTextureSampleType) {
    // This test works assuming Dawn Native's object deduplication.
    // Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
    // Native.
    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
    EXPECT_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(emptyVertexModule, unusedTextureFragmentModule).Get(),
        nonFilteringBGL.Get()));
    EXPECT_FALSE(native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(emptyVertexModule, unusedTextureFragmentModule).Get(), filteringBGL.Get()));

    // Textures used with textureLoad default to non-filtering
    EXPECT_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(emptyVertexModule, textureLoadFragmentModule).Get(), nonFilteringBGL.Get()));
    EXPECT_FALSE(native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(emptyVertexModule, textureLoadFragmentModule).Get(), filteringBGL.Get()));

    // Textures used with textureLoad on both stages default to non-filtering
    EXPECT_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(textureLoadVertexModule, textureLoadFragmentModule).Get(),
        nonFilteringBGL.Get()));
    EXPECT_FALSE(native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(textureLoadVertexModule, textureLoadFragmentModule).Get(),
        filteringBGL.Get()));

    // Textures used with textureSample default to filtering
    EXPECT_FALSE(native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(emptyVertexModule, textureSampleFragmentModule).Get(),
        nonFilteringBGL.Get()));
    EXPECT_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(emptyVertexModule, textureSampleFragmentModule).Get(), filteringBGL.Get()));
    EXPECT_FALSE(native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(textureSampleVertexModule, unusedTextureFragmentModule).Get(),
        nonFilteringBGL.Get()));
    EXPECT_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(textureSampleVertexModule, unusedTextureFragmentModule).Get(),
        filteringBGL.Get()));

    // Textures used with both textureLoad and textureSample default to filtering
    EXPECT_FALSE(native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(textureLoadVertexModule, textureSampleFragmentModule).Get(),
        nonFilteringBGL.Get()));
    EXPECT_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(textureLoadVertexModule, textureSampleFragmentModule).Get(),
        filteringBGL.Get()));
    EXPECT_FALSE(native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(textureSampleVertexModule, textureLoadFragmentModule).Get(),
        nonFilteringBGL.Get()));
    EXPECT_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(textureSampleVertexModule, textureLoadFragmentModule).Get(),
        filteringBGL.Get()));
}

// Test GetBindGroupLayout works with a compute pipeline
TEST_F(GetBindGroupLayoutTests, ComputePipeline) {
    // This test works assuming Dawn Native's object deduplication.
    // Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
    // Native.
    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;
    descriptor.compute.entryPoint = "main";

    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;

    EXPECT_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
        device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
}

// Test that the binding type matches the shader.
TEST_F(GetBindGroupLayoutTests, BindingType) {
    // This test works assuming Dawn Native's object deduplication.
    // Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
    // Native.
    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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }
    {
        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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

    {
        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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

    binding.buffer.type = wgpu::BufferBindingType::Undefined;
    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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

    {
        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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

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

            @fragment fn main() {
                _ = mySampler;
            })");
        EXPECT_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }
}

// Tests that the external texture binding type matches with a texture_external declared in the
// shader.
TEST_F(GetBindGroupLayoutTests, ExternalTextureBindingType) {
    // This test works assuming Dawn Native's object deduplication.
    // Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
    // Native.
    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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
        device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
}

// Test that texture view dimension matches the shader.
TEST_F(GetBindGroupLayoutTests, ViewDimension) {
    // This test works assuming Dawn Native's object deduplication.
    // Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
    // Native.
    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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

    {
        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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

    {
        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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

    {
        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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

    {
        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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

    {
        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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }
}

// Test that texture component type matches the shader.
TEST_F(GetBindGroupLayoutTests, TextureComponentType) {
    // This test works assuming Dawn Native's object deduplication.
    // Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
    // Native.
    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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

    {
        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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

    {
        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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }
}

// Test that binding= indices match.
TEST_F(GetBindGroupLayoutTests, BindingIndices) {
    // This test works assuming Dawn Native's object deduplication.
    // Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
    // Native.
    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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

    {
        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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

    {
        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_FALSE(native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }
}

// 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) {
    // This test works assuming Dawn Native's object deduplication.
    // Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
    // Native.
    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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            pipeline.GetBindGroupLayout(0).Get(), bgl4.Get()));
    }

    // 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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            pipeline.GetBindGroupLayout(0).Get(), bgl64.Get()));
    }

    // 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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            pipeline.GetBindGroupLayout(0).Get(), bgl64.Get()));
    }
}

// Test that the visibility is correctly aggregated if two stages have the exact same binding.
TEST_F(GetBindGroupLayoutTests, StageAggregation) {
    // This test works assuming Dawn Native's object deduplication.
    // Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
    // Native.
    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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            pipeline.GetBindGroupLayout(0).Get(), device.CreateBindGroupLayout(&desc).Get()));
    }

    // 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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            pipeline.GetBindGroupLayout(0).Get(), device.CreateBindGroupLayout(&desc).Get()));
    }

    // 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_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
            pipeline.GetBindGroupLayout(0).Get(), device.CreateBindGroupLayout(&desc).Get()));
    }
}

// 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 before the last used index, an
// error otherwise.
TEST_F(GetBindGroupLayoutTests, UnusedIndex) {
    // This test works assuming Dawn Native's object deduplication.
    // Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
    // Native.
    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_FALSE(native::BindGroupLayoutBindingsEqualForTesting(
        pipeline.GetBindGroupLayout(0).Get(), emptyBindGroupLayout.Get()));  // Used
    EXPECT_TRUE(native::BindGroupLayoutBindingsEqualForTesting(
        pipeline.GetBindGroupLayout(1).Get(), emptyBindGroupLayout.Get()));  // Not Used.
    EXPECT_FALSE(native::BindGroupLayoutBindingsEqualForTesting(
        pipeline.GetBindGroupLayout(2).Get(), emptyBindGroupLayout.Get()));  // Used.
    ASSERT_DEVICE_ERROR(pipeline.GetBindGroupLayout(3));  // Past last defined BGL, error!
}

// Test that after explicitly creating a pipeline with a pipeline layout, calling
// GetBindGroupLayout reflects the same bind group layouts.
TEST_F(GetBindGroupLayoutTests, Reflection) {
    // This test works assuming Dawn Native's object deduplication.
    // Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
    // Native.
    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_EQ(pipeline.GetBindGroupLayout(0).Get(), bindGroupLayout.Get());
}

// 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) {
    // This test works assuming Dawn Native's object deduplication.
    // Getting the same pointer to equivalent bind group layouts is an implementation detail of Dawn
    // Native.
    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.entryPoint = "main";
    pipelineDesc.compute.module = utils::CreateShaderModule(device, R"(
        @compute @workgroup_size(1) fn main() {
        }
    )");
    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&pipelineDesc);

    EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), emptyBGL.Get());
    EXPECT_EQ(pipeline.GetBindGroupLayout(1).Get(), emptyBGL.Get());
    EXPECT_EQ(pipeline.GetBindGroupLayout(2).Get(), emptyBGL.Get());
    EXPECT_EQ(pipeline.GetBindGroupLayout(3).Get(), emptyBGL.Get());
}

}  // anonymous namespace
}  // namespace dawn
