diff --git a/src/intel/vulkan/anv_android.c b/src/intel/vulkan/anv_android.c index df75c02cdb3..6f2d830a757 100644 --- a/src/intel/vulkan/anv_android.c +++ b/src/intel/vulkan/anv_android.c @@ -465,12 +465,22 @@ anv_image_bind_from_gralloc(struct anv_device *device, "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) { + VkMemoryRequirements2 mem_reqs = { + .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, + }; + + anv_image_get_memory_requirements(device, image, image->vk.aspects, + &mem_reqs); + + VkDeviceSize aligned_image_size = + align64(mem_reqs.memoryRequirements.size, + mem_reqs.memoryRequirements.alignment); + + if (bo->size < aligned_image_size) { result = vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE, "dma-buf from VkNativeBufferANDROID is too small for " "VkImage: %"PRIu64"B < %"PRIu64"B", - bo->size, img_size); + bo->size, aligned_image_size); anv_device_release_bo(device, bo); return result; } diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index d95c6759116..c1647081443 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -1620,6 +1620,15 @@ anv_image_init(struct anv_device *device, struct anv_image *image, image->n_planes = anv_get_format_planes(image->vk.format); +#ifdef VK_USE_PLATFORM_ANDROID_KHR + /* In the case of gralloc-backed swap chain image, we don't know the + * layout yet. + */ + if (vk_find_struct_const(pCreateInfo->pNext, + IMAGE_SWAPCHAIN_CREATE_INFO_KHR) != NULL) + return VK_SUCCESS; +#endif + image->from_wsi = vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA) != NULL; @@ -1916,9 +1925,9 @@ VkResult anv_CreateImage( __LINE__, pCreateInfo->flags); #ifndef VK_USE_PLATFORM_ANDROID_KHR - /* Ignore swapchain creation info on Android. Since we don't have an - * implementation in Mesa, we're guaranteed to access an Android object - * incorrectly. + /* Skip the WSI common swapchain creation here on Android. Similar to ahw, + * this case is handled by a partial image init and then resolved when the + * image is bound and gralloc info is passed. */ const VkImageSwapchainCreateInfoKHR *swapchain_info = vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR); @@ -2013,6 +2022,36 @@ resolve_ahw_image(struct anv_device *device, #endif } +static void +resolve_anb_image(struct anv_device *device, + struct anv_image *image, + const VkNativeBufferANDROID *gralloc_info) +{ +#if DETECT_OS_ANDROID && ANDROID_API_LEVEL >= 29 + VkResult result; + + /* Check tiling. */ + enum isl_tiling tiling; + struct u_gralloc_buffer_handle gr_handle = { + .handle = gralloc_info->handle, + .hal_format = gralloc_info->format, + .pixel_stride = gralloc_info->stride, + }; + result = anv_android_get_tiling(device, &gr_handle, &tiling); + assert(result == VK_SUCCESS); + + isl_tiling_flags_t isl_tiling_flags = (1u << tiling); + + /* Now we are able to fill anv_image fields properly and create + * isl_surface for it. + */ + result = add_all_surfaces_implicit_layout(device, image, NULL, gralloc_info->stride, + isl_tiling_flags, + ISL_SURF_USAGE_DISABLE_AUX_BIT); + assert(result == VK_SUCCESS); +#endif +} + static bool anv_image_is_pat_compressible(struct anv_device *device, struct anv_image *image) { @@ -2528,6 +2567,8 @@ anv_bind_image_memory(struct anv_device *device, gralloc_info); if (result != VK_SUCCESS) return result; + + resolve_anb_image(device, image, gralloc_info); did_bind = true; break; }