Esempio n. 1
0
int mggh::DRMHelper::get_authenticated_fd()
{
    /* We must have our own device fd first, so that it has become the DRM master */
    if (fd < 0)
        BOOST_THROW_EXCEPTION(
            std::runtime_error(
                "Tried to get authenticated DRM fd before setting up the DRM master"));

    int auth_fd = open_drm_device();

    if (auth_fd < 0)
        BOOST_THROW_EXCEPTION(
            std::runtime_error("Failed to open DRM device for authenticated fd"));

    drm_magic_t magic;
    int ret = -1;
    if ((ret = drmGetMagic(auth_fd, &magic)) < 0)
    {
        close(auth_fd);
        BOOST_THROW_EXCEPTION(
            boost::enable_error_info(
                std::runtime_error("Failed to get DRM device magic cookie")) << boost::errinfo_errno(ret));
    }

    if ((ret = drmAuthMagic(fd, magic)) < 0)
    {
        close(auth_fd);
        BOOST_THROW_EXCEPTION(
            boost::enable_error_info(
                std::runtime_error("Failed to authenticate DRM device magic cookie")) << boost::errinfo_errno(ret));
    }

    return auth_fd;
}
Esempio n. 2
0
static void
xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
{
   struct xwl_screen *xwl_screen = data;
   drm_magic_t magic;

   xwl_screen->device_name = strdup(device);
   if (!xwl_screen->device_name)
      return;

   xwl_screen->drm_fd = open(xwl_screen->device_name, O_RDWR | O_CLOEXEC);
   if (xwl_screen->drm_fd == -1) {
       ErrorF("wayland-egl: could not open %s (%s)\n",
	      xwl_screen->device_name, strerror(errno));
       return;
   }

   if (is_fd_render_node(xwl_screen->drm_fd)) {
       xwl_screen->fd_render_node = 1;
       xwl_drm_init_egl(xwl_screen);
   } else {
       drmGetMagic(xwl_screen->drm_fd, &magic);
       wl_drm_authenticate(xwl_screen->drm, magic);
   }
}
Esempio n. 3
0
static void
drm_handle_device(void *data, struct wl_drm *drm, const char *device)
{
    VADisplayContextP const pDisplayContext = data;
    VADriverContextP const ctx = pDisplayContext->pDriverContext;
    VADisplayContextWaylandDRM * const wl_drm_ctx = pDisplayContext->opaque;
    struct drm_state * const drm_state = ctx->drm_state;
    drm_magic_t magic;
    struct stat st;

    if (stat(device, &st) < 0) {
        va_wayland_error("failed to identify %s: %s (errno %d)",
                         device, strerror(errno), errno);
        return;
    }

    if (!S_ISCHR(st.st_mode)) {
        va_wayland_error("%s is not a device", device);
        return;
    }

    drm_state->fd = open(device, O_RDWR);
    if (drm_state->fd < 0) {
        va_wayland_error("failed to open %s: %s (errno %d)",
                         device, strerror(errno), errno);
        return;
    }

    drmGetMagic(drm_state->fd, &magic);
    wl_drm_authenticate(wl_drm_ctx->drm, magic);
}
Esempio n. 4
0
static inline int
is_drm_master(int drm_fd)
{
	drm_magic_t magic;

	return drmGetMagic(drm_fd, &magic) == 0 &&
		drmAuthMagic(drm_fd, magic) == 0;
}
Esempio n. 5
0
void QXcbConnection::initializeDri2()
{
    xcb_dri2_connect_cookie_t connect_cookie = xcb_dri2_connect_unchecked (m_connection,
                                                                           m_screens[0]->root(),
                                                                           XCB_DRI2_DRIVER_TYPE_DRI);

    xcb_dri2_connect_reply_t *connect = xcb_dri2_connect_reply (m_connection,
                                                                connect_cookie, NULL);

    if (! connect || connect->driver_name_length + connect->device_name_length == 0) {
        qDebug() << "Failed to connect to dri2";
        return;
    }

    m_dri2_device_name = QByteArray(xcb_dri2_connect_device_name (connect),
                                                    xcb_dri2_connect_device_name_length (connect));
    delete connect;

    int fd = open(m_dri2_device_name.constData(), O_RDWR);
    if (fd < 0) {
        qDebug() << "InitializeDri2: Could'nt open device << dri2DeviceName";
        m_dri2_device_name = QByteArray();
        return;
    }

    drm_magic_t magic;
    if (drmGetMagic(fd, &magic)) {
        qDebug() << "Failed to get drmMagic";
        return;
    }

    xcb_dri2_authenticate_cookie_t authenticate_cookie = xcb_dri2_authenticate_unchecked(m_connection,
                                                                                         m_screens[0]->root(), magic);
    xcb_dri2_authenticate_reply_t *authenticate = xcb_dri2_authenticate_reply(m_connection,
                                                                              authenticate_cookie, NULL);
    if (authenticate == NULL || !authenticate->authenticated) {
        fprintf(stderr, "DRI2: failed to authenticate\n");
        free(authenticate);
        return;
    }

    delete authenticate;

    EGLDisplay display = eglGetDRMDisplayMESA(fd);
    if (!display) {
        fprintf(stderr, "failed to create display\n");
        return;
    }

    m_egl_display = display;
    EGLint major,minor;
    if (!eglInitialize(display, &major, &minor)) {
        fprintf(stderr, "failed to initialize display\n");
        return;
    }
}
Esempio n. 6
0
static int
init_drm(struct display *d)
{
	EGLint major, minor;
	int fd;
	drm_magic_t magic;

	fd = open(d->device_name, O_RDWR);
	if (fd < 0) {
		fprintf(stderr, "drm open failed: %m\n");
		return -1;
	}

	if (drmGetMagic(fd, &magic)) {
		fprintf(stderr, "DRI2: failed to get drm magic");
		return -1;
	}

	/* Wait for authenticated event */
	wl_drm_authenticate(d->drm, magic);
	wl_display_iterate(d->display, WL_DISPLAY_WRITABLE);
	while (!d->authenticated)
		wl_display_iterate(d->display, WL_DISPLAY_READABLE);

	d->dpy = eglGetDRMDisplayMESA(fd);
	if (!eglInitialize(d->dpy, &major, &minor)) {
		fprintf(stderr, "failed to initialize display\n");
		return -1;
	}

	if (!eglBindAPI(EGL_OPENGL_API)) {
		fprintf(stderr, "failed to bind api EGL_OPENGL_API\n");
		return -1;
	}

	d->ctx = eglCreateContext(d->dpy, NULL, EGL_NO_CONTEXT, NULL);
	if (d->ctx == NULL) {
		fprintf(stderr, "failed to create context\n");
		return -1;
	}

	if (!eglMakeCurrent(d->dpy, NULL, NULL, d->ctx)) {
		fprintf(stderr, "faile to make context current\n");
		return -1;
	}

#ifdef HAVE_CAIRO_EGL
	d->device = cairo_egl_device_create(d->dpy, d->ctx);
	if (d->device == NULL) {
		fprintf(stderr, "failed to get cairo drm device\n");
		return -1;
	}
#endif

	return 0;
}
Esempio n. 7
0
static void
pipe_loader_drm_x_auth(int fd)
{
#ifdef HAVE_PIPE_LOADER_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;
   int screen;

   xcb_conn = xcb_connect(NULL, &screen);

   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,
                                               get_xcb_screen(s, screen)->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
}
Esempio n. 8
0
static int dri2_connect(Display *dpy, char **driver)
{
	int eventBase, errorBase, major, minor;
	char *device;
	drm_magic_t magic;
	Window root;
	int fd;

	if (!DRI2InitDisplay(dpy, &ops)) {
		ERROR_MSG("DRI2InitDisplay failed");
		return -1;
	}

	if (!DRI2QueryExtension(dpy, &eventBase, &errorBase)) {
		ERROR_MSG("DRI2QueryExtension failed");
		return -1;
	}

	MSG("DRI2QueryExtension: eventBase=%d, errorBase=%d", eventBase, errorBase);

	if (!DRI2QueryVersion(dpy, &major, &minor)) {
		ERROR_MSG("DRI2QueryVersion failed");
		return -1;
	}

	MSG("DRI2QueryVersion: major=%d, minor=%d", major, minor);

	root = RootWindow(dpy, DefaultScreen(dpy));

	if (!DRI2Connect(dpy, root, driver, &device)) {
		ERROR_MSG("DRI2Connect failed");
		return -1;
	}

	MSG("DRI2Connect: driver=%s, device=%s", *driver, device);

	fd = open(device, O_RDWR);
	if (fd < 0) {
		ERROR_MSG("open failed");
		return fd;
	}

	if (drmGetMagic(fd, &magic)) {
		ERROR_MSG("drmGetMagic failed");
		return -1;
	}

	if (!DRI2Authenticate(dpy, root, magic)) {
		ERROR_MSG("DRI2Authenticate failed");
		return -1;
	}

	return fd;
}
Esempio n. 9
0
/**
 * Enable DRI2 and returns the file descriptor of the DRM device.  The file
 * descriptor will be closed automatically when the screen is destoryed.
 */
