anv/android: Rework our handling of AHardwareBuffer imports

The current code we have for this is a bit of a mess, likely due to
trying too hard to put it in anv_android.c.  The external_format bit in
anv_image, for instance, really means "quit creation early" which is
something we want to do for AHardwareBuffer imports regardless of
whether or not they use a native format.  It gets set both by declaring
an AHardwareBuffer external handle type and by VkExternalFormatANDROID.
However, VkExternalFormatANDROID is only allowed for AHardwareBuffer
imports.  If we ever did get an external format outside the context of
an AHardwareBuffer import, we would end up with a useless partially
created image.

When we detect an AHardwareBuffer import, we punt off to a function in
anv_android.c that does nothing interesting but call anv_create_image
with AUX disabled and external_format = true.  The aux disable here is
useless because the actual isl_surf layout is done by resolve_ahw_image
which also sets ISL_SURF_USAGE_DISABLE_AUX_BIT.  As far as external
formats go, anv_image_from_external() sets it regardless of whether or
not there is actually an external format.

This commit replaces anv_image::external_format with anv_image::from_ahb
which is the thing we actually want to track for this.  We delete
anv_image_from_external and a bunch of the external_format handling
because it's all useless.  The end result is massively simpler and,
while it appears to blur the boundary between Android code and the rest
of the driver, it makes the whole flow more obvious.

Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12040>
This commit is contained in:
Jason Ekstrand 2021-07-22 11:17:28 -05:00 committed by Marge Bot
parent d903f51631
commit 49908c602f
3 changed files with 26 additions and 74 deletions

View File

@ -452,47 +452,6 @@ anv_create_ahw_memory(VkDevice device_h,
}
VkResult
anv_image_from_external(
VkDevice device_h,
const VkImageCreateInfo *base_info,
const VkExternalMemoryImageCreateInfo *create_info,
const VkAllocationCallbacks *alloc,
VkImage *out_image_h)
{
#if ANDROID_API_LEVEL >= 26
ANV_FROM_HANDLE(anv_device, device, device_h);
const 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;
#else
return VK_ERROR_EXTENSION_NOT_PRESENT;
#endif
}
VkResult
anv_image_from_gralloc(VkDevice device_h,
const VkImageCreateInfo *base_info,

View File

@ -1266,6 +1266,9 @@ anv_image_create(VkDevice _device,
const struct wsi_image_create_info *wsi_info =
vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
const VkExternalFormatANDROID *ext_format =
vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID);
if (pCreateInfo->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
mod_explicit_info =
vk_find_struct_const(pCreateInfo->pNext,
@ -1312,6 +1315,9 @@ anv_image_create(VkDevice _device,
image->drm_format_mod = isl_mod_info ? isl_mod_info->modifier :
DRM_FORMAT_MOD_INVALID;
if (ext_format && ext_format->externalFormat != 0)
image->has_android_external_format = true;
if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
image->stencil_usage = pCreateInfo->usage;
const VkImageStencilUsageCreateInfoEXT *stencil_usage_info =
@ -1330,11 +1336,12 @@ anv_image_create(VkDevice _device,
};
}
/* 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;
/* In case of AHardwareBuffer import, we don't know the layout yet */
const VkExternalMemoryImageCreateInfo *ext_mem_info =
vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
if (ext_mem_info && (ext_mem_info->handleTypes &
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)) {
image->from_ahb = true;
*pImage = anv_image_to_handle(image);
return VK_SUCCESS;
}
@ -1453,7 +1460,6 @@ anv_image_from_swapchain(VkDevice device,
return anv_image_create(device,
&(struct anv_image_create_info) {
.vk_info = &local_create_info,
.external_format = swapchain_image->external_format,
},
pAllocator,
pImage);
@ -1465,25 +1471,6 @@ anv_CreateImage(VkDevice device,
const VkAllocationCallbacks *pAllocator,
VkImage *pImage)
{
const 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);
bool use_external_format = false;
const VkExternalFormatANDROID *ext_format =
vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID);
/* "If externalFormat is zero, the effect is as if the
* VkExternalFormatANDROID structure was not present. Otherwise, the image
* will have the specified external format."
*/
if (ext_format && ext_format->externalFormat != 0)
use_external_format = true;
const VkNativeBufferANDROID *gralloc_info =
vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
if (gralloc_info)
@ -1499,7 +1486,6 @@ anv_CreateImage(VkDevice device,
return anv_image_create(device,
&(struct anv_image_create_info) {
.vk_info = pCreateInfo,
.external_format = use_external_format,
},
pAllocator,
pImage);
@ -1653,7 +1639,7 @@ void anv_GetImageMemoryRequirements2(
switch (ext->sType) {
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
VkMemoryDedicatedRequirements *requirements = (void *)ext;
if (image->needs_set_tiling || image->external_format) {
if (image->needs_set_tiling || image->from_ahb) {
/* If we need to set the tiling for external consumers, we need a
* dedicated allocation.
*
@ -2705,7 +2691,7 @@ anv_CreateImageView(VkDevice _device,
* VKSamplerYcbcrConversionInfo with a conversion object created with the same
* external format as image."
*/
assert(!image->external_format || conv_info);
assert(!image->has_android_external_format || conv_info);
if (conv_info) {
ANV_FROM_HANDLE(anv_ycbcr_conversion, conversion, conv_info->conversion);
@ -2791,7 +2777,8 @@ anv_CreateImageView(VkDevice _device,
iview->vk_format = pCreateInfo->format;
/* "If image has an external format, format must be VK_FORMAT_UNDEFINED." */
assert(!image->external_format || pCreateInfo->format == VK_FORMAT_UNDEFINED);
assert(!image->has_android_external_format ||
pCreateInfo->format == VK_FORMAT_UNDEFINED);
/* Format is undefined, this can happen when using external formats. Set
* view format from the passed conversion info.

View File

@ -3983,8 +3983,16 @@ struct anv_image {
*/
bool disjoint;
/* Image was created with external format. */
bool external_format;
/**
* Image was imported from an struct AHardwareBuffer. We have to delay
* final image creation until bind time.
*/
bool from_ahb;
/**
* True if an external format was specified
*/
bool has_android_external_format;
/**
* Image was imported from gralloc with VkNativeBufferANDROID. The gralloc bo
@ -4434,8 +4442,6 @@ struct anv_image_create_info {
/** These flags will be added to any derived from VkImageCreateInfo. */
isl_surf_usage_flags_t isl_extra_usage_flags;
bool external_format;
};
VkResult anv_image_create(VkDevice _device,