D3D12: Use D3D12_HEAP_FLAG_CREATE_NOT_ZEROED on committed resources

This patch uses D3D12_HEAP_FLAG_CREATE_NOT_ZEROED on committed
resources when Toggle::D3D12CreateNotZeroedHeap is enabled.

Note that due to some driver issues, we cannot use NOT_ZEROED heap
flag on the textures created with CreateCommittedResource() on these
platforms. So in this patch we add another toggle to avoid doing so
on these platforms.

Bug: dawn:484
Change-Id: Id18622e7a112e5e259f99829e9db767b3032675e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/149225
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
diff --git a/src/dawn/native/Toggles.cpp b/src/dawn/native/Toggles.cpp
index 9b12aa0..8fb0d31 100644
--- a/src/dawn/native/Toggles.cpp
+++ b/src/dawn/native/Toggles.cpp
@@ -449,6 +449,12 @@
       "Create D3D12 heap with D3D12_HEAP_FLAG_CREATE_NOT_ZEROED when it is supported. It is safe "
       "because in Dawn we always clear the resources manually when needed.",
       "https://crbug.com/dawn/484", ToggleStage::Device}},
+    {Toggle::D3D12DontUseNotZeroedHeapFlagOnTexturesAsCommitedResources,
+     {"d3d12_dont_use_not_zeroed_heap_flag_on_textures_as_commited_resources",
+      "Don't set the heap flag D3D12_HEAP_FLAG_CREATE_NOT_ZEROED on the D3D12 textures created "
+      "with CreateCommittedResource() as a workaround of some driver issues on Intel Gen9 and "
+      "Gen11 GPUs.",
+      "https://crbug.com/dawn/484", ToggleStage::Device}},
     {Toggle::NoWorkaroundSampleMaskBecomesZeroForAllButLastColorTarget,
      {"no_workaround_sample_mask_becomes_zero_for_all_but_last_color_target",
       "MacOS 12.0+ Intel has a bug where the sample mask is only applied for the last color "
diff --git a/src/dawn/native/Toggles.h b/src/dawn/native/Toggles.h
index 3895d4c..491ff36 100644
--- a/src/dawn/native/Toggles.h
+++ b/src/dawn/native/Toggles.h
@@ -104,6 +104,7 @@
     D3D12Use64KBAlignedMSAATexture,
     ResolveMultipleAttachmentInSeparatePasses,
     D3D12CreateNotZeroedHeap,
+    D3D12DontUseNotZeroedHeapFlagOnTexturesAsCommitedResources,
 
     // Unresolved issues.
     NoWorkaroundSampleMaskBecomesZeroForAllButLastColorTarget,
diff --git a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
index 35f9c15..fa17392 100644
--- a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
@@ -633,6 +633,13 @@
         }
     }
 
+    // Currently these workarounds are only needed on Intel Gen9 and Gen11 GPUs.
+    // See http://crbug.com/dawn/484 for more information.
+    if (gpu_info::IsIntelGen9(vendorId, deviceId) || gpu_info::IsIntelGen11(vendorId, deviceId)) {
+        deviceToggles->Default(Toggle::D3D12DontUseNotZeroedHeapFlagOnTexturesAsCommitedResources,
+                               true);
+    }
+
 #if D3D12_SDK_VERSION >= 602
     D3D12_FEATURE_DATA_D3D12_OPTIONS13 featureData13;
     if (FAILED(mD3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS13, &featureData13,
diff --git a/src/dawn/native/d3d12/ResourceAllocatorManagerD3D12.cpp b/src/dawn/native/d3d12/ResourceAllocatorManagerD3D12.cpp
index 065b7c6..308031d 100644
--- a/src/dawn/native/d3d12/ResourceAllocatorManagerD3D12.cpp
+++ b/src/dawn/native/d3d12/ResourceAllocatorManagerD3D12.cpp
@@ -320,6 +320,21 @@
            device->IsToggleEnabled(Toggle::DisableResourceSuballocation);
 }
 
+D3D12_HEAP_FLAGS GetHeapFlagsForCommittedResource(Device* device,
+                                                  const D3D12_RESOURCE_DESC& resourceDescriptor) {
+    if (!device->IsToggleEnabled(Toggle::D3D12CreateNotZeroedHeap)) {
+        return D3D12_HEAP_FLAG_NONE;
+    }
+
+    if (device->IsToggleEnabled(
+            Toggle::D3D12DontUseNotZeroedHeapFlagOnTexturesAsCommitedResources) &&
+        resourceDescriptor.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER) {
+        return D3D12_HEAP_FLAG_NONE;
+    }
+
+    return D3D12_HEAP_FLAG_CREATE_NOT_ZEROED;
+}
+
 }  // namespace
 
 ResourceAllocatorManager::ResourceAllocatorManager(Device* device) : mDevice(device) {
@@ -581,9 +596,12 @@
         mDevice->IsToggleEnabled(Toggle::D3D12Use64KBAlignedMSAATexture)) {
         appliedResourceDescriptor.Alignment = D3D12_SMALL_MSAA_RESOURCE_PLACEMENT_ALIGNMENT;
     }
+
+    D3D12_HEAP_FLAGS heapFlags =
+        GetHeapFlagsForCommittedResource(mDevice, appliedResourceDescriptor);
     DAWN_TRY(CheckOutOfMemoryHRESULT(
         mDevice->GetD3D12Device()->CreateCommittedResource(
-            &heapProperties, D3D12_HEAP_FLAG_NONE, &appliedResourceDescriptor, initialUsage,
+            &heapProperties, heapFlags, &appliedResourceDescriptor, initialUsage,
             optimizedClearValue, IID_PPV_ARGS(&committedResource)),
         "ID3D12Device::CreateCommittedResource"));