Update BindGroupTests to use WGSL

Bug: dawn:572
Change-Id: I1e7cd05ff184f7d26a75006d10b216aea28abb04
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/32513
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/tests/end2end/BindGroupTests.cpp b/src/tests/end2end/BindGroupTests.cpp
index eb31624..a47388d 100644
--- a/src/tests/end2end/BindGroupTests.cpp
+++ b/src/tests/end2end/BindGroupTests.cpp
@@ -45,11 +45,17 @@
     }
 
     wgpu::ShaderModule MakeSimpleVSModule() const {
-        return utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
-        #version 450
-        void main() {
-            const vec2 pos[3] = vec2[3](vec2(-1.f, 1.f), vec2(1.f, 1.f), vec2(-1.f, -1.f));
-            gl_Position = vec4(pos[gl_VertexIndex], 0.f, 1.f);
+        return utils::CreateShaderModuleFromWGSL(device, R"(
+        [[builtin(vertex_idx)]] var<in> VertexIndex : u32;
+        [[builtin(position)]] var<out> Position : vec4<f32>;
+
+        [[stage(vertex)]] fn main() -> void {
+             const pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>(
+                vec2<f32>(-1.0, 1.0),
+                vec2<f32>( 1.0, 1.0),
+                vec2<f32>(-1.0, -1.0));
+
+            Position = vec4<f32>(pos[VertexIndex], 0.0, 1.0);
         })");
     }
 
@@ -57,43 +63,33 @@
         ASSERT(bindingTypes.size() <= kMaxBindGroups);
 
         std::ostringstream fs;
-        fs << R"(
-        #version 450
-        layout(location = 0) out vec4 fragColor;
-        )";
+        fs << "[[location(0)]] var<out> fragColor : vec4<f32>;\n";
 
         for (size_t i = 0; i < bindingTypes.size(); ++i) {
+            fs << "[[block]] struct Buffer" << i << R"( {
+                [[offset(0)]] color : vec4<f32>;
+            };)";
+
             switch (bindingTypes[i]) {
                 case wgpu::BufferBindingType::Uniform:
-                    fs << "layout (std140, set = " << i << ", binding = 0) uniform UniformBuffer"
-                       << i << R"( {
-                        vec4 color;
-                    } buffer)"
-                       << i << ";\n";
+                    fs << "\n[[set(" << i << "), binding(0)]] var<uniform> buffer" << i
+                       << " : Buffer" << i << ";";
                     break;
                 case wgpu::BufferBindingType::Storage:
-                    fs << "layout (std430, set = " << i << ", binding = 0) buffer StorageBuffer"
-                       << i << R"( {
-                        vec4 color;
-                    } buffer)"
-                       << i << ";\n";
+                    fs << "\n[[set(" << i << "), binding(0)]] var<storage_buffer> buffer" << i
+                       << " : [[access(read)]] Buffer" << i << ";";
                     break;
                 default:
                     UNREACHABLE();
             }
         }
 
-        fs << R"(
-        void main() {
-            fragColor = vec4(0.0);
-        )";
+        fs << "\n[[stage(fragment)]] fn main() -> void {\n";
         for (size_t i = 0; i < bindingTypes.size(); ++i) {
-            fs << "fragColor += buffer" << i << ".color;\n";
+            fs << "fragColor = fragColor + buffer" << i << ".color;\n";
         }
         fs << "}\n";
