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:
parent
8d679f4f4e
commit
19b7bbba73
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue