Handle suballocated AHB buffers
VkBuffers backed by AHBs do not require dedicated allocations.
As such, update SupportsAllocateInfo() to report supported as
long as a VkImportAndroidHardwareBufferInfoANDROID or a
VkExportMemoryAllocateInfo with AHB bit was found.
Updates allocateAndroidHardwareBuffer() to treat the lack of a
dedicated buffer or image as a request to allocate a blob AHB.
Bug: b/147316305
Bug: b/169796031
Test: cts -m CtsNativeHardwareTestCases
Test: cts -m CtsDeqpTestCases -t
dEQP-VK.api.external.memory.android_hardware_buffer.*
Change-Id: Ica2782b4570bd4d4c1e5585b696b40314a267b2f
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/51248
Presubmit-Ready: Jason Macnak <natsu@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Jason Macnak <natsu@google.com>
Commit-Queue: Jason Macnak <natsu@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp b/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp
index f353e8a..729a9d0 100644
--- a/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp
+++ b/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp
@@ -194,16 +194,16 @@
break;
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO:
{
- // AHB requires dedicated allocation -- for images, the gralloc gets to decide the image layout,
- // not us.
const auto *dedicatedAllocateInfo = reinterpret_cast<const VkMemoryDedicatedAllocateInfo *>(createInfo);
- imageHandle = vk::Cast(dedicatedAllocateInfo->image);
- bufferHandle = vk::Cast(dedicatedAllocateInfo->buffer);
+ dedicatedImageHandle = vk::Cast(dedicatedAllocateInfo->image);
+ dedicatedBufferHandle = vk::Cast(dedicatedAllocateInfo->buffer);
}
break;
-
default:
- WARN("VkMemoryAllocateInfo->pNext sType = %s", vk::Stringify(createInfo->sType).c_str());
+ {
+ LOG_TRAP("VkMemoryAllocateInfo->pNext sType = %s", vk::Stringify(createInfo->sType).c_str());
+ }
+ break;
}
createInfo = createInfo->pNext;
}
@@ -221,7 +221,7 @@
}
// VkAllocateMemory
-VkResult AHardwareBufferExternalMemory::allocate(size_t /*size*/, void **pBuffer)
+VkResult AHardwareBufferExternalMemory::allocate(size_t size, void **pBuffer)
{
if(allocateInfo.importAhb)
{
@@ -230,7 +230,7 @@
else
{
ASSERT(allocateInfo.exportAhb);
- return allocateAndroidHardwareBuffer(pBuffer);
+ return allocateAndroidHardwareBuffer(size, pBuffer);
}
}
@@ -255,12 +255,11 @@
return lockAndroidHardwareBuffer(pBuffer);
}
-VkResult AHardwareBufferExternalMemory::allocateAndroidHardwareBuffer(void **pBuffer)
+VkResult AHardwareBufferExternalMemory::allocateAndroidHardwareBuffer(size_t size, void **pBuffer)
{
- if(allocateInfo.imageHandle)
+ if(allocateInfo.dedicatedImageHandle)
{
- vk::Image *image = allocateInfo.imageHandle;
- ASSERT(image != nullptr);
+ vk::Image *image = allocateInfo.dedicatedImageHandle;
ASSERT(image->getArrayLayers() == 1);
VkExtent3D extent = image->getExtent();
@@ -271,10 +270,9 @@
ahbDesc.format = GetAHBFormatFromVkFormat(image->getFormat());
ahbDesc.usage = GetAHBUsageFromVkImageFlags(image->getFlags(), image->getUsage());
}
- else
+ else if(allocateInfo.dedicatedBufferHandle)
{
- vk::Buffer *buffer = allocateInfo.bufferHandle;
- ASSERT(buffer != nullptr);
+ vk::Buffer *buffer = allocateInfo.dedicatedBufferHandle;
ahbDesc.width = static_cast<uint32_t>(buffer->getSize());
ahbDesc.height = 1;
@@ -282,6 +280,18 @@
ahbDesc.format = AHARDWAREBUFFER_FORMAT_BLOB;
ahbDesc.usage = GetAHBUsageFromVkBufferFlags(buffer->getFlags(), buffer->getUsage());
}
+ else
+ {
+ // Android Hardware Buffer Buffer Resources: "Android hardware buffers with a format of
+ // AHARDWAREBUFFER_FORMAT_BLOB and usage that includes AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER can
+ // be used as the backing store for VkBuffer objects. Such Android hardware buffers have a size
+ // in bytes specified by their width; height and layers are both 1."
+ ahbDesc.width = static_cast<uint32_t>(size);
+ ahbDesc.height = 1;
+ ahbDesc.layers = 1;
+ ahbDesc.format = AHARDWAREBUFFER_FORMAT_BLOB;
+ ahbDesc.usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
+ }
int ret = AHardwareBuffer_allocate(&ahbDesc, &ahb);
if(ret != 0)
@@ -297,13 +307,17 @@
VkResult AHardwareBufferExternalMemory::lockAndroidHardwareBuffer(void **pBuffer)
{
uint64_t usage = 0;
- if(allocateInfo.imageHandle)
+ if(allocateInfo.dedicatedImageHandle)
{
- usage = GetAHBLockUsageFromVkImageUsageFlags(allocateInfo.imageHandle->getUsage());
+ usage = GetAHBLockUsageFromVkImageUsageFlags(allocateInfo.dedicatedImageHandle->getUsage());
+ }
+ else if(allocateInfo.dedicatedBufferHandle)
+ {
+ usage = GetAHBLockUsageFromVkBufferUsageFlags(allocateInfo.dedicatedBufferHandle->getUsage());
}
else
{
- usage = GetAHBLockUsageFromVkBufferUsageFlags(allocateInfo.bufferHandle->getUsage());
+ usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
}
// Empty fence, lock immedietly.
@@ -465,6 +479,8 @@
int AHardwareBufferExternalMemory::externalImageRowPitchBytes(VkImageAspectFlagBits aspect) const
{
+ ASSERT(allocateInfo.dedicatedImageHandle != nullptr);
+
switch(ahbDesc.format)
{
case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
@@ -490,6 +506,8 @@
VkDeviceSize AHardwareBufferExternalMemory::externalImageMemoryOffset(VkImageAspectFlagBits aspect) const
{
+ ASSERT(allocateInfo.dedicatedImageHandle != nullptr);
+
switch(ahbDesc.format)
{
case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
diff --git a/src/Vulkan/VkDeviceMemoryExternalAndroid.hpp b/src/Vulkan/VkDeviceMemoryExternalAndroid.hpp
index 74a53c4..df46548 100644
--- a/src/Vulkan/VkDeviceMemoryExternalAndroid.hpp
+++ b/src/Vulkan/VkDeviceMemoryExternalAndroid.hpp
@@ -34,8 +34,8 @@
bool importAhb = false;
bool exportAhb = false;
AHardwareBuffer *ahb = nullptr;
- vk::Image *imageHandle = nullptr;
- vk::Buffer *bufferHandle = nullptr;
+ vk::Image *dedicatedImageHandle = nullptr;
+ vk::Buffer *dedicatedBufferHandle = nullptr;
AllocateInfo() = default;
@@ -48,7 +48,7 @@
static bool SupportsAllocateInfo(const VkMemoryAllocateInfo *pAllocateInfo)
{
AllocateInfo info(pAllocateInfo);
- return (info.importAhb || info.exportAhb) && (info.bufferHandle || info.imageHandle);
+ return info.importAhb || info.exportAhb;
}
explicit AHardwareBufferExternalMemory(const VkMemoryAllocateInfo *pAllocateInfo);
@@ -81,7 +81,7 @@
private:
VkResult importAndroidHardwareBuffer(AHardwareBuffer *buffer, void **pBuffer);
- VkResult allocateAndroidHardwareBuffer(void **pBuffer);
+ VkResult allocateAndroidHardwareBuffer(size_t size, void **pBuffer);
VkResult lockAndroidHardwareBuffer(void **pBuffer);
VkResult unlockAndroidHardwareBuffer();