webgpu.h: More trivial defaulting: BindGroupLayoutDescriptor

Implements the following sub-structures of BindGroupLayoutDescriptor.
Defaulting is done in the constructor, which (in most cases) is called
by a bounce through the backend.

- TextureBindingLayout.viewDimension: TextureViewDimension = 2D
- StorageTextureBindingLayout.viewDimension: TextureViewDimension = 2D

I couldn't find any end2end tests using explicit bind group layouts with
texture or storageTexture, so these are only spot-tested in the
GetBindGroupLayout caching tests (which won't hit the backends but will
verify that defaulting is applied to cache keys).

Bug: dawn:2224
Change-Id: Ie1173ada37c65ab28f71f63f7786c7441fc12306
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/166823
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/native/BindGroupLayoutInternal.cpp b/src/dawn/native/BindGroupLayoutInternal.cpp
index 4228f53..273a930 100644
--- a/src/dawn/native/BindGroupLayoutInternal.cpp
+++ b/src/dawn/native/BindGroupLayoutInternal.cpp
@@ -401,6 +401,7 @@
     } else if (binding->texture.sampleType != wgpu::TextureSampleType::Undefined) {
         bindingInfo.bindingType = BindingInfoType::Texture;
         bindingInfo.texture = binding->texture;
+        bindingInfo.texture.ApplyTrivialFrontendDefaults();
 
         if (binding->texture.viewDimension == wgpu::TextureViewDimension::Undefined) {
             bindingInfo.texture.viewDimension = wgpu::TextureViewDimension::e2D;
@@ -408,6 +409,7 @@
     } else if (binding->storageTexture.access != wgpu::StorageTextureAccess::Undefined) {
         bindingInfo.bindingType = BindingInfoType::StorageTexture;
         bindingInfo.storageTexture = binding->storageTexture;
+        bindingInfo.storageTexture.ApplyTrivialFrontendDefaults();
 
         if (binding->storageTexture.viewDimension == wgpu::TextureViewDimension::Undefined) {
             bindingInfo.storageTexture.viewDimension = wgpu::TextureViewDimension::e2D;
diff --git a/src/dawn/tests/unittests/validation/GetBindGroupLayoutValidationTests.cpp b/src/dawn/tests/unittests/validation/GetBindGroupLayoutValidationTests.cpp
index b948a9c..bd6b8c0 100644
--- a/src/dawn/tests/unittests/validation/GetBindGroupLayoutValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/GetBindGroupLayoutValidationTests.cpp
@@ -466,7 +466,7 @@
 }
 
 // Test that texture view dimension matches the shader.
-TEST_F(GetBindGroupLayoutTests, ViewDimension) {
+TEST_F(GetBindGroupLayoutTests, TextureViewDimension) {
     DAWN_SKIP_TEST_IF(UsesWire());
 
     wgpu::BindGroupLayoutEntry binding = {};
@@ -500,6 +500,11 @@
             })");
         EXPECT_THAT(device.CreateBindGroupLayout(&desc),
                     BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
+
+        // viewDimension defaults to 2D, so should be cached the same.
+        binding.texture.viewDimension = wgpu::TextureViewDimension::Undefined;
+        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
+                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
     }
 
     {
@@ -551,6 +556,74 @@
     }
 }
 
+// Test that storageTexture view dimension matches the shader.
+TEST_F(GetBindGroupLayoutTests, StorageTextureViewDimension) {
+    DAWN_SKIP_TEST_IF(UsesWire());
+
+    wgpu::BindGroupLayoutEntry binding = {};
+    binding.binding = 0;
+    binding.visibility = wgpu::ShaderStage::Fragment;
+    binding.storageTexture.access = wgpu::StorageTextureAccess::WriteOnly;
+    binding.storageTexture.format = wgpu::TextureFormat::R32Float;
+
+    wgpu::BindGroupLayoutDescriptor desc = {};
+    desc.entryCount = 1;
+    desc.entries = &binding;
+
+    {
+        binding.storageTexture.viewDimension = wgpu::TextureViewDimension::e1D;
+        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
+            @group(0) @binding(0) var myTexture : texture_storage_1d<r32float, write>;
+
+            @fragment fn main() {
+                _ = textureDimensions(myTexture);
+            })");
+        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
+                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
+    }
+
+    {
+        binding.storageTexture.viewDimension = wgpu::TextureViewDimension::e2D;
+        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
+            @group(0) @binding(0) var myTexture : texture_storage_2d<r32float, write>;
+
+            @fragment fn main() {
+                _ = textureDimensions(myTexture);
+            })");
+        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
+                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
+
+        // viewDimension defaults to 2D, so should be cached the same.
+        binding.storageTexture.viewDimension = wgpu::TextureViewDimension::Undefined;
+        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
+                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
+    }
+
+    {
+        binding.storageTexture.viewDimension = wgpu::TextureViewDimension::e2DArray;
+        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
+            @group(0) @binding(0) var myTexture : texture_storage_2d_array<r32float, write>;
+
+            @fragment fn main() {
+                _ = textureDimensions(myTexture);
+            })");
+        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
+                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
+    }
+
+    {
+        binding.storageTexture.viewDimension = wgpu::TextureViewDimension::e3D;
+        wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
+            @group(0) @binding(0) var myTexture : texture_storage_3d<r32float, write>;
+
+            @fragment fn main() {
+                _ = textureDimensions(myTexture);
+            })");
+        EXPECT_THAT(device.CreateBindGroupLayout(&desc),
+                    BindGroupLayoutCacheEq(pipeline.GetBindGroupLayout(0)));
+    }
+}
+
 // Test that texture component type matches the shader.
 TEST_F(GetBindGroupLayoutTests, TextureComponentType) {
     DAWN_SKIP_TEST_IF(UsesWire());