On Tue, Aug 21, 2018 at 3:28 AM Tapani Pälli <tapani.pa...@intel.com> 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 > > Signed-off-by: Tapani Pälli <tapani.pa...@intel.com> > --- > src/intel/vulkan/anv_android.c | 40 ++++++++++++++ > src/intel/vulkan/anv_device.c | 2 +- > src/intel/vulkan/anv_image.c | 115 > +++++++++++++++++++++++++++++++++++++++++ > src/intel/vulkan/anv_private.h | 10 ++++ > 4 files changed, 166 insertions(+), 1 deletion(-) > > diff --git a/src/intel/vulkan/anv_android.c > b/src/intel/vulkan/anv_android.c > index 6f90649847d..299b728a6f2 100644 > --- a/src/intel/vulkan/anv_android.c > +++ b/src/intel/vulkan/anv_android.c > @@ -344,6 +344,46 @@ 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; > + > + /* Note, we can't set format, stride and such yet. */ > + struct anv_image_create_info anv_info = { > + .vk_info = base_info, > + .isl_extra_usage_flags = ISL_SURF_USAGE_DISABLE_AUX_BIT, > + .external_format = true, > + }; > + > + 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); > + } > + > + 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 54919112d08..fbe057a8eec 100644 > --- a/src/intel/vulkan/anv_device.c > +++ b/src/intel/vulkan/anv_device.c > @@ -2634,7 +2634,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 e4ab74a15d6..de03d64c6a7 100644 > --- a/src/intel/vulkan/anv_image.c > +++ b/src/intel/vulkan/anv_image.c > @@ -596,6 +596,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); > > @@ -631,6 +640,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); > > @@ -687,6 +704,99 @@ static void anv_image_bind_memory_plane(struct > anv_device *device, > }; > } > > +#ifdef ANDROID > +/* We are binding AHardwareBuffer. Get a description and > + * prepare anv_image properly. > + */ > +static void > +prepare_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) { > + case I915_TILING_NONE: > + vk_tiling = VK_IMAGE_TILING_LINEAR; > + isl_tiling_flags = ISL_TILING_LINEAR_BIT; > + break; > + case I915_TILING_X: > + vk_tiling = VK_IMAGE_TILING_OPTIMAL; > + isl_tiling_flags = ISL_TILING_X_BIT; > + break; > + case I915_TILING_Y: > + vk_tiling = VK_IMAGE_TILING_OPTIMAL; > + isl_tiling_flags = ISL_TILING_Y0_BIT; > + break; > + case -1: > + default: > + unreachable("Invalid tiling flags."); > + } > + > + assert(vk_tiling == VK_IMAGE_TILING_LINEAR || > + vk_tiling == VK_IMAGE_TILING_OPTIMAL); > + > + /* Check format. */ > + VkFormat vk_format = vk_format_from_android(desc.format); > + enum isl_format isl_fmt = anv_get_isl_format(&device->info, > + vk_format, > + VK_IMAGE_ASPECT_COLOR_BIT, > + vk_tiling); > + assert(format != ISL_FORMAT_UNSUPPORTED); > + > + /* Now we should be able to fill anv_image fields properly and > + * create isl_surface for it. > + */ > + image->vk_format = vk_format; > + image->format = anv_get_format(vk_format); > + image->aspects = vk_format_aspects(image->vk_format); > + > + const struct anv_format *format = anv_get_format(image->vk_format); > + assert(format != NULL); > + > + image->n_planes = format->n_planes; > + > + /* Fill anv_image_create_info here so that we can call make_surface. */ > + VkImageCreateInfo base_info = { > + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, > + .pNext = NULL, > + .format = vk_format, > + .imageType = VK_IMAGE_TYPE_2D, > + .usage = VK_IMAGE_USAGE_SAMPLED_BIT, > + .tiling = VK_IMAGE_TILING_OPTIMAL, > + .samples = image->samples, > + .arrayLayers = image->array_size, > + .mipLevels = image->levels, > + .extent = image->extent, > + }; > This is gross. Most of the stuff that make_surface pulls from the VkImageCreateInfo is already stashed in the image. We should make make_surface pull the data it needs from the image and stop referencing the VkImageCreateInfo directly. Then this function would get a lot smaller and we would have less redundant information to get out of sync. > + > + struct anv_image_create_info anv_info = { > + .vk_info = &base_info, > + .isl_extra_usage_flags = ISL_SURF_USAGE_DISABLE_AUX_BIT, > + .external_format = true, > + }; > + > + anv_info.stride = desc.stride * > + (isl_format_get_layout(isl_fmt)->bpb / 8); > + > + uint32_t b; > + for_each_bit(b, image->aspects) { > + VkResult r = make_surface(device, image, &anv_info, > isl_tiling_flags, > + (1 << b)); > + assert(r == VK_SUCCESS); > + } > +} > +#endif > + > VkResult anv_BindImageMemory( > VkDevice _device, > VkImage _image, > @@ -697,6 +807,11 @@ VkResult anv_BindImageMemory( > ANV_FROM_HANDLE(anv_device_memory, mem, _memory); > ANV_FROM_HANDLE(anv_image, image, _image); > > +#ifdef ANDROID > + if (mem->ahw && image->format == VK_FORMAT_UNDEFINED) > + prepare_ahw_image(device, image, mem); > +#endif > + > uint32_t aspect_bit; > anv_foreach_image_aspect_bit(aspect_bit, image, image->aspects) { > uint32_t plane = > diff --git a/src/intel/vulkan/anv_private.h > b/src/intel/vulkan/anv_private.h > index 56dee607dbe..7c01cf82a52 100644 > --- a/src/intel/vulkan/anv_private.h > +++ b/src/intel/vulkan/anv_private.h > @@ -2665,6 +2665,9 @@ struct anv_image { > */ > bool disjoint; > > + /* Image was created with external format. */ > + bool external_format; > + > /** > * Image subsurfaces > * > @@ -3040,6 +3043,7 @@ struct anv_image_create_info { > isl_surf_usage_flags_t isl_extra_usage_flags; > > uint32_t stride; > + bool external_format; > }; > > VkResult anv_image_create(VkDevice _device, > @@ -3054,6 +3058,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); > + > VkResult anv_import_ahw_memory(VkDevice device_h, > struct anv_device_memory *mem, > const > VkImportAndroidHardwareBufferInfoANDROID *info); > -- > 2.14.4 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev