diff --git a/src/intel/vulkan/anv_android.c b/src/intel/vulkan/anv_android.c index 05925b015cc..da52da66b97 100644 --- a/src/intel/vulkan/anv_android.c +++ b/src/intel/vulkan/anv_android.c @@ -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) diff --git a/src/intel/vulkan/anv_android.h b/src/intel/vulkan/anv_android.h index 81ecf67f87e..2e329b3029c 100644 --- a/src/intel/vulkan/anv_android.h +++ b/src/intel/vulkan/anv_android.h @@ -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, diff --git a/src/intel/vulkan/anv_android_stubs.c b/src/intel/vulkan/anv_android_stubs.c index 3e773dfe710..f6b2d1c8dd1 100644 --- a/src/intel/vulkan/anv_android_stubs.c +++ b/src/intel/vulkan/anv_android_stubs.c @@ -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) diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index 12e123e2186..8a94a226b96 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -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;