summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>2019-04-17 01:30:49 +0200
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>2019-04-23 23:49:39 +0000
commitf2e0f5c3c44967da8a10ac363ab667e07ea03c28 (patch)
tree7798bceec1b829068e63267d67f423288759f75e
parent3c2e8267d0b2300963d9a04aa4c46058ef448e49 (diff)
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 <jason@jlekstrand.net>
-rw-r--r--src/amd/vulkan/radv_wsi.c3
-rw-r--r--src/freedreno/vulkan/tu_wsi.c2
-rw-r--r--src/intel/vulkan/anv_wsi.c3
-rw-r--r--src/vulkan/wsi/meson.build1
-rw-r--r--src/vulkan/wsi/wsi_common.c10
-rw-r--r--src/vulkan/wsi/wsi_common.h9
-rw-r--r--src/vulkan/wsi/wsi_common_x11.c34
7 files changed, 57 insertions, 5 deletions
diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c
index 346fb43d675..1b391f74f98 100644
--- a/src/amd/vulkan/radv_wsi.c
+++ b/src/amd/vulkan/radv_wsi.c
@@ -42,7 +42,8 @@ radv_init_wsi(struct radv_physical_device *physical_device)
radv_physical_device_to_handle(physical_device),
radv_wsi_proc_addr,
&physical_device->instance->alloc,
- physical_device->master_fd);
+ physical_device->master_fd,
+ &physical_device->instance->dri_options);
}
void
diff --git a/src/freedreno/vulkan/tu_wsi.c b/src/freedreno/vulkan/tu_wsi.c
index ce06a05d5d5..21466108b20 100644
--- a/src/freedreno/vulkan/tu_wsi.c
+++ b/src/freedreno/vulkan/tu_wsi.c
@@ -40,7 +40,7 @@ tu_wsi_init(struct tu_physical_device *physical_device)
return wsi_device_init(&physical_device->wsi_device,
tu_physical_device_to_handle(physical_device),
tu_wsi_proc_addr, &physical_device->instance->alloc,
- physical_device->master_fd);
+ physical_device->master_fd, NULL);
}
void
diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c
index 024bc1c245d..ba07bcef8b3 100644
--- a/src/intel/vulkan/anv_wsi.c
+++ b/src/intel/vulkan/anv_wsi.c
@@ -49,7 +49,8 @@ anv_init_wsi(struct anv_physical_device *physical_device)
anv_physical_device_to_handle(physical_device),
anv_wsi_proc_addr,
&physical_device->instance->alloc,
- physical_device->master_fd);
+ physical_device->master_fd,
+ NULL);
if (result != VK_SUCCESS)
return result;
diff --git a/src/vulkan/wsi/meson.build b/src/vulkan/wsi/meson.build
index 9adc4d47c5a..1f8ada56962 100644
--- a/src/vulkan/wsi/meson.build
+++ b/src/vulkan/wsi/meson.build
@@ -42,6 +42,7 @@ libvulkan_wsi = static_library(
'vulkan_wsi',
files_vulkan_wsi,
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,
diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c
index 66cc4500cb9..d44b9fad542 100644
--- a/src/vulkan/wsi/wsi_common.c
+++ b/src/vulkan/wsi/wsi_common.c
@@ -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,
+ "adaptive_sync");
+ }
+
return VK_SUCCESS;
fail:
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
index 6446320b95d..46e51286e09 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -87,6 +87,8 @@ struct wsi_fence {
struct wsi_interface;
+struct driOptionCache;
+
#define VK_ICD_WSI_PLATFORM_MAX (VK_ICD_WSI_PLATFORM_DISPLAY + 1)
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);
void
wsi_device_finish(struct wsi_device *wsi,
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index 1782aa525bc..46f1c08b453 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -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)
+ return;
+
+ if (state)
+ check = xcb_change_property_checked(conn, XCB_PROP_MODE_REPLACE,
+ drawable, reply->atom,
+ XCB_ATOM_CARDINAL, 32, 1, &state);
+ else
+ check = xcb_delete_property_checked(conn, drawable, reply->atom);
+
+ xcb_discard_reply(conn, check.sequence);
+ free(reply);
+}
+
+
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,
+ wsi_device->enable_adaptive_sync);
+
*swapchain_out = &chain->base;
return VK_SUCCESS;