Fix bugs about TextureViewDesc's default values

TextureViewDescriptor's default values for dimension and
arrayLayerCount in Dawn are not correct according to WebGPU spec.
This change fixes these bugs.

Bug: dawn:760
Change-Id: Ic1d069838d6c0f7bb1afa1dceaf73e91bdfdb20a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/58020
Commit-Queue: Yunchao He <yunchao.he@intel.com>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn_native/Texture.cpp b/src/dawn_native/Texture.cpp
index d9567d5..8d6bc55 100644
--- a/src/dawn_native/Texture.cpp
+++ b/src/dawn_native/Texture.cpp
@@ -362,11 +362,7 @@
                     break;
 
                 case wgpu::TextureDimension::e2D:
-                    if (texture->GetArrayLayers() > 1u && desc.arrayLayerCount == 0) {
-                        desc.dimension = wgpu::TextureViewDimension::e2DArray;
-                    } else {
-                        desc.dimension = wgpu::TextureViewDimension::e2D;
-                    }
+                    desc.dimension = wgpu::TextureViewDimension::e2D;
                     break;
 
                 case wgpu::TextureDimension::e3D:
@@ -380,7 +376,22 @@
             desc.format = texture->GetFormat().format;
         }
         if (desc.arrayLayerCount == 0) {
-            desc.arrayLayerCount = texture->GetArrayLayers() - desc.baseArrayLayer;
+            switch (desc.dimension) {
+                case wgpu::TextureViewDimension::e1D:
+                case wgpu::TextureViewDimension::e2D:
+                case wgpu::TextureViewDimension::e3D:
+                    desc.arrayLayerCount = 1;
+                    break;
+                case wgpu::TextureViewDimension::Cube:
+                    desc.arrayLayerCount = 6;
+                    break;
+                case wgpu::TextureViewDimension::e2DArray:
+                case wgpu::TextureViewDimension::CubeArray:
+                    desc.arrayLayerCount = texture->GetArrayLayers() - desc.baseArrayLayer;
+                    break;
+                default:
+                    UNREACHABLE();
+            }
         }
         if (desc.mipLevelCount == 0) {
             desc.mipLevelCount = texture->GetNumMipLevels() - desc.baseMipLevel;
diff --git a/src/tests/end2end/StorageTextureTests.cpp b/src/tests/end2end/StorageTextureTests.cpp
index c8cb6a0..47e082c 100644
--- a/src/tests/end2end/StorageTextureTests.cpp
+++ b/src/tests/end2end/StorageTextureTests.cpp
@@ -583,8 +583,10 @@
             << fragmentShader;
     }
 
-    void CheckResultInStorageBuffer(wgpu::Texture readonlyStorageTexture,
-                                    const std::string& computeShader) {
+    void CheckResultInStorageBuffer(
+        wgpu::Texture readonlyStorageTexture,
+        const std::string& computeShader,
+        wgpu::TextureViewDimension dimension = wgpu::TextureViewDimension::e2D) {
         wgpu::ComputePipeline pipeline = CreateComputePipeline(computeShader.c_str());
 
         // Clear the content of the result buffer into 0.
@@ -592,9 +594,11 @@
         wgpu::Buffer resultBuffer =
             utils::CreateBufferFromData(device, &kInitialValue, sizeof(kInitialValue),
                                         wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc);
-        wgpu::BindGroup bindGroup =
-            utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
-                                 {{0, readonlyStorageTexture.CreateView()}, {1, resultBuffer}});
+        wgpu::TextureViewDescriptor descriptor;
+        descriptor.dimension = dimension;
+        wgpu::BindGroup bindGroup = utils::MakeBindGroup(
+            device, pipeline.GetBindGroupLayout(0),
+            {{0, readonlyStorageTexture.CreateView(&descriptor)}, {1, resultBuffer}});
 
         wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
         wgpu::ComputePassEncoder computeEncoder = encoder.BeginComputePass();
@@ -635,12 +639,17 @@
         queue.Submit(1, &commandBuffer);
     }
 
