<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Feb 21, 2018 at 6:05 AM, Daniel Stone <span dir="ltr"><<a href="mailto:daniels@collabora.com" target="_blank">daniels@collabora.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Adds support for multiple planes and buffer modifiers.<br>
<br>
v4: Rename "has_dri3_v1_1" to "has_dri3_modifiers"<br>
Signed-off-by: Daniel Stone <<a href="mailto:daniels@collabora.com">daniels@collabora.com</a>><br>
---<br>
 src/vulkan/wsi/wsi_common_x11.<wbr>c | 185 ++++++++++++++++++++++++++++++<wbr>++++++----<br>
 1 file changed, 168 insertions(+), 17 deletions(-)<br>
<br>
diff --git a/src/vulkan/wsi/wsi_common_<wbr>x11.c b/src/vulkan/wsi/wsi_common_<wbr>x11.c<br>
index dadada82ef1..213a597a430 100644<br>
--- a/src/vulkan/wsi/wsi_common_<wbr>x11.c<br>
+++ b/src/vulkan/wsi/wsi_common_<wbr>x11.c<br>
@@ -36,6 +36,7 @@<br>
 #include <fcntl.h><br>
 #include <poll.h><br>
 #include <xf86drm.h><br>
+#include <drm_fourcc.h><br>
 #include "util/hash_table.h"<br>
<br>
 #include "vk_util.h"<br>
@@ -50,6 +51,7 @@<br>
<br>
 struct wsi_x11_connection {<br>
    bool has_dri3;<br>
+   bool has_dri3_modifiers;<br>
    bool has_present;<br>
    bool is_proprietary_x11;<br>
 };<br>
@@ -164,6 +166,19 @@ wsi_x11_connection_create(<wbr>const VkAllocationCallbacks *alloc,<br>
    }<br>
<br>
    wsi_conn->has_dri3 = dri3_reply->present != 0;<br>
+#if XCB_DRI3_MAJOR_VERSION > 1 || XCB_DRI3_MINOR_VERSION >= 1<br>
+   if (wsi_conn->has_dri3) {<br>
+      xcb_dri3_query_version_cookie_<wbr>t ver_cookie;<br>
+      xcb_dri3_query_version_reply_t *ver_reply;<br>
+<br>
+      ver_cookie = xcb_dri3_query_version(conn, 1, 1);<br>
+      ver_reply = xcb_dri3_query_version_reply(<wbr>conn, ver_cookie, NULL);<br>
+      wsi_conn->has_dri3_modifiers =<br>
+         (ver_reply->major_version > 1 || ver_reply->minor_version >= 1);<br>
+      free(ver_reply);<br>
+   }<br>
+#endif<br>
+<br>
    wsi_conn->has_present = pres_reply->present != 0;<br>
    wsi_conn->is_proprietary_x11 = false;<br>
    if (amd_reply && amd_reply->present)<br>
@@ -620,6 +635,8 @@ struct x11_image {<br>
 struct x11_swapchain {<br>
    struct wsi_swapchain                        base;<br>
<br>
+   bool                                         has_dri3_modifiers;<br>
+<br>
    xcb_connection_t *                           conn;<br>
    xcb_window_t                                 window;<br>
    xcb_gc_t                                     gc;<br>
@@ -974,7 +991,9 @@ static VkResult<br>
 x11_image_init(VkDevice device_h, struct x11_swapchain *chain,<br>
                const VkSwapchainCreateInfoKHR *pCreateInfo,<br>
                const VkAllocationCallbacks* pAllocator,<br>
-               struct x11_image *image)<br>
+               const uint64_t *const *modifiers,<br>
+               const uint32_t *num_modifiers,<br>
+               int num_tranches, struct x11_image *image)<br>
 {<br>
    xcb_void_cookie_t cookie;<br>
    VkResult result;<br>
@@ -984,28 +1003,60 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,<br>
       result = wsi_create_prime_image(&chain-<wbr>>base, pCreateInfo, &image->base);<br>
    } else {<br>
       result = wsi_create_native_image(&<wbr>chain->base, pCreateInfo,<br>
-                                       0, NULL, NULL, &image->base);<br>
+                                       num_tranches, num_modifiers, modifiers,<br>
+                                       &image->base);<br>
    }<br>
    if (result < 0)<br>
       return result;<br>
<br>
    image->pixmap = xcb_generate_id(chain->conn);<br>
<br>
-   /* Without passing modifiers, we can't have multi-plane RGB images. */<br>
-   assert(image->base.num_planes == 1);<br>
-<br>
-   cookie =<br>
-      xcb_dri3_pixmap_from_buffer_<wbr>checked(chain->conn,<br>
-                                          image->pixmap,<br>
-                                          chain->window,<br>
-                                          image->base.sizes[0],<br>
-                                          pCreateInfo->imageExtent.<wbr>width,<br>
-                                          pCreateInfo->imageExtent.<wbr>height,<br>
-                                          image->base.row_pitches[0],<br>
-                                          chain->depth, bpp,<br>
-                                          image->base.fds[0]);<br>
+#if XCB_DRI3_MAJOR_VERSION > 1 || XCB_DRI3_MINOR_VERSION >= 1<br>
+   if (image->base.drm_modifier != DRM_FORMAT_MOD_INVALID) {<br>
+      /* If the image has a modifier, we must have DRI3 v1.1. */<br>
+      assert(chain->has_dri3_<wbr>modifiers);<br>
+<br>
+      cookie =<br>
+         xcb_dri3_pixmap_from_buffers_<wbr>checked(chain->conn,<br>
+                                              image->pixmap,<br>
+                                              chain->window,<br>
+                                              image->base.num_planes,<br>
+                                              pCreateInfo->imageExtent.<wbr>width,<br>
+                                              pCreateInfo->imageExtent.<wbr>height,<br>
+                                              image->base.row_pitches[0],<br>
+                                              image->base.offsets[0],<br>
+                                              image->base.row_pitches[1],<br>
+                                              image->base.offsets[1],<br>
+                                              image->base.row_pitches[2],<br>
+                                              image->base.offsets[2],<br>
+                                              image->base.row_pitches[3],<br>
+                                              image->base.offsets[3],<br>
+                                              chain->depth, bpp,<br>
+                                              image->base.drm_modifier,<br>
+                                              image->base.fds);<br>
+   } else<br>
+#endif<br>
+   {<br>
+      /* Without passing modifiers, we can't have multi-plane RGB images. */<br>
+      assert(image->base.num_planes == 1);<br>
+<br>
+      cookie =<br>
+         xcb_dri3_pixmap_from_buffer_<wbr>checked(chain->conn,<br>
+                                             image->pixmap,<br>
+                                             chain->window,<br>
+                                             image->base.sizes[0],<br>
+                                             pCreateInfo->imageExtent.<wbr>width,<br>
+                                             pCreateInfo->imageExtent.<wbr>height,<br>
+                                             image->base.row_pitches[0],<br>
+                                             chain->depth, bpp,<br>
+                                             image->base.fds[0]);<br>
+   }<br>
+<br>
    xcb_discard_reply(chain->conn, cookie.sequence);<br>
-   image->base.fds[0] = -1; /* XCB has now taken ownership of the FD */<br>
+<br>
+   /* XCB has now taken ownership of the FDs. */<br>
+   for (int i = 0; i < image->base.num_planes; i++)<br>
+      image->base.fds[i] = -1;<br>
<br>
    int fence_fd = xshmfence_alloc_shm();<br>
    if (fence_fd < 0)<br>
@@ -1056,6 +1107,84 @@ x11_image_finish(struct x11_swapchain *chain,<br>
    wsi_destroy_image(&chain-><wbr>base, &image->base);<br>
 }<br>
