blob: 94f3315bbf8e1ec55c819412cc1e26b5cc222d33 [file] [log] [blame]
Chia-I Wu1db76e02014-09-15 14:21:14 +08001/*
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002 * Vulkan
Chia-I Wu1db76e02014-09-15 14:21:14 +08003 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <unistd.h>
31#include <fcntl.h>
32#include <xcb/xcb.h>
33#include <xcb/dri3.h>
34#include <xcb/present.h>
35
36#include "kmd/winsys.h"
Chia-I Wu8635e912015-04-09 14:13:57 +080037#include "kmd/libdrm/xf86drmMode.h"
Chia-I Wu1db76e02014-09-15 14:21:14 +080038#include "dev.h"
39#include "fence.h"
40#include "gpu.h"
41#include "img.h"
42#include "mem.h"
43#include "queue.h"
Chia-I Wu41858c82015-04-04 16:39:25 +080044#include "wsi.h"
Chia-I Wu1db76e02014-09-15 14:21:14 +080045
Chia-I Wu8635e912015-04-09 14:13:57 +080046struct intel_x11_display {
47 struct intel_handle handle;
48
49 int fd;
50 uint32_t connector_id;
51
52 char name[32];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060053 VK_EXTENT2D physical_dimension;
54 VK_EXTENT2D physical_resolution;
Chia-I Wu8635e912015-04-09 14:13:57 +080055
56 drmModeModeInfoPtr modes;
57 uint32_t mode_count;
58};
59
Chia-I Wu6532d1d2015-04-04 22:16:45 +080060struct intel_x11_swap_chain {
61 struct intel_handle handle;
62
63 xcb_connection_t *c;
64 xcb_window_t window;
Chia-I Wu1db76e02014-09-15 14:21:14 +080065
66 xcb_present_event_t present_special_event_id;
67 xcb_special_event_t *present_special_event;
68
69 struct {
70 uint32_t serial;
71 } local;
72
73 struct {
74 uint32_t serial;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060075 uint64_t msc;
Chia-I Wu1db76e02014-09-15 14:21:14 +080076 } remote;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +080077
Chia-I Wu6532d1d2015-04-04 22:16:45 +080078 struct intel_x11_swap_chain *next;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +080079};
80
81struct intel_wsi_x11 {
Chia-I Wu41858c82015-04-04 16:39:25 +080082 struct intel_handle handle;
83
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +080084 xcb_connection_t *c;
85 xcb_window_t root;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +080086 int root_depth;
87
88 int dri3_major, dri3_minor;
89 int present_major, present_minor;
90
Chia-I Wu6532d1d2015-04-04 22:16:45 +080091 struct intel_x11_swap_chain *swap_chains;
Chia-I Wu1db76e02014-09-15 14:21:14 +080092};
93
Chia-I Wu41858c82015-04-04 16:39:25 +080094struct intel_x11_img_data {
95 struct intel_mem *mem;
96 int prime_fd;
97 uint32_t pixmap;
98};
99
100struct intel_x11_fence_data {
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800101 struct intel_x11_swap_chain *swap_chain;
Chia-I Wu41858c82015-04-04 16:39:25 +0800102 uint32_t serial;
103};
104
Chia-I Wufcbc5252015-04-08 11:44:26 +0800105static bool x11_is_format_presentable(const struct intel_dev *dev,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600106 VK_FORMAT format)
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800107{
108 /* this is what DDX expects */
109 switch (format) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600110 case VK_FMT_B5G6R5_UNORM:
111 case VK_FMT_B8G8R8A8_UNORM:
112 case VK_FMT_B8G8R8A8_SRGB:
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800113 return true;
114 default:
115 return false;
116 }
117}
118
Chia-I Wu030b2db2015-04-08 13:46:29 +0800119static int x11_export_prime_fd(struct intel_dev *dev,
120 struct intel_bo *bo,
121 const struct intel_layout *layout)
122{
123 struct intel_winsys_handle export;
124 enum intel_tiling_mode tiling;
125
126 export.type = INTEL_WINSYS_HANDLE_FD;
127
128 switch (layout->tiling) {
129 case GEN6_TILING_X:
130 tiling = INTEL_TILING_X;
131 break;
132 case GEN6_TILING_Y:
133 tiling = INTEL_TILING_Y;
134 break;
135 default:
136 assert(layout->tiling == GEN6_TILING_NONE);
137 tiling = INTEL_TILING_NONE;
138 break;
139 }
140
141 if (intel_bo_set_tiling(bo, tiling, layout->bo_stride))
142 return -1;
143
144 if (intel_winsys_export_handle(dev->winsys, bo, tiling,
145 layout->bo_stride, layout->bo_height, &export))
146 return -1;
147
148 return (int) export.handle;
149}
150
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800151/**
Chia-I Wufcbc5252015-04-08 11:44:26 +0800152 * Return true if fd points to the primary or render node of the GPU.
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800153 */
Chia-I Wufcbc5252015-04-08 11:44:26 +0800154static bool x11_gpu_match_fd(const struct intel_gpu *gpu, int fd)
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800155{
Chia-I Wufcbc5252015-04-08 11:44:26 +0800156 struct stat fd_stat, gpu_stat;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800157
Chia-I Wufcbc5252015-04-08 11:44:26 +0800158 if (fstat(fd, &fd_stat))
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800159 return false;
160
161 /* is it the primary node? */
162 if (!stat(gpu->primary_node, &gpu_stat) &&
Chia-I Wufcbc5252015-04-08 11:44:26 +0800163 !memcmp(&fd_stat, &gpu_stat, sizeof(fd_stat)))
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800164 return true;
165
166 /* is it the render node? */
167 if (gpu->render_node && !stat(gpu->render_node, &gpu_stat) &&
Chia-I Wufcbc5252015-04-08 11:44:26 +0800168 !memcmp(&fd_stat, &gpu_stat, sizeof(fd_stat)))
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800169 return true;
170
171 return false;
172}
173
Chia-I Wufcbc5252015-04-08 11:44:26 +0800174/*
175 * Return the depth of \p drawable.
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800176 */
Chia-I Wufcbc5252015-04-08 11:44:26 +0800177static int x11_get_drawable_depth(xcb_connection_t *c,
178 xcb_drawable_t drawable)
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800179{
Chia-I Wufcbc5252015-04-08 11:44:26 +0800180 xcb_get_geometry_cookie_t cookie;
181 xcb_get_geometry_reply_t *reply;
182 uint8_t depth;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800183
Chia-I Wufcbc5252015-04-08 11:44:26 +0800184 cookie = xcb_get_geometry(c, drawable);
185 reply = xcb_get_geometry_reply(c, cookie, NULL);
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800186
Chia-I Wufcbc5252015-04-08 11:44:26 +0800187 if (reply) {
188 depth = reply->depth;
189 free(reply);
190 } else {
191 depth = 0;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800192 }
193
Chia-I Wufcbc5252015-04-08 11:44:26 +0800194 return depth;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800195}
196
Chia-I Wu1db76e02014-09-15 14:21:14 +0800197/**
198 * Return true if DRI3 and Present are supported by the server.
199 */
Chia-I Wufcbc5252015-04-08 11:44:26 +0800200static bool x11_is_dri3_and_present_supported(xcb_connection_t *c)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800201{
202 const xcb_query_extension_reply_t *ext;
203
Chia-I Wufcbc5252015-04-08 11:44:26 +0800204 xcb_prefetch_extension_data(c, &xcb_dri3_id);
205 xcb_prefetch_extension_data(c, &xcb_present_id);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800206
Chia-I Wufcbc5252015-04-08 11:44:26 +0800207 ext = xcb_get_extension_data(c, &xcb_dri3_id);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800208 if (!ext || !ext->present)
209 return false;
210
Chia-I Wufcbc5252015-04-08 11:44:26 +0800211 ext = xcb_get_extension_data(c, &xcb_present_id);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800212 if (!ext || !ext->present)
213 return false;
214
215 return true;
216}
217
218/**
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800219 * Send a DRI3Open to get the server GPU fd.
Chia-I Wu1db76e02014-09-15 14:21:14 +0800220 */
Chia-I Wufcbc5252015-04-08 11:44:26 +0800221static int x11_dri3_open(xcb_connection_t *c,
222 xcb_drawable_t drawable,
223 xcb_randr_provider_t provider)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800224{
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800225 xcb_dri3_open_cookie_t cookie;
226 xcb_dri3_open_reply_t *reply;
227 int fd;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800228
Chia-I Wufcbc5252015-04-08 11:44:26 +0800229 cookie = xcb_dri3_open(c, drawable, provider);
230 reply = xcb_dri3_open_reply(c, cookie, NULL);
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800231 if (!reply)
Chia-I Wufcbc5252015-04-08 11:44:26 +0800232 return -1;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800233
Chia-I Wufcbc5252015-04-08 11:44:26 +0800234 fd = (reply->nfd == 1) ? xcb_dri3_open_reply_fds(c, reply)[0] : -1;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800235 free(reply);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800236
Chia-I Wufcbc5252015-04-08 11:44:26 +0800237 return fd;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800238}
239
240/**
Chia-I Wu030b2db2015-04-08 13:46:29 +0800241 * Send a DRI3PixmapFromBuffer to create a pixmap from \p prime_fd.
242 */
243static xcb_pixmap_t x11_dri3_pixmap_from_buffer(xcb_connection_t *c,
244 xcb_drawable_t drawable,
245 uint8_t depth, int prime_fd,
246 const struct intel_layout *layout)
247{
248 xcb_pixmap_t pixmap;
249
250 pixmap = xcb_generate_id(c);
251
252 xcb_dri3_pixmap_from_buffer(c, pixmap, drawable,
253 layout->bo_stride * layout->bo_height,
254 layout->width0, layout->height0,
255 layout->bo_stride, depth,
256 layout->block_size * 8, prime_fd);
257
258 return pixmap;
259}
260
261/**
Chia-I Wu41858c82015-04-04 16:39:25 +0800262 * Send DRI3QueryVersion and PresentQueryVersion to query extension versions.
Chia-I Wu1db76e02014-09-15 14:21:14 +0800263 */
Chia-I Wu41858c82015-04-04 16:39:25 +0800264static bool wsi_x11_dri3_and_present_query_version(struct intel_wsi_x11 *x11)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800265{
266 xcb_dri3_query_version_cookie_t dri3_cookie;
267 xcb_dri3_query_version_reply_t *dri3_reply;
268 xcb_present_query_version_cookie_t present_cookie;
269 xcb_present_query_version_reply_t *present_reply;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800270
Chia-I Wu41858c82015-04-04 16:39:25 +0800271 dri3_cookie = xcb_dri3_query_version(x11->c,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800272 XCB_DRI3_MAJOR_VERSION, XCB_DRI3_MINOR_VERSION);
Chia-I Wu41858c82015-04-04 16:39:25 +0800273 present_cookie = xcb_present_query_version(x11->c,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800274 XCB_PRESENT_MAJOR_VERSION, XCB_PRESENT_MINOR_VERSION);
275
Chia-I Wu41858c82015-04-04 16:39:25 +0800276 dri3_reply = xcb_dri3_query_version_reply(x11->c, dri3_cookie, NULL);
277 if (!dri3_reply)
278 return false;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800279
280 x11->dri3_major = dri3_reply->major_version;
281 x11->dri3_minor = dri3_reply->minor_version;
282 free(dri3_reply);
283
Chia-I Wu41858c82015-04-04 16:39:25 +0800284 present_reply = xcb_present_query_version_reply(x11->c, present_cookie, NULL);
285 if (!present_reply)
286 return false;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800287
288 x11->present_major = present_reply->major_version;
289 x11->present_minor = present_reply->minor_version;
290 free(present_reply);
291
Chia-I Wu41858c82015-04-04 16:39:25 +0800292 return true;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800293}
294
295/**
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800296 * Send a PresentSelectInput to select interested events.
Chia-I Wu1db76e02014-09-15 14:21:14 +0800297 */
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600298static VK_RESULT x11_swap_chain_present_select_input(struct intel_x11_swap_chain *sc)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800299{
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800300 xcb_void_cookie_t cookie;
301 xcb_generic_error_t *error;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800302
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800303 /* create the event queue */
304 sc->present_special_event_id = xcb_generate_id(sc->c);
305 sc->present_special_event = xcb_register_for_special_xge(sc->c,
306 &xcb_present_id, sc->present_special_event_id, NULL);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800307
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800308 cookie = xcb_present_select_input_checked(sc->c,
309 sc->present_special_event_id, sc->window,
310 XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800311
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800312 error = xcb_request_check(sc->c, cookie);
313 if (error) {
314 free(error);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600315 return VK_ERROR_UNKNOWN;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800316 }
Chia-I Wu1db76e02014-09-15 14:21:14 +0800317
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600318 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800319}
320
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600321static VK_RESULT wsi_x11_dri3_pixmap_from_buffer(struct intel_wsi_x11 *x11,
322 struct intel_dev *dev,
323 struct intel_img *img,
324 struct intel_mem *mem)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800325{
Chia-I Wu41858c82015-04-04 16:39:25 +0800326 struct intel_x11_img_data *data =
327 (struct intel_x11_img_data *) img->wsi_data;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800328
Chia-I Wu030b2db2015-04-08 13:46:29 +0800329 data->prime_fd = x11_export_prime_fd(dev, mem->bo, &img->layout);
330 if (data->prime_fd < 0)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600331 return VK_ERROR_UNKNOWN;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800332
Chia-I Wu030b2db2015-04-08 13:46:29 +0800333 data->pixmap = x11_dri3_pixmap_from_buffer(x11->c, x11->root,
334 x11->root_depth, data->prime_fd, &img->layout);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800335
Chia-I Wu41858c82015-04-04 16:39:25 +0800336 data->mem = mem;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800337
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600338 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800339}
340
341/**
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800342 * Create a presentable image.
Chia-I Wu1db76e02014-09-15 14:21:14 +0800343 */
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600344static VK_RESULT wsi_x11_img_create(struct intel_wsi_x11 *x11,
345 struct intel_dev *dev,
346 const VK_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO *info,
347 struct intel_img **img_ret)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800348{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600349 VK_IMAGE_CREATE_INFO img_info;
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600350 VkMemoryAllocInfo mem_info;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800351 struct intel_img *img;
352 struct intel_mem *mem;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600353 VK_RESULT ret;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800354
Chia-I Wufcbc5252015-04-08 11:44:26 +0800355 if (!x11_is_format_presentable(dev, info->format)) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600356 intel_dev_log(dev, VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0,
357 VK_NULL_HANDLE, 0, 0, "invalid presentable image format");
358 return VK_ERROR_INVALID_VALUE;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800359 }
360
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800361 /* create image */
362 memset(&img_info, 0, sizeof(img_info));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600363 img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
364 img_info.imageType = VK_IMAGE_2D;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800365 img_info.format = info->format;
366 img_info.extent.width = info->extent.width;
367 img_info.extent.height = info->extent.height;
368 img_info.extent.depth = 1;
369 img_info.mipLevels = 1;
370 img_info.arraySize = 1;
371 img_info.samples = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600372 img_info.tiling = VK_OPTIMAL_TILING;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800373 img_info.usage = info->usage;
374 img_info.flags = 0;
375
376 ret = intel_img_create(dev, &img_info, true, &img);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600377 if (ret != VK_SUCCESS)
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800378 return ret;
379
380 /* allocate memory */
381 memset(&mem_info, 0, sizeof(mem_info));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600382 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800383 mem_info.allocationSize = img->total_size;
384 mem_info.memProps = 0;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600385 mem_info.memType = VK_MEMORY_TYPE_IMAGE;
386 mem_info.memPriority = VK_MEMORY_PRIORITY_HIGH;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800387
388 ret = intel_mem_alloc(dev, &mem_info, &mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600389 if (ret != VK_SUCCESS) {
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800390 intel_img_destroy(img);
391 return ret;
392 }
393
394 ret = wsi_x11_dri3_pixmap_from_buffer(x11, dev, img, mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600395 if (ret != VK_SUCCESS) {
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800396 intel_mem_free(mem);
397 intel_img_destroy(img);
398 return ret;
399 }
400
401 intel_obj_bind_mem(&img->obj, mem, 0);
402
403 *img_ret = img;
404
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600405 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800406}
407
408/**
409 * Send a PresentPixmap.
410 */
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600411static VK_RESULT x11_swap_chain_present_pixmap(struct intel_x11_swap_chain *sc,
412 const VK_WSI_X11_PRESENT_INFO *info)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800413{
414 struct intel_img *img = intel_img(info->srcImage);
Chia-I Wu41858c82015-04-04 16:39:25 +0800415 struct intel_x11_img_data *data =
416 (struct intel_x11_img_data *) img->wsi_data;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800417 uint32_t options = XCB_PRESENT_OPTION_NONE;
418 xcb_void_cookie_t cookie;
419 xcb_generic_error_t *err;
420
421 if (info->async)
422 options |= XCB_PRESENT_OPTION_ASYNC;
423 if (!info->flip)
424 options |= XCB_PRESENT_OPTION_COPY;
425
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800426 cookie = xcb_present_pixmap(sc->c,
427 sc->window,
Chia-I Wu41858c82015-04-04 16:39:25 +0800428 data->pixmap,
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800429 ++sc->local.serial,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800430 0, /* valid-area */
431 0, /* update-area */
432 0, /* x-off */
433 0, /* y-off */
434 info->crtc,
435 0, /* wait-fence */
436 0, /* idle-fence */
437 options,
438 info->target_msc,
439 info->divisor,
440 info->remainder,
441 0, NULL);
442
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800443 err = xcb_request_check(sc->c, cookie);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800444 if (err) {
445 free(err);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600446 return VK_ERROR_UNKNOWN;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800447 }
448
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600449 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800450}
451
452/**
453 * Send a PresentNotifyMSC for the current MSC.
454 */
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800455static void x11_swap_chain_present_notify_msc(struct intel_x11_swap_chain *sc)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800456{
457 /* cannot specify CRTC? */
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800458 xcb_present_notify_msc(sc->c, sc->window, ++sc->local.serial, 0, 0, 0);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800459
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800460 xcb_flush(sc->c);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800461}
462
463/**
464 * Handle a Present event.
465 */
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800466static void x11_swap_chain_present_event(struct intel_x11_swap_chain *sc,
467 const xcb_present_generic_event_t *ev)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800468{
469 union {
470 const xcb_present_generic_event_t *ev;
471 const xcb_present_complete_notify_event_t *complete;
472 } u = { .ev = ev };
473
474 switch (u.ev->evtype) {
475 case XCB_PRESENT_COMPLETE_NOTIFY:
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800476 sc->remote.serial = u.complete->serial;
477 sc->remote.msc = u.complete->msc;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800478 break;
479 default:
480 break;
481 }
482}
483
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600484static VK_RESULT x11_swap_chain_wait(struct intel_x11_swap_chain *sc,
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800485 uint32_t serial, int64_t timeout)
486{
487 const bool wait = (timeout != 0);
488
489 while (sc->remote.serial < serial) {
490 xcb_present_generic_event_t *ev;
491
492 if (wait) {
493 ev = (xcb_present_generic_event_t *)
494 xcb_wait_for_special_event(sc->c, sc->present_special_event);
495 if (!ev)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600496 return VK_ERROR_UNKNOWN;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800497 } else {
498 ev = (xcb_present_generic_event_t *)
499 xcb_poll_for_special_event(sc->c, sc->present_special_event);
500 if (!ev)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600501 return VK_NOT_READY;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800502 }
503
504 x11_swap_chain_present_event(sc, ev);
505
506 free(ev);
507 }
508
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600509 return VK_SUCCESS;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800510}
511
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800512static void x11_swap_chain_destroy(struct intel_x11_swap_chain *sc)
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800513{
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800514 if (sc->present_special_event)
515 xcb_unregister_for_special_event(sc->c, sc->present_special_event);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800516
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800517 intel_free(sc, sc);
518}
519
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800520static void wsi_x11_destroy(struct intel_wsi_x11 *x11)
521{
522 struct intel_x11_swap_chain *sc = x11->swap_chains;
523
524 while (sc) {
525 struct intel_x11_swap_chain *next = sc->next;
526 x11_swap_chain_destroy(sc);
527 sc = next;
528 }
529
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800530 intel_free(x11, x11);
531}
532
533static struct intel_wsi_x11 *wsi_x11_create(struct intel_gpu *gpu,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600534 const VK_WSI_X11_CONNECTION_INFO *info)
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800535{
536 struct intel_wsi_x11 *x11;
Chia-I Wufcbc5252015-04-08 11:44:26 +0800537 int depth, fd;
538
539 if (!x11_is_dri3_and_present_supported(info->pConnection))
540 return NULL;
541
542 depth = x11_get_drawable_depth(info->pConnection, info->root);
543 if (!depth)
544 return NULL;
545
546 fd = x11_dri3_open(info->pConnection, info->root, info->provider);
547 if (fd < 0 || !x11_gpu_match_fd(gpu, fd)) {
548 if (fd >= 0)
549 close(fd);
550 return NULL;
551 }
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800552
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600553 x11 = intel_alloc(gpu, sizeof(*x11), 0, VK_SYSTEM_ALLOC_API_OBJECT);
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800554 if (!x11)
555 return NULL;
556
557 memset(x11, 0, sizeof(*x11));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600558 /* there is no VK_DBG_OBJECT_WSI_DISPLAY */
559 intel_handle_init(&x11->handle, VK_DBG_OBJECT_UNKNOWN, gpu->handle.icd);
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800560
561 x11->c = info->pConnection;
562 x11->root = info->root;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800563
Chia-I Wufcbc5252015-04-08 11:44:26 +0800564 x11->root_depth = depth;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800565
Chia-I Wufcbc5252015-04-08 11:44:26 +0800566 if (!wsi_x11_dri3_and_present_query_version(x11)) {
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800567 wsi_x11_destroy(x11);
568 return NULL;
569 }
570
571 return x11;
572}
573
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800574static struct intel_x11_swap_chain *x11_swap_chain_create(struct intel_dev *dev,
575 xcb_window_t window)
576{
577 struct intel_wsi_x11 *x11 = (struct intel_wsi_x11 *) dev->gpu->wsi_data;
578 struct intel_x11_swap_chain *sc;
579
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600580 sc = intel_alloc(dev, sizeof(*sc), 0, VK_SYSTEM_ALLOC_API_OBJECT);
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800581 if (!sc)
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800582 return NULL;
583
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800584 memset(sc, 0, sizeof(*sc));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600585 /* there is no VK_DBG_OBJECT_WSI_SWAP_CHAIN */
586 intel_handle_init(&sc->handle, VK_DBG_OBJECT_UNKNOWN,
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800587 dev->base.handle.icd);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800588
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800589 sc->c = x11->c;
590 sc->window = window;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800591
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600592 if (x11_swap_chain_present_select_input(sc) != VK_SUCCESS) {
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800593 intel_free(dev, sc);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800594 return NULL;
595 }
596
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800597 return sc;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800598}
599
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800600static struct intel_x11_swap_chain *x11_swap_chain_lookup(struct intel_dev *dev,
601 xcb_window_t window)
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800602{
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800603 struct intel_wsi_x11 *x11 = (struct intel_wsi_x11 *) dev->gpu->wsi_data;
604 struct intel_x11_swap_chain *sc = x11->swap_chains;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800605
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800606 while (sc) {
607 if (sc->window == window)
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800608 break;
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800609 sc = sc->next;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800610 }
611
612 /* lookup failed */
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800613 if (!sc) {
614 sc = x11_swap_chain_create(dev, window);
615 if (sc) {
616 sc->next = x11->swap_chains;
617 x11->swap_chains = sc;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800618 }
619 }
620
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800621 return sc;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800622}
623
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600624static VK_RESULT intel_wsi_gpu_init(struct intel_gpu *gpu,
625 const VK_WSI_X11_CONNECTION_INFO *info)
Chia-I Wu41858c82015-04-04 16:39:25 +0800626{
627 struct intel_wsi_x11 *x11;
628
629 x11 = wsi_x11_create(gpu, info);
630 if (!x11)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600631 return VK_ERROR_UNKNOWN;
Chia-I Wu41858c82015-04-04 16:39:25 +0800632
633 gpu->wsi_data = x11;
634
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600635 return VK_SUCCESS;
Chia-I Wu41858c82015-04-04 16:39:25 +0800636}
637
Chia-I Wu8635e912015-04-09 14:13:57 +0800638static void x11_display_init_modes(struct intel_x11_display *dpy,
639 const drmModeConnectorPtr conn)
640{
641 int i;
642
643 if (!conn->count_modes)
644 return;
645
646 dpy->modes = intel_alloc(dpy, sizeof(dpy->modes[0]) * conn->count_modes,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600647 0, VK_SYSTEM_ALLOC_INTERNAL);
Chia-I Wu8635e912015-04-09 14:13:57 +0800648 if (!dpy->modes)
649 return;
650
651 for (i = 0; i < conn->count_modes; i++) {
652 dpy->modes[i] = conn->modes[i];
653
654 if (dpy->physical_resolution.width < conn->modes[i].hdisplay &&
655 dpy->physical_resolution.height < conn->modes[i].vdisplay) {
656 dpy->physical_resolution.width = conn->modes[i].hdisplay;
657 dpy->physical_resolution.height = conn->modes[i].vdisplay;
658 }
659 }
660
661 dpy->mode_count = conn->count_modes;
662
663 dpy->physical_dimension.width = conn->mmWidth;
664 dpy->physical_dimension.height = conn->mmHeight;
665}
666
667static void x11_display_init_name(struct intel_x11_display *dpy,
668 const drmModeConnectorPtr conn)
669{
670 static const char *connector_names[] = {
671 [DRM_MODE_CONNECTOR_Unknown] = "Unknown",
672 [DRM_MODE_CONNECTOR_VGA] = "VGA",
673 [DRM_MODE_CONNECTOR_DVII] = "DVII",
674 [DRM_MODE_CONNECTOR_DVID] = "DVID",
675 [DRM_MODE_CONNECTOR_DVIA] = "DVIA",
676 [DRM_MODE_CONNECTOR_Composite] = "Composite",
677 [DRM_MODE_CONNECTOR_SVIDEO] = "SVIDEO",
678 [DRM_MODE_CONNECTOR_LVDS] = "LVDS",
679 [DRM_MODE_CONNECTOR_Component] = "COMPONENT",
680 [DRM_MODE_CONNECTOR_9PinDIN] = "9PinDIN",
681 [DRM_MODE_CONNECTOR_DisplayPort] = "DisplayPort",
682 [DRM_MODE_CONNECTOR_HDMIA] = "HDMIA",
683 [DRM_MODE_CONNECTOR_HDMIB] = "HDMIB",
684 [DRM_MODE_CONNECTOR_TV] = "TV",
685 [DRM_MODE_CONNECTOR_eDP] = "eDP",
686 [DRM_MODE_CONNECTOR_VIRTUAL] = "VIRTUAL",
687 [DRM_MODE_CONNECTOR_DSI] = "DSI",
688 };
689 const char *name;
690
691 name = (conn->connector_type < ARRAY_SIZE(connector_names)) ?
692 connector_names[conn->connector_type] : NULL;
693 if (!name)
694 name = connector_names[DRM_MODE_CONNECTOR_Unknown];
695
696 snprintf(dpy->name, sizeof(dpy->name),
697 "%s%d", name, conn->connector_type_id);
698}
699
700static void x11_display_destroy(struct intel_x11_display *dpy)
701{
702 intel_free(dpy, dpy->modes);
703 intel_free(dpy, dpy);
704}
705
706static struct intel_x11_display *x11_display_create(struct intel_gpu *gpu,
707 int fd,
708 uint32_t connector_id)
709{
710 struct intel_x11_display *dpy;
711 drmModeConnectorPtr conn;
712
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600713 dpy = intel_alloc(gpu, sizeof(*dpy), 0, VK_SYSTEM_ALLOC_API_OBJECT);
Chia-I Wu8635e912015-04-09 14:13:57 +0800714 if (!dpy)
715 return NULL;
716
717 memset(dpy, 0, sizeof(*dpy));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600718 /* there is no VK_DBG_OBJECT_WSI_DISPLAY */
719 intel_handle_init(&dpy->handle, VK_DBG_OBJECT_UNKNOWN, gpu->handle.icd);
Chia-I Wu8635e912015-04-09 14:13:57 +0800720
721 dpy->fd = fd;
722 dpy->connector_id = connector_id;
723
724 conn = drmModeGetConnector(fd, connector_id);
725 if (!conn) {
726 x11_display_destroy(dpy);
727 return NULL;
728 }
729
730 x11_display_init_name(dpy, conn);
731 x11_display_init_modes(dpy, conn);
732
733 drmModeFreeConnector(conn);
734
735 return dpy;
736}
737
738static void x11_display_scan(struct intel_gpu *gpu)
739{
740 struct intel_x11_display **displays;
741 drmModeResPtr res;
742 int fd, i;
743
744 fd = intel_gpu_get_primary_fd(gpu);
745 if (fd < 0)
746 return;
747
748 res = drmModeGetResources(fd);
749 if (!res)
750 return;
751
752 displays = intel_alloc(gpu, sizeof(*displays) * res->count_connectors,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600753 0, VK_SYSTEM_ALLOC_INTERNAL);
Chia-I Wu8635e912015-04-09 14:13:57 +0800754 if (!displays) {
755 drmModeFreeResources(res);
756 return;
757 }
758
759 for (i = 0; i < res->count_connectors; i++) {
760 displays[i] = x11_display_create(gpu, fd, res->connectors[i]);
761 if (!displays[i])
762 break;
763 }
764
765 drmModeFreeResources(res);
766
767 gpu->displays = (struct intel_wsi_display **) displays;
768 gpu->display_count = i;
769}
770
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600771VK_RESULT intel_wsi_gpu_get_info(struct intel_gpu *gpu,
772 VK_PHYSICAL_GPU_INFO_TYPE type,
Chia-I Wu41858c82015-04-04 16:39:25 +0800773 size_t *size, void *data)
774{
Chia-I Wu8635e912015-04-09 14:13:57 +0800775 if (false)
776 x11_display_scan(gpu);
777
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600778 return VK_ERROR_INVALID_VALUE;
Chia-I Wu41858c82015-04-04 16:39:25 +0800779}
780
781void intel_wsi_gpu_cleanup(struct intel_gpu *gpu)
782{
Chia-I Wu8635e912015-04-09 14:13:57 +0800783 if (gpu->displays) {
784 uint32_t i;
Chia-I Wu41858c82015-04-04 16:39:25 +0800785
Chia-I Wu8635e912015-04-09 14:13:57 +0800786 for (i = 0; i < gpu->display_count; i++) {
787 struct intel_x11_display *dpy =
788 (struct intel_x11_display *) gpu->displays[i];
789 x11_display_destroy(dpy);
790 }
791 intel_free(gpu, gpu->displays);
792 }
793
794 if (gpu->wsi_data) {
795 struct intel_wsi_x11 *x11 = (struct intel_wsi_x11 *) gpu->wsi_data;
796 wsi_x11_destroy(x11);
797 }
Chia-I Wu41858c82015-04-04 16:39:25 +0800798}
799
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600800VK_RESULT intel_wsi_img_init(struct intel_img *img)
Chia-I Wu41858c82015-04-04 16:39:25 +0800801{
802 struct intel_x11_img_data *data;
803
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600804 data = intel_alloc(img, sizeof(*data), 0, VK_SYSTEM_ALLOC_INTERNAL);
Chia-I Wu41858c82015-04-04 16:39:25 +0800805 if (!data)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600806 return VK_ERROR_OUT_OF_MEMORY;
Chia-I Wu41858c82015-04-04 16:39:25 +0800807
808 memset(data, 0, sizeof(*data));
809
810 assert(!img->wsi_data);
811 img->wsi_data = data;
812
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600813 return VK_SUCCESS;
Chia-I Wu41858c82015-04-04 16:39:25 +0800814}
815
816void intel_wsi_img_cleanup(struct intel_img *img)
817{
818 struct intel_x11_img_data *data =
819 (struct intel_x11_img_data *) img->wsi_data;
820
821 if (data->mem) {
822 close(data->prime_fd);
823 intel_mem_free(data->mem);
824 }
825
826 intel_free(img, img->wsi_data);
827}
828
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600829VK_RESULT intel_wsi_fence_init(struct intel_fence *fence)
Chia-I Wu41858c82015-04-04 16:39:25 +0800830{
831 struct intel_x11_fence_data *data;
832
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600833 data = intel_alloc(fence, sizeof(*data), 0, VK_SYSTEM_ALLOC_INTERNAL);
Chia-I Wu41858c82015-04-04 16:39:25 +0800834 if (!data)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600835 return VK_ERROR_OUT_OF_MEMORY;
Chia-I Wu41858c82015-04-04 16:39:25 +0800836
837 memset(data, 0, sizeof(*data));
838
839 assert(!fence->wsi_data);
840 fence->wsi_data = data;
841
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600842 return VK_SUCCESS;
Chia-I Wu41858c82015-04-04 16:39:25 +0800843}
844
845void intel_wsi_fence_cleanup(struct intel_fence *fence)
846{
847 intel_free(fence, fence->wsi_data);
848}
849
850void intel_wsi_fence_copy(struct intel_fence *fence,
851 const struct intel_fence *src)
852{
853 memcpy(fence->wsi_data, src->wsi_data,
854 sizeof(struct intel_x11_fence_data));
855}
856
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600857VK_RESULT intel_wsi_fence_wait(struct intel_fence *fence,
Chia-I Wu41858c82015-04-04 16:39:25 +0800858 int64_t timeout_ns)
859{
860 struct intel_x11_fence_data *data =
861 (struct intel_x11_fence_data *) fence->wsi_data;
862
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800863 if (!data->swap_chain)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600864 return VK_SUCCESS;
Chia-I Wu41858c82015-04-04 16:39:25 +0800865
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800866 return x11_swap_chain_wait(data->swap_chain, data->serial, timeout_ns);
Chia-I Wu41858c82015-04-04 16:39:25 +0800867}
868
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600869ICD_EXPORT VK_RESULT VKAPI vkWsiX11AssociateConnection(
870 VK_PHYSICAL_GPU gpu_,
871 const VK_WSI_X11_CONNECTION_INFO* pConnectionInfo)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800872{
873 struct intel_gpu *gpu = intel_gpu(gpu_);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800874
Chia-I Wu41858c82015-04-04 16:39:25 +0800875 return intel_wsi_gpu_init(gpu, pConnectionInfo);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800876}
877
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600878ICD_EXPORT VK_RESULT VKAPI vkWsiX11GetMSC(
879 VK_DEVICE device,
Chia-I Wu6204f342014-11-07 13:33:45 +0800880 xcb_window_t window,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800881 xcb_randr_crtc_t crtc,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600882 uint64_t * pMsc)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800883{
884 struct intel_dev *dev = intel_dev(device);
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800885 struct intel_x11_swap_chain *sc;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600886 VK_RESULT ret;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800887
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800888 sc = x11_swap_chain_lookup(dev, window);
889 if (!sc)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600890 return VK_ERROR_UNKNOWN;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800891
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800892 x11_swap_chain_present_notify_msc(sc);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800893
894 /* wait for the event */
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800895 ret = x11_swap_chain_wait(sc, sc->local.serial, -1);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600896 if (ret != VK_SUCCESS)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800897 return ret;
898
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800899 *pMsc = sc->remote.msc;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800900
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600901 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800902}
903
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600904ICD_EXPORT VK_RESULT VKAPI vkWsiX11CreatePresentableImage(
905 VK_DEVICE device,
906 const VK_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO* pCreateInfo,
907 VK_IMAGE* pImage,
908 VK_GPU_MEMORY* pMem)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800909{
910 struct intel_dev *dev = intel_dev(device);
Chia-I Wu41858c82015-04-04 16:39:25 +0800911 struct intel_wsi_x11 *x11 = (struct intel_wsi_x11 *) dev->gpu->wsi_data;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800912 struct intel_img *img;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600913 VK_RESULT ret;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800914
915 ret = wsi_x11_img_create(x11, dev, pCreateInfo, &img);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600916 if (ret == VK_SUCCESS) {
917 *pImage = (VK_IMAGE) img;
918 *pMem = (VK_GPU_MEMORY) img->obj.mem;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800919 }
920
921 return ret;
922}
923
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600924ICD_EXPORT VK_RESULT VKAPI vkWsiX11QueuePresent(
925 VK_QUEUE queue_,
926 const VK_WSI_X11_PRESENT_INFO* pPresentInfo,
927 VK_FENCE fence_)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800928{
929 struct intel_queue *queue = intel_queue(queue_);
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800930 struct intel_dev *dev = queue->dev;
Chia-I Wub56f5df2015-04-04 20:21:10 +0800931 struct intel_x11_fence_data *data =
932 (struct intel_x11_fence_data *) queue->fence->wsi_data;
933 struct intel_img *img = intel_img(pPresentInfo->srcImage);
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800934 struct intel_x11_swap_chain *sc;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600935 VK_RESULT ret;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800936
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800937 sc = x11_swap_chain_lookup(dev, pPresentInfo->destWindow);
938 if (!sc)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600939 return VK_ERROR_UNKNOWN;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800940
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800941 ret = x11_swap_chain_present_pixmap(sc, pPresentInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600942 if (ret != VK_SUCCESS)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800943 return ret;
944
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800945 data->swap_chain = sc;
946 data->serial = sc->local.serial;
Chia-I Wub56f5df2015-04-04 20:21:10 +0800947 intel_fence_set_seqno(queue->fence, img->obj.mem->bo);
Chia-I Wubda4f622015-02-25 15:06:15 -0700948
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600949 if (fence_ != VK_NULL_HANDLE) {
Chia-I Wub56f5df2015-04-04 20:21:10 +0800950 struct intel_fence *fence = intel_fence(fence_);
951 intel_fence_copy(fence, queue->fence);
Chia-I Wubda4f622015-02-25 15:06:15 -0700952 }
Chia-I Wu1db76e02014-09-15 14:21:14 +0800953
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600954 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800955}