int
x11_screen_enable_dri2(struct x11_screen *xscr,
                       x11_drawable_invalidate_buffers invalidate_buffers,
                       void *user_data)
{
   if (xscr->dri_fd < 0) {
      int fd;
      drm_magic_t magic;

      /* get the driver name and the device name first */
      if (!x11_screen_probe_dri2(xscr, NULL, NULL))
         return -1;

      fd = open(xscr->dri_device, O_RDWR);
      if (fd < 0) {
         _eglLog(_EGL_WARNING, "failed to open %s", xscr->dri_device);
         return -1;
      }

      memset(&magic, 0, sizeof(magic));
      if (drmGetMagic(fd, &magic)) {
         _eglLog(_EGL_WARNING, "failed to get magic");
         close(fd);
         return -1;
      }

      if (!DRI2Authenticate(xscr->dpy,
               RootWindow(xscr->dpy, xscr->number), magic)) {
         _eglLog(_EGL_WARNING, "failed to authenticate magic");
         close(fd);
         return -1;
      }

      if (!x11_screen_init_glx(xscr)) {
         _eglLog(_EGL_WARNING, "failed to initialize GLX");
         close(fd);
         return -1;
      }
      if (xscr->glx_dpy->xscr) {
         _eglLog(_EGL_WARNING,
               "display is already managed by another x11 screen");
         close(fd);
         return -1;
      }

      xscr->glx_dpy->xscr = xscr;
      xscr->dri_invalidate_buffers = invalidate_buffers;
      xscr->dri_user_data = user_data;

      xscr->dri_fd = fd;
   }

   return xscr->dri_fd;
}
Esempio n. 10
0
static EGLBoolean
dri2_x11_local_authenticate(struct dri2_egl_display *dri2_dpy)
{
#ifdef HAVE_LIBDRM
   drm_magic_t magic;

   if (drmGetMagic(dri2_dpy->fd, &magic)) {
      _eglLog(_EGL_WARNING, "DRI2: failed to get drm magic");
      return EGL_FALSE;
   }

   if (dri2_x11_do_authenticate(dri2_dpy, magic) < 0) {
      _eglLog(_EGL_WARNING, "DRI2: failed to authenticate");
      return EGL_FALSE;
   }
#endif
   return EGL_TRUE;
}
Esempio n. 11
0
static EGLBoolean
dri2_authenticate(_EGLDisplay *disp)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   drm_magic_t magic;

   if (drmGetMagic(dri2_dpy->fd, &magic)) {
      _eglLog(_EGL_WARNING, "DRI2: failed to get drm magic");
      return EGL_FALSE;
   }
   
   if (dri2_x11_authenticate(disp, magic) < 0) {
      _eglLog(_EGL_WARNING, "DRI2: failed to authenticate");
      return EGL_FALSE;
   }

   return EGL_TRUE;
}
Esempio n. 12
0
static int
xwl_dri3_open_client(ClientPtr client,
                     ScreenPtr screen,
                     RRProviderPtr provider,
                     int *pfd)
{
    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
    struct xwl_auth_state *state;
    struct wl_callback *callback;
    drm_magic_t magic;
    int fd;

    fd = open(xwl_screen->device_name, O_RDWR | O_CLOEXEC);
    if (fd < 0)
        return BadAlloc;
    if (xwl_screen->fd_render_node) {
        *pfd = fd;
        return Success;
    }

    state = malloc(sizeof *state);
    if (state == NULL) {
        close(fd);
        return BadAlloc;
    }

    state->client = client;
    state->fd = fd;

    if (drmGetMagic(state->fd, &magic) < 0) {
        close(state->fd);
        free(state);
        return BadMatch;
    }

    wl_drm_authenticate(xwl_screen->drm, magic);
    callback = wl_display_sync(xwl_screen->display);
    wl_callback_add_listener(callback, &sync_listener, state);

    IgnoreClient(client);

    return Success;
}
Esempio n. 13
0
static void
drm_handle_device(void *data, struct wl_drm *drm, const char *device)
{
   struct wayland_drm_display *drmdpy = data;
   drm_magic_t magic;

   drmdpy->device_name = strdup(device);
   if (!drmdpy->device_name)
      return;

   drmdpy->fd = open(drmdpy->device_name, O_RDWR);
   if (drmdpy->fd == -1) {
      _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
              drmdpy->device_name, strerror(errno));
      return;
   }

   drmGetMagic(drmdpy->fd, &magic);
   wl_drm_authenticate(drmdpy->wl_drm, magic);
}
Esempio n. 14
0
Bool 
isDRI2Connected(VADriverContextP ctx, char **driver_name)
{
    struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
    int major, minor;
    int error_base;
    int event_base;
    char *device_name = NULL;
    drm_magic_t magic;        
    *driver_name = NULL;
    dri_state->base.fd = -1;
    dri_state->base.auth_type = VA_NONE;
    if (!VA_DRI2QueryExtension(ctx->native_dpy, &event_base, &error_base))
        goto err_out;

    if (!VA_DRI2QueryVersion(ctx->native_dpy, &major, &minor))
        goto err_out;


    if (!VA_DRI2Connect(ctx->native_dpy, RootWindow(ctx->native_dpy, ctx->x11_screen),
                     driver_name, &device_name) || !device_name)
        goto err_out;

    dri_state->base.fd = open(device_name, O_RDWR);
    assert(dri_state->base.fd >= 0);

    if (dri_state->base.fd < 0)
        goto err_out;

    if (drmGetMagic(dri_state->base.fd, &magic))
        goto err_out;

    if (!VA_DRI2Authenticate(ctx->native_dpy, RootWindow(ctx->native_dpy, ctx->x11_screen),
                          magic))
        goto err_out;

    dri_state->base.auth_type = VA_DRI2;
    dri_state->createDrawable = dri2CreateDrawable;
    dri_state->destroyDrawable = dri2DestroyDrawable;
    dri_state->swapBuffer = dri2SwapBuffer;
    dri_state->getRenderingBuffer = dri2GetRenderingBuffer;
    dri_state->close = dri2Close;
    gsDRI2SwapAvailable = (minor >= 2);

    Xfree(device_name);

    return True;

err_out:
    if (device_name)
        Xfree(device_name);

    if (*driver_name)
        Xfree(*driver_name);

    if (dri_state->base.fd >= 0)
        close(dri_state->base.fd);

    *driver_name = NULL;
    dri_state->base.fd = -1;
    
    return False;
}
static struct pipe_screen *
radeon_hardpipe_screen_create(void)
{
   Display *dpy;
   Window rootWin;
   XWindowAttributes winAttr;
   int isCapable;
   int screen;
   char *driverName;
   char *curBusID;
   unsigned magic;
   int ddxDriverMajor;
   int ddxDriverMinor;
   int ddxDriverPatch;
   drm_handle_t sAreaOffset;
   int ret;
   int drmFD;
   drm_context_t hHWContext;
   XID id;

   dpy = XOpenDisplay(":0");
   if (!dpy) {
      fprintf(stderr, "Open Display Failed\n");
      return NULL;
   }

   screen = DefaultScreen(dpy);
   rootWin = RootWindow(dpy, screen);
   XGetWindowAttributes(dpy, rootWin, &winAttr);

   ret = uniDRIQueryDirectRenderingCapable(dpy, screen, &isCapable);
   if (!ret || !isCapable) {
      fprintf(stderr, "No DRI on this display:sceen\n");
      goto error;
   }

   if (!uniDRIOpenConnection(dpy, screen, &sAreaOffset,
                             &curBusID)) {
      fprintf(stderr, "Could not open DRI connection.\n");
      goto error;
   }

   if (!uniDRIGetClientDriverName(dpy, screen, &ddxDriverMajor,
                                  &ddxDriverMinor, &ddxDriverPatch,
                                  &driverName)) {
      fprintf(stderr, "Could not get DRI driver name.\n");
      goto error;
   }

   if ((drmFD = drmOpen(NULL, curBusID)) < 0) {
      perror("DRM Device could not be opened");
      goto error;
   }

   drmGetMagic(drmFD, &magic);
   if (!uniDRIAuthConnection(dpy, screen, magic)) {
      fprintf(stderr, "Could not get X server to authenticate us.\n");
      goto error;
   }

   if (!uniDRICreateContext(dpy, screen, winAttr.visual,
                            &id, &hHWContext)) {
      fprintf(stderr, "Could not create DRI context.\n");
      goto error;
   }

   /* FIXME: create a radeon pipe_screen from drmFD and hHWContext */

   return NULL;
   
error:
   return NULL;
}
/*
 * Get the magic for authentication.
 */