-
-        return utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment,
-                                         fs.str().c_str());
+        return utils::CreateShaderModuleFromWGSL(device, fs.str().c_str());
     }
 
     wgpu::RenderPipeline MakeTestPipeline(const utils::BasicRenderPass& renderPass,
@@ -123,17 +119,14 @@
 // Test a bindgroup reused in two command buffers in the same call to queue.Submit().
 // This test passes by not asserting or crashing.
 TEST_P(BindGroupTests, ReusedBindGroupSingleSubmit) {
-    const char* shader = R"(
-        #version 450
-        layout(std140, set = 0, binding = 0) uniform Contents {
-            float f;
-        } contents;
-        void main() {
-        }
-    )";
+    wgpu::ShaderModule module = utils::CreateShaderModuleFromWGSL(device, R"(
+        [[block]] struct Contents {
+            [[offset(0)]] f : f32;
+        };
+        [[set(0), binding(0)]] var <uniform> contents: Contents;
 
-    wgpu::ShaderModule module =
-        utils::CreateShaderModule(device, utils::SingleShaderStage::Compute, shader);
+        [[stage(compute)]] fn main() -> void {
+        })");
 
     wgpu::ComputePipelineDescriptor cpDesc;
     cpDesc.computeStage.module = module;
@@ -163,26 +156,39 @@
 
     utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
 
-    wgpu::ShaderModule vsModule =
-        utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
-        #version 450
-        layout (set = 0, binding = 0) uniform vertexUniformBuffer {
-            mat2 transform;
+    wgpu::ShaderModule vsModule = utils::CreateShaderModuleFromWGSL(device, R"(
+        # TODO(crbug.com/tint/369): Use a mat2x2 when Tint translates it correctly.
+        [[block]] struct VertexUniformBuffer {
+            [[offset(0)]] transform : vec4<f32>;
         };
-        void main() {
-            const vec2 pos[3] = vec2[3](vec2(-1.f, 1.f), vec2(1.f, 1.f), vec2(-1.f, -1.f));
-            gl_Position = vec4(transform * pos[gl_VertexIndex], 0.f, 1.f);
+
+        [[set(0), binding(0)]] var <uniform> vertexUbo : VertexUniformBuffer;
+
+        [[builtin(vertex_idx)]] var<in> VertexIndex : u32;
+        [[builtin(position)]] var<out> Position : vec4<f32>;
+
+        [[stage(vertex)]] fn main() -> void {
+            const pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>(
+                vec2<f32>(-1.0, 1.0),
+                vec2<f32>( 1.0, 1.0),
+                vec2<f32>(-1.0, -1.0));
+
+            var transform : mat2x2<f32> = mat2x2<f32>(
+                vec2<f32>(vertexUbo.transform[0], vertexUbo.transform[1]),
+                vec2<f32>(vertexUbo.transform[2], vertexUbo.transform[3]));
+            Position = vec4<f32>(transform * pos[VertexIndex], 0.0, 1.0);
         })");
 
-    wgpu::ShaderModule fsModule =
-        utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
-        #version 450
-        layout (set = 0, binding = 1) uniform fragmentUniformBuffer {
-            vec4 color;
+    wgpu::ShaderModule fsModule = utils::CreateShaderModuleFromWGSL(device, R"(
+        [[block]] struct FragmentUniformBuffer {
+            [[offset(0)]] color : vec4<f32>;
         };
-        layout(location = 0) out vec4 fragColor;
-        void main() {
-            fragColor = color;
+        [[set(0), binding(1)]] var <uniform> fragmentUbo : FragmentUniformBuffer;
+
+        [[location(0)]] var<out> fragColor : vec4<f32>;
+
+        [[stage(fragment)]] fn main() -> void {
+            fragColor = fragmentUbo.color;
         })");
 
     utils::ComboRenderPipelineDescriptor textureDescriptor(device);
@@ -198,9 +204,8 @@
         float color[4];
     };
     ASSERT(offsetof(Data, color) == 256);
-    constexpr float dummy = 0.0f;
     Data data{
-        {1.f, 0.f, dummy, dummy, 0.f, 1.0f, dummy, dummy},
+        {1.f, 0.f, 0.f, 1.0f},
         {0},
         {0.f, 1.f, 0.f, 1.f},
     };
@@ -239,25 +244,37 @@
 
     utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
 
-    wgpu::ShaderModule vsModule =
-        utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
-        #version 450
-        layout (set = 0, binding = 0) uniform vertexUniformBuffer {
-            mat2 transform;
+    wgpu::ShaderModule vsModule = utils::CreateShaderModuleFromWGSL(device, R"(
+        # TODO(crbug.com/tint/369): Use a mat2x2 when Tint translates it correctly.
+        [[block]] struct VertexUniformBuffer {
+            [[offset(0)]] transform : vec4<f32>;
         };
-        void main() {
-            const vec2 pos[3] = vec2[3](vec2(-1.f, 1.f), vec2(1.f, 1.f), vec2(-1.f, -1.f));
-            gl_Position = vec4(transform * pos[gl_VertexIndex], 0.f, 1.f);
+        [[set(0), binding(0)]] var <uniform> vertexUbo : VertexUniformBuffer;
+
+        [[builtin(vertex_idx)]] var<in> VertexIndex : u32;
+        [[builtin(position)]] var<out> Position : vec4<f32>;
+
+        [[stage(vertex)]] fn main() -> void {
+            const pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>(
+                vec2<f32>(-1.0, 1.0),
+                vec2<f32>( 1.0, 1.0),
+                vec2<f32>(-1.0, -1.0));
+
+            var transform : mat2x2<f32> = mat2x2<f32>(
+                vec2<f32>(vertexUbo.transform[0], vertexUbo.transform[1]),
+                vec2<f32>(vertexUbo.transform[2], vertexUbo.transform[3]));
+            Position = vec4<f32>(transform * pos[VertexIndex], 0.0, 1.0);
         })");
 
-    wgpu::ShaderModule fsModule =
-        utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
-        #version 450
-        layout (set = 0, binding = 1) uniform sampler samp;
-        layout (set = 0, binding = 2) uniform texture2D tex;
-        layout (location = 0) out vec4 fragColor;
-        void main() {
-            fragColor = texture(sampler2D(tex, samp), gl_FragCoord.xy);
+    wgpu::ShaderModule fsModule = utils::CreateShaderModuleFromWGSL(device, R"(
+        [[set(0), binding(1)]] var <uniform_constant> samp : sampler;
+        [[set(0), binding(2)]] var <uniform_constant> tex : texture_2d<f32>;
+        [[builtin(frag_coord)]] var<in> FragCoord : vec4<f32>;
+
+        [[location(0)]] var<out> fragColor : vec4<f32>;
+
+        [[stage(fragment)]] fn main() -> void {
+            fragColor = textureSample(tex, samp, FragCoord.xy);
         })");
 
     utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);
@@ -267,8 +284,7 @@
 
     wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDescriptor);
 
-    constexpr float dummy = 0.0f;
-    constexpr float transform[] = {1.f, 0.f, dummy, dummy, 0.f, 1.f, dummy, dummy};
+    constexpr float transform[] = {1.f, 0.f, 0.f, 1.f};
     wgpu::Buffer buffer = utils::CreateBufferFromData(device, &transform, sizeof(transform),
                                                       wgpu::BufferUsage::Uniform);
 
@@ -343,32 +359,54 @@
 
     utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
 
-    wgpu::ShaderModule vsModule =
-        utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
-        #version 450
-        layout (set = 0, binding = 0) uniform vertexUniformBuffer1 {
-            mat2 transform1;
+    wgpu::ShaderModule vsModule = utils::CreateShaderModuleFromWGSL(device, R"(
+        # TODO(crbug.com/tint/369): Use a mat2x2 when Tint translates it correctly.
+        # TODO(crbug.com/tint/386): Use the same struct.
+        [[block]] struct VertexUniformBuffer1 {
+            [[offset(0)]] transform : vec4<f32>;
         };
-        layout (set = 1, binding = 0) uniform vertexUniformBuffer2 {
-            mat2 transform2;
+
+        [[block]] struct VertexUniformBuffer2 {
+            [[offset(0)]] transform : vec4<f32>;
         };
-        void main() {
-            const vec2 pos[3] = vec2[3](vec2(-1.f, 1.f), vec2(1.f, 1.f), vec2(-1.f, -1.f));
-            gl_Position = vec4((transform1 + transform2) * pos[gl_VertexIndex], 0.f, 1.f);
+
+        # TODO(crbug.com/tint/386): Use the same struct definition.
+        [[set(0), binding(0)]] var <uniform> vertexUbo1 : VertexUniformBuffer1;
+        [[set(1), binding(0)]] var <uniform> vertexUbo2 : VertexUniformBuffer2;
+
+        [[builtin(vertex_idx)]] var<in> VertexIndex : u32;
+        [[builtin(position)]] var<out> Position : vec4<f32>;
+
+        [[stage(vertex)]] fn main() -> void {
+            const pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>(
+                vec2<f32>(-1.0, 1.0),
+                vec2<f32>( 1.0, 1.0),
+                vec2<f32>(-1.0, -1.0));
+
+            Position = vec4<f32>(mat2x2<f32>(
+                vertexUbo1.transform.xy + vertexUbo2.transform.xy,
+                vertexUbo1.transform.zw + vertexUbo2.transform.zw
+            ) * pos[VertexIndex], 0.0, 1.0);
         })");
 
-    wgpu::ShaderModule fsModule =
-        utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
-        #version 450
-        layout (set = 0, binding = 1) uniform fragmentUniformBuffer1 {
-            vec4 color1;
+    wgpu::ShaderModule fsModule = utils::CreateShaderModuleFromWGSL(device, R"(
+        # TODO(crbug.com/tint/386): Use the same struct
+        [[block]] struct FragmentUniformBuffer1 {
+            [[offset(0)]] color : vec4<f32>;
         };
-        layout (set = 1, binding = 1) uniform fragmentUniformBuffer2 {
-            vec4 color2;
+
+        [[block]] struct FragmentUniformBuffer2 {
+            [[offset(0)]] color : vec4<f32>;
         };
-        layout(location = 0) out vec4 fragColor;
-        void main() {
-            fragColor = color1 + color2;
+
+        # TODO(crbug.com/tint/386): Use the same struct definition.
+        [[set(0), binding(1)]] var <uniform> fragmentUbo1 : FragmentUniformBuffer1;
+        [[set(1), binding(1)]] var <uniform> fragmentUbo2 : FragmentUniformBuffer2;
+
+        [[location(0)]] var<out> fragColor : vec4<f32>;
+
+        [[stage(fragment)]] fn main() -> void {
+            fragColor = fragmentUbo1.color + fragmentUbo2.color;
         })");
 
     utils::ComboRenderPipelineDescriptor textureDescriptor(device);
@@ -379,8 +417,8 @@
     wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&textureDescriptor);
 
     struct Data {
-        float transform[8];
-        char padding[256 - 8 * sizeof(float)];
+        float transform[4];
+        char padding[256 - 4 * sizeof(float)];
         float color[4];
     };
     ASSERT(offsetof(Data, color) == 256);
@@ -389,11 +427,9 @@
     std::vector<wgpu::Buffer> buffers;
     std::vector<wgpu::BindGroup> bindGroups;
 
-    data.push_back(
-        {{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, {0}, {0.0f, 1.0f, 0.0f, 1.0f}});
+    data.push_back({{1.0f, 0.0f, 0.0f, 0.0f}, {0}, {0.0f, 1.0f, 0.0f, 1.0f}});
 
-    data.push_back(
-        {{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}, {0}, {1.0f, 0.0f, 0.0f, 1.0f}});
+    data.push_back({{0.0f, 0.0f, 0.0f, 1.0f}, {0}, {1.0f, 0.0f, 0.0f, 1.0f}});
 
     for (int i = 0; i < 2; i++) {
         wgpu::Buffer buffer =
@@ -809,25 +845,32 @@
                                                      });
 
     wgpu::ComputePipelineDescriptor pipelineDescriptor;
-    pipelineDescriptor.computeStage.module =
-        utils::CreateShaderModule(device, utils::SingleShaderStage::Compute, R"(
-        #version 450
-        layout(std140, set = 0, binding = 2) uniform Buffer2 {
-            uint value2;
+    pipelineDescriptor.computeStage.module = utils::CreateShaderModuleFromWGSL(device, R"(
+        # TODO(crbug.com/tint/386): Use the same struct
+        [[block]] struct Buffer0 {
+            [[offset(0)]] value : u32;
         };
-        layout(std430, set = 0, binding = 3) readonly buffer Buffer3 {
-            uint value3;
+
+        [[block]] struct Buffer2 {
+            [[offset(0)]] value : u32;
         };
-        layout(std430, set = 0, binding = 0) readonly buffer Buffer0 {
-            uint value0;
+
+        [[block]] struct Buffer3 {
+            [[offset(0)]] value : u32;
         };
-        layout(std430, set = 0, binding = 4) buffer OutputBuffer {
-            uvec3 outputBuffer;
+
+        [[block]] struct OutputBuffer {
+            [[offset(0)]] value : vec3<u32>;
         };
-        void main() {
-            outputBuffer = uvec3(value0, value2, value3);
-        }
-    )");
+
+        [[set(0), binding(2)]] var<uniform> buffer2 : Buffer2;
+        [[set(0), binding(3)]] var<storage_buffer> buffer3 : [[access(read)]] Buffer3;
+        [[set(0), binding(0)]] var<storage_buffer> buffer0 : [[access(read)]] Buffer0;
+        [[set(0), binding(4)]] var<storage_buffer> outputBuffer : [[access(read_write)]] OutputBuffer;
+
+        [[stage(compute)]] fn main() -> void {
+            outputBuffer.value = vec3<u32>(buffer0.value, buffer2.value, buffer3.value);
+        })");
     pipelineDescriptor.computeStage.entryPoint = "main";
     pipelineDescriptor.layout = utils::MakeBasicPipelineLayout(device, &bgl);
     wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&pipelineDescriptor);
@@ -917,29 +960,42 @@
 TEST_P(BindGroupTests, ArbitraryBindingNumbers) {
     utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
 
-    wgpu::ShaderModule vsModule =
-        utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
-        #version 450
-        void main() {
-            const vec2 pos[3] = vec2[3](vec2(-1.f, 1.f), vec2(1.f, 1.f), vec2(-1.f, -1.f));
-            gl_Position = vec4(pos[gl_VertexIndex], 0.f, 1.f);
+    wgpu::ShaderModule vsModule = utils::CreateShaderModuleFromWGSL(device, R"(
+        [[builtin(vertex_idx)]] var<in> VertexIndex : u32;
+        [[builtin(position)]] var<out> Position : vec4<f32>;
+
+        [[stage(vertex)]] fn main() -> void {
+            const pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>(
+                vec2<f32>(-1.0, 1.0),
+                vec2<f32>( 1.0, 1.0),
+                vec2<f32>(-1.0, -1.0));
+
+            Position = vec4<f32>(pos[VertexIndex], 0.0, 1.0);
         })");
 
-    wgpu::ShaderModule fsModule =
-        utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
-        #version 450
-        layout (set = 0, binding = 953) uniform ubo1 {
-            vec4 color1;
+    wgpu::ShaderModule fsModule = utils::CreateShaderModuleFromWGSL(device, R"(
+        # TODO(crbug.com/tint/386): Use the same struct
+        [[block]] struct Ubo1 {
+            [[offset(0)]] color : vec4<f32>;
         };
-        layout (set = 0, binding = 47) uniform ubo2 {
-            vec4 color2;
+
+        [[block]] struct Ubo2 {
+            [[offset(0)]] color : vec4<f32>;
         };
-        layout (set = 0, binding = 111) uniform ubo3 {
-            vec4 color3;
+
+        [[block]] struct Ubo3 {
+            [[offset(0)]] color : vec4<f32>;
         };
-        layout(location = 0) out vec4 fragColor;
-        void main() {
-            fragColor = color1 + 2 * color2 + 4 * color3;
+
+        # TODO(crbug.com/tint/386): Use the same struct definition.
+        [[set(0), binding(953)]] var <uniform> ubo1 : Ubo1;
+        [[set(0), binding(47)]] var <uniform> ubo2 : Ubo2;
+        [[set(0), binding(111)]] var <uniform> ubo3 : Ubo3;
+
+        [[location(0)]] var<out> fragColor : vec4<f32>;
+
+        [[stage(fragment)]] fn main() -> void {
+            fragColor = ubo1.color + 2.0 * ubo2.color + 4.0 * ubo3.color;
         })");
 
     utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);
@@ -1037,10 +1093,8 @@
     wgpu::ComputePipelineDescriptor pipelineDesc;
     pipelineDesc.layout = utils::MakeBasicPipelineLayout(device, &bgl);
     pipelineDesc.computeStage.entryPoint = "main";
-    pipelineDesc.computeStage.module =
-        utils::CreateShaderModule(device, utils::SingleShaderStage::Compute, R"(
-        #version 450
-        void main() {
+    pipelineDesc.computeStage.module = utils::CreateShaderModuleFromWGSL(device, R"(
+        [[stage(compute)]] fn main() -> void {
         })");
 
     wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&pipelineDesc);
@@ -1062,24 +1116,29 @@
 TEST_P(BindGroupTests, ReadonlyStorage) {
     utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);
 
-    pipelineDescriptor.vertexStage.module =
-        utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
-            #version 450
-            void main() {
-                const vec2 pos[3] = vec2[3](vec2(-1.f, 1.f), vec2(1.f, 1.f), vec2(-1.f, -1.f));
-                gl_Position = vec4(pos[gl_VertexIndex], 0.f, 1.f);
-            })");
+    pipelineDescriptor.vertexStage.module = utils::CreateShaderModuleFromWGSL(device, R"(
+        [[builtin(vertex_idx)]] var<in> VertexIndex : u32;
+        [[builtin(position)]] var<out> Position : vec4<f32>;
 
-    pipelineDescriptor.cFragmentStage.module =
-        utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
-            #version 450
-            layout(set = 0, binding = 0) readonly buffer buffer0 {
-                vec4 color;
-            };
-            layout(location = 0) out vec4 fragColor;
-            void main() {
-                fragColor = color;
-            })");
+        [[stage(vertex)]] fn main() -> void {
+            const pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>(
+                vec2<f32>(-1.0, 1.0),
+                vec2<f32>( 1.0, 1.0),
+                vec2<f32>(-1.0, -1.0));
+
+            Position = vec4<f32>(pos[VertexIndex], 0.0, 1.0);
+        })");
+
+    pipelineDescriptor.cFragmentStage.module = utils::CreateShaderModuleFromWGSL(device, R"(
+        [[block]] struct Buffer0 {
+            [[offset(0)]] color : vec4<f32>;
+        };
+        [[set(0), binding(0)]] var<storage_buffer> buffer0 : [[access(read)]] Buffer0;
+
+        [[location(0)]] var<out> fragColor : vec4<f32>;
+        [[stage(fragment)]] fn main() -> void {
+            fragColor = buffer0.color;
+        })");
 
     constexpr uint32_t kRTSize = 4;
     utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
@@ -1115,22 +1174,27 @@
 // buffer if all values are correct.
 TEST_P(BindGroupTests, ReallyLargeBindGroup) {
     DAWN_SKIP_TEST_IF(IsOpenGLES());
-    std::string interface = "#version 450\n";
-    std::string body;
+    std::ostringstream interface;
+    std::ostringstream body;
     uint32_t binding = 0;
     uint32_t expectedValue = 42;
 
     wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
 
-    auto CreateTextureWithRedData = [&](uint32_t value, wgpu::TextureUsage usage) {
+    auto CreateTextureWithRedData = [&](wgpu::TextureFormat format, uint32_t value,
+                                        wgpu::TextureUsage usage) {
         wgpu::TextureDescriptor textureDesc = {};
         textureDesc.usage = wgpu::TextureUsage::CopyDst | usage;
         textureDesc.size = {1, 1, 1};
-        textureDesc.format = wgpu::TextureFormat::R32Uint;
+        textureDesc.format = format;
         wgpu::Texture texture = device.CreateTexture(&textureDesc);
 
+        if (format == wgpu::TextureFormat::R8Unorm) {
+            ASSERT(expectedValue < 255u);
+        }
         wgpu::Buffer textureData =
-            utils::CreateBufferFromData(device, wgpu::BufferUsage::CopySrc, {expectedValue});
+            utils::CreateBufferFromData(device, wgpu::BufferUsage::CopySrc, {value});
+
         wgpu::BufferCopyView bufferCopyView = {};
         bufferCopyView.buffer = textureData;
         bufferCopyView.layout.bytesPerRow = 256;
@@ -1147,52 +1211,55 @@
     std::vector<wgpu::BindGroupEntry> bgEntries;
     static_assert(kMaxSampledTexturesPerShaderStage == kMaxSamplersPerShaderStage,
                   "Please update this test");
-    body += "result = 0;\n";
     for (uint32_t i = 0; i < kMaxSampledTexturesPerShaderStage; ++i) {
-        wgpu::Texture texture =
-            CreateTextureWithRedData(expectedValue, wgpu::TextureUsage::Sampled);
+        wgpu::Texture texture = CreateTextureWithRedData(
+            wgpu::TextureFormat::R8Unorm, expectedValue, wgpu::TextureUsage::Sampled);
         bgEntries.push_back({binding, nullptr, 0, 0, nullptr, texture.CreateView()});
 
-        interface += "layout(set = 0, binding = " + std::to_string(binding++) +
-                     ") uniform utexture2D tex" + std::to_string(i) + ";\n";
+        interface << "[[set(0), binding(" << binding++ << ")]] "
+                  << "var<uniform_constant> tex" << i << " : texture_2d<f32>;\n";
 
         wgpu::SamplerDescriptor samplerDesc = {};
         bgEntries.push_back({binding, nullptr, 0, 0, device.CreateSampler(&samplerDesc), nullptr});
 
-        interface += "layout(set = 0, binding = " + std::to_string(binding++) +
-                     ") uniform sampler samp" + std::to_string(i) + ";\n";
+        interface << "[[set(0), binding(" << binding++ << ")]]"
+                  << "var<uniform_constant> samp" << i << " : sampler;\n";
 
-        body += "if (texelFetch(usampler2D(tex" + std::to_string(i) + ", samp" + std::to_string(i) +
-                "), ivec2(0, 0), 0).r != " + std::to_string(expectedValue++) + ") {\n";
-        body += "    return;\n";
-        body += "}\n";
+        body << "if (abs(textureSampleLevel(tex" << i << ", samp" << i
+             << ", vec2<f32>(0.5, 0.5), 0.0).r - " << expectedValue++
+             << ".0 / 255.0) > 0.0001) {\n";
+        body << "    return;\n";
+        body << "}\n";
     }
     for (uint32_t i = 0; i < kMaxStorageTexturesPerShaderStage; ++i) {
-        wgpu::Texture texture =
-            CreateTextureWithRedData(expectedValue, wgpu::TextureUsage::Storage);
+        wgpu::Texture texture = CreateTextureWithRedData(
+            wgpu::TextureFormat::R32Uint, expectedValue, wgpu::TextureUsage::Storage);
         bgEntries.push_back({binding, nullptr, 0, 0, nullptr, texture.CreateView()});
 
-        interface += "layout(set = 0, binding = " + std::to_string(binding++) +
-                     ", r32ui) uniform readonly uimage2D image" + std::to_string(i) + ";\n";
+        interface << "[[set(0), binding(" << binding++ << ")]] "
+                  << "var<uniform_constant> image" << i << " : texture_storage_ro_2d<r32uint>;\n";
 
-        body += "if (imageLoad(image" + std::to_string(i) +
-                ", ivec2(0, 0)).r != " + std::to_string(expectedValue++) + ") {\n";
-        body += "    return;\n";
-        body += "}\n";
+        body << "if (textureLoad(image" << i << ", vec2<i32>(0, 0)).r != " << expectedValue++
+             << "u) {\n";
+        body << "    return;\n";
+        body << "}\n";
     }
+
     for (uint32_t i = 0; i < kMaxUniformBuffersPerShaderStage; ++i) {
         wgpu::Buffer buffer = utils::CreateBufferFromData<uint32_t>(
             device, wgpu::BufferUsage::Uniform, {expectedValue, 0, 0, 0});
         bgEntries.push_back({binding, buffer, 0, 4 * sizeof(uint32_t), nullptr, nullptr});
 
-        interface += "layout(std140, set = 0, binding = " + std::to_string(binding++) +
-                     ") uniform UBuf" + std::to_string(i) + " {\n";
-        interface += "    uint ubuf" + std::to_string(i) + ";\n";
-        interface += "};\n";
+        interface << "[[block]] struct UniformBuffer" << i << R"({
+                [[offset(0)]] value : u32;
+            };
+        )";
+        interface << "[[set(0), binding(" << binding++ << ")]] "
+                  << "var<uniform> ubuf" << i << " : UniformBuffer" << i << ";\n";
 
-        body += "if (ubuf" + std::to_string(i) + " != " + std::to_string(expectedValue++) + ") {\n";
-        body += "    return;\n";
-        body += "}\n";
+        body << "if (ubuf" << i << ".value != " << expectedValue++ << "u) {\n";
+        body << "    return;\n";
+        body << "}\n";
     }
     // Save one storage buffer for writing the result
     for (uint32_t i = 0; i < kMaxStorageBuffersPerShaderStage - 1; ++i) {
@@ -1200,32 +1267,36 @@
             device, wgpu::BufferUsage::Storage, {expectedValue});
         bgEntries.push_back({binding, buffer, 0, sizeof(uint32_t), nullptr, nullptr});
 
-        interface += "layout(std430, set = 0, binding = " + std::to_string(binding++) +
-                     ") readonly buffer SBuf" + std::to_string(i) + " {\n";
-        interface += "    uint sbuf" + std::to_string(i) + ";\n";
-        interface += "};\n";
+        interface << "[[block]] struct ReadOnlyStorageBuffer" << i << R"({
+                [[offset(0)]] value : u32;
+            };
+        )";
+        interface << "[[set(0), binding(" << binding++ << ")]] "
+                  << "var<storage_buffer> sbuf" << i << " : [[access(read)]] ReadOnlyStorageBuffer"
+                  << i << ";\n";
 
-        body += "if (sbuf" + std::to_string(i) + " != " + std::to_string(expectedValue++) + ") {\n";
-        body += "    return;\n";
-        body += "}\n";
+        body << "if (sbuf" << i << ".value != " << expectedValue++ << "u) {\n";
+        body << "    return;\n";
+        body << "}\n";
     }
 
     wgpu::Buffer result = utils::CreateBufferFromData<uint32_t>(
         device, wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc, {0});
     bgEntries.push_back({binding, result, 0, sizeof(uint32_t), nullptr, nullptr});
 
-    interface += "layout(std430, set = 0, binding = " + std::to_string(binding++) +
-                 ") writeonly buffer Result {\n";
-    interface += "    uint result;\n";
-    interface += "};\n";
+    interface << R"([[block]] struct ReadWriteStorageBuffer{
+            [[offset(0)]] value : u32;
+        };
+    )";
+    interface << "[[set(0), binding(" << binding++ << ")]] "
+              << "var<storage_buffer> result : [[access(read_write)]] ReadWriteStorageBuffer;\n";
 
-    body += "result = 1;\n";
+    body << "result.value = 1u;\n";
 
-    std::string shader = interface + "void main() {\n" + body + "}\n";
-
+    std::string shader =
+        interface.str() + "[[stage(compute)]] fn main() -> void {\n" + body.str() + "}\n";
     wgpu::ComputePipelineDescriptor cpDesc;
-    cpDesc.computeStage.module =
-        utils::CreateShaderModule(device, utils::SingleShaderStage::Compute, shader.c_str());
+    cpDesc.computeStage.module = utils::CreateShaderModuleFromWGSL(device, shader.c_str());
     cpDesc.computeStage.entryPoint = "main";
     wgpu::ComputePipeline cp = device.CreateComputePipeline(&cpDesc);