Allow the winsys to provide a set of acceptable modifiers to the driver when creating WSI images.
Signed-off-by: Daniel Stone <dani...@collabora.com> --- src/amd/vulkan/radv_wsi.c | 3 ++ src/intel/vulkan/anv_image.c | 9 +++- src/intel/vulkan/anv_private.h | 3 ++ src/intel/vulkan/anv_wsi.c | 101 ++++++++++++++++++++++++++++++++++++----- src/vulkan/wsi/wsi_common.h | 11 +++++ 5 files changed, 114 insertions(+), 13 deletions(-) diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c index c4c6ff9736..a1881eaa35 100644 --- a/src/amd/vulkan/radv_wsi.c +++ b/src/amd/vulkan/radv_wsi.c @@ -223,6 +223,8 @@ radv_wsi_image_create(VkDevice device_h, wsi_image->image = image_h; wsi_image->memory = memory_h; + wsi_image->linear_image = VK_NULL_HANDLE; + wsi_image->linear_memory = VK_NULL_HANDLE; wsi_image->num_planes = 1; wsi_image->drm_modifier = DRM_FORMAT_MOD_INVALID; wsi_image->sizes[0] = image->size; @@ -256,6 +258,7 @@ radv_wsi_image_free(VkDevice device, static const struct wsi_image_fns radv_wsi_image_fns = { .create_wsi_image = radv_wsi_image_create, + .create_wsi_image_with_modifiers = NULL, .free_wsi_image = radv_wsi_image_free, }; diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index cd96bfd0d6..262f6805dc 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -274,12 +274,16 @@ make_surface(const struct anv_device *dev, /* Translate the Vulkan tiling to an equivalent ISL tiling, then filter the * result with an optionally provided ISL tiling argument. */ - isl_tiling_flags_t tiling_flags = + isl_tiling_flags_t mask = (vk_info->tiling == VK_IMAGE_TILING_LINEAR) ? ISL_TILING_LINEAR_BIT : ISL_TILING_ANY_MASK; + isl_tiling_flags_t tiling_flags = mask; + isl_tiling_flags_t suboptimal_tiling_flags = 0; if (anv_info->isl_tiling_flags) tiling_flags &= anv_info->isl_tiling_flags; + if (anv_info->isl_suboptimal_tiling_flags) + suboptimal_tiling_flags = anv_info->isl_suboptimal_tiling_flags & mask; assert(tiling_flags); @@ -322,7 +326,8 @@ make_surface(const struct anv_device *dev, .min_alignment = 0, .row_pitch = anv_info->stride, .usage = usage, - .tiling_flags = tiling_flags); + .tiling_flags = tiling_flags, + .suboptimal_tiling_flags = suboptimal_tiling_flags); /* isl_surf_init() will fail only if provided invalid input. Invalid input * is illegal in Vulkan. diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 8de5103453..5e5010fde9 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2630,6 +2630,9 @@ struct anv_image_create_info { /** An opt-in bitmask which filters an ISL-mapping of the Vulkan tiling. */ isl_tiling_flags_t isl_tiling_flags; + /** Set of possible but suboptimal tiling flags. */ + isl_tiling_flags_t isl_suboptimal_tiling_flags; + /** These flags will be added to any derived from VkImageCreateInfo. */ isl_surf_usage_flags_t isl_extra_usage_flags; diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c index 740bbff9d3..f41db86f12 100644 --- a/src/intel/vulkan/anv_wsi.c +++ b/src/intel/vulkan/anv_wsi.c @@ -169,12 +169,13 @@ VkResult anv_GetPhysicalDeviceSurfacePresentModesKHR( static VkResult -anv_wsi_image_create(VkDevice device_h, - const VkSwapchainCreateInfoKHR *pCreateInfo, - const VkAllocationCallbacks* pAllocator, - bool should_export, - bool different_gpu, - struct wsi_image_base *wsi_image) +anv_wsi_image_alloc(VkDevice device_h, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks* pAllocator, + bool should_export, + isl_tiling_flags_t *isl_tiling, + VkImageTiling vk_tiling, + struct wsi_image_base *wsi_image) { struct anv_device *device = anv_device_from_handle(device_h); VkImage image_h; @@ -183,7 +184,8 @@ anv_wsi_image_create(VkDevice device_h, VkResult result; result = anv_image_create(anv_device_to_handle(device), &(struct anv_image_create_info) { - .isl_tiling_flags = ISL_TILING_X_BIT, + .isl_tiling_flags = isl_tiling[0], + .isl_suboptimal_tiling_flags = isl_tiling[1], .stride = 0, .vk_info = &(VkImageCreateInfo) { @@ -198,8 +200,7 @@ anv_wsi_image_create(VkDevice device_h, .mipLevels = 1, .arrayLayers = 1, .samples = 1, - /* FIXME: Need a way to use X tiling to allow scanout */ - .tiling = VK_IMAGE_TILING_OPTIMAL, + .tiling = vk_tiling, .usage = (pCreateInfo->imageUsage | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT), .flags = 0, @@ -238,10 +239,11 @@ anv_wsi_image_create(VkDevice device_h, assert(image->planes[0].offset == 0); struct anv_surface *surface = &image->planes[0].surface; - assert(surface->isl.tiling == ISL_TILING_X); + assert((isl_tiling[0] | isl_tiling[1]) & (1 << surface->isl.tiling)); int ret = anv_gem_set_tiling(device, memory->bo->gem_handle, - surface->isl.row_pitch, I915_TILING_X); + surface->isl.row_pitch, + isl_tiling_to_i915_tiling(surface->isl.tiling)); if (ret) { /* FINISHME: Choose a better error. */ result = vk_errorf(device->instance, device, @@ -266,6 +268,8 @@ anv_wsi_image_create(VkDevice device_h, wsi_image->image = image_h; wsi_image->memory = memory_h; + wsi_image->linear_image = VK_NULL_HANDLE; + wsi_image->linear_memory = VK_NULL_HANDLE; /* We don't yet allow sharing of aux planes with the winsys. Doing so * would require a separate external_aux_usage member in the anv_image, @@ -289,6 +293,80 @@ fail_create_image: return result; } +static VkResult +anv_wsi_image_create(VkDevice device_h, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks* pAllocator, + bool should_export, + bool different_gpu, + struct wsi_image_base *wsi_image) +{ + isl_tiling_flags_t isl_tiling[2] = {ISL_TILING_X_BIT, 0}; + VkImageTiling vk_tiling = VK_IMAGE_TILING_OPTIMAL; + + return anv_wsi_image_alloc(device_h, + pCreateInfo, + pAllocator, + should_export, + isl_tiling, + vk_tiling, + wsi_image); +} + +static VkResult +anv_wsi_image_create_with_modifiers(VkDevice device_h, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks* pAllocator, + bool different_gpu, + uint64_t **modifiers, + int *num_modifiers, + int num_tranches, + struct wsi_image_base *wsi_image) +{ + isl_tiling_flags_t isl_tiling[2] = {0,}; + VkImageTiling vk_tiling = VK_IMAGE_TILING_OPTIMAL; + + assert(num_tranches >= 0 && num_tranches <= 2); + + /* If we haven't been provided any modifiers, fall back to our previous + * default of X-tiling, which the other side can infer through the BO + * get_tiling ioctl. */ + if (num_tranches == 0) { + isl_tiling[0] = ISL_TILING_X_BIT; + } else { + for (int i = 0; i < num_tranches; i++) { + for (int j = 0; j < num_modifiers[i]; j++) { + const struct isl_drm_modifier_info *info = + isl_drm_modifier_get_info(modifiers[i][j]); + if (!info || info->aux_usage != ISL_AUX_USAGE_NONE) + continue; + isl_tiling[i] |= (1 << info->tiling); + } + } + } + + /* This isn't strictly correct; really we want something more like + * SURFACE_LOST, because we'll never be able to render to it in these + * conditions. + */ + if (isl_tiling[0] == 0) + return VK_ERROR_OUT_OF_DEVICE_MEMORY; + + if (isl_tiling[0] & ISL_TILING_NON_LINEAR_MASK || + isl_tiling[1] & ISL_TILING_NON_LINEAR_MASK) + vk_tiling = VK_IMAGE_TILING_OPTIMAL; + else + vk_tiling = VK_IMAGE_TILING_LINEAR; + + return anv_wsi_image_alloc(device_h, + pCreateInfo, + pAllocator, + true, + isl_tiling, + vk_tiling, + wsi_image); +} + static void anv_wsi_image_free(VkDevice device, const VkAllocationCallbacks* pAllocator, @@ -301,6 +379,7 @@ anv_wsi_image_free(VkDevice device, static const struct wsi_image_fns anv_wsi_image_fns = { .create_wsi_image = anv_wsi_image_create, + .create_wsi_image_with_modifiers = anv_wsi_image_create_with_modifiers, .free_wsi_image = anv_wsi_image_free, }; diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index d808a4cfdc..0741e59875 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -33,6 +33,8 @@ struct wsi_image_base { VkImage image; VkDeviceMemory memory; + VkImage linear_image; + VkDeviceMemory linear_memory; uint64_t drm_modifier; int num_planes; @@ -50,6 +52,15 @@ struct wsi_image_fns { bool should_export, bool different_gpu, struct wsi_image_base *image_p); + + VkResult (*create_wsi_image_with_modifiers)(VkDevice device_h, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + bool different_gpu, + uint64_t **modifiers, + int *num_modifiers, + int num_tranches, + struct wsi_image_base *image_p); void (*free_wsi_image)(VkDevice device, const VkAllocationCallbacks *pAllocator, struct wsi_image_base *image); -- 2.13.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev