<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Feb 21, 2018 at 1:22 PM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">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" target="_blank">daniels@collabora.com</a>><br>
---<br>
 src/vulkan/wsi/wsi_common_<wbr>x11.c | 185 ++++++++++++++++++++++++++++++<wbr>++++++----<br>
 1 file changed, 168 insertions(+), 17 deletions(-)<br>
<br>
diff --git a/src/vulkan/wsi/wsi_common_x1<wbr>1.c b/src/vulkan/wsi/wsi_common_x1<wbr>1.c<br>
index dadada82ef1..213a597a430 100644<br>
--- a/src/vulkan/wsi/wsi_common_x1<wbr>1.c<br>
+++ b/src/vulkan/wsi/wsi_common_x1<wbr>1.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(cons<wbr>t 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(c<wbr>onn, 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(&chain<wbr>->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_ch<wbr>ecked(chain->conn,<br>
-                                          image->pixmap,<br>
-                                          chain->window,<br>
-                                          image->base.sizes[0],<br>
-                                          pCreateInfo->imageExtent.width<wbr>,<br>
-                                          pCreateInfo->imageExtent.heigh<wbr>t,<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_modifie<wbr>rs);<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.width<wbr>,<br>
+                                              pCreateInfo->imageExtent.heigh<wbr>t,<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_c<wbr>hecked(chain->conn,<br>
+                                             image->pixmap,<br>
+                                             chain->window,<br>
+                                             image->base.sizes[0],<br>
+                                             pCreateInfo->imageExtent.widt<wbr>h,<br>
+                                             pCreateInfo->imageExtent.heig<wbr>ht,<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->base<wbr>, &image->base);<br>
 }<br>
<br>
+static void<br>
+wsi_x11_get_dri3_modifiers(st<wbr>ruct 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_modifiers<wbr>)<br>
+      goto out;<br>
+<br>
+   xcb_generic_error_t *error = NULL;<br>
+   xcb_dri3_get_supported_modifi<wbr>ers_cookie_t mod_cookie =<br>
+      xcb_dri3_get_supported_modifie<wbr>rs(conn, window, depth, bpp);<br>
+   xcb_dri3_get_supported_modifi<wbr>ers_reply_t *mod_reply =<br>
+      xcb_dri3_get_supported_modifie<wbr>rs_reply(conn, mod_cookie, &error);<br>
+   free(error);<br>
+<br>
+   if (!mod_reply || (mod_reply->num_drawable_modif<wbr>iers == 0 &&<br>
+                      mod_reply->num_screen_modifier<wbr>s == 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_modif<wbr>iers) {<br>
+      counts[n] = mod_reply->num_drawable_modifi<wbr>ers;<br>
+      modifiers[n] = vk_alloc(pAllocator,<br>
+                              counts[n] * sizeof(uint64_t),<br>
+                              8, VK_SYSTEM_ALLOCATION_SCOPE_OBJ<wbr>ECT);<br>
+      if (!modifiers[n]) {<br>
+         free(mod_reply);<br>
+         goto out;<br>
+      }<br>
+<br>
+      memcpy(modifiers[n],<br>
+             xcb_dri3_get_supported_modifi<wbr>ers_drawable_modifiers(mod_<wbr>reply),<br></blockquote><div><br></div></div></div><div>Did we ever get a solid answer on whether or not this memcpy is really needed?  I doubt it is.<span class="HOEnZb"><font color="#888888"><br></font></span></div></div></div></div></blockquote><div><br></div><div>I'm an idiot.  It is needed because we free mod_reply at the end of the function.  We could probably restructure so it isn't needed but I doubt it's really worth it.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><span class="HOEnZb"><font color="#888888"></font></span></div><span class="HOEnZb"><font color="#888888"><div>--Jason<br></div></font></span><div><div class="h5"><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_modifie<wbr>rs) {<br>
+      counts[n] = mod_reply->num_screen_modifier<wbr>s;<br>
+      modifiers[n] = vk_alloc(pAllocator,<br>
+                              counts[n] * sizeof(uint64_t),<br>
+                              8, VK_SYSTEM_ALLOCATION_SCOPE_OBJ<wbr>ECT);<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_modifi<wbr>ers_screen_modifiers(mod_<wbr>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(V<wbr>kIcdSurfaceBase *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(icd<wbr>_surface);<br>
+   struct wsi_x11_connection *wsi_conn =<br>
+      wsi_x11_get_connection(wsi_dev<wbr>ice, 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_sur<wbr>face);<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(V<wbr>kIcdSurfaceBase *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_compatibl<wbr>e(conn, local_fd))<br>
        chain->base.use_prime_blit = true;<br>
@@ -1171,9 +1306,20 @@ x11_surface_create_swapchain(V<wbr>kIcdSurfaceBase *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_modifier<wbr>s)<br>
+      wsi_x11_get_dri3_modifiers(wsi<wbr>_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(V<wbr>kIcdSurfaceBase *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_eve<wbr>nt(chain->conn, chain->special_event);<br>
<br>
    wsi_swapchain_finish(&chain->b<wbr>ase);<br>
<span class="m_-8327231154265644771HOEnZb"><font color="#888888">--<br>
2.14.3<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">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></div></div><br></div></div>
</blockquote></div><br></div></div>