-    void WriteIntoStorageTextureInComputePass(wgpu::Texture writeonlyStorageTexture,
-                                              const char* computeShader) {
+    void WriteIntoStorageTextureInComputePass(
+        wgpu::Texture writeonlyStorageTexture,
+        const char* computeShader,
+        wgpu::TextureViewDimension dimension = wgpu::TextureViewDimension::e2D) {
         // Create a compute pipeline that writes the expected pixel values into the storage texture.
+        wgpu::TextureViewDescriptor descriptor;
+        descriptor.dimension = dimension;
         wgpu::ComputePipeline pipeline = CreateComputePipeline(computeShader);
-        wgpu::BindGroup bindGroup = utils::MakeBindGroup(
-            device, pipeline.GetBindGroupLayout(0), {{0, writeonlyStorageTexture.CreateView()}});
+        wgpu::BindGroup bindGroup =
+            utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
+                                 {{0, writeonlyStorageTexture.CreateView(&descriptor)}});
 
         wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
         wgpu::ComputePassEncoder computePassEncoder = encoder.BeginComputePass();
@@ -652,14 +661,19 @@
         queue.Submit(1, &commandBuffer);
     }
 
-    void ReadWriteIntoStorageTextureInComputePass(wgpu::Texture readonlyStorageTexture,
-                                                  wgpu::Texture writeonlyStorageTexture,
-                                                  const char* computeShader) {
+    void ReadWriteIntoStorageTextureInComputePass(
+        wgpu::Texture readonlyStorageTexture,
+        wgpu::Texture writeonlyStorageTexture,
+        const char* computeShader,
+        wgpu::TextureViewDimension dimension = wgpu::TextureViewDimension::e2D) {
         // Create a compute pipeline that writes the expected pixel values into the storage texture.
+        wgpu::TextureViewDescriptor descriptor;
+        descriptor.dimension = dimension;
         wgpu::ComputePipeline pipeline = CreateComputePipeline(computeShader);
-        wgpu::BindGroup bindGroup = utils::MakeBindGroup(
-            device, pipeline.GetBindGroupLayout(0),
-            {{0, writeonlyStorageTexture.CreateView()}, {1, readonlyStorageTexture.CreateView()}});
+        wgpu::BindGroup bindGroup =
+            utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
+                                 {{0, writeonlyStorageTexture.CreateView(&descriptor)},
+                                  {1, readonlyStorageTexture.CreateView(&descriptor)}});
 
         wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
         wgpu::ComputePassEncoder computePassEncoder = encoder.BeginComputePass();
@@ -991,7 +1005,7 @@
   }
 })";
 
-        CheckResultInStorageBuffer(readonlyStorageTexture, csStream.str());
+        CheckResultInStorageBuffer(readonlyStorageTexture, csStream.str(), dimension);
     }
 }
 
@@ -1018,7 +1032,8 @@
         // Write the expected pixel values into the write-only storage texture.
         const std::string computeShader =
             CommonWriteOnlyTestCode("compute", kTextureFormat, dimension);
-        WriteIntoStorageTextureInComputePass(writeonlyStorageTexture, computeShader.c_str());
+        WriteIntoStorageTextureInComputePass(writeonlyStorageTexture, computeShader.c_str(),
+                                             dimension);
 
         // Verify the pixel data in the write-only storage texture is expected.
         CheckOutputStorageTexture(writeonlyStorageTexture, kTextureFormat, kSliceCount);
@@ -1053,7 +1068,7 @@
         // Read values from read-only storage texture and write into the write-only storage texture.
         const std::string computeShader = CommonReadWriteTestCode(kTextureFormat, dimension);
         ReadWriteIntoStorageTextureInComputePass(readonlyStorageTexture, writeonlyStorageTexture,
-                                                 computeShader.c_str());
+                                                 computeShader.c_str(), dimension);
 
         // Verify the data in the write-only storage texture is expected.
         CheckOutputStorageTexture(writeonlyStorageTexture, kTextureFormat, kSliceCount);
