Re: [Mesa-dev] [PATCH 10/15] anv/android: support creating images from external format
On 12/11/18 3:27 PM, Lionel Landwerlin wrote: On 27/11/2018 10:53, Tapani Pälli wrote: Since we don't know the exact format at creation time, some initialization is done only when bound with memory in vkBindImageMemory. v2: demand dedicated allocation in vkGetImageMemoryRequirements2 if image has external format v3: refactor prepare_ahw_image, support vkBindImageMemory2, calculate stride correctly for rgb(x) surfaces, rename as 'resolve_ahw_image' v4: rebase to b43f955037c changes Signed-off-by: Tapani Pälli Another couple of suggestions belower, otherwise : Reviewed-by: Lionel Landwerlin --- src/intel/vulkan/anv_android.c | 36 ++ src/intel/vulkan/anv_android.h | 8 +++ src/intel/vulkan/anv_android_stubs.c | 10 +++ src/intel/vulkan/anv_device.c | 2 +- src/intel/vulkan/anv_image.c | 103 ++- src/intel/vulkan/anv_private.h | 4 ++ 6 files changed, 160 insertions(+), 3 deletions(-) diff --git a/src/intel/vulkan/anv_android.c b/src/intel/vulkan/anv_android.c index bdc720214c4..3bc2b63b1c9 100644 --- a/src/intel/vulkan/anv_android.c +++ b/src/intel/vulkan/anv_android.c @@ -356,6 +356,42 @@ anv_create_ahw_memory(VkDevice device_h, return VK_SUCCESS; } +VkResult +anv_image_from_external( + VkDevice device_h, + const VkImageCreateInfo *base_info, + const struct VkExternalMemoryImageCreateInfo *create_info, + const VkAllocationCallbacks *alloc, + VkImage *out_image_h) +{ + ANV_FROM_HANDLE(anv_device, device, device_h); + + const struct VkExternalFormatANDROID *ext_info = + vk_find_struct_const(base_info->pNext, EXTERNAL_FORMAT_ANDROID); + + if (ext_info && ext_info->externalFormat != 0) { + assert(base_info->format == VK_FORMAT_UNDEFINED); + assert(base_info->imageType == VK_IMAGE_TYPE_2D); + assert(base_info->usage == VK_IMAGE_USAGE_SAMPLED_BIT); + assert(base_info->tiling == VK_IMAGE_TILING_OPTIMAL); + } + + struct anv_image_create_info anv_info = { + .vk_info = base_info, + .isl_extra_usage_flags = ISL_SURF_USAGE_DISABLE_AUX_BIT, + .external_format = true, + }; + + VkImage image_h; + VkResult result = anv_image_create(device_h, &anv_info, alloc, &image_h); + if (result != VK_SUCCESS) + return result; + + *out_image_h = image_h; + + return VK_SUCCESS; +} + VkResult anv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info, diff --git a/src/intel/vulkan/anv_android.h b/src/intel/vulkan/anv_android.h index 01f0e856291..d5c073126e3 100644 --- a/src/intel/vulkan/anv_android.h +++ b/src/intel/vulkan/anv_android.h @@ -29,6 +29,8 @@ #include struct anv_device_memory; +struct anv_device; +struct anv_image; VkResult anv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info, @@ -36,6 +38,12 @@ VkResult anv_image_from_gralloc(VkDevice device_h, const VkAllocationCallbacks *alloc, VkImage *pImage); +VkResult anv_image_from_external(VkDevice device_h, + const VkImageCreateInfo *base_info, + const struct VkExternalMemoryImageCreateInfo *create_info, + const VkAllocationCallbacks *alloc, + VkImage *out_image_h); + uint64_t anv_ahw_usage_from_vk_usage(const VkImageCreateFlags vk_create, const VkImageUsageFlags vk_usage); diff --git a/src/intel/vulkan/anv_android_stubs.c b/src/intel/vulkan/anv_android_stubs.c index ccc16500494..a34afc198a1 100644 --- a/src/intel/vulkan/anv_android_stubs.c +++ b/src/intel/vulkan/anv_android_stubs.c @@ -55,3 +55,13 @@ anv_create_ahw_memory(VkDevice device_h, { return VK_ERROR_EXTENSION_NOT_PRESENT; } + +VkResult +anv_image_from_external(VkDevice device_h, + const VkImageCreateInfo *base_info, + const struct VkExternalMemoryImageCreateInfo *create_info, + const VkAllocationCallbacks *alloc, + VkImage *out_image_h) +{ + return VK_ERROR_EXTENSION_NOT_PRESENT; +} diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index a1ee9315956..5777de96d80 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -2768,7 +2768,7 @@ void anv_GetImageMemoryRequirements2( switch (ext->sType) { case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: { VkMemoryDedicatedRequirements *requirements = (void *)ext; - if (image->needs_set_tiling) { + if (image->needs_set_tiling || image->external_format) { /* If we need to set the tiling for external consumers, we need a * dedicated allocation. It's tempting to add an assert(image->size > 0) in the
Re: [Mesa-dev] [PATCH 10/15] anv/android: support creating images from external format
On 27/11/2018 10:53, Tapani Pälli wrote: Since we don't know the exact format at creation time, some initialization is done only when bound with memory in vkBindImageMemory. v2: demand dedicated allocation in vkGetImageMemoryRequirements2 if image has external format v3: refactor prepare_ahw_image, support vkBindImageMemory2, calculate stride correctly for rgb(x) surfaces, rename as 'resolve_ahw_image' v4: rebase to b43f955037c changes Signed-off-by: Tapani Pälli Another couple of suggestions belower, otherwise : Reviewed-by: Lionel Landwerlin --- src/intel/vulkan/anv_android.c | 36 ++ src/intel/vulkan/anv_android.h | 8 +++ src/intel/vulkan/anv_android_stubs.c | 10 +++ src/intel/vulkan/anv_device.c| 2 +- src/intel/vulkan/anv_image.c | 103 ++- src/intel/vulkan/anv_private.h | 4 ++ 6 files changed, 160 insertions(+), 3 deletions(-) diff --git a/src/intel/vulkan/anv_android.c b/src/intel/vulkan/anv_android.c index bdc720214c4..3bc2b63b1c9 100644 --- a/src/intel/vulkan/anv_android.c +++ b/src/intel/vulkan/anv_android.c @@ -356,6 +356,42 @@ anv_create_ahw_memory(VkDevice device_h, return VK_SUCCESS; } +VkResult +anv_image_from_external( + VkDevice device_h, + const VkImageCreateInfo *base_info, + const struct VkExternalMemoryImageCreateInfo *create_info, + const VkAllocationCallbacks *alloc, + VkImage *out_image_h) +{ + ANV_FROM_HANDLE(anv_device, device, device_h); + + const struct VkExternalFormatANDROID *ext_info = + vk_find_struct_const(base_info->pNext, EXTERNAL_FORMAT_ANDROID); + + if (ext_info && ext_info->externalFormat != 0) { + assert(base_info->format == VK_FORMAT_UNDEFINED); + assert(base_info->imageType == VK_IMAGE_TYPE_2D); + assert(base_info->usage == VK_IMAGE_USAGE_SAMPLED_BIT); + assert(base_info->tiling == VK_IMAGE_TILING_OPTIMAL); + } + + struct anv_image_create_info anv_info = { + .vk_info = base_info, + .isl_extra_usage_flags = ISL_SURF_USAGE_DISABLE_AUX_BIT, + .external_format = true, + }; + + VkImage image_h; + VkResult result = anv_image_create(device_h, &anv_info, alloc, &image_h); + if (result != VK_SUCCESS) + return result; + + *out_image_h = image_h; + + return VK_SUCCESS; +} + VkResult anv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info, diff --git a/src/intel/vulkan/anv_android.h b/src/intel/vulkan/anv_android.h index 01f0e856291..d5c073126e3 100644 --- a/src/intel/vulkan/anv_android.h +++ b/src/intel/vulkan/anv_android.h @@ -29,6 +29,8 @@ #include struct anv_device_memory; +struct anv_device; +struct anv_image; VkResult anv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info, @@ -36,6 +38,12 @@ VkResult anv_image_from_gralloc(VkDevice device_h, const VkAllocationCallbacks *alloc, VkImage *pImage); +VkResult anv_image_from_external(VkDevice device_h, + const VkImageCreateInfo *base_info, + const struct VkExternalMemoryImageCreateInfo *create_info, + const VkAllocationCallbacks *alloc, + VkImage *out_image_h); + uint64_t anv_ahw_usage_from_vk_usage(const VkImageCreateFlags vk_create, const VkImageUsageFlags vk_usage); diff --git a/src/intel/vulkan/anv_android_stubs.c b/src/intel/vulkan/anv_android_stubs.c index ccc16500494..a34afc198a1 100644 --- a/src/intel/vulkan/anv_android_stubs.c +++ b/src/intel/vulkan/anv_android_stubs.c @@ -55,3 +55,13 @@ anv_create_ahw_memory(VkDevice device_h, { return VK_ERROR_EXTENSION_NOT_PRESENT; } + +VkResult +anv_image_from_external(VkDevice device_h, +const VkImageCreateInfo *base_info, +const struct VkExternalMemoryImageCreateInfo *create_info, +const VkAllocationCallbacks *alloc, +VkImage *out_image_h) +{ + return VK_ERROR_EXTENSION_NOT_PRESENT; +} diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index a1ee9315956..5777de96d80 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -2768,7 +2768,7 @@ void anv_GetImageMemoryRequirements2( switch (ext->sType) { case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: { VkMemoryDedicatedRequirements *requirements = (void *)ext; - if (image->needs_set_tiling) { + if (image->needs_set_tiling || image->external_format) { /* If we need to set the tiling for external consumers, we need a * dedicated allocation. It's tempting to add an assert(image->size > 0) in the GetImageMemoryRequirements*() functions. Wit
[Mesa-dev] [PATCH 10/15] anv/android: support creating images from external format
Since we don't know the exact format at creation time, some initialization is done only when bound with memory in vkBindImageMemory. v2: demand dedicated allocation in vkGetImageMemoryRequirements2 if image has external format v3: refactor prepare_ahw_image, support vkBindImageMemory2, calculate stride correctly for rgb(x) surfaces, rename as 'resolve_ahw_image' v4: rebase to b43f955037c changes Signed-off-by: Tapani Pälli --- src/intel/vulkan/anv_android.c | 36 ++ src/intel/vulkan/anv_android.h | 8 +++ src/intel/vulkan/anv_android_stubs.c | 10 +++ src/intel/vulkan/anv_device.c| 2 +- src/intel/vulkan/anv_image.c | 103 ++- src/intel/vulkan/anv_private.h | 4 ++ 6 files changed, 160 insertions(+), 3 deletions(-) diff --git a/src/intel/vulkan/anv_android.c b/src/intel/vulkan/anv_android.c index bdc720214c4..3bc2b63b1c9 100644 --- a/src/intel/vulkan/anv_android.c +++ b/src/intel/vulkan/anv_android.c @@ -356,6 +356,42 @@ anv_create_ahw_memory(VkDevice device_h, return VK_SUCCESS; } +VkResult +anv_image_from_external( + VkDevice device_h, + const VkImageCreateInfo *base_info, + const struct VkExternalMemoryImageCreateInfo *create_info, + const VkAllocationCallbacks *alloc, + VkImage *out_image_h) +{ + ANV_FROM_HANDLE(anv_device, device, device_h); + + const struct VkExternalFormatANDROID *ext_info = + vk_find_struct_const(base_info->pNext, EXTERNAL_FORMAT_ANDROID); + + if (ext_info && ext_info->externalFormat != 0) { + assert(base_info->format == VK_FORMAT_UNDEFINED); + assert(base_info->imageType == VK_IMAGE_TYPE_2D); + assert(base_info->usage == VK_IMAGE_USAGE_SAMPLED_BIT); + assert(base_info->tiling == VK_IMAGE_TILING_OPTIMAL); + } + + struct anv_image_create_info anv_info = { + .vk_info = base_info, + .isl_extra_usage_flags = ISL_SURF_USAGE_DISABLE_AUX_BIT, + .external_format = true, + }; + + VkImage image_h; + VkResult result = anv_image_create(device_h, &anv_info, alloc, &image_h); + if (result != VK_SUCCESS) + return result; + + *out_image_h = image_h; + + return VK_SUCCESS; +} + VkResult anv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info, diff --git a/src/intel/vulkan/anv_android.h b/src/intel/vulkan/anv_android.h index 01f0e856291..d5c073126e3 100644 --- a/src/intel/vulkan/anv_android.h +++ b/src/intel/vulkan/anv_android.h @@ -29,6 +29,8 @@ #include struct anv_device_memory; +struct anv_device; +struct anv_image; VkResult anv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info, @@ -36,6 +38,12 @@ VkResult anv_image_from_gralloc(VkDevice device_h, const VkAllocationCallbacks *alloc, VkImage *pImage); +VkResult anv_image_from_external(VkDevice device_h, + const VkImageCreateInfo *base_info, + const struct VkExternalMemoryImageCreateInfo *create_info, + const VkAllocationCallbacks *alloc, + VkImage *out_image_h); + uint64_t anv_ahw_usage_from_vk_usage(const VkImageCreateFlags vk_create, const VkImageUsageFlags vk_usage); diff --git a/src/intel/vulkan/anv_android_stubs.c b/src/intel/vulkan/anv_android_stubs.c index ccc16500494..a34afc198a1 100644 --- a/src/intel/vulkan/anv_android_stubs.c +++ b/src/intel/vulkan/anv_android_stubs.c @@ -55,3 +55,13 @@ anv_create_ahw_memory(VkDevice device_h, { return VK_ERROR_EXTENSION_NOT_PRESENT; } + +VkResult +anv_image_from_external(VkDevice device_h, +const VkImageCreateInfo *base_info, +const struct VkExternalMemoryImageCreateInfo *create_info, +const VkAllocationCallbacks *alloc, +VkImage *out_image_h) +{ + return VK_ERROR_EXTENSION_NOT_PRESENT; +} diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index a1ee9315956..5777de96d80 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -2768,7 +2768,7 @@ void anv_GetImageMemoryRequirements2( switch (ext->sType) { case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: { VkMemoryDedicatedRequirements *requirements = (void *)ext; - if (image->needs_set_tiling) { + if (image->needs_set_tiling || image->external_format) { /* If we need to set the tiling for external consumers, we need a * dedicated allocation. * diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index 59e9d007831..79777efe456 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -594,6 +594,15 @@ anv_image_create(VkDevice _device, image->drm_format_mod
[Mesa-dev] [PATCH 10/15] anv/android: support creating images from external format
Since we don't know the exact format at creation time, some initialization is done only when bound with memory in vkBindImageMemory. v2: demand dedicated allocation in vkGetImageMemoryRequirements2 if image has external format v3: refactor prepare_ahw_image, support vkBindImageMemory2, calculate stride correctly for rgb(x) surfaces, rename as 'resolve_ahw_image' Signed-off-by: Tapani Pälli --- src/intel/vulkan/anv_android.c | 39 src/intel/vulkan/anv_device.c | 2 +- src/intel/vulkan/anv_image.c | 108 - src/intel/vulkan/anv_private.h | 10 +++ 4 files changed, 157 insertions(+), 2 deletions(-) diff --git a/src/intel/vulkan/anv_android.c b/src/intel/vulkan/anv_android.c index 42fa050af93..f993da875fe 100644 --- a/src/intel/vulkan/anv_android.c +++ b/src/intel/vulkan/anv_android.c @@ -360,6 +360,45 @@ anv_create_ahw_memory(VkDevice device_h, return VK_SUCCESS; } +VkResult +anv_image_from_external( + VkDevice device_h, + const VkImageCreateInfo *base_info, + const struct VkExternalMemoryImageCreateInfo *create_info, + const VkAllocationCallbacks *alloc, + VkImage *out_image_h) +{ + ANV_FROM_HANDLE(anv_device, device, device_h); + VkImage image_h = VK_NULL_HANDLE; + struct anv_image *image = NULL; + VkResult result = VK_SUCCESS; + + const struct VkExternalFormatANDROID *ext_info = + vk_find_struct_const(base_info->pNext, EXTERNAL_FORMAT_ANDROID); + + if (ext_info && ext_info->externalFormat != 0) { + assert(base_info->format == VK_FORMAT_UNDEFINED); + assert(base_info->imageType == VK_IMAGE_TYPE_2D); + assert(base_info->usage == VK_IMAGE_USAGE_SAMPLED_BIT); + assert(base_info->tiling == VK_IMAGE_TILING_OPTIMAL); + } + + struct anv_image_create_info anv_info = { + .vk_info = base_info, + .isl_extra_usage_flags = ISL_SURF_USAGE_DISABLE_AUX_BIT, + .external_format = true, + }; + + result = anv_image_create(device_h, &anv_info, alloc, &image_h); + image = anv_image_from_handle(image_h); + if (result != VK_SUCCESS) + return result; + + *out_image_h = image_h; + + return result; +} + VkResult anv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info, diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 37f923ab3d0..0bf6a5e3e1f 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -2763,7 +2763,7 @@ void anv_GetImageMemoryRequirements2( switch (ext->sType) { case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: { VkMemoryDedicatedRequirements *requirements = (void *)ext; - if (image->needs_set_tiling) { + if (image->needs_set_tiling || image->external_format) { /* If we need to set the tiling for external consumers, we need a * dedicated allocation. * diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index be467815b96..26b5389f6d9 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -595,6 +595,15 @@ anv_image_create(VkDevice _device, image->drm_format_mod = isl_mod_info ? isl_mod_info->modifier : DRM_FORMAT_MOD_INVALID; + /* In case of external format, We don't know format yet, +* so skip the rest for now. +*/ + if (create_info->external_format) { + image->external_format = true; + *pImage = anv_image_to_handle(image); + return VK_SUCCESS; + } + const struct anv_format *format = anv_get_format(image->vk_format); assert(format != NULL); @@ -637,6 +646,14 @@ anv_CreateImage(VkDevice device, VkImage *pImage) { #ifdef ANDROID + const struct VkExternalMemoryImageCreateInfo *create_info = + vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO); + + if (create_info && create_info->handleTypes & + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) + return anv_image_from_external(device, pCreateInfo, create_info, + pAllocator, pImage); + const VkNativeBufferANDROID *gralloc_info = vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID); @@ -693,6 +710,85 @@ static void anv_image_bind_memory_plane(struct anv_device *device, }; } +#ifdef ANDROID +/* We are binding AHardwareBuffer. Get a description, resolve the + * format and prepare anv_image properly. + */ +static void +resolve_ahw_image(struct anv_device *device, + struct anv_image *image, + struct anv_device_memory *mem) +{ + assert(mem->ahw); + + AHardwareBuffer_Desc desc; + AHardwareBuffer_describe(mem->ahw, &desc); + + /* Check tiling. */ + int i915_tiling = anv_gem_get_tiling(device, mem->bo->gem_handle); + VkImageTiling vk_tiling = 2; + + isl_tiling_flags_t isl_tiling_flags = 0; + + switch (i915_tiling) {