<div dir="auto"><div><div class="gmail_extra"><div class="gmail_quote">On Feb 19, 2017 2:33 PM, "Dave Airlie" <<a href="mailto:airlied@gmail.com">airlied@gmail.com</a>> wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Dave Airlie <<a href="mailto:airlied@redhat.com">airlied@redhat.com</a>><br>
<br>
This adds support to radv_<wbr>GetPhysicalDeviceXlibPresentat<wbr>ionSupportKHR<br>
and radv_<wbr>GetPhysicalDeviceXcbPresentati<wbr>onSupportKHR to check if the<br>
local device file descriptor is compatible with the descriptor<br>
retrieved from the X server via DRI3.<br>
<br>
This will stop radv binding to an X server until we have prime<br>
support in place. Hopefully apps use this API before trying<br>
to render things.<br>
<br>
v2: drop unneeded function, don't leak memory. (jekstrand)<br>
v3: also check in surface_get_support callback.<br>
<br>
Signed-off-by: Dave Airlie <<a href="mailto:airlied@redhat.com">airlied@redhat.com</a>><br>
---<br>
src/amd/vulkan/radv_device.c | 5 ++-<br>
src/amd/vulkan/radv_private.h | 1 +<br>
src/amd/vulkan/radv_wsi.c | 2 +-<br>
src/amd/vulkan/radv_wsi_x11.c | 8 +++-<br>
src/intel/vulkan/Makefile.am | 3 +-<br>
src/intel/vulkan/anv_device.c | 3 +-<br>
src/intel/vulkan/anv_private.h | 1 +<br>
src/intel/vulkan/anv_wsi.c | 2 +-<br>
src/intel/vulkan/anv_wsi_x11.c | 8 +++-<br>
src/vulkan/wsi/Makefile.am | 1 +<br>
src/vulkan/wsi/wsi_common.h | 1 +<br>
src/vulkan/wsi/wsi_common_<wbr>wayland.c | 1 +<br>
src/vulkan/wsi/wsi_common_x11.<wbr>c | 73 ++++++++++++++++++++++++++++++<wbr>++++++-<br>
src/vulkan/wsi/wsi_common_x11.<wbr>h | 1 +<br>
14 files changed, 100 insertions(+), 10 deletions(-)<br>
<br>
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c<br>
index 93cf006..f0cbb7b 100644<br>
--- a/src/amd/vulkan/radv_device.c<br>
+++ b/src/amd/vulkan/radv_device.c<br>
@@ -225,6 +225,8 @@ radv_physical_device_init(<wbr>struct radv_physical_device *device,<br>
result = VK_ERROR_INCOMPATIBLE_DRIVER;<br>
goto fail;<br>
}<br>
+<br>
+ device->local_fd = fd;<br>
device->ws->query_info(device-<wbr>>ws, &device->rad_info);<br>
result = radv_init_wsi(device);<br>
if (result != VK_SUCCESS) {<br>
@@ -249,7 +251,7 @@ radv_physical_device_init(<wbr>struct radv_physical_device *device,<br>
<br>
fprintf(stderr, "WARNING: radv is not a conformant vulkan implementation, testing use only.\n");<br>
device->name = device-><a href="http://rad_info.name" rel="noreferrer" target="_blank">rad_info.name</a>;<br>
- close(fd);<br>
+<br>
return VK_SUCCESS;<br>
<br>
fail:<br>
@@ -263,6 +265,7 @@ radv_physical_device_finish(<wbr>struct radv_physical_device *device)<br>
radv_extensions_finish(device-<wbr>>instance, &device->extensions);<br>
radv_finish_wsi(device);<br>
device->ws->destroy(device-><wbr>ws);<br>
+ close(device->local_fd);<br>
}<br>
<br>
<br>
diff --git a/src/amd/vulkan/radv_private.<wbr>h b/src/amd/vulkan/radv_private.<wbr>h<br>
index 099dba3..2e4bdcd 100644<br>
--- a/src/amd/vulkan/radv_private.<wbr>h<br>
+++ b/src/amd/vulkan/radv_private.<wbr>h<br>
@@ -280,6 +280,7 @@ struct radv_physical_device {<br>
const char * name;<br>
uint8_t uuid[VK_UUID_SIZE];<br>
<br>
+ int local_fd;<br>
struct wsi_device wsi_device;<br>
struct radv_extensions extensions;<br>
};<br>
diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c<br>
index 9c9e1bb..ea8e784 100644<br>
--- a/src/amd/vulkan/radv_wsi.c<br>
+++ b/src/amd/vulkan/radv_wsi.c<br>
@@ -92,7 +92,7 @@ VkResult radv_<wbr>GetPhysicalDeviceSurfaceSuppor<wbr>tKHR(<br>
<br>
return iface->get_support(surface, &device->wsi_device,<br>
&device->instance->alloc,<br>
- queueFamilyIndex, pSupported);<br>
+ queueFamilyIndex, device->local_fd, pSupported);<br>
}<br>
<br>
VkResult radv_<wbr>GetPhysicalDeviceSurfaceCapabi<wbr>litiesKHR(<br>
diff --git a/src/amd/vulkan/radv_wsi_x11.<wbr>c b/src/amd/vulkan/radv_wsi_x11.<wbr>c<br>
index 946b990..97d4277 100644<br>
--- a/src/amd/vulkan/radv_wsi_x11.<wbr>c<br>
+++ b/src/amd/vulkan/radv_wsi_x11.<wbr>c<br>
@@ -45,7 +45,9 @@ VkBool32 radv_<wbr>GetPhysicalDeviceXcbPresentati<wbr>onSupportKHR(<br>
return wsi_get_physical_device_xcb_<wbr>presentation_support(<br>
&device->wsi_device,<br>
&device->instance->alloc,<br>
- queueFamilyIndex, connection, visual_id);<br>
+ queueFamilyIndex,<br>
+ device->local_fd,<br>
+ connection, visual_id);<br>
}<br>
<br>
VkBool32 radv_<wbr>GetPhysicalDeviceXlibPresentat<wbr>ionSupportKHR(<br>
@@ -59,7 +61,9 @@ VkBool32 radv_<wbr>GetPhysicalDeviceXlibPresentat<wbr>ionSupportKHR(<br>
return wsi_get_physical_device_xcb_<wbr>presentation_support(<br>
&device->wsi_device,<br>
&device->instance->alloc,<br>
- queueFamilyIndex, XGetXCBConnection(dpy), visualID);<br>
+ queueFamilyIndex,<br>
+ device->local_fd,<br>
+ XGetXCBConnection(dpy), visualID);<br>
}<br>
<br>
VkResult radv_CreateXcbSurfaceKHR(<br>
diff --git a/src/intel/vulkan/Makefile.am b/src/intel/vulkan/Makefile.am<br>
index 4197b0e..93f2ceb 100644<br>
--- a/src/intel/vulkan/Makefile.am<br>
+++ b/src/intel/vulkan/Makefile.am<br>
@@ -68,6 +68,7 @@ AM_CPPFLAGS += \<br>
endif<br>
<br>
AM_CPPFLAGS += \<br>
+ $(LIBDRM_CFLAGS) \<br>
$(INTEL_CFLAGS) \<br>
$(VALGRIND_CFLAGS) \<br>
$(DEFINES)<br>
@@ -93,7 +94,7 @@ VULKAN_SOURCES = \<br>
$(VULKAN_GENERATED_FILES) \<br>
$(VULKAN_FILES)<br>
<br>
-VULKAN_LIB_DEPS =<br>
+VULKAN_LIB_DEPS = $(LIBDRM_LIBS)<br>
<br>
if HAVE_PLATFORM_X11<br>
AM_CPPFLAGS += \<br>
diff --git a/src/intel/vulkan/anv_device.<wbr>c b/src/intel/vulkan/anv_device.<wbr>c<br>
index cae5fef..dd2a1ea 100644<br>
--- a/src/intel/vulkan/anv_device.<wbr>c<br>
+++ b/src/intel/vulkan/anv_device.<wbr>c<br>
@@ -202,7 +202,7 @@ anv_physical_device_init(<wbr>struct anv_physical_device *device,<br>
<br>
isl_device_init(&device->isl_<wbr>dev, &device->info, swizzled);<br>
<br>
- close(fd);<br>
+ device->local_fd = fd;<br>
return VK_SUCCESS;<br>
<br>
fail:<br>
@@ -215,6 +215,7 @@ anv_physical_device_finish(<wbr>struct anv_physical_device *device)<br>
{<br>
anv_finish_wsi(device);<br>
ralloc_free(device->compiler);<br>
+ close(device->local_fd);<br>
}<br>
<br>
static const VkExtensionProperties global_extensions[] = {<br>
diff --git a/src/intel/vulkan/anv_<wbr>private.h b/src/intel/vulkan/anv_<wbr>private.h<br>
index da1ca29..82e2831 100644<br>
--- a/src/intel/vulkan/anv_<wbr>private.h<br>
+++ b/src/intel/vulkan/anv_<wbr>private.h<br>
@@ -532,6 +532,7 @@ struct anv_physical_device {<br>
uint8_t uuid[VK_UUID_SIZE];<br>
<br>
struct wsi_device wsi_device;<br>
+ int local_fd;<br>
};<br>
<br>
struct anv_instance {<br>
diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c<br>
index 3a36698..a69a741 100644<br>
--- a/src/intel/vulkan/anv_wsi.c<br>
+++ b/src/intel/vulkan/anv_wsi.c<br>
@@ -94,7 +94,7 @@ VkResult anv_<wbr>GetPhysicalDeviceSurfaceSuppor<wbr>tKHR(<br>
<br>
return iface->get_support(surface, &device->wsi_device,<br>
&device->instance->alloc,<br>
- queueFamilyIndex, pSupported);<br>
+ queueFamilyIndex, device->local_fd, pSupported);<br>
}<br>
<br>
VkResult anv_<wbr>GetPhysicalDeviceSurfaceCapabi<wbr>litiesKHR(<br>
diff --git a/src/intel/vulkan/anv_wsi_<wbr>x11.c b/src/intel/vulkan/anv_wsi_<wbr>x11.c<br>
index 60bc568..3042509 100644<br>
--- a/src/intel/vulkan/anv_wsi_<wbr>x11.c<br>
+++ b/src/intel/vulkan/anv_wsi_<wbr>x11.c<br>
@@ -41,7 +41,9 @@ VkBool32 anv_<wbr>GetPhysicalDeviceXcbPresentati<wbr>onSupportKHR(<br>
return wsi_get_physical_device_xcb_<wbr>presentation_support(<br>
&device->wsi_device,<br>
&device->instance->alloc,<br>
- queueFamilyIndex, connection, visual_id);<br>
+ queueFamilyIndex,<br>
+ device->local_fd,<br>
+ connection, visual_id);<br>
}<br>
<br>
VkBool32 anv_<wbr>GetPhysicalDeviceXlibPresentat<wbr>ionSupportKHR(<br>
@@ -55,7 +57,9 @@ VkBool32 anv_<wbr>GetPhysicalDeviceXlibPresentat<wbr>ionSupportKHR(<br>
return wsi_get_physical_device_xcb_<wbr>presentation_support(<br>
&device->wsi_device,<br>
&device->instance->alloc,<br>
- queueFamilyIndex, XGetXCBConnection(dpy), visualID);<br>
+ queueFamilyIndex,<br>
+ device->local_fd,<br>
+ XGetXCBConnection(dpy), visualID);<br>
}<br>
<br>
VkResult anv_CreateXcbSurfaceKHR(<br>
diff --git a/src/vulkan/wsi/Makefile.am b/src/vulkan/wsi/Makefile.am<br>
index a712799..b5ccf98 100644<br>
--- a/src/vulkan/wsi/Makefile.am<br>
+++ b/src/vulkan/wsi/Makefile.am<br>
@@ -13,6 +13,7 @@ AM_CPPFLAGS = \<br>
-I$(top_srcdir)/src/gallium/<wbr>include<br>
<br>
AM_CFLAGS = \<br>
+ $(LIBDRM_CFLAGS) \<br>
$(VISIBILITY_CFLAGS)<br>
<br>
VULKAN_LIB_DEPS =<br>
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h<br>
index 394b8fa..ae9e587 100644<br>
--- a/src/vulkan/wsi/wsi_common.h<br>
+++ b/src/vulkan/wsi/wsi_common.h<br>
@@ -71,6 +71,7 @@ struct wsi_interface {<br>
struct wsi_device *wsi_device,<br>
const VkAllocationCallbacks *alloc,<br>
uint32_t queueFamilyIndex,<br>
+ int local_fd,<br>
VkBool32* pSupported);<br>
VkResult (*get_capabilities)(<wbr>VkIcdSurfaceBase *surface,<br>
VkSurfaceCapabilitiesKHR* pSurfaceCapabilities);<br>
diff --git a/src/vulkan/wsi/wsi_common_<wbr>wayland.c b/src/vulkan/wsi/wsi_common_<wbr>wayland.c<br>
index c2dfc65..4489736 100644<br>
--- a/src/vulkan/wsi/wsi_common_<wbr>wayland.c<br>
+++ b/src/vulkan/wsi/wsi_common_<wbr>wayland.c<br>
@@ -351,6 +351,7 @@ wsi_wl_surface_get_support(<wbr>VkIcdSurfaceBase *surface,<br>
struct wsi_device *wsi_device,<br>
const VkAllocationCallbacks *alloc,<br>
uint32_t queueFamilyIndex,<br>
+ int local_fd,<br>
VkBool32* pSupported)<br>
{<br>
*pSupported = true;<br>
diff --git a/src/vulkan/wsi/wsi_common_<wbr>x11.c b/src/vulkan/wsi/wsi_common_<wbr>x11.c<br>
index 64ba921..fe3ce22 100644<br>
--- a/src/vulkan/wsi/wsi_common_<wbr>x11.c<br>
+++ b/src/vulkan/wsi/wsi_common_<wbr>x11.c<br>
@@ -33,8 +33,9 @@<br>
#include <unistd.h><br>
#include <errno.h><br>
#include <string.h><br>
-<br>
+#include <fcntl.h><br>
#include <poll.h><br>
+#include <xf86drm.h><br>
#include "util/hash_table.h"<br>
<br>
#include "wsi_common.h"<br>
@@ -59,6 +60,66 @@ struct wsi_x11 {<br>
struct hash_table *connections;<br>
};<br>
<br>
+<br>
+/** wsi_dri3_open<br>
+ *<br>
+ * Wrapper around xcb_dri3_open<br>
+ */<br>
+static int<br>
+wsi_dri3_open(xcb_connection_<wbr>t *conn,<br>
+ xcb_window_t root,<br>
+ uint32_t provider)<br>
+{<br>
+ xcb_dri3_open_cookie_t cookie;<br>
+ xcb_dri3_open_reply_t *reply;<br>
+ int fd;<br>
+<br>
+ cookie = xcb_dri3_open(conn,<br>
+ root,<br>
+ provider);<br>
+<br>
+ reply = xcb_dri3_open_reply(conn, cookie, NULL);<br>
+ if (!reply)<br>
+ return -1;<br>
+<br>
+ if (reply->nfd != 1) {<br>
+ free(reply);<br>
+ return -1;<br>
+ }<br>
+<br>
+ fd = xcb_dri3_open_reply_fds(conn, reply)[0];<br>
+ free(reply);<br>
+ fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);<br>
+<br>
+ return fd;<br>
+}<br>
+<br>
+static bool<br>
+wsi_x11_check_dri3_<wbr>compatible(xcb_connection_t *conn, int local_fd)<br>
+{<br>
+ xcb_screen_iterator_t screen_iter =<br>
+ xcb_setup_roots_iterator(xcb_<wbr>get_setup(conn));<br>
+ xcb_screen_t *screen = screen_iter.data;<br>
+<br>
+ int dri3_fd = wsi_dri3_open(conn, screen->root, None);<br>
+ if (dri3_fd != -1) {<br>
+ char *local_dev = drmGetRenderDeviceNameFromFd(<wbr>local_fd);<br>
+ char *dri3_dev = drmGetRenderDeviceNameFromFd(<wbr>dri3_fd);<br></blockquote></div></div></div><div dir="auto"><br></div><div dir="auto">Pardon me for being pedantic about error checking but what if one of these returns NULL?</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ int ret;<br>
+<br>
+ close(dri3_fd);<br>
+<br>
+ ret = strcmp(local_dev, dri3_dev);<br>
+<br>
+ free(local_dev);<br>
+ free(dri3_dev);<br>
+<br>
+ if (ret != 0)<br>
+ return false;<br>
+ }<br>
+ return true;<br>
+}<br>
+<br>
static struct wsi_x11_connection *<br>
wsi_x11_connection_create(<wbr>const VkAllocationCallbacks *alloc,<br>
xcb_connection_t *conn)<br>
@@ -255,6 +316,7 @@ VkBool32 wsi_get_physical_device_xcb_<wbr>presentation_support(<br>
struct wsi_device *wsi_device,<br>
VkAllocationCallbacks *alloc,<br>
uint32_t queueFamilyIndex,<br>
+ int fd,<br>
xcb_connection_t* connection,<br>
xcb_visualid_t visual_id)<br>
{<br>
@@ -270,6 +332,10 @@ VkBool32 wsi_get_physical_device_xcb_<wbr>presentation_support(<br>
return false;<br>
}<br>
<br>
+ bool ret = wsi_x11_check_dri3_compatible(<wbr>connection, fd);<br>
+ if (ret == false)<br>
+ return false;<br>
+<br>
unsigned visual_depth;<br>
if (!connection_get_visualtype(<wbr>connection, visual_id, &visual_depth))<br>
return false;<br>
@@ -303,6 +369,7 @@ x11_surface_get_support(<wbr>VkIcdSurfaceBase *icd_surface,<br>
struct wsi_device *wsi_device,<br>
const VkAllocationCallbacks *alloc,<br>
uint32_t queueFamilyIndex,<br>
+ int local_fd,<br>
VkBool32* pSupported)<br>
{<br>
xcb_connection_t *conn = x11_surface_get_connection(<wbr>icd_surface);<br>
@@ -320,6 +387,10 @@ x11_surface_get_support(<wbr>VkIcdSurfaceBase *icd_surface,<br>
return VK_SUCCESS;<br>
}<br>
<br>
+ bool ret = wsi_x11_check_dri3_compatible(<wbr>conn, local_fd);<br>
+ if (ret == false)<br>
+ return false;<br>
+<br>
unsigned visual_depth;<br>
if (!get_visualtype_for_window(<wbr>conn, window, &visual_depth)) {<br>
*pSupported = false;<br>
diff --git a/src/vulkan/wsi/wsi_common_<wbr>x11.h b/src/vulkan/wsi/wsi_common_<wbr>x11.h<br>
index 7166f09..01f1d66 100644<br>
--- a/src/vulkan/wsi/wsi_common_<wbr>x11.h<br>
+++ b/src/vulkan/wsi/wsi_common_<wbr>x11.h<br>
@@ -29,6 +29,7 @@ VkBool32 wsi_get_physical_device_xcb_<wbr>presentation_support(<br>
struct wsi_device *wsi_device,<br>
VkAllocationCallbacks *alloc,<br>
uint32_t queueFamilyIndex,<br>
+ int local_fd,<br>
xcb_connection_t* connection,<br>
xcb_visualid_t visual_id);<br>
<font color="#888888"><br>
--<br>
2.9.3<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></blockquote></div><br></div></div></div>