diff options
author | Dave Airlie <[email protected]> | 2017-02-19 15:27:47 +1000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2017-02-20 12:53:52 +1000 |
commit | 0a44a680ff702bb4488c345db84a35c190be345e (patch) | |
tree | 96ea720f00a248c704829f38d289d27b4a685915 /src/vulkan/wsi | |
parent | 1f6376935bf91aa2e086a66dfe9737d7f4066bee (diff) |
vulkan/wsi/x11: add support to detect if we can support rendering (v3)
This adds support to radv_GetPhysicalDeviceXlibPresentationSupportKHR
and radv_GetPhysicalDeviceXcbPresentationSupportKHR to check if the
local device file descriptor is compatible with the descriptor
retrieved from the X server via DRI3.
This will stop radv binding to an X server until we have prime
support in place. Hopefully apps use this API before trying
to render things.
v2: drop unneeded function, don't leak memory. (jekstrand)
v3: also check in surface_get_support callback.
Reviewed-by: Jason Ekstrand <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/vulkan/wsi')
-rw-r--r-- | src/vulkan/wsi/Makefile.am | 1 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common.h | 1 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common_wayland.c | 1 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common_x11.c | 71 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common_x11.h | 1 |
5 files changed, 74 insertions, 1 deletions
diff --git a/src/vulkan/wsi/Makefile.am b/src/vulkan/wsi/Makefile.am index a71279947a9..b5ccf986ac3 100644 --- a/src/vulkan/wsi/Makefile.am +++ b/src/vulkan/wsi/Makefile.am @@ -13,6 +13,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/gallium/include AM_CFLAGS = \ + $(LIBDRM_CFLAGS) \ $(VISIBILITY_CFLAGS) VULKAN_LIB_DEPS = diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index 394b8fa1914..ae9e5876112 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -71,6 +71,7 @@ struct wsi_interface { struct wsi_device *wsi_device, const VkAllocationCallbacks *alloc, uint32_t queueFamilyIndex, + int local_fd, VkBool32* pSupported); VkResult (*get_capabilities)(VkIcdSurfaceBase *surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c index c2dfc657b35..44897366d94 100644 --- a/src/vulkan/wsi/wsi_common_wayland.c +++ b/src/vulkan/wsi/wsi_common_wayland.c @@ -351,6 +351,7 @@ wsi_wl_surface_get_support(VkIcdSurfaceBase *surface, struct wsi_device *wsi_device, const VkAllocationCallbacks *alloc, uint32_t queueFamilyIndex, + int local_fd, VkBool32* pSupported) { *pSupported = true; diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 64ba92196fc..bec4907adad 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -33,8 +33,9 @@ #include <unistd.h> #include <errno.h> #include <string.h> - +#include <fcntl.h> #include <poll.h> +#include <xf86drm.h> #include "util/hash_table.h" #include "wsi_common.h" @@ -59,6 +60,66 @@ struct wsi_x11 { struct hash_table *connections; }; + +/** wsi_dri3_open + * + * Wrapper around xcb_dri3_open + */ +static int +wsi_dri3_open(xcb_connection_t *conn, + xcb_window_t root, + uint32_t provider) +{ + xcb_dri3_open_cookie_t cookie; + xcb_dri3_open_reply_t *reply; + int fd; + + cookie = xcb_dri3_open(conn, + root, + provider); + + reply = xcb_dri3_open_reply(conn, cookie, NULL); + if (!reply) + return -1; + + if (reply->nfd != 1) { + free(reply); + return -1; + } + + fd = xcb_dri3_open_reply_fds(conn, reply)[0]; + free(reply); + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); + + return fd; +} + +static bool +wsi_x11_check_dri3_compatible(xcb_connection_t *conn, int local_fd) +{ + xcb_screen_iterator_t screen_iter = + xcb_setup_roots_iterator(xcb_get_setup(conn)); + xcb_screen_t *screen = screen_iter.data; + + int dri3_fd = wsi_dri3_open(conn, screen->root, None); + if (dri3_fd != -1) { + char *local_dev = drmGetRenderDeviceNameFromFd(local_fd); + char *dri3_dev = drmGetRenderDeviceNameFromFd(dri3_fd); + int ret; + + close(dri3_fd); + + ret = strcmp(local_dev, dri3_dev); + + free(local_dev); + free(dri3_dev); + + if (ret != 0) + return false; + } + return true; +} + static struct wsi_x11_connection * wsi_x11_connection_create(const VkAllocationCallbacks *alloc, xcb_connection_t *conn) @@ -255,6 +316,7 @@ VkBool32 wsi_get_physical_device_xcb_presentation_support( struct wsi_device *wsi_device, VkAllocationCallbacks *alloc, uint32_t queueFamilyIndex, + int fd, xcb_connection_t* connection, xcb_visualid_t visual_id) { @@ -270,6 +332,9 @@ VkBool32 wsi_get_physical_device_xcb_presentation_support( return false; } + if (!wsi_x11_check_dri3_compatible(connection, fd)) + return false; + unsigned visual_depth; if (!connection_get_visualtype(connection, visual_id, &visual_depth)) return false; @@ -303,6 +368,7 @@ x11_surface_get_support(VkIcdSurfaceBase *icd_surface, struct wsi_device *wsi_device, const VkAllocationCallbacks *alloc, uint32_t queueFamilyIndex, + int local_fd, VkBool32* pSupported) { xcb_connection_t *conn = x11_surface_get_connection(icd_surface); @@ -320,6 +386,9 @@ x11_surface_get_support(VkIcdSurfaceBase *icd_surface, return VK_SUCCESS; } + if (!wsi_x11_check_dri3_compatible(conn, local_fd)) + return false; + unsigned visual_depth; if (!get_visualtype_for_window(conn, window, &visual_depth)) { *pSupported = false; diff --git a/src/vulkan/wsi/wsi_common_x11.h b/src/vulkan/wsi/wsi_common_x11.h index 7166f099fdb..01f1d66eeaa 100644 --- a/src/vulkan/wsi/wsi_common_x11.h +++ b/src/vulkan/wsi/wsi_common_x11.h @@ -29,6 +29,7 @@ VkBool32 wsi_get_physical_device_xcb_presentation_support( struct wsi_device *wsi_device, VkAllocationCallbacks *alloc, uint32_t queueFamilyIndex, + int local_fd, xcb_connection_t* connection, xcb_visualid_t visual_id); |