<br>
+static void<br>
+wsi_x11_get_dri3_modifiers(<wbr>struct wsi_x11_connection *wsi_conn,<br>
+                           xcb_connection_t *conn, xcb_window_t window,<br>
+                           uint8_t depth, uint8_t bpp,<br>
+                           VkCompositeAlphaFlagsKHR vk_alpha,<br>
+                           uint64_t **modifiers_in, uint32_t *num_modifiers_in,<br>
+                           uint32_t *num_tranches_in,<br>
+                           const VkAllocationCallbacks *pAllocator)<br>
+{<br>
+#if XCB_DRI3_MAJOR_VERSION > 1 || XCB_DRI3_MINOR_VERSION >= 1<br>
+   if (!wsi_conn->has_dri3_<wbr>modifiers)<br>
+      goto out;<br>
+<br>
+   xcb_generic_error_t *error = NULL;<br>
+   xcb_dri3_get_supported_<wbr>modifiers_cookie_t mod_cookie =<br>
+      xcb_dri3_get_supported_<wbr>modifiers(conn, window, depth, bpp);<br>
+   xcb_dri3_get_supported_<wbr>modifiers_reply_t *mod_reply =<br>
+      xcb_dri3_get_supported_<wbr>modifiers_reply(conn, mod_cookie, &error);<br>
+   free(error);<br>
+<br>
+   if (!mod_reply || (mod_reply->num_drawable_<wbr>modifiers == 0 &&<br>
+                      mod_reply->num_screen_<wbr>modifiers == 0)) {<br>
+      free(mod_reply);<br>
+      goto out;<br>
+   }<br>
+<br>
+   uint32_t n = 0;<br>
+   uint32_t counts[2];<br>
+   uint64_t *modifiers[2];<br>
+<br>
+   if (mod_reply->num_drawable_<wbr>modifiers) {<br>
+      counts[n] = mod_reply->num_drawable_<wbr>modifiers;<br>
+      modifiers[n] = vk_alloc(pAllocator,<br>
+                              counts[n] * sizeof(uint64_t),<br>
+                              8, VK_SYSTEM_ALLOCATION_SCOPE_<wbr>OBJECT);<br>
+      if (!modifiers[n]) {<br>
+         free(mod_reply);<br>
+         goto out;<br>
+      }<br>
+<br>
+      memcpy(modifiers[n],<br>
+             xcb_dri3_get_supported_<wbr>modifiers_drawable_modifiers(<wbr>mod_reply),<br></blockquote><div><br></div><div>Did we ever get a solid answer on whether or not this memcpy is really needed?  I doubt it is.<br><br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+             counts[n] * sizeof(uint64_t));<br>
+      n++;<br>
+   }<br>
+<br>
+   if (mod_reply->num_screen_<wbr>modifiers) {<br>
+      counts[n] = mod_reply->num_screen_<wbr>modifiers;<br>
+      modifiers[n] = vk_alloc(pAllocator,<br>
+                              counts[n] * sizeof(uint64_t),<br>
+                              8, VK_SYSTEM_ALLOCATION_SCOPE_<wbr>OBJECT);<br>
+      if (!modifiers[n]) {<br>
+        if (n > 0)<br>
+            vk_free(pAllocator, modifiers[0]);<br>
+         free(mod_reply);<br>
+         goto out;<br>
+      }<br>
+<br>
+      memcpy(modifiers[n],<br>
+             xcb_dri3_get_supported_<wbr>modifiers_screen_modifiers(<wbr>mod_reply),<br>
+             counts[n] * sizeof(uint64_t));<br>
+      n++;<br>
+   }<br>
+<br>
+   for (int i = 0; i < n; i++) {<br>
+      modifiers_in[i] = modifiers[i];<br>
+      num_modifiers_in[i] = counts[i];<br>
+   }<br>
+   *num_tranches_in = n;<br>
+<br>
+   free(mod_reply);<br>
+   return;<br>
+#endif<br>
+<br>
+out:<br>
+   *num_tranches_in = 0;<br>
+}<br>
+<br>
 static VkResult<br>
 x11_swapchain_destroy(struct wsi_swapchain *anv_chain,<br>
                       const VkAllocationCallbacks *pAllocator)<br>
