summaryrefslogtreecommitdiff
path: root/driver/xf86-video-ati/src
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2019-03-08 21:59:58 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2019-03-08 21:59:58 +0000
commitc4f0a5e3d3fc40d0a80cc31ee710e05fa0cce5c5 (patch)
treea9367808d33e2560613403402f0ff352d274b04c /driver/xf86-video-ati/src
parent62278a148bb5b51b727d8fdceca73da2c7223a42 (diff)
update to xf86-video-ati 19.0.0
fixes Xorg segfault reported by Mihai Popescu ok matthieu@
Diffstat (limited to 'driver/xf86-video-ati/src')
-rw-r--r--driver/xf86-video-ati/src/drmmode_display.c330
-rw-r--r--driver/xf86-video-ati/src/drmmode_display.h20
-rw-r--r--driver/xf86-video-ati/src/radeon.h3
-rw-r--r--driver/xf86-video-ati/src/radeon_bo_helper.c2
-rw-r--r--driver/xf86-video-ati/src/radeon_dri2.c29
-rw-r--r--driver/xf86-video-ati/src/radeon_dri3.c41
-rw-r--r--driver/xf86-video-ati/src/radeon_drm_queue.c129
-rw-r--r--driver/xf86-video-ati/src/radeon_drm_queue.h3
-rw-r--r--driver/xf86-video-ati/src/radeon_glamor.c9
-rw-r--r--driver/xf86-video-ati/src/radeon_kms.c266
-rw-r--r--driver/xf86-video-ati/src/radeon_present.c11
-rw-r--r--driver/xf86-video-ati/src/radeon_probe.h4
12 files changed, 560 insertions, 287 deletions
diff --git a/driver/xf86-video-ati/src/drmmode_display.c b/driver/xf86-video-ati/src/drmmode_display.c
index 8445ef2a7..c5fccd2aa 100644
--- a/driver/xf86-video-ati/src/drmmode_display.c
+++ b/driver/xf86-video-ati/src/drmmode_display.c
@@ -508,8 +508,17 @@ drmmode_crtc_scanout_destroy(drmmode_ptr drmmode,
}
void
-drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc)
+drmmode_crtc_scanout_free(xf86CrtcPtr crtc)
{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+ if (drmmode_crtc->scanout_update_pending) {
+ radeon_drm_wait_pending_flip(crtc);
+ radeon_drm_abort_entry(drmmode_crtc->scanout_update_pending);
+ drmmode_crtc->scanout_update_pending = 0;
+ radeon_drm_queue_handle_deferred(crtc);
+ }
+
drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
&drmmode_crtc->scanout[0]);
drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
@@ -772,11 +781,17 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode,
*fb = radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap);
*x = *y = 0;
- radeon_scanout_do_update(crtc, scanout_id,
- screen->GetWindowPixmap(screen->root),
- extents);
- RegionEmpty(DamageRegion(drmmode_crtc->scanout_damage));
- radeon_finish(scrn, drmmode_crtc->scanout[scanout_id].bo);
+ if (radeon_scanout_do_update(crtc, scanout_id,
+ screen->GetWindowPixmap(screen->root),
+ extents)) {
+ RegionEmpty(DamageRegion(drmmode_crtc->scanout_damage));
+ radeon_glamor_finish(scrn);
+
+ if (!drmmode_crtc->flip_pending) {
+ radeon_drm_abort_entry(drmmode_crtc->
+ scanout_update_pending);
+ }
+ }
}
}
@@ -848,6 +863,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ Bool handle_deferred = FALSE;
unsigned scanout_id = 0;
drmmode_ptr drmmode = drmmode_crtc->drmmode;
int saved_x, saved_y;
@@ -915,6 +931,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
}
radeon_drm_wait_pending_flip(crtc);
+ handle_deferred = TRUE;
if (!drmmode_set_mode(crtc, fb, mode, x, y))
goto done;
@@ -967,16 +984,16 @@ done:
if (drmmode_crtc->scanout[scanout_id].pixmap &&
fb != radeon_pixmap_get_fb(drmmode_crtc->
scanout[scanout_id].pixmap)) {
- radeon_drm_abort_entry(drmmode_crtc->scanout_update_pending);
- drmmode_crtc->scanout_update_pending = 0;
- drmmode_crtc_scanout_free(drmmode_crtc);
+ drmmode_crtc_scanout_free(crtc);
} else if (!drmmode_crtc->tear_free) {
drmmode_crtc_scanout_destroy(drmmode,
&drmmode_crtc->scanout[1]);
}
}
- radeon_drm_queue_handle_deferred(crtc);
+ if (handle_deferred)
+ radeon_drm_queue_handle_deferred(crtc);
+
return ret;
}
@@ -1000,6 +1017,9 @@ drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
}
#endif
+ drmmode_crtc->cursor_x = x;
+ drmmode_crtc->cursor_y = y;
+
drmModeMoveCursor(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, x, y);
}
@@ -1038,29 +1058,62 @@ drmmode_cursor_src_offset(Rotation rotation, int width, int height,
#endif
-static uint32_t
-drmmode_cursor_gamma(xf86CrtcPtr crtc, uint32_t argb)
+static Bool
+drmmode_cursor_pixel(xf86CrtcPtr crtc, uint32_t *argb, Bool *premultiplied,
+ Bool *apply_gamma)
{
- uint32_t alpha = argb >> 24;
+ uint32_t alpha = *argb >> 24;
uint32_t rgb[3];
int i;
- if (!alpha)
- return 0;
+ if (premultiplied) {
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 18, 4, 0, 0)
+ if (alpha == 0 && (*argb & 0xffffff) != 0) {
+ /* Doesn't look like premultiplied alpha */
+ *premultiplied = FALSE;
+ return FALSE;
+ }
+#endif
- if (crtc->scrn->depth != 24 && crtc->scrn->depth != 32)
- return argb;
+ if (!(*apply_gamma))
+ return TRUE;
+
+ if (*argb > (alpha | alpha << 8 | alpha << 16 | alpha << 24)) {
+ /* Un-premultiplied R/G/B would overflow gamma LUT,
+ * don't apply gamma correction
+ */
+ *apply_gamma = FALSE;
+ return FALSE;
+ }
+ }
+
+ if (!alpha) {
+ *argb = 0;
+ return TRUE;
+ }
- /* Un-premultiply alpha */
+ /* Extract RGB */
for (i = 0; i < 3; i++)
- rgb[i] = ((argb >> (i * 8)) & 0xff) * 0xff / alpha;
+ rgb[i] = (*argb >> (i * 8)) & 0xff;
- /* Apply gamma correction and pre-multiply alpha */
- rgb[0] = (crtc->gamma_blue[rgb[0]] >> 8) * alpha / 0xff;
- rgb[1] = (crtc->gamma_green[rgb[1]] >> 8) * alpha / 0xff;
- rgb[2] = (crtc->gamma_red[rgb[2]] >> 8) * alpha / 0xff;
+ if (premultiplied) {
+ /* Un-premultiply alpha */
+ for (i = 0; i < 3; i++)
+ rgb[i] = rgb[i] * 0xff / alpha;
+ }
+
+ if (*apply_gamma) {
+ rgb[0] = crtc->gamma_blue[rgb[0]] >> 8;
+ rgb[1] = crtc->gamma_green[rgb[1]] >> 8;
+ rgb[2] = crtc->gamma_red[rgb[2]] >> 8;
+ }
- return alpha << 24 | rgb[2] << 16 | rgb[1] << 8 | rgb[0];
+ /* Premultiply alpha */
+ for (i = 0; i < 3; i++)
+ rgb[i] = rgb[i] * alpha / 0xff;
+
+ *argb = alpha << 24 | rgb[2] << 16 | rgb[1] << 8 | rgb[0];
+ return TRUE;
}
static void
@@ -1069,10 +1122,21 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
ScrnInfoPtr pScrn = crtc->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ unsigned id = drmmode_crtc->cursor_id;
+ Bool premultiplied = TRUE;
+ Bool apply_gamma = TRUE;
+ uint32_t argb;
uint32_t *ptr;
+ if (drmmode_crtc->cursor &&
+ XF86_CRTC_CONFIG_PTR(pScrn)->cursor != drmmode_crtc->cursor)
+ id ^= 1;
+
/* cursor should be mapped already */
- ptr = (uint32_t *)(drmmode_crtc->cursor_bo->ptr);
+ ptr = (uint32_t *)(drmmode_crtc->cursor_bo[id]->ptr);
+
+ if (crtc->scrn->depth != 24 && crtc->scrn->depth != 32)
+ apply_gamma = FALSE;
#if XF86_CRTC_VERSION < 7
if (crtc->driverIsPerformingTransform) {
@@ -1080,16 +1144,19 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
int dstx, dsty;
int srcoffset;
+retry_transform:
for (dsty = 0; dsty < cursor_h; dsty++) {
for (dstx = 0; dstx < cursor_w; dstx++) {
srcoffset = drmmode_cursor_src_offset(crtc->rotation,
cursor_w,
cursor_h,
dstx, dsty);
+ argb = image[srcoffset];
+ if (!drmmode_cursor_pixel(crtc, &argb, &premultiplied,
+ &apply_gamma))
+ goto retry_transform;
- ptr[dsty * info->cursor_w + dstx] =
- cpu_to_le32(drmmode_cursor_gamma(crtc,
- image[srcoffset]));
+ ptr[dsty * info->cursor_w + dstx] = cpu_to_le32(argb);
}
}
} else
@@ -1098,8 +1165,20 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
uint32_t cursor_size = info->cursor_w * info->cursor_h;
int i;
- for (i = 0; i < cursor_size; i++)
- ptr[i] = cpu_to_le32(drmmode_cursor_gamma(crtc, image[i]));
+retry:
+ for (i = 0; i < cursor_size; i++) {
+ argb = image[i];
+ if (!drmmode_cursor_pixel(crtc, &argb, &premultiplied,
+ &apply_gamma))
+ goto retry;
+
+ ptr[i] = cpu_to_le32(argb);
+ }
+ }
+
+ if (id != drmmode_crtc->cursor_id) {
+ drmmode_crtc->cursor_id = id;
+ crtc->funcs->show_cursor(crtc);
}
}
@@ -1126,7 +1205,7 @@ drmmode_hide_cursor (xf86CrtcPtr crtc)
drmModeSetCursor(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, 0,
info->cursor_w, info->cursor_h);
-
+ drmmode_crtc->cursor = NULL;
}
static void
@@ -1136,56 +1215,73 @@ drmmode_show_cursor (xf86CrtcPtr crtc)
RADEONInfoPtr info = RADEONPTR(pScrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- uint32_t handle = drmmode_crtc->cursor_bo->handle;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ CursorPtr cursor = xf86_config->cursor;
+ int xhot = cursor->bits->xhot;
+ int yhot = cursor->bits->yhot;
static Bool use_set_cursor2 = TRUE;
+ struct drm_mode_cursor2 arg;
+
+ drmmode_crtc->cursor = xf86_config->cursor;
+
+ memset(&arg, 0, sizeof(arg));
+
+ arg.handle = drmmode_crtc->cursor_bo[drmmode_crtc->cursor_id]->handle;
+ arg.flags = DRM_MODE_CURSOR_BO;
+ arg.crtc_id = drmmode_crtc->mode_crtc->crtc_id;
+ arg.width = info->cursor_w;
+ arg.height = info->cursor_h;
+
+ if (crtc->rotation != RR_Rotate_0 &&
+ crtc->rotation != (RR_Rotate_180 | RR_Reflect_X |
+ RR_Reflect_Y)) {
+ int t;
+
+ /* Reflect & rotate hotspot position */
+ if (crtc->rotation & RR_Reflect_X)
+ xhot = info->cursor_w - xhot - 1;
+ if (crtc->rotation & RR_Reflect_Y)
+ yhot = info->cursor_h - yhot - 1;
+
+ switch (crtc->rotation & 0xf) {
+ case RR_Rotate_90:
+ t = xhot;
+ xhot = yhot;
+ yhot = info->cursor_w - t - 1;
+ break;
+ case RR_Rotate_180:
+ xhot = info->cursor_w - xhot - 1;
+ yhot = info->cursor_h - yhot - 1;
+ break;
+ case RR_Rotate_270:
+ t = xhot;
+ xhot = info->cursor_h - yhot - 1;
+ yhot = t;
+ }
+ }
+
+ if (xhot != drmmode_crtc->cursor_xhot || yhot != drmmode_crtc->cursor_yhot) {
+ arg.flags |= DRM_MODE_CURSOR_MOVE;
+ arg.x = drmmode_crtc->cursor_x += drmmode_crtc->cursor_xhot - xhot;
+ arg.y = drmmode_crtc->cursor_y += drmmode_crtc->cursor_yhot - yhot;
+ drmmode_crtc->cursor_xhot = xhot;
+ drmmode_crtc->cursor_yhot = yhot;
+ }
if (use_set_cursor2) {
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
- CursorPtr cursor = xf86_config->cursor;
- int xhot = cursor->bits->xhot;
- int yhot = cursor->bits->yhot;
int ret;
- if (crtc->rotation != RR_Rotate_0 &&
- crtc->rotation != (RR_Rotate_180 | RR_Reflect_X |
- RR_Reflect_Y)) {
- int t;
-
- /* Reflect & rotate hotspot position */
- if (crtc->rotation & RR_Reflect_X)
- xhot = info->cursor_w - xhot - 1;
- if (crtc->rotation & RR_Reflect_Y)
- yhot = info->cursor_h - yhot - 1;
-
- switch (crtc->rotation & 0xf) {
- case RR_Rotate_90:
- t = xhot;
- xhot = yhot;
- yhot = info->cursor_w - t - 1;
- break;
- case RR_Rotate_180:
- xhot = info->cursor_w - xhot - 1;
- yhot = info->cursor_h - yhot - 1;
- break;
- case RR_Rotate_270:
- t = xhot;
- xhot = info->cursor_h - yhot - 1;
- yhot = t;
- }
- }
+ arg.hot_x = xhot;
+ arg.hot_y = yhot;
- ret =
- drmModeSetCursor2(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id,
- handle, info->cursor_w, info->cursor_h,
- xhot, yhot);
+ ret = drmIoctl(pRADEONEnt->fd, DRM_IOCTL_MODE_CURSOR2, &arg);
if (ret == -EINVAL)
use_set_cursor2 = FALSE;
else
return;
}
- drmModeSetCursor(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, handle,
- info->cursor_w, info->cursor_h);
+ drmIoctl(pRADEONEnt->fd, DRM_IOCTL_MODE_CURSOR, &arg);
}
/* Xorg expects a non-NULL return value from drmmode_crtc_shadow_allocate, and
@@ -1265,7 +1361,7 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
}
}
- drmmode_crtc_scanout_free(drmmode_crtc);
+ drmmode_crtc_scanout_free(crtc);
drmmode_crtc->prime_scanout_pixmap = NULL;
if (!ppix)
@@ -1280,7 +1376,7 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
!drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1],
ppix->drawable.width,
ppix->drawable.height)) {
- drmmode_crtc_scanout_free(drmmode_crtc);
+ drmmode_crtc_scanout_free(crtc);
return FALSE;
}
@@ -2049,9 +2145,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
if (!RADEONZaphodStringMatches(pScrn, s, name))
goto out_free_encoders;
} else {
- if (!info->IsSecondary && (num != 0))
- goto out_free_encoders;
- else if (info->IsSecondary && (num != 1))
+ if (info->instance_id != num)
goto out_free_encoders;
}
}
@@ -2557,12 +2651,14 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even
flipdata->fe_usec = usec;
}
- if (drmmode_crtc->flip_pending == *fb) {
- drmmode_fb_reference(pRADEONEnt->fd,
- &drmmode_crtc->flip_pending, NULL);
+ if (*fb) {
+ if (drmmode_crtc->flip_pending == *fb) {
+ drmmode_fb_reference(pRADEONEnt->fd,
+ &drmmode_crtc->flip_pending, NULL);
+ }
+ drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, *fb);
+ drmmode_fb_reference(pRADEONEnt->fd, fb, NULL);
}
- drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, *fb);
- drmmode_fb_reference(pRADEONEnt->fd, fb, NULL);
if (--flipdata->flip_count == 0) {
/* Deliver MSC & UST from reference/current CRTC to flip event
@@ -2669,6 +2765,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
int i, num_dvi = 0, num_hdmi = 0;
drmModeResPtr mode_res;
unsigned int crtcs_needed = 0;
+ unsigned int crtcs_got = 0;
char *bus_id_string, *provider_name;
xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
@@ -2707,16 +2804,26 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
drmmode->count_crtcs = mode_res->count_crtcs;
xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width, mode_res->max_height);
- for (i = 0; i < mode_res->count_crtcs; i++)
+ for (i = 0; i < mode_res->count_crtcs; i++) {
if (!xf86IsEntityShared(pScrn->entityList[0]) ||
- (crtcs_needed && !(pRADEONEnt->assigned_crtcs & (1 << i))))
- crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, mode_res, i);
+ (crtcs_got < crtcs_needed &&
+ !(pRADEONEnt->assigned_crtcs & (1 << i))))
+ crtcs_got += drmmode_crtc_init(pScrn, drmmode, mode_res, i);
+ }
/* All ZaphodHeads outputs provided with matching crtcs? */
- if (xf86IsEntityShared(pScrn->entityList[0]) && (crtcs_needed > 0))
+ if (crtcs_got < crtcs_needed) {
+ if (crtcs_got == 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No ZaphodHeads CRTC available, needed %u\n",
+ crtcs_needed);
+ return FALSE;
+ }
+
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"%d ZaphodHeads crtcs unavailable. Some outputs will stay off.\n",
crtcs_needed);
+ }
/* workout clones */
drmmode_clones_init(pScrn, drmmode, mode_res);
@@ -2770,6 +2877,9 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
if (info->dri2.pKernelDRMVersion->version_minor < 4 || !info->drmmode_inited)
return;
+ for (c = 0; c < config->num_crtc; c++)
+ drmmode_crtc_scanout_free(config->crtc[c]);
+
if (pRADEONEnt->fd_wakeup_registered == serverGeneration &&
!--pRADEONEnt->fd_wakeup_ref) {
#if HAVE_NOTIFY_FD
@@ -2780,9 +2890,6 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
drm_wakeup_handler, pScrn);
#endif
}
-
- for (c = 0; c < config->num_crtc; c++)
- drmmode_crtc_scanout_free(config->crtc[c]->driver_private);
}
@@ -2892,15 +2999,6 @@ miPointerSpriteFuncRec drmmode_sprite_funcs = {
};
-void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- xf86CrtcPtr crtc = xf86_config->crtc[id];
- drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-
- drmmode_crtc->cursor_bo = bo;
-}
-
void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
@@ -3004,7 +3102,8 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
}
/* Validate leases on VT re-entry */
- drmmode_validate_leases(pScrn);
+ if (dixPrivateKeyRegistered(rrPrivKey))
+ drmmode_validate_leases(pScrn);
return TRUE;
}
@@ -3159,13 +3258,14 @@ restart_destroy:
/* find new output ids we don't have outputs for */
for (i = 0; i < mode_res->count_connectors; i++) {
- if (drmmode_find_output(pRADEONEnt->primary_scrn,
- mode_res->connectors[i],
- &num_dvi, &num_hdmi) ||
- (pRADEONEnt->secondary_scrn &&
- drmmode_find_output(pRADEONEnt->secondary_scrn,
- mode_res->connectors[i],
- &num_dvi, &num_hdmi)))
+ for (j = 0; j < pRADEONEnt->num_scrns; j++) {
+ if (drmmode_find_output(pRADEONEnt->scrn[j],
+ mode_res->connectors[i],
+ &num_dvi, &num_hdmi))
+ break;
+ }
+
+ if (j < pRADEONEnt->num_scrns)
continue;
if (drmmode_output_init(scrn, drmmode, mode_res, i, &num_dvi,
@@ -3176,7 +3276,7 @@ restart_destroy:
/* Check to see if a lessee has disappeared */
drmmode_validate_leases(scrn);
- if (changed && dixPrivateKeyRegistered(rrPrivKey)) {
+ if (changed) {
#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,2,0)
RRSetChanged(xf86ScrnToScreen(scrn));
#else
@@ -3276,6 +3376,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CrtcPtr crtc = NULL;
drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private;
+ int crtc_id;
uint32_t flip_flags = flip_sync == FLIP_ASYNC ? DRM_MODE_PAGE_FLIP_ASYNC : 0;
drmmode_flipdata_ptr flipdata;
Bool handle_deferred = FALSE;
@@ -3283,7 +3384,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
struct drmmode_fb *fb;
int i = 0;
- flipdata = calloc(1, sizeof(*flipdata) + config->num_crtc *
+ flipdata = calloc(1, sizeof(*flipdata) + drmmode_crtc->drmmode->count_crtcs *
sizeof(flipdata->fb[0]));
if (!flipdata) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -3315,6 +3416,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
for (i = 0; i < config->num_crtc; i++) {
crtc = config->crtc[i];
drmmode_crtc = crtc->driver_private;
+ crtc_id = drmmode_get_crtc_id(crtc);
if (!drmmode_crtc_can_flip(crtc) ||
(drmmode_crtc->tear_free && crtc != ref_crtc))
@@ -3325,7 +3427,8 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
drm_queue_seq = radeon_drm_queue_alloc(crtc, client, id,
flipdata,
drmmode_flip_handler,
- drmmode_flip_abort);
+ drmmode_flip_abort,
+ TRUE);
if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Allocating DRM queue event entry failed.\n");
@@ -3348,9 +3451,9 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
goto next;
}
- drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb[i],
+ drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb[crtc_id],
radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap));
- if (!flipdata->fb[i]) {
+ if (!flipdata->fb[crtc_id]) {
ErrorF("Failed to get FB for TearFree flip\n");
goto error;
}
@@ -3366,13 +3469,13 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
drmmode_crtc->scanout_update_pending = 0;
}
} else {
- drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb[i], fb);
+ drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb[crtc_id], fb);
}
if (crtc == ref_crtc) {
if (drmmode_page_flip_target_absolute(pRADEONEnt,
drmmode_crtc,
- flipdata->fb[i]->handle,
+ flipdata->fb[crtc_id]->handle,
flip_flags,
drm_queue_seq,
target_msc) != 0)
@@ -3380,7 +3483,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
} else {
if (drmmode_page_flip_target_relative(pRADEONEnt,
drmmode_crtc,
- flipdata->fb[i]->handle,
+ flipdata->fb[crtc_id]->handle,
flip_flags,
drm_queue_seq, 0) != 0)
goto flip_error;
@@ -3391,9 +3494,10 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
drmmode_crtc->ignore_damage = TRUE;
}
- next:
drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending,
- flipdata->fb[i]);
+ flipdata->fb[crtc_id]);
+
+ next:
drm_queue_seq = 0;
}
diff --git a/driver/xf86-video-ati/src/drmmode_display.h b/driver/xf86-video-ati/src/drmmode_display.h
index bc66eda65..2c2c3d57f 100644
--- a/driver/xf86-video-ati/src/drmmode_display.h
+++ b/driver/xf86-video-ati/src/drmmode_display.h
@@ -71,6 +71,12 @@ struct drmmode_fb {
uint32_t handle;
};
+enum drmmode_scanout_status {
+ DRMMODE_SCANOUT_OK,
+ DRMMODE_SCANOUT_FLIP_FAILED = 1u << 0,
+ DRMMODE_SCANOUT_VBLANK_FAILED = 1u << 1,
+};
+
struct drmmode_scanout {
struct radeon_buffer *bo;
PixmapPtr pixmap;
@@ -81,7 +87,15 @@ typedef struct {
drmmode_ptr drmmode;
drmModeCrtcPtr mode_crtc;
int hw_id;
- struct radeon_bo *cursor_bo;
+
+ CursorPtr cursor;
+ int cursor_x;
+ int cursor_y;
+ int cursor_xhot;
+ int cursor_yhot;
+ unsigned cursor_id;
+ struct radeon_bo *cursor_bo[2];
+
struct drmmode_scanout rotate;
struct drmmode_scanout scanout[2];
DamagePtr scanout_damage;
@@ -90,6 +104,7 @@ typedef struct {
unsigned scanout_id;
uintptr_t scanout_update_pending;
Bool tear_free;
+ enum drmmode_scanout_status scanout_status;
PixmapPtr prime_scanout_pixmap;
@@ -206,7 +221,6 @@ extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp);
extern void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
extern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr);
-extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo);
void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);
extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
Bool set_hw);
@@ -215,7 +229,7 @@ extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
extern void drmmode_crtc_scanout_destroy(drmmode_ptr drmmode,
struct drmmode_scanout *scanout);
-void drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc);
+void drmmode_crtc_scanout_free(xf86CrtcPtr crtc);
PixmapPtr drmmode_crtc_scanout_create(xf86CrtcPtr crtc,
struct drmmode_scanout *scanout,
int width, int height);
diff --git a/driver/xf86-video-ati/src/radeon.h b/driver/xf86-video-ati/src/radeon.h
index b1d5f5af4..74454c307 100644
--- a/driver/xf86-video-ati/src/radeon.h
+++ b/driver/xf86-video-ati/src/radeon.h
@@ -560,7 +560,7 @@ typedef struct {
/* Number of SW cursors currently visible on this screen */
int sprites_visible;
- Bool IsSecondary;
+ int instance_id;
Bool r600_shadow_fb;
void *fb_shadow;
@@ -572,7 +572,6 @@ typedef struct {
struct radeon_cs_manager *csm;
struct radeon_cs *cs;
- struct radeon_bo *cursor_bo[32];
uint64_t vram_size;
uint64_t gart_size;
drmmode_rec drmmode;
diff --git a/driver/xf86-video-ati/src/radeon_bo_helper.c b/driver/xf86-video-ati/src/radeon_bo_helper.c
index da5a484f2..8b3e57974 100644
--- a/driver/xf86-video-ati/src/radeon_bo_helper.c
+++ b/driver/xf86-video-ati/src/radeon_bo_helper.c
@@ -39,6 +39,8 @@ radeon_get_gbm_format(int depth, int bitsPerPixel)
case 8:
return GBM_FORMAT_R8;
#endif
+ case 15:
+ return GBM_FORMAT_ARGB1555;
case 16:
return GBM_FORMAT_RGB565;
case 32:
diff --git a/driver/xf86-video-ati/src/radeon_dri2.c b/driver/xf86-video-ati/src/radeon_dri2.c
index 4d12fc09a..a9f14e8d8 100644
--- a/driver/xf86-video-ati/src/radeon_dri2.c
+++ b/driver/xf86-video-ati/src/radeon_dri2.c
@@ -252,6 +252,12 @@ radeon_dri2_create_buffer2(ScreenPtr pScreen,
} else if (is_glamor_pixmap) {
pixmap = radeon_glamor_set_pixmap_bo(drawable, pixmap);
pixmap->refcnt++;
+
+ /* The copy operation from radeon_glamor_set_pixmap_bo needs to
+ * be flushed to the kernel driver before the client starts
+ * using the pixmap storage for direct rendering.
+ */
+ radeon_cs_flush_indirect(pScrn);
}
if (!radeon_get_flink_name(pRADEONEnt, pixmap, &buffers->name))
@@ -973,12 +979,18 @@ 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_seq)
+
+ if (event_info->drm_queue_seq) {
drmmode_crtc->drmmode->event_context.
vblank_handler(pRADEONEnt->fd, 0, 0, 0,
(void*)event_info->drm_queue_seq);
- else
+ drmmode_crtc->wait_flip_nesting_level++;
+ radeon_drm_queue_handle_deferred(crtc);
+
+ } else {
radeon_dri2_frame_event_handler(crtc, 0, 0, data);
+ }
+
return 0;
}
/*
@@ -989,13 +1001,18 @@ 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_seq)
+
+ if (event_info->drm_queue_seq) {
drmmode_crtc->drmmode->event_context.
vblank_handler(pRADEONEnt->fd, frame, drm_now / 1000000,
drm_now % 1000000,
(void*)event_info->drm_queue_seq);
- else
+ drmmode_crtc->wait_flip_nesting_level++;
+ radeon_drm_queue_handle_deferred(crtc);
+ } else {
radeon_dri2_frame_event_handler(crtc, frame, drm_now, data);
+ }
+
return 0;
}
@@ -1076,7 +1093,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
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);
+ radeon_dri2_frame_event_abort, FALSE);
if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Allocating DRM queue event entry failed.\n");
@@ -1215,7 +1232,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
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);
+ radeon_dri2_frame_event_abort, FALSE);
if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Allocating DRM queue entry failed.\n");
diff --git a/driver/xf86-video-ati/src/radeon_dri3.c b/driver/xf86-video-ati/src/radeon_dri3.c
index 7e89a2f0b..73353bf51 100644
--- a/driver/xf86-video-ati/src/radeon_dri3.c
+++ b/driver/xf86-video-ati/src/radeon_dri3.c
@@ -37,6 +37,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <gbm.h>
#include <errno.h>
#include <libgen.h>
@@ -212,20 +213,46 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen,
CARD16 *stride,
CARD32 *size)
{
- struct radeon_bo *bo;
+ struct radeon_buffer *bo;
int fd;
#ifdef USE_GLAMOR
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
RADEONInfoPtr info = RADEONPTR(scrn);
- if (info->use_glamor)
- return glamor_fd_from_pixmap(screen, pixmap, stride, size);
+ if (info->use_glamor) {
+ Bool need_flush = TRUE;
+ int ret = -1;
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,19,99,904,0)
+ struct gbm_bo *gbm_bo = glamor_gbm_bo_from_pixmap(screen, pixmap);
+
+ if (gbm_bo) {
+ ret = gbm_bo_get_fd(gbm_bo);
+ gbm_bo_destroy(gbm_bo);
+
+ if (ret >= 0)
+ need_flush = FALSE;
+ }
+#endif
+
+ if (ret < 0)
+ ret = glamor_fd_from_pixmap(screen, pixmap, stride, size);
+
+ /* glamor might have needed to reallocate the pixmap storage and
+ * copy the pixmap contents to the new storage. The copy
+ * operation needs to be flushed to the kernel driver before the
+ * client starts using the pixmap storage for direct rendering.
+ */
+ if (ret >= 0 && need_flush)
+ radeon_cs_flush_indirect(scrn);
+
+ return ret;
+ }
#endif
- bo = radeon_get_pixmap_bo(pixmap)->bo.radeon;
+ bo = radeon_get_pixmap_bo(pixmap);
if (!bo) {
exaMoveInPixmap(pixmap);
- bo = radeon_get_pixmap_bo(pixmap)->bo.radeon;
+ bo = radeon_get_pixmap_bo(pixmap);
if (!bo)
return -1;
}
@@ -233,11 +260,11 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen,
if (pixmap->devKind > UINT16_MAX)
return -1;
- if (radeon_gem_prime_share_bo(bo, &fd) < 0)
+ if (radeon_gem_prime_share_bo(bo->bo.radeon, &fd) < 0)
return -1;
*stride = pixmap->devKind;
- *size = bo->size;
+ *size = bo->bo.radeon->size;
return fd;
}
diff --git a/driver/xf86-video-ati/src/radeon_drm_queue.c b/driver/xf86-video-ati/src/radeon_drm_queue.c
index ea78e8e2b..fc0436058 100644
--- a/driver/xf86-video-ati/src/radeon_drm_queue.c
+++ b/driver/xf86-video-ati/src/radeon_drm_queue.c
@@ -30,6 +30,8 @@
#include "config.h"
#endif
+#include <errno.h>
+
#include <xorg-server.h>
#include <X11/Xdefs.h>
#include <list.h>
@@ -48,6 +50,7 @@ struct radeon_drm_queue_entry {
xf86CrtcPtr crtc;
radeon_drm_handler_proc handler;
radeon_drm_abort_proc abort;
+ Bool is_flip;
unsigned int frame;
};
@@ -55,6 +58,7 @@ static int radeon_drm_queue_refcnt;
static struct xorg_list radeon_drm_queue;
static struct xorg_list radeon_drm_flip_signalled;
static struct xorg_list radeon_drm_vblank_signalled;
+static struct xorg_list radeon_drm_vblank_deferred;
static uintptr_t radeon_drm_queue_seq;
@@ -72,9 +76,22 @@ radeon_drm_queue_handle_one(struct radeon_drm_queue_entry *e)
free(e);
}
+/*
+ * Abort one queued DRM entry, removing it
+ * from the list, calling the abort function and
+ * freeing the memory
+ */
static void
-radeon_drm_queue_handler(struct xorg_list *signalled, unsigned int frame,
- unsigned int sec, unsigned int usec, void *user_ptr)
+radeon_drm_abort_one(struct radeon_drm_queue_entry *e)
+{
+ xorg_list_del(&e->list);
+ e->abort(e->crtc, e->data);
+ free(e);
+}
+
+static void
+radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec,
+ unsigned int usec, void *user_ptr)
{
uintptr_t seq = (uintptr_t)user_ptr;
struct radeon_drm_queue_entry *e, *tmp;
@@ -82,39 +99,44 @@ radeon_drm_queue_handler(struct xorg_list *signalled, unsigned int frame,
xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) {
if (e->seq == seq) {
if (!e->handler) {
- radeon_drm_queue_handle_one(e);
+ radeon_drm_abort_one(e);
break;
}
xorg_list_del(&e->list);
e->usec = (uint64_t)sec * 1000000 + usec;
e->frame = frame;
- xorg_list_append(&e->list, signalled);
+ xorg_list_append(&e->list, e->is_flip ?
+ &radeon_drm_flip_signalled :
+ &radeon_drm_vblank_signalled);
break;
}
}
}
/*
- * Signal a DRM page flip event
+ * Handle signalled vblank events. If we're waiting for a flip event,
+ * put events for that CRTC in the vblank_deferred list.
*/
static void
-radeon_drm_page_flip_handler(int fd, unsigned int frame, unsigned int sec,
- unsigned int usec, void *user_ptr)
+radeon_drm_handle_vblank_signalled(void)
{
- radeon_drm_queue_handler(&radeon_drm_flip_signalled, frame, sec, usec,
- user_ptr);
-}
+ drmmode_crtc_private_ptr drmmode_crtc;
+ struct radeon_drm_queue_entry *e;
-/*
- * Signal a DRM vblank event
- */
-static void
-radeon_drm_vblank_handler(int fd, unsigned int frame, unsigned int sec,
- unsigned int usec, void *user_ptr)
-{
- radeon_drm_queue_handler(&radeon_drm_vblank_signalled, frame, sec, usec,
- user_ptr);
+ while (!xorg_list_is_empty(&radeon_drm_vblank_signalled)) {
+ e = xorg_list_first_entry(&radeon_drm_vblank_signalled,
+ struct radeon_drm_queue_entry, list);
+ drmmode_crtc = e->crtc->driver_private;
+
+ if (drmmode_crtc->wait_flip_nesting_level == 0) {
+ radeon_drm_queue_handle_one(e);
+ continue;
+ }
+
+ xorg_list_del(&e->list);
+ xorg_list_append(&e->list, &radeon_drm_vblank_deferred);
+ }
}
/*
@@ -133,12 +155,18 @@ radeon_drm_queue_handle_deferred(xf86CrtcPtr crtc)
--drmmode_crtc->wait_flip_nesting_level > 0)
return;
- xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_signalled, list) {
- drmmode_crtc_private_ptr drmmode_crtc = e->crtc->driver_private;
+ /* Put previously deferred vblank events for this CRTC back in the
+ * signalled queue
+ */
+ xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_deferred, list) {
+ if (e->crtc != crtc)
+ continue;
- if (drmmode_crtc->wait_flip_nesting_level == 0)
- radeon_drm_queue_handle_one(e);
+ xorg_list_del(&e->list);
+ xorg_list_append(&e->list, &radeon_drm_vblank_signalled);
}
+
+ radeon_drm_handle_vblank_signalled();
}
/*
@@ -149,7 +177,8 @@ uintptr_t
radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client,
uint64_t id, void *data,
radeon_drm_handler_proc handler,
- radeon_drm_abort_proc abort)
+ radeon_drm_abort_proc abort,
+ Bool is_flip)
{
struct radeon_drm_queue_entry *e;
@@ -167,6 +196,7 @@ radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client,
e->data = data;
e->handler = handler;
e->abort = abort;
+ e->is_flip = is_flip;
xorg_list_append(&e->list, &radeon_drm_queue);
@@ -174,19 +204,6 @@ radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client,
}
/*
- * Abort one queued DRM entry, removing it
- * from the list, calling the abort function and
- * freeing the memory
- */
-static void
-radeon_drm_abort_one(struct radeon_drm_queue_entry *e)
-{
- xorg_list_del(&e->list);
- e->abort(e->crtc, e->data);
- free(e);
-}
-
-/*
* Abort drm queue entries for a client
*
* NOTE: This keeps the entries in the list until the DRM event arrives,
@@ -222,6 +239,13 @@ radeon_drm_abort_entry(uintptr_t seq)
}
}
+ xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_deferred, list) {
+ if (e->seq == seq) {
+ radeon_drm_abort_one(e);
+ return;
+ }
+ }
+
xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) {
if (e->seq == seq) {
radeon_drm_abort_one(e);
@@ -252,10 +276,23 @@ radeon_drm_abort_id(uint64_t id)
int
radeon_drm_handle_event(int fd, drmEventContext *event_context)
{
- struct radeon_drm_queue_entry *e, *tmp;
+ struct radeon_drm_queue_entry *e;
int r;
- r = drmHandleEvent(fd, event_context);
+ /* Retry drmHandleEvent if it was interrupted by a signal in read() */
+ do {
+ r = drmHandleEvent(fd, event_context);
+ } while (r < 0 && (errno == EINTR || errno == EAGAIN));
+
+ if (r < 0) {
+ static Bool printed;
+
+ if (!printed) {
+ ErrorF("%s: drmHandleEvent returned %d, errno=%d (%s)\n",
+ __func__, r, errno, strerror(errno));
+ printed = TRUE;
+ }
+ }
while (!xorg_list_is_empty(&radeon_drm_flip_signalled)) {
e = xorg_list_first_entry(&radeon_drm_flip_signalled,
@@ -263,12 +300,7 @@ radeon_drm_handle_event(int fd, drmEventContext *event_context)
radeon_drm_queue_handle_one(e);
}
- xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_signalled, list) {
- drmmode_crtc_private_ptr drmmode_crtc = e->crtc->driver_private;
-
- if (drmmode_crtc->wait_flip_nesting_level == 0)
- radeon_drm_queue_handle_one(e);
- }
+ radeon_drm_handle_vblank_signalled();
return r;
}
@@ -293,7 +325,7 @@ void radeon_drm_wait_pending_flip(xf86CrtcPtr crtc)
while (drmmode_crtc->flip_pending
&& radeon_drm_handle_event(pRADEONEnt->fd,
- &drmmode_crtc->drmmode->event_context) > 0);
+ &drmmode_crtc->drmmode->event_context) >= 0);
}
/*
@@ -306,8 +338,8 @@ radeon_drm_queue_init(ScrnInfoPtr scrn)
drmmode_ptr drmmode = &info->drmmode;
drmmode->event_context.version = 2;
- drmmode->event_context.vblank_handler = radeon_drm_vblank_handler;
- drmmode->event_context.page_flip_handler = radeon_drm_page_flip_handler;
+ drmmode->event_context.vblank_handler = radeon_drm_queue_handler;
+ drmmode->event_context.page_flip_handler = radeon_drm_queue_handler;
if (radeon_drm_queue_refcnt++)
return;
@@ -315,6 +347,7 @@ radeon_drm_queue_init(ScrnInfoPtr scrn)
xorg_list_init(&radeon_drm_queue);
xorg_list_init(&radeon_drm_flip_signalled);
xorg_list_init(&radeon_drm_vblank_signalled);
+ xorg_list_init(&radeon_drm_vblank_deferred);
}
/*
diff --git a/driver/xf86-video-ati/src/radeon_drm_queue.h b/driver/xf86-video-ati/src/radeon_drm_queue.h
index 334c4ca63..19d42e930 100644
--- a/driver/xf86-video-ati/src/radeon_drm_queue.h
+++ b/driver/xf86-video-ati/src/radeon_drm_queue.h
@@ -44,7 +44,8 @@ void radeon_drm_queue_handle_deferred(xf86CrtcPtr crtc);
uintptr_t radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client,
uint64_t id, void *data,
radeon_drm_handler_proc handler,
- radeon_drm_abort_proc abort);
+ radeon_drm_abort_proc abort,
+ Bool is_flip);
void radeon_drm_abort_client(ClientPtr client);
void radeon_drm_abort_entry(uintptr_t seq);
void radeon_drm_abort_id(uint64_t id);
diff --git a/driver/xf86-video-ati/src/radeon_glamor.c b/driver/xf86-video-ati/src/radeon_glamor.c
index b0da8537f..eae351fbf 100644
--- a/driver/xf86-video-ati/src/radeon_glamor.c
+++ b/driver/xf86-video-ati/src/radeon_glamor.c
@@ -109,9 +109,14 @@ radeon_glamor_pre_init(ScrnInfoPtr scrn)
"glamor may not work (well) with GPUs < RV515.\n");
}
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,20,99,0,0)
if (scrn->depth < 24) {
+#else
+ if (scrn->depth < 15) {
+#endif
xf86DrvMsg(scrn->scrnIndex, s ? X_ERROR : X_WARNING,
- "glamor requires depth >= 24, disabling.\n");
+ "Depth %d not supported with glamor, disabling\n",
+ scrn->depth);
return FALSE;
}
@@ -233,7 +238,7 @@ radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
if (info->shadow_primary) {
if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP)
return fbCreatePixmap(screen, w, h, depth, usage);
- } else {
+ } else if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP) {
pixmap = glamor_create_pixmap(screen, w, h, depth, usage);
if (pixmap)
return pixmap;
diff --git a/driver/xf86-video-ati/src/radeon_kms.c b/driver/xf86-video-ati/src/radeon_kms.c
index ae69f3353..ff4f8dcf6 100644
--- a/driver/xf86-video-ati/src/radeon_kms.c
+++ b/driver/xf86-video-ati/src/radeon_kms.c
@@ -202,6 +202,10 @@ static void RADEONFreeRec(ScrnInfoPtr pScrn)
if (!pScrn)
return;
+ pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
+ pPriv = xf86GetEntityPrivate(pEnt->index, gRADEONEntityIndex);
+ pRADEONEnt = pPriv->ptr;
+
info = RADEONPTR(pScrn);
if (info) {
if (info->fbcon_pixmap)
@@ -217,15 +221,12 @@ static void RADEONFreeRec(ScrnInfoPtr pScrn)
gbm_device_destroy(info->gbm);
#endif
- pEnt = info->pEnt;
+ pRADEONEnt->scrn[info->instance_id] = NULL;
+ pRADEONEnt->num_scrns--;
free(pScrn->driverPrivate);
pScrn->driverPrivate = NULL;
- } else {
- pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
}
- pPriv = xf86GetEntityPrivate(pEnt->index, gRADEONEntityIndex);
- pRADEONEnt = pPriv->ptr;
if (pRADEONEnt->fd > 0) {
DevUnion *pPriv;
RADEONEntPtr pRADEONEnt;
@@ -348,13 +349,13 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
RROutputChanged(rrScrPriv->primaryOutput, FALSE);
rrScrPriv->layoutChanged = TRUE;
}
+
+ drmmode_uevent_init(pScrn, &info->drmmode);
}
if (!drmmode_set_desired_modes(pScrn, &info->drmmode, pScreen->isGPU))
return FALSE;
- drmmode_uevent_init(pScrn, &info->drmmode);
-
if (info->r600_shadow_fb) {
pixmap = pScreen->GetScreenPixmap(pScreen);
@@ -525,10 +526,14 @@ radeon_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data)
{
RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ struct drmmode_fb *fb = event_data;
drmmode_crtc->scanout_update_pending = 0;
- drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending,
- NULL);
+
+ if (drmmode_crtc->flip_pending == fb) {
+ drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending,
+ NULL);
+ }
}
static void
@@ -537,9 +542,9 @@ radeon_scanout_flip_handler(xf86CrtcPtr crtc, uint32_t msc, uint64_t usec,
{
RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ struct drmmode_fb *fb = event_data;
- drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb,
- drmmode_crtc->flip_pending);
+ drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, fb);
radeon_scanout_flip_abort(crtc, event_data);
}
@@ -751,6 +756,7 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
{
ScreenPtr screen = dirty->slave_dst->drawable.pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
xf86CrtcPtr xf86_crtc = radeon_prime_dirty_to_crtc(dirty);
drmmode_crtc_private_ptr drmmode_crtc;
uintptr_t drm_queue_seq;
@@ -768,23 +774,45 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
RADEON_DRM_QUEUE_CLIENT_DEFAULT,
RADEON_DRM_QUEUE_ID_DEFAULT, NULL,
radeon_prime_scanout_update_handler,
- radeon_prime_scanout_update_abort);
+ radeon_prime_scanout_update_abort,
+ FALSE);
if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"radeon_drm_queue_alloc failed for PRIME update\n");
+ radeon_prime_scanout_update_handler(xf86_crtc, 0, 0, NULL);
return;
}
+ drmmode_crtc->scanout_update_pending = drm_queue_seq;
+
if (!drmmode_wait_vblank(xf86_crtc, DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT,
1, drm_queue_seq, NULL, NULL)) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "drmmode_wait_vblank failed for PRIME update: %s\n",
- strerror(errno));
- radeon_drm_abort_entry(drm_queue_seq);
+ if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_VBLANK_FAILED)) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "drmmode_wait_vblank failed for PRIME update: %s\n",
+ strerror(errno));
+ drmmode_crtc->scanout_status |= DRMMODE_SCANOUT_VBLANK_FAILED;
+ }
+
+ drmmode_crtc->drmmode->event_context.vblank_handler(pRADEONEnt->fd,
+ 0, 0, 0,
+ (void*)drm_queue_seq);
+ drmmode_crtc->wait_flip_nesting_level++;
+ radeon_drm_queue_handle_deferred(xf86_crtc);
return;
}
- drmmode_crtc->scanout_update_pending = drm_queue_seq;
+ if (drmmode_crtc->scanout_status ==
+ (DRMMODE_SCANOUT_FLIP_FAILED | DRMMODE_SCANOUT_VBLANK_FAILED)) {
+ /* The page flip and vblank ioctls failed before, but the vblank
+ * ioctl is working again, so we can try re-enabling TearFree
+ */
+ xf86_crtc->funcs->set_mode_major(xf86_crtc, &xf86_crtc->mode,
+ xf86_crtc->rotation,
+ xf86_crtc->x, xf86_crtc->y);
+ }
+
+ drmmode_crtc->scanout_status &= ~DRMMODE_SCANOUT_VBLANK_FAILED;
}
static void
@@ -797,52 +825,61 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent)
drmmode_crtc_private_ptr drmmode_crtc;
uintptr_t drm_queue_seq;
unsigned scanout_id;
+ struct drmmode_fb *fb;
if (!crtc || !crtc->enabled)
return;
drmmode_crtc = crtc->driver_private;
+ scanout_id = drmmode_crtc->scanout_id ^ 1;
if (drmmode_crtc->scanout_update_pending ||
- !drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap ||
+ !drmmode_crtc->scanout[scanout_id].pixmap ||
drmmode_crtc->dpms_mode != DPMSModeOn)
return;
- scanout_id = drmmode_crtc->scanout_id ^ 1;
if (!radeon_prime_scanout_do_update(crtc, scanout_id))
return;
+ fb = radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap);
+ if (!fb) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "Failed to get FB for PRIME flip.\n");
+ return;
+ }
+
drm_queue_seq = radeon_drm_queue_alloc(crtc,
RADEON_DRM_QUEUE_CLIENT_DEFAULT,
- RADEON_DRM_QUEUE_ID_DEFAULT,
- NULL,
+ RADEON_DRM_QUEUE_ID_DEFAULT, fb,
radeon_scanout_flip_handler,
- radeon_scanout_flip_abort);
+ radeon_scanout_flip_abort, TRUE);
if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Allocating DRM event queue entry failed for PRIME flip.\n");
return;
}
- drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending,
- radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap));
- if (!drmmode_crtc->flip_pending) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "Failed to get FB for PRIME flip.\n");
+ if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc,
+ fb->handle, 0, drm_queue_seq, 1)
+ != 0) {
+ if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED)) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "flip queue failed in %s: %s, TearFree inactive\n",
+ __func__, strerror(errno));
+ drmmode_crtc->scanout_status |= DRMMODE_SCANOUT_FLIP_FAILED;
+ }
+
radeon_drm_abort_entry(drm_queue_seq);
return;
}
- if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc,
- drmmode_crtc->flip_pending->handle,
- 0, drm_queue_seq, 0) != 0) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n",
- __func__, strerror(errno));
- radeon_drm_abort_entry(drm_queue_seq);
- return;
+ if (drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED) {
+ xf86DrvMsg(scrn->scrnIndex, X_INFO, "TearFree active again\n");
+ drmmode_crtc->scanout_status &= ~DRMMODE_SCANOUT_FLIP_FAILED;
}
drmmode_crtc->scanout_id = scanout_id;
drmmode_crtc->scanout_update_pending = drm_queue_seq;
+ drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, fb);
}
static void
@@ -1020,8 +1057,9 @@ static void
radeon_scanout_update(xf86CrtcPtr xf86_crtc)
{
drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
+ ScrnInfoPtr scrn = xf86_crtc->scrn;
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
uintptr_t drm_queue_seq;
- ScrnInfoPtr scrn;
DamagePtr pDamage;
RegionPtr pRegion;
BoxRec extents;
@@ -1046,29 +1084,50 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc)
return;
}
- scrn = xf86_crtc->scrn;
drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc,
RADEON_DRM_QUEUE_CLIENT_DEFAULT,
RADEON_DRM_QUEUE_ID_DEFAULT,
drmmode_crtc,
radeon_scanout_update_handler,
- radeon_scanout_update_abort);
+ radeon_scanout_update_abort,
+ FALSE);
if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"radeon_drm_queue_alloc failed for scanout update\n");
+ radeon_scanout_update_handler(xf86_crtc, 0, 0, drmmode_crtc);
return;
}
+ drmmode_crtc->scanout_update_pending = drm_queue_seq;
+
if (!drmmode_wait_vblank(xf86_crtc, DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT,
1, drm_queue_seq, NULL, NULL)) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "drmmode_wait_vblank failed for scanout update: %s\n",
- strerror(errno));
- radeon_drm_abort_entry(drm_queue_seq);
+ if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_VBLANK_FAILED)) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "drmmode_wait_vblank failed for scanout update: %s\n",
+ strerror(errno));
+ drmmode_crtc->scanout_status |= DRMMODE_SCANOUT_VBLANK_FAILED;
+ }
+
+ drmmode_crtc->drmmode->event_context.vblank_handler(pRADEONEnt->fd,
+ 0, 0, 0,
+ (void*)drm_queue_seq);
+ drmmode_crtc->wait_flip_nesting_level++;
+ radeon_drm_queue_handle_deferred(xf86_crtc);
return;
}
- drmmode_crtc->scanout_update_pending = drm_queue_seq;
+ if (drmmode_crtc->scanout_status ==
+ (DRMMODE_SCANOUT_FLIP_FAILED | DRMMODE_SCANOUT_VBLANK_FAILED)) {
+ /* The page flip and vblank ioctls failed before, but the vblank
+ * ioctl is working again, so we can try re-enabling TearFree
+ */
+ xf86_crtc->funcs->set_mode_major(xf86_crtc, &xf86_crtc->mode,
+ xf86_crtc->rotation,
+ xf86_crtc->x, xf86_crtc->y);
+ }
+
+ drmmode_crtc->scanout_status &= ~DRMMODE_SCANOUT_VBLANK_FAILED;
}
static void
@@ -1081,6 +1140,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info,
RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
uintptr_t drm_queue_seq;
unsigned scanout_id;
+ struct drmmode_fb *fb;
if (drmmode_crtc->scanout_update_pending ||
drmmode_crtc->flip_pending ||
@@ -1096,33 +1156,34 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info,
radeon_cs_flush_indirect(scrn);
RegionEmpty(region);
+ fb = radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap);
+ if (!fb) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "Failed to get FB for scanout flip.\n");
+ return;
+ }
+
drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc,
RADEON_DRM_QUEUE_CLIENT_DEFAULT,
- RADEON_DRM_QUEUE_ID_DEFAULT,
- NULL,
+ RADEON_DRM_QUEUE_ID_DEFAULT, fb,
radeon_scanout_flip_handler,
- radeon_scanout_flip_abort);
+ radeon_scanout_flip_abort, TRUE);
if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Allocating DRM event queue entry failed.\n");
return;
}
- drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending,
- radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap));
- if (!drmmode_crtc->flip_pending) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "Failed to get FB for scanout flip.\n");
- radeon_drm_abort_entry(drm_queue_seq);
- return;
- }
-
if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc,
- drmmode_crtc->flip_pending->handle,
- 0, drm_queue_seq, 0) != 0) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s, "
- "TearFree inactive until next modeset\n",
- __func__, strerror(errno));
+ fb->handle, 0, drm_queue_seq, 1)
+ != 0) {
+ if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED)) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "flip queue failed in %s: %s, TearFree inactive\n",
+ __func__, strerror(errno));
+ drmmode_crtc->scanout_status |= DRMMODE_SCANOUT_FLIP_FAILED;
+ }
+
radeon_drm_abort_entry(drm_queue_seq);
RegionCopy(DamageRegion(drmmode_crtc->scanout_damage),
&drmmode_crtc->scanout_last_region);
@@ -1134,8 +1195,14 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info,
return;
}
+ if (drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED) {
+ xf86DrvMsg(scrn->scrnIndex, X_INFO, "TearFree active again\n");
+ drmmode_crtc->scanout_status &= ~DRMMODE_SCANOUT_FLIP_FAILED;
+ }
+
drmmode_crtc->scanout_id = scanout_id;
drmmode_crtc->scanout_update_pending = drm_queue_seq;
+ drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, fb);
}
static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
@@ -1689,7 +1756,6 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
RADEONInfoPtr info;
RADEONEntPtr pRADEONEnt;
MessageType from;
- DevUnion* pPriv;
Gamma zeros = { 0.0, 0.0, 0.0 };
uint32_t tiling = 0;
int cpp;
@@ -1700,10 +1766,23 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"RADEONPreInit_KMS\n");
if (pScrn->numEntities != 1) return FALSE;
+
+ pRADEONEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ getRADEONEntityIndex())->ptr;
+ if (pRADEONEnt->num_scrns == ARRAY_SIZE(pRADEONEnt->scrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Only up to %u Zaphod instances supported\n",
+ (unsigned)ARRAY_SIZE(pRADEONEnt->scrn));
+ return FALSE;
+ }
+
if (!RADEONGetRec(pScrn)) return FALSE;
info = RADEONPTR(pScrn);
- info->IsSecondary = FALSE;
+
+ info->instance_id = pRADEONEnt->num_scrns++;
+ pRADEONEnt->scrn[info->instance_id] = pScrn;
+
info->pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
if (info->pEnt->location.type != BUS_PCI
#ifdef XSERVER_PLATFORM_BUS
@@ -1712,27 +1791,11 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
)
return FALSE;
- pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
- getRADEONEntityIndex());
- pRADEONEnt = pPriv->ptr;
-
- if(xf86IsEntityShared(pScrn->entityList[0]))
- {
- if(xf86IsPrimInitDone(pScrn->entityList[0]))
- {
- info->IsSecondary = TRUE;
- }
- else
- {
- xf86SetPrimInitDone(pScrn->entityList[0]);
- }
+ if (xf86IsEntityShared(pScrn->entityList[0]) &&
+ info->instance_id == 0) {
+ xf86SetPrimInitDone(pScrn->entityList[0]);
}
- if (info->IsSecondary)
- pRADEONEnt->secondary_scrn = pScrn;
- else
- pRADEONEnt->primary_scrn = pScrn;
-
info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
pScrn->monitor = pScrn->confScreen->monitor;
@@ -2614,7 +2677,7 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn)
pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap,
None, pRADEONEnt);
} else {
- drmmode_crtc_scanout_free(drmmode_crtc);
+ drmmode_crtc_scanout_free(crtc);
}
}
}
@@ -2694,28 +2757,29 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
{
int cursor_size;
- int c;
+ int c, i;
cursor_size = info->cursor_w * info->cursor_h * 4;
cursor_size = RADEON_ALIGN(cursor_size, RADEON_GPU_PAGE_SIZE);
for (c = 0; c < xf86_config->num_crtc; c++) {
- /* cursor objects */
- if (!info->cursor_bo[c]) {
- info->cursor_bo[c] = radeon_bo_open(info->bufmgr, 0,
- cursor_size, 0,
- RADEON_GEM_DOMAIN_VRAM, 0);
- if (!info->cursor_bo[c]) {
- ErrorF("Failed to allocate cursor buffer memory\n");
- return FALSE;
- }
-
- if (radeon_bo_map(info->cursor_bo[c], 1)) {
- ErrorF("Failed to map cursor buffer memory\n");
- }
-
- drmmode_set_cursor(pScrn, &info->drmmode, c, info->cursor_bo[c]);
- }
- }
+ drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[c]->driver_private;
+
+ for (i = 0; i < 2; i++) {
+ if (!drmmode_crtc->cursor_bo[i]) {
+ drmmode_crtc->cursor_bo[i] =
+ radeon_bo_open(info->bufmgr, 0, cursor_size, 0,
+ RADEON_GEM_DOMAIN_VRAM, 0);
+
+ if (!(drmmode_crtc->cursor_bo[i])) {
+ ErrorF("Failed to allocate cursor buffer memory\n");
+ return FALSE;
+ }
+
+ if (radeon_bo_map(drmmode_crtc->cursor_bo[i], 1))
+ ErrorF("Failed to map cursor buffer memory\n");
+ }
+ }
+ }
}
if (!info->front_buffer) {
@@ -2779,7 +2843,9 @@ void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size)
int c;
for (c = 0; c < xf86_config->num_crtc; c++) {
- if (info->cursor_bo[c])
+ drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[c]->driver_private;
+
+ if (drmmode_crtc->cursor_bo[0])
new_fb_size += (64 * 4 * 64);
}
diff --git a/driver/xf86-video-ati/src/radeon_present.c b/driver/xf86-video-ati/src/radeon_present.c
index d0a0c68ca..38a9a6b79 100644
--- a/driver/xf86-video-ati/src/radeon_present.c
+++ b/driver/xf86-video-ati/src/radeon_present.c
@@ -157,7 +157,8 @@ radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
RADEON_DRM_QUEUE_CLIENT_DEFAULT,
event_id, event,
radeon_present_vblank_handler,
- radeon_present_vblank_abort);
+ radeon_present_vblank_abort,
+ FALSE);
if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
free(event);
return BadAlloc;
@@ -255,7 +256,7 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
ScrnInfoPtr scrn = xf86_crtc->scrn;
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
RADEONInfoPtr info = RADEONPTR(scrn);
- PixmapPtr screen_pixmap;
+ PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
int num_crtcs_on;
int i;
@@ -271,10 +272,14 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
if (info->drmmode.dri2_flipping)
return FALSE;
+#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(1, 20, 99, 1, 0)
+ if (pixmap->devKind != screen_pixmap->devKind)
+ return FALSE;
+#endif
+
/* The kernel driver doesn't handle flipping between BOs with different
* tiling parameters correctly yet
*/
- screen_pixmap = screen->GetScreenPixmap(screen);
if (radeon_present_get_pixmap_tiling_flags(info, pixmap) !=
radeon_present_get_pixmap_tiling_flags(info, screen_pixmap))
return FALSE;
diff --git a/driver/xf86-video-ati/src/radeon_probe.h b/driver/xf86-video-ati/src/radeon_probe.h
index be82f9aea..7cb29b916 100644
--- a/driver/xf86-video-ati/src/radeon_probe.h
+++ b/driver/xf86-video-ati/src/radeon_probe.h
@@ -140,8 +140,8 @@ typedef struct
unsigned long fd_wakeup_registered; /* server generation for which fd has been registered for wakeup handling */
int fd_wakeup_ref;
unsigned int assigned_crtcs;
- ScrnInfoPtr primary_scrn;
- ScrnInfoPtr secondary_scrn;
+ unsigned int num_scrns;
+ ScrnInfoPtr scrn[6];
#ifdef XSERVER_PLATFORM_BUS
struct xf86_platform_device *platform_dev;
#endif