From: Daniel Stone <dani...@collabora.com> Adds support for multiple planes and buffer modifiers. --- src/intel/vulkan/anv_wsi.c | 7 ++- src/vulkan/wsi/wsi_common_x11.c | 118 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 112 insertions(+), 13 deletions(-)
diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c index 88e2d7abc5..b3d04aade1 100644 --- a/src/intel/vulkan/anv_wsi.c +++ b/src/intel/vulkan/anv_wsi.c @@ -201,8 +201,11 @@ anv_wsi_image_create(VkDevice device_h, for (i = 0; i < num_modifiers; i++) { enum isl_tiling t; enum isl_aux_usage a; - if (isl_tiling_from_drm_format_mod(modifiers[i], &t, &a)) + if (modifiers[i] != DRM_FORMAT_MOD_LINEAR && + isl_tiling_from_drm_format_mod(modifiers[i], &t, &a)) { vk_tiling = VK_IMAGE_TILING_OPTIMAL; + break; + } } VkResult result; @@ -231,7 +234,7 @@ anv_wsi_image_create(VkDevice device_h, .pNext = &(VkExportImageDmaBufInfoMESAX) { .sType = VK_STRUCTURE_TYPE_EXPORT_IMAGE_DMA_BUF_INFO_MESAX, - .drmFormatModifierCount = ARRAY_SIZE(modifiers), + .drmFormatModifierCount = num_modifiers, .pDrmFormatModifiers = modifiers, }}}, NULL, diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index f12583db13..de5a8091d7 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" @@ -43,6 +44,10 @@ #include "wsi_common_x11.h" #include "wsi_common_queue.h" +#ifndef DRM_FORMAT_MOD_INVALID +#define DRM_FORMAT_MOD_INVALID (1ULL<<56)-1 +#endif + #define typed_memcpy(dest, src, count) ({ \ STATIC_ASSERT(sizeof(*src) == sizeof(*dest)); \ memcpy((dest), (src), (count) * sizeof(*(src))); \ @@ -50,6 +55,7 @@ struct wsi_x11_connection { bool has_dri3; + bool has_dri3_v1_1; bool has_present; bool is_proprietary_x11; }; @@ -164,6 +170,16 @@ wsi_x11_connection_create(const VkAllocationCallbacks *alloc, } wsi_conn->has_dri3 = dri3_reply->present != 0; + 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_v1_1 = ver_reply->major_version > 1 || + ver_reply->minor_version >= 1; + } + wsi_conn->has_present = pres_reply->present != 0; wsi_conn->is_proprietary_x11 = false; if (amd_reply && amd_reply->present) @@ -628,6 +644,8 @@ struct x11_image { struct x11_swapchain { struct wsi_swapchain base; + bool has_dri3_v1_1; + xcb_connection_t * conn; xcb_window_t window; xcb_gc_t gc; @@ -966,7 +984,7 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, uint32_t bpp = 32; int fd; uint32_t size; - uint64_t modifier; + uint64_t modifier = DRM_FORMAT_MOD_INVALID; result = chain->base.image_fns->create_wsi_image(device_h, pCreateInfo, @@ -1009,15 +1027,36 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, image->pixmap = xcb_generate_id(chain->conn); - cookie = - xcb_dri3_pixmap_from_buffer_checked(chain->conn, - image->pixmap, - chain->window, - size, - pCreateInfo->imageExtent.width, - pCreateInfo->imageExtent.height, - row_pitch, - chain->depth, bpp, fd); +#if XCB_DRI3_MAJOR_VERSION > 1 || XCB_DRI3_MINOR_VERSION >= 1 + if (chain->has_dri3_v1_1 && modifier != DRM_FORMAT_MOD_INVALID) { + cookie = + xcb_dri3_pixmap_from_buffers_checked(chain->conn, + image->pixmap, + chain->window, + 1, /* XXX: multi-plane */ + pCreateInfo->imageExtent.width, + pCreateInfo->imageExtent.height, + row_pitch, offset, + 0, 0, + 0, 0, + 0, 0, + chain->depth, bpp, + modifier >> 32, + modifier & 0xffffffff, + &fd); + } else +#endif + { + cookie = + xcb_dri3_pixmap_from_buffer_checked(chain->conn, + image->pixmap, + chain->window, + size, + pCreateInfo->imageExtent.width, + pCreateInfo->imageExtent.height, + row_pitch, + chain->depth, bpp, fd); + } xcb_discard_reply(chain->conn, cookie.sequence); int fence_fd = xshmfence_alloc_shm(); @@ -1109,6 +1148,45 @@ x11_swapchain_destroy(struct wsi_swapchain *anv_chain, return VK_SUCCESS; } +static void +wsi_x11_get_dri3_modifiers(xcb_connection_t *conn, xcb_window_t window, + uint8_t depth, uint8_t bpp, + VkCompositeAlphaFlagsKHR vk_alpha, + uint64_t **modifiers_in, int *num_modifiers_in, + const VkAllocationCallbacks* pAllocator) +{ +#if XCB_DRI3_MAJOR_VERSION > 1 || XCB_DRI3_MINOR_VERSION >= 1 + uint64_t *modifiers; + + 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); + if (!mod_reply) + return; + + if (!mod_reply->num_modifiers) + return; + + modifiers = vk_alloc(pAllocator, mod_reply->num_modifiers * sizeof(uint64_t), + 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!modifiers) + return; + + uint32_t *mod_parts = xcb_dri3_get_supported_modifiers_modifiers(mod_reply); + for (int i = 0; i < mod_reply->num_modifiers; i++) { + modifiers[i] = (uint64_t) mod_parts[i * 2] << 32; + modifiers[i] |= (uint64_t) mod_parts[i * 2 + 1] & 0xffffffff; + } + + free(mod_reply); + + *modifiers_in = modifiers; + *num_modifiers_in = mod_reply->num_modifiers; +#endif +} + static VkResult x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, VkDevice device, @@ -1122,6 +1200,8 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, struct x11_swapchain *chain; xcb_void_cookie_t cookie; VkResult result; + uint64_t *modifiers = NULL; + int num_modifiers = 0; assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR); @@ -1161,10 +1241,21 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, free(geometry); + struct wsi_x11_connection *wsi_conn = + wsi_x11_get_connection(wsi_device, pAllocator, conn); + if (!wsi_conn) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + chain->has_dri3_v1_1 = wsi_conn->has_dri3_v1_1; + chain->base.needs_linear_copy = false; if (!wsi_x11_check_dri3_compatible(conn, local_fd)) chain->base.needs_linear_copy = true; + wsi_x11_get_dri3_modifiers(conn, window, chain->depth, 32, + pCreateInfo->compositeAlpha, + &modifiers, &num_modifiers, pAllocator); + chain->event_id = xcb_generate_id(chain->conn); xcb_present_select_input(chain->conn, chain->event_id, chain->window, XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY | @@ -1195,7 +1286,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, uint32_t image = 0; for (; image < chain->base.image_count; image++) { result = x11_image_init(device, chain, pCreateInfo, pAllocator, - NULL, 0, &chain->images[image]); + modifiers, num_modifiers, &chain->images[image]); if (result != VK_SUCCESS) goto fail_init_images; } @@ -1231,11 +1322,16 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, } } + if (modifiers) + vk_free(pAllocator, modifiers); *swapchain_out = &chain->base; return VK_SUCCESS; fail_init_images: + if (modifiers) + vk_free(pAllocator, modifiers); + for (uint32_t j = 0; j < image; j++) x11_image_finish(chain, pAllocator, &chain->images[j]); -- 2.13.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev