Fix a bug for 3D texture clear on D3D12

When we clear an uninitialized 3D texture, we should clear all depth
slices for each mip level. The current implementation only clears one
slice (the first slice) for each mip level. This change fixes this
bug. Dawn end2end tests of NonzeroTextureCreationTests can pass with
this fix. These tests fail on D3D12 without the fix.

This change also renames arguments for GetRTVDescriptor() for 3D
texture: change baseArrayLayer/layerCount to baseSlice/sliceCount.

Bug: dawn:547
Change-Id: Ic56f28e9e6430058c31aaa2bb21f4e42f7b7621c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/57840
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
Commit-Queue: Yunchao He <yunchao.he@intel.com>
diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp
index 044d7ce..61f9411 100644
--- a/src/dawn_native/d3d12/TextureD3D12.cpp
+++ b/src/dawn_native/d3d12/TextureD3D12.cpp
@@ -810,15 +810,15 @@
     }
 
     D3D12_RENDER_TARGET_VIEW_DESC Texture::GetRTVDescriptor(uint32_t mipLevel,
-                                                            uint32_t baseArrayLayer,
-                                                            uint32_t layerCount) const {
+                                                            uint32_t baseSlice,
+                                                            uint32_t sliceCount) const {
         D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
         rtvDesc.Format = GetD3D12Format();
         if (IsMultisampledTexture()) {
             ASSERT(GetDimension() == wgpu::TextureDimension::e2D);
             ASSERT(GetNumMipLevels() == 1);
-            ASSERT(layerCount == 1);
-            ASSERT(baseArrayLayer == 0);
+            ASSERT(sliceCount == 1);
+            ASSERT(baseSlice == 0);
             ASSERT(mipLevel == 0);
             rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS;
             return rtvDesc;
@@ -832,16 +832,16 @@
                 // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_array
                 // _rtv
                 rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
-                rtvDesc.Texture2DArray.FirstArraySlice = baseArrayLayer;
-                rtvDesc.Texture2DArray.ArraySize = layerCount;
+                rtvDesc.Texture2DArray.FirstArraySlice = baseSlice;
+                rtvDesc.Texture2DArray.ArraySize = sliceCount;
                 rtvDesc.Texture2DArray.MipSlice = mipLevel;
                 rtvDesc.Texture2DArray.PlaneSlice = 0;
                 break;
             case wgpu::TextureDimension::e3D:
                 rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D;
                 rtvDesc.Texture3D.MipSlice = mipLevel;
-                rtvDesc.Texture3D.FirstWSlice = baseArrayLayer;
-                rtvDesc.Texture3D.WSize = layerCount;
+                rtvDesc.Texture3D.FirstWSlice = baseSlice;
+                rtvDesc.Texture3D.WSize = sliceCount;
                 break;
             case wgpu::TextureDimension::e1D:
                 UNREACHABLE();
@@ -953,7 +953,14 @@
                         device->GetRenderTargetViewAllocator()->AllocateTransientCPUDescriptors());
                     const D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetBaseDescriptor();
 
-                    D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = GetRTVDescriptor(level, layer, 1);
+                    uint32_t baseSlice = layer;
+                    uint32_t sliceCount = 1;
+                    if (GetDimension() == wgpu::TextureDimension::e3D) {
+                        baseSlice = 0;
+                        sliceCount = std::max(GetDepth() >> level, 1u);
+                    }
+                    D3D12_RENDER_TARGET_VIEW_DESC rtvDesc =
+                        GetRTVDescriptor(level, baseSlice, sliceCount);
                     device->GetD3D12Device()->CreateRenderTargetView(GetD3D12Resource(), &rtvDesc,
                                                                      rtvHandle);
                     commandList->ClearRenderTargetView(rtvHandle, clearColorRGBA, 0, nullptr);
diff --git a/src/dawn_native/d3d12/TextureD3D12.h b/src/dawn_native/d3d12/TextureD3D12.h
index 6356800..9082ffc 100644
--- a/src/dawn_native/d3d12/TextureD3D12.h
+++ b/src/dawn_native/d3d12/TextureD3D12.h
@@ -55,8 +55,8 @@
         DXGI_FORMAT GetD3D12CopyableSubresourceFormat(Aspect aspect) const;
 
         D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor(uint32_t mipLevel,
-                                                       uint32_t baseArrayLayer,
-                                                       uint32_t layerCount) const;
+                                                       uint32_t baseSlice,
+                                                       uint32_t sliceCount) const;
         D3D12_DEPTH_STENCIL_VIEW_DESC GetDSVDescriptor(uint32_t mipLevel,
                                                        uint32_t baseArrayLayer,
                                                        uint32_t layerCount) const;
diff --git a/src/tests/end2end/NonzeroTextureCreationTests.cpp b/src/tests/end2end/NonzeroTextureCreationTests.cpp
index 0274631..4903e35 100644
--- a/src/tests/end2end/NonzeroTextureCreationTests.cpp
+++ b/src/tests/end2end/NonzeroTextureCreationTests.cpp
@@ -92,10 +92,9 @@
             DAWN_TEST_UNSUPPORTED_IF(GetParam().mFormat == wgpu::TextureFormat::RGBA8Snorm &&
                                      HasToggleEnabled("disable_snorm_read"));
 
-            // TODO(crbug.com/dawn/547): 3D texture copies not fully implemented on D3D12.
             // TODO(crbug.com/angleproject/5967): This texture readback hits an assert in ANGLE.
             DAWN_SUPPRESS_TEST_IF(GetParam().mDimension == wgpu::TextureDimension::e3D &&
-                                  (IsANGLE() || IsD3D12()));
+                                  IsANGLE());
 
             // TODO(crbug.com/dawn/791): Determine Intel specific platforms this occurs on, and
             // implement a workaround on all backends (happens on Windows too, but not on our test