static Bool nouveau_present_flip_exec(ScrnInfoPtr scrn, uint64_t event_id, int sync, uint64_t target_msc, PixmapPtr pixmap, Bool vsync) { ScreenPtr screen = scrn->pScreen; struct nouveau_pixmap *priv = NULL; NVPtr pNv = NVPTR(scrn); uint32_t next_fb; CARD16 stride; CARD32 size; void *token; int ret; #ifdef HAVE_GLAMOR if (pNv->AccelMethod == GLAMOR && !(priv = nouveau_glamor_pixmap_get(pixmap))) { int fd = glamor_fd_from_pixmap(screen, pixmap, &stride, &size); if (fd < 0) return FALSE; priv = calloc(1, sizeof(*priv)); if (!priv) return FALSE; ret = nouveau_bo_prime_handle_ref(pNv->dev, fd, &priv->bo); if (ret) { free(priv); return FALSE; } nouveau_glamor_pixmap_set(pixmap, priv); } else #endif if (!priv) priv = nouveau_pixmap(pixmap); ret = drmModeAddFB(pNv->dev->fd, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth, pixmap->drawable.bitsPerPixel, pixmap->devKind, priv->bo->handle, &next_fb); if (ret == 0) { struct nouveau_present_flip *flip = drmmode_event_queue(scrn, event_id, sizeof(*flip), nouveau_present_flip, &token); if (flip) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); int last = 0, i; drmmode_swap(scrn, next_fb, &flip->old); flip->fd = pNv->dev->fd; flip->msc = target_msc; for (i = 0; i < config->num_crtc; i++) { if (config->crtc[i]->enabled) last = i; } for (i = 0; i < config->num_crtc; i++) { int type = vsync ? 0 : DRM_MODE_PAGE_FLIP_ASYNC; int crtc = drmmode_crtc(config->crtc[i]); void *user = NULL; if (!config->crtc[i]->enabled) continue; if (token && ((crtc == sync) || (i == last))) { type |= DRM_MODE_PAGE_FLIP_EVENT; user = token; } ret = drmModePageFlip(pNv->dev->fd, crtc, next_fb, type, user); if (ret == 0 && user) { token = NULL; } } if (token == NULL) { return TRUE; } drmmode_swap(scrn, flip->old, &next_fb); drmmode_event_abort(scrn, event_id, false); } drmModeRmFB(pNv->dev->fd, next_fb); } return FALSE; }
/* Get GEM handle for the pixmap */ Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle) { struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap); #ifdef USE_GLAMOR ScreenPtr screen = pixmap->drawable.pScreen; RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen)); #endif if (bo) { *handle = bo->handle; return TRUE; } #ifdef USE_GLAMOR if (info->use_glamor) { struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); CARD16 stride; CARD32 size; int fd, r; if (!priv) { priv = calloc(1, sizeof(*priv)); radeon_set_pixmap_private(pixmap, priv); } if (priv->handle_valid) { *handle = priv->handle; return TRUE; } fd = glamor_fd_from_pixmap(screen, pixmap, &stride, &size); if (fd < 0) return FALSE; r = drmPrimeFDToHandle(info->dri2.drm_fd, fd, &priv->handle); close(fd); if (r == 0) { struct drm_radeon_gem_set_tiling args = { .handle = priv->handle }; priv->handle_valid = TRUE; *handle = priv->handle; if (drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_GEM_GET_TILING, &args, sizeof(args)) == 0) priv->tiling_flags = args.tiling_flags; return TRUE; } } #endif return FALSE; } uint32_t radeon_get_pixmap_tiling_flags(PixmapPtr pPix) { #ifdef USE_GLAMOR RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen)); if (info->use_glamor) { struct radeon_pixmap *priv = radeon_get_pixmap_private(pPix); if (!priv || (!priv->bo && !priv->handle_valid)) { uint32_t handle; radeon_get_pixmap_handle(pPix, &handle); priv = radeon_get_pixmap_private(pPix); } return priv ? priv->tiling_flags : 0; } else #endif { struct radeon_exa_pixmap_priv *driver_priv; driver_priv = exaGetPixmapDriverPrivate(pPix); return driver_priv ? driver_priv->tiling_flags : 0; } }