D3D12: Allocate 2D textures with CopyDst as committed resources on Intel GPUs

This patch adds a workaround on Intel Gen9.5 and Gen11 GPUs to always
allocate 2D textures with CopyDst as committed resources instead of
placed resources to mitigate a driver bug about CreatePlacedResource().

Bug: chromium:1237175
Test: dawn_end2end_tests
Change-Id: I64ab9c083c8835fb2971660eed51252fecac416c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/100641
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/Toggles.cpp b/src/dawn/native/Toggles.cpp
index d16cbf5..ebee065 100644
--- a/src/dawn/native/Toggles.cpp
+++ b/src/dawn/native/Toggles.cpp
@@ -319,6 +319,12 @@
       "default on Qualcomm GPUs, which have been observed experiencing a driver crash in this "
       "situation.",
       "https://crbug.com/dawn/1564"}},
+    {Toggle::D3D12Allocate2DTexturewithCopyDstAsCommittedResource,
+     {"d3d12_allocate_2d_texture_with_copy_dst_as_committed_resource",
+      "Allocate each 2D texture with CopyDst usage as committed resources instead of placed "
+      "resources. This toggle is enabled by default on D3D12 backends using Intel Gen9.5 and Gen11 "
+      "GPUs due to a driver issue on Intel D3D12 driver.",
+      "https://crbug.com/1237175"}},
     // Comment to separate the }} so it is clearer what to copy-paste to add a toggle.
 }};
 }  // anonymous namespace
diff --git a/src/dawn/native/Toggles.h b/src/dawn/native/Toggles.h
index 36221ee..5a29de3 100644
--- a/src/dawn/native/Toggles.h
+++ b/src/dawn/native/Toggles.h
@@ -81,6 +81,7 @@
     ApplyClearBigIntegerColorValueWithDraw,
     MetalUseMockBlitEncoderForWriteTimestamp,
     VulkanSplitCommandBufferOnDepthStencilComputeSampleAfterRenderPass,
+    D3D12Allocate2DTexturewithCopyDstAsCommittedResource,
 
     EnumCount,
     InvalidEnum = EnumCount,
diff --git a/src/dawn/native/d3d12/DeviceD3D12.cpp b/src/dawn/native/d3d12/DeviceD3D12.cpp
index d26fefd..8c79f06 100644
--- a/src/dawn/native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/DeviceD3D12.cpp
@@ -565,10 +565,12 @@
     D3D12_HEAP_TYPE heapType,
     const D3D12_RESOURCE_DESC& resourceDescriptor,
     D3D12_RESOURCE_STATES initialUsage,
-    uint32_t formatBytesPerBlock) {
+    uint32_t formatBytesPerBlock,
+    bool forceAllocateAsCommittedResource) {
     // formatBytesPerBlock is needed only for color non-compressed formats for a workaround.
     return mResourceAllocatorManager->AllocateMemory(heapType, resourceDescriptor, initialUsage,
-                                                     formatBytesPerBlock);
+                                                     formatBytesPerBlock,
+                                                     forceAllocateAsCommittedResource);
 }
 
 std::unique_ptr<ExternalImageDXGIImpl> Device::CreateExternalImageDXGIImpl(
@@ -727,6 +729,13 @@
             SetToggle(Toggle::D3D12AllocateExtraMemoryFor2DArrayTexture, true);
         }
     }
+
+    // Currently this workaround is only needed on Intel Gen9.5 and Gen11 GPUs.
+    // See http://crbug.com/1237175 for more information.
+    if ((gpu_info::IsIntelGen9(vendorId, deviceId) && !gpu_info::IsSkylake(deviceId)) ||
+        gpu_info::IsIntelGen11(vendorId, deviceId)) {
+        SetToggle(Toggle::D3D12Allocate2DTexturewithCopyDstAsCommittedResource, true);
+    }
 }
 
 MaybeError Device::WaitForIdleForDestruction() {
diff --git a/src/dawn/native/d3d12/DeviceD3D12.h b/src/dawn/native/d3d12/DeviceD3D12.h
index ccd5cb0..a5255ed 100644
--- a/src/dawn/native/d3d12/DeviceD3D12.h
+++ b/src/dawn/native/d3d12/DeviceD3D12.h
@@ -119,7 +119,8 @@
         D3D12_HEAP_TYPE heapType,
         const D3D12_RESOURCE_DESC& resourceDescriptor,
         D3D12_RESOURCE_STATES initialUsage,
-        uint32_t formatBytesPerBlock);
+        uint32_t formatBytesPerBlock,
+        bool forceAllocateAsCommittedResource = false);
 
     void DeallocateMemory(ResourceHeapAllocation& allocation);
 
diff --git a/src/dawn/native/d3d12/ResourceAllocatorManagerD3D12.cpp b/src/dawn/native/d3d12/ResourceAllocatorManagerD3D12.cpp
index c63e348..201cd9c 100644
--- a/src/dawn/native/d3d12/ResourceAllocatorManagerD3D12.cpp
+++ b/src/dawn/native/d3d12/ResourceAllocatorManagerD3D12.cpp
@@ -306,6 +306,11 @@
     return 0;
 }
 
