Incremental implementation of VK_EXT_image_drm_format_modifier. --- src/intel/vulkan/anv_image.c | 72 ++++++++++++++++++++++++++++++++++++++---- src/intel/vulkan/anv_private.h | 6 ++++ 2 files changed, 72 insertions(+), 6 deletions(-)
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index ba932ba47c3..8d434293124 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -27,6 +27,7 @@ #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> +#include <drm_fourcc.h> #include "anv_private.h" #include "util/debug.h" @@ -35,11 +36,12 @@ #include "vk_format_info.h" static isl_surf_usage_flags_t -choose_isl_surf_usage(VkImageCreateFlags vk_create_flags, - VkImageUsageFlags vk_usage, +choose_isl_surf_usage(const VkImageCreateInfo *vk_info, isl_surf_usage_flags_t isl_extra_usage, VkImageAspectFlagBits aspect) { + VkImageCreateFlags vk_create_flags = vk_info->flags; + VkImageUsageFlags vk_usage = vk_info->usage; isl_surf_usage_flags_t isl_usage = isl_extra_usage; if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT) @@ -87,11 +89,15 @@ choose_isl_surf_usage(VkImageCreateFlags vk_create_flags, isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT; } + if (vk_info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) + isl_usage |= ISL_SURF_USAGE_DISABLE_AUX_BIT; + return isl_usage; } static isl_tiling_flags_t -choose_isl_tiling_flags(const struct anv_image_create_info *anv_info) +choose_isl_tiling_flags(const struct anv_image_create_info *anv_info, + const struct isl_drm_modifier_info *isl_mod_info) { const VkImageCreateInfo *base_info = anv_info->vk_info; isl_tiling_flags_t flags = 0; @@ -100,11 +106,16 @@ choose_isl_tiling_flags(const struct anv_image_create_info *anv_info) default: unreachable("bad VkImageTiling"); case VK_IMAGE_TILING_OPTIMAL: + assert(isl_mod_info == NULL); flags = ISL_TILING_ANY_MASK; break; case VK_IMAGE_TILING_LINEAR: + assert(isl_mod_info == NULL); flags = ISL_TILING_LINEAR_BIT; break; + case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT: + flags = 1 << isl_mod_info->tiling; + break; } if (anv_info->isl_tiling_flags) @@ -298,8 +309,7 @@ make_surface(const struct anv_device *dev, struct anv_surface *anv_surf = &image->planes[plane].surface; const isl_surf_usage_flags_t usage = - choose_isl_surf_usage(vk_info->flags, image->usage, - anv_info->isl_extra_usage_flags, aspect); + choose_isl_surf_usage(vk_info, anv_info->isl_extra_usage_flags, aspect); /* If an image is created as BLOCK_TEXEL_VIEW_COMPATIBLE, then we need to * fall back to linear on Broadwell and earlier because we aren't @@ -492,6 +502,38 @@ make_surface(const struct anv_device *dev, return VK_SUCCESS; } +static uint32_t +score_drm_format_mod(uint64_t mod) +{ + switch (mod) { + default: unreachable("bad DRM format modifier"); + case I915_FORMAT_MOD_Y_TILED: return 3; + case I915_FORMAT_MOD_X_TILED: return 2; + case DRM_FORMAT_MOD_LINEAR: return 1; + } +} + +static const struct isl_drm_modifier_info * +choose_drm_format_mod(const VkImageDrmFormatModifierListCreateInfoEXT *mod_list) +{ + uint64_t best_mod = UINT64_MAX; + uint32_t best_score = 0; + + for (uint32_t i = 0; i < mod_list->drmFormatModifierCount; ++i) { + uint64_t mod = mod_list->pDrmFormatModifiers[i]; + uint32_t score = score_drm_format_mod(mod); + + if (score > best_score) { + best_mod = mod; + best_score = score; + } + } + + assert(best_score != 0); + + return isl_drm_modifier_get_info(best_mod); +} + VkResult anv_image_create(VkDevice _device, const struct anv_image_create_info *create_info, @@ -500,11 +542,26 @@ anv_image_create(VkDevice _device, { ANV_FROM_HANDLE(anv_device, device, _device); const VkImageCreateInfo *pCreateInfo = create_info->vk_info; + const VkImageDrmFormatModifierListCreateInfoEXT *vk_mod_list = NULL; + const struct isl_drm_modifier_info *isl_mod_info = NULL; struct anv_image *image = NULL; VkResult r; assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO); + /* Extract input structs */ + vk_foreach_struct_const(s, pCreateInfo->pNext) { + switch (s->sType) { + case VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT: + vk_mod_list = (const VkImageDrmFormatModifierListCreateInfoEXT *) s; + isl_mod_info = choose_drm_format_mod(vk_mod_list); + break; + default: + anv_debug_ignored_stype(s->sType); + break; + } + } + anv_assert(pCreateInfo->mipLevels > 0); anv_assert(pCreateInfo->arrayLayers > 0); anv_assert(pCreateInfo->samples > 0); @@ -529,11 +586,14 @@ anv_image_create(VkDevice _device, image->tiling = pCreateInfo->tiling; image->disjoint = pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT_KHR; + if (isl_mod_info) + image->drm_format_mod = isl_mod_info->modifier; + const struct anv_format *format = anv_get_format(image->vk_format); assert(format != NULL); const isl_tiling_flags_t isl_tiling_flags = - choose_isl_tiling_flags(create_info); + choose_isl_tiling_flags(create_info, isl_mod_info); image->n_planes = format->n_planes; diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index e17a52a4a70..2312845570b 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2337,6 +2337,12 @@ struct anv_image { VkImageUsageFlags usage; /**< Superset of VkImageCreateInfo::usage. */ VkImageTiling tiling; /** VkImageCreateInfo::tiling */ + /** + * Must be DRM_FORMAT_MOD_INVALID unless tiling is + * VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT. + */ + uint64_t drm_format_mod; + VkDeviceSize size; uint32_t alignment; -- 2.13.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev