amdgpu_dri2.c revision 11bf0794
1/*
2 * Copyright 2008 Kristian Høgsberg
3 * Copyright 2008 Jérôme Glisse
4 *
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation on the rights to use, copy, modify, merge,
11 * publish, distribute, sublicense, and/or sell copies of the Software,
12 * and to permit persons to whom the Software is furnished to do so,
13 * subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial
17 * portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
23 * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 */
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "amdgpu_drv.h"
33#include "amdgpu_dri2.h"
34#include "amdgpu_glamor.h"
35#include "amdgpu_video.h"
36#include "amdgpu_pixmap.h"
37
38#ifdef DRI2
39
40#include <sys/ioctl.h>
41#include <sys/types.h>
42#include <sys/stat.h>
43#include <fcntl.h>
44#include <errno.h>
45
46#include <gbm.h>
47
48#include "amdgpu_bo_helper.h"
49#include "amdgpu_version.h"
50
51#include "amdgpu_list.h"
52
53#include <xf86Priv.h>
54#include <X11/extensions/dpmsconst.h>
55
56#if DRI2INFOREC_VERSION >= 9
57#define USE_DRI2_PRIME
58#endif
59
60#define FALLBACK_SWAP_DELAY 16
61
62typedef DRI2BufferPtr BufferPtr;
63
64struct dri2_buffer_priv {
65	PixmapPtr pixmap;
66	unsigned int attachment;
67	unsigned int refcnt;
68};
69
70struct dri2_window_priv {
71	xf86CrtcPtr crtc;
72	int vblank_delta;
73};
74
75static DevPrivateKeyRec dri2_window_private_key_rec;
76#define dri2_window_private_key (&dri2_window_private_key_rec)
77
78#define get_dri2_window_priv(window) \
79	((struct dri2_window_priv*) \
80	 dixLookupPrivate(&(window)->devPrivates, dri2_window_private_key))
81
82/* Get GEM flink name for a pixmap */
83static Bool
84amdgpu_get_flink_name(AMDGPUEntPtr pAMDGPUEnt, PixmapPtr pixmap, uint32_t *name)
85{
86	struct amdgpu_buffer *bo = amdgpu_get_pixmap_bo(pixmap);
87	struct drm_gem_flink flink;
88
89	if (bo && !(bo->flags & AMDGPU_BO_FLAGS_GBM) &&
90	    amdgpu_bo_export(bo->bo.amdgpu,
91			     amdgpu_bo_handle_type_gem_flink_name,
92			     name) == 0)
93		return TRUE;
94
95	if (!amdgpu_pixmap_get_handle(pixmap, &flink.handle) ||
96	    ioctl(pAMDGPUEnt->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0)
97		return FALSE;
98	*name = flink.name;
99	return TRUE;
100}
101
102static BufferPtr
103amdgpu_dri2_create_buffer2(ScreenPtr pScreen,
104			   DrawablePtr drawable,
105			   unsigned int attachment, unsigned int format)
106{
107	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
108	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
109	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
110	BufferPtr buffers;
111	struct dri2_buffer_priv *privates;
112	PixmapPtr pixmap;
113	unsigned front_width;
114	unsigned aligned_width = drawable->width;
115	unsigned height = drawable->height;
116	Bool is_glamor_pixmap = FALSE;
117	int depth;
118	int cpp;
119
120	if (format) {
121		depth = format;
122
123		switch (depth) {
124		case 15:
125			cpp = 2;
126			break;
127		case 24:
128			cpp = 4;
129			break;
130		default:
131			cpp = depth / 8;
132		}
133	} else {
134		depth = drawable->depth;
135		cpp = drawable->bitsPerPixel / 8;
136	}
137
138	front_width = pScreen->GetScreenPixmap(pScreen)->drawable.width;
139
140	pixmap = NULL;
141
142	if (attachment == DRI2BufferFrontLeft) {
143		uint32_t handle;
144
145		pixmap = get_drawable_pixmap(drawable);
146		if (pScreen != pixmap->drawable.pScreen)
147			pixmap = NULL;
148		else if (info->use_glamor && !amdgpu_pixmap_get_handle(pixmap, &handle)) {
149			is_glamor_pixmap = TRUE;
150			aligned_width = pixmap->drawable.width;
151			height = pixmap->drawable.height;
152			pixmap = NULL;
153		} else
154			pixmap->refcnt++;
155	}
156
157	if (!pixmap && (is_glamor_pixmap || attachment != DRI2BufferFrontLeft)) {
158		if (aligned_width == front_width)
159			aligned_width = pScrn->virtualX;
160
161		pixmap = (*pScreen->CreatePixmap) (pScreen,
162						   aligned_width,
163						   height,
164						   depth,
165						   AMDGPU_CREATE_PIXMAP_DRI2);
166	}
167
168	buffers = calloc(1, sizeof *buffers);
169	if (buffers == NULL)
170		goto error;
171
172	if (pixmap) {
173		if (is_glamor_pixmap) {
174			pixmap = amdgpu_glamor_set_pixmap_bo(drawable, pixmap);
175			pixmap->refcnt++;
176		}
177
178		if (!amdgpu_get_flink_name(pAMDGPUEnt, pixmap, &buffers->name))
179			goto error;
180	}
181
182	privates = calloc(1, sizeof(struct dri2_buffer_priv));
183	if (privates == NULL)
184		goto error;
185
186	buffers->attachment = attachment;
187	if (pixmap) {
188		buffers->pitch = pixmap->devKind;
189		buffers->cpp = cpp;
190	}
191	buffers->driverPrivate = privates;
192	buffers->format = format;
193	buffers->flags = 0;	/* not tiled */
194	privates->pixmap = pixmap;
195	privates->attachment = attachment;
196	privates->refcnt = 1;
197
198	return buffers;
199
200error:
201	free(buffers);
202	if (pixmap)
203		(*pScreen->DestroyPixmap) (pixmap);
204	return NULL;
205}
206
207DRI2BufferPtr
208amdgpu_dri2_create_buffer(DrawablePtr pDraw, unsigned int attachment,
209			  unsigned int format)
210{
211	return amdgpu_dri2_create_buffer2(pDraw->pScreen, pDraw,
212					  attachment, format);
213}
214
215static void
216amdgpu_dri2_destroy_buffer2(ScreenPtr pScreen,
217			    DrawablePtr drawable, BufferPtr buffers)
218{
219	if (buffers) {
220		struct dri2_buffer_priv *private = buffers->driverPrivate;
221
222		/* Trying to free an already freed buffer is unlikely to end well */
223		if (private->refcnt == 0) {
224			ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
225
226			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
227				   "Attempted to destroy previously destroyed buffer.\
228 This is a programming error\n");
229			return;
230		}
231
232		private->refcnt--;
233		if (private->refcnt == 0) {
234			if (private->pixmap)
235				(*pScreen->DestroyPixmap) (private->pixmap);
236
237			free(buffers->driverPrivate);
238			free(buffers);
239		}
240	}
241}
242
243void amdgpu_dri2_destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buf)
244{
245	amdgpu_dri2_destroy_buffer2(pDraw->pScreen, pDraw, buf);
246}
247
248static inline PixmapPtr GetDrawablePixmap(DrawablePtr drawable)
249{
250	if (drawable->type == DRAWABLE_PIXMAP)
251		return (PixmapPtr) drawable;
252	else {
253		struct _Window *pWin = (struct _Window *)drawable;
254		return drawable->pScreen->GetWindowPixmap(pWin);
255	}
256}
257
258static void
259amdgpu_dri2_copy_region2(ScreenPtr pScreen,
260			 DrawablePtr drawable,
261			 RegionPtr region,
262			 BufferPtr dest_buffer, BufferPtr src_buffer)
263{
264	struct dri2_buffer_priv *src_private = src_buffer->driverPrivate;
265	struct dri2_buffer_priv *dst_private = dest_buffer->driverPrivate;
266	DrawablePtr src_drawable;
267	DrawablePtr dst_drawable;
268	RegionPtr copy_clip;
269	GCPtr gc;
270	Bool translate = FALSE;
271	int off_x = 0, off_y = 0;
272
273	src_drawable = &src_private->pixmap->drawable;
274	dst_drawable = &dst_private->pixmap->drawable;
275
276	if (src_private->attachment == DRI2BufferFrontLeft) {
277#ifdef USE_DRI2_PRIME
278		if (drawable->pScreen != pScreen) {
279			src_drawable = DRI2UpdatePrime(drawable, src_buffer);
280			if (!src_drawable)
281				return;
282		} else
283#endif
284			src_drawable = drawable;
285	}
286	if (dst_private->attachment == DRI2BufferFrontLeft) {
287#ifdef USE_DRI2_PRIME
288		if (drawable->pScreen != pScreen) {
289			dst_drawable = DRI2UpdatePrime(drawable, dest_buffer);
290			if (!dst_drawable)
291				return;
292			if (dst_drawable != drawable)
293				translate = TRUE;
294		} else
295#endif
296			dst_drawable = drawable;
297	}
298
299	if (translate && drawable->type == DRAWABLE_WINDOW) {
300		PixmapPtr pPix = GetDrawablePixmap(drawable);
301
302		off_x = drawable->x - pPix->screen_x;
303		off_y = drawable->y - pPix->screen_y;
304	}
305	gc = GetScratchGC(dst_drawable->depth, pScreen);
306	copy_clip = REGION_CREATE(pScreen, NULL, 0);
307	REGION_COPY(pScreen, copy_clip, region);
308
309	if (translate) {
310		REGION_TRANSLATE(pScreen, copy_clip, off_x, off_y);
311	}
312
313	(*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0);
314	ValidateGC(dst_drawable, gc);
315
316	(*gc->ops->CopyArea) (src_drawable, dst_drawable, gc,
317			      0, 0, drawable->width, drawable->height, off_x,
318			      off_y);
319
320	FreeScratchGC(gc);
321}
322
323void
324amdgpu_dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
325			DRI2BufferPtr pDstBuffer, DRI2BufferPtr pSrcBuffer)
326{
327	return amdgpu_dri2_copy_region2(pDraw->pScreen, pDraw, pRegion,
328					pDstBuffer, pSrcBuffer);
329}
330
331enum DRI2FrameEventType {
332	DRI2_SWAP,
333	DRI2_FLIP,
334	DRI2_WAITMSC,
335};
336
337typedef struct _DRI2FrameEvent {
338	XID drawable_id;
339	ClientPtr client;
340	enum DRI2FrameEventType type;
341	unsigned frame;
342	xf86CrtcPtr crtc;
343	OsTimerPtr timer;
344	uintptr_t drm_queue_seq;
345
346	/* for swaps & flips only */
347	DRI2SwapEventPtr event_complete;
348	void *event_data;
349	DRI2BufferPtr front;
350	DRI2BufferPtr back;
351} DRI2FrameEventRec, *DRI2FrameEventPtr;
352
353static int DRI2InfoCnt;
354
355static void amdgpu_dri2_ref_buffer(BufferPtr buffer)
356{
357	struct dri2_buffer_priv *private = buffer->driverPrivate;
358	private->refcnt++;
359}
360
361static void amdgpu_dri2_unref_buffer(BufferPtr buffer)
362{
363	if (buffer) {
364		struct dri2_buffer_priv *private = buffer->driverPrivate;
365		amdgpu_dri2_destroy_buffer(&(private->pixmap->drawable),
366					   buffer);
367	}
368}
369
370static void
371amdgpu_dri2_client_state_changed(CallbackListPtr * ClientStateCallback,
372				 pointer data, pointer calldata)
373{
374	NewClientInfoRec *clientinfo = calldata;
375	ClientPtr pClient = clientinfo->client;
376
377	switch (pClient->clientState) {
378	case ClientStateRetained:
379	case ClientStateGone:
380		amdgpu_drm_abort_client(pClient);
381		break;
382	default:
383		break;
384	}
385}
386
387/*
388 * Get current frame count delta for the specified drawable and CRTC
389 */
390static uint32_t amdgpu_get_msc_delta(DrawablePtr pDraw, xf86CrtcPtr crtc)
391{
392	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
393
394	if (pDraw && pDraw->type == DRAWABLE_WINDOW)
395		return drmmode_crtc->interpolated_vblanks +
396			get_dri2_window_priv((WindowPtr)pDraw)->vblank_delta;
397
398	return drmmode_crtc->interpolated_vblanks;
399}
400
401/*
402 * Get current frame count and timestamp of the specified CRTC
403 */
404static Bool amdgpu_dri2_get_crtc_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc)
405{
406	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
407
408	if (!amdgpu_crtc_is_enabled(crtc) ||
409	    drmmode_crtc_get_ust_msc(crtc, ust, msc) != Success) {
410		/* CRTC is not running, extrapolate MSC and timestamp */
411		ScrnInfoPtr scrn = crtc->scrn;
412		AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
413		CARD64 now, delta_t, delta_seq;
414
415		if (!drmmode_crtc->dpms_last_ust)
416			return FALSE;
417
418		if (drmmode_get_current_ust(pAMDGPUEnt->fd, &now) != 0) {
419			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
420				   "%s cannot get current time\n", __func__);
421			return FALSE;
422		}
423
424		delta_t = now - drmmode_crtc->dpms_last_ust;
425		delta_seq = delta_t * drmmode_crtc->dpms_last_fps;
426		delta_seq /= 1000000;
427		*ust = drmmode_crtc->dpms_last_ust;
428		delta_t = delta_seq * 1000000;
429		delta_t /= drmmode_crtc->dpms_last_fps;
430		*ust += delta_t;
431		*msc = drmmode_crtc->dpms_last_seq;
432		*msc += delta_seq;
433	}
434
435	*msc += drmmode_crtc->interpolated_vblanks;
436
437	return TRUE;
438}
439
440static
441xf86CrtcPtr amdgpu_dri2_drawable_crtc(DrawablePtr pDraw, Bool consider_disabled)
442{
443	ScreenPtr pScreen = pDraw->pScreen;
444	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
445	xf86CrtcPtr crtc = amdgpu_pick_best_crtc(pScrn, consider_disabled,
446						 pDraw->x, pDraw->x + pDraw->width,
447						 pDraw->y, pDraw->y + pDraw->height);
448
449	if (crtc && pDraw->type == DRAWABLE_WINDOW) {
450		struct dri2_window_priv *priv = get_dri2_window_priv((WindowPtr)pDraw);
451
452		if (priv->crtc && priv->crtc != crtc) {
453			CARD64 ust, mscold, mscnew;
454
455			if (amdgpu_dri2_get_crtc_msc(priv->crtc, &ust, &mscold) &&
456			    amdgpu_dri2_get_crtc_msc(crtc, &ust, &mscnew))
457				priv->vblank_delta += mscold - mscnew;
458		}
459
460		priv->crtc = crtc;
461	}
462
463	return crtc;
464}
465
466static void
467amdgpu_dri2_flip_event_abort(xf86CrtcPtr crtc, void *event_data)
468{
469	if (crtc)
470		AMDGPUPTR(crtc->scrn)->drmmode.dri2_flipping = FALSE;
471
472	free(event_data);
473}
474
475static void
476amdgpu_dri2_flip_event_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
477			       void *event_data)
478{
479	DRI2FrameEventPtr flip = event_data;
480	ScrnInfoPtr scrn = crtc->scrn;
481	unsigned tv_sec, tv_usec;
482	DrawablePtr drawable;
483	ScreenPtr screen;
484	int status;
485	PixmapPtr pixmap;
486
487	status = dixLookupDrawable(&drawable, flip->drawable_id, serverClient,
488				   M_ANY, DixWriteAccess);
489	if (status != Success)
490		goto abort;
491
492	frame += amdgpu_get_msc_delta(drawable, crtc);
493
494	screen = scrn->pScreen;
495	pixmap = screen->GetScreenPixmap(screen);
496	xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
497		       "%s:%d fevent[%p] width %d pitch %d (/4 %d)\n",
498		       __func__, __LINE__, flip, pixmap->drawable.width,
499		       pixmap->devKind, pixmap->devKind / 4);
500
501	tv_sec = usec / 1000000;
502	tv_usec = usec % 1000000;
503
504	/* We assume our flips arrive in order, so we don't check the frame */
505	switch (flip->type) {
506	case DRI2_SWAP:
507		/* Check for too small vblank count of pageflip completion, taking wraparound
508		 * into account. This usually means some defective kms pageflip completion,
509		 * causing wrong (msc, ust) return values and possible visual corruption.
510		 */
511		if ((frame < flip->frame) && (flip->frame - frame < 5)) {
512			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
513				   "%s: Pageflip completion event has impossible msc %u < target_msc %u\n",
514				   __func__, frame, flip->frame);
515			/* All-Zero values signal failure of (msc, ust) timestamping to client. */
516			frame = tv_sec = tv_usec = 0;
517		}
518
519		DRI2SwapComplete(flip->client, drawable, frame, tv_sec, tv_usec,
520				 DRI2_FLIP_COMPLETE, flip->event_complete,
521				 flip->event_data);
522		break;
523	default:
524		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
525			   "%s: unknown vblank event received\n", __func__);
526		/* Unknown type */
527		break;
528	}
529
530abort:
531	amdgpu_dri2_flip_event_abort(crtc, event_data);
532}
533
534static Bool
535amdgpu_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client,
536			  DrawablePtr draw, DRI2BufferPtr front,
537			  DRI2BufferPtr back, DRI2SwapEventPtr func,
538			  void *data, unsigned int target_msc)
539{
540	ScrnInfoPtr scrn = crtc->scrn;
541	AMDGPUInfoPtr info = AMDGPUPTR(scrn);
542	struct dri2_buffer_priv *back_priv;
543	DRI2FrameEventPtr flip_info;
544	int ref_crtc_hw_id = drmmode_get_crtc_id(crtc);
545
546	flip_info = calloc(1, sizeof(DRI2FrameEventRec));
547	if (!flip_info)
548		return FALSE;
549
550	flip_info->drawable_id = draw->id;
551	flip_info->client = client;
552	flip_info->type = DRI2_SWAP;
553	flip_info->event_complete = func;
554	flip_info->event_data = data;
555	flip_info->frame = target_msc;
556	flip_info->crtc = crtc;
557
558	xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
559		       "%s:%d fevent[%p]\n", __func__, __LINE__, flip_info);
560
561	/* Page flip the full screen buffer */
562	back_priv = back->driverPrivate;
563	if (amdgpu_do_pageflip(scrn, client, back_priv->pixmap,
564			       AMDGPU_DRM_QUEUE_ID_DEFAULT, flip_info,
565			       ref_crtc_hw_id,
566			       amdgpu_dri2_flip_event_handler,
567			       amdgpu_dri2_flip_event_abort, FLIP_VSYNC,
568			       target_msc - amdgpu_get_msc_delta(draw, crtc))) {
569		info->drmmode.dri2_flipping = TRUE;
570		return TRUE;
571	}
572	return FALSE;
573}
574
575static Bool update_front(DrawablePtr draw, DRI2BufferPtr front)
576{
577	ScreenPtr screen = draw->pScreen;
578	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
579	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
580	PixmapPtr pixmap = get_drawable_pixmap(draw);
581	struct dri2_buffer_priv *priv = front->driverPrivate;
582
583	if (!amdgpu_get_flink_name(pAMDGPUEnt, pixmap, &front->name))
584		return FALSE;
585
586	(*draw->pScreen->DestroyPixmap) (priv->pixmap);
587	front->pitch = pixmap->devKind;
588	front->cpp = pixmap->drawable.bitsPerPixel / 8;
589	priv->pixmap = pixmap;
590	pixmap->refcnt++;
591
592	return TRUE;
593}
594
595static Bool
596can_exchange(ScrnInfoPtr pScrn, DrawablePtr draw,
597	     DRI2BufferPtr front, DRI2BufferPtr back)
598{
599	struct dri2_buffer_priv *front_priv = front->driverPrivate;
600	struct dri2_buffer_priv *back_priv = back->driverPrivate;
601	PixmapPtr front_pixmap;
602	PixmapPtr back_pixmap = back_priv->pixmap;
603	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
604	int i;
605
606	for (i = 0; i < xf86_config->num_crtc; i++) {
607		xf86CrtcPtr crtc = xf86_config->crtc[i];
608		drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
609
610		if (crtc->enabled &&
611		    (crtc->rotatedData || drmmode_crtc->scanout[0].bo))
612			return FALSE;
613	}
614
615	if (!update_front(draw, front))
616		return FALSE;
617
618	front_pixmap = front_priv->pixmap;
619
620	if (front_pixmap->drawable.width != back_pixmap->drawable.width)
621		return FALSE;
622
623	if (front_pixmap->drawable.height != back_pixmap->drawable.height)
624		return FALSE;
625
626	if (front_pixmap->drawable.bitsPerPixel !=
627	    back_pixmap->drawable.bitsPerPixel)
628		return FALSE;
629
630	if (front_pixmap->devKind != back_pixmap->devKind)
631		return FALSE;
632
633	return TRUE;
634}
635
636static Bool
637can_flip(ScrnInfoPtr pScrn, DrawablePtr draw,
638	 DRI2BufferPtr front, DRI2BufferPtr back)
639{
640	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
641	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
642	int num_crtcs_on;
643	int i;
644
645	if (draw->type != DRAWABLE_WINDOW ||
646	    !info->allowPageFlip ||
647	    info->hwcursor_disabled ||
648	    info->drmmode.present_flipping ||
649	    !pScrn->vtSema ||
650	    !DRI2CanFlip(draw))
651		return FALSE;
652
653	for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) {
654		xf86CrtcPtr crtc = config->crtc[i];
655		drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
656
657		if (!crtc->enabled)
658			continue;
659
660		if (!drmmode_crtc || drmmode_crtc->rotate.bo ||
661			drmmode_crtc->scanout[0].bo)
662			return FALSE;
663
664		if (drmmode_crtc->pending_dpms_mode == DPMSModeOn)
665			num_crtcs_on++;
666	}
667
668	return num_crtcs_on > 0 && can_exchange(pScrn, draw, front, back);
669}
670
671static void
672amdgpu_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front,
673			     DRI2BufferPtr back)
674{
675	struct dri2_buffer_priv *front_priv = front->driverPrivate;
676	struct dri2_buffer_priv *back_priv = back->driverPrivate;
677	struct amdgpu_pixmap *front_pix;
678	struct amdgpu_pixmap *back_pix;
679	ScreenPtr screen;
680	AMDGPUInfoPtr info;
681	RegionRec region;
682	int tmp;
683
684	region.extents.x1 = region.extents.y1 = 0;
685	region.extents.x2 = front_priv->pixmap->drawable.width;
686	region.extents.y2 = front_priv->pixmap->drawable.height;
687	region.data = NULL;
688	DamageRegionAppend(&front_priv->pixmap->drawable, &region);
689
690	/* Swap BO names so DRI works */
691	tmp = front->name;
692	front->name = back->name;
693	back->name = tmp;
694
695	/* Swap pixmap privates */
696	front_pix = amdgpu_get_pixmap_private(front_priv->pixmap);
697	back_pix = amdgpu_get_pixmap_private(back_priv->pixmap);
698	amdgpu_set_pixmap_private(front_priv->pixmap, back_pix);
699	amdgpu_set_pixmap_private(back_priv->pixmap, front_pix);
700
701	/* Do we need to update the Screen? */
702	screen = draw->pScreen;
703	info = AMDGPUPTR(xf86ScreenToScrn(screen));
704	if (front_pix->bo == info->front_buffer) {
705		struct amdgpu_pixmap *screen_priv =
706			amdgpu_get_pixmap_private(screen->GetScreenPixmap(screen));
707
708		amdgpu_bo_ref(back_pix->bo);
709		amdgpu_bo_unref(&info->front_buffer);
710		info->front_buffer = back_pix->bo;
711		*screen_priv = *back_pix;
712	}
713
714	amdgpu_glamor_exchange_buffers(front_priv->pixmap, back_priv->pixmap);
715
716	DamageRegionProcessPending(&front_priv->pixmap->drawable);
717}
718
719static void amdgpu_dri2_frame_event_abort(xf86CrtcPtr crtc, void *event_data)
720{
721	DRI2FrameEventPtr event = event_data;
722
723	TimerCancel(event->timer);
724	TimerFree(event->timer);
725	amdgpu_dri2_unref_buffer(event->front);
726	amdgpu_dri2_unref_buffer(event->back);
727	free(event);
728}
729
730static void amdgpu_dri2_frame_event_handler(xf86CrtcPtr crtc, uint32_t seq,
731					    uint64_t usec, void *event_data)
732{
733	DRI2FrameEventPtr event = event_data;
734	ScrnInfoPtr scrn = crtc->scrn;
735	DrawablePtr drawable;
736	int status;
737	int swap_type;
738	BoxRec box;
739	RegionRec region;
740
741	status = dixLookupDrawable(&drawable, event->drawable_id, serverClient,
742				   M_ANY, DixWriteAccess);
743	if (status != Success)
744		goto cleanup;
745
746	seq += amdgpu_get_msc_delta(drawable, crtc);
747
748	switch (event->type) {
749	case DRI2_FLIP:
750		if (can_flip(scrn, drawable, event->front, event->back) &&
751		    amdgpu_dri2_schedule_flip(crtc,
752					      event->client,
753					      drawable,
754					      event->front,
755					      event->back,
756					      event->event_complete,
757					      event->event_data,
758					      event->frame)) {
759			amdgpu_dri2_exchange_buffers(drawable, event->front,
760						     event->back);
761			break;
762		}
763		/* else fall through to exchange/blit */
764	case DRI2_SWAP:
765		if (DRI2CanExchange(drawable) &&
766		    can_exchange(scrn, drawable, event->front, event->back)) {
767			amdgpu_dri2_exchange_buffers(drawable, event->front,
768						     event->back);
769			swap_type = DRI2_EXCHANGE_COMPLETE;
770		} else {
771			box.x1 = 0;
772			box.y1 = 0;
773			box.x2 = drawable->width;
774			box.y2 = drawable->height;
775			REGION_INIT(pScreen, &region, &box, 0);
776			amdgpu_dri2_copy_region(drawable, &region, event->front,
777						event->back);
778			swap_type = DRI2_BLIT_COMPLETE;
779		}
780
781		DRI2SwapComplete(event->client, drawable, seq, usec / 1000000,
782				 usec % 1000000, swap_type, event->event_complete,
783				 event->event_data);
784
785		break;
786	case DRI2_WAITMSC:
787		DRI2WaitMSCComplete(event->client, drawable, seq, usec / 1000000,
788				    usec % 1000000);
789		break;
790	default:
791		/* Unknown type */
792		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
793			   "%s: unknown vblank event received\n", __func__);
794		break;
795	}
796
797cleanup:
798	amdgpu_dri2_frame_event_abort(crtc, event_data);
799}
800
801drmVBlankSeqType amdgpu_populate_vbl_request_type(xf86CrtcPtr crtc)
802{
803	drmVBlankSeqType type = 0;
804	int crtc_id = drmmode_get_crtc_id(crtc);
805
806	if (crtc_id == 1)
807		type |= DRM_VBLANK_SECONDARY;
808	else if (crtc_id > 1)
809		type |= (crtc_id << DRM_VBLANK_HIGH_CRTC_SHIFT) &
810		    DRM_VBLANK_HIGH_CRTC_MASK;
811
812	return type;
813}
814
815/*
816 * This function should be called on a disabled CRTC only (i.e., CRTC
817 * in DPMS-off state). It will calculate the delay necessary to reach
818 * target_msc from present time if the CRTC were running.
819 */
820static
821CARD32 amdgpu_dri2_extrapolate_msc_delay(xf86CrtcPtr crtc, CARD64 * target_msc,
822					 CARD64 divisor, CARD64 remainder)
823{
824	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
825	ScrnInfoPtr pScrn = crtc->scrn;
826	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
827	int nominal_frame_rate = drmmode_crtc->dpms_last_fps;
828	CARD64 last_vblank_ust = drmmode_crtc->dpms_last_ust;
829	uint32_t last_vblank_seq = drmmode_crtc->dpms_last_seq;
830	CARD64 now, target_time, delta_t;
831	int64_t d, delta_seq;
832	int ret;
833	CARD32 d_ms;
834
835	if (!last_vblank_ust) {
836		*target_msc = 0;
837		return FALLBACK_SWAP_DELAY;
838	}
839	ret = drmmode_get_current_ust(pAMDGPUEnt->fd, &now);
840	if (ret) {
841		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
842			   "%s cannot get current time\n", __func__);
843		*target_msc = 0;
844		return FALLBACK_SWAP_DELAY;
845	}
846	delta_seq = *target_msc - last_vblank_seq;
847	delta_seq *= 1000000;
848	target_time = last_vblank_ust;
849	target_time += delta_seq / nominal_frame_rate;
850	d = target_time - now;
851	if (d < 0) {
852		/* we missed the event, adjust target_msc, do the divisor magic */
853		CARD64 current_msc = last_vblank_seq;
854
855		delta_t = now - last_vblank_ust;
856		delta_seq = delta_t * nominal_frame_rate;
857		current_msc += delta_seq / 1000000;
858		current_msc &= 0xffffffff;
859		if (divisor == 0) {
860			*target_msc = current_msc;
861			d = 0;
862		} else {
863			*target_msc =
864			    current_msc - (current_msc % divisor) + remainder;
865			if ((current_msc % divisor) >= remainder)
866				*target_msc += divisor;
867			*target_msc &= 0xffffffff;
868			delta_seq = *target_msc - last_vblank_seq;
869			delta_seq *= 1000000;
870			target_time = last_vblank_ust;
871			target_time += delta_seq / nominal_frame_rate;
872			d = target_time - now;
873		}
874	}
875	/*
876	 * convert delay to milliseconds and add margin to prevent the client
877	 * from coming back early (due to timer granularity and rounding
878	 * errors) and getting the same MSC it just got
879	 */
880	d_ms = (CARD32) d / 1000;
881	if ((CARD32) d - d_ms * 1000 > 0)
882		d_ms += 2;
883	else
884		d_ms++;
885	return d_ms;
886}
887
888/*
889 * Get current interpolated frame count and frame count timestamp, based on
890 * drawable's crtc.
891 */
892static int amdgpu_dri2_get_msc(DrawablePtr draw, CARD64 * ust, CARD64 * msc)
893{
894	xf86CrtcPtr crtc = amdgpu_dri2_drawable_crtc(draw, TRUE);
895
896	/* Drawable not displayed, make up a value */
897	if (crtc == NULL) {
898		*ust = 0;
899		*msc = 0;
900		return TRUE;
901	}
902
903	if (!amdgpu_dri2_get_crtc_msc(crtc, ust, msc))
904		return FALSE;
905
906	if (draw && draw->type == DRAWABLE_WINDOW)
907		*msc += get_dri2_window_priv((WindowPtr)draw)->vblank_delta;
908	*msc &= 0xffffffff;
909	return TRUE;
910}
911
912static
913CARD32 amdgpu_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
914{
915	DRI2FrameEventPtr event_info = (DRI2FrameEventPtr) data;
916	xf86CrtcPtr crtc = event_info->crtc;
917	ScrnInfoPtr scrn;
918	AMDGPUEntPtr pAMDGPUEnt;
919	CARD64 drm_now;
920	int ret;
921	CARD64 delta_t, delta_seq, frame;
922	drmmode_crtc_private_ptr drmmode_crtc;
923
924	/*
925	 * This is emulated event, so its time is current time, which we
926	 * have to get in DRM-compatible form (which is a bit messy given
927	 * the information that we have at this point). Can't use now argument
928	 * because DRM event time may come from monotonic clock, while
929	 * DIX timer facility uses real-time clock.
930	 */
931	if (!event_info->crtc) {
932		ErrorF("%s no crtc\n", __func__);
933		if (event_info->drm_queue_seq)
934			amdgpu_drm_abort_entry(event_info->drm_queue_seq);
935		else
936			amdgpu_dri2_frame_event_abort(NULL, data);
937		return 0;
938	}
939
940	scrn = crtc->scrn;
941	pAMDGPUEnt = AMDGPUEntPriv(scrn);
942	ret = drmmode_get_current_ust(pAMDGPUEnt->fd, &drm_now);
943	if (ret) {
944		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
945			   "%s cannot get current time\n", __func__);
946		if (event_info->drm_queue_seq)
947			amdgpu_drm_queue_handler(pAMDGPUEnt->fd, 0, 0, 0,
948						 (void*)event_info->drm_queue_seq);
949		else
950			amdgpu_dri2_frame_event_handler(crtc, 0, 0, data);
951		return 0;
952	}
953	/*
954	 * calculate the frame number from current time
955	 * that would come from CRTC if it were running
956	 */
957	drmmode_crtc = event_info->crtc->driver_private;
958	delta_t = drm_now - (CARD64) drmmode_crtc->dpms_last_ust;
959	delta_seq = delta_t * drmmode_crtc->dpms_last_fps;
960	delta_seq /= 1000000;
961	frame = (CARD64) drmmode_crtc->dpms_last_seq + delta_seq;
962	if (event_info->drm_queue_seq)
963		amdgpu_drm_queue_handler(pAMDGPUEnt->fd, frame, drm_now / 1000000,
964					 drm_now % 1000000,
965					 (void*)event_info->drm_queue_seq);
966	else
967		amdgpu_dri2_frame_event_handler(crtc, frame, drm_now, data);
968	return 0;
969}
970
971static
972void amdgpu_dri2_schedule_event(CARD32 delay, DRI2FrameEventPtr event_info)
973{
974	event_info->timer = TimerSet(NULL, 0, delay, amdgpu_dri2_deferred_event,
975				     event_info);
976	if (delay == 0) {
977		CARD32 now = GetTimeInMillis();
978		amdgpu_dri2_deferred_event(event_info->timer, now, event_info);
979	}
980}
981
982/*
983 * Request a DRM event when the requested conditions will be satisfied.
984 *
985 * We need to handle the event and ask the server to wake up the client when
986 * we receive it.
987 */
988static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
989					 CARD64 target_msc, CARD64 divisor,
990					 CARD64 remainder)
991{
992	ScreenPtr screen = draw->pScreen;
993	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
994	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
995	DRI2FrameEventPtr wait_info = NULL;
996	uintptr_t drm_queue_seq = 0;
997	xf86CrtcPtr crtc = amdgpu_dri2_drawable_crtc(draw, TRUE);
998	uint32_t msc_delta;
999	drmVBlank vbl;
1000	int ret;
1001	CARD64 current_msc;
1002
1003	/* Truncate to match kernel interfaces; means occasional overflow
1004	 * misses, but that's generally not a big deal */
1005	target_msc &= 0xffffffff;
1006	divisor &= 0xffffffff;
1007	remainder &= 0xffffffff;
1008
1009	/* Drawable not visible, return immediately */
1010	if (crtc == NULL)
1011		goto out_complete;
1012
1013	msc_delta = amdgpu_get_msc_delta(draw, crtc);
1014
1015	wait_info = calloc(1, sizeof(DRI2FrameEventRec));
1016	if (!wait_info)
1017		goto out_complete;
1018
1019	wait_info->drawable_id = draw->id;
1020	wait_info->client = client;
1021	wait_info->type = DRI2_WAITMSC;
1022	wait_info->crtc = crtc;
1023
1024	/*
1025	 * CRTC is in DPMS off state, calculate wait time from current time,
1026	 * target_msc and last vblank time/sequence when CRTC was turned off
1027	 */
1028	if (!amdgpu_crtc_is_enabled(crtc)) {
1029		CARD32 delay;
1030		target_msc -= msc_delta;
1031		delay = amdgpu_dri2_extrapolate_msc_delay(crtc, &target_msc,
1032							  divisor, remainder);
1033		amdgpu_dri2_schedule_event(delay, wait_info);
1034		DRI2BlockClient(client, draw);
1035		return TRUE;
1036	}
1037
1038	/* Get current count */
1039	vbl.request.type = DRM_VBLANK_RELATIVE;
1040	vbl.request.type |= amdgpu_populate_vbl_request_type(crtc);
1041	vbl.request.sequence = 0;
1042	ret = drmWaitVBlank(pAMDGPUEnt->fd, &vbl);
1043	if (ret) {
1044		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
1045			   "get vblank counter failed: %s\n", strerror(errno));
1046		goto out_complete;
1047	}
1048
1049	current_msc = vbl.reply.sequence + msc_delta;
1050	current_msc &= 0xffffffff;
1051
1052	drm_queue_seq = amdgpu_drm_queue_alloc(crtc, client, AMDGPU_DRM_QUEUE_ID_DEFAULT,
1053					       wait_info, amdgpu_dri2_frame_event_handler,
1054					       amdgpu_dri2_frame_event_abort);
1055	if (drm_queue_seq == AMDGPU_DRM_QUEUE_ERROR) {
1056		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
1057			   "Allocating DRM queue event entry failed.\n");
1058		goto out_complete;
1059	}
1060	wait_info->drm_queue_seq = drm_queue_seq;
1061
1062	/*
1063	 * If divisor is zero, or current_msc is smaller than target_msc,
1064	 * we just need to make sure target_msc passes  before waking up the
1065	 * client.
1066	 */
1067	if (divisor == 0 || current_msc < target_msc) {
1068		/* If target_msc already reached or passed, set it to
1069		 * current_msc to ensure we return a reasonable value back
1070		 * to the caller. This keeps the client from continually
1071		 * sending us MSC targets from the past by forcibly updating
1072		 * their count on this call.
1073		 */
1074		if (current_msc >= target_msc)
1075			target_msc = current_msc;
1076		vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
1077		vbl.request.type |= amdgpu_populate_vbl_request_type(crtc);
1078		vbl.request.sequence = target_msc - msc_delta;
1079		vbl.request.signal = drm_queue_seq;
1080		ret = drmWaitVBlank(pAMDGPUEnt->fd, &vbl);
1081		if (ret) {
1082			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
1083				   "get vblank counter failed: %s\n",
1084				   strerror(errno));
1085			goto out_complete;
1086		}
1087
1088		DRI2BlockClient(client, draw);
1089		return TRUE;
1090	}
1091
1092	/*
1093	 * If we get here, target_msc has already passed or we don't have one,
1094	 * so we queue an event that will satisfy the divisor/remainder equation.
1095	 */
1096	vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
1097	vbl.request.type |= amdgpu_populate_vbl_request_type(crtc);
1098
1099	vbl.request.sequence = current_msc - (current_msc % divisor) +
1100	    remainder - msc_delta;
1101
1102	/*
1103	 * If calculated remainder is larger than requested remainder,
1104	 * it means we've passed the last point where
1105	 * seq % divisor == remainder, so we need to wait for the next time
1106	 * that will happen.
1107	 */
1108	if ((current_msc % divisor) >= remainder)
1109		vbl.request.sequence += divisor;
1110
1111	vbl.request.signal = drm_queue_seq;
1112	ret = drmWaitVBlank(pAMDGPUEnt->fd, &vbl);
1113	if (ret) {
1114		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
1115			   "get vblank counter failed: %s\n", strerror(errno));
1116		goto out_complete;
1117	}
1118
1119	DRI2BlockClient(client, draw);
1120
1121	return TRUE;
1122
1123out_complete:
1124	if (wait_info)
1125		amdgpu_dri2_deferred_event(NULL, 0, wait_info);
1126	return TRUE;
1127}
1128
1129/*
1130 * ScheduleSwap is responsible for requesting a DRM vblank event for the
1131 * appropriate frame.
1132 *
1133 * In the case of a blit (e.g. for a windowed swap) or buffer exchange,
1134 * the vblank requested can simply be the last queued swap frame + the swap
1135 * interval for the drawable.
1136 *
1137 * In the case of a page flip, we request an event for the last queued swap
1138 * frame + swap interval - 1, since we'll need to queue the flip for the frame
1139 * immediately following the received event.
1140 *
1141 * The client will be blocked if it tries to perform further GL commands
1142 * after queueing a swap, though in the Intel case after queueing a flip, the
1143 * client is free to queue more commands; they'll block in the kernel if
1144 * they access buffers busy with the flip.
1145 *
1146 * When the swap is complete, the driver should call into the server so it
1147 * can send any swap complete events that have been requested.
1148 */
1149static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
1150				     DRI2BufferPtr front, DRI2BufferPtr back,
1151				     CARD64 * target_msc, CARD64 divisor,
1152				     CARD64 remainder, DRI2SwapEventPtr func,
1153				     void *data)
1154{
1155	ScreenPtr screen = draw->pScreen;
1156	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
1157	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
1158	xf86CrtcPtr crtc = amdgpu_dri2_drawable_crtc(draw, TRUE);
1159	uint32_t msc_delta;
1160	drmVBlank vbl;
1161	int ret, flip = 0;
1162	DRI2FrameEventPtr swap_info = NULL;
1163	uintptr_t drm_queue_seq;
1164	CARD64 current_msc;
1165	BoxRec box;
1166	RegionRec region;
1167
1168	/* Truncate to match kernel interfaces; means occasional overflow
1169	 * misses, but that's generally not a big deal */
1170	*target_msc &= 0xffffffff;
1171	divisor &= 0xffffffff;
1172	remainder &= 0xffffffff;
1173
1174	/* amdgpu_dri2_frame_event_handler will get called some unknown time in the
1175	 * future with these buffers.  Take a reference to ensure that they won't
1176	 * get destroyed before then.
1177	 */
1178	amdgpu_dri2_ref_buffer(front);
1179	amdgpu_dri2_ref_buffer(back);
1180
1181	/* either off-screen or CRTC not usable... just complete the swap */
1182	if (crtc == NULL)
1183		goto blit_fallback;
1184
1185	msc_delta = amdgpu_get_msc_delta(draw, crtc);
1186
1187	swap_info = calloc(1, sizeof(DRI2FrameEventRec));
1188	if (!swap_info)
1189		goto blit_fallback;
1190
1191	swap_info->type = DRI2_SWAP;
1192	swap_info->drawable_id = draw->id;
1193	swap_info->client = client;
1194	swap_info->event_complete = func;
1195	swap_info->event_data = data;
1196	swap_info->front = front;
1197	swap_info->back = back;
1198	swap_info->crtc = crtc;
1199
1200	drm_queue_seq = amdgpu_drm_queue_alloc(crtc, client, AMDGPU_DRM_QUEUE_ID_DEFAULT,
1201					       swap_info, amdgpu_dri2_frame_event_handler,
1202					       amdgpu_dri2_frame_event_abort);
1203	if (drm_queue_seq == AMDGPU_DRM_QUEUE_ERROR) {
1204		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
1205			   "Allocating DRM queue entry failed.\n");
1206		goto blit_fallback;
1207	}
1208	swap_info->drm_queue_seq = drm_queue_seq;
1209
1210	/*
1211	 * CRTC is in DPMS off state, fallback to blit, but calculate
1212	 * wait time from current time, target_msc and last vblank
1213	 * time/sequence when CRTC was turned off
1214	 */
1215	if (!amdgpu_crtc_is_enabled(crtc)) {
1216		CARD32 delay;
1217		*target_msc -= msc_delta;
1218		delay = amdgpu_dri2_extrapolate_msc_delay(crtc, target_msc,
1219							  divisor, remainder);
1220		*target_msc += msc_delta;
1221		*target_msc &= 0xffffffff;
1222		amdgpu_dri2_schedule_event(delay, swap_info);
1223		return TRUE;
1224	}
1225
1226	/* Get current count */
1227	vbl.request.type = DRM_VBLANK_RELATIVE;
1228	vbl.request.type |= amdgpu_populate_vbl_request_type(crtc);
1229	vbl.request.sequence = 0;
1230	ret = drmWaitVBlank(pAMDGPUEnt->fd, &vbl);
1231	if (ret) {
1232		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
1233			   "first get vblank counter failed: %s\n",
1234			   strerror(errno));
1235		goto blit_fallback;
1236	}
1237
1238	current_msc = vbl.reply.sequence + msc_delta;
1239	current_msc &= 0xffffffff;
1240
1241	/* Flips need to be submitted one frame before */
1242	if (can_flip(scrn, draw, front, back)) {
1243		swap_info->type = DRI2_FLIP;
1244		flip = 1;
1245	}
1246
1247	/* Correct target_msc by 'flip' if swap_info->type == DRI2_FLIP.
1248	 * Do it early, so handling of different timing constraints
1249	 * for divisor, remainder and msc vs. target_msc works.
1250	 */
1251	if (*target_msc > 0)
1252		*target_msc -= flip;
1253
1254	/*
1255	 * If divisor is zero, or current_msc is smaller than target_msc
1256	 * we just need to make sure target_msc passes before initiating
1257	 * the swap.
1258	 */
1259	if (divisor == 0 || current_msc < *target_msc) {
1260		vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
1261		/* If non-pageflipping, but blitting/exchanging, we need to use
1262		 * DRM_VBLANK_NEXTONMISS to avoid unreliable timestamping later
1263		 * on.
1264		 */
1265		if (flip == 0)
1266			vbl.request.type |= DRM_VBLANK_NEXTONMISS;
1267		vbl.request.type |= amdgpu_populate_vbl_request_type(crtc);
1268
1269		/* If target_msc already reached or passed, set it to
1270		 * current_msc to ensure we return a reasonable value back
1271		 * to the caller. This makes swap_interval logic more robust.
1272		 */
1273		if (current_msc >= *target_msc)
1274			*target_msc = current_msc;
1275
1276		vbl.request.sequence = *target_msc - msc_delta;
1277		vbl.request.signal = drm_queue_seq;
1278		ret = drmWaitVBlank(pAMDGPUEnt->fd, &vbl);
1279		if (ret) {
1280			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
1281				   "divisor 0 get vblank counter failed: %s\n",
1282				   strerror(errno));
1283			goto blit_fallback;
1284		}
1285
1286		*target_msc = vbl.reply.sequence + flip + msc_delta;
1287		*target_msc &= 0xffffffff;
1288		swap_info->frame = *target_msc;
1289
1290		return TRUE;
1291	}
1292
1293	/*
1294	 * If we get here, target_msc has already passed or we don't have one,
1295	 * and we need to queue an event that will satisfy the divisor/remainder
1296	 * equation.
1297	 */
1298	vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
1299	if (flip == 0)
1300		vbl.request.type |= DRM_VBLANK_NEXTONMISS;
1301	vbl.request.type |= amdgpu_populate_vbl_request_type(crtc);
1302
1303	vbl.request.sequence = current_msc - (current_msc % divisor) +
1304	    remainder - msc_delta;
1305
1306	/*
1307	 * If the calculated deadline vbl.request.sequence is smaller than
1308	 * or equal to current_msc, it means we've passed the last point
1309	 * when effective onset frame seq could satisfy
1310	 * seq % divisor == remainder, so we need to wait for the next time
1311	 * this will happen.
1312
1313	 * This comparison takes the 1 frame swap delay in pageflipping mode
1314	 * into account, as well as a potential DRM_VBLANK_NEXTONMISS delay
1315	 * if we are blitting/exchanging instead of flipping.
1316	 */
1317	if (vbl.request.sequence <= current_msc)
1318		vbl.request.sequence += divisor;
1319
1320	/* Account for 1 frame extra pageflip delay if flip > 0 */
1321	vbl.request.sequence -= flip;
1322
1323	vbl.request.signal = drm_queue_seq;
1324	ret = drmWaitVBlank(pAMDGPUEnt->fd, &vbl);
1325	if (ret) {
1326		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
1327			   "final get vblank counter failed: %s\n",
1328			   strerror(errno));
1329		goto blit_fallback;
1330	}
1331
1332	/* Adjust returned value for 1 fame pageflip offset of flip > 0 */
1333	*target_msc = vbl.reply.sequence + flip + msc_delta;
1334	*target_msc &= 0xffffffff;
1335	swap_info->frame = *target_msc;
1336
1337	return TRUE;
1338
1339blit_fallback:
1340	if (swap_info) {
1341		swap_info->type = DRI2_SWAP;
1342		amdgpu_dri2_schedule_event(FALLBACK_SWAP_DELAY, swap_info);
1343	} else {
1344		box.x1 = 0;
1345		box.y1 = 0;
1346		box.x2 = draw->width;
1347		box.y2 = draw->height;
1348		REGION_INIT(pScreen, &region, &box, 0);
1349
1350		amdgpu_dri2_copy_region(draw, &region, front, back);
1351
1352		DRI2SwapComplete(client, draw, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data);
1353
1354		amdgpu_dri2_unref_buffer(front);
1355		amdgpu_dri2_unref_buffer(back);
1356	}
1357
1358	*target_msc = 0;	/* offscreen, so zero out target vblank count */
1359	return TRUE;
1360}
1361
1362Bool amdgpu_dri2_screen_init(ScreenPtr pScreen)
1363{
1364	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1365	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
1366	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
1367	DRI2InfoRec dri2_info = { 0 };
1368	const char *driverNames[2];
1369	Bool scheduling_works = TRUE;
1370
1371	if (!info->dri2.available)
1372		return FALSE;
1373
1374	info->dri2.device_name = drmGetDeviceNameFromFd(pAMDGPUEnt->fd);
1375
1376	dri2_info.driverName = SI_DRIVER_NAME;
1377	dri2_info.fd = pAMDGPUEnt->fd;
1378	dri2_info.deviceName = info->dri2.device_name;
1379	dri2_info.version = DRI2INFOREC_VERSION;
1380	dri2_info.CreateBuffer = amdgpu_dri2_create_buffer;
1381	dri2_info.DestroyBuffer = amdgpu_dri2_destroy_buffer;
1382	dri2_info.CopyRegion = amdgpu_dri2_copy_region;
1383
1384	if (info->drmmode.count_crtcs > 2) {
1385		uint64_t cap_value;
1386
1387		if (drmGetCap
1388		    (pAMDGPUEnt->fd, DRM_CAP_VBLANK_HIGH_CRTC, &cap_value)) {
1389			xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1390				   "You need a newer kernel "
1391				   "for VBLANKs on CRTC > 1\n");
1392			scheduling_works = FALSE;
1393		} else if (!cap_value) {
1394			xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1395				   "Your kernel does not "
1396				   "handle VBLANKs on CRTC > 1\n");
1397			scheduling_works = FALSE;
1398		}
1399	}
1400
1401	if (scheduling_works) {
1402		dri2_info.version = 4;
1403		dri2_info.ScheduleSwap = amdgpu_dri2_schedule_swap;
1404		dri2_info.GetMSC = amdgpu_dri2_get_msc;
1405		dri2_info.ScheduleWaitMSC = amdgpu_dri2_schedule_wait_msc;
1406		dri2_info.numDrivers = AMDGPU_ARRAY_SIZE(driverNames);
1407		dri2_info.driverNames = driverNames;
1408		driverNames[0] = driverNames[1] = dri2_info.driverName;
1409
1410		if (DRI2InfoCnt == 0) {
1411			if (!dixRegisterPrivateKey(dri2_window_private_key,
1412						   PRIVATE_WINDOW,
1413						   sizeof(struct dri2_window_priv))) {
1414				xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1415					   "Failed to get DRI2 window private\n");
1416				return FALSE;
1417			}
1418
1419			AddCallback(&ClientStateCallback,
1420				    amdgpu_dri2_client_state_changed, 0);
1421		}
1422
1423		DRI2InfoCnt++;
1424	}
1425
1426#if DRI2INFOREC_VERSION >= 9
1427	dri2_info.version = 9;
1428	dri2_info.CreateBuffer2 = amdgpu_dri2_create_buffer2;
1429	dri2_info.DestroyBuffer2 = amdgpu_dri2_destroy_buffer2;
1430	dri2_info.CopyRegion2 = amdgpu_dri2_copy_region2;
1431#endif
1432
1433	info->dri2.enabled = DRI2ScreenInit(pScreen, &dri2_info);
1434	return info->dri2.enabled;
1435}
1436
1437void amdgpu_dri2_close_screen(ScreenPtr pScreen)
1438{
1439	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1440	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
1441
1442	if (--DRI2InfoCnt == 0)
1443		DeleteCallback(&ClientStateCallback,
1444			       amdgpu_dri2_client_state_changed, 0);
1445
1446	DRI2CloseScreen(pScreen);
1447	drmFree(info->dri2.device_name);
1448}
1449
1450#endif /* DRI2 */
1451