Commit f2e0f5c3 authored by Bas Nieuwenhuizen's avatar Bas Nieuwenhuizen
Browse files

vulkan/wsi: Add X11 adaptive sync support based on dri options.

The dri options are optional. When the dri options are not provided
the WSI will not  use adaptive sync.

FWIW I think for xf86-video-amdgpu this still requires an X11 config
option, so only people who opt in can get possible regressions from this.

So then the remaining question is: why do this in the WSI?

It has been suggested in another MR that the application sets this.
However, I disagree with that as I don't think we'll ever get a
reasonable set of applications setting it.

The next questions is whether this can be a layer. It definitely
can be as implemented now. However, I think this generally fits
well with the function of the WSI. Furthemore, for e.g. the DISPLAY
WSI this is much harder to do in a layer.

Of course, most of the WSI could almost be a layer, but I think
this still fits best in the WSI.
Acked-by: Jason Ekstrand's avatarJason Ekstrand <>
parent 3c2e8267
......@@ -42,7 +42,8 @@ radv_init_wsi(struct radv_physical_device *physical_device)
......@@ -40,7 +40,7 @@ tu_wsi_init(struct tu_physical_device *physical_device)
return wsi_device_init(&physical_device->wsi_device,
tu_wsi_proc_addr, &physical_device->instance->alloc,
physical_device->master_fd, NULL);
......@@ -49,7 +49,8 @@ anv_init_wsi(struct anv_physical_device *physical_device)
if (result != VK_SUCCESS)
return result;
......@@ -42,6 +42,7 @@ libvulkan_wsi = static_library(
include_directories : [inc_common, inc_vulkan_util, inc_include],
link_with: [libxmlconfig],
dependencies : [vulkan_wsi_deps, dep_libdrm],
c_args : [c_vis_args, vulkan_wsi_args],
build_by_default : false,
......@@ -24,6 +24,7 @@
#include "wsi_common_private.h"
#include "drm-uapi/drm_fourcc.h"
#include "util/macros.h"
#include "util/xmlconfig.h"
#include "vk_util.h"
#include <time.h>
......@@ -37,7 +38,8 @@ wsi_device_init(struct wsi_device *wsi,
VkPhysicalDevice pdevice,
WSI_FN_GetPhysicalDeviceProcAddr proc_addr,
const VkAllocationCallbacks *alloc,
int display_fd)
int display_fd,
const struct driOptionCache *dri_options)
const char *present_mode;
VkResult result;
......@@ -129,6 +131,12 @@ wsi_device_init(struct wsi_device *wsi,
if (dri_options) {
if (driCheckOption(dri_options, "adaptive_sync", DRI_BOOL))
wsi->enable_adaptive_sync = driQueryOptionb(dri_options,
return VK_SUCCESS;
......@@ -87,6 +87,8 @@ struct wsi_fence {
struct wsi_interface;
struct driOptionCache;
struct wsi_device {
......@@ -103,6 +105,10 @@ struct wsi_device {
uint32_t maxImageDimension2D;
VkPresentModeKHR override_present_mode;
/* Whether to enable adaptive sync for a swapchain if implemented and
* available. Not all window systems might support this. */
bool enable_adaptive_sync;
uint64_t (*image_get_modifier)(VkImage image);
#define WSI_CB(cb) PFN_vk##cb cb
......@@ -144,7 +150,8 @@ wsi_device_init(struct wsi_device *wsi,
VkPhysicalDevice pdevice,
WSI_FN_GetPhysicalDeviceProcAddr proc_addr,
const VkAllocationCallbacks *alloc,
int display_fd);
int display_fd,
const struct driOptionCache *dri_options);
wsi_device_finish(struct wsi_device *wsi,
......@@ -1315,6 +1315,33 @@ x11_swapchain_destroy(struct wsi_swapchain *anv_chain,
return VK_SUCCESS;
static void
wsi_x11_set_adaptive_sync_property(xcb_connection_t *conn,
xcb_drawable_t drawable,
uint32_t state)
static char const name[] = "_VARIABLE_REFRESH";
xcb_intern_atom_cookie_t cookie;
xcb_intern_atom_reply_t* reply;
xcb_void_cookie_t check;
cookie = xcb_intern_atom(conn, 0, strlen(name), name);
reply = xcb_intern_atom_reply(conn, cookie, NULL);
if (reply == NULL)
if (state)
check = xcb_change_property_checked(conn, XCB_PROP_MODE_REPLACE,
drawable, reply->atom,
XCB_ATOM_CARDINAL, 32, 1, &state);
check = xcb_delete_property_checked(conn, drawable, reply->atom);
xcb_discard_reply(conn, check.sequence);
static VkResult
x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
VkDevice device,
......@@ -1467,6 +1494,13 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
for (int i = 0; i < ARRAY_SIZE(modifiers); i++)
vk_free(pAllocator, modifiers[i]);
/* It is safe to set it here as only one swapchain can be associated with
* the window, and swapchain creation does the association. At this point
* we know the creation is going to succeed. */
wsi_x11_set_adaptive_sync_property(conn, window,
*swapchain_out = &chain->base;
return VK_SUCCESS;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment