From: Daniel Stone <dani...@collabora.com> 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 | 36 +++++++++++++++++++++++++++++-- src/intel/vulkan/anv_image.c | 9 ++++++-- src/intel/vulkan/anv_private.h | 3 +++ src/intel/vulkan/anv_wsi.c | 42 ++++++++++++++++++++++++++++++++++--- src/vulkan/wsi/wsi_common.h | 3 +++ src/vulkan/wsi/wsi_common_wayland.c | 3 +++ src/vulkan/wsi/wsi_common_x11.c | 3 +++ 7 files changed, 92 insertions(+), 7 deletions(-) diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c index dd820dc431..31448ae981 100644 --- a/src/amd/vulkan/radv_wsi.c +++ b/src/amd/vulkan/radv_wsi.c @@ -226,11 +226,42 @@ radv_wsi_image_create(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) { VkResult result = VK_SUCCESS; struct radeon_surf *surface; struct radv_image *image; + bool linear; + + /* If modifiers are provided, then try to use them. Unfortunately, + * as there are no modifiers actually defined for AMD, if we're + * provided with an explicit list of modifiers, then all we can do + * is try to use linear. + */ + if (num_tranches == 0) { + linear = different_gpu; + } else { + bool linear_found = false; + for (int i = 0; i < num_tranches; i++) { + for (int j = 0; j < num_modifiers[i]; j++) { + if (modifiers[i][j] == DRM_FORMAT_MOD_LINEAR) { + linear = true; + linear_found = true; + break; + } + } + } + + /* The right error is probably more like SURFACE_LOST, since + * we'll never be able to allocate for the surface with these + * attributes, but then we'd have to lose the surface. + */ + if (!linear_found) + return VK_ERROR_OUT_OF_DEVICE_MEMORY; + } result = radv_wsi_image_alloc(device_h, pCreateInfo, pAllocator, false, &wsi_image->image, @@ -238,7 +269,7 @@ radv_wsi_image_create(VkDevice device_h, if (result != VK_SUCCESS) return result; - if (different_gpu) { + if (linear) { result = radv_wsi_image_alloc(device_h, pCreateInfo, pAllocator, true, &wsi_image->linear_image, &wsi_image->linear_memory); @@ -260,7 +291,8 @@ radv_wsi_image_create(VkDevice device_h, goto fail; wsi_image->num_planes = 1; - wsi_image->drm_modifier = DRM_FORMAT_MOD_INVALID; + wsi_image->drm_modifier = + linear ? DRM_FORMAT_MOD_LINEAR : DRM_FORMAT_MOD_INVALID; wsi_image->sizes[0] = image->size; wsi_image->offsets[0] = image->offset; if (device->physical_device->rad_info.chip_class >= GFX9) diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index c8ebdce0b4..f266c7bc91 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -273,12 +273,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); @@ -317,7 +321,8 @@ make_surface(const struct anv_device *dev, .min_alignment = 0, .row_pitch = anv_info->stride, .usage = choose_isl_surf_usage(vk_info->flags, image->usage, aspect), - .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 abc278b40b..6cca45c479 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2625,6 +2625,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; + uint32_t stride; }; diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c index 61073a9788..8919a82d94 100644 --- a/src/intel/vulkan/anv_wsi.c +++ b/src/intel/vulkan/anv_wsi.c @@ -173,18 +173,54 @@ anv_wsi_image_create(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) { struct anv_device *device = anv_device_from_handle(device_h); VkImage image_h; struct anv_image *image; - isl_tiling_flags_t isl_tiling = ISL_TILING_X_BIT; + 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; + VkResult result; result = anv_image_create(anv_device_to_handle(device), &(struct anv_image_create_info) { - .isl_tiling_flags = isl_tiling, + .isl_tiling_flags = isl_tiling[0], + .isl_suboptimal_tiling_flags = isl_tiling[1], .stride = 0, .vk_info = &(VkImageCreateInfo) { @@ -238,7 +274,7 @@ anv_wsi_image_create(VkDevice device_h, assert(image->planes[0].offset == 0); struct anv_surface *surface = &image->planes[0].surface; - assert(isl_tiling & (1 << surface->isl.tiling)); + 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, diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index 8172f4b318..99836054ca 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -50,6 +50,9 @@ struct wsi_image_fns { 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, diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c index 8df30d993c..0ab73f0957 100644 --- a/src/vulkan/wsi/wsi_common_wayland.c +++ b/src/vulkan/wsi/wsi_common_wayland.c @@ -731,6 +731,9 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain, pCreateInfo, pAllocator, false, + NULL, + NULL, + 0, &image->base); if (result != VK_SUCCESS) return result; diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 784d275dc5..8bc6dc9125 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -962,6 +962,9 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, pCreateInfo, pAllocator, chain->base.needs_linear_copy, + NULL, + NULL, + 0, &image->base); if (result != VK_SUCCESS) return result; -- 2.13.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev