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

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

        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 : vec4<f32>
        }
        @group(0) @binding(0) var<uniform> uniform0 : S;
        @group(1) @binding(0) var<uniform> uniform1 : S;

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

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

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

        @stage(fragment) fn main() {
            var pos_u : vec4<f32> = 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 : vec4<f32>
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @stage(fragment) fn main() {
            var pos : vec4<f32> = 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 : vec4<f32>
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @stage(fragment) fn main() {
            var pos : vec4<f32> = 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;
        @stage(vertex) fn main() -> @builtin(position) vec4<f32> {
            _ = myTexture;
            _ = mySampler;
            return vec4<f32>();
        })");

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

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

    wgpu::ShaderModule unusedTextureFragmentModule = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var myTexture : texture_2d<f32>;
        @group(0) @binding(1) var mySampler : sampler;
        @stage(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;
        @stage(fragment) fn main() {
            textureLoad(myTexture, vec2<i32>(), 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;
        @stage(fragment) fn main() {
            textureSample(myTexture, mySampler, vec2<f32>());
        })");

    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(dawn::native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(emptyVertexModule, unusedTextureFragmentModule).Get(),
        nonFilteringBGL.Get()));
    EXPECT_FALSE(dawn::native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(emptyVertexModule, unusedTextureFragmentModule).Get(), filteringBGL.Get()));

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

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

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

    // Textures used with both textureLoad and textureSample default to filtering
    EXPECT_FALSE(dawn::native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(textureLoadVertexModule, textureSampleFragmentModule).Get(),
        nonFilteringBGL.Get()));
    EXPECT_TRUE(dawn::native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(textureLoadVertexModule, textureSampleFragmentModule).Get(),
        filteringBGL.Get()));
    EXPECT_FALSE(dawn::native::BindGroupLayoutBindingsEqualForTesting(
        BGLFromModules(textureSampleVertexModule, textureLoadFragmentModule).Get(),
        nonFilteringBGL.Get()));
    EXPECT_TRUE(dawn::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 : vec4<f32>
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

        @stage(compute) @workgroup_size(1) fn main() {
            var pos : vec4<f32> = 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(dawn::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 : vec4<f32>
            }
            @group(0) @binding(0) var<storage, read_write> ssbo : S;

            @stage(fragment) fn main() {
                var pos : vec4<f32> = ssbo.pos;
            })");
        EXPECT_TRUE(dawn::native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }
    {
        binding.buffer.type = wgpu::BufferBindingType::Uniform;
        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
            struct S {
                pos : vec4<f32>
            }
            @group(0) @binding(0) var<uniform> uniforms : S;

            @stage(fragment) fn main() {
                var pos : vec4<f32> = uniforms.pos;
            })");
        EXPECT_TRUE(dawn::native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

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

            @stage(fragment) fn main() {
                var pos : vec4<f32> = ssbo.pos;
            })");
        EXPECT_TRUE(dawn::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>;

            @stage(fragment) fn main() {
                textureDimensions(myTexture);
            })");
        EXPECT_TRUE(dawn::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>;

            @stage(fragment) fn main() {
                textureDimensions(myTexture);
            })");
        EXPECT_TRUE(dawn::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;

            @stage(fragment) fn main() {
                _ = mySampler;
            })");
        EXPECT_TRUE(dawn::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;

            @stage(fragment) fn main() {
               _ = myExternalTexture;
            })");
    EXPECT_TRUE(dawn::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>;

            @stage(fragment) fn main() {
                textureDimensions(myTexture);
            })");
        EXPECT_TRUE(dawn::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>;

            @stage(fragment) fn main() {
                textureDimensions(myTexture);
            })");
        EXPECT_TRUE(dawn::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>;

            @stage(fragment) fn main() {
                textureDimensions(myTexture);
            })");
        EXPECT_TRUE(dawn::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>;

            @stage(fragment) fn main() {
                textureDimensions(myTexture);
            })");
        EXPECT_TRUE(dawn::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>;

            @stage(fragment) fn main() {
                textureDimensions(myTexture);
            })");
        EXPECT_TRUE(dawn::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>;

            @stage(fragment) fn main() {
                textureDimensions(myTexture);
            })");
        EXPECT_TRUE(dawn::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>;

            @stage(fragment) fn main() {
                textureDimensions(myTexture);
            })");
        EXPECT_TRUE(dawn::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>;

            @stage(fragment) fn main() {
                textureDimensions(myTexture);
            })");
        EXPECT_TRUE(dawn::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>;

            @stage(fragment) fn main() {
                textureDimensions(myTexture);
            })");
        EXPECT_TRUE(dawn::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 : vec4<f32>
            }
            @group(0) @binding(0) var<uniform> uniforms : S;

            @stage(fragment) fn main() {
                var pos : vec4<f32> = uniforms.pos;
            })");
        EXPECT_TRUE(dawn::native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

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

            @stage(fragment) fn main() {
                var pos : vec4<f32> = uniforms.pos;
            })");
        EXPECT_TRUE(dawn::native::BindGroupLayoutBindingsEqualForTesting(
            device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()));
    }

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

            @stage(fragment) fn main() {
                var pos : vec4<f32> = uniforms.pos;
            })");
        EXPECT_FALSE(dawn::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 : vec4<f32>
        }
        @group(0) @binding(0) var<uniform> uniform0 : S;
        @group(1) @binding(0) var<uniform> uniform1 : S;

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

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

        @stage(fragment) fn main() {
            var pos : vec4<f32> = 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;

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

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

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

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

        @stage(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;

        @stage(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(dawn::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(dawn::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(dawn::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"(
        @stage(vertex) fn main() -> @builtin(position) vec4<f32> {
            return vec4<f32>();
        })");

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

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

    wgpu::ShaderModule fsModuleSampler = utils::CreateShaderModule(device, R"(
        @group(0) @binding(0) var mySampler: sampler;
        @stage(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(dawn::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(dawn::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(dawn::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 : vec4<f32>
        }
        @group(0) @binding(0) var<uniform> ubo : S;

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

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

        @stage(fragment) fn main() {
            var pos : vec4<f32> = 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>;

        @stage(vertex) fn main() -> @builtin(position) vec4<f32> {
            textureDimensions(myTexture);
            return vec4<f32>();
        })");

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

        @stage(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>;

        @stage(vertex) fn main() -> @builtin(position) vec4<f32> {
            textureDimensions(myTexture);
            return vec4<f32>();
        })");

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

        @stage(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>;

        @stage(vertex) fn main() -> @builtin(position) vec4<f32> {
            textureDimensions(myTexture);
            return vec4<f32>();
        })");

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

        @stage(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"(
        @stage(fragment) fn main() {
        })")
                            .GetBindGroupLayout(kMaxBindGroups));

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

// Test that unused indices return the empty bind group layout.
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 : vec4<f32>
        }
        @group(0) @binding(0) var<uniform> uniforms0 : S;
        @group(2) @binding(0) var<uniform> uniforms2 : S;

        @stage(fragment) fn main() {
            var pos : vec4<f32> = uniforms0.pos;
            pos = uniforms2.pos;
        })");

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

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

    EXPECT_FALSE(dawn::native::BindGroupLayoutBindingsEqualForTesting(
        pipeline.GetBindGroupLayout(0).Get(), emptyBindGroupLayout.Get()));  // Used
    EXPECT_TRUE(dawn::native::BindGroupLayoutBindingsEqualForTesting(
        pipeline.GetBindGroupLayout(1).Get(), emptyBindGroupLayout.Get()));  // Not Used.
    EXPECT_FALSE(dawn::native::BindGroupLayoutBindingsEqualForTesting(
        pipeline.GetBindGroupLayout(2).Get(), emptyBindGroupLayout.Get()));  // Used.
    EXPECT_TRUE(dawn::native::BindGroupLayoutBindingsEqualForTesting(
        pipeline.GetBindGroupLayout(3).Get(), emptyBindGroupLayout.Get()));  // Not used
}

// 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 : vec4<f32>
        }
        @group(0) @binding(0) var<uniform> uniforms : S;

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

    wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
        @stage(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());

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

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

        // Check that the rest of the bind group layouts reflect the empty one.
        EXPECT_EQ(pipeline.GetBindGroupLayout(1).Get(), emptyBindGroupLayout.Get());
        EXPECT_EQ(pipeline.GetBindGroupLayout(2).Get(), emptyBindGroupLayout.Get());
        EXPECT_EQ(pipeline.GetBindGroupLayout(3).Get(), emptyBindGroupLayout.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;

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

        @stage(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}}));
}
