From: Jason Ekstrand Date: Thu, 16 Jan 2020 19:38:55 +0000 (-0600) Subject: anv: Support modifiers in GetImageFormatProperties2 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6790397346ccafbe1baa2ef03ce33d6bef5f257c;p=mesa.git anv: Support modifiers in GetImageFormatProperties2 Images with modifiers come with restrictions: 1. They have to be simple 2D images right now 2. They need to have a sensible format (not compressed, multi-plane, or non-power-of-two) 3. If a CCS modifier is being requested, they have to actually support CCS_E and be CCS-compatible with any other formats the client may wish to use for image views. Reviewed-by: Lionel Landwerlin Part-of: --- diff --git a/src/intel/vulkan/anv_formats.c b/src/intel/vulkan/anv_formats.c index 405c7326976..7bd08c87722 100644 --- a/src/intel/vulkan/anv_formats.c +++ b/src/intel/vulkan/anv_formats.c @@ -475,6 +475,18 @@ anv_get_format_plane(const struct gen_device_info *devinfo, VkFormat vk_format, (isl_layout->bpb == 24 || isl_layout->bpb == 48)) return unsupported; + if (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { + /* No non-power-of-two fourcc formats exist */ + if (!util_is_power_of_two_or_zero(isl_layout->bpb)) + return unsupported; + + if (vk_format_is_depth_or_stencil(vk_format)) + return unsupported; + + if (isl_format_is_compressed(plane_format.isl_format)) + return unsupported; + } + if (tiling == VK_IMAGE_TILING_OPTIMAL && !util_is_power_of_two_or_zero(isl_layout->bpb)) { /* Tiled formats *must* be power-of-two because we need up upload @@ -908,6 +920,40 @@ anv_get_image_format_properties( */ } + if (info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { + const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *modifier_info = + vk_find_struct_const(info->pNext, + PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT); + + /* Modifiers are only supported on simple 2D images */ + if (info->type != VK_IMAGE_TYPE_2D) + goto unsupported; + maxArraySize = 1; + maxMipLevels = 1; + assert(sampleCounts == VK_SAMPLE_COUNT_1_BIT); + + /* Modifiers are not yet supported for YCbCr */ + const struct anv_format *format = anv_get_format(info->format); + if (format->n_planes > 1) + goto unsupported; + + const struct isl_drm_modifier_info *isl_mod_info = + isl_drm_modifier_get_info(modifier_info->drmFormatModifier); + if (isl_mod_info->aux_usage == ISL_AUX_USAGE_CCS_E) { + /* If we have a CCS modifier, ensure that the format supports CCS + * and, if VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT is set, all of the + * formats in the format list are CCS compatible. + */ + const VkImageFormatListCreateInfoKHR *fmt_list = + vk_find_struct_const(info->pNext, + IMAGE_FORMAT_LIST_CREATE_INFO_KHR); + if (!anv_formats_ccs_e_compatible(devinfo, info->flags, + info->format, info->tiling, + fmt_list)) + goto unsupported; + } + } + /* From the bspec section entitled "Surface Layout and Tiling", * pre-gen9 has a 2 GB limitation of the size in bytes, * gen9 and gen10 have a 256 GB limitation and gen11+ @@ -1035,6 +1081,9 @@ VkResult anv_GetPhysicalDeviceImageFormatProperties2( case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO: external_info = (const void *) s; break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT: + /* anv_get_image_format_properties will handle this */ + break; case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT: /* Ignore but don't warn */ break; diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index d2395314c91..14dd88537c1 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -159,19 +159,21 @@ add_surface(struct anv_image *image, struct anv_surface *surf, uint32_t plane) } -static bool -all_formats_ccs_e_compatible(const struct gen_device_info *devinfo, - const VkImageFormatListCreateInfoKHR *fmt_list, - struct anv_image *image) +bool +anv_formats_ccs_e_compatible(const struct gen_device_info *devinfo, + VkImageCreateFlags create_flags, + VkFormat vk_format, + VkImageTiling vk_tiling, + const VkImageFormatListCreateInfoKHR *fmt_list) { enum isl_format format = - anv_get_isl_format(devinfo, image->vk_format, - VK_IMAGE_ASPECT_COLOR_BIT, image->tiling); + anv_get_isl_format(devinfo, vk_format, + VK_IMAGE_ASPECT_COLOR_BIT, vk_tiling); if (!isl_format_supports_ccs_e(devinfo, format)) return false; - if (!(image->create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) + if (!(create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) return true; if (!fmt_list || fmt_list->viewFormatCount == 0) @@ -180,7 +182,7 @@ all_formats_ccs_e_compatible(const struct gen_device_info *devinfo, for (uint32_t i = 0; i < fmt_list->viewFormatCount; i++) { enum isl_format view_format = anv_get_isl_format(devinfo, fmt_list->pViewFormats[i], - VK_IMAGE_ASPECT_COLOR_BIT, image->tiling); + VK_IMAGE_ASPECT_COLOR_BIT, vk_tiling); if (!isl_formats_are_ccs_e_compatible(devinfo, format, view_format)) return false; @@ -654,7 +656,8 @@ anv_image_create(VkDevice _device, IMAGE_FORMAT_LIST_CREATE_INFO_KHR); image->ccs_e_compatible = - all_formats_ccs_e_compatible(&device->info, fmt_list, image); + anv_formats_ccs_e_compatible(&device->info, image->create_flags, + image->vk_format, image->tiling, fmt_list); uint32_t b; for_each_bit(b, image->aspects) { diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index dd47df9a09d..b41e1a2ddbd 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -3287,6 +3287,12 @@ anv_get_isl_format(const struct gen_device_info *devinfo, VkFormat vk_format, return anv_get_format_plane(devinfo, vk_format, aspect, tiling).isl_format; } +bool anv_formats_ccs_e_compatible(const struct gen_device_info *devinfo, + VkImageCreateFlags create_flags, + VkFormat vk_format, + VkImageTiling vk_tiling, + const VkImageFormatListCreateInfoKHR *fmt_list); + static inline struct isl_swizzle anv_swizzle_for_render(struct isl_swizzle swizzle) {