pipe_loader: Try to connect with the X server before probing pciids v2

When X is running it is neccesary for pipe_loader to authenticate with
DRM, in order to be able to use the device.

This makes it possible to run OpenCL programs while X is running.

v2:
  - Fix C++ style comments
  - Drop Xlib-xcb dependency
  - Close the X connection when done
  - Split auth code into separate function

Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
This commit is contained in:
Tom Stellard
2012-07-17 18:36:06 +00:00
parent 17f6c9195f
commit 044de40cb0
2 changed files with 67 additions and 0 deletions

View File

@@ -35,6 +35,12 @@
#include <libudev.h>
#include <xf86drm.h>
#ifdef PIPE_LOADER_HAVE_XCB
#include <xcb/dri2.h>
#endif
#include "state_tracker/drm_driver.h"
#include "pipe_loader_priv.h"
@@ -127,6 +133,59 @@ find_drm_driver_name(struct pipe_loader_drm_device *ddev)
static struct pipe_loader_ops pipe_loader_drm_ops;
static void
pipe_loader_drm_x_auth(int fd)
{
#if PIPE_LOADER_HAVE_XCB
/* Try authenticate with the X server to give us access to devices that X
* is running on. */
xcb_connection_t *xcb_conn;
const xcb_setup_t *xcb_setup;
xcb_screen_iterator_t s;
xcb_dri2_connect_cookie_t connect_cookie;
xcb_dri2_connect_reply_t *connect;
drm_magic_t magic;
xcb_dri2_authenticate_cookie_t authenticate_cookie;
xcb_dri2_authenticate_reply_t *authenticate;
xcb_conn = xcb_connect(NULL, NULL);
if(!xcb_conn)
return;
xcb_setup = xcb_get_setup(xcb_conn);
if (!xcb_setup)
goto disconnect;
s = xcb_setup_roots_iterator(xcb_setup);
connect_cookie = xcb_dri2_connect_unchecked(xcb_conn, s.data->root,
XCB_DRI2_DRIVER_TYPE_DRI);
connect = xcb_dri2_connect_reply(xcb_conn, connect_cookie, NULL);
if (!connect || connect->driver_name_length
+ connect->device_name_length == 0) {
goto disconnect;
}
if (drmGetMagic(fd, &magic))
goto disconnect;
authenticate_cookie = xcb_dri2_authenticate_unchecked(xcb_conn,
s.data->root,
magic);
authenticate = xcb_dri2_authenticate_reply(xcb_conn,
authenticate_cookie,
NULL);
FREE(authenticate);
disconnect:
xcb_disconnect(xcb_conn);
#endif
}
boolean
pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd)
{
@@ -136,6 +195,8 @@ pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd)
ddev->base.ops = &pipe_loader_drm_ops;
ddev->fd = fd;
pipe_loader_drm_x_auth(fd);
if (!find_drm_pci_id(ddev))
goto fail;