summaryrefslogtreecommitdiff
path: root/driver/xf86-video-ati/src/radeon_dri2.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/xf86-video-ati/src/radeon_dri2.c')
-rw-r--r--driver/xf86-video-ati/src/radeon_dri2.c181
1 files changed, 54 insertions, 127 deletions
diff --git a/driver/xf86-video-ati/src/radeon_dri2.c b/driver/xf86-video-ati/src/radeon_dri2.c
index d30bbd0bd..0cd6b2419 100644
--- a/driver/xf86-video-ati/src/radeon_dri2.c
+++ b/driver/xf86-video-ati/src/radeon_dri2.c
@@ -70,86 +70,14 @@ struct dri2_window_priv {
int vblank_delta;
};
-#if HAS_DEVPRIVATEKEYREC
-
static DevPrivateKeyRec dri2_window_private_key_rec;
#define dri2_window_private_key (&dri2_window_private_key_rec)
-#else
-
-static int dri2_window_private_key_index;
-DevPrivateKey dri2_window_private_key = &dri2_window_private_key_index;
-
-#endif /* HAS_DEVPRIVATEKEYREC */
-
#define get_dri2_window_priv(window) \
((struct dri2_window_priv*) \
dixLookupPrivate(&(window)->devPrivates, dri2_window_private_key))
-static PixmapPtr get_drawable_pixmap(DrawablePtr drawable)
-{
- if (drawable->type == DRAWABLE_PIXMAP)
- return (PixmapPtr)drawable;
- else
- return (*drawable->pScreen->GetWindowPixmap)((WindowPtr)drawable);
-}
-
-
-static PixmapPtr fixup_glamor(DrawablePtr drawable, PixmapPtr pixmap)
-{
- PixmapPtr old = get_drawable_pixmap(drawable);
-#ifdef USE_GLAMOR
- ScreenPtr screen = drawable->pScreen;
- struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
- GCPtr gc;
-
- /* With a glamor pixmap, 2D pixmaps are created in texture
- * and without a static BO attached to it. To support DRI,
- * we need to create a new textured-drm pixmap and
- * need to copy the original content to this new textured-drm
- * pixmap, and then convert the old pixmap to a coherent
- * textured-drm pixmap which has a valid BO attached to it
- * and also has a valid texture, thus both glamor and DRI2
- * can access it.
- *
- */
-
- /* Copy the current contents of the pixmap to the bo. */
- gc = GetScratchGC(drawable->depth, screen);
- if (gc) {
- ValidateGC(&pixmap->drawable, gc);
- gc->ops->CopyArea(&old->drawable, &pixmap->drawable,
- gc,
- 0, 0,
- old->drawable.width,
- old->drawable.height,
- 0, 0);
- FreeScratchGC(gc);
- }
-
- radeon_set_pixmap_private(pixmap, NULL);
-
- /* And redirect the pixmap to the new bo (for 3D). */
- glamor_egl_exchange_buffers(old, pixmap);
- radeon_set_pixmap_private(old, priv);
- old->refcnt++;
-
- screen->ModifyPixmapHeader(old,
- old->drawable.width,
- old->drawable.height,
- 0, 0,
- pixmap->devKind,
- NULL);
- old->devPrivate.ptr = NULL;
-
- screen->DestroyPixmap(pixmap);
-
-#endif /* USE_GLAMOR*/
-
- return old;
-}
-
/* Get GEM flink name for a pixmap */
static Bool
radeon_get_flink_name(RADEONInfoPtr info, PixmapPtr pixmap, uint32_t *name)
@@ -319,10 +247,11 @@ radeon_dri2_create_buffer2(ScreenPtr pScreen,
/* this happen if pixmap is non accelerable */
goto error;
}
+ } else if (is_glamor_pixmap) {
+ pixmap = radeon_glamor_set_pixmap_bo(drawable, pixmap);
+ pixmap->refcnt++;
}
- if (is_glamor_pixmap)
- pixmap = fixup_glamor(drawable, pixmap);
if (!radeon_get_flink_name(info, pixmap, &buffers->name))
goto error;
}
@@ -525,7 +454,7 @@ typedef struct _DRI2FrameEvent {
unsigned frame;
xf86CrtcPtr crtc;
OsTimerPtr timer;
- struct radeon_drm_queue_entry *drm_queue;
+ uintptr_t drm_queue_seq;
/* for swaps & flips only */
DRI2SwapEventPtr event_complete;
@@ -587,10 +516,11 @@ static uint32_t radeon_get_msc_delta(DrawablePtr pDraw, xf86CrtcPtr crtc)
*/
static Bool radeon_dri2_get_crtc_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc)
{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
if (!radeon_crtc_is_enabled(crtc) ||
drmmode_crtc_get_ust_msc(crtc, ust, msc) != Success) {
/* CRTC is not running, extrapolate MSC and timestamp */
- drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
ScrnInfoPtr scrn = crtc->scrn;
RADEONInfoPtr info = RADEONPTR(scrn);
CARD64 now, delta_t, delta_seq;
@@ -615,6 +545,8 @@ static Bool radeon_dri2_get_crtc_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc)
*msc += delta_seq;
}
+ *msc += drmmode_crtc->interpolated_vblanks;
+
return TRUE;
}
@@ -645,17 +577,20 @@ xf86CrtcPtr radeon_dri2_drawable_crtc(DrawablePtr pDraw, Bool consider_disabled)
}
static void
-radeon_dri2_flip_event_abort(ScrnInfoPtr scrn, void *event_data)
+radeon_dri2_flip_event_abort(xf86CrtcPtr crtc, void *event_data)
{
+ RADEONInfoPtr info = RADEONPTR(crtc->scrn);
+
+ info->drmmode.dri2_flipping = FALSE;
free(event_data);
}
static void
-radeon_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec,
+radeon_dri2_flip_event_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
void *event_data)
{
- RADEONInfoPtr info = RADEONPTR(scrn);
DRI2FrameEventPtr flip = event_data;
+ ScrnInfoPtr scrn = crtc->scrn;
unsigned tv_sec, tv_usec;
DrawablePtr drawable;
ScreenPtr screen;
@@ -667,9 +602,7 @@ radeon_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec,
if (status != Success)
goto abort;
- if (!flip->crtc)
- goto abort;
- frame += radeon_get_msc_delta(drawable, flip->crtc);
+ frame += radeon_get_msc_delta(drawable, crtc);
screen = scrn->pScreen;
pixmap = screen->GetScreenPixmap(screen);
@@ -698,7 +631,6 @@ radeon_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec,
DRI2SwapComplete(flip->client, drawable, frame, tv_sec, tv_usec,
DRI2_FLIP_COMPLETE, flip->event_complete,
flip->event_data);
- info->drmmode.dri2_flipping = FALSE;
break;
default:
xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: unknown vblank event received\n", __func__);
@@ -707,22 +639,21 @@ radeon_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec,
}
abort:
- radeon_dri2_flip_event_abort(scrn, event_data);
+ radeon_dri2_flip_event_abort(crtc, event_data);
}
static Bool
-radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr client,
+radeon_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client,
DrawablePtr draw, DRI2BufferPtr front,
DRI2BufferPtr back, DRI2SwapEventPtr func,
void *data, unsigned int target_msc)
{
+ ScrnInfoPtr scrn = crtc->scrn;
RADEONInfoPtr info = RADEONPTR(scrn);
struct dri2_buffer_priv *back_priv;
struct radeon_bo *bo;
DRI2FrameEventPtr flip_info;
- /* Main crtc for this drawable shall finally deliver pageflip event. */
- xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, FALSE);
- int ref_crtc_hw_id = crtc ? drmmode_get_crtc_id(crtc) : -1;
+ int ref_crtc_hw_id = drmmode_get_crtc_id(crtc);
flip_info = calloc(1, sizeof(DRI2FrameEventRec));
if (!flip_info)
@@ -824,6 +755,7 @@ can_flip(ScrnInfoPtr pScrn, DrawablePtr draw,
return draw->type == DRAWABLE_WINDOW &&
info->allowPageFlip &&
+ !info->hwcursor_disabled &&
!info->drmmode.present_flipping &&
pScrn->vtSema &&
DRI2CanFlip(draw) &&
@@ -843,7 +775,7 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt
region.extents.x1 = region.extents.y1 = 0;
region.extents.x2 = front_priv->pixmap->drawable.width;
- region.extents.y2 = front_priv->pixmap->drawable.width;
+ region.extents.y2 = front_priv->pixmap->drawable.height;
region.data = NULL;
DamageRegionAppend(&front_priv->pixmap->drawable, &region);
@@ -873,7 +805,7 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt
DamageRegionProcessPending(&front_priv->pixmap->drawable);
}
-static void radeon_dri2_frame_event_abort(ScrnInfoPtr scrn, void *event_data)
+static void radeon_dri2_frame_event_abort(xf86CrtcPtr crtc, void *event_data)
{
DRI2FrameEventPtr event = event_data;
@@ -884,30 +816,28 @@ static void radeon_dri2_frame_event_abort(ScrnInfoPtr scrn, void *event_data)
free(event);
}
-static void radeon_dri2_frame_event_handler(ScrnInfoPtr scrn, uint32_t seq,
+static void radeon_dri2_frame_event_handler(xf86CrtcPtr crtc, uint32_t seq,
uint64_t usec, void *event_data)
{
DRI2FrameEventPtr event = event_data;
+ ScrnInfoPtr scrn = crtc->scrn;
DrawablePtr drawable;
int status;
int swap_type;
BoxRec box;
RegionRec region;
- if (!event->crtc)
- goto cleanup;
-
status = dixLookupDrawable(&drawable, event->drawable_id, serverClient,
M_ANY, DixWriteAccess);
if (status != Success)
goto cleanup;
- seq += radeon_get_msc_delta(drawable, event->crtc);
+ seq += radeon_get_msc_delta(drawable, crtc);
switch (event->type) {
case DRI2_FLIP:
if (can_flip(scrn, drawable, event->front, event->back) &&
- radeon_dri2_schedule_flip(scrn,
+ radeon_dri2_schedule_flip(crtc,
event->client,
drawable,
event->front,
@@ -951,7 +881,7 @@ static void radeon_dri2_frame_event_handler(ScrnInfoPtr scrn, uint32_t seq,
}
cleanup:
- radeon_dri2_frame_event_abort(scrn, event_data);
+ radeon_dri2_frame_event_abort(crtc, event_data);
}
drmVBlankSeqType radeon_populate_vbl_request_type(xf86CrtcPtr crtc)
@@ -1064,7 +994,8 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
if (!radeon_dri2_get_crtc_msc(crtc, ust, msc))
return FALSE;
- *msc += radeon_get_msc_delta(draw, crtc);
+ if (draw && draw->type == DRAWABLE_WINDOW)
+ *msc += get_dri2_window_priv((WindowPtr)draw)->vblank_delta;
*msc &= 0xffffffff;
return TRUE;
}
@@ -1090,8 +1021,8 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
*/
if (!event_info->crtc) {
ErrorF("%s no crtc\n", __func__);
- if (event_info->drm_queue)
- radeon_drm_abort_entry(event_info->drm_queue);
+ if (event_info->drm_queue_seq)
+ radeon_drm_abort_entry(event_info->drm_queue_seq);
else
radeon_dri2_frame_event_abort(NULL, data);
return 0;
@@ -1103,11 +1034,11 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"%s cannot get current time\n", __func__);
- if (event_info->drm_queue)
+ if (event_info->drm_queue_seq)
radeon_drm_queue_handler(info->dri2.drm_fd, 0, 0, 0,
- event_info->drm_queue);
+ (void*)event_info->drm_queue_seq);
else
- radeon_dri2_frame_event_handler(scrn, 0, 0, data);
+ radeon_dri2_frame_event_handler(crtc, 0, 0, data);
return 0;
}
/*
@@ -1119,11 +1050,12 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
delta_seq = delta_t * drmmode_crtc->dpms_last_fps;
delta_seq /= 1000000;
frame = (CARD64)drmmode_crtc->dpms_last_seq + delta_seq;
- if (event_info->drm_queue)
+ if (event_info->drm_queue_seq)
radeon_drm_queue_handler(info->dri2.drm_fd, frame, drm_now / 1000000,
- drm_now % 1000000, event_info->drm_queue);
+ drm_now % 1000000,
+ (void*)event_info->drm_queue_seq);
else
- radeon_dri2_frame_event_handler(scrn, frame, drm_now, data);
+ radeon_dri2_frame_event_handler(crtc, frame, drm_now, data);
return 0;
}
@@ -1152,7 +1084,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
DRI2FrameEventPtr wait_info = NULL;
- struct radeon_drm_queue_entry *wait = NULL;
+ uintptr_t drm_queue_seq = 0;
xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE);
uint32_t msc_delta;
drmVBlank vbl;
@@ -1208,15 +1140,15 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
current_msc = vbl.reply.sequence + msc_delta;
current_msc &= 0xffffffff;
- wait = radeon_drm_queue_alloc(scrn, client, RADEON_DRM_QUEUE_ID_DEFAULT,
- wait_info, radeon_dri2_frame_event_handler,
- radeon_dri2_frame_event_abort);
- if (!wait) {
+ drm_queue_seq = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT,
+ wait_info, radeon_dri2_frame_event_handler,
+ radeon_dri2_frame_event_abort);
+ if (!drm_queue_seq) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Allocating DRM queue event entry failed.\n");
goto out_complete;
}
- wait_info->drm_queue = wait;
+ wait_info->drm_queue_seq = drm_queue_seq;
/*
* If divisor is zero, or current_msc is smaller than target_msc,
@@ -1235,7 +1167,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
vbl.request.type |= radeon_populate_vbl_request_type(crtc);
vbl.request.sequence = target_msc - msc_delta;
- vbl.request.signal = (unsigned long)wait;
+ vbl.request.signal = drm_queue_seq;
ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1266,7 +1198,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
if ((current_msc % divisor) >= remainder)
vbl.request.sequence += divisor;
- vbl.request.signal = (unsigned long)wait;
+ vbl.request.signal = drm_queue_seq;
ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1318,7 +1250,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
drmVBlank vbl;
int ret, flip = 0;
DRI2FrameEventPtr swap_info = NULL;
- struct radeon_drm_queue_entry *swap;
+ uintptr_t drm_queue_seq;
CARD64 current_msc;
BoxRec box;
RegionRec region;
@@ -1355,15 +1287,15 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
swap_info->back = back;
swap_info->crtc = crtc;
- swap = radeon_drm_queue_alloc(scrn, client, RADEON_DRM_QUEUE_ID_DEFAULT,
- swap_info, radeon_dri2_frame_event_handler,
- radeon_dri2_frame_event_abort);
- if (!swap) {
+ drm_queue_seq = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT,
+ swap_info, radeon_dri2_frame_event_handler,
+ radeon_dri2_frame_event_abort);
+ if (!drm_queue_seq) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Allocating DRM queue entry failed.\n");
goto blit_fallback;
}
- swap_info->drm_queue = swap;
+ swap_info->drm_queue_seq = drm_queue_seq;
/*
* CRTC is in DPMS off state, fallback to blit, but calculate
@@ -1432,7 +1364,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
*target_msc = current_msc;
vbl.request.sequence = *target_msc - msc_delta;
- vbl.request.signal = (unsigned long)swap;
+ vbl.request.signal = drm_queue_seq;
ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1477,7 +1409,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
/* Account for 1 frame extra pageflip delay if flip > 0 */
vbl.request.sequence -= flip;
- vbl.request.signal = (unsigned long)swap;
+ vbl.request.signal = drm_queue_seq;
ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1590,14 +1522,9 @@ radeon_dri2_screen_init(ScreenPtr pScreen)
driverNames[1] = NULL; /* no VDPAU support */
if (DRI2InfoCnt == 0) {
-#if HAS_DIXREGISTERPRIVATEKEY
if (!dixRegisterPrivateKey(dri2_window_private_key,
PRIVATE_WINDOW,
sizeof(struct dri2_window_priv))) {
-#else
- if (!dixRequestPrivate(dri2_window_private_key,
- sizeof(struct dri2_window_priv))) {
-#endif
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Failed to get DRI2 window private\n");
return FALSE;