Esempio n. 1
0
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;
}
Esempio n. 2
0
void
radeon_glamor_flush(ScrnInfoPtr pScrn)
{
	RADEONInfoPtr info = RADEONPTR(pScrn);

	if (info->use_glamor)
		glamor_block_handler(pScrn->pScreen);
}
Esempio n. 3
0
/*
 * 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
}
Esempio n. 4
0
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);
    }
}
Esempio n. 5
0
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 */
}