summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-02-19 15:27:47 +1000
committerDave Airlie <airlied@redhat.com>2017-02-20 12:53:52 +1000
commit0a44a680ff702bb4488c345db84a35c190be345e (patch)
tree96ea720f00a248c704829f38d289d27b4a685915
parent1f6376935bf91aa2e086a66dfe9737d7f4066bee (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 <jason@jlekstrand.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--src/amd/vulkan/radv_device.c5
-rw-r--r--src/amd/vulkan/radv_private.h1
-rw-r--r--src/amd/vulkan/radv_wsi.c2
-rw-r--r--src/amd/vulkan/radv_wsi_x11.c8
-rw-r--r--src/intel/vulkan/Makefile.am3
-rw-r--r--src/intel/vulkan/anv_device.c3
-rw-r--r--src/intel/vulkan/anv_private.h1
-rw-r--r--src/intel/vulkan/anv_wsi.c2
-rw-r--r--src/intel/vulkan/anv_wsi_x11.c8
-rw-r--r--src/vulkan/wsi/Makefile.am1
-rw-r--r--src/vulkan/wsi/wsi_common.h1
-rw-r--r--src/vulkan/wsi/wsi_common_wayland.c1
-rw-r--r--src/vulkan/wsi/wsi_common_x11.c71
-rw-r--r--src/vulkan/wsi/wsi_common_x11.h1
14 files changed, 98 insertions, 10 deletions
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index 7900ece9c8..3d0e74273e 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -225,6 +225,8 @@ radv_physical_device_init(struct radv_physical_device *device,
result = VK_ERROR_INCOMPATIBLE_DRIVER;
goto fail;
}
+
+ device->local_fd = fd;
device->ws->query_info(device->ws, &device->rad_info);
result = radv_init_wsi(device);
if (result != VK_SUCCESS) {
@@ -249,7 +251,7 @@ radv_physical_device_init(struct radv_physical_device *device,
fprintf(stderr, "WARNING: radv is not a conformant vulkan implementation, testing use only.\n");
device->name = device->rad_info.name;
- close(fd);
+
return VK_SUCCESS;
fail:
@@ -263,6 +265,7 @@ radv_physical_device_finish(struct radv_physical_device *device)
radv_extensions_finish(device->instance, &device->extensions);
radv_finish_wsi(device);
device->ws->destroy(device->ws);
+ close(device->local_fd);
}
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index ac21b075c2..5fabc409d8 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -280,6 +280,7 @@ struct radv_physical_device {
const char * name;
uint8_t uuid[VK_UUID_SIZE];
+ int local_fd;
struct wsi_device wsi_device;
struct radv_extensions extensions;
};
diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c
index 9c9e1bb0a8..ea8e784972 100644
--- a/src/amd/vulkan/radv_wsi.c
+++ b/src/amd/vulkan/radv_wsi.c
@@ -92,7 +92,7 @@ VkResult radv_GetPhysicalDeviceSurfaceSupportKHR(
return iface->get_support(surface, &device->wsi_device,
&device->instance->alloc,
- queueFamilyIndex, pSupported);
+ queueFamilyIndex, device->local_fd, pSupported);
}
VkResult radv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
diff --git a/src/amd/vulkan/radv_wsi_x11.c b/src/amd/vulkan/radv_wsi_x11.c
index 946b99095a..97d4277c49 100644
--- a/src/amd/vulkan/radv_wsi_x11.c
+++ b/src/amd/vulkan/radv_wsi_x11.c
@@ -45,7 +45,9 @@ VkBool32 radv_GetPhysicalDeviceXcbPresentationSupportKHR(
return wsi_get_physical_device_xcb_presentation_support(
&device->wsi_device,
&device->instance->alloc,
- queueFamilyIndex, connection, visual_id);
+ queueFamilyIndex,
+ device->local_fd,
+ connection, visual_id);
}
VkBool32 radv_GetPhysicalDeviceXlibPresentationSupportKHR(
@@ -59,7 +61,9 @@ VkBool32 radv_GetPhysicalDeviceXlibPresentationSupportKHR(
return wsi_get_physical_device_xcb_presentation_support(
&device->wsi_device,
&device->instance->alloc,
- queueFamilyIndex, XGetXCBConnection(dpy), visualID);
+ queueFamilyIndex,
+ device->local_fd,
+ XGetXCBConnection(dpy), visualID);
}
VkResult radv_CreateXcbSurfaceKHR(
diff --git a/src/intel/vulkan/Makefile.am b/src/intel/vulkan/Makefile.am
index 4197b0e77c..93f2ceb00f 100644
--- a/src/intel/vulkan/Makefile.am
+++ b/src/intel/vulkan/Makefile.am
@@ -68,6 +68,7 @@ AM_CPPFLAGS += \
endif
AM_CPPFLAGS += \
+ $(LIBDRM_CFLAGS) \
$(INTEL_CFLAGS) \
$(VALGRIND_CFLAGS) \
$(DEFINES)
@@ -93,7 +94,7 @@ VULKAN_SOURCES = \
$(VULKAN_GENERATED_FILES) \
$(VULKAN_FILES)
-VULKAN_LIB_DEPS =
+VULKAN_LIB_DEPS = $(LIBDRM_LIBS)
if HAVE_PLATFORM_X11
AM_CPPFLAGS += \
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index cae5feff94..dd2a1ea34a 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -202,7 +202,7 @@ anv_physical_device_init(struct anv_physical_device *device,
isl_device_init(&device->isl_dev, &device->info, swizzled);
- close(fd);
+ device->local_fd = fd;
return VK_SUCCESS;
fail:
@@ -215,6 +215,7 @@ anv_physical_device_finish(struct anv_physical_device *device)
{
anv_finish_wsi(device);
ralloc_free(device->compiler);
+ close(device->local_fd);
}
static const VkExtensionProperties global_extensions[] = {
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index da1ca29f64..82e283171e 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -532,6 +532,7 @@ struct anv_physical_device {
uint8_t uuid[VK_UUID_SIZE];
struct wsi_device wsi_device;
+ int local_fd;
};
struct anv_instance {
diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c
index 3a366988de..a69a741723 100644
--- a/src/intel/vulkan/anv_wsi.c
+++ b/src/intel/vulkan/anv_wsi.c
@@ -94,7 +94,7 @@ VkResult anv_GetPhysicalDeviceSurfaceSupportKHR(
return iface->get_support(surface, &device->wsi_device,
&device->instance->alloc,
- queueFamilyIndex, pSupported);
+ queueFamilyIndex, device->local_fd, pSupported);
}
VkResult anv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
diff --git a/src/intel/vulkan/anv_wsi_x11.c b/src/intel/vulkan/anv_wsi_x11.c
index 60bc568ab0..30425096a9 100644
--- a/src/intel/vulkan/anv_wsi_x11.c
+++ b/src/intel/vulkan/anv_wsi_x11.c
@@ -41,7 +41,9 @@ VkBool32 anv_GetPhysicalDeviceXcbPresentationSupportKHR(
return wsi_get_physical_device_xcb_presentation_support(
&device->wsi_device,
&device->instance->alloc,
- queueFamilyIndex, connection, visual_id);
+ queueFamilyIndex,
+ device->local_fd,
+ connection, visual_id);
}
VkBool32 anv_GetPhysicalDeviceXlibPresentationSupportKHR(
@@ -55,7 +57,9 @@ VkBool32 anv_GetPhysicalDeviceXlibPresentationSupportKHR(
return wsi_get_physical_device_xcb_presentation_support(
&device->wsi_device,
&device->instance->alloc,
- queueFamilyIndex, XGetXCBConnection(dpy), visualID);
+ queueFamilyIndex,
+ device->local_fd,
+ XGetXCBConnection(dpy), visualID);
}
VkResult anv_CreateXcbSurfaceKHR(
diff --git a/src/vulkan/wsi/Makefile.am b/src/vulkan/wsi/Makefile.am
index a71279947a..b5ccf986ac 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 394b8fa191..ae9e587611 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 c2dfc657b3..44897366d9 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 64ba92196f..bec4907ada 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 7166f099fd..01f1d66eea 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);