blob: d484177f968387243d08648c118d73f7719e4028 [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;
57 XGL_UINT64 msc;
58 } 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 */
120static struct intel_wsi_x11 *wsi_x11_create(xcb_connection_t *c,
121 xcb_window_t root,
122 xcb_randr_provider_t provider)
123{
124 xcb_dri3_query_version_cookie_t dri3_cookie;
125 xcb_dri3_query_version_reply_t *dri3_reply;
126 xcb_present_query_version_cookie_t present_cookie;
127 xcb_present_query_version_reply_t *present_reply;
128 struct intel_wsi_x11 *x11;
129
130 dri3_cookie = xcb_dri3_query_version(c,
131 XCB_DRI3_MAJOR_VERSION, XCB_DRI3_MINOR_VERSION);
132 present_cookie = xcb_present_query_version(c,
133 XCB_PRESENT_MAJOR_VERSION, XCB_PRESENT_MINOR_VERSION);
134
135 x11 = icd_alloc(sizeof(*x11), 0, XGL_SYSTEM_ALLOC_INTERNAL);
136 if (!x11)
137 return NULL;
138 memset(x11, 0, sizeof(*x11));
139
140 x11->c = c;
141 x11->root = root;
142 x11->provider = provider;
143
144 x11->root_depth = wsi_x11_get_root_depth(x11);
145
146 dri3_reply = xcb_dri3_query_version_reply(c, dri3_cookie, NULL);
147 if (!dri3_reply) {
148 icd_free(x11);
149 return NULL;
150 }
151
152 x11->dri3_major = dri3_reply->major_version;
153 x11->dri3_minor = dri3_reply->minor_version;
154 free(dri3_reply);
155
156 present_reply = xcb_present_query_version_reply(c, present_cookie, NULL);
157 if (!present_reply) {
158 icd_free(x11);
159 return NULL;
160 }
161
162 x11->present_major = present_reply->major_version;
163 x11->present_minor = present_reply->minor_version;
164 free(present_reply);
165
166 x11->fd = -1;
167
168 return x11;
169}
170
171/**
172 * Return true if x11->fd points to the primary or render node of the GPU.
173 */
174static bool wsi_x11_uses_gpu(const struct intel_wsi_x11 *x11,
175 const struct intel_gpu *gpu)
176{
177 struct stat x11_stat, gpu_stat;
178
179 if (fstat(x11->fd, &x11_stat))
180 return false;
181
182 /* is it the primary node? */
183 if (!stat(gpu->primary_node, &gpu_stat) &&
184 !memcmp(&x11_stat, &gpu_stat, sizeof(x11_stat)))
185 return true;
186
187 /* is it the render node? */
188 if (gpu->render_node && !stat(gpu->render_node, &gpu_stat) &&
189 !memcmp(&x11_stat, &gpu_stat, sizeof(x11_stat)))
190 return true;
191
192 return false;
193}
194
195/**
196 * Send a DRI3Open to get the server GPU fd.
197 */
198static XGL_RESULT wsi_x11_dri3_open(struct intel_wsi_x11 *x11)
199{
200 xcb_dri3_open_cookie_t cookie;
201 xcb_dri3_open_reply_t *reply;
202 int fd;
203
204 cookie = xcb_dri3_open(x11->c, x11->root, x11->provider);
205 reply = xcb_dri3_open_reply(x11->c, cookie, NULL);
206 if (!reply)
207 return XGL_ERROR_UNKNOWN;
208
209 fd = (reply->nfd == 1) ? xcb_dri3_open_reply_fds(x11->c, reply)[0] : -1;
210 free(reply);
211
212 if (fd < 0)
213 return XGL_ERROR_UNKNOWN;
214
215 fcntl(fd, F_SETFD, FD_CLOEXEC);
216 x11->fd = fd;
217
218 return XGL_SUCCESS;
219}
220
221/**
222 * Send a DRI3PixmapFromBuffer to create a Pixmap from \p mem for \p img.
223 */
224static XGL_RESULT wsi_x11_dri3_pixmap_from_buffer(struct intel_wsi_x11 *x11,
225 struct intel_dev *dev,
226 struct intel_img *img,
227 struct intel_mem *mem)
228{
229 struct intel_winsys_handle export;
230 xcb_pixmap_t pixmap;
231
232 /* get prime fd of the bo first */
233 export.type = INTEL_WINSYS_HANDLE_FD;
234 if (intel_winsys_export_handle(dev->winsys, mem->bo, img->layout.tiling,
235 img->layout.bo_stride, img->layout.bo_height, &export))
236 return XGL_ERROR_UNKNOWN;
237
238 pixmap = xcb_generate_id(x11->c);
239
240 /* create a pixmap from the prime fd */
241 xcb_dri3_pixmap_from_buffer(x11->c, pixmap,
242 x11->root, img->total_size,
243 img->layout.width0, img->layout.height0,
244 img->layout.bo_stride, x11->root_depth,
245 img->layout.block_size * 8, export.handle);
246
247 img->x11_prime_fd = export.handle;
248 img->x11_pixmap = pixmap;
249
250 return XGL_SUCCESS;
251}
252
253/**
254 * Send a PresentSelectInput to select interested events.
255 */
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800256static XGL_RESULT wsi_x11_present_select_input(struct intel_wsi_x11 *x11,
257 struct intel_wsi_x11_window *win)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800258{
259 xcb_void_cookie_t cookie;
260 xcb_generic_error_t *error;
261
262 /* create the event queue */
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800263 win->present_special_event_id = xcb_generate_id(x11->c);
264 win->present_special_event = xcb_register_for_special_xge(x11->c,
265 &xcb_present_id, win->present_special_event_id, NULL);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800266
267 cookie = xcb_present_select_input_checked(x11->c,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800268 win->present_special_event_id, win->window_id,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800269 XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY);
270
271 error = xcb_request_check(x11->c, cookie);
272 if (error) {
273 free(error);
274 return XGL_ERROR_UNKNOWN;
275 }
276
277 return XGL_SUCCESS;
278}
279
280/**
281 * Send a PresentPixmap.
282 */
283static XGL_RESULT wsi_x11_present_pixmap(struct intel_wsi_x11 *x11,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800284 struct intel_wsi_x11_window *win,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800285 const XGL_WSI_X11_PRESENT_INFO *info)
286{
287 struct intel_img *img = intel_img(info->srcImage);
288 uint32_t options = XCB_PRESENT_OPTION_NONE;
289 xcb_void_cookie_t cookie;
290 xcb_generic_error_t *err;
291
292 if (info->async)
293 options |= XCB_PRESENT_OPTION_ASYNC;
294 if (!info->flip)
295 options |= XCB_PRESENT_OPTION_COPY;
296
297 cookie = xcb_present_pixmap(x11->c,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800298 win->window_id,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800299 img->x11_pixmap,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800300 ++win->local.serial,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800301 0, /* valid-area */
302 0, /* update-area */
303 0, /* x-off */
304 0, /* y-off */
305 info->crtc,
306 0, /* wait-fence */
307 0, /* idle-fence */
308 options,
309 info->target_msc,
310 info->divisor,
311 info->remainder,
312 0, NULL);
313
314 err = xcb_request_check(x11->c, cookie);
315 if (err) {
316 free(err);
317 return XGL_ERROR_UNKNOWN;
318 }
319
320 return XGL_SUCCESS;
321}
322
323/**
324 * Send a PresentNotifyMSC for the current MSC.
325 */
326static void wsi_x11_present_notify_msc(struct intel_wsi_x11 *x11,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800327 struct intel_wsi_x11_window *win)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800328{
329 /* cannot specify CRTC? */
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800330 xcb_present_notify_msc(x11->c, win->window_id, ++win->local.serial,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800331 0, 0, 0);
332
333 xcb_flush(x11->c);
334}
335
336/**
337 * Handle a Present event.
338 */
339static void wsi_x11_present_event(struct intel_wsi_x11 *x11,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800340 struct intel_wsi_x11_window *win,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800341 const xcb_present_generic_event_t *ev)
342{
343 union {
344 const xcb_present_generic_event_t *ev;
345 const xcb_present_complete_notify_event_t *complete;
346 } u = { .ev = ev };
347
348 switch (u.ev->evtype) {
349 case XCB_PRESENT_COMPLETE_NOTIFY:
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800350 win->remote.serial = u.complete->serial;
351 win->remote.msc = u.complete->msc;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800352 break;
353 default:
354 break;
355 }
356}
357
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800358static struct intel_wsi_x11_window *wsi_x11_create_window(struct intel_wsi_x11 *x11,
359 xcb_window_t win_id)
360{
361 struct intel_wsi_x11_window *win;
362
363 win = icd_alloc(sizeof(*win), 0, XGL_SYSTEM_ALLOC_INTERNAL);
364 if (!win)
365 return NULL;
366
367 memset(win, 0, sizeof(*win));
368
369 win->window_id = win_id;
370
371 if (wsi_x11_present_select_input(x11, win) != XGL_SUCCESS) {
372 icd_free(win);
373 return NULL;
374 }
375
376 return win;
377}
378
379static void wsi_x11_destroy_window(struct intel_wsi_x11 *x11,
380 struct intel_wsi_x11_window *win)
381{
382 if (win->present_special_event)
383 xcb_unregister_for_special_event(x11->c, win->present_special_event);
384
385 icd_free(win);
386}
387
388static struct intel_wsi_x11_window *wsi_x11_lookup_window(struct intel_wsi_x11 *x11,
389 xcb_window_t win_id)
390{
391 struct intel_wsi_x11_window *win = x11->windows;
392
393 while (win) {
394 if (win->window_id == win_id)
395 break;
396 win = win->next;
397 }
398
399 /* lookup failed */
400 if (!win) {
401 win = wsi_x11_create_window(x11, win_id);
402 if (win) {
403 win->next = x11->windows;
404 x11->windows = win;
405 }
406 }
407
408 return win;
409}
410
Chia-I Wu1db76e02014-09-15 14:21:14 +0800411void intel_wsi_x11_destroy(struct intel_wsi_x11 *x11)
412{
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800413 struct intel_wsi_x11_window *win = x11->windows;
414
415 while (win) {
416 struct intel_wsi_x11_window *next = win->next;
417 wsi_x11_destroy_window(x11, win);
418 win = next;
419 }
Chia-I Wu1db76e02014-09-15 14:21:14 +0800420
421 if (x11->fd >= 0)
422 close(x11->fd);
423
424 icd_free(x11);
425}
426
427XGL_RESULT intel_wsi_x11_wait(struct intel_wsi_x11 *x11,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800428 struct intel_wsi_x11_window *win,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800429 uint32_t serial, bool wait)
430{
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800431 while (win->remote.serial < serial) {
Chia-I Wu1db76e02014-09-15 14:21:14 +0800432 xcb_present_generic_event_t *ev;
433
434 if (wait) {
435 ev = (xcb_present_generic_event_t *)
436 xcb_wait_for_special_event(x11->c,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800437 win->present_special_event);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800438 if (!ev)
439 return XGL_ERROR_UNKNOWN;
440 } else {
441 ev = (xcb_present_generic_event_t *)
442 xcb_poll_for_special_event(x11->c,
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800443 win->present_special_event);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800444 if (!ev)
445 return XGL_NOT_READY;
446 }
447
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800448 wsi_x11_present_event(x11, win, ev);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800449
450 free(ev);
451 }
452
453 return XGL_SUCCESS;
454}
455
Chia-I Wuc505a6f2014-11-13 00:04:01 +0800456static bool wsi_x11_is_format_presentable(struct intel_wsi_x11 *x11,
457 struct intel_dev *dev,
458 XGL_FORMAT format)
459{
460 /* this is what DDX expects */
461 switch (format.channelFormat) {
462 case XGL_CH_FMT_B5G6R5:
463 if (format.numericFormat == XGL_NUM_FMT_UNORM)
464 return true;
465 break;
466 case XGL_CH_FMT_B8G8R8A8:
467 if (format.numericFormat == XGL_NUM_FMT_UNORM ||
468 format.numericFormat == XGL_NUM_FMT_SRGB)
469 return true;
470 break;
471 default:
472 break;
473 }
474
475 return false;
476}
477
Chia-I Wu1db76e02014-09-15 14:21:14 +0800478/**
479 * Create a presentable image.
480 */
481static XGL_RESULT wsi_x11_img_create(struct intel_wsi_x11 *x11,
482 struct intel_dev *dev,
483 const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO *info,
484 struct intel_img **img_ret)
485{
486 XGL_IMAGE_CREATE_INFO img_info;
487 XGL_MEMORY_ALLOC_INFO mem_info;
488 struct intel_img *img;
489 struct intel_mem *mem;
490 XGL_RESULT ret;
491
Chia-I Wuc505a6f2014-11-13 00:04:01 +0800492 if (!wsi_x11_is_format_presentable(x11, dev, info->format)) {
493 intel_dev_log(dev, XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0,
494 XGL_NULL_HANDLE, 0, 0, "invalid presentable image format");
495 return XGL_ERROR_INVALID_VALUE;
496 }
497
Chia-I Wu1db76e02014-09-15 14:21:14 +0800498 /* create image */
499 memset(&img_info, 0, sizeof(img_info));
500 img_info.sType = XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
501 img_info.imageType = XGL_IMAGE_2D;
502 img_info.format = info->format;
503 img_info.extent.width = info->extent.width;
504 img_info.extent.height = info->extent.height;
505 img_info.extent.depth = 1;
506 img_info.mipLevels = 1;
507 img_info.arraySize = 1;
508 img_info.samples = 1;
509 img_info.tiling = XGL_OPTIMAL_TILING;
510 img_info.usage = info->usage;
511 img_info.flags = 0;
512
513 ret = intel_img_create(dev, &img_info, true, &img);
514 if (ret != XGL_SUCCESS)
515 return ret;
516
517 /* allocate memory */
518 memset(&mem_info, 0, sizeof(mem_info));
519 mem_info.sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
520 mem_info.allocationSize = img->total_size;
521 mem_info.alignment = 4096;
522 mem_info.flags = 0;
523 mem_info.heapCount = 1;
524 mem_info.memPriority = XGL_MEMORY_PRIORITY_HIGH;
525
526 ret = intel_mem_alloc(dev, &mem_info, &mem);
527 if (ret != XGL_SUCCESS) {
528 intel_img_destroy(img);
529 return ret;
530 }
531
532 ret = wsi_x11_dri3_pixmap_from_buffer(x11, dev, img, mem);
533 if (ret != XGL_SUCCESS) {
534 intel_mem_free(mem);
535 intel_img_destroy(img);
536 return ret;
537 }
538
539 intel_obj_bind_mem(&img->obj, mem, 0);
540
541 *img_ret = img;
542
543 return XGL_SUCCESS;
544}
545
546XGL_RESULT XGLAPI intelWsiX11AssociateConnection(
547 XGL_PHYSICAL_GPU gpu_,
548 const XGL_WSI_X11_CONNECTION_INFO* pConnectionInfo)
549{
550 struct intel_gpu *gpu = intel_gpu(gpu_);
551 struct intel_wsi_x11 *x11;
552 XGL_RESULT ret;
553
554 if (gpu->x11)
555 return XGL_SUCCESS;
556
Chia-I Wud8965932014-10-13 13:32:37 +0800557 if (gpu->winsys)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800558 return XGL_ERROR_DEVICE_ALREADY_CREATED;
559
560 if (!wsi_x11_has_dri3_and_present(pConnectionInfo->pConnection))
561 return XGL_ERROR_UNKNOWN;
562
563 x11 = wsi_x11_create(pConnectionInfo->pConnection,
564 pConnectionInfo->root, pConnectionInfo->provider);
565 if (!x11)
566 return XGL_ERROR_UNKNOWN;
567
568 ret = wsi_x11_dri3_open(x11);
569 if (ret != XGL_SUCCESS) {
570 intel_wsi_x11_destroy(x11);
571 return ret;
572 }
573
574 if (!wsi_x11_uses_gpu(x11, gpu)) {
575 intel_wsi_x11_destroy(x11);
576 return XGL_ERROR_UNKNOWN;
577 }
578
Chia-I Wu1db76e02014-09-15 14:21:14 +0800579 intel_gpu_associate_x11(gpu, x11, x11->fd);
580
581 return XGL_SUCCESS;
582}
583
584XGL_RESULT XGLAPI intelWsiX11GetMSC(
585 XGL_DEVICE device,
Chia-I Wu6204f342014-11-07 13:33:45 +0800586 xcb_window_t window,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800587 xcb_randr_crtc_t crtc,
588 XGL_UINT64* pMsc)
589{
590 struct intel_dev *dev = intel_dev(device);
591 struct intel_wsi_x11 *x11 = dev->gpu->x11;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800592 struct intel_wsi_x11_window *win;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800593 XGL_RESULT ret;
594
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800595 win = wsi_x11_lookup_window(x11, window);
596 if (!win)
597 return XGL_ERROR_UNKNOWN;
598
599 wsi_x11_present_notify_msc(x11, win);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800600
601 /* wait for the event */
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800602 ret = intel_wsi_x11_wait(x11, win, win->local.serial, -1);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800603 if (ret != XGL_SUCCESS)
604 return ret;
605
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800606 *pMsc = win->remote.msc;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800607
608 return XGL_SUCCESS;
609}
610
611XGL_RESULT XGLAPI intelWsiX11CreatePresentableImage(
612 XGL_DEVICE device,
613 const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO* pCreateInfo,
614 XGL_IMAGE* pImage,
615 XGL_GPU_MEMORY* pMem)
616{
617 struct intel_dev *dev = intel_dev(device);
618 struct intel_wsi_x11 *x11 = dev->gpu->x11;
619 struct intel_img *img;
620 XGL_RESULT ret;
621
622 ret = wsi_x11_img_create(x11, dev, pCreateInfo, &img);
623 if (ret == XGL_SUCCESS) {
624 *pImage = (XGL_IMAGE) img;
625 *pMem = (XGL_GPU_MEMORY) img->obj.mem;
626 }
627
628 return ret;
629}
630
631XGL_RESULT XGLAPI intelWsiX11QueuePresent(
632 XGL_QUEUE queue_,
633 const XGL_WSI_X11_PRESENT_INFO* pPresentInfo,
634 XGL_FENCE fence_)
635{
636 struct intel_queue *queue = intel_queue(queue_);
637 struct intel_fence *fence = intel_fence(fence_);
638 struct intel_wsi_x11 *x11 = queue->dev->gpu->x11;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800639 struct intel_wsi_x11_window *win;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800640 XGL_RESULT ret;
641
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800642 win = wsi_x11_lookup_window(x11, pPresentInfo->destWindow);
643 if (!win)
644 return XGL_ERROR_UNKNOWN;
645
646 ret = wsi_x11_present_pixmap(x11, win, pPresentInfo);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800647 if (ret != XGL_SUCCESS)
648 return ret;
649
650 if (fence)
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800651 intel_fence_set_x11(fence, x11, win, win->local.serial);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800652
653 return XGL_SUCCESS;
654}