blob: 4789b147c5e46c66d72925e819fe867e6f5a55eb [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 Wu5b66aa52015-04-16 22:02:10 +080065 bool force_copy;
66
67 int dri3_major, dri3_minor;
68 int present_major, present_minor;
Chia-I Wu1db76e02014-09-15 14:21:14 +080069
70 xcb_present_event_t present_special_event_id;
71 xcb_special_event_t *present_special_event;
72
Chia-I Wu5b66aa52015-04-16 22:02:10 +080073 struct intel_img **persistent_images;
74 uint32_t persistent_image_count;
75
Chia-I Wu1db76e02014-09-15 14:21:14 +080076 struct {
77 uint32_t serial;
78 } local;
79
80 struct {
81 uint32_t serial;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060082 uint64_t msc;
Chia-I Wu1db76e02014-09-15 14:21:14 +080083 } remote;
84};
85
Chia-I Wu41858c82015-04-04 16:39:25 +080086struct intel_x11_img_data {
Chia-I Wu5b66aa52015-04-16 22:02:10 +080087 struct intel_x11_swap_chain *swap_chain;
Chia-I Wu41858c82015-04-04 16:39:25 +080088 struct intel_mem *mem;
89 int prime_fd;
90 uint32_t pixmap;
91};
92
93struct intel_x11_fence_data {
Chia-I Wu6532d1d2015-04-04 22:16:45 +080094 struct intel_x11_swap_chain *swap_chain;
Chia-I Wu41858c82015-04-04 16:39:25 +080095 uint32_t serial;
96};
97
Chia-I Wu5b66aa52015-04-16 22:02:10 +080098/* these are what DDX expects */
99static const VkFormat x11_presentable_formats[] = {
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800100 VK_FORMAT_B8G8R8A8_UNORM,
101 VK_FORMAT_B8G8R8A8_SRGB,
Ian Elliott32536f92015-04-21 16:41:02 -0600102 VK_FORMAT_B5G6R5_UNORM,
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800103};
104
105static inline struct intel_x11_display *x11_display(VkDisplayWSI dpy)
106{
107 return (struct intel_x11_display *) dpy;
108}
109
110static inline struct intel_x11_swap_chain *x11_swap_chain(VkSwapChainWSI sc)
111{
112 return (struct intel_x11_swap_chain *) sc;
113}
114
Chia-I Wufcbc5252015-04-08 11:44:26 +0800115static bool x11_is_format_presentable(const struct intel_dev *dev,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600116 VkFormat format)
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800117{
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800118 uint32_t i;
119
120 for (i = 0; i < ARRAY_SIZE(x11_presentable_formats); i++) {
121 if (x11_presentable_formats[i] == format)
122 return true;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800123 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800124
125 return false;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800126}
127
Chia-I Wu030b2db2015-04-08 13:46:29 +0800128static int x11_export_prime_fd(struct intel_dev *dev,
129 struct intel_bo *bo,
130 const struct intel_layout *layout)
131{
132 struct intel_winsys_handle export;
133 enum intel_tiling_mode tiling;
134
135 export.type = INTEL_WINSYS_HANDLE_FD;
136
137 switch (layout->tiling) {
138 case GEN6_TILING_X:
139 tiling = INTEL_TILING_X;
140 break;
141 case GEN6_TILING_Y:
142 tiling = INTEL_TILING_Y;
143 break;
144 default:
145 assert(layout->tiling == GEN6_TILING_NONE);
146 tiling = INTEL_TILING_NONE;
147 break;
148 }
149
150 if (intel_bo_set_tiling(bo, tiling, layout->bo_stride))
151 return -1;
152
153 if (intel_winsys_export_handle(dev->winsys, bo, tiling,
154 layout->bo_stride, layout->bo_height, &export))
155 return -1;
156
157 return (int) export.handle;
158}
159
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800160/**
Chia-I Wufcbc5252015-04-08 11:44:26 +0800161 * Return true if fd points to the primary or render node of the GPU.
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800162 */
Chia-I Wufcbc5252015-04-08 11:44:26 +0800163static bool x11_gpu_match_fd(const struct intel_gpu *gpu, int fd)
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800164{
Chia-I Wufcbc5252015-04-08 11:44:26 +0800165 struct stat fd_stat, gpu_stat;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800166
Chia-I Wufcbc5252015-04-08 11:44:26 +0800167 if (fstat(fd, &fd_stat))
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800168 return false;
169
170 /* is it the primary node? */
171 if (!stat(gpu->primary_node, &gpu_stat) &&
Chia-I Wufcbc5252015-04-08 11:44:26 +0800172 !memcmp(&fd_stat, &gpu_stat, sizeof(fd_stat)))
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800173 return true;
174
175 /* is it the render node? */
176 if (gpu->render_node && !stat(gpu->render_node, &gpu_stat) &&
Chia-I Wufcbc5252015-04-08 11:44:26 +0800177 !memcmp(&fd_stat, &gpu_stat, sizeof(fd_stat)))
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800178 return true;
179
180 return false;
181}
182
Chia-I Wufcbc5252015-04-08 11:44:26 +0800183/*
184 * Return the depth of \p drawable.
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800185 */
Chia-I Wufcbc5252015-04-08 11:44:26 +0800186static int x11_get_drawable_depth(xcb_connection_t *c,
187 xcb_drawable_t drawable)
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800188{
Chia-I Wufcbc5252015-04-08 11:44:26 +0800189 xcb_get_geometry_cookie_t cookie;
190 xcb_get_geometry_reply_t *reply;
191 uint8_t depth;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800192
Chia-I Wufcbc5252015-04-08 11:44:26 +0800193 cookie = xcb_get_geometry(c, drawable);
194 reply = xcb_get_geometry_reply(c, cookie, NULL);
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800195
Chia-I Wufcbc5252015-04-08 11:44:26 +0800196 if (reply) {
197 depth = reply->depth;
198 free(reply);
199 } else {
200 depth = 0;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800201 }
202
Chia-I Wufcbc5252015-04-08 11:44:26 +0800203 return depth;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800204}
205
Chia-I Wu1db76e02014-09-15 14:21:14 +0800206/**
207 * Return true if DRI3 and Present are supported by the server.
208 */
Chia-I Wufcbc5252015-04-08 11:44:26 +0800209static bool x11_is_dri3_and_present_supported(xcb_connection_t *c)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800210{
211 const xcb_query_extension_reply_t *ext;
212
Chia-I Wufcbc5252015-04-08 11:44:26 +0800213 xcb_prefetch_extension_data(c, &xcb_dri3_id);
214 xcb_prefetch_extension_data(c, &xcb_present_id);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800215
Chia-I Wufcbc5252015-04-08 11:44:26 +0800216 ext = xcb_get_extension_data(c, &xcb_dri3_id);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800217 if (!ext || !ext->present)
218 return false;
219
Chia-I Wufcbc5252015-04-08 11:44:26 +0800220 ext = xcb_get_extension_data(c, &xcb_present_id);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800221 if (!ext || !ext->present)
222 return false;
223
224 return true;
225}
226
227/**
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800228 * Send a DRI3Open to get the server GPU fd.
Chia-I Wu1db76e02014-09-15 14:21:14 +0800229 */
Chia-I Wufcbc5252015-04-08 11:44:26 +0800230static int x11_dri3_open(xcb_connection_t *c,
231 xcb_drawable_t drawable,
232 xcb_randr_provider_t provider)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800233{
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800234 xcb_dri3_open_cookie_t cookie;
235 xcb_dri3_open_reply_t *reply;
236 int fd;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800237
Chia-I Wufcbc5252015-04-08 11:44:26 +0800238 cookie = xcb_dri3_open(c, drawable, provider);
239 reply = xcb_dri3_open_reply(c, cookie, NULL);
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800240 if (!reply)
Chia-I Wufcbc5252015-04-08 11:44:26 +0800241 return -1;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800242
Chia-I Wufcbc5252015-04-08 11:44:26 +0800243 fd = (reply->nfd == 1) ? xcb_dri3_open_reply_fds(c, reply)[0] : -1;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800244 free(reply);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800245
Chia-I Wufcbc5252015-04-08 11:44:26 +0800246 return fd;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800247}
248
249/**
Chia-I Wu030b2db2015-04-08 13:46:29 +0800250 * Send a DRI3PixmapFromBuffer to create a pixmap from \p prime_fd.
251 */
252static xcb_pixmap_t x11_dri3_pixmap_from_buffer(xcb_connection_t *c,
253 xcb_drawable_t drawable,
254 uint8_t depth, int prime_fd,
255 const struct intel_layout *layout)
256{
257 xcb_pixmap_t pixmap;
258
259 pixmap = xcb_generate_id(c);
260
261 xcb_dri3_pixmap_from_buffer(c, pixmap, drawable,
262 layout->bo_stride * layout->bo_height,
263 layout->width0, layout->height0,
264 layout->bo_stride, depth,
265 layout->block_size * 8, prime_fd);
266
267 return pixmap;
268}
269
270/**
Chia-I Wu41858c82015-04-04 16:39:25 +0800271 * Send DRI3QueryVersion and PresentQueryVersion to query extension versions.
Chia-I Wu1db76e02014-09-15 14:21:14 +0800272 */
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800273static bool x11_swap_chain_dri3_and_present_query_version(struct intel_x11_swap_chain *sc)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800274{
275 xcb_dri3_query_version_cookie_t dri3_cookie;
276 xcb_dri3_query_version_reply_t *dri3_reply;
277 xcb_present_query_version_cookie_t present_cookie;
278 xcb_present_query_version_reply_t *present_reply;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800279
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800280 dri3_cookie = xcb_dri3_query_version(sc->c,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800281 XCB_DRI3_MAJOR_VERSION, XCB_DRI3_MINOR_VERSION);
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800282 present_cookie = xcb_present_query_version(sc->c,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800283 XCB_PRESENT_MAJOR_VERSION, XCB_PRESENT_MINOR_VERSION);
284
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800285 dri3_reply = xcb_dri3_query_version_reply(sc->c, dri3_cookie, NULL);
Chia-I Wu41858c82015-04-04 16:39:25 +0800286 if (!dri3_reply)
287 return false;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800288
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800289 sc->dri3_major = dri3_reply->major_version;
290 sc->dri3_minor = dri3_reply->minor_version;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800291 free(dri3_reply);
292
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800293 present_reply = xcb_present_query_version_reply(sc->c, present_cookie, NULL);
Chia-I Wu41858c82015-04-04 16:39:25 +0800294 if (!present_reply)
295 return false;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800296
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800297 sc->present_major = present_reply->major_version;
298 sc->present_minor = present_reply->minor_version;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800299 free(present_reply);
300
Chia-I Wu41858c82015-04-04 16:39:25 +0800301 return true;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800302}
303
304/**
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800305 * Send a PresentSelectInput to select interested events.
Chia-I Wu1db76e02014-09-15 14:21:14 +0800306 */
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800307static bool x11_swap_chain_present_select_input(struct intel_x11_swap_chain *sc)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800308{
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800309 xcb_void_cookie_t cookie;
310 xcb_generic_error_t *error;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800311
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800312 /* create the event queue */
313 sc->present_special_event_id = xcb_generate_id(sc->c);
314 sc->present_special_event = xcb_register_for_special_xge(sc->c,
315 &xcb_present_id, sc->present_special_event_id, NULL);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800316
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800317 cookie = xcb_present_select_input_checked(sc->c,
318 sc->present_special_event_id, sc->window,
319 XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800320
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800321 error = xcb_request_check(sc->c, cookie);
322 if (error) {
323 free(error);
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800324 return false;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800325 }
Chia-I Wu1db76e02014-09-15 14:21:14 +0800326
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800327 return true;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800328}
329
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800330static struct intel_img *x11_swap_chain_create_persistent_image(struct intel_x11_swap_chain *sc,
331 struct intel_dev *dev,
332 const VkImageCreateInfo *img_info)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800333{
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800334 struct intel_img *img;
335 struct intel_mem *mem;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800336 struct intel_x11_img_data *data;
337 VkMemoryAllocInfo mem_info;
338 int prime_fd;
339 xcb_pixmap_t pixmap;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600340 VkResult ret;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800341
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800342 ret = intel_img_create(dev, img_info, true, &img);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600343 if (ret != VK_SUCCESS)
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800344 return NULL;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800345
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800346 memset(&mem_info, 0, sizeof(mem_info));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600347 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800348 mem_info.allocationSize = img->total_size;
349 mem_info.memProps = 0;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800350
351 ret = intel_mem_alloc(dev, &mem_info, &mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600352 if (ret != VK_SUCCESS) {
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800353 intel_img_destroy(img);
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800354 return NULL;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800355 }
356
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800357 prime_fd = x11_export_prime_fd(dev, mem->bo, &img->layout);
358 if (prime_fd < 0) {
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800359 intel_mem_free(mem);
360 intel_img_destroy(img);
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800361 return NULL;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800362 }
363
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800364 pixmap = x11_dri3_pixmap_from_buffer(sc->c, sc->window,
365 x11_get_drawable_depth(sc->c, sc->window),
366 prime_fd, &img->layout);
367
368 data = (struct intel_x11_img_data *) img->wsi_data;
369 data->swap_chain = sc;
370 data->mem = mem;
371 data->prime_fd = prime_fd;
372 data->pixmap = pixmap;
373
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800374 intel_obj_bind_mem(&img->obj, mem, 0);
375
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800376 return img;
377}
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800378
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800379static bool x11_swap_chain_create_persistent_images(struct intel_x11_swap_chain *sc,
380 struct intel_dev *dev,
381 const VkSwapChainCreateInfoWSI *info)
382{
383 struct intel_img **images;
384 VkImageCreateInfo img_info;
385 uint32_t i;
386
387 images = intel_alloc(sc, sizeof(*images) * info->imageCount,
388 0, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
389 if (!images)
390 return false;
391
392 memset(&img_info, 0, sizeof(img_info));
393 img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
394 img_info.imageType = VK_IMAGE_TYPE_2D;
395 img_info.format = info->imageFormat;
396 img_info.extent.width = info->imageExtent.width;
397 img_info.extent.height = info->imageExtent.height;
398 img_info.extent.depth = 1;
399 img_info.mipLevels = 1;
400 img_info.arraySize = info->imageArraySize;
401 img_info.samples = 1;
402 img_info.tiling = VK_IMAGE_TILING_OPTIMAL;
403 img_info.usage = info->imageUsageFlags;
404 img_info.flags = 0;
405
406 for (i = 0; i < info->imageCount; i++) {
407 images[i] = x11_swap_chain_create_persistent_image(sc,
408 dev, &img_info);
409 if (!images[i])
410 break;
411 }
412
413 if (i < info->imageCount) {
414 uint32_t j;
415 for (j = 0; j < i; j++)
416 intel_img_destroy(images[i]);
417
418 intel_free(sc, images);
419
420 return false;
421 }
422
423 sc->persistent_images = images;
424 sc->persistent_image_count = info->imageCount;
425
426 return true;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800427}
428
429/**
430 * Send a PresentPixmap.
431 */
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600432static VkResult x11_swap_chain_present_pixmap(struct intel_x11_swap_chain *sc,
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800433 const VkPresentInfoWSI *info)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800434{
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800435 struct intel_img *img = intel_img(info->image);
Chia-I Wu41858c82015-04-04 16:39:25 +0800436 struct intel_x11_img_data *data =
437 (struct intel_x11_img_data *) img->wsi_data;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800438 uint32_t options = XCB_PRESENT_OPTION_NONE;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800439 uint32_t target_msc, divisor, remainder;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800440 xcb_void_cookie_t cookie;
441 xcb_generic_error_t *err;
442
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800443 target_msc = 0;
444 divisor = info->flipInterval;
445 remainder = 0;
446 if (!info->flipInterval)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800447 options |= XCB_PRESENT_OPTION_ASYNC;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800448
449 if (sc->force_copy)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800450 options |= XCB_PRESENT_OPTION_COPY;
451
Chia-I Wuf689c602015-04-28 10:55:52 +0800452 cookie = xcb_present_pixmap_checked(sc->c,
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800453 sc->window,
Chia-I Wu41858c82015-04-04 16:39:25 +0800454 data->pixmap,
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800455 ++sc->local.serial,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800456 0, /* valid-area */
457 0, /* update-area */
458 0, /* x-off */
459 0, /* y-off */
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800460 0, /* crtc */
Chia-I Wu1db76e02014-09-15 14:21:14 +0800461 0, /* wait-fence */
462 0, /* idle-fence */
463 options,
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800464 target_msc,
465 divisor,
466 remainder,
Chia-I Wu1db76e02014-09-15 14:21:14 +0800467 0, NULL);
468
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800469 err = xcb_request_check(sc->c, cookie);
Chia-I Wu1db76e02014-09-15 14:21:14 +0800470 if (err) {
471 free(err);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600472 return VK_ERROR_UNKNOWN;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800473 }
474
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600475 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800476}
477
478/**
Chia-I Wu1db76e02014-09-15 14:21:14 +0800479 * Handle a Present event.
480 */
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800481static void x11_swap_chain_present_event(struct intel_x11_swap_chain *sc,
482 const xcb_present_generic_event_t *ev)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800483{
484 union {
485 const xcb_present_generic_event_t *ev;
486 const xcb_present_complete_notify_event_t *complete;
487 } u = { .ev = ev };
488
489 switch (u.ev->evtype) {
490 case XCB_PRESENT_COMPLETE_NOTIFY:
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800491 sc->remote.serial = u.complete->serial;
492 sc->remote.msc = u.complete->msc;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800493 break;
494 default:
495 break;
496 }
497}
498
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600499static VkResult x11_swap_chain_wait(struct intel_x11_swap_chain *sc,
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800500 uint32_t serial, int64_t timeout)
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800501{
502 const bool wait = (timeout != 0);
503
504 while (sc->remote.serial < serial) {
505 xcb_present_generic_event_t *ev;
Mike Stroyan4a387162015-04-27 15:42:41 -0600506 xcb_intern_atom_reply_t *reply;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800507
508 if (wait) {
509 ev = (xcb_present_generic_event_t *)
510 xcb_wait_for_special_event(sc->c, sc->present_special_event);
Mike Stroyan4a387162015-04-27 15:42:41 -0600511 /* use xcb_intern_atom_reply just to wake other threads waiting on sc->c */
512 reply = xcb_intern_atom_reply(sc->c, xcb_intern_atom(sc->c, 1, 1, "a"), NULL);
513 if (reply) {
514 free(reply);
515 }
516
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800517 if (!ev)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600518 return VK_ERROR_UNKNOWN;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800519 } else {
Mike Stroyan4a387162015-04-27 15:42:41 -0600520 /* use xcb_intern_atom_reply just to check socket for special event */
521 reply = xcb_intern_atom_reply(sc->c, xcb_intern_atom(sc->c, 1, 1, "a"), NULL);
522 if (reply) {
523 free(reply);
524 }
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800525 ev = (xcb_present_generic_event_t *)
526 xcb_poll_for_special_event(sc->c, sc->present_special_event);
527 if (!ev)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600528 return VK_NOT_READY;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800529 }
530
531 x11_swap_chain_present_event(sc, ev);
532
533 free(ev);
534 }
535
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600536 return VK_SUCCESS;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800537}
538
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800539static void x11_swap_chain_destroy(struct intel_x11_swap_chain *sc)
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800540{
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800541 if (sc->persistent_images) {
542 uint32_t i;
543
544 for (i = 0; i < sc->persistent_image_count; i++)
545 intel_img_destroy(sc->persistent_images[i]);
546 intel_free(sc, sc->persistent_images);
547 }
548
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800549 if (sc->present_special_event)
550 xcb_unregister_for_special_event(sc->c, sc->present_special_event);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800551
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800552 intel_free(sc, sc);
553}
554
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800555static VkResult x11_swap_chain_create(struct intel_dev *dev,
556 const VkSwapChainCreateInfoWSI *info,
557 struct intel_x11_swap_chain **sc_ret)
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800558{
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800559 const xcb_randr_provider_t provider = 0;
560 xcb_connection_t *c = (xcb_connection_t *)
561 info->pNativeWindowSystemHandle;
562 xcb_window_t window = (xcb_window_t)
563 ((intptr_t) info->pNativeWindowHandle);
564 struct intel_x11_swap_chain *sc;
565 int fd;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800566
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800567 if (!x11_is_format_presentable(dev, info->imageFormat)) {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600568 intel_dev_log(dev, VK_DBG_REPORT_ERROR_BIT,
569 VK_NULL_HANDLE, 0, 0, "invalid presentable image format");
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800570 return VK_ERROR_INVALID_VALUE;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800571 }
572
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800573 if (!x11_is_dri3_and_present_supported(c))
574 return VK_ERROR_INVALID_VALUE;
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800575
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800576 fd = x11_dri3_open(c, window, provider);
577 if (fd < 0 || !x11_gpu_match_fd(dev->gpu, fd)) {
Chia-I Wufcbc5252015-04-08 11:44:26 +0800578 if (fd >= 0)
579 close(fd);
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800580 return VK_ERROR_INVALID_VALUE;
Chia-I Wufcbc5252015-04-08 11:44:26 +0800581 }
Chia-I Wudbbe6ea2015-04-08 10:30:57 +0800582
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800583 close(fd);
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800584
Tony Barbour8205d902015-04-16 15:59:00 -0600585 sc = intel_alloc(dev, sizeof(*sc), 0, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800586 if (!sc)
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800587 return VK_ERROR_OUT_OF_HOST_MEMORY;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800588
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800589 memset(sc, 0, sizeof(*sc));
Courtney Goeltzenleuchter9ecf6852015-06-09 08:22:48 -0600590 intel_handle_init(&sc->handle, VK_OBJECT_TYPE_SWAP_CHAIN_WSI, dev->base.handle.instance);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800591
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800592 sc->c = c;
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800593 sc->window = window;
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800594
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800595 /* always copy unless flip bit is set */
596 sc->force_copy = !(info->swapModeFlags & VK_SWAP_MODE_FLIP_BIT_WSI);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800597
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800598 if (!x11_swap_chain_dri3_and_present_query_version(sc) ||
599 !x11_swap_chain_present_select_input(sc) ||
600 !x11_swap_chain_create_persistent_images(sc, dev, info)) {
601 x11_swap_chain_destroy(sc);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600602 return VK_ERROR_UNKNOWN;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800603 }
Chia-I Wu41858c82015-04-04 16:39:25 +0800604
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800605 *sc_ret = sc;
Chia-I Wu41858c82015-04-04 16:39:25 +0800606
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600607 return VK_SUCCESS;
Chia-I Wu41858c82015-04-04 16:39:25 +0800608}
609
Chia-I Wu8635e912015-04-09 14:13:57 +0800610static void x11_display_init_modes(struct intel_x11_display *dpy,
611 const drmModeConnectorPtr conn)
612{
613 int i;
614
615 if (!conn->count_modes)
616 return;
617
618 dpy->modes = intel_alloc(dpy, sizeof(dpy->modes[0]) * conn->count_modes,
Tony Barbour8205d902015-04-16 15:59:00 -0600619 0, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
Chia-I Wu8635e912015-04-09 14:13:57 +0800620 if (!dpy->modes)
621 return;
622
623 for (i = 0; i < conn->count_modes; i++) {
624 dpy->modes[i] = conn->modes[i];
625
626 if (dpy->physical_resolution.width < conn->modes[i].hdisplay &&
627 dpy->physical_resolution.height < conn->modes[i].vdisplay) {
628 dpy->physical_resolution.width = conn->modes[i].hdisplay;
629 dpy->physical_resolution.height = conn->modes[i].vdisplay;
630 }
631 }
632
633 dpy->mode_count = conn->count_modes;
634
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800635#if 0 // Remove this until we support an upstream version of WSI that has this:
Chia-I Wu8635e912015-04-09 14:13:57 +0800636 dpy->physical_dimension.width = conn->mmWidth;
637 dpy->physical_dimension.height = conn->mmHeight;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800638#endif
Chia-I Wu8635e912015-04-09 14:13:57 +0800639}
640
641static void x11_display_init_name(struct intel_x11_display *dpy,
642 const drmModeConnectorPtr conn)
643{
644 static const char *connector_names[] = {
645 [DRM_MODE_CONNECTOR_Unknown] = "Unknown",
646 [DRM_MODE_CONNECTOR_VGA] = "VGA",
647 [DRM_MODE_CONNECTOR_DVII] = "DVII",
648 [DRM_MODE_CONNECTOR_DVID] = "DVID",
649 [DRM_MODE_CONNECTOR_DVIA] = "DVIA",
650 [DRM_MODE_CONNECTOR_Composite] = "Composite",
651 [DRM_MODE_CONNECTOR_SVIDEO] = "SVIDEO",
652 [DRM_MODE_CONNECTOR_LVDS] = "LVDS",
653 [DRM_MODE_CONNECTOR_Component] = "COMPONENT",
654 [DRM_MODE_CONNECTOR_9PinDIN] = "9PinDIN",
655 [DRM_MODE_CONNECTOR_DisplayPort] = "DisplayPort",
656 [DRM_MODE_CONNECTOR_HDMIA] = "HDMIA",
657 [DRM_MODE_CONNECTOR_HDMIB] = "HDMIB",
658 [DRM_MODE_CONNECTOR_TV] = "TV",
659 [DRM_MODE_CONNECTOR_eDP] = "eDP",
660 [DRM_MODE_CONNECTOR_VIRTUAL] = "VIRTUAL",
661 [DRM_MODE_CONNECTOR_DSI] = "DSI",
662 };
663 const char *name;
664
665 name = (conn->connector_type < ARRAY_SIZE(connector_names)) ?
666 connector_names[conn->connector_type] : NULL;
667 if (!name)
668 name = connector_names[DRM_MODE_CONNECTOR_Unknown];
669
670 snprintf(dpy->name, sizeof(dpy->name),
671 "%s%d", name, conn->connector_type_id);
672}
673
674static void x11_display_destroy(struct intel_x11_display *dpy)
675{
676 intel_free(dpy, dpy->modes);
677 intel_free(dpy, dpy);
678}
679
680static struct intel_x11_display *x11_display_create(struct intel_gpu *gpu,
681 int fd,
682 uint32_t connector_id)
683{
684 struct intel_x11_display *dpy;
685 drmModeConnectorPtr conn;
686
Tony Barbour8205d902015-04-16 15:59:00 -0600687 dpy = intel_alloc(gpu, sizeof(*dpy), 0, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
Chia-I Wu8635e912015-04-09 14:13:57 +0800688 if (!dpy)
689 return NULL;
690
691 memset(dpy, 0, sizeof(*dpy));
Courtney Goeltzenleuchter9ecf6852015-06-09 08:22:48 -0600692 intel_handle_init(&dpy->handle, VK_OBJECT_TYPE_DISPLAY_WSI, gpu->handle.instance);
Chia-I Wu8635e912015-04-09 14:13:57 +0800693
694 dpy->fd = fd;
695 dpy->connector_id = connector_id;
696
697 conn = drmModeGetConnector(fd, connector_id);
698 if (!conn) {
699 x11_display_destroy(dpy);
700 return NULL;
701 }
702
703 x11_display_init_name(dpy, conn);
704 x11_display_init_modes(dpy, conn);
705
706 drmModeFreeConnector(conn);
707
708 return dpy;
709}
710
711static void x11_display_scan(struct intel_gpu *gpu)
712{
713 struct intel_x11_display **displays;
714 drmModeResPtr res;
715 int fd, i;
716
717 fd = intel_gpu_get_primary_fd(gpu);
718 if (fd < 0)
719 return;
720
721 res = drmModeGetResources(fd);
722 if (!res)
723 return;
724
725 displays = intel_alloc(gpu, sizeof(*displays) * res->count_connectors,
Tony Barbour8205d902015-04-16 15:59:00 -0600726 0, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
Chia-I Wu8635e912015-04-09 14:13:57 +0800727 if (!displays) {
728 drmModeFreeResources(res);
729 return;
730 }
731
732 for (i = 0; i < res->count_connectors; i++) {
733 displays[i] = x11_display_create(gpu, fd, res->connectors[i]);
734 if (!displays[i])
735 break;
736 }
737
738 drmModeFreeResources(res);
739
740 gpu->displays = (struct intel_wsi_display **) displays;
741 gpu->display_count = i;
742}
743
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600744VkResult intel_wsi_gpu_get_info(struct intel_gpu *gpu,
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800745 VkPhysicalDeviceInfoType type,
746 size_t *size, void *data)
Chia-I Wu41858c82015-04-04 16:39:25 +0800747{
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800748 VkResult ret = VK_SUCCESS;
Chia-I Wu8635e912015-04-09 14:13:57 +0800749
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800750 if (!size)
751 return VK_ERROR_INVALID_POINTER;
752
753 switch ((int) type) {
754 case VK_PHYSICAL_DEVICE_INFO_TYPE_DISPLAY_PROPERTIES_WSI:
755 {
756 VkDisplayPropertiesWSI *dst = data;
757 size_t size_ret;
758 uint32_t i;
759
760 if (!gpu->display_count)
761 x11_display_scan(gpu);
762
763 size_ret = sizeof(*dst) * gpu->display_count;
764
765 if (dst && *size < size_ret)
766 return VK_ERROR_INVALID_VALUE;
767
768 *size = size_ret;
769 if (!dst)
770 return VK_SUCCESS;
771
772 for (i = 0; i < gpu->display_count; i++) {
773 struct intel_x11_display *dpy =
774 (struct intel_x11_display *) gpu->displays[i];
775
776 dst[i].display = (VkDisplayWSI) dpy;
777#if 0 // Remove this until we support an upstream version of WSI that has this:
778 dst[i].displayName = dpy->name;
779#endif
780 }
781 }
782 break;
783 case VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PRESENT_PROPERTIES_WSI:
784 {
785 VkPhysicalDeviceQueuePresentPropertiesWSI *dst = data;
786 size_t size_ret;
787 uint32_t i;
788
789 size_ret = sizeof(*dst) * INTEL_GPU_ENGINE_COUNT;
790
791 if (dst && *size < size_ret)
792 return VK_ERROR_INVALID_VALUE;
793
794 *size = size_ret;
795 if (!dst)
796 return VK_SUCCESS;
797
798 for (i = 0; i < INTEL_GPU_ENGINE_COUNT; i++)
799 dst[i].supportsPresent = true;
800 }
801 break;
802 default:
803 ret = VK_ERROR_INVALID_VALUE;
804 break;
805 }
806
807 return ret;
Chia-I Wu41858c82015-04-04 16:39:25 +0800808}
809
810void intel_wsi_gpu_cleanup(struct intel_gpu *gpu)
811{
Chia-I Wu8635e912015-04-09 14:13:57 +0800812 if (gpu->displays) {
813 uint32_t i;
Chia-I Wu41858c82015-04-04 16:39:25 +0800814
Chia-I Wu8635e912015-04-09 14:13:57 +0800815 for (i = 0; i < gpu->display_count; i++) {
816 struct intel_x11_display *dpy =
817 (struct intel_x11_display *) gpu->displays[i];
818 x11_display_destroy(dpy);
819 }
820 intel_free(gpu, gpu->displays);
821 }
Chia-I Wu41858c82015-04-04 16:39:25 +0800822}
823
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600824VkResult intel_wsi_img_init(struct intel_img *img)
Chia-I Wu41858c82015-04-04 16:39:25 +0800825{
826 struct intel_x11_img_data *data;
827
Tony Barbour8205d902015-04-16 15:59:00 -0600828 data = intel_alloc(img, sizeof(*data), 0, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
Chia-I Wu41858c82015-04-04 16:39:25 +0800829 if (!data)
Tony Barbour8205d902015-04-16 15:59:00 -0600830 return VK_ERROR_OUT_OF_HOST_MEMORY;
Chia-I Wu41858c82015-04-04 16:39:25 +0800831
832 memset(data, 0, sizeof(*data));
833
834 assert(!img->wsi_data);
835 img->wsi_data = data;
836
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600837 return VK_SUCCESS;
Chia-I Wu41858c82015-04-04 16:39:25 +0800838}
839
840void intel_wsi_img_cleanup(struct intel_img *img)
841{
842 struct intel_x11_img_data *data =
843 (struct intel_x11_img_data *) img->wsi_data;
844
845 if (data->mem) {
846 close(data->prime_fd);
847 intel_mem_free(data->mem);
848 }
849
850 intel_free(img, img->wsi_data);
851}
852
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600853VkResult intel_wsi_fence_init(struct intel_fence *fence)
Chia-I Wu41858c82015-04-04 16:39:25 +0800854{
855 struct intel_x11_fence_data *data;
856
Tony Barbour8205d902015-04-16 15:59:00 -0600857 data = intel_alloc(fence, sizeof(*data), 0, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
Chia-I Wu41858c82015-04-04 16:39:25 +0800858 if (!data)
Tony Barbour8205d902015-04-16 15:59:00 -0600859 return VK_ERROR_OUT_OF_HOST_MEMORY;
Chia-I Wu41858c82015-04-04 16:39:25 +0800860
861 memset(data, 0, sizeof(*data));
862
863 assert(!fence->wsi_data);
864 fence->wsi_data = data;
865
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600866 return VK_SUCCESS;
Chia-I Wu41858c82015-04-04 16:39:25 +0800867}
868
869void intel_wsi_fence_cleanup(struct intel_fence *fence)
870{
871 intel_free(fence, fence->wsi_data);
872}
873
874void intel_wsi_fence_copy(struct intel_fence *fence,
875 const struct intel_fence *src)
876{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600877 if (!fence->wsi_data) {
878 return;
879 }
Chia-I Wu41858c82015-04-04 16:39:25 +0800880 memcpy(fence->wsi_data, src->wsi_data,
881 sizeof(struct intel_x11_fence_data));
882}
883
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600884VkResult intel_wsi_fence_wait(struct intel_fence *fence,
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800885 int64_t timeout_ns)
Chia-I Wu41858c82015-04-04 16:39:25 +0800886{
887 struct intel_x11_fence_data *data =
888 (struct intel_x11_fence_data *) fence->wsi_data;
889
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600890 if (!data)
891 return VK_SUCCESS;
892
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800893 if (!data->swap_chain)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600894 return VK_SUCCESS;
Chia-I Wu41858c82015-04-04 16:39:25 +0800895
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800896 return x11_swap_chain_wait(data->swap_chain, data->serial, timeout_ns);
Chia-I Wu41858c82015-04-04 16:39:25 +0800897}
898
Jon Ashburnba4a1952015-06-16 12:44:51 -0600899#if 0
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800900ICD_EXPORT VkResult VKAPI vkGetDisplayInfoWSI(
901 VkDisplayWSI display,
902 VkDisplayInfoTypeWSI infoType,
903 size_t* pDataSize,
904 void* pData)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800905{
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800906 VkResult ret = VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800907
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800908 if (!pDataSize)
909 return VK_ERROR_INVALID_POINTER;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800910
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800911 switch (infoType) {
912 case VK_DISPLAY_INFO_TYPE_FORMAT_PROPERTIES_WSI:
913 {
914 VkDisplayFormatPropertiesWSI *dst = pData;
915 size_t size_ret;
916 uint32_t i;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800917
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800918 size_ret = sizeof(*dst) * ARRAY_SIZE(x11_presentable_formats);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800919
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800920 if (dst && *pDataSize < size_ret)
921 return VK_ERROR_INVALID_VALUE;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800922
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800923 *pDataSize = size_ret;
924 if (!dst)
925 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800926
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800927 for (i = 0; i < ARRAY_SIZE(x11_presentable_formats); i++)
928 dst[i].swapChainFormat = x11_presentable_formats[i];
929 }
930 break;
931 default:
932 ret = VK_ERROR_INVALID_VALUE;
933 break;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800934 }
935
936 return ret;
937}
Jon Ashburnba4a1952015-06-16 12:44:51 -0600938#endif
Chia-I Wu1db76e02014-09-15 14:21:14 +0800939
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800940ICD_EXPORT VkResult VKAPI vkCreateSwapChainWSI(
941 VkDevice device,
942 const VkSwapChainCreateInfoWSI* pCreateInfo,
943 VkSwapChainWSI* pSwapChain)
944{
945 struct intel_dev *dev = intel_dev(device);
946
947 return x11_swap_chain_create(dev, pCreateInfo,
948 (struct intel_x11_swap_chain **) pSwapChain);
949}
950
951ICD_EXPORT VkResult VKAPI vkDestroySwapChainWSI(
952 VkSwapChainWSI swapChain)
953{
954 struct intel_x11_swap_chain *sc = x11_swap_chain(swapChain);
955
956 x11_swap_chain_destroy(sc);
957
958 return VK_SUCCESS;
959}
960
961ICD_EXPORT VkResult VKAPI vkGetSwapChainInfoWSI(
962 VkSwapChainWSI swapChain,
963 VkSwapChainInfoTypeWSI infoType,
964 size_t* pDataSize,
965 void* pData)
966{
967 struct intel_x11_swap_chain *sc = x11_swap_chain(swapChain);
968 VkResult ret = VK_SUCCESS;
969
970 if (!pDataSize)
971 return VK_ERROR_INVALID_POINTER;
972
973 switch (infoType) {
974 case VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI:
975 {
976 VkSwapChainImageInfoWSI *images;
977 const size_t size = sizeof(*images) * sc->persistent_image_count;
978 uint32_t i;
979
980 if (pData && *pDataSize < size)
981 return VK_ERROR_INVALID_VALUE;
982
983 *pDataSize = size;
984 if (!pData)
985 return VK_SUCCESS;
986
987 images = (VkSwapChainImageInfoWSI *) pData;
988 for (i = 0; i < sc->persistent_image_count; i++) {
989 images[i].image = (VkImage) sc->persistent_images[i];
990 images[i].memory =
991 (VkDeviceMemory) sc->persistent_images[i]->obj.mem;
992 }
993 }
994 break;
995 default:
996 ret = VK_ERROR_INVALID_VALUE;
997 break;
998 }
999
1000 return ret;
1001}
1002
1003ICD_EXPORT VkResult VKAPI vkQueuePresentWSI(
1004 VkQueue queue_,
1005 const VkPresentInfoWSI* pPresentInfo)
Chia-I Wu1db76e02014-09-15 14:21:14 +08001006{
1007 struct intel_queue *queue = intel_queue(queue_);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001008 struct intel_img *img = intel_img(pPresentInfo->image);
1009 struct intel_x11_swap_chain *sc =
1010 ((struct intel_x11_img_data *) img->wsi_data)->swap_chain;
Chia-I Wub56f5df2015-04-04 20:21:10 +08001011 struct intel_x11_fence_data *data =
1012 (struct intel_x11_fence_data *) queue->fence->wsi_data;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001013 VkResult ret;
Chia-I Wu1db76e02014-09-15 14:21:14 +08001014
Chia-I Wu6532d1d2015-04-04 22:16:45 +08001015 ret = x11_swap_chain_present_pixmap(sc, pPresentInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001016 if (ret != VK_SUCCESS)
Chia-I Wu1db76e02014-09-15 14:21:14 +08001017 return ret;
1018
Chia-I Wu6532d1d2015-04-04 22:16:45 +08001019 data->swap_chain = sc;
1020 data->serial = sc->local.serial;
Chia-I Wub56f5df2015-04-04 20:21:10 +08001021 intel_fence_set_seqno(queue->fence, img->obj.mem->bo);
Chia-I Wubda4f622015-02-25 15:06:15 -07001022
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001023 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +08001024}