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..2e767a74 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,