Пример #1
0
void
NV11SyncToVBlank(PixmapPtr ppix, BoxPtr box)
{
	ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
	NVPtr pNv = NVPTR(pScrn);
	struct nouveau_channel *chan = pNv->chan;
	int crtcs;

	if (!nouveau_exa_pixmap_is_onscreen(ppix))
		return;

	crtcs = nv_window_belongs_to_crtc(pScrn, box->x1, box->y1,
					  box->x2 - box->x1,
					  box->y2 - box->y1);
	if (!crtcs)
		return;

	BEGIN_NV04(chan, SUBC_BLIT(0x0000012C), 1);
	OUT_RING  (chan, 0);
	BEGIN_NV04(chan, SUBC_BLIT(0x00000134), 1);
	OUT_RING  (chan, ffs(crtcs) - 1);
	BEGIN_NV04(chan, SUBC_BLIT(0x00000100), 1);
	OUT_RING  (chan, 0);
	BEGIN_NV04(chan, SUBC_BLIT(0x00000130), 1);
	OUT_RING  (chan, 0);
}
Пример #2
0
static void
nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame,
			 unsigned int tv_sec, unsigned int tv_usec,
			 struct nouveau_dri2_vblank_state *s)
{
	ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen);
	NVPtr pNv = NVPTR(scrn);
	PixmapPtr dst_pix;
	PixmapPtr src_pix = nouveau_dri2_buffer(s->src)->ppix;
	struct nouveau_bo *dst_bo;
	struct nouveau_bo *src_bo = nouveau_pixmap_bo(src_pix);
	struct nouveau_pushbuf *push = pNv->pushbuf;
	RegionRec reg;
	int type, ret;
	Bool front_updated, will_exchange;
	xf86CrtcPtr ref_crtc;

	REGION_INIT(0, &reg, (&(BoxRec){ 0, 0, draw->width, draw->height }), 0);
	REGION_TRANSLATE(0, &reg, draw->x, draw->y);

	/* Main crtc for this drawable shall finally deliver pageflip event. */
	ref_crtc = nouveau_pick_best_crtc(scrn, FALSE, draw->x, draw->y,
                                      draw->width, draw->height);

	/* Update frontbuffer pixmap and name: Could have changed due to
	 * window (un)redirection as part of compositing.
	 */
	front_updated = update_front(draw, s->dst);

	/* Assign frontbuffer pixmap, after update in update_front() */
	dst_pix = nouveau_dri2_buffer(s->dst)->ppix;
	dst_bo = nouveau_pixmap_bo(dst_pix);

	/* Throttle on the previous frame before swapping */
	nouveau_bo_wait(dst_bo, NOUVEAU_BO_RD, push->client);

	/* Swap by buffer exchange possible? */
	will_exchange = front_updated && can_exchange(draw, dst_pix, src_pix);

	/* Only emit a wait for vblank pushbuf here if this is a copy-swap, or
	 * if it is a kms pageflip-swap on an old kernel. Pure exchange swaps
	 * don't need sync to vblank. kms pageflip-swaps on Linux 3.13+ are
	 * synced to vblank in the kms driver, so we must not sync here, or
	 * framerate will be cut in half!
	 */
	if (can_sync_to_vblank(draw) &&
		(!will_exchange ||
		(!pNv->has_async_pageflip && nouveau_exa_pixmap_is_onscreen(dst_pix)))) {
		/* Reference the back buffer to sync it to vblank */
		nouveau_pushbuf_refn(push, &(struct nouveau_pushbuf_refn) {
					   src_bo,
					   NOUVEAU_BO_VRAM | NOUVEAU_BO_RD
				     }, 1);