Clamp clearStencilValue into the range of stencil format

This patch clamps clearStencilValue into the range of the stencil
format to align with the latest change in WebGPU SPEC.

Bug: dawn:1453
Test: dawn_end2end_tests
Change-Id: I37fab5fd4826a608cb972eed74308114002c7930
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/92750
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/native/CommandEncoder.cpp b/src/dawn/native/CommandEncoder.cpp
index 51fee4b..197e0c0 100644
--- a/src/dawn/native/CommandEncoder.cpp
+++ b/src/dawn/native/CommandEncoder.cpp
@@ -891,6 +891,15 @@
                     cmd->depthStencilAttachment.clearStencil =
                         descriptor->depthStencilAttachment->stencilClearValue;
                 }
+                if (view->GetFormat().HasStencil()) {
+                    // GPURenderPassDepthStencilAttachment.stencilClearValue will be converted to
+                    // the type of the stencil aspect of view by taking the same number of LSBs as
+                    // the number of bits in the stencil aspect of one texel block of view.
+                    ASSERT(view->GetFormat()
+                               .GetAspectInfo(dawn::native::Aspect::Stencil)
+                               .block.byteSize == 1u);
+                    cmd->depthStencilAttachment.clearStencil &= 0xFF;
+                }
 
                 cmd->depthStencilAttachment.depthReadOnly =
                     descriptor->depthStencilAttachment->depthReadOnly;
diff --git a/src/dawn/tests/end2end/DepthStencilLoadOpTests.cpp b/src/dawn/tests/end2end/DepthStencilLoadOpTests.cpp
index 9f27263..0c61f20 100644
--- a/src/dawn/tests/end2end/DepthStencilLoadOpTests.cpp
+++ b/src/dawn/tests/end2end/DepthStencilLoadOpTests.cpp
@@ -257,7 +257,7 @@
 
 namespace {
 
-auto GenerateParams() {
+auto GenerateParam() {
     auto params1 = MakeParamGenerator<DepthStencilLoadOpTestParams>(
         {D3D12Backend(), D3D12Backend({}, {"use_d3d12_render_pass"}), MetalBackend(),
          OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
@@ -280,8 +280,50 @@
 
 INSTANTIATE_TEST_SUITE_P(,
                          DepthStencilLoadOpTests,
-                         ::testing::ValuesIn(GenerateParams()),
+                         ::testing::ValuesIn(GenerateParam()),
                          DawnTestBase::PrintToStringParamName("DepthStencilLoadOpTests"));
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DepthStencilLoadOpTests);
 
+class StencilClearValueOverflowTest : public DepthStencilLoadOpTests {};
+
+// Test when stencilClearValue overflows uint8_t (>255), only the last 8 bits will be applied as the
+// stencil clear value in encoder.BeginRenderPass() (currently Dawn only supports 8-bit stencil
+// format).
+TEST_P(StencilClearValueOverflowTest, StencilClearValueOverFlowUint8) {
+    constexpr uint32_t kOverflowedStencilValue = kStencilValues[0] + 0x100;
+    renderPassDescriptors[0].cDepthStencilAttachmentInfo.stencilClearValue =
+        kOverflowedStencilValue;
+
+    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+    encoder.BeginRenderPass(&renderPassDescriptors[0]).End();
+    wgpu::CommandBuffer commandBuffer = encoder.Finish();
+    queue.Submit(1, &commandBuffer);
+
+    CheckMipLevel(0u);
+}
+
+// Test when stencilClearValue overflows uint16_t(>65535), only the last 8 bits will be applied as
+// the stencil clear value in encoder.BeginRenderPass() (currently Dawn only supports 8-bit stencil
+// format).
+TEST_P(StencilClearValueOverflowTest, StencilClearValueOverFlowUint16) {
+    constexpr uint32_t kOverflowedStencilValue = kStencilValues[0] + 0x10000;
+    renderPassDescriptors[0].cDepthStencilAttachmentInfo.stencilClearValue =
+        kOverflowedStencilValue;
+
+    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+    encoder.BeginRenderPass(&renderPassDescriptors[0]).End();
+    wgpu::CommandBuffer commandBuffer = encoder.Finish();
+    queue.Submit(1, &commandBuffer);
+
+    CheckMipLevel(0u);
+}
+
+DAWN_INSTANTIATE_TEST_P(StencilClearValueOverflowTest,
+                        {D3D12Backend(), D3D12Backend({}, {"use_d3d12_render_pass"}),
+                         MetalBackend(), OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
+                        {wgpu::TextureFormat::Depth24PlusStencil8,
+                         wgpu::TextureFormat::Depth24UnormStencil8,
+                         wgpu::TextureFormat::Depth32FloatStencil8, wgpu::TextureFormat::Stencil8},
+                        {Check::CopyStencil, Check::StencilTest});
+
 }  // namespace