<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>