@@ -1105,8 +1234,13 @@ x11_surface_create_swapchain(<wbr>VkIcdSurfaceBase *icd_surface,<br>
<br>
    const unsigned num_images = pCreateInfo->minImageCount;<br>
<br>
-   /* Check for whether or not we have a window up-front */<br>
    xcb_connection_t *conn = x11_surface_get_connection(<wbr>icd_surface);<br>
+   struct wsi_x11_connection *wsi_conn =<br>
+      wsi_x11_get_connection(wsi_<wbr>device, pAllocator, conn);<br>
+   if (!wsi_conn)<br>
+      return VK_ERROR_OUT_OF_HOST_MEMORY;<br>
+<br>
+   /* Check for whether or not we have a window up-front */<br>
    xcb_window_t window = x11_surface_get_window(icd_<wbr>surface);<br>
    xcb_get_geometry_reply_t *geometry =<br>
       xcb_get_geometry_reply(conn, xcb_get_geometry(conn, window), NULL);<br>
@@ -1140,6 +1274,7 @@ x11_surface_create_swapchain(<wbr>VkIcdSurfaceBase *icd_surface,<br>
    chain->last_present_msc = 0;<br>
    chain->threaded = false;<br>
    chain->status = VK_SUCCESS;<br>
+   chain->has_dri3_modifiers = wsi_conn->has_dri3_modifiers;<br>
<br>
    if (!wsi_x11_check_dri3_<wbr>compatible(conn, local_fd))<br>
        chain->base.use_prime_blit = true;<br>
@@ -1171,9 +1306,20 @@ x11_surface_create_swapchain(<wbr>VkIcdSurfaceBase *icd_surface,<br>
                           (uint32_t []) { 0 });<br>
    xcb_discard_reply(chain->conn, cookie.sequence);<br>
<br>
+   uint64_t *modifiers[2] = {NULL, NULL};<br>
+   uint32_t num_modifiers[2] = {0, 0};<br>
+   uint32_t num_tranches = 0;<br>
+   if (wsi_device->supports_<wbr>modifiers)<br>
+      wsi_x11_get_dri3_modifiers(<wbr>wsi_conn, conn, window, chain->depth, 32,<br>
+                                 pCreateInfo->compositeAlpha,<br>
+                                 modifiers, num_modifiers, &num_tranches,<br>
+                                 pAllocator);<br>
+<br>
    uint32_t image = 0;<br>
    for (; image < chain->base.image_count; image++) {<br>
       result = x11_image_init(device, chain, pCreateInfo, pAllocator,<br>
+                              (const uint64_t *const *)modifiers,<br>
+                              num_modifiers, num_tranches,<br>
                               &chain->images[image]);<br>
       if (result != VK_SUCCESS)<br>
          goto fail_init_images;<br>
@@ -1210,6 +1356,8 @@ x11_surface_create_swapchain(<wbr>VkIcdSurfaceBase *icd_surface,<br>
       }<br>
    }<br>
<br>
+   for (int i = 0; i < 2; i++)<br>
+      vk_free(pAllocator, modifiers[i]);<br>
    *swapchain_out = &chain->base;<br>
<br>
    return VK_SUCCESS;<br>
@@ -1219,6 +1367,9 @@ fail_init_images:<br>
       x11_image_finish(chain, pAllocator, &chain->images[j]);<br>
<br>
 fail_register:<br>
+   for (int i = 0; i < 2; i++)<br>
+      vk_free(pAllocator, modifiers[i]);<br>
+<br>
    xcb_unregister_for_special_<wbr>event(chain->conn, chain->special_event);<br>
<br>
    wsi_swapchain_finish(&chain-><wbr>base);<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.14.3<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>