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: 's avatarJason Macnak <natsu@google.com> Commit-Queue: Jason Macnak <natsu@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 236d75a2
......@@ -194,16 +194,16 @@ AHardwareBufferExternalMemory::AllocateInfo::AllocateInfo(const VkMemoryAllocate
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 @@ AHardwareBufferExternalMemory::~AHardwareBufferExternalMemory()
}
// VkAllocateMemory
VkResult AHardwareBufferExternalMemory::allocate(size_t /*size*/, void **pBuffer)
VkResult AHardwareBufferExternalMemory::allocate(size_t size, void **pBuffer)
{
if(allocateInfo.importAhb)
{
......@@ -230,7 +230,7 @@ VkResult AHardwareBufferExternalMemory::allocate(size_t /*size*/, void **pBuffer
else
{
ASSERT(allocateInfo.exportAhb);
return allocateAndroidHardwareBuffer(pBuffer);
return allocateAndroidHardwareBuffer(size, pBuffer);
}
}
......@@ -255,12 +255,11 @@ VkResult AHardwareBufferExternalMemory::importAndroidHardwareBuffer(AHardwareBuf
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 @@ VkResult AHardwareBufferExternalMemory::allocateAndroidHardwareBuffer(void **pBu
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 @@ VkResult AHardwareBufferExternalMemory::allocateAndroidHardwareBuffer(void **pBu
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::allocateAndroidHardwareBuffer(void **pBu
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 @@ VkResult AHardwareBufferExternalMemory::GetAndroidHardwareBufferProperties(VkDev
int AHardwareBufferExternalMemory::externalImageRowPitchBytes(VkImageAspectFlagBits aspect) const
{
ASSERT(allocateInfo.dedicatedImageHandle != nullptr);
switch(ahbDesc.format)
{
case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
......@@ -490,6 +506,8 @@ int AHardwareBufferExternalMemory::externalImageRowPitchBytes(VkImageAspectFlagB
VkDeviceSize AHardwareBufferExternalMemory::externalImageMemoryOffset(VkImageAspectFlagBits aspect) const
{
ASSERT(allocateInfo.dedicatedImageHandle != nullptr);
switch(ahbDesc.format)
{
case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
......
......@@ -34,8 +34,8 @@ public:
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 @@ public:
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 @@ public:
private:
VkResult importAndroidHardwareBuffer(AHardwareBuffer *buffer, void **pBuffer);
VkResult allocateAndroidHardwareBuffer(void **pBuffer);
VkResult allocateAndroidHardwareBuffer(size_t size, void **pBuffer);
VkResult lockAndroidHardwareBuffer(void **pBuffer);
VkResult unlockAndroidHardwareBuffer();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment