Validate that DS attachment must cover all aspects of the texture.

It isn't clear if this should be a limitation of the WebGPU
specification. Until further investigation is done, disallow it in Dawn
to avoid undefiend behavior.

Bug: dawn:812
Change-Id: Iab8208f1ea479263b08ede41374ce1a680ce191e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/53387
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp
index 7676a49..2e1c605 100644
--- a/src/dawn_native/CommandEncoder.cpp
+++ b/src/dawn_native/CommandEncoder.cpp
@@ -286,12 +286,23 @@
             DAWN_TRY(
                 ValidateCanUseAs(attachment->GetTexture(), wgpu::TextureUsage::RenderAttachment));
 
-            if ((attachment->GetAspects() & (Aspect::Depth | Aspect::Stencil)) == Aspect::None ||
-                !attachment->GetFormat().isRenderable) {
+            const Format& format = attachment->GetFormat();
+            if (!format.HasDepthOrStencil()) {
                 return DAWN_VALIDATION_ERROR(
                     "The format of the texture view used as depth stencil attachment is not a "
                     "depth stencil format");
             }
+            if (!format.isRenderable) {
+                return DAWN_VALIDATION_ERROR(
+                    "The format of the texture view used as depth stencil attachment is not "
+                    "renderable");
+            }
+            if (attachment->GetAspects() != format.aspects) {
+                // TODO(https://crbug.com/dawn/812): Investigate if this limitation should be added
+                // to the WebGPU spec of lifted from Dawn.
+                return DAWN_VALIDATION_ERROR(
+                    "The texture view used as depth stencil view must encompass all aspects");
+            }
 
             DAWN_TRY(ValidateLoadOp(depthStencilAttachment->depthLoadOp));
             DAWN_TRY(ValidateLoadOp(depthStencilAttachment->stencilLoadOp));
diff --git a/src/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp b/src/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp
index 06ee368..f82a6cb 100644
--- a/src/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp
+++ b/src/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp
@@ -880,6 +880,62 @@
         }
     }
 
+    // Check that the depth stencil attachment must use all aspects.
+    TEST_F(RenderPassDescriptorValidationTest, ValidateDepthStencilAllAspects) {
+        wgpu::TextureDescriptor texDesc;
+        texDesc.usage = wgpu::TextureUsage::RenderAttachment;
+        texDesc.size = {1, 1, 1};
+
+        wgpu::TextureViewDescriptor viewDesc;
+        viewDesc.baseMipLevel = 0;
+        viewDesc.mipLevelCount = 1;
+        viewDesc.baseArrayLayer = 0;
+        viewDesc.arrayLayerCount = 1;
+
+        // Using all aspects of a depth+stencil texture is allowed.
+        {
+            texDesc.format = wgpu::TextureFormat::Depth24PlusStencil8;
+            viewDesc.aspect = wgpu::TextureAspect::All;
+
+            wgpu::TextureView view = device.CreateTexture(&texDesc).CreateView(&viewDesc);
+            utils::ComboRenderPassDescriptor renderPass({}, view);
+            AssertBeginRenderPassSuccess(&renderPass);
+        }
+
+        // Using only depth of a depth+stencil texture is an error.
+        {
+            texDesc.format = wgpu::TextureFormat::Depth24PlusStencil8;
+            viewDesc.aspect = wgpu::TextureAspect::DepthOnly;
+
+            wgpu::TextureView view = device.CreateTexture(&texDesc).CreateView(&viewDesc);
+            utils::ComboRenderPassDescriptor renderPass({}, view);
+            AssertBeginRenderPassError(&renderPass);
+        }
+
+        // Using only stencil of a depth+stencil texture is an error.
+        {
+            texDesc.format = wgpu::TextureFormat::Depth24PlusStencil8;
+            viewDesc.aspect = wgpu::TextureAspect::StencilOnly;
+
+            wgpu::TextureView view = device.CreateTexture(&texDesc).CreateView(&viewDesc);
+            utils::ComboRenderPassDescriptor renderPass({}, view);
+            AssertBeginRenderPassError(&renderPass);
+        }
+
+        // Using DepthOnly of a depth only texture us allowed.
+        {
+            texDesc.format = wgpu::TextureFormat::Depth24Plus;
+            viewDesc.aspect = wgpu::TextureAspect::DepthOnly;
+
+            wgpu::TextureView view = device.CreateTexture(&texDesc).CreateView(&viewDesc);
+            utils::ComboRenderPassDescriptor renderPass({}, view);
+            AssertBeginRenderPassSuccess(&renderPass);
+        }
+
+        // TODO(https://crbug.com/dawn/666): Add a test case for stencil-only on stencil8 once this
+        // format is supported.
+    }
+
     // TODO(cwallez@chromium.org): Constraints on attachment aliasing?
 
 }  // anonymous namespace