int gralloc_drm_get_magic(struct gralloc_drm_t *drm, int32_t *magic)
{
	return drmGetMagic(drm->fd, (drm_magic_t *) magic);
}
Esempio n. 17
0
Bool 
isDRI1Connected(VADriverContextP ctx, char **driver_name)
{
    struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
    int direct_capable;
    int driver_major;
    int driver_minor;
    int driver_patch;
    int newlyopened;
    char *BusID;
    drm_magic_t magic;        

    *driver_name = NULL;
    dri_state->base.fd = -1;
    dri_state->pSAREA = MAP_FAILED;
    dri_state->base.auth_type = VA_NONE;

    if (!VA_DRIQueryDirectRenderingCapable(ctx->native_dpy, 
                                           ctx->x11_screen, 
                                           &direct_capable))
        goto err_out0;

    if (!direct_capable)
        goto err_out0;

    if (!VA_DRIGetClientDriverName(ctx->native_dpy, ctx->x11_screen, 
                                   &driver_major, &driver_minor,
                                   &driver_patch, driver_name))
        goto err_out0;

    if (!VA_DRIOpenConnection(ctx->native_dpy, ctx->x11_screen, 
                              &dri_state->hSAREA, &BusID))
        goto err_out0;

    
    dri_state->base.fd = drmOpenOnce(NULL, BusID, &newlyopened);
    XFree(BusID);

    if (dri_state->base.fd < 0)
        goto err_out1;


    if (drmGetMagic(dri_state->base.fd, &magic))
        goto err_out1;

    if (newlyopened && !VA_DRIAuthConnection(ctx->native_dpy, ctx->x11_screen, magic))
        goto err_out1;

    if (drmMap(dri_state->base.fd, dri_state->hSAREA, SAREA_MAX, &dri_state->pSAREA))
        goto err_out1;

    if (!VA_DRICreateContext(ctx->native_dpy, ctx->x11_screen,
                             DefaultVisual(ctx->native_dpy, ctx->x11_screen),
                             &dri_state->hwContextID, &dri_state->hwContext))
        goto err_out1;

    dri_state->base.auth_type = VA_DRI1;
    dri_state->createDrawable = dri1CreateDrawable;
    dri_state->destroyDrawable = dri1DestroyDrawable;
    dri_state->swapBuffer = dri1SwapBuffer;
    dri_state->getRenderingBuffer = dri1GetRenderingBuffer;
    dri_state->close = dri1Close;

    return True;

err_out1:
    if (dri_state->pSAREA != MAP_FAILED)
        drmUnmap(dri_state->pSAREA, SAREA_MAX);

    if (dri_state->base.fd >= 0)
        drmCloseOnce(dri_state->base.fd);

    VA_DRICloseConnection(ctx->native_dpy, ctx->x11_screen);

err_out0:
    if (*driver_name)
        XFree(*driver_name);

    dri_state->pSAREA = MAP_FAILED;
    dri_state->base.fd = -1;
    *driver_name = NULL;
    
    return False;
}
Esempio n. 18
0
static __GLXDRIscreen *
dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
                 __GLXdisplayPrivate * priv)
{
    const __DRIconfig **driver_configs;
    const __DRIextension **extensions;
    const __GLXDRIdisplayPrivate *const pdp = (__GLXDRIdisplayPrivate *)
            priv->dri2Display;
    __GLXDRIscreen *psp;
    char *driverName, *deviceName;
    drm_magic_t magic;
    int i;

    psp = Xmalloc(sizeof *psp);
    if (psp == NULL)
        return NULL;

    if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen),
                     &driverName, &deviceName)) {
        XFree(psp);
        return NULL;
    }

    psc->driver = driOpenDriver(driverName);
    if (psc->driver == NULL) {
        ErrorMessageF("driver pointer missing\n");
        goto handle_error;
    }

    extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
    if (extensions == NULL) {
        ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
        goto handle_error;
    }

    for (i = 0; extensions[i]; i++) {
        if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
            psc->core = (__DRIcoreExtension *) extensions[i];
        if (strcmp(extensions[i]->name, __DRI_DRI2) == 0)
            psc->dri2 = (__DRIdri2Extension *) extensions[i];
    }

    if (psc->core == NULL || psc->dri2 == NULL) {
        ErrorMessageF("core dri or dri2 extension not found\n");
        goto handle_error;
    }

    psc->fd = open(deviceName, O_RDWR);
    if (psc->fd < 0) {
        ErrorMessageF("failed to open drm device: %s\n", strerror(errno));
        goto handle_error;
    }

    if (drmGetMagic(psc->fd, &magic)) {
        ErrorMessageF("failed to get magic\n");
        goto handle_error;
    }

    if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) {
        ErrorMessageF("failed to authenticate magic %d\n", magic);
        goto handle_error;
    }

    /* If the server does not support the protocol for
     * DRI2GetBuffersWithFormat, don't supply that interface to the driver.
     */
    psc->__driScreen =
        psc->dri2->createNewScreen(screen, psc->fd, ((pdp->driMinor < 1)
                                   ? loader_extensions_old
                                   : loader_extensions),
                                   &driver_configs, psc);

    if (psc->__driScreen == NULL) {
        ErrorMessageF("failed to create dri screen\n");
        goto handle_error;
    }

    driBindCommonExtensions(psc);
    dri2BindExtensions(psc);

    psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
    psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);

    psc->driver_configs = driver_configs;

    psp->destroyScreen = dri2DestroyScreen;
    psp->createContext = dri2CreateContext;
    psp->createDrawable = dri2CreateDrawable;
    psp->swapBuffers = dri2SwapBuffers;
    psp->waitGL = dri2WaitGL;
    psp->waitX = dri2WaitX;
    psp->getDrawableMSC = NULL;
    psp->waitForMSC = NULL;
    psp->waitForSBC = NULL;
    psp->setSwapInterval = NULL;
    psp->getSwapInterval = NULL;

    if (pdp->driMinor >= 2) {
#ifdef X_DRI2GetMSC
        psp->getDrawableMSC = dri2DrawableGetMSC;
#endif
#ifdef X_DRI2WaitMSC
        psp->waitForMSC = dri2WaitForMSC;
        psp->waitForSBC = dri2WaitForSBC;
#endif
#ifdef X_DRI2SwapInterval
        psp->setSwapInterval = dri2SetSwapInterval;
        psp->getSwapInterval = dri2GetSwapInterval;
#endif
#if defined(X_DRI2GetMSC) && defined(X_DRI2WaitMSC) && defined(X_DRI2SwapInterval)
        __glXEnableDirectExtension(psc, "GLX_OML_sync_control");
#endif
    }

    /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always
     * available.*/
    psp->copySubBuffer = dri2CopySubBuffer;
    __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");

    Xfree(driverName);
    Xfree(deviceName);

    return psp;

handle_error:
    Xfree(driverName);
    Xfree(deviceName);
    XFree(psp);

    /* FIXME: clean up here */

    return NULL;
}
Esempio n. 19
0
static gboolean
try_enable_drm (ClutterBackendWayland *backend_wayland, GError **error)
{
  drm_magic_t magic;
  const gchar *exts, *glexts;

  if (backend_wayland->drm_fd < 0)
    {
      g_set_error (error, CLUTTER_INIT_ERROR,
		   CLUTTER_INIT_ERROR_BACKEND,
		   "Failed to open drm device");
      return FALSE;
    }

  glexts = glGetString(GL_EXTENSIONS);
  exts = eglQueryString (backend_wayland->edpy, EGL_EXTENSIONS);

  if (!_cogl_check_extension ("EGL_KHR_image_base", exts) ||
      !_cogl_check_extension ("EGL_MESA_drm_image", exts) ||
      !_cogl_check_extension ("GL_OES_EGL_image", glexts))
    {
      g_set_error (error, CLUTTER_INIT_ERROR,
		   CLUTTER_INIT_ERROR_BACKEND,
		   "Missing EGL extensions");
      return FALSE;
    }

  backend_wayland->create_drm_image =
    (PFNEGLCREATEDRMIMAGEMESA) eglGetProcAddress ("eglCreateDRMImageMESA");
  backend_wayland->destroy_image =
    (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress ("eglDestroyImageKHR");
  backend_wayland->export_drm_image =
    (PFNEGLEXPORTDRMIMAGEMESA) eglGetProcAddress ("eglExportDRMImageMESA");
  backend_wayland->image_target_texture_2d =
    (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress ("glEGLImageTargetTexture2DOES");

  if (backend_wayland->create_drm_image == NULL ||
      backend_wayland->destroy_image == NULL ||
      backend_wayland->export_drm_image == NULL ||
      backend_wayland->image_target_texture_2d == NULL)
    {
      g_set_error (error, CLUTTER_INIT_ERROR,
		   CLUTTER_INIT_ERROR_BACKEND,
		   "Missing EGL extensions");
      return FALSE;
    }

  if (drmGetMagic (backend_wayland->drm_fd, &magic))
    {
      g_set_error (error, CLUTTER_INIT_ERROR,
		   CLUTTER_INIT_ERROR_BACKEND,
		   "Failed to get drm magic");
      return FALSE;
    }

  wl_drm_authenticate (backend_wayland->wayland_drm, magic);
  wl_display_iterate (backend_wayland->wayland_display, WL_DISPLAY_WRITABLE);
  while (!backend_wayland->authenticated)
    wl_display_iterate (backend_wayland->wayland_display, WL_DISPLAY_READABLE);

  return TRUE;
};
Esempio n. 20
0
struct vl_screen *
vl_dri2_screen_create(Display *display, int screen)
{
   struct vl_dri_screen *scrn;
   const xcb_query_extension_reply_t *extension;
   xcb_dri2_query_version_cookie_t dri2_query_cookie;
   xcb_dri2_query_version_reply_t *dri2_query = NULL;
   xcb_dri2_connect_cookie_t connect_cookie;
   xcb_dri2_connect_reply_t *connect = NULL;
   xcb_dri2_authenticate_cookie_t authenticate_cookie;
   xcb_dri2_authenticate_reply_t *authenticate = NULL;
   xcb_screen_iterator_t s;
   xcb_generic_error_t *error = NULL;
   char *device_name;
   int fd, device_name_length;
   unsigned driverType;

   drm_magic_t magic;

   assert(display);

   scrn = CALLOC_STRUCT(vl_dri_screen);
   if (!scrn)
      return NULL;

   scrn->conn = XGetXCBConnection(display);
   if (!scrn->conn)
      goto free_screen;

   xcb_prefetch_extension_data(scrn->conn, &xcb_dri2_id);

   extension = xcb_get_extension_data(scrn->conn, &xcb_dri2_id);
   if (!(extension && extension->present))
      goto free_screen;

   dri2_query_cookie = xcb_dri2_query_version (scrn->conn,
                                               XCB_DRI2_MAJOR_VERSION,
                                               XCB_DRI2_MINOR_VERSION);
   dri2_query = xcb_dri2_query_version_reply (scrn->conn, dri2_query_cookie, &error);
   if (dri2_query == NULL || error != NULL || dri2_query->minor_version < 2)
      goto free_query;

   s = xcb_setup_roots_iterator(xcb_get_setup(scrn->conn));
   scrn->base.xcb_screen = get_xcb_screen(s, screen);
   if (!scrn->base.xcb_screen)
      goto free_query;

   driverType = XCB_DRI2_DRIVER_TYPE_DRI;
   {
      char *prime = getenv("DRI_PRIME");
      if (prime) {
         unsigned primeid;
         errno = 0;
         primeid = strtoul(prime, NULL, 0);
         if (errno == 0)
            driverType |=
               ((primeid & DRI2DriverPrimeMask) << DRI2DriverPrimeShift);
      }
   }

   connect_cookie = xcb_dri2_connect_unchecked(
      scrn->conn, ((xcb_screen_t *)(scrn->base.xcb_screen))->root, driverType);
   connect = xcb_dri2_connect_reply(scrn->conn, connect_cookie, NULL);
   if (connect == NULL ||
       connect->driver_name_length + connect->device_name_length == 0)
      goto free_connect;

   device_name_length = xcb_dri2_connect_device_name_length(connect);
   device_name = CALLOC(1, device_name_length + 1);
   if (!device_name)
      goto free_connect;
   memcpy(device_name, xcb_dri2_connect_device_name(connect), device_name_length);
   fd = loader_open_device(device_name);
   free(device_name);

   if (fd < 0)
      goto free_connect;

   if (drmGetMagic(fd, &magic))
      goto close_fd;

   authenticate_cookie = xcb_dri2_authenticate_unchecked(
      scrn->conn, ((xcb_screen_t *)(scrn->base.xcb_screen))->root, magic);
   authenticate = xcb_dri2_authenticate_reply(scrn->conn, authenticate_cookie, NULL);

   if (authenticate == NULL || !authenticate->authenticated)
      goto free_authenticate;

   if (pipe_loader_drm_probe_fd(&scrn->base.dev, fd))
      scrn->base.pscreen = pipe_loader_create_screen(scrn->base.dev);

   if (!scrn->base.pscreen)
      goto release_pipe;

   scrn->base.destroy = vl_dri2_screen_destroy;
   scrn->base.texture_from_drawable = vl_dri2_screen_texture_from_drawable;
   scrn->base.get_dirty_area = vl_dri2_screen_get_dirty_area;
   scrn->base.get_timestamp = vl_dri2_screen_get_timestamp;
   scrn->base.set_next_timestamp = vl_dri2_screen_set_next_timestamp;
   scrn->base.get_private = vl_dri2_screen_get_private;
   scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer;
   vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]);
   vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]);

   /* The pipe loader duplicates the fd */
   close(fd);
   free(authenticate);
   free(connect);
   free(dri2_query);
   free(error);

   return &scrn->base;