diff --git a/src/tests/end2end/TextureViewTests.cpp b/src/tests/end2end/TextureViewTests.cpp
index a4387b0..61116d2 100644
--- a/src/tests/end2end/TextureViewTests.cpp
+++ b/src/tests/end2end/TextureViewTests.cpp
@@ -361,7 +361,9 @@
     constexpr uint32_t kMipLevels = 1;
     initTexture(kLayers, kMipLevels);
 
-    wgpu::TextureView textureView = mTexture.CreateView();
+    wgpu::TextureViewDescriptor descriptor;
+    descriptor.dimension = wgpu::TextureViewDimension::e2DArray;
+    wgpu::TextureView textureView = mTexture.CreateView(&descriptor);
 
     const char* fragmentShader = R"(
             [[group(0), binding(0)]] var sampler0 : sampler;
diff --git a/src/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp b/src/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp
index 4505398..abbc379 100644
--- a/src/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp
+++ b/src/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp
@@ -559,7 +559,9 @@
         wgpu::Texture resolveTexture =
             CreateTexture(device, wgpu::TextureDimension::e2D, kColorFormat, kSize, kSize,
                           kArrayLayers2, kLevelCount);
-        wgpu::TextureView resolveTextureView = resolveTexture.CreateView();
+        wgpu::TextureViewDescriptor viewDesc;
+        viewDesc.dimension = wgpu::TextureViewDimension::e2DArray;
+        wgpu::TextureView resolveTextureView = resolveTexture.CreateView(&viewDesc);
 
         utils::ComboRenderPassDescriptor renderPass = CreateMultisampledRenderPass();
         renderPass.cColorAttachments[0].resolveTarget = resolveTextureView;
diff --git a/src/tests/unittests/validation/TextureViewValidationTests.cpp b/src/tests/unittests/validation/TextureViewValidationTests.cpp
index 31ad3c1..e60ba91 100644
--- a/src/tests/unittests/validation/TextureViewValidationTests.cpp
+++ b/src/tests/unittests/validation/TextureViewValidationTests.cpp
@@ -288,7 +288,7 @@
     // specifying the values they're supposed to default to.
     // Variant for a 2D texture with more than 1 array layer.
     TEST_F(TextureViewValidationTest, TextureViewDescriptorDefaults2DArray) {
-        constexpr uint32_t kDefaultArrayLayers = 6;
+        constexpr uint32_t kDefaultArrayLayers = 8;
         wgpu::Texture texture = Create2DArrayTexture(device, kDefaultArrayLayers);
 
         { texture.CreateView(); }
@@ -307,7 +307,25 @@
             texture.CreateView(&descriptor);
             descriptor.dimension = wgpu::TextureViewDimension::e2DArray;
             texture.CreateView(&descriptor);
+            // Setting view dimension to 2D, its arrayLayer will default to 1. And view creation
+            // will success.
             descriptor.dimension = wgpu::TextureViewDimension::e2D;
+            texture.CreateView(&descriptor);
+            // Setting view dimension to Cube, its arrayLayer will default to 6.
+            descriptor.dimension = wgpu::TextureViewDimension::Cube;
+            texture.CreateView(&descriptor);
+            descriptor.baseArrayLayer = 2;
+            texture.CreateView(&descriptor);
+            descriptor.baseArrayLayer = 3;
+            ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
+            // Setting view dimension to CubeArray, its arrayLayer will default to
+            // size.depthOrArrayLayers (kDefaultArrayLayers) - baseArrayLayer.
+            descriptor.dimension = wgpu::TextureViewDimension::CubeArray;
+            descriptor.baseArrayLayer = 0;
+            ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
+            descriptor.baseArrayLayer = 2;
+            texture.CreateView(&descriptor);
+            descriptor.baseArrayLayer = 3;
             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
         }
         {