[Mesa-dev] [PATCH 12/14] vulkan/wsi: Add modifiers to wsi_image_create

Daniel Stone daniels at collabora.com
Fri Jul 21 13:42:15 UTC 2017


Allow the winsys to provide a set of acceptable modifiers to the driver
when creating WSI images.

Signed-off-by: Daniel Stone <daniels at collabora.com>
---
 src/amd/vulkan/radv_wsi.c           | 28 ++++++++++++++++++++++++++++
 src/intel/vulkan/anv_wsi.c          | 31 ++++++++++++++++++++++++++++++-
 src/vulkan/wsi/wsi_common.h         |  2 ++
 src/vulkan/wsi/wsi_common_wayland.c |  2 ++
 src/vulkan/wsi/wsi_common_x11.c     |  2 ++
 5 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c
index a131265d3a..a45a5a3b9b 100644
--- a/src/amd/vulkan/radv_wsi.c
+++ b/src/amd/vulkan/radv_wsi.c
@@ -229,11 +229,39 @@ radv_wsi_image_create(VkDevice device_h,
 		      const VkSwapchainCreateInfoKHR *pCreateInfo,
 		      const VkAllocationCallbacks* pAllocator,
 		      bool different_gpu,
+		      uint64_t *modifiers,
+		      int num_modifiers,
 		      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 (!modifiers) {
+		linear = different_gpu;
+	} else {
+		bool linear_found = false;
+		for (int i = 0; i < num_modifiers; i++) {
+			if (modifiers[i] == 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,
diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c
index 81818b4590..f9c3b8a40b 100644
--- a/src/intel/vulkan/anv_wsi.c
+++ b/src/intel/vulkan/anv_wsi.c
@@ -173,14 +173,43 @@ anv_wsi_image_create(VkDevice device_h,
                      const VkSwapchainCreateInfoKHR *pCreateInfo,
                      const VkAllocationCallbacks* pAllocator,
                      bool different_gpu,
+                     uint64_t *modifiers,
+                     int num_modifiers,
                      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 = 0;
    VkImageTiling vk_tiling = VK_IMAGE_TILING_OPTIMAL;
 
+   /* 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 (!modifiers) {
+      isl_tiling = ISL_TILING_X_BIT;
+   } else {
+      for (int i = 0; i < num_modifiers; i++) {
+         struct isl_drm_modifier_info *info =
+            isl_drm_modifier_get_info(modifiers[i]);
+         if (!info || info->aux_usage != ISL_AUX_USAGE_NONE)
+            continue;
+         isl_tiling |= (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)
+      return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+
+   if (isl_tiling & 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) {
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
index 006ba4ed3b..add5b35c04 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -50,6 +50,8 @@ struct wsi_image_fns {
                                 const VkSwapchainCreateInfoKHR *pCreateInfo,
                                 const VkAllocationCallbacks *pAllocator,
                                 bool different_gpu,
+                                uint64_t *modifiers,
+                                int num_modifiers,
                                 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 462fc2a5a9..04b8c4ba73 100644
--- a/src/vulkan/wsi/wsi_common_wayland.c
+++ b/src/vulkan/wsi/wsi_common_wayland.c
@@ -698,6 +698,8 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain,
                                                     pCreateInfo,
                                                     pAllocator,
                                                     false,
+                                                    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 07823171cc..db9d709992 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -962,6 +962,8 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
                                                     pCreateInfo,
                                                     pAllocator,
                                                     chain->base.different_gpu,
+                                                    NULL,
+                                                    0,
                                                     &image->base);
    if (result != VK_SUCCESS)
       return result;
-- 
2.13.2



More information about the mesa-dev mailing list