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