[Compat] Fix BlitR8ToStencil for compat tex view array layer restrictions

In compat mode, we have the spec restriction that
array texture views used in bind groups must consist
of the entire array.

Pass base layer via uniform buffer instead of texture view.

Bug: dawn:42241333
Change-Id: I36738d53fb4efac38192f2f8e40b7c5d97b09a55
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/196237
Reviewed-by: Stephen White <senorblanco@chromium.org>
Reviewed-by: Brandon Jones <bajones@chromium.org>
Reviewed-by: Gregg Tavares <gman@chromium.org>
Commit-Queue: Shrek Shao <shrekshao@google.com>
diff --git a/src/dawn/native/BlitBufferToDepthStencil.cpp b/src/dawn/native/BlitBufferToDepthStencil.cpp
index f47b1c4..9ee91f7 100644
--- a/src/dawn/native/BlitBufferToDepthStencil.cpp
+++ b/src/dawn/native/BlitBufferToDepthStencil.cpp
@@ -88,14 +88,15 @@
 
 constexpr std::string_view kTexture2DArrayHead = R"(
 fn textureLoadGeneral(tex: texture_2d_array<u32>, coords: vec2u, level: u32) -> vec4<u32> {
-    return textureLoad(tex, coords, 0u, level);
+    return textureLoad(tex, coords, params.layer, level);
 }
 @group(0) @binding(0) var src_tex : texture_2d_array<u32>;
 )";
 
 constexpr std::string_view kBlitStencilShaderCommon = R"(
 struct Params {
-  origin : vec2u
+  origin : vec2u,
+  layer: u32,
 };
 @group(0) @binding(1) var<uniform> params : Params;
 
@@ -372,7 +373,7 @@
     if (device->IsCompatibilityMode()) {
         textureViewDimension = dataTexture->GetCompatibilityTextureBindingViewDimension();
     } else {
-        textureViewDimension = wgpu::TextureViewDimension::e2D;
+        textureViewDimension = wgpu::TextureViewDimension::e2DArray;
     }
 
     // This bgl is the same for all the render pipelines.
@@ -388,7 +389,7 @@
         bglEntries[1].binding = 1;
         bglEntries[1].visibility = wgpu::ShaderStage::Fragment;
         bglEntries[1].buffer.type = wgpu::BufferBindingType::Uniform;
-        bglEntries[1].buffer.minBindingSize = 2 * sizeof(uint32_t);
+        bglEntries[1].buffer.minBindingSize = 4 * sizeof(uint32_t);
 
         BindGroupLayoutDescriptor bglDesc = {};
         bglDesc.entryCount = bglEntries.size();
@@ -405,27 +406,35 @@
     Ref<BufferBase> paramsBuffer;
     {
         BufferDescriptor bufferDesc = {};
-        bufferDesc.size = sizeof(uint32_t) * 2;
-        bufferDesc.usage = wgpu::BufferUsage::Uniform;
+        bufferDesc.size = sizeof(uint32_t) * 4;
+        bufferDesc.usage = wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopyDst;
         bufferDesc.mappedAtCreation = true;
         DAWN_TRY_ASSIGN(paramsBuffer, device->CreateBuffer(&bufferDesc));
 
         uint32_t* params = static_cast<uint32_t*>(paramsBuffer->GetMappedRange(0, bufferDesc.size));
         params[0] = dst.origin.x;
         params[1] = dst.origin.y;
+        params[2] = 0;
         DAWN_TRY(paramsBuffer->Unmap());
     }
 
