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