[Mesa-dev] [PATCH v11 10/15] vulkan/wsi/x11: Add support for DRI3 v1.1

Jason Ekstrand jason at jlekstrand.net
Wed Feb 21 21:22:24 UTC 2018


On Wed, Feb 21, 2018 at 6:05 AM, Daniel Stone <daniels at collabora.com> wrote:

> Adds support for multiple planes and buffer modifiers.
>
> v4: Rename "has_dri3_v1_1" to "has_dri3_modifiers"
> Signed-off-by: Daniel Stone <daniels at collabora.com>
> ---
>  src/vulkan/wsi/wsi_common_x11.c | 185 ++++++++++++++++++++++++++++++
> ++++++----
>  1 file changed, 168 insertions(+), 17 deletions(-)
>
> diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_
> x11.c
> index dadada82ef1..213a597a430 100644
> --- a/src/vulkan/wsi/wsi_common_x11.c
> +++ b/src/vulkan/wsi/wsi_common_x11.c
> @@ -36,6 +36,7 @@
>  #include <fcntl.h>
>  #include <poll.h>
>  #include <xf86drm.h>
> +#include <drm_fourcc.h>
>  #include "util/hash_table.h"
>
>  #include "vk_util.h"
> @@ -50,6 +51,7 @@
>
>  struct wsi_x11_connection {
>     bool has_dri3;
> +   bool has_dri3_modifiers;
>     bool has_present;
>     bool is_proprietary_x11;
>  };
> @@ -164,6 +166,19 @@ wsi_x11_connection_create(const
> VkAllocationCallbacks *alloc,
>     }
>
>     wsi_conn->has_dri3 = dri3_reply->present != 0;
> +#if XCB_DRI3_MAJOR_VERSION > 1 || XCB_DRI3_MINOR_VERSION >= 1
> +   if (wsi_conn->has_dri3) {
> +      xcb_dri3_query_version_cookie_t ver_cookie;
> +      xcb_dri3_query_version_reply_t *ver_reply;
> +
> +      ver_cookie = xcb_dri3_query_version(conn, 1, 1);
> +      ver_reply = xcb_dri3_query_version_reply(conn, ver_cookie, NULL);
> +      wsi_conn->has_dri3_modifiers =
> +         (ver_reply->major_version > 1 || ver_reply->minor_version >= 1);
> +      free(ver_reply);
> +   }
> +#endif
> +
>     wsi_conn->has_present = pres_reply->present != 0;
>     wsi_conn->is_proprietary_x11 = false;
>     if (amd_reply && amd_reply->present)
> @@ -620,6 +635,8 @@ struct x11_image {
>  struct x11_swapchain {
>     struct wsi_swapchain                        base;
>
> +   bool                                         has_dri3_modifiers;
> +
>     xcb_connection_t *                           conn;
>     xcb_window_t                                 window;
>     xcb_gc_t                                     gc;
> @@ -974,7 +991,9 @@ static VkResult
>  x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
>                 const VkSwapchainCreateInfoKHR *pCreateInfo,
>                 const VkAllocationCallbacks* pAllocator,
> -               struct x11_image *image)
> +               const uint64_t *const *modifiers,
> +               const uint32_t *num_modifiers,
> +               int num_tranches, struct x11_image *image)
>  {
>     xcb_void_cookie_t cookie;
>     VkResult result;
> @@ -984,28 +1003,60 @@ x11_image_init(VkDevice device_h, struct
> x11_swapchain *chain,
>        result = wsi_create_prime_image(&chain->base, pCreateInfo,
> &image->base);
>     } else {
>        result = wsi_create_native_image(&chain->base, pCreateInfo,
> -                                       0, NULL, NULL, &image->base);
> +                                       num_tranches, num_modifiers,
> modifiers,
> +                                       &image->base);
>     }
>     if (result < 0)
>        return result;
>
>     image->pixmap = xcb_generate_id(chain->conn);
>
> -   /* Without passing modifiers, we can't have multi-plane RGB images. */
> -   assert(image->base.num_planes == 1);
> -
> -   cookie =
> -      xcb_dri3_pixmap_from_buffer_checked(chain->conn,
> -                                          image->pixmap,
> -                                          chain->window,
> -                                          image->base.sizes[0],
> -                                          pCreateInfo->imageExtent.width,
> -                                          pCreateInfo->imageExtent.
> height,
> -                                          image->base.row_pitches[0],
> -                                          chain->depth, bpp,
> -                                          image->base.fds[0]);
> +#if XCB_DRI3_MAJOR_VERSION > 1 || XCB_DRI3_MINOR_VERSION >= 1
> +   if (image->base.drm_modifier != DRM_FORMAT_MOD_INVALID) {
> +      /* If the image has a modifier, we must have DRI3 v1.1. */
> +      assert(chain->has_dri3_modifiers);
> +
> +      cookie =
> +         xcb_dri3_pixmap_from_buffers_checked(chain->conn,
> +                                              image->pixmap,
> +                                              chain->window,
> +                                              image->base.num_planes,
> +                                              pCreateInfo->imageExtent.
> width,
> +                                              pCreateInfo->imageExtent.
> height,
> +                                              image->base.row_pitches[0],
> +                                              image->base.offsets[0],
> +                                              image->base.row_pitches[1],
> +                                              image->base.offsets[1],
> +                                              image->base.row_pitches[2],
> +                                              image->base.offsets[2],
> +                                              image->base.row_pitches[3],
> +                                              image->base.offsets[3],
> +                                              chain->depth, bpp,
> +                                              image->base.drm_modifier,
> +                                              image->base.fds);
> +   } else
> +#endif
> +   {
> +      /* Without passing modifiers, we can't have multi-plane RGB images.
> */
> +      assert(image->base.num_planes == 1);
> +
> +      cookie =
> +         xcb_dri3_pixmap_from_buffer_checked(chain->conn,
> +                                             image->pixmap,
> +                                             chain->window,
> +                                             image->base.sizes[0],
> +                                             pCreateInfo->imageExtent.
> width,
> +                                             pCreateInfo->imageExtent.
> height,
> +                                             image->base.row_pitches[0],
> +                                             chain->depth, bpp,
> +                                             image->base.fds[0]);
> +   }
> +
>     xcb_discard_reply(chain->conn, cookie.sequence);
> -   image->base.fds[0] = -1; /* XCB has now taken ownership of the FD */
> +
> +   /* XCB has now taken ownership of the FDs. */
> +   for (int i = 0; i < image->base.num_planes; i++)
> +      image->base.fds[i] = -1;
>
>     int fence_fd = xshmfence_alloc_shm();
>     if (fence_fd < 0)
> @@ -1056,6 +1107,84 @@ x11_image_finish(struct x11_swapchain *chain,
>     wsi_destroy_image(&chain->base, &image->base);
>  }
>
> +static void
> +wsi_x11_get_dri3_modifiers(struct wsi_x11_connection *wsi_conn,
> +                           xcb_connection_t *conn, xcb_window_t window,
> +                           uint8_t depth, uint8_t bpp,
> +                           VkCompositeAlphaFlagsKHR vk_alpha,
> +                           uint64_t **modifiers_in, uint32_t
> *num_modifiers_in,
> +                           uint32_t *num_tranches_in,
> +                           const VkAllocationCallbacks *pAllocator)
> +{
> +#if XCB_DRI3_MAJOR_VERSION > 1 || XCB_DRI3_MINOR_VERSION >= 1
> +   if (!wsi_conn->has_dri3_modifiers)
> +      goto out;
> +
> +   xcb_generic_error_t *error = NULL;
> +   xcb_dri3_get_supported_modifiers_cookie_t mod_cookie =
> +      xcb_dri3_get_supported_modifiers(conn, window, depth, bpp);
> +   xcb_dri3_get_supported_modifiers_reply_t *mod_reply =
> +      xcb_dri3_get_supported_modifiers_reply(conn, mod_cookie, &error);
> +   free(error);
> +
> +   if (!mod_reply || (mod_reply->num_drawable_modifiers == 0 &&
> +                      mod_reply->num_screen_modifiers == 0)) {
> +      free(mod_reply);
> +      goto out;
> +   }
> +
> +   uint32_t n = 0;
> +   uint32_t counts[2];
> +   uint64_t *modifiers[2];
> +
> +   if (mod_reply->num_drawable_modifiers) {
> +      counts[n] = mod_reply->num_drawable_modifiers;
> +      modifiers[n] = vk_alloc(pAllocator,
> +                              counts[n] * sizeof(uint64_t),
> +                              8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
> +      if (!modifiers[n]) {
> +         free(mod_reply);
> +         goto out;
> +      }
> +
> +      memcpy(modifiers[n],
> +             xcb_dri3_get_supported_modifiers_drawable_modifiers(
> mod_reply),
>

Did we ever get a solid answer on whether or not this memcpy is really
needed?  I doubt it is.

--Jason


> +             counts[n] * sizeof(uint64_t));
> +      n++;
> +   }
> +
> +   if (mod_reply->num_screen_modifiers) {
> +      counts[n] = mod_reply->num_screen_modifiers;
> +      modifiers[n] = vk_alloc(pAllocator,
> +                              counts[n] * sizeof(uint64_t),
> +                              8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
> +      if (!modifiers[n]) {
> +        if (n > 0)
> +            vk_free(pAllocator, modifiers[0]);
> +         free(mod_reply);
> +         goto out;
> +      }
> +
> +      memcpy(modifiers[n],
> +             xcb_dri3_get_supported_modifiers_screen_modifiers(
> mod_reply),
> +             counts[n] * sizeof(uint64_t));
> +      n++;
> +   }
> +
> +   for (int i = 0; i < n; i++) {
> +      modifiers_in[i] = modifiers[i];
> +      num_modifiers_in[i] = counts[i];
> +   }
> +   *num_tranches_in = n;
> +
> +   free(mod_reply);
> +   return;
> +#endif
> +
> +out:
> +   *num_tranches_in = 0;
> +}
> +
>  static VkResult
>  x11_swapchain_destroy(struct wsi_swapchain *anv_chain,
>                        const VkAllocationCallbacks *pAllocator)
> @@ -1105,8 +1234,13 @@ x11_surface_create_swapchain(VkIcdSurfaceBase
> *icd_surface,
>
>     const unsigned num_images = pCreateInfo->minImageCount;
>
> -   /* Check for whether or not we have a window up-front */
>     xcb_connection_t *conn = x11_surface_get_connection(icd_surface);
> +   struct wsi_x11_connection *wsi_conn =
> +      wsi_x11_get_connection(wsi_device, pAllocator, conn);
> +   if (!wsi_conn)
> +      return VK_ERROR_OUT_OF_HOST_MEMORY;
> +
> +   /* Check for whether or not we have a window up-front */
>     xcb_window_t window = x11_surface_get_window(icd_surface);
>     xcb_get_geometry_reply_t *geometry =
>        xcb_get_geometry_reply(conn, xcb_get_geometry(conn, window), NULL);
> @@ -1140,6 +1274,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase
> *icd_surface,
>     chain->last_present_msc = 0;
>     chain->threaded = false;
>     chain->status = VK_SUCCESS;
> +   chain->has_dri3_modifiers = wsi_conn->has_dri3_modifiers;
>
>     if (!wsi_x11_check_dri3_compatible(conn, local_fd))
>         chain->base.use_prime_blit = true;
> @@ -1171,9 +1306,20 @@ x11_surface_create_swapchain(VkIcdSurfaceBase
> *icd_surface,
>                            (uint32_t []) { 0 });
>     xcb_discard_reply(chain->conn, cookie.sequence);
>
> +   uint64_t *modifiers[2] = {NULL, NULL};
> +   uint32_t num_modifiers[2] = {0, 0};
> +   uint32_t num_tranches = 0;
> +   if (wsi_device->supports_modifiers)
> +      wsi_x11_get_dri3_modifiers(wsi_conn, conn, window, chain->depth,
> 32,
> +                                 pCreateInfo->compositeAlpha,
> +                                 modifiers, num_modifiers, &num_tranches,
> +                                 pAllocator);
> +
>     uint32_t image = 0;
>     for (; image < chain->base.image_count; image++) {
>        result = x11_image_init(device, chain, pCreateInfo, pAllocator,
> +                              (const uint64_t *const *)modifiers,
> +                              num_modifiers, num_tranches,
>                                &chain->images[image]);
>        if (result != VK_SUCCESS)
>           goto fail_init_images;
> @@ -1210,6 +1356,8 @@ x11_surface_create_swapchain(VkIcdSurfaceBase
> *icd_surface,
>        }
>     }
>
> +   for (int i = 0; i < 2; i++)
> +      vk_free(pAllocator, modifiers[i]);
>     *swapchain_out = &chain->base;
>
>     return VK_SUCCESS;
> @@ -1219,6 +1367,9 @@ fail_init_images:
>        x11_image_finish(chain, pAllocator, &chain->images[j]);
>
>  fail_register:
> +   for (int i = 0; i < 2; i++)
> +      vk_free(pAllocator, modifiers[i]);
> +
>     xcb_unregister_for_special_event(chain->conn, chain->special_event);
>
>     wsi_swapchain_finish(&chain->base);
> --
> 2.14.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20180221/66d2cd1a/attachment-0001.html>


More information about the mesa-dev mailing list