+    Ref<TextureViewBase> srcView;
+    {
+        TextureViewDescriptor viewDesc = {};
+        viewDesc.dimension = textureViewDimension;
+        // Array layer in texture views used in bind groups must consist of the entire array.
+        viewDesc.baseArrayLayer = 0;
+        viewDesc.arrayLayerCount = dataTexture->GetArrayLayers();
+        viewDesc.mipLevelCount = 1;
+        DAWN_TRY_ASSIGN(srcView, dataTexture->CreateView(&viewDesc));
+    }
+
     // For each layer, blit the stencil data.
     for (uint32_t z = 0; z < copyExtent.depthOrArrayLayers; ++z) {
-        Ref<TextureViewBase> srcView;
-        {
-            TextureViewDescriptor viewDesc = {};
-            viewDesc.dimension = textureViewDimension;
-            viewDesc.baseArrayLayer = z;
-            viewDesc.arrayLayerCount = 1;
-            viewDesc.mipLevelCount = 1;
-            DAWN_TRY_ASSIGN(srcView, dataTexture->CreateView(&viewDesc));
+        if (z >= 1) {
+            // Pass the array layer info via the uniform buffer.
+            commandEncoder->APIWriteBuffer(paramsBuffer.Get(), sizeof(uint32_t) * 2,
+                                           reinterpret_cast<const uint8_t*>(&z), sizeof(uint32_t));
         }
 
         Ref<TextureViewBase> dstView;
diff --git a/src/dawn/tests/end2end/QueueTests.cpp b/src/dawn/tests/end2end/QueueTests.cpp
index 04f7e6f..4f3c25c 100644
--- a/src/dawn/tests/end2end/QueueTests.cpp
+++ b/src/dawn/tests/end2end/QueueTests.cpp
@@ -320,13 +320,6 @@
 
 class QueueWriteTextureTests : public DawnTestWithParams<WriteTextureFormatParams> {
   protected:
-    void SetUp() override {
-        DawnTestWithParams::SetUp();
-        // TODO(crbug.com/dawn/2391): Stencil8 format is failing on OpenGLES; needs
-        // investigation.
-        DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && GetParam().mTextureFormat == TextureFormat::Stencil8);
-    }
-
     static DataSpec MinimumDataSpec(wgpu::Extent3D writeSize,
                                     uint32_t overrideBytesPerRow = kStrideComputeDefault,
                                     uint32_t overrideRowsPerImage = kStrideComputeDefault) {
@@ -633,12 +626,15 @@
 // Test with bytesPerRow greater than needed for cube textures.
 // Made for testing compat behavior.
 TEST_P(QueueWriteTextureTests, VaryingBytesPerRowCube) {
+    auto format = GetParam().mTextureFormat;
     // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 4 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsQualcomm());
     // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 6 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
     // TODO(crbug.com/dawn/2131): diagnose this failure on Win Angle D3D11
     DAWN_SUPPRESS_TEST_IF(IsANGLED3D11());
+    // TODO(crbug.com/dawn/42241333): diagnose stencil8 failure on Angle Swiftshader
+    DAWN_SUPPRESS_TEST_IF(format == wgpu::TextureFormat::Stencil8 && IsANGLESwiftShader());
 
     constexpr uint32_t kWidth = 257;
     constexpr uint32_t kHeight = 257;
@@ -650,8 +646,7 @@
     auto TestBody = [&](wgpu::Origin3D copyOrigin, wgpu::Extent3D copyExtent) {
         textureSpec.copyOrigin = copyOrigin;
         for (unsigned int b : {1, 2, 3, 4}) {
-            uint32_t bytesPerRow =
-                copyExtent.width * utils::GetTexelBlockSizeInBytes(GetParam().mTextureFormat) + b;
+            uint32_t bytesPerRow = copyExtent.width * utils::GetTexelBlockSizeInBytes(format) + b;
             DoTest(textureSpec, MinimumDataSpec(copyExtent, bytesPerRow), copyExtent,
                    wgpu::TextureViewDimension::Cube);
         }
@@ -659,7 +654,7 @@
 
     TestBody({0, 0, 0}, textureSpec.textureSize);
 
-    if (utils::IsDepthOrStencilFormat(GetParam().mTextureFormat)) {
+    if (utils::IsDepthOrStencilFormat(format)) {
         // The entire subresource must be copied when the format is a depth/stencil format.
         return;
     }
diff --git a/webgpu-cts/compat-expectations.txt b/webgpu-cts/compat-expectations.txt
index 5f08d2f..5248a2f 100644
--- a/webgpu-cts/compat-expectations.txt
+++ b/webgpu-cts/compat-expectations.txt
@@ -191,17 +191,6 @@
 crbug.com/dawn/349420827 [ intel-0x9bc5 ] webgpu:shader,validation,expression,call,builtin,smoothstep:* [ Failure ]
 crbug.com/dawn/349420827 [ nvidia-0x2184 ] webgpu:shader,validation,expression,call,builtin,smoothstep:* [ Failure ]
 
-# stencil-only tests failing after the removal of the texture copy workaround
-crbug.com/343735745 webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth24plus-stencil8" [ Failure ]
-crbug.com/343735745 webgpu:api,operation,command_buffer,image_copy:offsets_and_sizes_copy_depth_stencil:format="depth24plus-stencil8";copyMethod="CopyB2T";aspect="stencil-only" [ Failure ]
-crbug.com/343735745 webgpu:api,operation,command_buffer,image_copy:offsets_and_sizes_copy_depth_stencil:format="depth24plus-stencil8";copyMethod="CopyT2B";aspect="stencil-only" [ Failure ]
-crbug.com/343735745 webgpu:api,operation,command_buffer,image_copy:offsets_and_sizes_copy_depth_stencil:format="depth24plus-stencil8";copyMethod="WriteTexture";aspect="stencil-only" [ Failure ]
-crbug.com/343735745 webgpu:api,operation,command_buffer,image_copy:offsets_and_sizes_copy_depth_stencil:format="stencil8";copyMethod="CopyB2T";aspect="stencil-only" [ Failure ]
-crbug.com/343735745 webgpu:api,operation,command_buffer,image_copy:rowsPerImage_and_bytesPerRow_depth_stencil:format="depth24plus-stencil8";copyMethod="CopyB2T";aspect="stencil-only" [ Failure ]
-crbug.com/343735745 webgpu:api,operation,command_buffer,image_copy:rowsPerImage_and_bytesPerRow_depth_stencil:format="depth24plus-stencil8";copyMethod="CopyT2B";aspect="stencil-only" [ Failure ]
-crbug.com/343735745 webgpu:api,operation,command_buffer,image_copy:rowsPerImage_and_bytesPerRow_depth_stencil:format="depth24plus-stencil8";copyMethod="WriteTexture";aspect="stencil-only" [ Failure ]
-crbug.com/343735745 webgpu:api,operation,command_buffer,image_copy:rowsPerImage_and_bytesPerRow_depth_stencil:format="stencil8";copyMethod="CopyB2T";aspect="stencil-only" [ Failure ]
-
 ### This section represents tests which may require CTS changes.
 
 # ANGLETextureSharing is not supported