blob: d90dff87ac9e66e847c6b255f2a8307a6403093b [file] [log] [blame]
Chia-I Wu1db76e02014-09-15 14:21:14 +08001/*
2 * XGL
3 *
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"
37#include "dev.h"
38#include "fence.h"
39#include "gpu.h"
40#include "img.h"
41#include "mem.h"
42#include "queue.h"
43#include "wsi_x11.h"
44
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +080045struct intel_wsi_x11_window {
46 xcb_window_t window_id;
Chia-I Wu1db76e02014-09-15 14:21:14 +080047
48 xcb_present_event_t present_special_event_id;
49 xcb_special_event_t *present_special_event;
50
51 struct {
52 uint32_t serial;
53 } local;
54
55 struct {
56 uint32_t serial;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060057 uint64_t msc;
Chia-I Wu1db76e02014-09-15 14:21:14 +080058 } remote;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +080059
60 struct intel_wsi_x11_window *next;
61};
62
63struct intel_wsi_x11 {
64 xcb_connection_t *c;
65 xcb_window_t root;
66 xcb_randr_provider_t provider;
67 int root_depth;
68
69 int dri3_major, dri3_minor;
70 int present_major, present_minor;
71
72 int fd;
73
74 struct intel_wsi_x11_window *windows;
Chia-I Wu1db76e02014-09-15 14:21:14 +080075};
76
77/**
78 * Return true if DRI3 and Present are supported by the server.
79 */
80static bool wsi_x11_has_dri3_and_present(xcb_connection_t *c)
81{
82 const xcb_query_extension_reply_t *ext;
83
84 xcb_prefetch_extension_data(c, &xcb_dri3_id);
85 xcb_prefetch_extension_data(c, &xcb_present_id);
86
87 ext = xcb_get_extension_data(c, &xcb_dri3_id);
88 if (!ext || !ext->present)
89 return false;
90
91 ext = xcb_get_extension_data(c, &xcb_present_id);
92 if (!ext || !ext->present)
93 return false;
94
95 return true;
96}
97
98/**
99 * Return the depth of the root window.
100 */
101static int wsi_x11_get_root_depth(struct intel_wsi_x11 *x11)
102{
103 const xcb_setup_t *setup;
104 xcb_screen_iterator_t iter;
105
106 setup = xcb_get_setup(x11->c);
107
108 iter = xcb_setup_roots_iterator(setup);
109 for (; iter.rem; xcb_screen_next(&iter)) {
110 if (iter.data->root == x11->root)
111 return iter.data->root_depth;
112 }
113
114 return 0;
115}
116
117/**
118 * Query DRI3 and Present versions and return an intel_wsi_x11.
119 */
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800120static struct intel_wsi_x11 *wsi_x11_create(const struct intel_gpu *gpu,
121 xcb_connection_t *c,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800122 xcb_window_t root,
123 xcb_randr_provider_t provider)
124{
125 xcb_dri3_query_version_cookie_t dri3_cookie;
126 xcb_dri3_query_version_reply_t *dri3_reply;
127 xcb_present_query_version_cookie_t present_cookie;
128 xcb_present_query_version_reply_t *present_reply;
129 struct intel_wsi_x11 *x11;
130
131 dri3_cookie = xcb_dri3_query_version(c,
132 XCB_DRI3_MAJOR_VERSION, XCB_DRI3_MINOR_VERSION);
133 present_cookie = xcb_present_query_version(c,
134 XCB_PRESENT_MAJOR_VERSION, XCB_PRESENT_MINOR_VERSION);
135
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800136 x11 = intel_alloc(gpu, sizeof(*x11), 0, XGL_SYSTEM_ALLOC_INTERNAL);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800137 if (!x11)
138 return NULL;
139 memset(x11, 0, sizeof(*x11));
140
141 x11->c = c;
142 x11->root = root;
143 x11->provider = provider;
144
145 x11->root_depth = wsi_x11_get_root_depth(x11);
146
147 dri3_reply = xcb_dri3_query_version_reply(c, dri3_cookie, NULL);
148 if (!dri3_reply) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800149 intel_free(gpu, x11);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800150 return NULL;
151 }
152
153 x11->dri3_major = dri3_reply->major_version;
154 x11->dri3_minor = dri3_reply->minor_version;
155 free(dri3_reply);
156
157 present_reply = xcb_present_query_version_reply(c, present_cookie, NULL);
158 if (!present_reply) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800159 intel_free(gpu, x11);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800160 return NULL;
161 }
162
163 x11->present_major = present_reply->major_version;
164 x11->present_minor = present_reply->minor_version;
165 free(present_reply);
166
167 x11->fd = -1;
168
169 return x11;
170}
171
172/**
173 * Return true if x11->fd points to the primary or render node of the GPU.
174 */
175static bool wsi_x11_uses_gpu(const struct intel_wsi_x11 *x11,
176 const struct intel_gpu *gpu)
177{
178 struct stat x11_stat, gpu_stat;
179
180 if (fstat(x11->fd, &x11_stat))
181 return false;
182
183 /* is it the primary node? */
184 if (!stat(gpu->primary_node, &gpu_stat) &&
185 !memcmp(&x11_stat, &gpu_stat, sizeof(x11_stat)))
186 return true;
187
188 /* is it the render node? */
189 if (gpu->render_node && !stat(gpu->render_node, &gpu_stat) &&
190 !memcmp(&x11_stat, &gpu_stat, sizeof(x11_stat)))
191 return true;
192
193 return false;
194}
195
196/**
197 * Send a DRI3Open to get the server GPU fd.
198 */
199static XGL_RESULT wsi_x11_dri3_open(struct intel_wsi_x11 *x11)
200{
201 xcb_dri3_open_cookie_t cookie;
202 xcb_dri3_open_reply_t *reply;
203 int fd;
204
205 cookie = xcb_dri3_open(x11->c, x11->root, x11->provider);
206 reply = xcb_dri3_open_reply(x11->c, cookie, NULL);
207 if (!reply)
208 return XGL_ERROR_UNKNOWN;
209
210 fd = (reply->nfd == 1) ? xcb_dri3_open_reply_fds(x11->c, reply)[0] : -1;
211 free(reply);
212
213 if (fd < 0)
214 return XGL_ERROR_UNKNOWN;
215
216 fcntl(fd, F_SETFD, FD_CLOEXEC);
217 x11->fd = fd;
218
219 return XGL_SUCCESS;
220}
221
222/**
223 * Send a DRI3PixmapFromBuffer to create a Pixmap from \p mem for \p img.
224 */
225static XGL_RESULT wsi_x11_dri3_pixmap_from_buffer(struct intel_wsi_x11 *x11,
226 struct intel_dev *dev,
227 struct intel_img *img,
228 struct intel_mem *mem)
229{
230 struct intel_winsys_handle export;
Chia-I Wud1eb90c2015-03-07 06:01:45 +0800231 enum intel_tiling_mode tiling;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800232 xcb_pixmap_t pixmap;
233
Chia-I Wud1eb90c2015-03-07 06:01:45 +0800234 switch (img->layout.tiling) {
235 case GEN6_TILING_X:
236 tiling = INTEL_TILING_X;
237 break;
238 case GEN6_TILING_Y:
239 tiling = INTEL_TILING_Y;
240 break;
241 default:
242 assert(img->layout.tiling == GEN6_TILING_NONE);
243 tiling = INTEL_TILING_NONE;
244 break;
245 }
246
Chia-I Wu1db76e02014-09-15 14:21:14 +0800247 /* get prime fd of the bo first */
Chia-I Wud1eb90c2015-03-07 06:01:45 +0800248 if (intel_bo_set_tiling(mem->bo, tiling, img->layout.bo_stride))
Chia-I Wu3d0f59c2015-03-07 06:00:46 +0800249 return XGL_ERROR_UNKNOWN;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800250 export.type = INTEL_WINSYS_HANDLE_FD;
Chia-I Wud1eb90c2015-03-07 06:01:45 +0800251 if (intel_winsys_export_handle(dev->winsys, mem->bo, tiling,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800252 img->layout.bo_stride, img->layout.bo_height, &export))
253 return XGL_ERROR_UNKNOWN;
254
255 pixmap = xcb_generate_id(x11->c);
256
257 /* create a pixmap from the prime fd */
258 xcb_dri3_pixmap_from_buffer(x11->c, pixmap,
259 x11->root, img->total_size,
260 img->layout.width0, img->layout.height0,
261 img->layout.bo_stride, x11->root_depth,
262 img->layout.block_size * 8, export.handle);
263
264 img->x11_prime_fd = export.handle;
265 img->x11_pixmap = pixmap;
266
267 return XGL_SUCCESS;
268}
269
270/**
271 * Send a PresentSelectInput to select interested events.
272 */
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800273static XGL_RESULT wsi_x11_present_select_input(struct intel_wsi_x11 *x11,
274 struct intel_wsi_x11_window *win)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800275{
276 xcb_void_cookie_t cookie;
277 xcb_generic_error_t *error;
278
279 /* create the event queue */
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800280 win->present_special_event_id = xcb_generate_id(x11->c);
281 win->present_special_event = xcb_register_for_special_xge(x11->c,
282 &xcb_present_id, win->present_special_event_id, NULL);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800283
284 cookie = xcb_present_select_input_checked(x11->c,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800285 win->present_special_event_id, win->window_id,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800286 XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY);
287
288 error = xcb_request_check(x11->c, cookie);
289 if (error) {
290 free(error);
291 return XGL_ERROR_UNKNOWN;
292 }
293
294 return XGL_SUCCESS;
295}
296
297/**
298 * Send a PresentPixmap.
299 */
300static XGL_RESULT wsi_x11_present_pixmap(struct intel_wsi_x11 *x11,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800301 struct intel_wsi_x11_window *win,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800302 const XGL_WSI_X11_PRESENT_INFO *info)
303{
304 struct intel_img *img = intel_img(info->srcImage);
305 uint32_t options = XCB_PRESENT_OPTION_NONE;
306 xcb_void_cookie_t cookie;
307 xcb_generic_error_t *err;
308
309 if (info->async)
310 options |= XCB_PRESENT_OPTION_ASYNC;
311 if (!info->flip)
312 options |= XCB_PRESENT_OPTION_COPY;
313
314 cookie = xcb_present_pixmap(x11->c,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800315 win->window_id,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800316 img->x11_pixmap,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800317 ++win->local.serial,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800318 0, /* valid-area */
319 0, /* update-area */
320 0, /* x-off */
321 0, /* y-off */
322 info->crtc,
323 0, /* wait-fence */
324 0, /* idle-fence */
325 options,
326 info->target_msc,
327 info->divisor,
328 info->remainder,
329 0, NULL);
330
331 err = xcb_request_check(x11->c, cookie);
332 if (err) {
333 free(err);
334 return XGL_ERROR_UNKNOWN;
335 }
336
337 return XGL_SUCCESS;
338}
339
340/**
341 * Send a PresentNotifyMSC for the current MSC.
342 */
343static void wsi_x11_present_notify_msc(struct intel_wsi_x11 *x11,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800344 struct intel_wsi_x11_window *win)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800345{
346 /* cannot specify CRTC? */
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800347 xcb_present_notify_msc(x11->c, win->window_id, ++win->local.serial,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800348 0, 0, 0);
349
350 xcb_flush(x11->c);
351}
352
353/**
354 * Handle a Present event.
355 */
356static void wsi_x11_present_event(struct intel_wsi_x11 *x11,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800357 struct intel_wsi_x11_window *win,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800358 const xcb_present_generic_event_t *ev)
359{
360 union {
361 const xcb_present_generic_event_t *ev;
362 const xcb_present_complete_notify_event_t *complete;
363 } u = { .ev = ev };
364
365 switch (u.ev->evtype) {
366 case XCB_PRESENT_COMPLETE_NOTIFY:
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800367 win->remote.serial = u.complete->serial;
368 win->remote.msc = u.complete->msc;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800369 break;
370 default:
371 break;
372 }
373}
374
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800375static struct intel_wsi_x11_window *wsi_x11_create_window(const struct intel_gpu *gpu,
376 struct intel_wsi_x11 *x11,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800377 xcb_window_t win_id)
378{
379 struct intel_wsi_x11_window *win;
380
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800381 win = intel_alloc(gpu, sizeof(*win), 0, XGL_SYSTEM_ALLOC_INTERNAL);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800382 if (!win)
383 return NULL;
384
385 memset(win, 0, sizeof(*win));
386
387 win->window_id = win_id;
388
389 if (wsi_x11_present_select_input(x11, win) != XGL_SUCCESS) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800390 intel_free(gpu, win);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800391 return NULL;
392 }
393
394 return win;
395}
396
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800397static void wsi_x11_destroy_window(const struct intel_gpu *gpu,
398 struct intel_wsi_x11 *x11,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800399 struct intel_wsi_x11_window *win)
400{
401 if (win->present_special_event)
402 xcb_unregister_for_special_event(x11->c, win->present_special_event);
403
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800404 intel_free(gpu, win);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800405}
406
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800407static struct intel_wsi_x11_window *wsi_x11_lookup_window(const struct intel_gpu *gpu,
408 struct intel_wsi_x11 *x11,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800409 xcb_window_t win_id)
410{
411 struct intel_wsi_x11_window *win = x11->windows;
412
413 while (win) {
414 if (win->window_id == win_id)
415 break;
416 win = win->next;
417 }
418
419 /* lookup failed */
420 if (!win) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800421 win = wsi_x11_create_window(gpu, x11, win_id);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800422 if (win) {
423 win->next = x11->windows;
424 x11->windows = win;
425 }
426 }
427
428 return win;
429}
430
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800431void intel_wsi_x11_destroy(const struct intel_gpu *gpu,
432 struct intel_wsi_x11 *x11)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800433{
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800434 struct intel_wsi_x11_window *win = x11->windows;
435
436 while (win) {
437 struct intel_wsi_x11_window *next = win->next;
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800438 wsi_x11_destroy_window(gpu, x11, win);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800439 win = next;
440 }
Chia-I Wu1db76e02014-09-15 14:21:14 +0800441
442 if (x11->fd >= 0)
443 close(x11->fd);
444
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800445 intel_free(gpu, x11);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800446}
447
448XGL_RESULT intel_wsi_x11_wait(struct intel_wsi_x11 *x11,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800449 struct intel_wsi_x11_window *win,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800450 uint32_t serial, bool wait)
451{
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800452 while (win->remote.serial < serial) {
Chia-I Wu1db76e02014-09-15 14:21:14 +0800453 xcb_present_generic_event_t *ev;
454
455 if (wait) {
456 ev = (xcb_present_generic_event_t *)
457 xcb_wait_for_special_event(x11->c,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800458 win->present_special_event);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800459 if (!ev)
460 return XGL_ERROR_UNKNOWN;
461 } else {
462 ev = (xcb_present_generic_event_t *)
463 xcb_poll_for_special_event(x11->c,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800464 win->present_special_event);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800465 if (!ev)
466 return XGL_NOT_READY;
467 }
468
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800469 wsi_x11_present_event(x11, win, ev);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800470
471 free(ev);
472 }
473
474 return XGL_SUCCESS;
475}
476
Chia-I Wuc505a6f2014-11-13 00:04:01 +0800477static bool wsi_x11_is_format_presentable(struct intel_wsi_x11 *x11,
478 struct intel_dev *dev,
479 XGL_FORMAT format)
480{
481 /* this is what DDX expects */
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700482 switch (format) {
483 case XGL_FMT_B5G6R5_UNORM:
484 case XGL_FMT_B8G8R8A8_UNORM:
485 case XGL_FMT_B8G8R8A8_SRGB:
486 return true;
Chia-I Wuc505a6f2014-11-13 00:04:01 +0800487 default:
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700488 return false;
Chia-I Wuc505a6f2014-11-13 00:04:01 +0800489 }
Chia-I Wuc505a6f2014-11-13 00:04:01 +0800490}
491
Chia-I Wu1db76e02014-09-15 14:21:14 +0800492/**
493 * Create a presentable image.
494 */
495static XGL_RESULT wsi_x11_img_create(struct intel_wsi_x11 *x11,
496 struct intel_dev *dev,
497 const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO *info,
498 struct intel_img **img_ret)
499{
500 XGL_IMAGE_CREATE_INFO img_info;
501 XGL_MEMORY_ALLOC_INFO mem_info;
502 struct intel_img *img;
503 struct intel_mem *mem;
504 XGL_RESULT ret;
505
Chia-I Wuc505a6f2014-11-13 00:04:01 +0800506 if (!wsi_x11_is_format_presentable(x11, dev, info->format)) {
507 intel_dev_log(dev, XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0,
508 XGL_NULL_HANDLE, 0, 0, "invalid presentable image format");
509 return XGL_ERROR_INVALID_VALUE;
510 }
511
Chia-I Wu1db76e02014-09-15 14:21:14 +0800512 /* create image */
513 memset(&img_info, 0, sizeof(img_info));
514 img_info.sType = XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
515 img_info.imageType = XGL_IMAGE_2D;
516 img_info.format = info->format;
517 img_info.extent.width = info->extent.width;
518 img_info.extent.height = info->extent.height;
519 img_info.extent.depth = 1;
520 img_info.mipLevels = 1;
521 img_info.arraySize = 1;
522 img_info.samples = 1;
523 img_info.tiling = XGL_OPTIMAL_TILING;
524 img_info.usage = info->usage;
525 img_info.flags = 0;
526
527 ret = intel_img_create(dev, &img_info, true, &img);
528 if (ret != XGL_SUCCESS)
529 return ret;
530
531 /* allocate memory */
532 memset(&mem_info, 0, sizeof(mem_info));
533 mem_info.sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
534 mem_info.allocationSize = img->total_size;
Jon Ashburn542cd092015-01-20 13:55:32 -0700535 mem_info.memProps = 0;
Jon Ashburn32769172015-01-20 15:06:59 -0700536 mem_info.memType = XGL_MEMORY_TYPE_IMAGE;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800537 mem_info.memPriority = XGL_MEMORY_PRIORITY_HIGH;
538
539 ret = intel_mem_alloc(dev, &mem_info, &mem);
540 if (ret != XGL_SUCCESS) {
541 intel_img_destroy(img);
542 return ret;
543 }
544
545 ret = wsi_x11_dri3_pixmap_from_buffer(x11, dev, img, mem);
546 if (ret != XGL_SUCCESS) {
547 intel_mem_free(mem);
548 intel_img_destroy(img);
549 return ret;
550 }
551
552 intel_obj_bind_mem(&img->obj, mem, 0);
553
554 *img_ret = img;
555
556 return XGL_SUCCESS;
557}
558
Chia-I Wu96177272015-01-03 15:27:41 +0800559ICD_EXPORT XGL_RESULT XGLAPI xglWsiX11AssociateConnection(
Chia-I Wu1db76e02014-09-15 14:21:14 +0800560 XGL_PHYSICAL_GPU gpu_,
561 const XGL_WSI_X11_CONNECTION_INFO* pConnectionInfo)
562{
563 struct intel_gpu *gpu = intel_gpu(gpu_);
564 struct intel_wsi_x11 *x11;
565 XGL_RESULT ret;
566
567 if (gpu->x11)
568 return XGL_SUCCESS;
569
Chia-I Wud8965932014-10-13 13:32:37 +0800570 if (gpu->winsys)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800571 return XGL_ERROR_DEVICE_ALREADY_CREATED;
572
573 if (!wsi_x11_has_dri3_and_present(pConnectionInfo->pConnection))
574 return XGL_ERROR_UNKNOWN;
575
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800576 x11 = wsi_x11_create(gpu, pConnectionInfo->pConnection,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800577 pConnectionInfo->root, pConnectionInfo->provider);
578 if (!x11)
579 return XGL_ERROR_UNKNOWN;
580
581 ret = wsi_x11_dri3_open(x11);
582 if (ret != XGL_SUCCESS) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800583 intel_wsi_x11_destroy(gpu, x11);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800584 return ret;
585 }
586
587 if (!wsi_x11_uses_gpu(x11, gpu)) {
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800588 intel_wsi_x11_destroy(gpu, x11);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800589 return XGL_ERROR_UNKNOWN;
590 }
591
Chia-I Wu1db76e02014-09-15 14:21:14 +0800592 intel_gpu_associate_x11(gpu, x11, x11->fd);
593
594 return XGL_SUCCESS;
595}
596
Chia-I Wu96177272015-01-03 15:27:41 +0800597ICD_EXPORT XGL_RESULT XGLAPI xglWsiX11GetMSC(
Chia-I Wu1db76e02014-09-15 14:21:14 +0800598 XGL_DEVICE device,
Chia-I Wu6204f342014-11-07 13:33:45 +0800599 xcb_window_t window,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800600 xcb_randr_crtc_t crtc,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600601 uint64_t * pMsc)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800602{
603 struct intel_dev *dev = intel_dev(device);
604 struct intel_wsi_x11 *x11 = dev->gpu->x11;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800605 struct intel_wsi_x11_window *win;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800606 XGL_RESULT ret;
607
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800608 win = wsi_x11_lookup_window(dev->gpu, x11, window);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800609 if (!win)
610 return XGL_ERROR_UNKNOWN;
611
612 wsi_x11_present_notify_msc(x11, win);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800613
614 /* wait for the event */
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800615 ret = intel_wsi_x11_wait(x11, win, win->local.serial, -1);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800616 if (ret != XGL_SUCCESS)
617 return ret;
618
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800619 *pMsc = win->remote.msc;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800620
621 return XGL_SUCCESS;
622}
623
Chia-I Wu96177272015-01-03 15:27:41 +0800624ICD_EXPORT XGL_RESULT XGLAPI xglWsiX11CreatePresentableImage(
Chia-I Wu1db76e02014-09-15 14:21:14 +0800625 XGL_DEVICE device,
626 const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO* pCreateInfo,
627 XGL_IMAGE* pImage,
628 XGL_GPU_MEMORY* pMem)
629{
630 struct intel_dev *dev = intel_dev(device);
631 struct intel_wsi_x11 *x11 = dev->gpu->x11;
632 struct intel_img *img;
633 XGL_RESULT ret;
634
635 ret = wsi_x11_img_create(x11, dev, pCreateInfo, &img);
636 if (ret == XGL_SUCCESS) {
637 *pImage = (XGL_IMAGE) img;
638 *pMem = (XGL_GPU_MEMORY) img->obj.mem;
639 }
640
641 return ret;
642}
643
Chia-I Wu96177272015-01-03 15:27:41 +0800644ICD_EXPORT XGL_RESULT XGLAPI xglWsiX11QueuePresent(
Chia-I Wu1db76e02014-09-15 14:21:14 +0800645 XGL_QUEUE queue_,
646 const XGL_WSI_X11_PRESENT_INFO* pPresentInfo,
647 XGL_FENCE fence_)
648{
649 struct intel_queue *queue = intel_queue(queue_);
650 struct intel_fence *fence = intel_fence(fence_);
651 struct intel_wsi_x11 *x11 = queue->dev->gpu->x11;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800652 struct intel_wsi_x11_window *win;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800653 XGL_RESULT ret;
654
Chia-I Wuf13ed3c2015-02-22 14:09:00 +0800655 win = wsi_x11_lookup_window(queue->dev->gpu,
656 x11, pPresentInfo->destWindow);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800657 if (!win)
658 return XGL_ERROR_UNKNOWN;
659
660 ret = wsi_x11_present_pixmap(x11, win, pPresentInfo);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800661 if (ret != XGL_SUCCESS)
662 return ret;
663
Chia-I Wubda4f622015-02-25 15:06:15 -0700664 if (fence) {
665 struct intel_img *img = intel_img(pPresentInfo->srcImage);
666
667 intel_fence_set_x11(fence, x11, win, win->local.serial,
668 img->obj.mem->bo);
669 }
Chia-I Wu1db76e02014-09-15 14:21:14 +0800670
671 return XGL_SUCCESS;
672}