[Mesa-dev] [RFC v2 22/23] RFC: vulkan/wsi: Add modifiers to WSI image creation

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Thu Aug 31 04:24:36 UTC 2017


From: Daniel Stone <daniels at 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



More information about the mesa-dev mailing list