blob: 64435241fbc678af3bdecdfc48d5100c476d554a [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 Goeltzenleuchter382489d2015-04-10 08:34:15 -060053 VkExtent2D physical_dimension;
54 VkExtent2D 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 Goeltzenleuchter382489d2015-04-10 08:34:15 -0600106 VkFormat format)
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800107{
108 /* this is what DDX expects */
109 switch (format) {
Tony Barbour8205d902015-04-16 15:59:00 -0600110 case VK_FORMAT_B5G6R5_UNORM:
111 case VK_FORMAT_B8G8R8A8_UNORM:
112 case VK_FORMAT_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 Goeltzenleuchter382489d2015-04-10 08:34:15 -0600298static VkResult 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 Goeltzenleuchter382489d2015-04-10 08:34:15 -0600321static VkResult wsi_x11_dri3_pixmap_from_buffer(struct intel_wsi_x11 *x11,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600322 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 Goeltzenleuchter382489d2015-04-10 08:34:15 -0600344static VkResult wsi_x11_img_create(struct intel_wsi_x11 *x11,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600345 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 Goeltzenleuchter382489d2015-04-10 08:34:15 -0600349 VkImageCreateInfo 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 Goeltzenleuchter382489d2015-04-10 08:34:15 -0600353 VkResult 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;
Tony Barbour8205d902015-04-16 15:59:00 -0600364 img_info.imageType = VK_IMAGE_TYPE_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;
Tony Barbour8205d902015-04-16 15:59:00 -0600372 img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
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.memPriority = VK_MEMORY_PRIORITY_HIGH;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800386
387 ret = intel_mem_alloc(dev, &mem_info, &mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600388 if (ret != VK_SUCCESS) {
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800389 intel_img_destroy(img);
390 return ret;
391 }
392
393 ret = wsi_x11_dri3_pixmap_from_buffer(x11, dev, img, mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600394 if (ret != VK_SUCCESS) {
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800395 intel_mem_free(mem);
396 intel_img_destroy(img);
397 return ret;
398 }
399
400 intel_obj_bind_mem(&img->obj, mem, 0);
401
402 *img_ret = img;
403
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600404 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800405}
406
407/**
408 * Send a PresentPixmap.
409 */
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600410static VkResult x11_swap_chain_present_pixmap(struct intel_x11_swap_chain *sc,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600411 const VK_WSI_X11_PRESENT_INFO *info)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800412{
413 struct intel_img *img = intel_img(info->srcImage);
Chia-I Wu41858c82015-04-04 16:39:25 +0800414 struct intel_x11_img_data *data =
415 (struct intel_x11_img_data *) img->wsi_data;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800416 uint32_t options = XCB_PRESENT_OPTION_NONE;
417 xcb_void_cookie_t cookie;
418 xcb_generic_error_t *err;
419
420 if (info->async)
421 options |= XCB_PRESENT_OPTION_ASYNC;
422 if (!info->flip)
423 options |= XCB_PRESENT_OPTION_COPY;
424
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800425 cookie = xcb_present_pixmap(sc->c,
426 sc->window,
Chia-I Wu41858c82015-04-04 16:39:25 +0800427 data->pixmap,
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800428 ++sc->local.serial,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800429 0, /* valid-area */
430 0, /* update-area */
431 0, /* x-off */
432 0, /* y-off */
433 info->crtc,
434 0, /* wait-fence */
435 0, /* idle-fence */
436 options,
437 info->target_msc,
438 info->divisor,
439 info->remainder,
440 0, NULL);
441
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800442 err = xcb_request_check(sc->c, cookie);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800443 if (err) {
444 free(err);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600445 return VK_ERROR_UNKNOWN;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800446 }
447
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600448 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800449}
450
451/**
452 * Send a PresentNotifyMSC for the current MSC.
453 */
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800454static void x11_swap_chain_present_notify_msc(struct intel_x11_swap_chain *sc)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800455{
456 /* cannot specify CRTC? */
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800457 xcb_present_notify_msc(sc->c, sc->window, ++sc->local.serial, 0, 0, 0);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800458
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800459 xcb_flush(sc->c);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800460}
461
462/**
463 * Handle a Present event.
464 */
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800465static void x11_swap_chain_present_event(struct intel_x11_swap_chain *sc,
466 const xcb_present_generic_event_t *ev)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800467{
468 union {
469 const xcb_present_generic_event_t *ev;
470 const xcb_present_complete_notify_event_t *complete;
471 } u = { .ev = ev };
472
473 switch (u.ev->evtype) {
474 case XCB_PRESENT_COMPLETE_NOTIFY:
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800475 sc->remote.serial = u.complete->serial;
476 sc->remote.msc = u.complete->msc;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800477 break;
478 default:
479 break;
480 }
481}
482
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600483static VkResult x11_swap_chain_wait(struct intel_x11_swap_chain *sc,
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800484 uint32_t serial, int64_t timeout)
485{
486 const bool wait = (timeout != 0);
487
488 while (sc->remote.serial < serial) {
489 xcb_present_generic_event_t *ev;
490
491 if (wait) {
492 ev = (xcb_present_generic_event_t *)
493 xcb_wait_for_special_event(sc->c, sc->present_special_event);
494 if (!ev)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600495 return VK_ERROR_UNKNOWN;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800496 } else {
497 ev = (xcb_present_generic_event_t *)
498 xcb_poll_for_special_event(sc->c, sc->present_special_event);
499 if (!ev)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600500 return VK_NOT_READY;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800501 }
502
503 x11_swap_chain_present_event(sc, ev);
504
505 free(ev);
506 }
507
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600508 return VK_SUCCESS;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800509}
510
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800511static void x11_swap_chain_destroy(struct intel_x11_swap_chain *sc)
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800512{
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800513 if (sc->present_special_event)
514 xcb_unregister_for_special_event(sc->c, sc->present_special_event);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800515
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800516 intel_free(sc, sc);
517}
518
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800519static void wsi_x11_destroy(struct intel_wsi_x11 *x11)
520{
521 struct intel_x11_swap_chain *sc = x11->swap_chains;
522
523 while (sc) {
524 struct intel_x11_swap_chain *next = sc->next;
525 x11_swap_chain_destroy(sc);
526 sc = next;
527 }
528
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800529 intel_free(x11, x11);
530}
531
532static struct intel_wsi_x11 *wsi_x11_create(struct intel_gpu *gpu,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600533 const VK_WSI_X11_CONNECTION_INFO *info)
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800534{
535 struct intel_wsi_x11 *x11;
Chia-I Wufcbc5252015-04-08 11:44:26 +0800536 int depth, fd;
537
538 if (!x11_is_dri3_and_present_supported(info->pConnection))
539 return NULL;
540
541 depth = x11_get_drawable_depth(info->pConnection, info->root);
542 if (!depth)
543 return NULL;
544
545 fd = x11_dri3_open(info->pConnection, info->root, info->provider);
546 if (fd < 0 || !x11_gpu_match_fd(gpu, fd)) {
547 if (fd >= 0)
548 close(fd);
549 return NULL;
550 }
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800551
Tony Barbour8205d902015-04-16 15:59:00 -0600552 x11 = intel_alloc(gpu, sizeof(*x11), 0, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800553 if (!x11)
554 return NULL;
555
556 memset(x11, 0, sizeof(*x11));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600557 /* there is no VK_DBG_OBJECT_WSI_DISPLAY */
558 intel_handle_init(&x11->handle, VK_DBG_OBJECT_UNKNOWN, gpu->handle.icd);
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800559
560 x11->c = info->pConnection;
561 x11->root = info->root;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800562
Chia-I Wufcbc5252015-04-08 11:44:26 +0800563 x11->root_depth = depth;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800564
Chia-I Wufcbc5252015-04-08 11:44:26 +0800565 if (!wsi_x11_dri3_and_present_query_version(x11)) {
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800566 wsi_x11_destroy(x11);
567 return NULL;
568 }
569
570 return x11;
571}
572
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800573static struct intel_x11_swap_chain *x11_swap_chain_create(struct intel_dev *dev,
574 xcb_window_t window)
575{
576 struct intel_wsi_x11 *x11 = (struct intel_wsi_x11 *) dev->gpu->wsi_data;
577 struct intel_x11_swap_chain *sc;
578
Tony Barbour8205d902015-04-16 15:59:00 -0600579 sc = intel_alloc(dev, sizeof(*sc), 0, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800580 if (!sc)
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800581 return NULL;
582
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800583 memset(sc, 0, sizeof(*sc));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600584 /* there is no VK_DBG_OBJECT_WSI_SWAP_CHAIN */
585 intel_handle_init(&sc->handle, VK_DBG_OBJECT_UNKNOWN,
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800586 dev->base.handle.icd);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800587
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800588 sc->c = x11->c;
589 sc->window = window;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800590
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600591 if (x11_swap_chain_present_select_input(sc) != VK_SUCCESS) {
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800592 intel_free(dev, sc);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800593 return NULL;
594 }
595
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800596 return sc;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800597}
598
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800599static struct intel_x11_swap_chain *x11_swap_chain_lookup(struct intel_dev *dev,
600 xcb_window_t window)
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800601{
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800602 struct intel_wsi_x11 *x11 = (struct intel_wsi_x11 *) dev->gpu->wsi_data;
603 struct intel_x11_swap_chain *sc = x11->swap_chains;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800604
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800605 while (sc) {
606 if (sc->window == window)
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800607 break;
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800608 sc = sc->next;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800609 }
610
611 /* lookup failed */
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800612 if (!sc) {
613 sc = x11_swap_chain_create(dev, window);
614 if (sc) {
615 sc->next = x11->swap_chains;
616 x11->swap_chains = sc;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800617 }
618 }
619
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800620 return sc;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800621}
622
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600623static VkResult intel_wsi_gpu_init(struct intel_gpu *gpu,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600624 const VK_WSI_X11_CONNECTION_INFO *info)
Chia-I Wu41858c82015-04-04 16:39:25 +0800625{
626 struct intel_wsi_x11 *x11;
627
628 x11 = wsi_x11_create(gpu, info);
629 if (!x11)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600630 return VK_ERROR_UNKNOWN;
Chia-I Wu41858c82015-04-04 16:39:25 +0800631
632 gpu->wsi_data = x11;
633
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600634 return VK_SUCCESS;
Chia-I Wu41858c82015-04-04 16:39:25 +0800635}
636
Chia-I Wu8635e912015-04-09 14:13:57 +0800637static void x11_display_init_modes(struct intel_x11_display *dpy,
638 const drmModeConnectorPtr conn)
639{
640 int i;
641
642 if (!conn->count_modes)
643 return;
644
645 dpy->modes = intel_alloc(dpy, sizeof(dpy->modes[0]) * conn->count_modes,
Tony Barbour8205d902015-04-16 15:59:00 -0600646 0, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
Chia-I Wu8635e912015-04-09 14:13:57 +0800647 if (!dpy->modes)
648 return;
649
650 for (i = 0; i < conn->count_modes; i++) {
651 dpy->modes[i] = conn->modes[i];
652
653 if (dpy->physical_resolution.width < conn->modes[i].hdisplay &&
654 dpy->physical_resolution.height < conn->modes[i].vdisplay) {
655 dpy->physical_resolution.width = conn->modes[i].hdisplay;
656 dpy->physical_resolution.height = conn->modes[i].vdisplay;
657 }
658 }
659
660 dpy->mode_count = conn->count_modes;
661
662 dpy->physical_dimension.width = conn->mmWidth;
663 dpy->physical_dimension.height = conn->mmHeight;
664}
665
666static void x11_display_init_name(struct intel_x11_display *dpy,
667 const drmModeConnectorPtr conn)
668{
669 static const char *connector_names[] = {
670 [DRM_MODE_CONNECTOR_Unknown] = "Unknown",
671 [DRM_MODE_CONNECTOR_VGA] = "VGA",
672 [DRM_MODE_CONNECTOR_DVII] = "DVII",
673 [DRM_MODE_CONNECTOR_DVID] = "DVID",
674 [DRM_MODE_CONNECTOR_DVIA] = "DVIA",
675 [DRM_MODE_CONNECTOR_Composite] = "Composite",
676 [DRM_MODE_CONNECTOR_SVIDEO] = "SVIDEO",
677 [DRM_MODE_CONNECTOR_LVDS] = "LVDS",
678 [DRM_MODE_CONNECTOR_Component] = "COMPONENT",
679 [DRM_MODE_CONNECTOR_9PinDIN] = "9PinDIN",
680 [DRM_MODE_CONNECTOR_DisplayPort] = "DisplayPort",
681 [DRM_MODE_CONNECTOR_HDMIA] = "HDMIA",
682 [DRM_MODE_CONNECTOR_HDMIB] = "HDMIB",
683 [DRM_MODE_CONNECTOR_TV] = "TV",
684 [DRM_MODE_CONNECTOR_eDP] = "eDP",
685 [DRM_MODE_CONNECTOR_VIRTUAL] = "VIRTUAL",
686 [DRM_MODE_CONNECTOR_DSI] = "DSI",
687 };
688 const char *name;
689
690 name = (conn->connector_type < ARRAY_SIZE(connector_names)) ?
691 connector_names[conn->connector_type] : NULL;
692 if (!name)
693 name = connector_names[DRM_MODE_CONNECTOR_Unknown];
694
695 snprintf(dpy->name, sizeof(dpy->name),
696 "%s%d", name, conn->connector_type_id);
697}
698
699static void x11_display_destroy(struct intel_x11_display *dpy)
700{
701 intel_free(dpy, dpy->modes);
702 intel_free(dpy, dpy);
703}
704
705static struct intel_x11_display *x11_display_create(struct intel_gpu *gpu,
706 int fd,
707 uint32_t connector_id)
708{
709 struct intel_x11_display *dpy;
710 drmModeConnectorPtr conn;
711
Tony Barbour8205d902015-04-16 15:59:00 -0600712 dpy = intel_alloc(gpu, sizeof(*dpy), 0, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
Chia-I Wu8635e912015-04-09 14:13:57 +0800713 if (!dpy)
714 return NULL;
715
716 memset(dpy, 0, sizeof(*dpy));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600717 /* there is no VK_DBG_OBJECT_WSI_DISPLAY */
718 intel_handle_init(&dpy->handle, VK_DBG_OBJECT_UNKNOWN, gpu->handle.icd);
Chia-I Wu8635e912015-04-09 14:13:57 +0800719
720 dpy->fd = fd;
721 dpy->connector_id = connector_id;
722
723 conn = drmModeGetConnector(fd, connector_id);
724 if (!conn) {
725 x11_display_destroy(dpy);
726 return NULL;
727 }
728
729 x11_display_init_name(dpy, conn);
730 x11_display_init_modes(dpy, conn);
731
732 drmModeFreeConnector(conn);
733
734 return dpy;
735}
736
737static void x11_display_scan(struct intel_gpu *gpu)
738{
739 struct intel_x11_display **displays;
740 drmModeResPtr res;
741 int fd, i;
742
743 fd = intel_gpu_get_primary_fd(gpu);
744 if (fd < 0)
745 return;
746
747 res = drmModeGetResources(fd);
748 if (!res)
749 return;
750
751 displays = intel_alloc(gpu, sizeof(*displays) * res->count_connectors,
Tony Barbour8205d902015-04-16 15:59:00 -0600752 0, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
Chia-I Wu8635e912015-04-09 14:13:57 +0800753 if (!displays) {
754 drmModeFreeResources(res);
755 return;
756 }
757
758 for (i = 0; i < res->count_connectors; i++) {
759 displays[i] = x11_display_create(gpu, fd, res->connectors[i]);
760 if (!displays[i])
761 break;
762 }
763
764 drmModeFreeResources(res);
765
766 gpu->displays = (struct intel_wsi_display **) displays;
767 gpu->display_count = i;
768}
769
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600770VkResult intel_wsi_gpu_get_info(struct intel_gpu *gpu,
Tony Barbour8205d902015-04-16 15:59:00 -0600771 VkPhysicalDeviceInfoType type,
Chia-I Wu41858c82015-04-04 16:39:25 +0800772 size_t *size, void *data)
773{
Chia-I Wu8635e912015-04-09 14:13:57 +0800774 if (false)
775 x11_display_scan(gpu);
776
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600777 return VK_ERROR_INVALID_VALUE;
Chia-I Wu41858c82015-04-04 16:39:25 +0800778}
779
780void intel_wsi_gpu_cleanup(struct intel_gpu *gpu)
781{
Chia-I Wu8635e912015-04-09 14:13:57 +0800782 if (gpu->displays) {
783 uint32_t i;
Chia-I Wu41858c82015-04-04 16:39:25 +0800784
Chia-I Wu8635e912015-04-09 14:13:57 +0800785 for (i = 0; i < gpu->display_count; i++) {
786 struct intel_x11_display *dpy =
787 (struct intel_x11_display *) gpu->displays[i];
788 x11_display_destroy(dpy);
789 }
790 intel_free(gpu, gpu->displays);
791 }
792
793 if (gpu->wsi_data) {
794 struct intel_wsi_x11 *x11 = (struct intel_wsi_x11 *) gpu->wsi_data;
795 wsi_x11_destroy(x11);
796 }
Chia-I Wu41858c82015-04-04 16:39:25 +0800797}
798
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600799VkResult intel_wsi_img_init(struct intel_img *img)
Chia-I Wu41858c82015-04-04 16:39:25 +0800800{
801 struct intel_x11_img_data *data;
802
Tony Barbour8205d902015-04-16 15:59:00 -0600803 data = intel_alloc(img, sizeof(*data), 0, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
Chia-I Wu41858c82015-04-04 16:39:25 +0800804 if (!data)
Tony Barbour8205d902015-04-16 15:59:00 -0600805 return VK_ERROR_OUT_OF_HOST_MEMORY;
Chia-I Wu41858c82015-04-04 16:39:25 +0800806
807 memset(data, 0, sizeof(*data));
808
809 assert(!img->wsi_data);
810 img->wsi_data = data;
811
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600812 return VK_SUCCESS;
Chia-I Wu41858c82015-04-04 16:39:25 +0800813}
814
815void intel_wsi_img_cleanup(struct intel_img *img)
816{
817 struct intel_x11_img_data *data =
818 (struct intel_x11_img_data *) img->wsi_data;
819
820 if (data->mem) {
821 close(data->prime_fd);
822 intel_mem_free(data->mem);
823 }
824
825 intel_free(img, img->wsi_data);
826}
827
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600828VkResult intel_wsi_fence_init(struct intel_fence *fence)
Chia-I Wu41858c82015-04-04 16:39:25 +0800829{
830 struct intel_x11_fence_data *data;
831
Tony Barbour8205d902015-04-16 15:59:00 -0600832 data = intel_alloc(fence, sizeof(*data), 0, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
Chia-I Wu41858c82015-04-04 16:39:25 +0800833 if (!data)
Tony Barbour8205d902015-04-16 15:59:00 -0600834 return VK_ERROR_OUT_OF_HOST_MEMORY;
Chia-I Wu41858c82015-04-04 16:39:25 +0800835
836 memset(data, 0, sizeof(*data));
837
838 assert(!fence->wsi_data);
839 fence->wsi_data = data;
840
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600841 return VK_SUCCESS;
Chia-I Wu41858c82015-04-04 16:39:25 +0800842}
843
844void intel_wsi_fence_cleanup(struct intel_fence *fence)
845{
846 intel_free(fence, fence->wsi_data);
847}
848
849void intel_wsi_fence_copy(struct intel_fence *fence,
850 const struct intel_fence *src)
851{
852 memcpy(fence->wsi_data, src->wsi_data,
853 sizeof(struct intel_x11_fence_data));
854}
855
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600856VkResult intel_wsi_fence_wait(struct intel_fence *fence,
Chia-I Wu41858c82015-04-04 16:39:25 +0800857 int64_t timeout_ns)
858{
859 struct intel_x11_fence_data *data =
860 (struct intel_x11_fence_data *) fence->wsi_data;
861
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800862 if (!data->swap_chain)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600863 return VK_SUCCESS;
Chia-I Wu41858c82015-04-04 16:39:25 +0800864
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800865 return x11_swap_chain_wait(data->swap_chain, data->serial, timeout_ns);
Chia-I Wu41858c82015-04-04 16:39:25 +0800866}
867
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600868ICD_EXPORT VkResult VKAPI vkWsiX11AssociateConnection(
Tony Barbour8205d902015-04-16 15:59:00 -0600869 VkPhysicalDevice gpu_,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600870 const VK_WSI_X11_CONNECTION_INFO* pConnectionInfo)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800871{
872 struct intel_gpu *gpu = intel_gpu(gpu_);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800873
Chia-I Wu41858c82015-04-04 16:39:25 +0800874 return intel_wsi_gpu_init(gpu, pConnectionInfo);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800875}
876
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600877ICD_EXPORT VkResult VKAPI vkWsiX11GetMSC(
878 VkDevice device,
Chia-I Wu6204f342014-11-07 13:33:45 +0800879 xcb_window_t window,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800880 xcb_randr_crtc_t crtc,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600881 uint64_t * pMsc)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800882{
883 struct intel_dev *dev = intel_dev(device);
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800884 struct intel_x11_swap_chain *sc;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600885 VkResult ret;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800886
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800887 sc = x11_swap_chain_lookup(dev, window);
888 if (!sc)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600889 return VK_ERROR_UNKNOWN;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800890
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800891 x11_swap_chain_present_notify_msc(sc);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800892
893 /* wait for the event */
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800894 ret = x11_swap_chain_wait(sc, sc->local.serial, -1);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600895 if (ret != VK_SUCCESS)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800896 return ret;
897
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800898 *pMsc = sc->remote.msc;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800899
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600900 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800901}
902
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600903ICD_EXPORT VkResult VKAPI vkWsiX11CreatePresentableImage(
904 VkDevice device,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600905 const VK_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO* pCreateInfo,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600906 VkImage* pImage,
Tony Barbour8205d902015-04-16 15:59:00 -0600907 VkDeviceMemory* pMem)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800908{
909 struct intel_dev *dev = intel_dev(device);
Chia-I Wu41858c82015-04-04 16:39:25 +0800910 struct intel_wsi_x11 *x11 = (struct intel_wsi_x11 *) dev->gpu->wsi_data;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800911 struct intel_img *img;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600912 VkResult ret;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800913
914 ret = wsi_x11_img_create(x11, dev, pCreateInfo, &img);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600915 if (ret == VK_SUCCESS) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600916 *pImage = (VkImage) img;
Tony Barbour8205d902015-04-16 15:59:00 -0600917 *pMem = (VkDeviceMemory) img->obj.mem;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800918 }
919
920 return ret;
921}
922
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600923ICD_EXPORT VkResult VKAPI vkWsiX11QueuePresent(
924 VkQueue queue_,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600925 const VK_WSI_X11_PRESENT_INFO* pPresentInfo,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600926 VkFence fence_)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800927{
928 struct intel_queue *queue = intel_queue(queue_);
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800929 struct intel_dev *dev = queue->dev;
Chia-I Wub56f5df2015-04-04 20:21:10 +0800930 struct intel_x11_fence_data *data =
931 (struct intel_x11_fence_data *) queue->fence->wsi_data;
932 struct intel_img *img = intel_img(pPresentInfo->srcImage);
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800933 struct intel_x11_swap_chain *sc;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600934 VkResult ret;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800935
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800936 sc = x11_swap_chain_lookup(dev, pPresentInfo->destWindow);
937 if (!sc)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600938 return VK_ERROR_UNKNOWN;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800939
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800940 ret = x11_swap_chain_present_pixmap(sc, pPresentInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600941 if (ret != VK_SUCCESS)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800942 return ret;
943
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800944 data->swap_chain = sc;
945 data->serial = sc->local.serial;
Chia-I Wub56f5df2015-04-04 20:21:10 +0800946 intel_fence_set_seqno(queue->fence, img->obj.mem->bo);
Chia-I Wubda4f622015-02-25 15:06:15 -0700947
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600948 if (fence_ != VK_NULL_HANDLE) {
Chia-I Wub56f5df2015-04-04 20:21:10 +0800949 struct intel_fence *fence = intel_fence(fence_);
950 intel_fence_copy(fence, queue->fence);
Chia-I Wubda4f622015-02-25 15:06:15 -0700951 }
Chia-I Wu1db76e02014-09-15 14:21:14 +0800952
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600953 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800954}