From: Daniel Stone <dani...@collabora.com> Allow the WSI to provide a set of modifiers to be used along with the format.
For now, no winsys provides any modifier support. Add a fallback to the previous default (X-tiling) inside ANV. RADV remains somewhat broken in the presence of a winsys which will suggest modifiers, but with a Vulkan driver which is not modifier-aware. Currently none of the AMD tiling modes have modifier tokens defined, and forcing to linear would be an unacceptable performance penalty. For now, just stick our head in the sand. --- src/amd/vulkan/radv_wsi.c | 9 ++++++++- src/intel/vulkan/anv_wsi.c | 33 +++++++++++++++++++++++++++------ src/vulkan/wsi/wsi_common.h | 5 ++++- src/vulkan/wsi/wsi_common_wayland.c | 6 +++++- src/vulkan/wsi/wsi_common_x11.c | 15 ++++++++++++--- 5 files changed, 56 insertions(+), 12 deletions(-) diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c index aa44b7d78a..2f62fda582 100644 --- a/src/amd/vulkan/radv_wsi.c +++ b/src/amd/vulkan/radv_wsi.c @@ -141,13 +141,15 @@ static VkResult radv_wsi_image_create(VkDevice device_h, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks* pAllocator, + uint64_t *modifiers, + int num_modifiers, bool needs_linear_copy, bool linear, VkImage *image_p, VkDeviceMemory *memory_p, uint32_t *size, uint32_t *offset, - uint32_t *row_pitch, int *fd_p) + uint32_t *row_pitch, int *fd_p, uint64_t *modifier) { VkResult result = VK_SUCCESS; struct radeon_surf *surface; @@ -156,6 +158,10 @@ radv_wsi_image_create(VkDevice device_h, int fd; RADV_FROM_HANDLE(radv_device, device, device_h); + /* FIXME: Square the circle. */ + assert(!modifiers || + (num_modifiers == 1 && modifiers[0] == DRM_FORMAT_MOD_LINEAR)); + result = radv_image_create(device_h, &(struct radv_image_create_info) { .vk_info = @@ -224,6 +230,7 @@ radv_wsi_image_create(VkDevice device_h, *memory_p = memory_h; *size = image->size; *offset = image->offset; + *modifier = DRM_FORMAT_MOD_INVALID; if (device->physical_device->rad_info.chip_class >= GFX9) *row_pitch = surface->u.gfx9.surf_pitch * surface->bpe; diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c index 8f01f62e8a..88e2d7abc5 100644 --- a/src/intel/vulkan/anv_wsi.c +++ b/src/intel/vulkan/anv_wsi.c @@ -172,17 +172,38 @@ static VkResult anv_wsi_image_create(VkDevice device_h, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks* pAllocator, + uint64_t *modifiers, + int num_modifiers, bool different_gpu, bool linear, VkImage *image_p, VkDeviceMemory *memory_p, uint32_t *size, uint32_t *offset, - uint32_t *row_pitch, int *fd_p) + uint32_t *row_pitch, int *fd_p, uint64_t *modifier) { struct anv_device *device = anv_device_from_handle(device_h); VkImage image_h; struct anv_image *image; + VkImageTiling vk_tiling = VK_IMAGE_TILING_LINEAR; + int i; + + uint64_t modifiers_fallback[] = { I915_FORMAT_MOD_X_TILED }; + if (num_modifiers == 0) { + modifiers = modifiers_fallback; + num_modifiers = ARRAY_SIZE(modifiers_fallback); + } + + /* XXX: Retconning the VkImageTiling from modifiers is a bit hairy, because + * the actual ISL tiling/aux selection happens further down, which may + * filter the modes out and return linear even though we suggest a + * tiling mode. */ + for (i = 0; i < num_modifiers; i++) { + enum isl_tiling t; + enum isl_aux_usage a; + if (isl_tiling_from_drm_format_mod(modifiers[i], &t, &a)) + vk_tiling = VK_IMAGE_TILING_OPTIMAL; + } VkResult result; result = anv_CreateImage(anv_device_to_handle(device), @@ -199,7 +220,7 @@ anv_wsi_image_create(VkDevice device_h, .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, @@ -210,10 +231,8 @@ anv_wsi_image_create(VkDevice device_h, .pNext = &(VkExportImageDmaBufInfoMESAX) { .sType = VK_STRUCTURE_TYPE_EXPORT_IMAGE_DMA_BUF_INFO_MESAX, - .drmFormatModifierCount = 1, - .pDrmFormatModifiers = (uint64_t[]) { - I915_FORMAT_MOD_X_TILED, - }, + .drmFormatModifierCount = ARRAY_SIZE(modifiers), + .pDrmFormatModifiers = modifiers, }}}, NULL, &image_h); @@ -273,6 +292,8 @@ anv_wsi_image_create(VkDevice device_h, *fd_p = fd; *size = image->size; *offset = image->offset; + *modifier = isl_tiling_to_drm_format_mod(image->color_surface.isl.tiling, + image->aux_usage); return VK_SUCCESS; fail_alloc_memory: anv_FreeMemory(device_h, memory_h, pAllocator); diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index 8166b7dd34..eb1b5a1063 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -35,6 +35,8 @@ struct wsi_image_fns { VkResult (*create_wsi_image)(VkDevice device_h, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, + uint64_t *modifiers, + int num_modifiers, bool needs_linear_copy, bool linear, VkImage *image_p, @@ -42,7 +44,8 @@ struct wsi_image_fns { uint32_t *size_p, uint32_t *offset_p, uint32_t *row_pitch_p, - int *fd_p); + int *fd_p, + uint64_t *modifier_p); void (*free_wsi_image)(VkDevice device, const VkAllocationCallbacks *pAllocator, VkImage image_h, diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c index dd283a1211..80300dc81a 100644 --- a/src/vulkan/wsi/wsi_common_wayland.c +++ b/src/vulkan/wsi/wsi_common_wayland.c @@ -698,9 +698,12 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain, uint32_t size; uint32_t row_pitch; uint32_t offset; + uint64_t modifier; result = chain->base.image_fns->create_wsi_image(vk_device, pCreateInfo, pAllocator, + NULL, + 0, false, false, &image->image, @@ -708,7 +711,8 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain, &size, &offset, &row_pitch, - &fd); + &fd, + &modifier); 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 ecdaf91434..f12583db13 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -955,6 +955,8 @@ static VkResult x11_image_init(VkDevice device_h, struct x11_swapchain *chain, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks* pAllocator, + uint64_t *modifiers, + int num_modifiers, struct x11_image *image) { xcb_void_cookie_t cookie; @@ -964,10 +966,13 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, uint32_t bpp = 32; int fd; uint32_t size; + uint64_t modifier; result = chain->base.image_fns->create_wsi_image(device_h, pCreateInfo, pAllocator, + modifiers, + num_modifiers, chain->base.needs_linear_copy, false, &image->image, @@ -975,7 +980,8 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, &size, &offset, &row_pitch, - &fd); + &fd, + &modifier); if (result != VK_SUCCESS) return result; @@ -983,6 +989,8 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, result = chain->base.image_fns->create_wsi_image(device_h, pCreateInfo, pAllocator, + modifiers, + num_modifiers, chain->base.needs_linear_copy, true, &image->linear_image, @@ -990,7 +998,8 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, &size, &offset, &row_pitch, - &fd); + &fd, + &modifier); if (result != VK_SUCCESS) { chain->base.image_fns->free_wsi_image(device_h, pAllocator, image->image, image->memory); @@ -1186,7 +1195,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, uint32_t image = 0; for (; image < chain->base.image_count; image++) { result = x11_image_init(device, chain, pCreateInfo, pAllocator, - &chain->images[image]); + NULL, 0, &chain->images[image]); if (result != VK_SUCCESS) goto fail_init_images; } -- 2.13.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev