Vulkan: Disable suballocation for 2D textures in some situation on Intel Mesa
This patch disables resource sub-allocation for the 2D textures with
CopyDst or RenderAttachment usage on Intel Gen12 GPUs using Mesa
driver on Linux and ChromeOS because of the driver issues about rebinding a
VkDeviceMemory from a VkImage to another VkImage.
Bug: dawn:1688
Change-Id: I28bb01a2d641a9024330ed761d27e0145d6b8aad
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/124382
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/common/GPUInfo.cpp b/src/dawn/common/GPUInfo.cpp
index 4b80876..b46f242 100644
--- a/src/dawn/common/GPUInfo.cpp
+++ b/src/dawn/common/GPUInfo.cpp
@@ -90,6 +90,16 @@
return 0;
}
+int CompareIntelMesaDriverVersion(const DriverVersion& version1, const DriverVersion& version2) {
+ for (uint32_t i = 0; i < 3; ++i) {
+ int diff = static_cast<int32_t>(version1[i]) - static_cast<int32_t>(version2[i]);
+ if (diff != 0) {
+ return diff;
+ }
+ }
+ return 0;
+}
+
// Intel GPUs
bool IsSkylake(PCIDeviceID deviceId) {
return std::find(Skylake.cbegin(), Skylake.cend(), deviceId) != Skylake.cend();
diff --git a/src/dawn/common/GPUInfo.h b/src/dawn/common/GPUInfo.h
index 855d05c..dab977f 100644
--- a/src/dawn/common/GPUInfo.h
+++ b/src/dawn/common/GPUInfo.h
@@ -52,6 +52,12 @@
const DriverVersion& version1,
const DriverVersion& version2);
+// Do comparison between two Intel Mesa driver versions.
+// - Return a negative number if build number of version1 is smaller
+// - Return a positive number if build number of version1 is bigger
+// - Return 0 if version1 and version2 represent same driver version
+int CompareIntelMesaDriverVersion(const DriverVersion& version1, const DriverVersion& version2);
+
// Intel architectures
bool IsSkylake(PCIDeviceID deviceId);
diff --git a/src/dawn/native/Toggles.cpp b/src/dawn/native/Toggles.cpp
index c2c105a..cd802ff 100644
--- a/src/dawn/native/Toggles.cpp
+++ b/src/dawn/native/Toggles.cpp
@@ -329,11 +329,11 @@
"default on Qualcomm GPUs, which have been observed experiencing a driver crash in this "
"situation.",
"https://crbug.com/dawn/1564", ToggleStage::Device}},
- {Toggle::D3D12Allocate2DTextureWithCopyDstOrRenderAttachmentAsCommittedResource,
- {"d3d12_allocate_2d_texture_with_copy_dst_or_render_attachment_as_committed_resource",
- "Allocate each 2D texture with CopyDst or RenderAttachment 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.",
+ {Toggle::DisableSubAllocationFor2DTextureWithCopyDstOrRenderAttachment,
+ {"disable_sub_allocation_for_2d_texture_with_copy_dst_or_render_attachment",
+ "Disable resource sub-allocation for the 2D texture with CopyDst or RenderAttachment usage. "
+ "This toggle is enabled by default on D3D12 backends using Intel Gen9.5 and Gen11 GPUs and "
+ "on Vulkan backends using Intel Gen12 GPUs due to Intel Mesa Vulkan and D3D12 driver issues.",
"https://crbug.com/1237175", ToggleStage::Device}},
{Toggle::MetalUseCombinedDepthStencilFormatForStencil8,
{"metal_use_combined_depth_stencil_format_for_stencil8",
diff --git a/src/dawn/native/Toggles.h b/src/dawn/native/Toggles.h
index 4962e3c..0eab485 100644
--- a/src/dawn/native/Toggles.h
+++ b/src/dawn/native/Toggles.h
@@ -83,7 +83,7 @@
ApplyClearBigIntegerColorValueWithDraw,
MetalUseMockBlitEncoderForWriteTimestamp,
VulkanSplitCommandBufferOnDepthStencilComputeSampleAfterRenderPass,
- D3D12Allocate2DTextureWithCopyDstOrRenderAttachmentAsCommittedResource,
+ DisableSubAllocationFor2DTextureWithCopyDstOrRenderAttachment,
MetalUseCombinedDepthStencilFormatForStencil8,
MetalUseBothDepthAndStencilAttachmentsForCombinedDepthStencilFormats,
MetalKeepMultisubresourceDepthStencilTexturesInitialized,
diff --git a/src/dawn/native/d3d12/AdapterD3D12.cpp b/src/dawn/native/d3d12/AdapterD3D12.cpp
index d56ef2f..ccd42bf 100644
--- a/src/dawn/native/d3d12/AdapterD3D12.cpp
+++ b/src/dawn/native/d3d12/AdapterD3D12.cpp
@@ -558,7 +558,7 @@
if ((gpu_info::IsIntelGen9(vendorId, deviceId) && !gpu_info::IsSkylake(deviceId)) ||
gpu_info::IsIntelGen11(vendorId, deviceId)) {
deviceToggles->Default(
- Toggle::D3D12Allocate2DTextureWithCopyDstOrRenderAttachmentAsCommittedResource, true);
+ Toggle::DisableSubAllocationFor2DTextureWithCopyDstOrRenderAttachment, true);
// Now we don't need to force clearing depth stencil textures with CopyDst as all the depth
// stencil textures (can only be 2D textures) will be created with CreateCommittedResource()
// instead of CreatePlacedResource().
diff --git a/src/dawn/native/d3d12/TextureD3D12.cpp b/src/dawn/native/d3d12/TextureD3D12.cpp
index 3c99d88..f87078a 100644
--- a/src/dawn/native/d3d12/TextureD3D12.cpp
+++ b/src/dawn/native/d3d12/TextureD3D12.cpp
@@ -612,7 +612,7 @@
}
bool forceAllocateAsCommittedResource =
(device->IsToggleEnabled(
- Toggle::D3D12Allocate2DTextureWithCopyDstOrRenderAttachmentAsCommittedResource)) &&
+ Toggle::DisableSubAllocationFor2DTextureWithCopyDstOrRenderAttachment)) &&
GetDimension() == wgpu::TextureDimension::e2D &&
(GetInternalUsage() & (wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment));
DAWN_TRY_ASSIGN(mResourceAllocation,
diff --git a/src/dawn/native/vulkan/AdapterVk.cpp b/src/dawn/native/vulkan/AdapterVk.cpp
index d6a61dc..cec496a 100644
--- a/src/dawn/native/vulkan/AdapterVk.cpp
+++ b/src/dawn/native/vulkan/AdapterVk.cpp
@@ -416,6 +416,17 @@
deviceToggles->Default(Toggle::AlwaysResolveIntoZeroLevelAndLayer, true);
}
+ if (IsIntelMesa() && gpu_info::IsIntelGen12LP(GetVendorId(), GetDeviceId())) {
+ // dawn:1688: Intel Mesa driver has a bug about reusing the VkDeviceMemory that was
+ // previously bound to a 2D VkImage. To work around that bug we have to disable the resource
+ // sub-allocation for 2D textures with CopyDst or RenderAttachment usage.
+ const gpu_info::DriverVersion kDriverVersion = {21, 3, 6, 0};
+ if (gpu_info::CompareIntelMesaDriverVersion(GetDriverVersion(), kDriverVersion) >= 0) {
+ deviceToggles->Default(
+ Toggle::DisableSubAllocationFor2DTextureWithCopyDstOrRenderAttachment, true);
+ }
+ }
+
// The environment can request to various options for depth-stencil formats that could be
// unavailable. Override the decision if it is not applicable.
bool supportsD32s8 = IsDepthStencilFormatSupported(VK_FORMAT_D32_SFLOAT_S8_UINT);
@@ -474,4 +485,11 @@
#endif
}
+bool Adapter::IsIntelMesa() const {
+ if (mDeviceInfo.HasExt(DeviceExt::DriverProperties)) {
+ return mDeviceInfo.driverProperties.driverID == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR;
+ }
+ return false;
+}
+
} // namespace dawn::native::vulkan
diff --git a/src/dawn/native/vulkan/AdapterVk.h b/src/dawn/native/vulkan/AdapterVk.h
index 0b8226a..0eb9317 100644
--- a/src/dawn/native/vulkan/AdapterVk.h
+++ b/src/dawn/native/vulkan/AdapterVk.h
@@ -43,6 +43,7 @@
bool IsDepthStencilFormatSupported(VkFormat format) const;
bool IsAndroidQualcomm() const;
+ bool IsIntelMesa() const;
private:
MaybeError InitializeImpl() override;
diff --git a/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.cpp b/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.cpp
index 390b326..ba1816e 100644
--- a/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.cpp
+++ b/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.cpp
@@ -124,7 +124,8 @@
ResultOrError<ResourceMemoryAllocation> ResourceMemoryAllocator::Allocate(
const VkMemoryRequirements& requirements,
- MemoryKind kind) {
+ MemoryKind kind,
+ bool forceDisableSubAllocation) {
// The Vulkan spec guarantees at least on memory type is valid.
int memoryType = FindBestTypeIndex(requirements, kind);
ASSERT(memoryType >= 0);
@@ -134,7 +135,8 @@
// Sub-allocate non-mappable resources because at the moment the mapped pointer
// is part of the resource and not the heap, which doesn't match the Vulkan model.
// TODO(crbug.com/dawn/849): allow sub-allocating mappable resources, maybe.
- if (requirements.size < kMaxSizeForSubAllocation && kind != MemoryKind::LinearMappable &&
+ if (!forceDisableSubAllocation && requirements.size < kMaxSizeForSubAllocation &&
+ kind != MemoryKind::LinearMappable &&
!mDevice->IsToggleEnabled(Toggle::DisableResourceSuballocation)) {
// When sub-allocating, Vulkan requires that we respect bufferImageGranularity. Some
// hardware puts information on the memory's page table entry and allocating a linear
diff --git a/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.h b/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.h
index 1ece6d7..2be1895 100644
--- a/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.h
+++ b/src/dawn/native/vulkan/ResourceMemoryAllocatorVk.h
@@ -43,7 +43,8 @@
~ResourceMemoryAllocator();
ResultOrError<ResourceMemoryAllocation> Allocate(const VkMemoryRequirements& requirements,
- MemoryKind kind);
+ MemoryKind kind,
+ bool forceDisableSubAllocation = false);
void Deallocate(ResourceMemoryAllocation* allocation);
void DestroyPool();
diff --git a/src/dawn/native/vulkan/TextureVk.cpp b/src/dawn/native/vulkan/TextureVk.cpp
index b15b9be..2e767a7 100644
--- a/src/dawn/native/vulkan/TextureVk.cpp
+++ b/src/dawn/native/vulkan/TextureVk.cpp
@@ -730,8 +730,14 @@
VkMemoryRequirements requirements;
device->fn.GetImageMemoryRequirements(device->GetVkDevice(), mHandle, &requirements);
- DAWN_TRY_ASSIGN(mMemoryAllocation, device->GetResourceMemoryAllocator()->Allocate(
- requirements, MemoryKind::Opaque));
+ bool forceDisableSubAllocation =
+ (device->IsToggleEnabled(
+ Toggle::DisableSubAllocationFor2DTextureWithCopyDstOrRenderAttachment)) &&
+ GetDimension() == wgpu::TextureDimension::e2D &&
+ (GetInternalUsage() & (wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment));
+ DAWN_TRY_ASSIGN(mMemoryAllocation,
+ device->GetResourceMemoryAllocator()->Allocate(requirements, MemoryKind::Opaque,
+ forceDisableSubAllocation));
DAWN_TRY(CheckVkSuccess(
device->fn.BindImageMemory(device->GetVkDevice(), mHandle,