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>
This commit is contained in:
Jiawei Shao 2023-03-18 02:54:58 +00:00 committed by Dawn LUCI CQ
parent 45cd391d56
commit 6b41ccc6ec
11 changed files with 57 additions and 13 deletions

View File

@ -90,6 +90,16 @@ int CompareWindowsDriverVersion(PCIVendorID vendorId,
return 0; 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 // Intel GPUs
bool IsSkylake(PCIDeviceID deviceId) { bool IsSkylake(PCIDeviceID deviceId) {
return std::find(Skylake.cbegin(), Skylake.cend(), deviceId) != Skylake.cend(); return std::find(Skylake.cbegin(), Skylake.cend(), deviceId) != Skylake.cend();

View File

@ -52,6 +52,12 @@ int CompareWindowsDriverVersion(PCIVendorID vendorId,
const DriverVersion& version1, const DriverVersion& version1,
const DriverVersion& version2); 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 // Intel architectures
bool IsSkylake(PCIDeviceID deviceId); bool IsSkylake(PCIDeviceID deviceId);

View File

@ -329,11 +329,11 @@ static constexpr ToggleEnumAndInfoList kToggleNameAndInfoList = {{
"default on Qualcomm GPUs, which have been observed experiencing a driver crash in this " "default on Qualcomm GPUs, which have been observed experiencing a driver crash in this "
"situation.", "situation.",
"https://crbug.com/dawn/1564", ToggleStage::Device}}, "https://crbug.com/dawn/1564", ToggleStage::Device}},
{Toggle::D3D12Allocate2DTextureWithCopyDstOrRenderAttachmentAsCommittedResource, {Toggle::DisableSubAllocationFor2DTextureWithCopyDstOrRenderAttachment,
{"d3d12_allocate_2d_texture_with_copy_dst_or_render_attachment_as_committed_resource", {"disable_sub_allocation_for_2d_texture_with_copy_dst_or_render_attachment",
"Allocate each 2D texture with CopyDst or RenderAttachment usage as committed resources " "Disable resource sub-allocation for the 2D texture with CopyDst or RenderAttachment usage. "
"instead of placed resources. This toggle is enabled by default on D3D12 backends using " "This toggle is enabled by default on D3D12 backends using Intel Gen9.5 and Gen11 GPUs and "
"Intel Gen9.5 and Gen11 GPUs due to a driver issue on Intel D3D12 driver.", "on Vulkan backends using Intel Gen12 GPUs due to Intel Mesa Vulkan and D3D12 driver issues.",
"https://crbug.com/1237175", ToggleStage::Device}}, "https://crbug.com/1237175", ToggleStage::Device}},
{Toggle::MetalUseCombinedDepthStencilFormatForStencil8, {Toggle::MetalUseCombinedDepthStencilFormatForStencil8,
{"metal_use_combined_depth_stencil_format_for_stencil8", {"metal_use_combined_depth_stencil_format_for_stencil8",

View File

@ -83,7 +83,7 @@ enum class Toggle {
ApplyClearBigIntegerColorValueWithDraw, ApplyClearBigIntegerColorValueWithDraw,
MetalUseMockBlitEncoderForWriteTimestamp, MetalUseMockBlitEncoderForWriteTimestamp,
VulkanSplitCommandBufferOnDepthStencilComputeSampleAfterRenderPass, VulkanSplitCommandBufferOnDepthStencilComputeSampleAfterRenderPass,
D3D12Allocate2DTextureWithCopyDstOrRenderAttachmentAsCommittedResource, DisableSubAllocationFor2DTextureWithCopyDstOrRenderAttachment,
MetalUseCombinedDepthStencilFormatForStencil8, MetalUseCombinedDepthStencilFormatForStencil8,
MetalUseBothDepthAndStencilAttachmentsForCombinedDepthStencilFormats, MetalUseBothDepthAndStencilAttachmentsForCombinedDepthStencilFormats,
MetalKeepMultisubresourceDepthStencilTexturesInitialized, MetalKeepMultisubresourceDepthStencilTexturesInitialized,

View File

@ -558,7 +558,7 @@ void Adapter::SetupBackendDeviceToggles(TogglesState* deviceToggles) const {
if ((gpu_info::IsIntelGen9(vendorId, deviceId) && !gpu_info::IsSkylake(deviceId)) || if ((gpu_info::IsIntelGen9(vendorId, deviceId) && !gpu_info::IsSkylake(deviceId)) ||
gpu_info::IsIntelGen11(vendorId, deviceId)) { gpu_info::IsIntelGen11(vendorId, deviceId)) {
deviceToggles->Default( 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 // 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() // stencil textures (can only be 2D textures) will be created with CreateCommittedResource()
// instead of CreatePlacedResource(). // instead of CreatePlacedResource().

View File

@ -612,7 +612,7 @@ MaybeError Texture::InitializeAsInternalTexture() {
} }
bool forceAllocateAsCommittedResource = bool forceAllocateAsCommittedResource =
(device->IsToggleEnabled( (device->IsToggleEnabled(
Toggle::D3D12Allocate2DTextureWithCopyDstOrRenderAttachmentAsCommittedResource)) && Toggle::DisableSubAllocationFor2DTextureWithCopyDstOrRenderAttachment)) &&
GetDimension() == wgpu::TextureDimension::e2D && GetDimension() == wgpu::TextureDimension::e2D &&
(GetInternalUsage() & (wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment)); (GetInternalUsage() & (wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment));
DAWN_TRY_ASSIGN(mResourceAllocation, DAWN_TRY_ASSIGN(mResourceAllocation,

View File

@ -416,6 +416,17 @@ void Adapter::SetupBackendDeviceToggles(TogglesState* deviceToggles) const {
deviceToggles->Default(Toggle::AlwaysResolveIntoZeroLevelAndLayer, true); 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 // The environment can request to various options for depth-stencil formats that could be
// unavailable. Override the decision if it is not applicable. // unavailable. Override the decision if it is not applicable.
bool supportsD32s8 = IsDepthStencilFormatSupported(VK_FORMAT_D32_SFLOAT_S8_UINT); bool supportsD32s8 = IsDepthStencilFormatSupported(VK_FORMAT_D32_SFLOAT_S8_UINT);
@ -474,4 +485,11 @@ bool Adapter::IsAndroidQualcomm() const {
#endif #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 } // namespace dawn::native::vulkan

View File

@ -43,6 +43,7 @@ class Adapter : public AdapterBase {
bool IsDepthStencilFormatSupported(VkFormat format) const; bool IsDepthStencilFormatSupported(VkFormat format) const;
bool IsAndroidQualcomm() const; bool IsAndroidQualcomm() const;
bool IsIntelMesa() const;
private: private:
MaybeError InitializeImpl() override; MaybeError InitializeImpl() override;

View File

@ -124,7 +124,8 @@ ResourceMemoryAllocator::~ResourceMemoryAllocator() = default;
ResultOrError<ResourceMemoryAllocation> ResourceMemoryAllocator::Allocate( ResultOrError<ResourceMemoryAllocation> ResourceMemoryAllocator::Allocate(
const VkMemoryRequirements& requirements, const VkMemoryRequirements& requirements,
MemoryKind kind) { MemoryKind kind,
bool forceDisableSubAllocation) {
// The Vulkan spec guarantees at least on memory type is valid. // The Vulkan spec guarantees at least on memory type is valid.
int memoryType = FindBestTypeIndex(requirements, kind); int memoryType = FindBestTypeIndex(requirements, kind);
ASSERT(memoryType >= 0); ASSERT(memoryType >= 0);
@ -134,7 +135,8 @@ ResultOrError<ResourceMemoryAllocation> ResourceMemoryAllocator::Allocate(
// Sub-allocate non-mappable resources because at the moment the mapped pointer // 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. // 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. // 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)) { !mDevice->IsToggleEnabled(Toggle::DisableResourceSuballocation)) {
// When sub-allocating, Vulkan requires that we respect bufferImageGranularity. Some // When sub-allocating, Vulkan requires that we respect bufferImageGranularity. Some
// hardware puts information on the memory's page table entry and allocating a linear // hardware puts information on the memory's page table entry and allocating a linear

View File

@ -43,7 +43,8 @@ class ResourceMemoryAllocator {
~ResourceMemoryAllocator(); ~ResourceMemoryAllocator();
ResultOrError<ResourceMemoryAllocation> Allocate(const VkMemoryRequirements& requirements, ResultOrError<ResourceMemoryAllocation> Allocate(const VkMemoryRequirements& requirements,
MemoryKind kind); MemoryKind kind,
bool forceDisableSubAllocation = false);
void Deallocate(ResourceMemoryAllocation* allocation); void Deallocate(ResourceMemoryAllocation* allocation);
void DestroyPool(); void DestroyPool();

View File

@ -730,8 +730,14 @@ MaybeError Texture::InitializeAsInternalTexture(VkImageUsageFlags extraUsages) {
VkMemoryRequirements requirements; VkMemoryRequirements requirements;
device->fn.GetImageMemoryRequirements(device->GetVkDevice(), mHandle, &requirements); device->fn.GetImageMemoryRequirements(device->GetVkDevice(), mHandle, &requirements);
DAWN_TRY_ASSIGN(mMemoryAllocation, device->GetResourceMemoryAllocator()->Allocate( bool forceDisableSubAllocation =
requirements, MemoryKind::Opaque)); (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( DAWN_TRY(CheckVkSuccess(
device->fn.BindImageMemory(device->GetVkDevice(), mHandle, device->fn.BindImageMemory(device->GetVkDevice(), mHandle,