Esempio n. 1
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;
Esempio n. 2
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;
}