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

Daniel Stone daniels at collabora.com
Thu Jun 8 18:44:19 UTC 2017


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.

Signed-off-by: Daniel Stone <daniels at collabora.com>
---
 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 cdb04ca962..72d1cf06b4 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;
@@ -155,6 +157,10 @@ radv_wsi_image_create(VkDevice device_h,
 	struct radv_image *image;
 	int fd;
 
+	/* 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 =
@@ -225,6 +231,7 @@ radv_wsi_image_create(VkDevice device_h,
 	*size = image->size;
 	*offset = image->offset;
 	*row_pitch = surface->u.legacy.level[0].nblk_x * surface->bpe;
+	*modifier = DRM_FORMAT_MOD_INVALID;
 	return VK_SUCCESS;
  fail_alloc_memory:
 	radv_FreeMemory(device_h, memory_h, pAllocator);
diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c
index bd60a4474a..53ad7d153e 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