static Bool radeon_glamor_prepare_access_cpu(ScrnInfoPtr scrn, RADEONInfoPtr info, PixmapPtr pixmap, struct radeon_pixmap *priv, Bool need_sync) { struct radeon_bo *bo = priv->bo; int ret; /* When falling back to swrast, flush all pending operations */ if (need_sync) { glamor_block_handler(scrn->pScreen); info->gpu_flushed++; } if (!pixmap->devPrivate.ptr) { ret = radeon_bo_map(bo, 1); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: bo map (tiling_flags %d) failed: %s\n", __FUNCTION__, priv->tiling_flags, strerror(-ret)); return FALSE; } pixmap->devPrivate.ptr = bo->ptr; info->gpu_synced = info->gpu_flushed; } else if (need_sync) { radeon_bo_wait(bo); info->gpu_synced = info->gpu_flushed; } return TRUE; }
void radeon_glamor_flush(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); if (info->use_glamor) glamor_block_handler(pScrn->pScreen); }
/* * Flush our batch buffer when requested by the Present extension. */ static void ms_present_flush(WindowPtr window) { #ifdef GLAMOR ScreenPtr screen = window->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); modesettingPtr ms = modesettingPTR(scrn); if (ms->drmmode.glamor) glamor_block_handler(screen); #endif }
static void _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap) { ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); EGLImageKHR image; struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(scrn); image = dixLookupPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key); if (image != EGL_NO_IMAGE_KHR && image != NULL) { /* Before destroy an image which was attached to * a texture. we must call glFlush to make sure the * operation on that texture has been done.*/ glamor_block_handler(pixmap->drawable.pScreen); eglDestroyImageKHR(glamor_egl->display, image); dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, NULL); } }
static Bool ms_do_pageflip(ScreenPtr screen, PixmapPtr new_front, struct ms_present_vblank_event *event, int ref_crtc_vblank_pipe, Bool async) { #ifndef GLAMOR_HAS_GBM return FALSE; #else ScrnInfoPtr scrn = xf86ScreenToScrn(screen); modesettingPtr ms = modesettingPTR(scrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); drmmode_bo new_front_bo; uint32_t flags; int i; struct ms_flipdata *flipdata; glamor_block_handler(screen); new_front_bo.gbm = glamor_gbm_bo_from_pixmap(screen, new_front); new_front_bo.dumb = NULL; if (!new_front_bo.gbm) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to get GBM bo for flip to new front.\n"); return FALSE; } flipdata = calloc(1, sizeof(struct ms_flipdata)); if (!flipdata) { drmmode_bo_destroy(&ms->drmmode, &new_front_bo); xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to allocate flipdata.\n"); return FALSE; } flipdata->event = event; flipdata->screen = screen; /* * Take a local reference on flipdata. * if the first flip fails, the sequence abort * code will free the crtc flip data, and drop * it's reference which would cause this to be * freed when we still required it. */ flipdata->flip_count++; /* Create a new handle for the back buffer */ flipdata->old_fb_id = ms->drmmode.fb_id; if (drmModeAddFB(ms->fd, scrn->virtualX, scrn->virtualY, scrn->depth, scrn->bitsPerPixel, drmmode_bo_get_pitch(&new_front_bo), drmmode_bo_get_handle(&new_front_bo), &ms->drmmode.fb_id)) { goto error_out; } drmmode_bo_destroy(&ms->drmmode, &new_front_bo); flags = DRM_MODE_PAGE_FLIP_EVENT; if (async) flags |= DRM_MODE_PAGE_FLIP_ASYNC; /* Queue flips on all enabled CRTCs. * * Note that if/when we get per-CRTC buffers, we'll have to update this. * Right now it assumes a single shared fb across all CRTCs, with the * kernel fixing up the offset of each CRTC as necessary. * * Also, flips queued on disabled or incorrectly configured displays * may never complete; this is a configuration error. */ for (i = 0; i < config->num_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; if (!ms_crtc_on(crtc)) continue; if (!queue_flip_on_crtc(screen, crtc, flipdata, ref_crtc_vblank_pipe, flags)) { goto error_undo; } } /* * Do we have more than our local reference, * if so and no errors, then drop our local * reference and return now. */ if (flipdata->flip_count > 1) { flipdata->flip_count--; return TRUE; } error_undo: /* * Have we just got the local reference? * free the framebuffer if so since nobody successfully * submitted anything */ if (flipdata->flip_count == 1) { drmModeRmFB(ms->fd, ms->drmmode.fb_id); ms->drmmode.fb_id = flipdata->old_fb_id; } error_out: xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n", strerror(errno)); /* if only the local reference - free the structure, * else drop the local reference and return */ if (flipdata->flip_count == 1) free(flipdata); else flipdata->flip_count--; return FALSE; #endif /* GLAMOR_HAS_GBM */ }