anv/android: handle image bindings from gralloc buffers

When creating an image out of a swapchain on Android, the android
layer call will detect a VkBindImageMemorySwapchainInfoKHR in the
pNext chain of the vkBindImageMemory2() call and add a
VkNativeBufferANDROID in the chain. This is what we should use as
backing memory for that image.

v2: Fix a couple of obvious mistakes (Tapani)

v3: Silence build warning (Lionel)
    Fix invalid object argument to vk_error() (Lionel)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: bc3c71b87a ("anv: don't try to access Android swapchains")
Cc: mesa-stable
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5180
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12244>
This commit is contained in:
Lionel Landwerlin 2021-08-11 12:57:37 +03:00 committed by Marge Bot
parent 8d679f4f4e
commit 19b7bbba73
4 changed files with 82 additions and 0 deletions

View File

@ -584,6 +584,59 @@ anv_image_from_gralloc(VkDevice device_h,
return result;
}
VkResult
anv_image_bind_from_gralloc(struct anv_device *device,
struct anv_image *image,
const VkNativeBufferANDROID *gralloc_info)
{
/* Do not close the gralloc handle's dma_buf. The lifetime of the dma_buf
* must exceed that of the gralloc handle, and we do not own the gralloc
* handle.
*/
int dma_buf = gralloc_info->handle->data[0];
/* We need to set the WRITE flag on window system buffers so that GEM will
* know we're writing to them and synchronize uses on other rings (for
* example, if the display server uses the blitter ring).
*
* If this function fails and if the imported bo was resident in the cache,
* we should avoid updating the bo's flags. Therefore, we defer updating
* the flags until success is certain.
*
*/
struct anv_bo *bo = NULL;
VkResult result = anv_device_import_bo(device, dma_buf,
ANV_BO_ALLOC_IMPLICIT_SYNC |
ANV_BO_ALLOC_IMPLICIT_WRITE,
0 /* client_address */,
&bo);
if (result != VK_SUCCESS) {
return vk_errorf(device, &device->vk.base, result,
"failed to import dma-buf from VkNativeBufferANDROID");
}
uint64_t img_size = image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].memory_range.size;
if (img_size < bo->size) {
result = vk_errorf(device, &device->vk.base, VK_ERROR_INVALID_EXTERNAL_HANDLE,
"dma-buf from VkNativeBufferANDROID is too small for "
"VkImage: %"PRIu64"B < %"PRIu64"B",
bo->size, img_size);
anv_device_release_bo(device, bo);
return result;
}
assert(!image->disjoint);
assert(image->n_planes == 1);
assert(image->planes[0].primary_surface.memory_range.binding ==
ANV_IMAGE_MEMORY_BINDING_MAIN);
assert(image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.bo == NULL);
assert(image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.offset == 0);
image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.bo = bo;
image->from_gralloc = true;
return VK_SUCCESS;
}
static VkResult
format_supported_with_usage(VkDevice device_h, VkFormat format,
VkImageUsageFlags imageUsage)

View File

@ -41,6 +41,10 @@ VkResult anv_image_from_gralloc(VkDevice device_h,
const VkAllocationCallbacks *alloc,
VkImage *pImage);
VkResult anv_image_bind_from_gralloc(struct anv_device *device,
struct anv_image *image,
const VkNativeBufferANDROID *gralloc_info);
VkResult anv_image_from_external(VkDevice device_h,
const VkImageCreateInfo *base_info,
const VkExternalMemoryImageCreateInfo *create_info,

View File

@ -33,6 +33,13 @@ anv_image_from_gralloc(VkDevice device_h,
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
VkResult anv_image_bind_from_gralloc(struct anv_device *device,
struct anv_image *image,
const VkNativeBufferANDROID *gralloc_info)
{
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
uint64_t
anv_ahw_usage_from_vk_usage(const VkImageCreateFlags vk_create,
const VkImageUsageFlags vk_usage)

View File

@ -1772,6 +1772,10 @@ VkResult anv_BindImageMemory2(
break;
}
case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: {
/* Ignore this struct on Android, we cannot access swapchain
* structures threre.
*/
#ifndef VK_USE_PLATFORM_ANDROID_KHR
const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
(const VkBindImageMemorySwapchainInfoKHR *) s;
struct anv_image *swapchain_image =
@ -1793,8 +1797,22 @@ VkResult anv_BindImageMemory2(
anv_bo_ref(private_bo);
did_bind = true;
#endif
break;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch"
case VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID: {
const VkNativeBufferANDROID *gralloc_info =
(const VkNativeBufferANDROID *)s;
VkResult result = anv_image_bind_from_gralloc(device, image,
gralloc_info);
if (result != VK_SUCCESS)
return result;
did_bind = true;
break;
}
#pragma GCC diagnostic pop
default:
anv_debug_ignored_stype(s->sType);
break;