+bool ShouldAllocateAsCommittedResource(Device* device, bool forceAllocateAsCommittedResource) {
+    return forceAllocateAsCommittedResource ||
+           device->IsToggleEnabled(Toggle::DisableResourceSuballocation);
+}
+
 }  // namespace
 
 ResourceAllocatorManager::ResourceAllocatorManager(Device* device) : mDevice(device) {
@@ -329,7 +334,8 @@
     D3D12_HEAP_TYPE heapType,
     const D3D12_RESOURCE_DESC& resourceDescriptor,
     D3D12_RESOURCE_STATES initialUsage,
-    uint32_t formatBytesPerBlock) {
+    uint32_t formatBytesPerBlock,
+    bool forceAllocateAsCommittedResource) {
     // In order to suppress a warning in the D3D12 debug layer, we need to specify an
     // optimized clear value. As there are no negative consequences when picking a mismatched
     // clear value, we use zero as the optimized clear value. This also enables fast clears on
@@ -358,7 +364,7 @@
     // For very small resources, it is inefficent to suballocate given the min. heap
     // size could be much larger then the resource allocation.
     // Attempt to satisfy the request using sub-allocation (placed resource in a heap).
-    if (!mDevice->IsToggleEnabled(Toggle::DisableResourceSuballocation)) {
+    if (!ShouldAllocateAsCommittedResource(mDevice, forceAllocateAsCommittedResource)) {
         ResourceHeapAllocation subAllocation;
         DAWN_TRY_ASSIGN(subAllocation, CreatePlacedResource(heapType, revisedDescriptor,
                                                             optimizedClearValue, initialUsage));
diff --git a/src/dawn/native/d3d12/ResourceAllocatorManagerD3D12.h b/src/dawn/native/d3d12/ResourceAllocatorManagerD3D12.h
index 4c3e016..8f3ffb8 100644
--- a/src/dawn/native/d3d12/ResourceAllocatorManagerD3D12.h
+++ b/src/dawn/native/d3d12/ResourceAllocatorManagerD3D12.h
@@ -64,7 +64,8 @@
         D3D12_HEAP_TYPE heapType,
         const D3D12_RESOURCE_DESC& resourceDescriptor,
         D3D12_RESOURCE_STATES initialUsage,
-        uint32_t formatBytesPerBlock);
+        uint32_t formatBytesPerBlock,
+        bool forceAllocateAsCommittedResource = false);
 
     void DeallocateMemory(ResourceHeapAllocation& allocation);
 
diff --git a/src/dawn/native/d3d12/TextureD3D12.cpp b/src/dawn/native/d3d12/TextureD3D12.cpp
index a754821..9736bf6 100644
--- a/src/dawn/native/d3d12/TextureD3D12.cpp
+++ b/src/dawn/native/d3d12/TextureD3D12.cpp
@@ -611,9 +611,14 @@
     if (GetFormat().IsColor()) {
         bytesPerBlock = GetFormat().GetAspectInfo(wgpu::TextureAspect::All).block.byteSize;
     }
+    bool forceAllocateAsCommittedResource =
+        device->IsToggleEnabled(Toggle::D3D12Allocate2DTexturewithCopyDstAsCommittedResource) &&
+        GetDimension() == wgpu::TextureDimension::e2D &&
+        (GetInternalUsage() & wgpu::TextureUsage::CopyDst);
     DAWN_TRY_ASSIGN(mResourceAllocation,
                     device->AllocateMemory(D3D12_HEAP_TYPE_DEFAULT, resourceDescriptor,
-                                           D3D12_RESOURCE_STATE_COMMON, bytesPerBlock));
+                                           D3D12_RESOURCE_STATE_COMMON, bytesPerBlock,
+                                           forceAllocateAsCommittedResource));
 
     SetLabelImpl();
 
diff --git a/src/dawn/tests/end2end/CopyTests.cpp b/src/dawn/tests/end2end/CopyTests.cpp
index be4a6ab..87eb3be 100644
--- a/src/dawn/tests/end2end/CopyTests.cpp
+++ b/src/dawn/tests/end2end/CopyTests.cpp
@@ -2738,9 +2738,6 @@
 class T2TCopyFromDirtyHeapTests : public DawnTest {
   public:
     void DoTest(uint32_t layerCount, uint32_t levelCount) {
-        // TODO(crbug.com/1237175): Re-enable these tests when we add the workaround on the Intel
-        // D3D12 drivers.
-        DAWN_SUPPRESS_TEST_IF(IsIntel() && IsD3D12());
         std::vector<uint32_t> expectedData;
         wgpu::Buffer uploadBuffer = GetUploadBufferAndExpectedData(&expectedData);
 
diff --git a/webgpu-cts/expectations.txt b/webgpu-cts/expectations.txt
index 209c74e..d5a621c 100644
--- a/webgpu-cts/expectations.txt
+++ b/webgpu-cts/expectations.txt
@@ -65,12 +65,15 @@
 
 ################################################################################
 # webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero
-# Flakes on Windows Intel. depth32float-stencil8 and stencil8 fail consistently.
-# Marked all as failing to avoid expectation overlap with `dimension="2d";*`
-# and `dimension="2d";moreParams...`
+# depth32float-stencil8 and stencil8 fail consistently.
 # KEEP
 ################################################################################
-crbug.com/dawn/1487 [ intel-gen-9 win10 ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";* [ Failure ]
+crbug.com/dawn/1487 [ intel-gen-9 win10 ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="CopyToBuffer";format="depth32float-stencil8" [ Failure ]
+crbug.com/dawn/1487 [ intel-gen-9 win10 ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="CopyToBuffer";format="stencil8" [ Failure ]
+crbug.com/dawn/1487 [ intel-gen-9 win10 ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="CopyToTexture";format="stencil8" [ Failure ]
+crbug.com/dawn/1487 [ intel-gen-9 win10 ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="StencilTest";format="stencil8" [ Failure ]
+
+################################################################################
 
 ################################################################################
 # webgpu:web_platform,copyToTexture,ImageBitmap flakes on Windows Intel with rgba32float and rg32float formats
@@ -131,37 +134,6 @@
 crbug.com/dawn/1107 [ intel mac ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:srcFormat="rgba32float";dstFormat="rgba32float";dimension="2d" [ Failure ]
 
 ################################################################################
-# copyToTexture failures. Needs investigation
-# KEEP
-################################################################################
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,array:srcFormat="rg16sint";dstFormat="rg16sint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,array:srcFormat="rg16uint";dstFormat="rg16uint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,array:srcFormat="rg32float";dstFormat="rg32float";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,array:srcFormat="rg32sint";dstFormat="rg32sint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,array:srcFormat="rg32uint";dstFormat="rg32uint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,array:srcFormat="rgba16sint";dstFormat="rgba16sint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,array:srcFormat="rgba16uint";dstFormat="rgba16uint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,array:srcFormat="rgba32float";dstFormat="rgba32float";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,array:srcFormat="rgba32sint";dstFormat="rgba32sint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,array:srcFormat="rgba32uint";dstFormat="rgba32uint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,array:srcFormat="rgba8sint";dstFormat="rgba8sint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,array:srcFormat="rgba8snorm";dstFormat="rgba8snorm";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,array:srcFormat="rgba8uint";dstFormat="rgba8uint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:srcFormat="rg16sint";dstFormat="rg16sint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:srcFormat="rg16uint";dstFormat="rg16uint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:srcFormat="rg32float";dstFormat="rg32float";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:srcFormat="rg32sint";dstFormat="rg32sint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:srcFormat="rg32uint";dstFormat="rg32uint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:srcFormat="rgba16sint";dstFormat="rgba16sint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:srcFormat="rgba16uint";dstFormat="rgba16uint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:srcFormat="rgba32float";dstFormat="rgba32float";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:srcFormat="rgba32sint";dstFormat="rgba32sint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:srcFormat="rgba32uint";dstFormat="rgba32uint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:srcFormat="rgba8sint";dstFormat="rgba8sint";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:srcFormat="rgba8snorm";dstFormat="rgba8snorm";dimension="2d" [ Failure ]
-crbug.com/dawn/1319 [ intel win ] webgpu:api,operation,command_buffer,copyTextureToTexture:color_textures,non_compressed,non_array:srcFormat="rgba8uint";dstFormat="rgba8uint";dimension="2d" [ Failure ]
-
-################################################################################
 # General test slowness because of https://github.com/gpuweb/cts/issues/1162
 # KEEP
 ################################################################################
@@ -544,7 +516,6 @@
 crbug.com/dawn/0000 [ dawn-no-backend-validation nvidia-0x2184 target-cpu-64 win10 ] worker_webgpu:api,validation,buffer,mapping:mapAsync,offsetAndSizeOOB: [ RetryOnFailure ]
 
 # New failures. Please triage:
-crbug.com/dawn/0000 [ intel-gen-9 win10 ] webgpu:api,operation,command_buffer,image_copy:mip_levels:initMethod="WriteTexture";checkMethod="PartialCopyT2B";format="rgba32uint";dimension="2d" [ Failure ]
 crbug.com/dawn/0000 webgpu:api,operation,shader_module,compilation_info:line_number_and_position:valid=false;name="carriage-return" [ Failure ]
 crbug.com/dawn/0000 webgpu:api,validation,compute_pipeline:overrides,workgroup_size,limits,* [ Failure ]
 crbug.com/dawn/0000 webgpu:api,validation,createBindGroupLayout:multisampled_validation:viewDimension="2d" [ Failure ]