On Tuesday, 2018-02-13 16:31:20 -0800, Keith Packard wrote:
This extension adds the ability to borrow an X RandR output for temporary use directly by a Vulkan application. For DRM, we use the Linux resource leasing mechanism.
Signed-off-by: Keith Packard keithp@keithp.com
configure.ac | 32 +++ meson.build | 17 ++ meson_options.txt | 7 + src/vulkan/Makefile.am | 5 + src/vulkan/wsi/meson.build | 7 + src/vulkan/wsi/wsi_common_display.c | 472 ++++++++++++++++++++++++++++++++++++ src/vulkan/wsi/wsi_common_display.h | 17 ++ 7 files changed, 557 insertions(+)
diff --git a/configure.ac b/configure.ac index 46318365603..cf05d049c26 100644 --- a/configure.ac +++ b/configure.ac @@ -1547,6 +1547,7 @@ AM_CONDITIONAL(HAVE_APPLEDRI, test "x$enable_dri" = xyes -a "x$dri_platform" = x AM_CONDITIONAL(HAVE_LMSENSORS, test "x$enable_lmsensors" = xyes ) AM_CONDITIONAL(HAVE_GALLIUM_EXTRA_HUD, test "x$enable_gallium_extra_hud" = xyes ) AM_CONDITIONAL(HAVE_WINDOWSDRI, test "x$enable_dri" = xyes -a "x$dri_platform" = xwindows ) +AM_CONDITIONAL(HAVE_XLEASE, test "x$have_xlease" = xyes )
AC_ARG_ENABLE([shared-glapi], [AS_HELP_STRING([--enable-shared-glapi], @@ -1846,6 +1847,18 @@ if test x"$enable_dri3" = xyes; then PKG_CHECK_MODULES([XCB_DRI3], [$dri3_modules]) fi
+if echo "$platforms" | grep -q 'x11' && echo "$platforms" | grep -q 'drm'; then
- have_xlease=yes
+else
- have_xlease=no
+fi
+if test x"$have_xlease" = xyes; then
- randr_modules="x11-xcb xcb-randr"
- PKG_CHECK_MODULES([XCB_RANDR], [$randr_modules])
+fi
AM_CONDITIONAL(HAVE_PLATFORM_X11, echo "$platforms" | grep -q 'x11') AM_CONDITIONAL(HAVE_PLATFORM_WAYLAND, echo "$platforms" | grep -q 'wayland') AM_CONDITIONAL(HAVE_PLATFORM_DRM, echo "$platforms" | grep -q 'drm') @@ -1853,6 +1866,25 @@ AM_CONDITIONAL(HAVE_PLATFORM_DISPLAY, echo "$platforms" | grep -q 'drm') AM_CONDITIONAL(HAVE_PLATFORM_SURFACELESS, echo "$platforms" | grep -q 'surfaceless') AM_CONDITIONAL(HAVE_PLATFORM_ANDROID, echo "$platforms" | grep -q 'android')
+AC_ARG_ENABLE(xlib-lease,
- [AS_HELP_STRING([--enable-xlib-lease]
[enable VK_acquire_xlib_display using X leases])],
- [enable_xlib_lease=$enableval], [enable_xlib_lease=auto])
+case "x$enable_xlib_lease" in +xyes)
- ;;
+xno)
- ;;
+*)
- if echo "$platforms" | grep -q 'x11' && echo "$platforms" | grep -q 'drm'; then
enable_xlib_lease=yes
- else
enable_xlib_lease=no
- fi
+esac
+AM_CONDITIONAL(HAVE_XLIB_LEASE, test "x$enable_xlib_lease" = xyes)
dnl dnl More DRI setup dnl diff --git a/meson.build b/meson.build index aeb7f5e2917..595b0f66cd7 100644 --- a/meson.build +++ b/meson.build @@ -262,6 +262,19 @@ if _platforms != '' egl_native_platform = _split[0] endif
+with_xlib_lease = get_option('xlib-lease') +if with_xlib_lease == 'auto'
- if with_platform_x11 and with_platform_display
- with_xlib_lease = true
- else
- with_xlib_lease = false
- endif
+elif with_xlib_lease == 'true'
- with_xlib_lease = true
+else
- with_xlib_lease = false
+endif
Can be simplified a bit:
_xlib_lease = get_option('xlib-lease') if _xlib_lease == 'auto' with_xlib_lease = with_platform_x11 and with_platform_display else with_xlib_lease = _xlib_lease == 'true' endif
(We also usually try to avoid changing the type of a var, and meson might start being more strict with types in future releases)
with_glx = get_option('glx') if with_glx == 'auto' if with_dri @@ -1151,6 +1164,7 @@ dep_xcb_present = [] dep_xcb_sync = [] dep_xcb_xfixes = [] dep_xshmfence = [] +dep_xcb_xrandr = [] if with_platform_x11 if with_glx == 'xlib' or with_glx == 'gallium-xlib' dep_x11 = dependency('x11') @@ -1190,6 +1204,9 @@ if with_platform_x11 if with_egl dep_xcb_xfixes = dependency('xcb-xfixes') endif
- if with_xlib_lease
- dep_xcb_xrandr = dependency('xcb-randr', version : '>= 1.12')
- endif
endif
if get_option('gallium-extra-hud') diff --git a/meson_options.txt b/meson_options.txt index 7fafe2deaac..d38c9aa6149 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -286,3 +286,10 @@ option( value : '', description : 'Comma delimited list of tools to build. choices : freedreno,glsl,intel,nir,nouveau or all' ) +option(
- 'xlib-lease',
- type : 'combo',
- value : 'auto',
- choices : ['auto', 'true', 'false'],
- description : 'Enable VK_EXT_acquire_xlib_display.'
+) diff --git a/src/vulkan/Makefile.am b/src/vulkan/Makefile.am index c33ac5758f7..e96ef68972c 100644 --- a/src/vulkan/Makefile.am +++ b/src/vulkan/Makefile.am @@ -64,6 +64,11 @@ AM_CPPFLAGS += \ VULKAN_WSI_SOURCES += $(VULKAN_WSI_DISPLAY_FILES) endif
+if HAVE_XLIB_LEASE +AM_CPPFLAGS += \
- -DVK_USE_PLATFORM_XLIB_XRANDR_EXT
+endif
BUILT_SOURCES += $(VULKAN_WSI_WAYLAND_GENERATED_FILES) CLEANFILES = $(BUILT_SOURCES)
diff --git a/src/vulkan/wsi/meson.build b/src/vulkan/wsi/meson.build index 743631a6113..5e3d43a2748 100644 --- a/src/vulkan/wsi/meson.build +++ b/src/vulkan/wsi/meson.build @@ -67,6 +67,13 @@ if with_platform_display ) endif
+if with_xlib_lease
- vulkan_wsi_deps += dep_xcb_xrandr
- vulkan_wsi_args += [
- '-DVK_USE_PLATFORM_XLIB_XRANDR_EXT',
- ]
vulkan_wsi_args += '-DVK_USE_PLATFORM_XLIB_XRANDR_EXT'
with that, the meson part of this is Reviewed-by: Eric Engestrom eric.engestrom@imgtec.com
+endif
libvulkan_wsi = static_library( 'vulkan_wsi', files_vulkan_wsi, diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c index 5c123e6465e..29d64b21aff 100644 --- a/src/vulkan/wsi/wsi_common_display.c +++ b/src/vulkan/wsi/wsi_common_display.c @@ -32,6 +32,10 @@ #include <math.h> #include <xf86drm.h> #include <xf86drmMode.h> +#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT +#include <xcb/randr.h> +#include <X11/Xlib-xcb.h> +#endif #include "util/hash_table.h" #include "util/list.h"
@@ -73,6 +77,9 @@ typedef struct wsi_display_connector { bool active; wsi_display_mode *current_mode; drmModeModeInfo current_drm_mode; +#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
- xcb_randr_output_t output;
+#endif } wsi_display_connector;
struct wsi_display { @@ -1381,5 +1388,470 @@ wsi_release_display(VkPhysicalDevice physical_device, close(wsi->master_fd); wsi->master_fd = -1; } +#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
- wsi_display_connector_from_handle(display)->output = None;
+#endif
- return VK_SUCCESS;
}
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+static struct wsi_display_connector * +wsi_display_find_output(struct wsi_device *wsi_device,
RROutput output)
+{
- struct wsi_display *wsi = (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
- struct wsi_display_connector *connector;
- connector = NULL;
- LIST_FOR_EACH_ENTRY(connector, &wsi->connectors, list) {
if (connector->output == output)
return connector;
- }
- return NULL;
+}
+/*
- Given a RandR output, find the associated kernel connector_id by
- looking at the CONNECTOR_ID property provided by the X server
- */
+static uint32_t +wsi_display_output_to_connector_id(xcb_connection_t *connection,
xcb_atom_t *connector_id_atom_p,
RROutput output)
+{
- uint32_t connector_id = 0;
- xcb_atom_t connector_id_atom = *connector_id_atom_p;
- if (connector_id_atom == 0) {
- /* Go dig out the CONNECTOR_ID property */
xcb_intern_atom_cookie_t ia_c = xcb_intern_atom(connection,
true,
12,
"CONNECTOR_ID");
xcb_intern_atom_reply_t *ia_r = xcb_intern_atom_reply(connection,
ia_c,
NULL);
if (ia_r) {
*connector_id_atom_p = connector_id_atom = ia_r->atom;
free(ia_r);
}
- }
- /* If there's an CONNECTOR_ID atom in the server, then there may be a CONNECTOR_ID property. Otherwise,
- there will not be and we don't even need to bother.
- */
- if (connector_id_atom) {
xcb_randr_query_version_cookie_t qv_c = xcb_randr_query_version(connection, 1, 6);
xcb_randr_get_output_property_cookie_t gop_c = xcb_randr_get_output_property(connection,
output,
connector_id_atom,
0,
0,
0xffffffffUL,
0,
0);
xcb_randr_query_version_reply_t *qv_r = xcb_randr_query_version_reply(connection, qv_c, NULL);
free(qv_r);
xcb_randr_get_output_property_reply_t *gop_r = xcb_randr_get_output_property_reply(connection,
gop_c,
NULL);
if (gop_r) {
if (gop_r->num_items == 1 && gop_r->format == 32)
memcpy(&connector_id, xcb_randr_get_output_property_data(gop_r), 4);
free(gop_r);
}
- }
- return connector_id;
+}
+static bool +wsi_display_check_randr_version(xcb_connection_t *connection) +{
- xcb_randr_query_version_cookie_t qv_c = xcb_randr_query_version(connection, 1, 6);
- xcb_randr_query_version_reply_t *qv_r = xcb_randr_query_version_reply(connection, qv_c, NULL);
- bool ret = false;
- if (!qv_r)
return false;
- /* Check for version 1.6 or newer */
- ret = qv_r->major_version > 1 || (qv_r->major_version == 1 && qv_r->minor_version >= 6);
- free(qv_r);
- return ret;
+}
+/*
- Given a kernel connector id, find the associated RandR output using the
- CONNECTOR_ID property
- */
+static xcb_randr_output_t +wsi_display_connector_id_to_output(xcb_connection_t *connection,
uint32_t connector_id)
+{
- if (!wsi_display_check_randr_version(connection))
return 0;
- const xcb_setup_t *setup = xcb_get_setup(connection);
- xcb_atom_t connector_id_atom = 0;
- xcb_randr_output_t output = 0;
- /* Search all of the screens for the provided output */
- xcb_screen_iterator_t iter;
- for (iter = xcb_setup_roots_iterator(setup); output == 0 && iter.rem; xcb_screen_next(&iter)) {
xcb_randr_get_screen_resources_cookie_t gsr_c = xcb_randr_get_screen_resources(connection, iter.data->root);
xcb_randr_get_screen_resources_reply_t *gsr_r = xcb_randr_get_screen_resources_reply(connection, gsr_c, NULL);
if (!gsr_r)
return 0;
xcb_randr_output_t *ro = xcb_randr_get_screen_resources_outputs(gsr_r);
int o;
for (o = 0; o < gsr_r->num_outputs; o++) {
if (wsi_display_output_to_connector_id(connection, &connector_id_atom, ro[o]) == connector_id) {
output = ro[o];
break;
}
}
free(gsr_r);
- }
- return output;
+}
+/*
- Given a RandR output, find out which screen it's associated with
- */
+static xcb_window_t +wsi_display_output_to_root(xcb_connection_t *connection,
xcb_randr_output_t output)
+{
- if (!wsi_display_check_randr_version(connection))
return 0;
- const xcb_setup_t *setup = xcb_get_setup(connection);
- xcb_window_t root = 0;
- /* Search all of the screens for the provided output */
- xcb_screen_iterator_t iter;
- for (iter = xcb_setup_roots_iterator(setup); root == 0 && iter.rem; xcb_screen_next(&iter)) {
xcb_randr_get_screen_resources_cookie_t gsr_c = xcb_randr_get_screen_resources(connection, iter.data->root);
xcb_randr_get_screen_resources_reply_t *gsr_r = xcb_randr_get_screen_resources_reply(connection, gsr_c, NULL);
if (!gsr_r)
return 0;
xcb_randr_output_t *ro = xcb_randr_get_screen_resources_outputs(gsr_r);
int o;
for (o = 0; o < gsr_r->num_outputs; o++) {
if (ro[o] == output) {
root = iter.data->root;
break;
}
}
free(gsr_r);
- }
- return root;
+}
+static bool +wsi_display_mode_matches_x(struct wsi_display_mode *wsi,
xcb_randr_mode_info_t *xcb)
+{
- return wsi->clock == (xcb->dot_clock + 500) / 1000 &&
wsi->hdisplay == xcb->width &&
wsi->hsync_start == xcb->hsync_start &&
wsi->hsync_end == xcb->hsync_end &&
wsi->htotal == xcb->htotal &&
wsi->hskew == xcb->hskew &&
wsi->vdisplay == xcb->height &&
wsi->vsync_start == xcb->vsync_start &&
wsi->vsync_end == xcb->vsync_end &&
wsi->vtotal == xcb->vtotal &&
wsi->flags == xcb->mode_flags;
+}
+static struct wsi_display_mode * +wsi_display_find_x_mode(struct wsi_device *wsi_device,
struct wsi_display_connector *connector,
xcb_randr_mode_info_t *mode)
+{
- struct wsi_display *wsi = (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
- struct wsi_display_mode *display_mode;
- LIST_FOR_EACH_ENTRY(display_mode, &wsi->display_modes, list) {
if (display_mode->connector == connector &&
wsi_display_mode_matches_x(display_mode, mode))
return display_mode;
- }
- return NULL;
+}
+static VkResult +wsi_display_register_x_mode(struct wsi_device *wsi_device,
struct wsi_display_connector *connector,
xcb_randr_mode_info_t *x_mode,
bool preferred)
+{
- struct wsi_display *wsi = (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
- struct wsi_display_mode *display_mode;
- display_mode = wsi_display_find_x_mode(wsi_device, connector, x_mode);
- if (display_mode) {
display_mode->valid = true;
return VK_SUCCESS;
- }
- display_mode = vk_alloc(wsi->alloc, sizeof (struct wsi_display_mode), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
- if (!display_mode)
return VK_ERROR_OUT_OF_HOST_MEMORY;
- display_mode->connector = connector;
- display_mode->valid = true;
- display_mode->preferred = preferred;
- display_mode->clock = (x_mode->dot_clock + 500) / 1000; /* kHz */
- display_mode->hdisplay = x_mode->width;
- display_mode->hsync_start = x_mode->hsync_start;
- display_mode->hsync_end = x_mode->hsync_end;
- display_mode->htotal = x_mode->htotal;
- display_mode->hskew = x_mode->hskew;
- display_mode->vdisplay = x_mode->height;
- display_mode->vsync_start = x_mode->vsync_start;
- display_mode->vsync_end = x_mode->vsync_end;
- display_mode->vtotal = x_mode->vtotal;
- display_mode->vscan = 0;
- if (x_mode->mode_flags & XCB_RANDR_MODE_FLAG_DOUBLE_SCAN)
display_mode->vscan = 1;
- display_mode->flags = x_mode->mode_flags;
- LIST_ADDTAIL(&display_mode->list, &wsi->display_modes);
- return VK_SUCCESS;
+}
+static struct wsi_display_connector * +wsi_display_get_output(struct wsi_device *wsi_device,
xcb_connection_t *connection,
RROutput output)
+{
- struct wsi_display *wsi = (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
- struct wsi_display_connector *connector;
- uint32_t connector_id;
- xcb_window_t root;
- xcb_randr_get_screen_resources_cookie_t src;
- xcb_randr_get_screen_resources_reply_t *srr;
- xcb_randr_get_output_info_cookie_t oic;
- xcb_randr_get_output_info_reply_t *oir;
- xcb_randr_mode_t *x_modes;
- int m;
- root = wsi_display_output_to_root(connection, output);
- if (!root)
return NULL;
- src = xcb_randr_get_screen_resources(connection, root);
- oic = xcb_randr_get_output_info(connection, output, XCB_CURRENT_TIME);
- srr = xcb_randr_get_screen_resources_reply(connection, src, NULL);
- oir = xcb_randr_get_output_info_reply(connection, oic, NULL);
- /* See if we already have a connector for this output */
- connector = wsi_display_find_output(wsi_device, output);
- if (!connector) {
xcb_atom_t connector_id_atom = 0;
/*
* Go get the kernel connector ID for this X output
*/
connector_id = wsi_display_output_to_connector_id(connection, &connector_id_atom, output);
/* Any X server with lease support will have this atom */
if (!connector_id) {
free(oir);
free(srr);
return NULL;
}
if (!connector) {
/* See if we already have a connector for this id */
connector = wsi_display_find_connector(wsi_device, connector_id);
if (connector)
connector->output = output;
}
- }
- if (!connector) {
connector = wsi_display_alloc_connector(wsi, connector_id);
if (!connector) {
free(oir);
free(srr);
return NULL;
}
LIST_ADDTAIL(&connector->list, &wsi->connectors);
connector->output = output;
- }
- if (oir && srr) {
/* Get X modes and add them */
connector->connected = oir->connection != XCB_RANDR_CONNECTION_DISCONNECTED;
wsi_display_invalidate_connector_modes(wsi_device, connector);
x_modes = xcb_randr_get_output_info_modes(oir);
for (m = 0; m < oir->num_modes; m++) {
xcb_randr_mode_info_iterator_t i = xcb_randr_get_screen_resources_modes_iterator(srr);
while (i.rem) {
xcb_randr_mode_info_t *mi = i.data;
if (mi->id == x_modes[m]) {
VkResult result = wsi_display_register_x_mode(wsi_device, connector, mi, m < oir->num_preferred);
if (result != VK_SUCCESS) {
free(oir);
free(srr);
return NULL;
}
break;
}
xcb_randr_mode_info_next(&i);
}
}
- }
- free(oir);
- free(srr);
- return connector;
+}
+static xcb_randr_crtc_t +wsi_display_find_crtc_for_output(xcb_connection_t *connection,
xcb_window_t root,
xcb_randr_output_t output)
+{
- xcb_randr_get_screen_resources_cookie_t gsr_c = xcb_randr_get_screen_resources(connection, root);
- xcb_randr_get_screen_resources_reply_t *gsr_r = xcb_randr_get_screen_resources_reply(connection, gsr_c, NULL);
- if (!gsr_r)
return 0;
- xcb_randr_crtc_t *rc = xcb_randr_get_screen_resources_crtcs(gsr_r);
- xcb_randr_crtc_t idle_crtc = 0;
- xcb_randr_crtc_t active_crtc = 0;
- /* Find either a crtc already connected to the desired output or idle */
- int c;
- for (c = 0; active_crtc == 0 && c < gsr_r->num_crtcs; c++) {
xcb_randr_get_crtc_info_cookie_t gci_c = xcb_randr_get_crtc_info(connection, rc[c], gsr_r->config_timestamp);
xcb_randr_get_crtc_info_reply_t *gci_r = xcb_randr_get_crtc_info_reply(connection, gci_c, NULL);
if (gci_r) {
if (gci_r->mode) {
int num_outputs = xcb_randr_get_crtc_info_outputs_length(gci_r);
xcb_randr_output_t *outputs = xcb_randr_get_crtc_info_outputs(gci_r);
for (int o = 0; o < num_outputs; o++)
if (outputs[o] == output && num_outputs == 1) {
active_crtc = rc[c];
break;
}
} else if (idle_crtc == 0) {
int num_possible = xcb_randr_get_crtc_info_possible_length(gci_r);
xcb_randr_output_t *possible = xcb_randr_get_crtc_info_possible(gci_r);
for (int p = 0; p < num_possible; p++)
if (possible[p] == output) {
idle_crtc = rc[c];
break;
}
}
free(gci_r);
}
- }
- free(gsr_r);
- if (active_crtc)
return active_crtc;
- return idle_crtc;
+}
+VkResult +wsi_acquire_xlib_display(VkPhysicalDevice physical_device,
struct wsi_device *wsi_device,
Display *dpy,
VkDisplayKHR display)
+{
- struct wsi_display *wsi = (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
- xcb_connection_t *connection = XGetXCBConnection(dpy);
- struct wsi_display_connector *connector = wsi_display_connector_from_handle(display);
- xcb_window_t root;
- if (!connector->output) {
connector->output = wsi_display_connector_id_to_output(connection, connector->id);
/* Check and see if we found the output */
if (!connector->output)
return VK_ERROR_OUT_OF_DATE_KHR;
- }
- root = wsi_display_output_to_root(connection, connector->output);
- if (!root)
return VK_ERROR_OUT_OF_DATE_KHR;
- xcb_randr_crtc_t crtc = wsi_display_find_crtc_for_output(connection,
root,
connector->output);
- if (!crtc)
return VK_ERROR_OUT_OF_DATE_KHR;
- xcb_randr_lease_t lease = xcb_generate_id(connection);
- xcb_randr_create_lease_cookie_t cl_c = xcb_randr_create_lease(connection,
root,
lease,
1,
1,
&crtc,
&connector->output);
- xcb_randr_create_lease_reply_t *cl_r = xcb_randr_create_lease_reply(connection, cl_c, NULL);
- if (!cl_r)
return VK_ERROR_OUT_OF_DATE_KHR;
- int fd = -1;
- if (cl_r->nfd > 0) {
int *rcl_f = xcb_randr_create_lease_reply_fds(connection, cl_r);
fd = rcl_f[0];
- }
- free (cl_r);
- if (fd < 0)
return VK_ERROR_OUT_OF_DATE_KHR;
- wsi->master_fd = fd;
- return VK_SUCCESS;
+}
+VkResult +wsi_get_randr_output_display(VkPhysicalDevice physical_device,
struct wsi_device *wsi_device,
Display *dpy,
RROutput output,
VkDisplayKHR *display)
+{
- xcb_connection_t *connection = XGetXCBConnection(dpy);
- struct wsi_display_connector *connector = wsi_display_get_output(wsi_device, connection, output);
- if (connector)
*display = wsi_display_connector_to_handle(connector);
- else
*display = NULL;
- return VK_SUCCESS;
+}
+#endif diff --git a/src/vulkan/wsi/wsi_common_display.h b/src/vulkan/wsi/wsi_common_display.h index 5fbb6925e4a..1997c2a3c40 100644 --- a/src/vulkan/wsi/wsi_common_display.h +++ b/src/vulkan/wsi/wsi_common_display.h @@ -74,4 +74,21 @@ wsi_release_display(VkPhysicalDevice physical_device, struct wsi_device *wsi_device, VkDisplayKHR display);
+#if VK_USE_PLATFORM_XLIB_XRANDR_EXT +VkResult +wsi_acquire_xlib_display(VkPhysicalDevice physical_device,
struct wsi_device *wsi_device,
Display *dpy,
VkDisplayKHR display);
+VkResult +wsi_get_randr_output_display(VkPhysicalDevice physical_device,
struct wsi_device *wsi_device,
Display *dpy,
RROutput output,
VkDisplayKHR *display);
+#endif /* VK_USE_PLATFORM_XLIB_XRANDR_EXT */
#endif
2.15.1