1971523410fd2235e13c617b6a1569f70486258d7Dave Airlie/* 2971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * Copyright © 2015 Intel Corporation 3971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * 4971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * Permission is hereby granted, free of charge, to any person obtaining a 5971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * copy of this software and associated documentation files (the "Software"), 6971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * to deal in the Software without restriction, including without limitation 7971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * and/or sell copies of the Software, and to permit persons to whom the 9971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * Software is furnished to do so, subject to the following conditions: 10971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * 11971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * The above copyright notice and this permission notice (including the next 12971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * paragraph) shall be included in all copies or substantial portions of the 13971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * Software. 14971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * 15971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * IN THE SOFTWARE. 22971523410fd2235e13c617b6a1569f70486258d7Dave Airlie */ 23971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 24971523410fd2235e13c617b6a1569f70486258d7Dave Airlie#include <X11/Xlib-xcb.h> 25971523410fd2235e13c617b6a1569f70486258d7Dave Airlie#include <X11/xshmfence.h> 26971523410fd2235e13c617b6a1569f70486258d7Dave Airlie#include <xcb/xcb.h> 27971523410fd2235e13c617b6a1569f70486258d7Dave Airlie#include <xcb/dri3.h> 28971523410fd2235e13c617b6a1569f70486258d7Dave Airlie#include <xcb/present.h> 29971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 303f7ef2488938d31b5ead043891fadc3cee4c6f05Dave Airlie#include "util/macros.h" 31971523410fd2235e13c617b6a1569f70486258d7Dave Airlie#include <stdlib.h> 32971523410fd2235e13c617b6a1569f70486258d7Dave Airlie#include <stdio.h> 33971523410fd2235e13c617b6a1569f70486258d7Dave Airlie#include <unistd.h> 34971523410fd2235e13c617b6a1569f70486258d7Dave Airlie#include <errno.h> 35971523410fd2235e13c617b6a1569f70486258d7Dave Airlie#include <string.h> 363f7ef2488938d31b5ead043891fadc3cee4c6f05Dave Airlie 37787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie#include <poll.h> 383f7ef2488938d31b5ead043891fadc3cee4c6f05Dave Airlie#include "util/hash_table.h" 393f7ef2488938d31b5ead043891fadc3cee4c6f05Dave Airlie 40971523410fd2235e13c617b6a1569f70486258d7Dave Airlie#include "wsi_common.h" 41971523410fd2235e13c617b6a1569f70486258d7Dave Airlie#include "wsi_common_x11.h" 42e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand#include "wsi_common_queue.h" 43971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 44971523410fd2235e13c617b6a1569f70486258d7Dave Airlie#define typed_memcpy(dest, src, count) ({ \ 45a77426fd922259bc37b762fa22b42b91d3ce494aEdward O'Callaghan STATIC_ASSERT(sizeof(*src) == sizeof(*dest)); \ 46971523410fd2235e13c617b6a1569f70486258d7Dave Airlie memcpy((dest), (src), (count) * sizeof(*(src))); \ 47971523410fd2235e13c617b6a1569f70486258d7Dave Airlie}) 48971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 49971523410fd2235e13c617b6a1569f70486258d7Dave Airliestruct wsi_x11_connection { 50971523410fd2235e13c617b6a1569f70486258d7Dave Airlie bool has_dri3; 51971523410fd2235e13c617b6a1569f70486258d7Dave Airlie bool has_present; 52d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay bool is_proprietary_x11; 53971523410fd2235e13c617b6a1569f70486258d7Dave Airlie}; 54971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 55971523410fd2235e13c617b6a1569f70486258d7Dave Airliestruct wsi_x11 { 56ec0bc14a700c2503d834ac0763f4cfbe312998faDave Airlie struct wsi_interface base; 57971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 58971523410fd2235e13c617b6a1569f70486258d7Dave Airlie pthread_mutex_t mutex; 59971523410fd2235e13c617b6a1569f70486258d7Dave Airlie /* Hash table of xcb_connection -> wsi_x11_connection mappings */ 60971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct hash_table *connections; 61971523410fd2235e13c617b6a1569f70486258d7Dave Airlie}; 62971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 63971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic struct wsi_x11_connection * 64971523410fd2235e13c617b6a1569f70486258d7Dave Airliewsi_x11_connection_create(const VkAllocationCallbacks *alloc, 65971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_connection_t *conn) 66971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 67d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay xcb_query_extension_cookie_t dri3_cookie, pres_cookie, amd_cookie, nv_cookie; 68d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay xcb_query_extension_reply_t *dri3_reply, *pres_reply, *amd_reply, *nv_reply; 69971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 70971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct wsi_x11_connection *wsi_conn = 71971523410fd2235e13c617b6a1569f70486258d7Dave Airlie vk_alloc(alloc, sizeof(*wsi_conn), 8, 72971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); 73971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (!wsi_conn) 74971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return NULL; 75971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 76971523410fd2235e13c617b6a1569f70486258d7Dave Airlie dri3_cookie = xcb_query_extension(conn, 4, "DRI3"); 77971523410fd2235e13c617b6a1569f70486258d7Dave Airlie pres_cookie = xcb_query_extension(conn, 7, "PRESENT"); 78971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 79d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay /* We try to be nice to users and emit a warning if they try to use a 80d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay * Vulkan application on a system without DRI3 enabled. However, this ends 81d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay * up spewing the warning when a user has, for example, both Intel 82d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay * integrated graphics and a discrete card with proprietary drivers and are 83d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay * running on the discrete card with the proprietary DDX. In this case, we 84d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay * really don't want to print the warning because it just confuses users. 85d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay * As a heuristic to detect this case, we check for a couple of proprietary 86d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay * X11 extensions. 87d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay */ 88d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay amd_cookie = xcb_query_extension(conn, 11, "ATIFGLRXDRI"); 89d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay nv_cookie = xcb_query_extension(conn, 10, "NV-CONTROL"); 90d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay 91971523410fd2235e13c617b6a1569f70486258d7Dave Airlie dri3_reply = xcb_query_extension_reply(conn, dri3_cookie, NULL); 92971523410fd2235e13c617b6a1569f70486258d7Dave Airlie pres_reply = xcb_query_extension_reply(conn, pres_cookie, NULL); 93d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay amd_reply = xcb_query_extension_reply(conn, amd_cookie, NULL); 94d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay nv_reply = xcb_query_extension_reply(conn, nv_cookie, NULL); 95d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay if (!dri3_reply || !pres_reply) { 96971523410fd2235e13c617b6a1569f70486258d7Dave Airlie free(dri3_reply); 97971523410fd2235e13c617b6a1569f70486258d7Dave Airlie free(pres_reply); 98d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay free(amd_reply); 99d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay free(nv_reply); 100971523410fd2235e13c617b6a1569f70486258d7Dave Airlie vk_free(alloc, wsi_conn); 101971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return NULL; 102971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 103971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 104971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi_conn->has_dri3 = dri3_reply->present != 0; 105971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi_conn->has_present = pres_reply->present != 0; 106d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay wsi_conn->is_proprietary_x11 = false; 107d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay if (amd_reply && amd_reply->present) 108d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay wsi_conn->is_proprietary_x11 = true; 109d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay if (nv_reply && nv_reply->present) 110d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay wsi_conn->is_proprietary_x11 = true; 111971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 112971523410fd2235e13c617b6a1569f70486258d7Dave Airlie free(dri3_reply); 113971523410fd2235e13c617b6a1569f70486258d7Dave Airlie free(pres_reply); 114d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay free(amd_reply); 115d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay free(nv_reply); 116971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 117971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return wsi_conn; 118971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 119971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 120971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic void 121971523410fd2235e13c617b6a1569f70486258d7Dave Airliewsi_x11_connection_destroy(const VkAllocationCallbacks *alloc, 122971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct wsi_x11_connection *conn) 123971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 124971523410fd2235e13c617b6a1569f70486258d7Dave Airlie vk_free(alloc, conn); 125971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 126971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 127d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshaystatic bool 128d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshaywsi_x11_check_for_dri3(struct wsi_x11_connection *wsi_conn) 129d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay{ 130d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay if (wsi_conn->has_dri3) 131d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay return true; 132d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay if (!wsi_conn->is_proprietary_x11) { 133d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay fprintf(stderr, "vulkan: No DRI3 support detected - required for presentation\n" 134d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay "Note: you can probably enable DRI3 in your Xorg config\n"); 135d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay } 136d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay return false; 137d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay} 138d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay 139971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic struct wsi_x11_connection * 140ec0bc14a700c2503d834ac0763f4cfbe312998faDave Airliewsi_x11_get_connection(struct wsi_device *wsi_dev, 141971523410fd2235e13c617b6a1569f70486258d7Dave Airlie const VkAllocationCallbacks *alloc, 142971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_connection_t *conn) 143971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 144971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct wsi_x11 *wsi = 145971523410fd2235e13c617b6a1569f70486258d7Dave Airlie (struct wsi_x11 *)wsi_dev->wsi[VK_ICD_WSI_PLATFORM_XCB]; 146971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 147971523410fd2235e13c617b6a1569f70486258d7Dave Airlie pthread_mutex_lock(&wsi->mutex); 148971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 149971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct hash_entry *entry = _mesa_hash_table_search(wsi->connections, conn); 150971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (!entry) { 151971523410fd2235e13c617b6a1569f70486258d7Dave Airlie /* We're about to make a bunch of blocking calls. Let's drop the 152971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * mutex for now so we don't block up too badly. 153971523410fd2235e13c617b6a1569f70486258d7Dave Airlie */ 154971523410fd2235e13c617b6a1569f70486258d7Dave Airlie pthread_mutex_unlock(&wsi->mutex); 155971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 156971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct wsi_x11_connection *wsi_conn = 157971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi_x11_connection_create(alloc, conn); 158fc0e9e3e40e4b044ce1b62c1b757941f4ed4c820Jason Ekstrand if (!wsi_conn) 159fc0e9e3e40e4b044ce1b62c1b757941f4ed4c820Jason Ekstrand return NULL; 160971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 161971523410fd2235e13c617b6a1569f70486258d7Dave Airlie pthread_mutex_lock(&wsi->mutex); 162971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 163971523410fd2235e13c617b6a1569f70486258d7Dave Airlie entry = _mesa_hash_table_search(wsi->connections, conn); 164971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (entry) { 165971523410fd2235e13c617b6a1569f70486258d7Dave Airlie /* Oops, someone raced us to it */ 166971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi_x11_connection_destroy(alloc, wsi_conn); 167971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } else { 168971523410fd2235e13c617b6a1569f70486258d7Dave Airlie entry = _mesa_hash_table_insert(wsi->connections, conn, wsi_conn); 169971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 170971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 171971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 172971523410fd2235e13c617b6a1569f70486258d7Dave Airlie pthread_mutex_unlock(&wsi->mutex); 173971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 174971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return entry->data; 175971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 176971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 177971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic const VkSurfaceFormatKHR formats[] = { 178971523410fd2235e13c617b6a1569f70486258d7Dave Airlie { .format = VK_FORMAT_B8G8R8A8_SRGB, }, 179971523410fd2235e13c617b6a1569f70486258d7Dave Airlie { .format = VK_FORMAT_B8G8R8A8_UNORM, }, 180971523410fd2235e13c617b6a1569f70486258d7Dave Airlie}; 181971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 182971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic const VkPresentModeKHR present_modes[] = { 183ca035006c86a5055c8e640f49c858f04770681ebDave Airlie VK_PRESENT_MODE_IMMEDIATE_KHR, 184971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VK_PRESENT_MODE_MAILBOX_KHR, 185e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand VK_PRESENT_MODE_FIFO_KHR, 186971523410fd2235e13c617b6a1569f70486258d7Dave Airlie}; 187971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 188971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic xcb_screen_t * 189971523410fd2235e13c617b6a1569f70486258d7Dave Airlieget_screen_for_root(xcb_connection_t *conn, xcb_window_t root) 190971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 191971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_screen_iterator_t screen_iter = 192971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_setup_roots_iterator(xcb_get_setup(conn)); 193971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 194971523410fd2235e13c617b6a1569f70486258d7Dave Airlie for (; screen_iter.rem; xcb_screen_next (&screen_iter)) { 195971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (screen_iter.data->root == root) 196971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return screen_iter.data; 197971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 198971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 199971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return NULL; 200971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 201971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 202971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic xcb_visualtype_t * 203971523410fd2235e13c617b6a1569f70486258d7Dave Airliescreen_get_visualtype(xcb_screen_t *screen, xcb_visualid_t visual_id, 204971523410fd2235e13c617b6a1569f70486258d7Dave Airlie unsigned *depth) 205971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 206971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_depth_iterator_t depth_iter = 207971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_screen_allowed_depths_iterator(screen); 208971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 209971523410fd2235e13c617b6a1569f70486258d7Dave Airlie for (; depth_iter.rem; xcb_depth_next (&depth_iter)) { 210971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_visualtype_iterator_t visual_iter = 211971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_depth_visuals_iterator (depth_iter.data); 212971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 213971523410fd2235e13c617b6a1569f70486258d7Dave Airlie for (; visual_iter.rem; xcb_visualtype_next (&visual_iter)) { 214971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (visual_iter.data->visual_id == visual_id) { 215971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (depth) 216971523410fd2235e13c617b6a1569f70486258d7Dave Airlie *depth = depth_iter.data->depth; 217971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return visual_iter.data; 218971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 219971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 220971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 221971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 222971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return NULL; 223971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 224971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 225971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic xcb_visualtype_t * 226971523410fd2235e13c617b6a1569f70486258d7Dave Airlieconnection_get_visualtype(xcb_connection_t *conn, xcb_visualid_t visual_id, 227971523410fd2235e13c617b6a1569f70486258d7Dave Airlie unsigned *depth) 228971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 229971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_screen_iterator_t screen_iter = 230971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_setup_roots_iterator(xcb_get_setup(conn)); 231971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 232971523410fd2235e13c617b6a1569f70486258d7Dave Airlie /* For this we have to iterate over all of the screens which is rather 233971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * annoying. Fortunately, there is probably only 1. 234971523410fd2235e13c617b6a1569f70486258d7Dave Airlie */ 235971523410fd2235e13c617b6a1569f70486258d7Dave Airlie for (; screen_iter.rem; xcb_screen_next (&screen_iter)) { 236971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_visualtype_t *visual = screen_get_visualtype(screen_iter.data, 237971523410fd2235e13c617b6a1569f70486258d7Dave Airlie visual_id, depth); 238971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (visual) 239971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return visual; 240971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 241971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 242971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return NULL; 243971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 244971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 245971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic xcb_visualtype_t * 246971523410fd2235e13c617b6a1569f70486258d7Dave Airlieget_visualtype_for_window(xcb_connection_t *conn, xcb_window_t window, 247971523410fd2235e13c617b6a1569f70486258d7Dave Airlie unsigned *depth) 248971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 249971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_query_tree_cookie_t tree_cookie; 250971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_get_window_attributes_cookie_t attrib_cookie; 251971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_query_tree_reply_t *tree; 252971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_get_window_attributes_reply_t *attrib; 253971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 254971523410fd2235e13c617b6a1569f70486258d7Dave Airlie tree_cookie = xcb_query_tree(conn, window); 255971523410fd2235e13c617b6a1569f70486258d7Dave Airlie attrib_cookie = xcb_get_window_attributes(conn, window); 256971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 257971523410fd2235e13c617b6a1569f70486258d7Dave Airlie tree = xcb_query_tree_reply(conn, tree_cookie, NULL); 258971523410fd2235e13c617b6a1569f70486258d7Dave Airlie attrib = xcb_get_window_attributes_reply(conn, attrib_cookie, NULL); 259971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (attrib == NULL || tree == NULL) { 260971523410fd2235e13c617b6a1569f70486258d7Dave Airlie free(attrib); 261971523410fd2235e13c617b6a1569f70486258d7Dave Airlie free(tree); 262971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return NULL; 263971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 264971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 265971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_window_t root = tree->root; 266971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_visualid_t visual_id = attrib->visual; 267971523410fd2235e13c617b6a1569f70486258d7Dave Airlie free(attrib); 268971523410fd2235e13c617b6a1569f70486258d7Dave Airlie free(tree); 269971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 270971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_screen_t *screen = get_screen_for_root(conn, root); 271971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (screen == NULL) 272971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return NULL; 273971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 274971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return screen_get_visualtype(screen, visual_id, depth); 275971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 276971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 277971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic bool 278971523410fd2235e13c617b6a1569f70486258d7Dave Airlievisual_has_alpha(xcb_visualtype_t *visual, unsigned depth) 279971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 280971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t rgb_mask = visual->red_mask | 281971523410fd2235e13c617b6a1569f70486258d7Dave Airlie visual->green_mask | 282971523410fd2235e13c617b6a1569f70486258d7Dave Airlie visual->blue_mask; 283971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 284971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t all_mask = 0xffffffff >> (32 - depth); 285971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 286971523410fd2235e13c617b6a1569f70486258d7Dave Airlie /* Do we have bits left over after RGB? */ 287971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return (all_mask & ~rgb_mask) != 0; 288971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 289971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 290ec0bc14a700c2503d834ac0763f4cfbe312998faDave AirlieVkBool32 wsi_get_physical_device_xcb_presentation_support( 291ec0bc14a700c2503d834ac0763f4cfbe312998faDave Airlie struct wsi_device *wsi_device, 292971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkAllocationCallbacks *alloc, 293971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t queueFamilyIndex, 294971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_connection_t* connection, 295971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_visualid_t visual_id) 296971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 297971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct wsi_x11_connection *wsi_conn = 298971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi_x11_get_connection(wsi_device, alloc, connection); 299971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 30099de7b752546c3f87aa8a18f72fd46856270555fArda Coskunses if (!wsi_conn) 30199de7b752546c3f87aa8a18f72fd46856270555fArda Coskunses return false; 30299de7b752546c3f87aa8a18f72fd46856270555fArda Coskunses 303d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay if (!wsi_x11_check_for_dri3(wsi_conn)) 304971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return false; 305971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 306971523410fd2235e13c617b6a1569f70486258d7Dave Airlie unsigned visual_depth; 307971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (!connection_get_visualtype(connection, visual_id, &visual_depth)) 308971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return false; 309971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 310971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (visual_depth != 24 && visual_depth != 32) 311971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return false; 312971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 313971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return true; 314971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 315971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 316971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic xcb_connection_t* 317971523410fd2235e13c617b6a1569f70486258d7Dave Airliex11_surface_get_connection(VkIcdSurfaceBase *icd_surface) 318971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 319971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (icd_surface->platform == VK_ICD_WSI_PLATFORM_XLIB) 320971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return XGetXCBConnection(((VkIcdSurfaceXlib *)icd_surface)->dpy); 321971523410fd2235e13c617b6a1569f70486258d7Dave Airlie else 322971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return ((VkIcdSurfaceXcb *)icd_surface)->connection; 323971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 324971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 325971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic xcb_window_t 326971523410fd2235e13c617b6a1569f70486258d7Dave Airliex11_surface_get_window(VkIcdSurfaceBase *icd_surface) 327971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 328971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (icd_surface->platform == VK_ICD_WSI_PLATFORM_XLIB) 329971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return ((VkIcdSurfaceXlib *)icd_surface)->window; 330971523410fd2235e13c617b6a1569f70486258d7Dave Airlie else 331971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return ((VkIcdSurfaceXcb *)icd_surface)->window; 332971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 333971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 334971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic VkResult 335971523410fd2235e13c617b6a1569f70486258d7Dave Airliex11_surface_get_support(VkIcdSurfaceBase *icd_surface, 336ec0bc14a700c2503d834ac0763f4cfbe312998faDave Airlie struct wsi_device *wsi_device, 337971523410fd2235e13c617b6a1569f70486258d7Dave Airlie const VkAllocationCallbacks *alloc, 338971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t queueFamilyIndex, 339971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkBool32* pSupported) 340971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 341971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_connection_t *conn = x11_surface_get_connection(icd_surface); 342971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_window_t window = x11_surface_get_window(icd_surface); 343971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 344971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct wsi_x11_connection *wsi_conn = 345971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi_x11_get_connection(wsi_device, alloc, conn); 346971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (!wsi_conn) 347971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_ERROR_OUT_OF_HOST_MEMORY; 348971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 349d74d7cc0ff517c67c3f2f55a1e625b04c4001591Jacob Lifshay if (!wsi_x11_check_for_dri3(wsi_conn)) { 350971523410fd2235e13c617b6a1569f70486258d7Dave Airlie *pSupported = false; 351971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 352971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 353971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 354971523410fd2235e13c617b6a1569f70486258d7Dave Airlie unsigned visual_depth; 355971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (!get_visualtype_for_window(conn, window, &visual_depth)) { 356971523410fd2235e13c617b6a1569f70486258d7Dave Airlie *pSupported = false; 357971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 358971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 359971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 360971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (visual_depth != 24 && visual_depth != 32) { 361971523410fd2235e13c617b6a1569f70486258d7Dave Airlie *pSupported = false; 362971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 363971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 364971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 365971523410fd2235e13c617b6a1569f70486258d7Dave Airlie *pSupported = true; 366971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 367971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 368971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 369971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic VkResult 370971523410fd2235e13c617b6a1569f70486258d7Dave Airliex11_surface_get_capabilities(VkIcdSurfaceBase *icd_surface, 371971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkSurfaceCapabilitiesKHR *caps) 372971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 373971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_connection_t *conn = x11_surface_get_connection(icd_surface); 374971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_window_t window = x11_surface_get_window(icd_surface); 375971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_get_geometry_cookie_t geom_cookie; 376971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_generic_error_t *err; 377971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_get_geometry_reply_t *geom; 378971523410fd2235e13c617b6a1569f70486258d7Dave Airlie unsigned visual_depth; 379971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 380971523410fd2235e13c617b6a1569f70486258d7Dave Airlie geom_cookie = xcb_get_geometry(conn, window); 381971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 382971523410fd2235e13c617b6a1569f70486258d7Dave Airlie /* This does a round-trip. This is why we do get_geometry first and 383971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * wait to read the reply until after we have a visual. 384971523410fd2235e13c617b6a1569f70486258d7Dave Airlie */ 385971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_visualtype_t *visual = 386971523410fd2235e13c617b6a1569f70486258d7Dave Airlie get_visualtype_for_window(conn, window, &visual_depth); 387971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 38801dd363e671ac3a457bc3ff60b43b04e108c33fcArda Coskunses if (!visual) 38901dd363e671ac3a457bc3ff60b43b04e108c33fcArda Coskunses return VK_ERROR_SURFACE_LOST_KHR; 39001dd363e671ac3a457bc3ff60b43b04e108c33fcArda Coskunses 391971523410fd2235e13c617b6a1569f70486258d7Dave Airlie geom = xcb_get_geometry_reply(conn, geom_cookie, &err); 392971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (geom) { 393971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkExtent2D extent = { geom->width, geom->height }; 394971523410fd2235e13c617b6a1569f70486258d7Dave Airlie caps->currentExtent = extent; 395971523410fd2235e13c617b6a1569f70486258d7Dave Airlie caps->minImageExtent = extent; 396971523410fd2235e13c617b6a1569f70486258d7Dave Airlie caps->maxImageExtent = extent; 397971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } else { 398971523410fd2235e13c617b6a1569f70486258d7Dave Airlie /* This can happen if the client didn't wait for the configure event 399971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * to come back from the compositor. In that case, we don't know the 400971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * size of the window so we just return valid "I don't know" stuff. 401971523410fd2235e13c617b6a1569f70486258d7Dave Airlie */ 402971523410fd2235e13c617b6a1569f70486258d7Dave Airlie caps->currentExtent = (VkExtent2D) { -1, -1 }; 403971523410fd2235e13c617b6a1569f70486258d7Dave Airlie caps->minImageExtent = (VkExtent2D) { 1, 1 }; 404e79043bbb9499b3f29b84acff3664e2a85b95a9dJason Ekstrand /* This is the maximum supported size on Intel */ 405e79043bbb9499b3f29b84acff3664e2a85b95a9dJason Ekstrand caps->maxImageExtent = (VkExtent2D) { 1 << 14, 1 << 14 }; 406971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 407971523410fd2235e13c617b6a1569f70486258d7Dave Airlie free(err); 408971523410fd2235e13c617b6a1569f70486258d7Dave Airlie free(geom); 409971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 410971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (visual_has_alpha(visual, visual_depth)) { 411971523410fd2235e13c617b6a1569f70486258d7Dave Airlie caps->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR | 412971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR; 413971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } else { 414971523410fd2235e13c617b6a1569f70486258d7Dave Airlie caps->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR | 415971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; 416971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 417971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 4184fa0ca80eeeac813affcbb0129ed61f1534d8df0Jason Ekstrand /* For true mailbox mode, we need at least 4 images: 4194fa0ca80eeeac813affcbb0129ed61f1534d8df0Jason Ekstrand * 1) One to scan out from 4204fa0ca80eeeac813affcbb0129ed61f1534d8df0Jason Ekstrand * 2) One to have queued for scan-out 4214fa0ca80eeeac813affcbb0129ed61f1534d8df0Jason Ekstrand * 3) One to be currently held by the X server 4224fa0ca80eeeac813affcbb0129ed61f1534d8df0Jason Ekstrand * 4) One to render to 4234fa0ca80eeeac813affcbb0129ed61f1534d8df0Jason Ekstrand */ 424971523410fd2235e13c617b6a1569f70486258d7Dave Airlie caps->minImageCount = 2; 4254fa0ca80eeeac813affcbb0129ed61f1534d8df0Jason Ekstrand /* There is no real maximum */ 4264fa0ca80eeeac813affcbb0129ed61f1534d8df0Jason Ekstrand caps->maxImageCount = 0; 4274fa0ca80eeeac813affcbb0129ed61f1534d8df0Jason Ekstrand 428971523410fd2235e13c617b6a1569f70486258d7Dave Airlie caps->supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; 429971523410fd2235e13c617b6a1569f70486258d7Dave Airlie caps->currentTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; 430971523410fd2235e13c617b6a1569f70486258d7Dave Airlie caps->maxImageArrayLayers = 1; 431971523410fd2235e13c617b6a1569f70486258d7Dave Airlie caps->supportedUsageFlags = 432971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 433971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VK_IMAGE_USAGE_SAMPLED_BIT | 434971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VK_IMAGE_USAGE_TRANSFER_DST_BIT | 435971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 436971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 437971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 438971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 439971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 440971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic VkResult 441971523410fd2235e13c617b6a1569f70486258d7Dave Airliex11_surface_get_formats(VkIcdSurfaceBase *surface, 442ec0bc14a700c2503d834ac0763f4cfbe312998faDave Airlie struct wsi_device *wsi_device, 443971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t *pSurfaceFormatCount, 444971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkSurfaceFormatKHR *pSurfaceFormats) 445971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 446971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (pSurfaceFormats == NULL) { 447971523410fd2235e13c617b6a1569f70486258d7Dave Airlie *pSurfaceFormatCount = ARRAY_SIZE(formats); 448971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 449971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 450971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 451129da274261b6e79f459e24428591f137bf92ed1Eduardo Lima Mitev *pSurfaceFormatCount = MIN2(*pSurfaceFormatCount, ARRAY_SIZE(formats)); 452971523410fd2235e13c617b6a1569f70486258d7Dave Airlie typed_memcpy(pSurfaceFormats, formats, *pSurfaceFormatCount); 453971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 454129da274261b6e79f459e24428591f137bf92ed1Eduardo Lima Mitev return *pSurfaceFormatCount < ARRAY_SIZE(formats) ? 455129da274261b6e79f459e24428591f137bf92ed1Eduardo Lima Mitev VK_INCOMPLETE : VK_SUCCESS; 456971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 457971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 458971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic VkResult 459971523410fd2235e13c617b6a1569f70486258d7Dave Airliex11_surface_get_present_modes(VkIcdSurfaceBase *surface, 460971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t *pPresentModeCount, 461971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkPresentModeKHR *pPresentModes) 462971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 463971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (pPresentModes == NULL) { 464971523410fd2235e13c617b6a1569f70486258d7Dave Airlie *pPresentModeCount = ARRAY_SIZE(present_modes); 465971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 466971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 467971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 468b677b99db5c48ffd1eeef538b962080ac5fd65d9Eduardo Lima Mitev *pPresentModeCount = MIN2(*pPresentModeCount, ARRAY_SIZE(present_modes)); 469971523410fd2235e13c617b6a1569f70486258d7Dave Airlie typed_memcpy(pPresentModes, present_modes, *pPresentModeCount); 470971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 471b677b99db5c48ffd1eeef538b962080ac5fd65d9Eduardo Lima Mitev return *pPresentModeCount < ARRAY_SIZE(present_modes) ? 472b677b99db5c48ffd1eeef538b962080ac5fd65d9Eduardo Lima Mitev VK_INCOMPLETE : VK_SUCCESS; 473971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 474971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 475ec0bc14a700c2503d834ac0763f4cfbe312998faDave AirlieVkResult wsi_create_xcb_surface(const VkAllocationCallbacks *pAllocator, 476971523410fd2235e13c617b6a1569f70486258d7Dave Airlie const VkXcbSurfaceCreateInfoKHR *pCreateInfo, 477971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkSurfaceKHR *pSurface) 478971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 479971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkIcdSurfaceXcb *surface; 480971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 481971523410fd2235e13c617b6a1569f70486258d7Dave Airlie surface = vk_alloc(pAllocator, sizeof *surface, 8, 482971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 483971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (surface == NULL) 484971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_ERROR_OUT_OF_HOST_MEMORY; 485971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 486971523410fd2235e13c617b6a1569f70486258d7Dave Airlie surface->base.platform = VK_ICD_WSI_PLATFORM_XCB; 487971523410fd2235e13c617b6a1569f70486258d7Dave Airlie surface->connection = pCreateInfo->connection; 488971523410fd2235e13c617b6a1569f70486258d7Dave Airlie surface->window = pCreateInfo->window; 489971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 490c085bfcec9915879e97a33c5235cf21607c72318Chad Versace *pSurface = VkIcdSurfaceBase_to_handle(&surface->base); 491971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 492971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 493971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 494ec0bc14a700c2503d834ac0763f4cfbe312998faDave AirlieVkResult wsi_create_xlib_surface(const VkAllocationCallbacks *pAllocator, 495971523410fd2235e13c617b6a1569f70486258d7Dave Airlie const VkXlibSurfaceCreateInfoKHR *pCreateInfo, 496971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkSurfaceKHR *pSurface) 497971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 498971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkIcdSurfaceXlib *surface; 499971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 500971523410fd2235e13c617b6a1569f70486258d7Dave Airlie surface = vk_alloc(pAllocator, sizeof *surface, 8, 501971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 502971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (surface == NULL) 503971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_ERROR_OUT_OF_HOST_MEMORY; 504971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 505971523410fd2235e13c617b6a1569f70486258d7Dave Airlie surface->base.platform = VK_ICD_WSI_PLATFORM_XLIB; 506971523410fd2235e13c617b6a1569f70486258d7Dave Airlie surface->dpy = pCreateInfo->dpy; 507971523410fd2235e13c617b6a1569f70486258d7Dave Airlie surface->window = pCreateInfo->window; 508971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 509c085bfcec9915879e97a33c5235cf21607c72318Chad Versace *pSurface = VkIcdSurfaceBase_to_handle(&surface->base); 510971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 511971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 512971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 513971523410fd2235e13c617b6a1569f70486258d7Dave Airliestruct x11_image { 514971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkImage image; 515971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkDeviceMemory memory; 516971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_pixmap_t pixmap; 517971523410fd2235e13c617b6a1569f70486258d7Dave Airlie bool busy; 518971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct xshmfence * shm_fence; 519971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t sync_fence; 520971523410fd2235e13c617b6a1569f70486258d7Dave Airlie}; 521971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 522971523410fd2235e13c617b6a1569f70486258d7Dave Airliestruct x11_swapchain { 523ec0bc14a700c2503d834ac0763f4cfbe312998faDave Airlie struct wsi_swapchain base; 524971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 525971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_connection_t * conn; 526971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_window_t window; 527971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_gc_t gc; 528972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund uint32_t depth; 529971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkExtent2D extent; 530971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t image_count; 531971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 532971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_present_event_t event_id; 533971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_special_event_t * special_event; 534971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint64_t send_sbc; 535e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand uint64_t last_present_msc; 536971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t stamp; 537971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 538e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand bool threaded; 539e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand VkResult status; 540e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand struct wsi_queue present_queue; 541e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand struct wsi_queue acquire_queue; 542e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand pthread_t queue_manager; 543e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 544971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct x11_image images[0]; 545971523410fd2235e13c617b6a1569f70486258d7Dave Airlie}; 546971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 547971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic VkResult 548ec0bc14a700c2503d834ac0763f4cfbe312998faDave Airliex11_get_images(struct wsi_swapchain *anv_chain, 549971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t* pCount, VkImage *pSwapchainImages) 550971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 551971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain; 552253fa25d09b77e18f736b97da07d57be0e6c4200Dave Airlie uint32_t ret_count; 553253fa25d09b77e18f736b97da07d57be0e6c4200Dave Airlie VkResult result; 554971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 555971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (pSwapchainImages == NULL) { 556971523410fd2235e13c617b6a1569f70486258d7Dave Airlie *pCount = chain->image_count; 557971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 558971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 559971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 560253fa25d09b77e18f736b97da07d57be0e6c4200Dave Airlie result = VK_SUCCESS; 561253fa25d09b77e18f736b97da07d57be0e6c4200Dave Airlie ret_count = chain->image_count; 562253fa25d09b77e18f736b97da07d57be0e6c4200Dave Airlie if (chain->image_count > *pCount) { 563253fa25d09b77e18f736b97da07d57be0e6c4200Dave Airlie ret_count = *pCount; 564253fa25d09b77e18f736b97da07d57be0e6c4200Dave Airlie result = VK_INCOMPLETE; 565253fa25d09b77e18f736b97da07d57be0e6c4200Dave Airlie } 566971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 567253fa25d09b77e18f736b97da07d57be0e6c4200Dave Airlie for (uint32_t i = 0; i < ret_count; i++) 568253fa25d09b77e18f736b97da07d57be0e6c4200Dave Airlie pSwapchainImages[i] = chain->images[i].image; 569971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 570253fa25d09b77e18f736b97da07d57be0e6c4200Dave Airlie return result; 571971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 572971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 573971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic VkResult 574971523410fd2235e13c617b6a1569f70486258d7Dave Airliex11_handle_dri3_present_event(struct x11_swapchain *chain, 575971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_present_generic_event_t *event) 576971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 577971523410fd2235e13c617b6a1569f70486258d7Dave Airlie switch (event->evtype) { 578971523410fd2235e13c617b6a1569f70486258d7Dave Airlie case XCB_PRESENT_CONFIGURE_NOTIFY: { 579971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_present_configure_notify_event_t *config = (void *) event; 580971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 581971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (config->width != chain->extent.width || 582971523410fd2235e13c617b6a1569f70486258d7Dave Airlie config->height != chain->extent.height) 583971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_ERROR_OUT_OF_DATE_KHR; 584971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 585971523410fd2235e13c617b6a1569f70486258d7Dave Airlie break; 586971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 587971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 588971523410fd2235e13c617b6a1569f70486258d7Dave Airlie case XCB_PRESENT_EVENT_IDLE_NOTIFY: { 589971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_present_idle_notify_event_t *idle = (void *) event; 590971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 591971523410fd2235e13c617b6a1569f70486258d7Dave Airlie for (unsigned i = 0; i < chain->image_count; i++) { 592971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (chain->images[i].pixmap == idle->pixmap) { 593971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->images[i].busy = false; 594e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand if (chain->threaded) 595e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand wsi_queue_push(&chain->acquire_queue, i); 596971523410fd2235e13c617b6a1569f70486258d7Dave Airlie break; 597971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 598971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 599971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 600971523410fd2235e13c617b6a1569f70486258d7Dave Airlie break; 601971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 602971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 603e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand case XCB_PRESENT_EVENT_COMPLETE_NOTIFY: { 604e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand xcb_present_complete_notify_event_t *complete = (void *) event; 605e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand if (complete->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP) 606e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand chain->last_present_msc = complete->msc; 607e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand break; 608e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } 609e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 610971523410fd2235e13c617b6a1569f70486258d7Dave Airlie default: 611971523410fd2235e13c617b6a1569f70486258d7Dave Airlie break; 612971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 613971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 614971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 615971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 616971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 617787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie 618787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airliestatic uint64_t wsi_get_current_time(void) 619787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie{ 620787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie uint64_t current_time; 621787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie struct timespec tv; 622787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie 623787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie clock_gettime(CLOCK_MONOTONIC, &tv); 624787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie current_time = tv.tv_nsec + tv.tv_sec*1000000000ull; 625787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie return current_time; 626787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie} 627787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie 628787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airliestatic uint64_t wsi_get_absolute_timeout(uint64_t timeout) 629787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie{ 630787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie uint64_t current_time = wsi_get_current_time(); 631787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie 632787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie timeout = MIN2(UINT64_MAX - current_time, timeout); 633787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie 634787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie return current_time + timeout; 635787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie} 636787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie 637971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic VkResult 638e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrandx11_acquire_next_image_poll_x11(struct x11_swapchain *chain, 639e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand uint32_t *image_index, uint64_t timeout) 640971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 641787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie xcb_generic_event_t *event; 642787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie struct pollfd pfds; 643787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie uint64_t atimeout; 644971523410fd2235e13c617b6a1569f70486258d7Dave Airlie while (1) { 645971523410fd2235e13c617b6a1569f70486258d7Dave Airlie for (uint32_t i = 0; i < chain->image_count; i++) { 646971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (!chain->images[i].busy) { 647971523410fd2235e13c617b6a1569f70486258d7Dave Airlie /* We found a non-busy image */ 648971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xshmfence_await(chain->images[i].shm_fence); 649971523410fd2235e13c617b6a1569f70486258d7Dave Airlie *image_index = i; 650971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->images[i].busy = true; 651971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 652971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 653971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 654971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 655971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_flush(chain->conn); 656787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie 657787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie if (timeout == UINT64_MAX) { 658787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie event = xcb_wait_for_special_event(chain->conn, chain->special_event); 659787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie if (!event) 660787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie return VK_ERROR_OUT_OF_DATE_KHR; 661787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie } else { 662787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie event = xcb_poll_for_special_event(chain->conn, chain->special_event); 663787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie if (!event) { 664787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie int ret; 665787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie if (timeout == 0) 666787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie return VK_NOT_READY; 667787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie 668787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie atimeout = wsi_get_absolute_timeout(timeout); 669787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie 670787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie pfds.fd = xcb_get_file_descriptor(chain->conn); 671787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie pfds.events = POLLIN; 672787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie ret = poll(&pfds, 1, timeout / 1000 / 1000); 673787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie if (ret == 0) 674787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie return VK_TIMEOUT; 675787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie if (ret == -1) 676787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie return VK_ERROR_OUT_OF_DATE_KHR; 677787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie 678787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie /* If a non-special event happens, the fd will still 679787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie * poll. So recalculate the timeout now just in case. 680787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie */ 681787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie uint64_t current_time = wsi_get_current_time(); 682787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie if (atimeout > current_time) 683787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie timeout = atimeout - current_time; 684787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie else 685787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie timeout = 0; 686787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie continue; 687787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie } 688787c172aed0ae88ca6a8c1a193d9dd744fbdc918Dave Airlie } 689971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 690971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkResult result = x11_handle_dri3_present_event(chain, (void *)event); 691971523410fd2235e13c617b6a1569f70486258d7Dave Airlie free(event); 692971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (result != VK_SUCCESS) 693971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return result; 694971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 695971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 696971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 697971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic VkResult 698e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrandx11_acquire_next_image_from_queue(struct x11_swapchain *chain, 699e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand uint32_t *image_index_out, uint64_t timeout) 700e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand{ 701e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand assert(chain->threaded); 702e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 703e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand uint32_t image_index; 704e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand VkResult result = wsi_queue_pull(&chain->acquire_queue, 705e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand &image_index, timeout); 706e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand if (result != VK_SUCCESS) { 707e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand return result; 708e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } else if (chain->status != VK_SUCCESS) { 709e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand return chain->status; 710e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } 711e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 712e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand assert(image_index < chain->image_count); 713e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand xshmfence_await(chain->images[image_index].shm_fence); 714e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 715e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand *image_index_out = image_index; 716e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 717e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand return VK_SUCCESS; 718e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand} 719e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 720e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrandstatic VkResult 721e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrandx11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index, 722e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand uint32_t target_msc) 723971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 724971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct x11_image *image = &chain->images[image_index]; 725971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 726971523410fd2235e13c617b6a1569f70486258d7Dave Airlie assert(image_index < chain->image_count); 727971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 728971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t options = XCB_PRESENT_OPTION_NONE; 729971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 730971523410fd2235e13c617b6a1569f70486258d7Dave Airlie int64_t divisor = 0; 731971523410fd2235e13c617b6a1569f70486258d7Dave Airlie int64_t remainder = 0; 732971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 733ca035006c86a5055c8e640f49c858f04770681ebDave Airlie if (chain->base.present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR) 734ca035006c86a5055c8e640f49c858f04770681ebDave Airlie options |= XCB_PRESENT_OPTION_ASYNC; 735971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 736971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xshmfence_reset(image->shm_fence); 737971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 738971523410fd2235e13c617b6a1569f70486258d7Dave Airlie ++chain->send_sbc; 739971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_void_cookie_t cookie = 740971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_present_pixmap(chain->conn, 741971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->window, 742971523410fd2235e13c617b6a1569f70486258d7Dave Airlie image->pixmap, 743971523410fd2235e13c617b6a1569f70486258d7Dave Airlie (uint32_t) chain->send_sbc, 744971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 0, /* valid */ 745971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 0, /* update */ 746971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 0, /* x_off */ 747971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 0, /* y_off */ 748971523410fd2235e13c617b6a1569f70486258d7Dave Airlie XCB_NONE, /* target_crtc */ 749971523410fd2235e13c617b6a1569f70486258d7Dave Airlie XCB_NONE, 750971523410fd2235e13c617b6a1569f70486258d7Dave Airlie image->sync_fence, 751971523410fd2235e13c617b6a1569f70486258d7Dave Airlie options, 752971523410fd2235e13c617b6a1569f70486258d7Dave Airlie target_msc, 753971523410fd2235e13c617b6a1569f70486258d7Dave Airlie divisor, 754971523410fd2235e13c617b6a1569f70486258d7Dave Airlie remainder, 0, NULL); 755971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_discard_reply(chain->conn, cookie.sequence); 756971523410fd2235e13c617b6a1569f70486258d7Dave Airlie image->busy = true; 757971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 758971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_flush(chain->conn); 759971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 760971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 761971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 762971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 763971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic VkResult 764e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrandx11_acquire_next_image(struct wsi_swapchain *anv_chain, 765e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand uint64_t timeout, 766e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand VkSemaphore semaphore, 767e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand uint32_t *image_index) 768e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand{ 769e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain; 770e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 771e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand if (chain->threaded) { 772e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand return x11_acquire_next_image_from_queue(chain, image_index, timeout); 773e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } else { 774e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand return x11_acquire_next_image_poll_x11(chain, image_index, timeout); 775e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } 776e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand} 777e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 778e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrandstatic VkResult 779e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrandx11_queue_present(struct wsi_swapchain *anv_chain, 780e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand uint32_t image_index) 781e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand{ 782e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain; 783e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 784e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand if (chain->threaded) { 785e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand wsi_queue_push(&chain->present_queue, image_index); 786e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand return chain->status; 787e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } else { 788e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand return x11_present_to_x11(chain, image_index, 0); 789e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } 790e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand} 791e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 792e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrandstatic void * 793e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrandx11_manage_fifo_queues(void *state) 794e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand{ 795e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand struct x11_swapchain *chain = state; 796e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand VkResult result; 797e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 798e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand assert(chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR); 799e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 800e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand while (chain->status == VK_SUCCESS) { 801e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand /* It should be safe to unconditionally block here. Later in the loop 802e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand * we blocks until the previous present has landed on-screen. At that 803e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand * point, we should have received IDLE_NOTIFY on all images presented 804e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand * before that point so the client should be able to acquire any image 805e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand * other than the currently presented one. 806e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand */ 807e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand uint32_t image_index; 808e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand result = wsi_queue_pull(&chain->present_queue, &image_index, INT64_MAX); 809e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand if (result != VK_SUCCESS) { 810e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand goto fail; 811e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } else if (chain->status != VK_SUCCESS) { 812e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand return NULL; 813e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } 814e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 815e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand uint64_t target_msc = chain->last_present_msc + 1; 816e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand result = x11_present_to_x11(chain, image_index, target_msc); 817e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand if (result != VK_SUCCESS) 818e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand goto fail; 819e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 820e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand while (chain->last_present_msc < target_msc) { 821e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand xcb_generic_event_t *event = 822e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand xcb_wait_for_special_event(chain->conn, chain->special_event); 823e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand if (!event) 824e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand goto fail; 825e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 826e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand result = x11_handle_dri3_present_event(chain, (void *)event); 827e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand if (result != VK_SUCCESS) 828e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand goto fail; 829e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } 830e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } 831e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 832e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrandfail: 833e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand chain->status = result; 834e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand wsi_queue_push(&chain->acquire_queue, UINT32_MAX); 835e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 836e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand return NULL; 837e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand} 838e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 839e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrandstatic VkResult 840971523410fd2235e13c617b6a1569f70486258d7Dave Airliex11_image_init(VkDevice device_h, struct x11_swapchain *chain, 841971523410fd2235e13c617b6a1569f70486258d7Dave Airlie const VkSwapchainCreateInfoKHR *pCreateInfo, 842971523410fd2235e13c617b6a1569f70486258d7Dave Airlie const VkAllocationCallbacks* pAllocator, 843971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct x11_image *image) 844971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 845971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_void_cookie_t cookie; 846971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkResult result; 847971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t row_pitch; 848971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t offset; 849971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t bpp = 32; 850971523410fd2235e13c617b6a1569f70486258d7Dave Airlie int fd; 851971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t size; 852971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 853971523410fd2235e13c617b6a1569f70486258d7Dave Airlie result = chain->base.image_fns->create_wsi_image(device_h, 854971523410fd2235e13c617b6a1569f70486258d7Dave Airlie pCreateInfo, 855971523410fd2235e13c617b6a1569f70486258d7Dave Airlie pAllocator, 856971523410fd2235e13c617b6a1569f70486258d7Dave Airlie &image->image, 857971523410fd2235e13c617b6a1569f70486258d7Dave Airlie &image->memory, 858971523410fd2235e13c617b6a1569f70486258d7Dave Airlie &size, 859971523410fd2235e13c617b6a1569f70486258d7Dave Airlie &offset, 860971523410fd2235e13c617b6a1569f70486258d7Dave Airlie &row_pitch, 861971523410fd2235e13c617b6a1569f70486258d7Dave Airlie &fd); 862971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (result != VK_SUCCESS) 863971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return result; 864971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 865971523410fd2235e13c617b6a1569f70486258d7Dave Airlie image->pixmap = xcb_generate_id(chain->conn); 866971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 867971523410fd2235e13c617b6a1569f70486258d7Dave Airlie cookie = 868971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_dri3_pixmap_from_buffer_checked(chain->conn, 869971523410fd2235e13c617b6a1569f70486258d7Dave Airlie image->pixmap, 870971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->window, 871971523410fd2235e13c617b6a1569f70486258d7Dave Airlie size, 872971523410fd2235e13c617b6a1569f70486258d7Dave Airlie pCreateInfo->imageExtent.width, 873971523410fd2235e13c617b6a1569f70486258d7Dave Airlie pCreateInfo->imageExtent.height, 874971523410fd2235e13c617b6a1569f70486258d7Dave Airlie row_pitch, 875972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund chain->depth, bpp, fd); 876971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_discard_reply(chain->conn, cookie.sequence); 877971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 878971523410fd2235e13c617b6a1569f70486258d7Dave Airlie int fence_fd = xshmfence_alloc_shm(); 879971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (fence_fd < 0) 880971523410fd2235e13c617b6a1569f70486258d7Dave Airlie goto fail_pixmap; 881971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 882971523410fd2235e13c617b6a1569f70486258d7Dave Airlie image->shm_fence = xshmfence_map_shm(fence_fd); 883971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (image->shm_fence == NULL) 884971523410fd2235e13c617b6a1569f70486258d7Dave Airlie goto fail_shmfence_alloc; 885971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 886971523410fd2235e13c617b6a1569f70486258d7Dave Airlie image->sync_fence = xcb_generate_id(chain->conn); 887971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_dri3_fence_from_fd(chain->conn, 888971523410fd2235e13c617b6a1569f70486258d7Dave Airlie image->pixmap, 889971523410fd2235e13c617b6a1569f70486258d7Dave Airlie image->sync_fence, 890971523410fd2235e13c617b6a1569f70486258d7Dave Airlie false, 891971523410fd2235e13c617b6a1569f70486258d7Dave Airlie fence_fd); 892971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 893971523410fd2235e13c617b6a1569f70486258d7Dave Airlie image->busy = false; 894971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xshmfence_trigger(image->shm_fence); 895971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 896971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 897971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 898971523410fd2235e13c617b6a1569f70486258d7Dave Airliefail_shmfence_alloc: 899971523410fd2235e13c617b6a1569f70486258d7Dave Airlie close(fence_fd); 900971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 901971523410fd2235e13c617b6a1569f70486258d7Dave Airliefail_pixmap: 902971523410fd2235e13c617b6a1569f70486258d7Dave Airlie cookie = xcb_free_pixmap(chain->conn, image->pixmap); 903971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_discard_reply(chain->conn, cookie.sequence); 904971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 905971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->base.image_fns->free_wsi_image(device_h, pAllocator, 906971523410fd2235e13c617b6a1569f70486258d7Dave Airlie image->image, image->memory); 907971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 908971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return result; 909971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 910971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 911971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic void 912971523410fd2235e13c617b6a1569f70486258d7Dave Airliex11_image_finish(struct x11_swapchain *chain, 913971523410fd2235e13c617b6a1569f70486258d7Dave Airlie const VkAllocationCallbacks* pAllocator, 914971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct x11_image *image) 915971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 916971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_void_cookie_t cookie; 917971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 918971523410fd2235e13c617b6a1569f70486258d7Dave Airlie cookie = xcb_sync_destroy_fence(chain->conn, image->sync_fence); 919971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_discard_reply(chain->conn, cookie.sequence); 920971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xshmfence_unmap_shm(image->shm_fence); 921971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 922971523410fd2235e13c617b6a1569f70486258d7Dave Airlie cookie = xcb_free_pixmap(chain->conn, image->pixmap); 923971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_discard_reply(chain->conn, cookie.sequence); 924971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 925971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->base.image_fns->free_wsi_image(chain->base.device, pAllocator, 926971523410fd2235e13c617b6a1569f70486258d7Dave Airlie image->image, image->memory); 927971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 928971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 929971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic VkResult 930ec0bc14a700c2503d834ac0763f4cfbe312998faDave Airliex11_swapchain_destroy(struct wsi_swapchain *anv_chain, 931971523410fd2235e13c617b6a1569f70486258d7Dave Airlie const VkAllocationCallbacks *pAllocator) 932971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 933971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain; 934550cd272b4b97fc06dbd3b5fad2bf0e5d526236dMichel Dänzer xcb_void_cookie_t cookie; 935550cd272b4b97fc06dbd3b5fad2bf0e5d526236dMichel Dänzer 936971523410fd2235e13c617b6a1569f70486258d7Dave Airlie for (uint32_t i = 0; i < chain->image_count; i++) 937971523410fd2235e13c617b6a1569f70486258d7Dave Airlie x11_image_finish(chain, pAllocator, &chain->images[i]); 938971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 939e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand if (chain->threaded) { 940e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand chain->status = VK_ERROR_OUT_OF_DATE_KHR; 941e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand /* Push a UINT32_MAX to wake up the manager */ 942e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand wsi_queue_push(&chain->present_queue, UINT32_MAX); 943e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand pthread_join(chain->queue_manager, NULL); 944e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand wsi_queue_destroy(&chain->acquire_queue); 945e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand wsi_queue_destroy(&chain->present_queue); 946e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } 947e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 948971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_unregister_for_special_event(chain->conn, chain->special_event); 949550cd272b4b97fc06dbd3b5fad2bf0e5d526236dMichel Dänzer cookie = xcb_present_select_input_checked(chain->conn, chain->event_id, 950550cd272b4b97fc06dbd3b5fad2bf0e5d526236dMichel Dänzer chain->window, 951550cd272b4b97fc06dbd3b5fad2bf0e5d526236dMichel Dänzer XCB_PRESENT_EVENT_MASK_NO_EVENT); 952550cd272b4b97fc06dbd3b5fad2bf0e5d526236dMichel Dänzer xcb_discard_reply(chain->conn, cookie.sequence); 953971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 954971523410fd2235e13c617b6a1569f70486258d7Dave Airlie vk_free(pAllocator, chain); 955971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 956971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 957971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 958971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 959971523410fd2235e13c617b6a1569f70486258d7Dave Airliestatic VkResult 960971523410fd2235e13c617b6a1569f70486258d7Dave Airliex11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, 961971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkDevice device, 962ec0bc14a700c2503d834ac0763f4cfbe312998faDave Airlie struct wsi_device *wsi_device, 963971523410fd2235e13c617b6a1569f70486258d7Dave Airlie const VkSwapchainCreateInfoKHR *pCreateInfo, 964971523410fd2235e13c617b6a1569f70486258d7Dave Airlie const VkAllocationCallbacks* pAllocator, 965ec0bc14a700c2503d834ac0763f4cfbe312998faDave Airlie const struct wsi_image_fns *image_fns, 966ec0bc14a700c2503d834ac0763f4cfbe312998faDave Airlie struct wsi_swapchain **swapchain_out) 967971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 968971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct x11_swapchain *chain; 969971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_void_cookie_t cookie; 970971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkResult result; 971971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 972971523410fd2235e13c617b6a1569f70486258d7Dave Airlie assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR); 973971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 9744fa0ca80eeeac813affcbb0129ed61f1534d8df0Jason Ekstrand const unsigned num_images = pCreateInfo->minImageCount; 975971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 976971523410fd2235e13c617b6a1569f70486258d7Dave Airlie size_t size = sizeof(*chain) + num_images * sizeof(chain->images[0]); 977971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain = vk_alloc(pAllocator, size, 8, 978971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 979971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (chain == NULL) 980971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_ERROR_OUT_OF_HOST_MEMORY; 981971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 982972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund xcb_connection_t *conn = x11_surface_get_connection(icd_surface); 983972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund xcb_window_t window = x11_surface_get_window(icd_surface); 984972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund xcb_get_geometry_reply_t *geometry = 985972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund xcb_get_geometry_reply(conn, xcb_get_geometry(conn, window), NULL); 986972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund 987972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund if (geometry == NULL) 988972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund return VK_ERROR_SURFACE_LOST_KHR; 989972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund 990971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->base.device = device; 991971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->base.destroy = x11_swapchain_destroy; 992971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->base.get_images = x11_get_images; 993971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->base.acquire_next_image = x11_acquire_next_image; 994971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->base.queue_present = x11_queue_present; 995971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->base.image_fns = image_fns; 9961cdca1eb16ab33da338dda076794efd4bf859f7bDave Airlie chain->base.present_mode = pCreateInfo->presentMode; 997972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund chain->conn = conn; 998972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund chain->window = window; 999972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund chain->depth = geometry->depth; 1000971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->extent = pCreateInfo->imageExtent; 1001971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->image_count = num_images; 1002971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->send_sbc = 0; 1003e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand chain->last_present_msc = 0; 1004e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand chain->threaded = false; 1005e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand chain->status = VK_SUCCESS; 1006971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1007972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund free(geometry); 1008972670c2007c1c5a51b4f0876d31476858f79351Fredrik Höglund 1009971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->event_id = xcb_generate_id(chain->conn); 1010971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_present_select_input(chain->conn, chain->event_id, chain->window, 1011971523410fd2235e13c617b6a1569f70486258d7Dave Airlie XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY | 1012971523410fd2235e13c617b6a1569f70486258d7Dave Airlie XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY | 1013971523410fd2235e13c617b6a1569f70486258d7Dave Airlie XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY); 1014971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1015971523410fd2235e13c617b6a1569f70486258d7Dave Airlie /* Create an XCB event queue to hold present events outside of the usual 1016971523410fd2235e13c617b6a1569f70486258d7Dave Airlie * application event queue 1017971523410fd2235e13c617b6a1569f70486258d7Dave Airlie */ 1018971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->special_event = 1019971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_register_for_special_xge(chain->conn, &xcb_present_id, 1020971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->event_id, NULL); 1021971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1022971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->gc = xcb_generate_id(chain->conn); 1023971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (!chain->gc) { 1024971523410fd2235e13c617b6a1569f70486258d7Dave Airlie /* FINISHME: Choose a better error. */ 1025971523410fd2235e13c617b6a1569f70486258d7Dave Airlie result = VK_ERROR_OUT_OF_HOST_MEMORY; 1026971523410fd2235e13c617b6a1569f70486258d7Dave Airlie goto fail_register; 1027971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 1028971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1029971523410fd2235e13c617b6a1569f70486258d7Dave Airlie cookie = xcb_create_gc(chain->conn, 1030971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->gc, 1031971523410fd2235e13c617b6a1569f70486258d7Dave Airlie chain->window, 1032971523410fd2235e13c617b6a1569f70486258d7Dave Airlie XCB_GC_GRAPHICS_EXPOSURES, 1033971523410fd2235e13c617b6a1569f70486258d7Dave Airlie (uint32_t []) { 0 }); 1034971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_discard_reply(chain->conn, cookie.sequence); 1035971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1036971523410fd2235e13c617b6a1569f70486258d7Dave Airlie uint32_t image = 0; 1037971523410fd2235e13c617b6a1569f70486258d7Dave Airlie for (; image < chain->image_count; image++) { 1038971523410fd2235e13c617b6a1569f70486258d7Dave Airlie result = x11_image_init(device, chain, pCreateInfo, pAllocator, 1039971523410fd2235e13c617b6a1569f70486258d7Dave Airlie &chain->images[image]); 1040971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (result != VK_SUCCESS) 1041971523410fd2235e13c617b6a1569f70486258d7Dave Airlie goto fail_init_images; 1042971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 1043971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1044e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand if (chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR) { 1045e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand chain->threaded = true; 1046e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 1047e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand /* Initialize our queues. We make them image_count + 1 because we will 1048e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand * occasionally use UINT32_MAX to signal the other thread that an error 1049e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand * has occurred and we don't want an overflow. 1050e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand */ 1051e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand int ret; 1052e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand ret = wsi_queue_init(&chain->acquire_queue, chain->image_count + 1); 1053e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand if (ret) { 1054e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand goto fail_init_images; 1055e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } 1056e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 1057e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand ret = wsi_queue_init(&chain->present_queue, chain->image_count + 1); 1058e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand if (ret) { 1059e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand wsi_queue_destroy(&chain->acquire_queue); 1060e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand goto fail_init_images; 1061e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } 1062e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 1063e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand for (unsigned i = 0; i < chain->image_count; i++) 1064e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand wsi_queue_push(&chain->acquire_queue, i); 1065e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 1066e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand ret = pthread_create(&chain->queue_manager, NULL, 1067e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand x11_manage_fifo_queues, chain); 1068e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand if (ret) { 1069e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand wsi_queue_destroy(&chain->present_queue); 1070e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand wsi_queue_destroy(&chain->acquire_queue); 1071e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand goto fail_init_images; 1072e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } 1073e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand } 1074e73d136a02308088cacab842790c7670e5d07b23Jason Ekstrand 1075971523410fd2235e13c617b6a1569f70486258d7Dave Airlie *swapchain_out = &chain->base; 1076971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1077971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 1078971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1079971523410fd2235e13c617b6a1569f70486258d7Dave Airliefail_init_images: 1080971523410fd2235e13c617b6a1569f70486258d7Dave Airlie for (uint32_t j = 0; j < image; j++) 1081971523410fd2235e13c617b6a1569f70486258d7Dave Airlie x11_image_finish(chain, pAllocator, &chain->images[j]); 1082971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1083971523410fd2235e13c617b6a1569f70486258d7Dave Airliefail_register: 1084971523410fd2235e13c617b6a1569f70486258d7Dave Airlie xcb_unregister_for_special_event(chain->conn, chain->special_event); 1085971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1086971523410fd2235e13c617b6a1569f70486258d7Dave Airlie vk_free(pAllocator, chain); 1087971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1088971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return result; 1089971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 1090971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1091971523410fd2235e13c617b6a1569f70486258d7Dave AirlieVkResult 1092ec0bc14a700c2503d834ac0763f4cfbe312998faDave Airliewsi_x11_init_wsi(struct wsi_device *wsi_device, 1093971523410fd2235e13c617b6a1569f70486258d7Dave Airlie const VkAllocationCallbacks *alloc) 1094971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 1095971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct wsi_x11 *wsi; 1096971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VkResult result; 1097971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1098971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi = vk_alloc(alloc, sizeof(*wsi), 8, 1099971523410fd2235e13c617b6a1569f70486258d7Dave Airlie VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); 1100971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (!wsi) { 1101971523410fd2235e13c617b6a1569f70486258d7Dave Airlie result = VK_ERROR_OUT_OF_HOST_MEMORY; 1102971523410fd2235e13c617b6a1569f70486258d7Dave Airlie goto fail; 1103971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 1104971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1105971523410fd2235e13c617b6a1569f70486258d7Dave Airlie int ret = pthread_mutex_init(&wsi->mutex, NULL); 1106971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (ret != 0) { 1107971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (ret == ENOMEM) { 1108971523410fd2235e13c617b6a1569f70486258d7Dave Airlie result = VK_ERROR_OUT_OF_HOST_MEMORY; 1109971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } else { 1110971523410fd2235e13c617b6a1569f70486258d7Dave Airlie /* FINISHME: Choose a better error. */ 1111971523410fd2235e13c617b6a1569f70486258d7Dave Airlie result = VK_ERROR_OUT_OF_HOST_MEMORY; 1112971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 1113971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1114971523410fd2235e13c617b6a1569f70486258d7Dave Airlie goto fail_alloc; 1115971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 1116971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1117971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi->connections = _mesa_hash_table_create(NULL, _mesa_hash_pointer, 1118971523410fd2235e13c617b6a1569f70486258d7Dave Airlie _mesa_key_pointer_equal); 1119971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (!wsi->connections) { 1120971523410fd2235e13c617b6a1569f70486258d7Dave Airlie result = VK_ERROR_OUT_OF_HOST_MEMORY; 1121971523410fd2235e13c617b6a1569f70486258d7Dave Airlie goto fail_mutex; 1122971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 1123971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1124971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi->base.get_support = x11_surface_get_support; 1125971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi->base.get_capabilities = x11_surface_get_capabilities; 1126971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi->base.get_formats = x11_surface_get_formats; 1127971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi->base.get_present_modes = x11_surface_get_present_modes; 1128971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi->base.create_swapchain = x11_surface_create_swapchain; 1129971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1130971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi_device->wsi[VK_ICD_WSI_PLATFORM_XCB] = &wsi->base; 1131971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi_device->wsi[VK_ICD_WSI_PLATFORM_XLIB] = &wsi->base; 1132971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1133971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return VK_SUCCESS; 1134971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1135971523410fd2235e13c617b6a1569f70486258d7Dave Airliefail_mutex: 1136971523410fd2235e13c617b6a1569f70486258d7Dave Airlie pthread_mutex_destroy(&wsi->mutex); 1137971523410fd2235e13c617b6a1569f70486258d7Dave Airliefail_alloc: 1138971523410fd2235e13c617b6a1569f70486258d7Dave Airlie vk_free(alloc, wsi); 1139971523410fd2235e13c617b6a1569f70486258d7Dave Airliefail: 1140971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi_device->wsi[VK_ICD_WSI_PLATFORM_XCB] = NULL; 1141971523410fd2235e13c617b6a1569f70486258d7Dave Airlie wsi_device->wsi[VK_ICD_WSI_PLATFORM_XLIB] = NULL; 1142971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1143971523410fd2235e13c617b6a1569f70486258d7Dave Airlie return result; 1144971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 1145971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1146971523410fd2235e13c617b6a1569f70486258d7Dave Airlievoid 1147ec0bc14a700c2503d834ac0763f4cfbe312998faDave Airliewsi_x11_finish_wsi(struct wsi_device *wsi_device, 1148971523410fd2235e13c617b6a1569f70486258d7Dave Airlie const VkAllocationCallbacks *alloc) 1149971523410fd2235e13c617b6a1569f70486258d7Dave Airlie{ 1150971523410fd2235e13c617b6a1569f70486258d7Dave Airlie struct wsi_x11 *wsi = 1151971523410fd2235e13c617b6a1569f70486258d7Dave Airlie (struct wsi_x11 *)wsi_device->wsi[VK_ICD_WSI_PLATFORM_XCB]; 1152971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1153971523410fd2235e13c617b6a1569f70486258d7Dave Airlie if (wsi) { 1154daeb21e47845795d0320811db1e202540fba356bJason Ekstrand struct hash_entry *entry; 1155daeb21e47845795d0320811db1e202540fba356bJason Ekstrand hash_table_foreach(wsi->connections, entry) 1156daeb21e47845795d0320811db1e202540fba356bJason Ekstrand wsi_x11_connection_destroy(alloc, entry->data); 1157daeb21e47845795d0320811db1e202540fba356bJason Ekstrand 1158971523410fd2235e13c617b6a1569f70486258d7Dave Airlie _mesa_hash_table_destroy(wsi->connections, NULL); 1159971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1160971523410fd2235e13c617b6a1569f70486258d7Dave Airlie pthread_mutex_destroy(&wsi->mutex); 1161971523410fd2235e13c617b6a1569f70486258d7Dave Airlie 1162971523410fd2235e13c617b6a1569f70486258d7Dave Airlie vk_free(alloc, wsi); 1163971523410fd2235e13c617b6a1569f70486258d7Dave Airlie } 1164971523410fd2235e13c617b6a1569f70486258d7Dave Airlie} 1165