diff options
author | Bas Nieuwenhuizen <[email protected]> | 2019-04-17 01:30:49 +0200 |
---|---|---|
committer | Bas Nieuwenhuizen <[email protected]> | 2019-04-23 23:49:39 +0000 |
commit | f2e0f5c3c44967da8a10ac363ab667e07ea03c28 (patch) | |
tree | 7798bceec1b829068e63267d67f423288759f75e | |
parent | 3c2e8267d0b2300963d9a04aa4c46058ef448e49 (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 <[email protected]>
-rw-r--r-- | src/amd/vulkan/radv_wsi.c | 3 | ||||
-rw-r--r-- | src/freedreno/vulkan/tu_wsi.c | 2 | ||||
-rw-r--r-- | src/intel/vulkan/anv_wsi.c | 3 | ||||
-rw-r--r-- | src/vulkan/wsi/meson.build | 1 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common.c | 10 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common.h | 9 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common_x11.c | 34 |
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; |