blob: 34ade00799c49884f383e4f5f558a6c7d19719d2 [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
Jon Ashburneb66fee2015-06-16 15:06:44 -0600610#if 0
Chia-I Wu8635e912015-04-09 14:13:57 +0800611static void x11_display_init_modes(struct intel_x11_display *dpy,
612 const drmModeConnectorPtr conn)
613{
614 int i;
615
616 if (!conn->count_modes)
617 return;
618
619 dpy->modes = intel_alloc(dpy, sizeof(dpy->modes[0]) * conn->count_modes,
Tony Barbour8205d902015-04-16 15:59:00 -0600620 0, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
Chia-I Wu8635e912015-04-09 14:13:57 +0800621 if (!dpy->modes)
622 return;
623
624 for (i = 0; i < conn->count_modes; i++) {
625 dpy->modes[i] = conn->modes[i];
626
627 if (dpy->physical_resolution.width < conn->modes[i].hdisplay &&
628 dpy->physical_resolution.height < conn->modes[i].vdisplay) {
629 dpy->physical_resolution.width = conn->modes[i].hdisplay;
630 dpy->physical_resolution.height = conn->modes[i].vdisplay;
631 }
632 }
633
634 dpy->mode_count = conn->count_modes;
635
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800636#if 0 // Remove this until we support an upstream version of WSI that has this:
Chia-I Wu8635e912015-04-09 14:13:57 +0800637 dpy->physical_dimension.width = conn->mmWidth;
638 dpy->physical_dimension.height = conn->mmHeight;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800639#endif
Chia-I Wu8635e912015-04-09 14:13:57 +0800640}
641
642static void x11_display_init_name(struct intel_x11_display *dpy,
643 const drmModeConnectorPtr conn)
644{
645 static const char *connector_names[] = {
646 [DRM_MODE_CONNECTOR_Unknown] = "Unknown",
647 [DRM_MODE_CONNECTOR_VGA] = "VGA",
648 [DRM_MODE_CONNECTOR_DVII] = "DVII",
649 [DRM_MODE_CONNECTOR_DVID] = "DVID",
650 [DRM_MODE_CONNECTOR_DVIA] = "DVIA",
651 [DRM_MODE_CONNECTOR_Composite] = "Composite",
652 [DRM_MODE_CONNECTOR_SVIDEO] = "SVIDEO",
653 [DRM_MODE_CONNECTOR_LVDS] = "LVDS",
654 [DRM_MODE_CONNECTOR_Component] = "COMPONENT",
655 [DRM_MODE_CONNECTOR_9PinDIN] = "9PinDIN",
656 [DRM_MODE_CONNECTOR_DisplayPort] = "DisplayPort",
657 [DRM_MODE_CONNECTOR_HDMIA] = "HDMIA",
658 [DRM_MODE_CONNECTOR_HDMIB] = "HDMIB",
659 [DRM_MODE_CONNECTOR_TV] = "TV",
660 [DRM_MODE_CONNECTOR_eDP] = "eDP",
661 [DRM_MODE_CONNECTOR_VIRTUAL] = "VIRTUAL",
662 [DRM_MODE_CONNECTOR_DSI] = "DSI",
663 };
664 const char *name;
665
666 name = (conn->connector_type < ARRAY_SIZE(connector_names)) ?
667 connector_names[conn->connector_type] : NULL;
668 if (!name)
669 name = connector_names[DRM_MODE_CONNECTOR_Unknown];
670
671 snprintf(dpy->name, sizeof(dpy->name),
672 "%s%d", name, conn->connector_type_id);
673}
Jon Ashburneb66fee2015-06-16 15:06:44 -0600674#endif
Chia-I Wu8635e912015-04-09 14:13:57 +0800675
676static void x11_display_destroy(struct intel_x11_display *dpy)
677{
678 intel_free(dpy, dpy->modes);
679 intel_free(dpy, dpy);
680}
681
Jon Ashburneb66fee2015-06-16 15:06:44 -0600682#if 0
Chia-I Wu8635e912015-04-09 14:13:57 +0800683static struct intel_x11_display *x11_display_create(struct intel_gpu *gpu,
684 int fd,
685 uint32_t connector_id)
686{
687 struct intel_x11_display *dpy;
688 drmModeConnectorPtr conn;
689
Tony Barbour8205d902015-04-16 15:59:00 -0600690 dpy = intel_alloc(gpu, sizeof(*dpy), 0, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
Chia-I Wu8635e912015-04-09 14:13:57 +0800691 if (!dpy)
692 return NULL;
693
694 memset(dpy, 0, sizeof(*dpy));
Courtney Goeltzenleuchter9ecf6852015-06-09 08:22:48 -0600695 intel_handle_init(&dpy->handle, VK_OBJECT_TYPE_DISPLAY_WSI, gpu->handle.instance);
Chia-I Wu8635e912015-04-09 14:13:57 +0800696
697 dpy->fd = fd;
698 dpy->connector_id = connector_id;
699
700 conn = drmModeGetConnector(fd, connector_id);
701 if (!conn) {
702 x11_display_destroy(dpy);
703 return NULL;
704 }
705
706 x11_display_init_name(dpy, conn);
707 x11_display_init_modes(dpy, conn);
708
709 drmModeFreeConnector(conn);
710
711 return dpy;
712}
713
714static void x11_display_scan(struct intel_gpu *gpu)
715{
716 struct intel_x11_display **displays;
717 drmModeResPtr res;
718 int fd, i;
719
720 fd = intel_gpu_get_primary_fd(gpu);
721 if (fd < 0)
722 return;
723
724 res = drmModeGetResources(fd);
725 if (!res)
726 return;
727
728 displays = intel_alloc(gpu, sizeof(*displays) * res->count_connectors,
Tony Barbour8205d902015-04-16 15:59:00 -0600729 0, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
Chia-I Wu8635e912015-04-09 14:13:57 +0800730 if (!displays) {
731 drmModeFreeResources(res);
732 return;
733 }
734
735 for (i = 0; i < res->count_connectors; i++) {
736 displays[i] = x11_display_create(gpu, fd, res->connectors[i]);
737 if (!displays[i])
738 break;
739 }
740
741 drmModeFreeResources(res);
742
743 gpu->displays = (struct intel_wsi_display **) displays;
744 gpu->display_count = i;
745}
Jon Ashburneb66fee2015-06-16 15:06:44 -0600746#endif
Chia-I Wu8635e912015-04-09 14:13:57 +0800747
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600748VkResult intel_wsi_gpu_get_info(struct intel_gpu *gpu,
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800749 VkPhysicalDeviceInfoType type,
750 size_t *size, void *data)
Chia-I Wu41858c82015-04-04 16:39:25 +0800751{
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800752 VkResult ret = VK_SUCCESS;
Chia-I Wu8635e912015-04-09 14:13:57 +0800753
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800754 if (!size)
755 return VK_ERROR_INVALID_POINTER;
756
757 switch ((int) type) {
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800758 case VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PRESENT_PROPERTIES_WSI:
759 {
760 VkPhysicalDeviceQueuePresentPropertiesWSI *dst = data;
761 size_t size_ret;
762 uint32_t i;
763
764 size_ret = sizeof(*dst) * INTEL_GPU_ENGINE_COUNT;
765
766 if (dst && *size < size_ret)
767 return VK_ERROR_INVALID_VALUE;
768
769 *size = size_ret;
770 if (!dst)
771 return VK_SUCCESS;
772
773 for (i = 0; i < INTEL_GPU_ENGINE_COUNT; i++)
774 dst[i].supportsPresent = true;
775 }
776 break;
777 default:
778 ret = VK_ERROR_INVALID_VALUE;
779 break;
780 }
781
782 return ret;
Chia-I Wu41858c82015-04-04 16:39:25 +0800783}
784
785void intel_wsi_gpu_cleanup(struct intel_gpu *gpu)
786{
Chia-I Wu8635e912015-04-09 14:13:57 +0800787 if (gpu->displays) {
788 uint32_t i;
Chia-I Wu41858c82015-04-04 16:39:25 +0800789
Chia-I Wu8635e912015-04-09 14:13:57 +0800790 for (i = 0; i < gpu->display_count; i++) {
791 struct intel_x11_display *dpy =
792 (struct intel_x11_display *) gpu->displays[i];
793 x11_display_destroy(dpy);
794 }
795 intel_free(gpu, gpu->displays);
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{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600852 if (!fence->wsi_data) {
853 return;
854 }
Chia-I Wu41858c82015-04-04 16:39:25 +0800855 memcpy(fence->wsi_data, src->wsi_data,
856 sizeof(struct intel_x11_fence_data));
857}
858
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600859VkResult intel_wsi_fence_wait(struct intel_fence *fence,
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800860 int64_t timeout_ns)
Chia-I Wu41858c82015-04-04 16:39:25 +0800861{
862 struct intel_x11_fence_data *data =
863 (struct intel_x11_fence_data *) fence->wsi_data;
864
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600865 if (!data)
866 return VK_SUCCESS;
867
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800868 if (!data->swap_chain)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600869 return VK_SUCCESS;
Chia-I Wu41858c82015-04-04 16:39:25 +0800870
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800871 return x11_swap_chain_wait(data->swap_chain, data->serial, timeout_ns);
Chia-I Wu41858c82015-04-04 16:39:25 +0800872}
873
Jon Ashburnba4a1952015-06-16 12:44:51 -0600874#if 0
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800875ICD_EXPORT VkResult VKAPI vkGetDisplayInfoWSI(
876 VkDisplayWSI display,
877 VkDisplayInfoTypeWSI infoType,
878 size_t* pDataSize,
879 void* pData)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800880{
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800881 VkResult ret = VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800882
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800883 if (!pDataSize)
884 return VK_ERROR_INVALID_POINTER;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800885
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800886 switch (infoType) {
887 case VK_DISPLAY_INFO_TYPE_FORMAT_PROPERTIES_WSI:
888 {
889 VkDisplayFormatPropertiesWSI *dst = pData;
890 size_t size_ret;
891 uint32_t i;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800892
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800893 size_ret = sizeof(*dst) * ARRAY_SIZE(x11_presentable_formats);
Chia-I Wu7fbe2ab2014-11-07 13:26:45 +0800894
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800895 if (dst && *pDataSize < size_ret)
896 return VK_ERROR_INVALID_VALUE;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800897
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800898 *pDataSize = size_ret;
899 if (!dst)
900 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800901
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800902 for (i = 0; i < ARRAY_SIZE(x11_presentable_formats); i++)
903 dst[i].swapChainFormat = x11_presentable_formats[i];
904 }
905 break;
906 default:
907 ret = VK_ERROR_INVALID_VALUE;
908 break;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800909 }
910
911 return ret;
912}
Jon Ashburnba4a1952015-06-16 12:44:51 -0600913#endif
Chia-I Wu1db76e02014-09-15 14:21:14 +0800914
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800915ICD_EXPORT VkResult VKAPI vkCreateSwapChainWSI(
916 VkDevice device,
917 const VkSwapChainCreateInfoWSI* pCreateInfo,
918 VkSwapChainWSI* pSwapChain)
919{
920 struct intel_dev *dev = intel_dev(device);
921
922 return x11_swap_chain_create(dev, pCreateInfo,
923 (struct intel_x11_swap_chain **) pSwapChain);
924}
925
926ICD_EXPORT VkResult VKAPI vkDestroySwapChainWSI(
927 VkSwapChainWSI swapChain)
928{
929 struct intel_x11_swap_chain *sc = x11_swap_chain(swapChain);
930
931 x11_swap_chain_destroy(sc);
932
933 return VK_SUCCESS;
934}
935
936ICD_EXPORT VkResult VKAPI vkGetSwapChainInfoWSI(
937 VkSwapChainWSI swapChain,
938 VkSwapChainInfoTypeWSI infoType,
939 size_t* pDataSize,
940 void* pData)
941{
942 struct intel_x11_swap_chain *sc = x11_swap_chain(swapChain);
943 VkResult ret = VK_SUCCESS;
944
945 if (!pDataSize)
946 return VK_ERROR_INVALID_POINTER;
947
948 switch (infoType) {
949 case VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI:
950 {
951 VkSwapChainImageInfoWSI *images;
952 const size_t size = sizeof(*images) * sc->persistent_image_count;
953 uint32_t i;
954
955 if (pData && *pDataSize < size)
956 return VK_ERROR_INVALID_VALUE;
957
958 *pDataSize = size;
959 if (!pData)
960 return VK_SUCCESS;
961
962 images = (VkSwapChainImageInfoWSI *) pData;
963 for (i = 0; i < sc->persistent_image_count; i++) {
964 images[i].image = (VkImage) sc->persistent_images[i];
965 images[i].memory =
966 (VkDeviceMemory) sc->persistent_images[i]->obj.mem;
967 }
968 }
969 break;
970 default:
971 ret = VK_ERROR_INVALID_VALUE;
972 break;
973 }
974
975 return ret;
976}
977
978ICD_EXPORT VkResult VKAPI vkQueuePresentWSI(
979 VkQueue queue_,
980 const VkPresentInfoWSI* pPresentInfo)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800981{
982 struct intel_queue *queue = intel_queue(queue_);
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800983 struct intel_img *img = intel_img(pPresentInfo->image);
984 struct intel_x11_swap_chain *sc =
985 ((struct intel_x11_img_data *) img->wsi_data)->swap_chain;
Chia-I Wub56f5df2015-04-04 20:21:10 +0800986 struct intel_x11_fence_data *data =
987 (struct intel_x11_fence_data *) queue->fence->wsi_data;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600988 VkResult ret;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800989
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800990 ret = x11_swap_chain_present_pixmap(sc, pPresentInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600991 if (ret != VK_SUCCESS)
Chia-I Wu1db76e02014-09-15 14:21:14 +0800992 return ret;
993
Chia-I Wu6532d1d2015-04-04 22:16:45 +0800994 data->swap_chain = sc;
995 data->serial = sc->local.serial;
Chia-I Wub56f5df2015-04-04 20:21:10 +0800996 intel_fence_set_seqno(queue->fence, img->obj.mem->bo);
Chia-I Wubda4f622015-02-25 15:06:15 -0700997
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600998 return VK_SUCCESS;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800999}