release_pipe:
   if (scrn->base.dev)
      pipe_loader_release(&scrn->base.dev, 1);
free_authenticate:
   free(authenticate);
close_fd:
   close(fd);
free_connect:
   free(connect);
free_query:
   free(dri2_query);
   free(error);

free_screen:
   FREE(scrn);
   return NULL;
}
LOCAL dri_state_t*
getDRI2State(Display* dpy, int screen, char **driver_name)
{
  int major, minor;
  int error_base;
  int event_base;
  char *device_name = NULL;
  drm_magic_t magic;
  char * internal_driver_name = NULL;
  int fd = -1;
  dri_state_t* state = NULL;

  if (!VA_DRI2QueryExtension(dpy, &event_base, &error_base))
    goto err_out;

  if (!VA_DRI2QueryVersion(dpy, &major, &minor))
    goto err_out;


  if (!VA_DRI2Connect(dpy, RootWindow(dpy, screen),
        &internal_driver_name, &device_name))
    goto err_out;

  fd = open(device_name, O_RDWR);

  if (fd < 0)
    goto err_out;

  if (drmGetMagic(fd, &magic))
    goto err_out;

  if (!VA_DRI2Authenticate(dpy, RootWindow(dpy, screen),
        magic))
    goto err_out;

  if(driver_name)
    *driver_name = internal_driver_name;
  else
    Xfree(internal_driver_name);

  state = dri_state_new();
  state->fd = fd;
  state->x11_dpy = dpy;
  state->x11_screen = screen;
  state->driConnectedFlag = DRI2;
  if (device_name)
    Xfree(device_name);
  return state;

err_out:
  if (device_name)
    Xfree(device_name);

  if (internal_driver_name)
    Xfree(internal_driver_name);

  if(driver_name) *driver_name = NULL;

  if (fd >= 0)
    close(fd);

  if (driver_name)
    *driver_name = NULL;

  return state;
}
Esempio n. 22
0
/**
 * Perform the required libGL-side initialization and call the client-side
 * driver's \c __driCreateNewScreen function.
 * 
 * \param dpy    Display pointer.
 * \param scrn   Screen number on the display.
 * \param psc    DRI screen information.
 * \param driDpy DRI display information.
 * \param createNewScreen  Pointer to the client-side driver's
 *               \c __driCreateNewScreen function.
 * \returns A pointer to the \c __DRIscreen structure returned by
 *          the client-side driver on success, or \c NULL on failure.
 */
