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;
}
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();

View File

@ -52,6 +52,12 @@ int CompareWindowsDriverVersion(PCIVendorID vendorId,
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);

View File

@ -329,11 +329,11 @@ static constexpr ToggleEnumAndInfoList kToggleNameAndInfoList = {{
"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",

View File

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

View File

@ -558,7 +558,7 @@ void Adapter::SetupBackendDeviceToggles(TogglesState* deviceToggles) const {
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().

View File

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

View File

@ -416,6 +416,17 @@ void Adapter::SetupBackendDeviceToggles(TogglesState* deviceToggles) const {
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 @@ bool Adapter::IsAndroidQualcomm() const {
#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

View File

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

View File

@ -124,7 +124,8 @@ ResourceMemoryAllocator::~ResourceMemoryAllocator() = default;
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 @@ ResultOrError<ResourceMemoryAllocation> ResourceMemoryAllocator::Allocate(
// 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

View File

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

View File

@ -730,8 +730,14 @@ MaybeError Texture::InitializeAsInternalTexture(VkImageUsageFlags extraUsages) {
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,