[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:24:31 UTC 2018
On Wed, Feb 21, 2018 at 1:22 PM, Jason Ekstrand <jason at jlekstrand.net>
wrote:
> 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.heigh
>> t,
>> - 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.
>
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.
> --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/f390ea3c/attachment-0001.html>
More information about the mesa-dev
mailing list