Add a toggle to disable validation of AHB VkImage required size
- Move the check of the required size till after the VkImage is
bound to memory. This is required by the Vulkan spec.
- also add AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER to test
CPUWriteThenGPURead. Some GPU drivers require at least one
non-CPU usage to import into Vulkan.
Bug: 333424893
Change-Id: I80abc52eec19c093576bf68f2f1ed2bfa16929ee
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/187587
Reviewed-by: Brian Sheedy <bsheedy@google.com>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/native/Toggles.cpp b/src/dawn/native/Toggles.cpp
index 2b373e7..2d9d36f 100644
--- a/src/dawn/native/Toggles.cpp
+++ b/src/dawn/native/Toggles.cpp
@@ -581,6 +581,11 @@
{Toggle::D3D11UseUnmonitoredFence,
{"d3d11_use_unmonitored_fence", "Use d3d11 unmonitored fence.",
"https://crbug.com/chromium/335553337", ToggleStage::Device}},
+ {Toggle::IgnoreImportedAHardwareBufferVulkanImageSize,
+ {"ignore_imported_ahardwarebuffer_vulkan_image_size",
+ "Don't validate the required VkImage size against the size of the AHardwareBuffer on import. "
+ "Some drivers report the wrong size.",
+ "https://crbug.com/333424893", ToggleStage::Device}},
// Comment to separate the }} so it is clearer what to copy-paste to add a toggle.
}};
} // anonymous namespace
diff --git a/src/dawn/native/Toggles.h b/src/dawn/native/Toggles.h
index b5f35e6..cb343ee 100644
--- a/src/dawn/native/Toggles.h
+++ b/src/dawn/native/Toggles.h
@@ -144,6 +144,7 @@
VulkanSkipDraw,
D3D11UseUnmonitoredFence,
+ IgnoreImportedAHardwareBufferVulkanImageSize,
EnumCount,
InvalidEnum = EnumCount,
diff --git a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
index 6075a4c..b7d9eb1 100644
--- a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
+++ b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
@@ -663,6 +663,10 @@
deviceToggles->Default(Toggle::ResolveMultipleAttachmentInSeparatePasses, true);
}
+ if (IsAndroidSamsung() || IsAndroidQualcomm()) {
+ deviceToggles->Default(Toggle::IgnoreImportedAHardwareBufferVulkanImageSize, 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
@@ -806,6 +810,14 @@
#endif
}
+bool PhysicalDevice::IsAndroidSamsung() const {
+#if DAWN_PLATFORM_IS(ANDROID)
+ return gpu_info::IsSamsung(GetVendorId());
+#else
+ return false;
+#endif
+}
+
bool PhysicalDevice::IsIntelMesa() const {
if (mDeviceInfo.HasExt(DeviceExt::DriverProperties)) {
return mDeviceInfo.driverProperties.driverID == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR;
diff --git a/src/dawn/native/vulkan/PhysicalDeviceVk.h b/src/dawn/native/vulkan/PhysicalDeviceVk.h
index fb8d266..8a09e4f 100644
--- a/src/dawn/native/vulkan/PhysicalDeviceVk.h
+++ b/src/dawn/native/vulkan/PhysicalDeviceVk.h
@@ -60,6 +60,7 @@
bool IsAndroidQualcomm() const;
bool IsAndroidARM() const;
+ bool IsAndroidSamsung() const;
bool IsIntelMesa() const;
uint32_t GetDefaultComputeSubgroupSize() const;
diff --git a/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp b/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
index 7691e89..732806a 100644
--- a/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
+++ b/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
@@ -676,19 +676,9 @@
// Import the memory as VkDeviceMemory and bind to the VkImage.
{
- // Get the valid memory types for the VkImage.
+ // Choose the best memory type that satisfies the import's constraint.
VkMemoryRequirements memoryRequirements;
- device->fn.GetImageMemoryRequirements(vkDevice, sharedTextureMemory->mVkImage->Get(),
- &memoryRequirements);
-
- DAWN_INVALID_IF(memoryRequirements.size > bufferProperties.allocationSize,
- "Required texture memory size (%u) is larger than the AHardwareBuffer "
- "allocation size (%u).",
- memoryRequirements.size, bufferProperties.allocationSize);
-
- // Choose the best memory type that satisfies both the image's constraint and the
- // import's constraint.
- memoryRequirements.memoryTypeBits &= bufferProperties.memoryTypeBits;
+ memoryRequirements.memoryTypeBits = bufferProperties.memoryTypeBits;
int memoryTypeIndex = device->GetResourceMemoryAllocator()->FindBestTypeIndex(
memoryRequirements, MemoryKind::Opaque);
DAWN_INVALID_IF(memoryTypeIndex == -1,
@@ -724,6 +714,22 @@
device->fn.BindImageMemory(vkDevice, sharedTextureMemory->mVkImage->Get(),
sharedTextureMemory->mVkDeviceMemory->Get(), 0),
"vkBindImageMemory"));
+
+ // Verify the texture memory requirements fit within the constraints of the AHardwareBuffer.
+ device->fn.GetImageMemoryRequirements(vkDevice, sharedTextureMemory->mVkImage->Get(),
+ &memoryRequirements);
+
+ DAWN_INVALID_IF((memoryRequirements.memoryTypeBits & bufferProperties.memoryTypeBits) == 0,
+ "Required memory type bits (%u) do not overlap with AHardwareBuffer memory "
+ "type bits (%u).",
+ memoryRequirements.memoryTypeBits, bufferProperties.memoryTypeBits);
+
+ if (!device->IsToggleEnabled(Toggle::IgnoreImportedAHardwareBufferVulkanImageSize)) {
+ DAWN_INVALID_IF(memoryRequirements.size > bufferProperties.allocationSize,
+ "Required texture memory size (%u) is larger than the AHardwareBuffer "
+ "allocation size (%u).",
+ memoryRequirements.size, bufferProperties.allocationSize);
+ }
}
return sharedTextureMemory;
#else
diff --git a/src/dawn/tests/white_box/SharedTextureMemoryTests_android.cpp b/src/dawn/tests/white_box/SharedTextureMemoryTests_android.cpp
index 6e97075..d24cc0a 100644
--- a/src/dawn/tests/white_box/SharedTextureMemoryTests_android.cpp
+++ b/src/dawn/tests/white_box/SharedTextureMemoryTests_android.cpp
@@ -255,7 +255,8 @@
.height = 4,
.layers = 1,
.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
- .usage = AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
+ // Include at least one GPU usage. Otherwise import to Vulkan can fail.
+ .usage = AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN | AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER,
};
AHardwareBuffer* aHardwareBuffer;
EXPECT_EQ(AHardwareBuffer_allocate(&aHardwareBufferDesc, &aHardwareBuffer), 0);