static void *
CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc,
                    struct dri_display * driDpy)
{
   void *psp = NULL;
   drm_handle_t hSAREA;
   drmAddress pSAREA = MAP_FAILED;
   char *BusID;
   __DRIversion ddx_version;
   __DRIversion dri_version;
   __DRIversion drm_version;
   __DRIframebuffer framebuffer;
   int fd = -1;
   int status;

   drm_magic_t magic;
   drmVersionPtr version;
   int newlyopened;
   char *driverName;
   drm_handle_t hFB;
   int junk;
   const __DRIconfig **driver_configs;
   struct glx_config *visual, *configs = NULL, *visuals = NULL;

   /* DRI protocol version. */
   dri_version.major = driDpy->driMajor;
   dri_version.minor = driDpy->driMinor;
   dri_version.patch = driDpy->driPatch;

   framebuffer.base = MAP_FAILED;
   framebuffer.dev_priv = NULL;
   framebuffer.size = 0;

   if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
      ErrorMessageF("XF86DRIOpenConnection failed\n");
      goto handle_error;
   }

   fd = drmOpenOnce(NULL, BusID, &newlyopened);

   free(BusID);                /* No longer needed */

   if (fd < 0) {
      ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd));
      goto handle_error;
   }

   if (drmGetMagic(fd, &magic)) {
      ErrorMessageF("drmGetMagic failed\n");
      goto handle_error;
   }

   version = drmGetVersion(fd);
   if (version) {
      drm_version.major = version->version_major;
      drm_version.minor = version->version_minor;
      drm_version.patch = version->version_patchlevel;
      drmFreeVersion(version);
   }
   else {
      drm_version.major = -1;
      drm_version.minor = -1;
      drm_version.patch = -1;
   }

   if (newlyopened && !XF86DRIAuthConnection(dpy, scrn, magic)) {
      ErrorMessageF("XF86DRIAuthConnection failed\n");
      goto handle_error;
   }

   /* Get device name (like "radeon") and the ddx version numbers.
    * We'll check the version in each DRI driver's "createNewScreen"
    * function. */
   if (!XF86DRIGetClientDriverName(dpy, scrn,
                                   &ddx_version.major,
                                   &ddx_version.minor,
                                   &ddx_version.patch, &driverName)) {
      ErrorMessageF("XF86DRIGetClientDriverName failed\n");
      goto handle_error;
   }

   free(driverName);           /* No longer needed. */

   /*
    * Get device-specific info.  pDevPriv will point to a struct
    * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
    * has information about the screen size, depth, pitch, ancilliary
    * buffers, DRM mmap handles, etc.
    */
   if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, &junk,
                             &framebuffer.size, &framebuffer.stride,
                             &framebuffer.dev_priv_size,
                             &framebuffer.dev_priv)) {
      ErrorMessageF("XF86DRIGetDeviceInfo failed\n");
      goto handle_error;
   }

   framebuffer.width = DisplayWidth(dpy, scrn);
   framebuffer.height = DisplayHeight(dpy, scrn);

   /* Map the framebuffer region. */
   status = drmMap(fd, hFB, framebuffer.size,
                   (drmAddressPtr) & framebuffer.base);
   if (status != 0) {
      ErrorMessageF("drmMap of framebuffer failed (%s)\n", strerror(-status));
      goto handle_error;
   }

   /* Map the SAREA region.  Further mmap regions may be setup in
    * each DRI driver's "createNewScreen" function.
    */
   status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
   if (status != 0) {
      ErrorMessageF("drmMap of SAREA failed (%s)\n", strerror(-status));
      goto handle_error;
   }

   psp = (*psc->legacy->createNewScreen) (scrn,
                                          &ddx_version,
                                          &dri_version,
                                          &drm_version,
                                          &framebuffer,
                                          pSAREA,
                                          fd,
                                          loader_extensions,
                                          &driver_configs, psc);

   if (psp == NULL) {
      ErrorMessageF("Calling driver entry point failed\n");
      goto handle_error;
   }

   configs = driConvertConfigs(psc->core, psc->base.configs, driver_configs);
   visuals = driConvertConfigs(psc->core, psc->base.visuals, driver_configs);

   if (!configs || !visuals)
       goto handle_error;

   glx_config_destroy_list(psc->base.configs);
   psc->base.configs = configs;
   glx_config_destroy_list(psc->base.visuals);
   psc->base.visuals = visuals;

   psc->driver_configs = driver_configs;

   /* Visuals with depth != screen depth are subject to automatic compositing
    * in the X server, so DRI1 can't render to them properly. Mark them as
    * non-conformant to prevent apps from picking them up accidentally.
    */
   for (visual = psc->base.visuals; visual; visual = visual->next) {
      XVisualInfo template;
static int
dri2_connect(Display *display)
{
	xcb_dri2_query_version_cookie_t query_version_cookie;
	xcb_dri2_query_version_reply_t *query_version_reply;
	xcb_dri2_connect_cookie_t connect_cookie;
	xcb_dri2_connect_reply_t *connect_reply;
	xcb_dri2_authenticate_cookie_t auth_cookie;
	xcb_dri2_authenticate_reply_t *auth_reply;
	xcb_screen_t *root;
	xcb_connection_t *c = XGetXCBConnection(display);
	drm_magic_t magic;
	const xcb_query_extension_reply_t *dri2_reply;
	char *device_name;
	int len;

	root = xcb_aux_get_screen(c, DefaultScreen(display));

	dri2_reply = xcb_get_extension_data(c, &xcb_dri2_id);

	if (!dri2_reply) {
		XVMC_ERR("DRI2 required");
		return BadValue;
	}

	/* Query the extension and make our first use of it at the same time. */
	query_version_cookie = xcb_dri2_query_version(c, 1, 0);
	connect_cookie = xcb_dri2_connect(c, root->root, DRI2DriverDRI);

	query_version_reply =
		xcb_dri2_query_version_reply(c, query_version_cookie, NULL);
	connect_reply = xcb_dri2_connect_reply(c, connect_cookie, NULL);

	if (!query_version_reply) {
		XVMC_ERR("DRI2 required");
		return BadValue;
	}
	free(query_version_reply);

	len = xcb_dri2_connect_device_name_length(connect_reply);
	device_name = malloc(len + 1);
	if (!device_name) {
		XVMC_ERR("malloc failure");
		return BadAlloc;
	}
	strncpy(device_name, xcb_dri2_connect_device_name(connect_reply), len);
	device_name[len] = 0;
	xvmc_driver->fd = open(device_name, O_RDWR);
	free(device_name);
	free(connect_reply);
	if (xvmc_driver->fd < 0) {
		XVMC_ERR("Failed to open drm device: %s\n", strerror(errno));
		return BadValue;
	}

	if (drmGetMagic(xvmc_driver->fd, &magic)) {
		XVMC_ERR("Failed to get magic\n");
		return BadValue;
	}

	auth_cookie = xcb_dri2_authenticate(c, root->root, magic);
	auth_reply = xcb_dri2_authenticate_reply(c, auth_cookie, NULL);
	if (!auth_reply) {
		XVMC_ERR("Failed to authenticate magic %d\n", magic);
		return BadValue;
	}
	free(auth_reply);

	return Success;
}