Skip to content
Commits on Source (10)
......@@ -23,7 +23,7 @@
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([xf86-video-ati],
[19.0.1],
[19.1.0],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon],
[xf86-video-ati])
......
......@@ -309,6 +309,7 @@ struct radeon_pixmap {
struct radeon_buffer *bo;
struct drmmode_fb *fb;
Bool fb_failed;
uint32_t tiling_flags;
......@@ -877,22 +878,23 @@ static inline struct drmmode_fb*
radeon_pixmap_get_fb(PixmapPtr pix)
{
struct drmmode_fb **fb_ptr = radeon_pixmap_get_fb_ptr(pix);
if (!fb_ptr)
return NULL;
if (!*fb_ptr) {
uint32_t handle;
if (fb_ptr && *fb_ptr)
return *fb_ptr;
if (radeon_get_pixmap_handle(pix, &handle)) {
ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen);
RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
*fb_ptr = radeon_fb_create(scrn, pRADEONEnt->fd, pix->drawable.width,
if (!fb_ptr)
fb_ptr = radeon_pixmap_get_fb_ptr(pix);
*fb_ptr = radeon_fb_create(scrn, pRADEONEnt->fd,
pix->drawable.width,
pix->drawable.height, pix->devKind,
handle);
}
}
return *fb_ptr;
}
......
......@@ -509,18 +509,20 @@ static Bool radeon_dri2_get_crtc_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc)
}
static
xf86CrtcPtr radeon_dri2_drawable_crtc(DrawablePtr pDraw, Bool consider_disabled)
xf86CrtcPtr radeon_dri2_drawable_crtc(DrawablePtr pDraw)
{
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
xf86CrtcPtr crtc = radeon_pick_best_crtc(pScrn, consider_disabled,
xf86CrtcPtr crtc = radeon_pick_best_crtc(pScrn, TRUE,
pDraw->x, pDraw->x + pDraw->width,
pDraw->y, pDraw->y + pDraw->height);
if (crtc && pDraw->type == DRAWABLE_WINDOW) {
if (pDraw->type == DRAWABLE_WINDOW) {
struct dri2_window_priv *priv = get_dri2_window_priv((WindowPtr)pDraw);
if (priv->crtc && priv->crtc != crtc) {
if (!crtc) {
crtc = priv->crtc;
} else if (priv->crtc && priv->crtc != crtc) {
CARD64 ust, mscold, mscnew;
if (radeon_dri2_get_crtc_msc(priv->crtc, &ust, &mscold) &&
......@@ -926,7 +928,7 @@ CARD32 radeon_dri2_extrapolate_msc_delay(xf86CrtcPtr crtc, CARD64 *target_msc,
*/
static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
{
xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE);
xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw);
/* Drawable not displayed, make up a value */
if (!crtc) {
......@@ -1041,7 +1043,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
DRI2FrameEventPtr wait_info = NULL;
uintptr_t drm_queue_seq = 0;
xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE);
xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw);
uint32_t msc_delta;
uint32_t seq;
CARD64 current_msc;
......@@ -1156,6 +1158,9 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
out_complete:
if (wait_info)
radeon_dri2_deferred_event(NULL, 0, wait_info);
else
DRI2WaitMSCComplete(client, draw, 0, 0, 0);
return TRUE;
}
......@@ -1187,7 +1192,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
{
ScreenPtr screen = draw->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE);
xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw);
uint32_t msc_delta;
drmVBlankSeqType type;
uint32_t seq;
......
......@@ -220,29 +220,13 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen,
RADEONInfoPtr info = RADEONPTR(scrn);
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);
int ret = glamor_fd_from_pixmap(screen, pixmap, stride, size);
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.
/* Any pending drawing operations need to be flushed to the
* kernel driver before the client starts using the pixmap
* storage for direct rendering.
*/
if (ret >= 0 && need_flush)
if (ret >= 0)
radeon_cs_flush_indirect(scrn);
return ret;
......
......@@ -1917,19 +1917,15 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
if (!pScrn->is_gpu) {
if (info->dri2.pKernelDRMVersion->version_minor >= 8) {
Bool sw_cursor = xf86ReturnOptValBool(info->Options,
OPTION_SW_CURSOR, FALSE);
info->allowPageFlip = xf86ReturnOptValBool(info->Options,
OPTION_PAGE_FLIP, TRUE);
if (sw_cursor || info->shadow_primary) {
if (info->shadow_primary) {
xf86DrvMsg(pScrn->scrnIndex,
info->allowPageFlip ? X_WARNING : X_DEFAULT,
"KMS Pageflipping: disabled%s\n",
info->allowPageFlip ?
(sw_cursor ? " because of SWcursor" :
" because of ShadowPrimary") : "");
" because of ShadowPrimary" : "");
info->allowPageFlip = FALSE;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
......@@ -2606,16 +2602,25 @@ CARD32 cleanup_black_fb(OsTimerPtr timer, CARD32 now, pointer data)
}
static void
pixmap_unref_fb(void *value, XID id, void *cdata)
pixmap_unref_fb(PixmapPtr pixmap)
{
PixmapPtr pixmap = value;
RADEONEntPtr pRADEONEnt = cdata;
ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
struct drmmode_fb **fb_ptr = radeon_pixmap_get_fb_ptr(pixmap);
RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
if (fb_ptr)
drmmode_fb_reference(pRADEONEnt->fd, fb_ptr, NULL);
}
static void
client_pixmap_unref_fb(void *value, XID id, void *pScreen)
{
PixmapPtr pixmap = value;
if (pixmap->drawable.pScreen == pScreen)
pixmap_unref_fb(pixmap);
}
void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
......@@ -2633,6 +2638,12 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn)
unsigned w = 0, h = 0;
int i;
/* If we're called from CloseScreen, trying to clear the black
* scanout BO will likely crash and burn
*/
if (!pScreen->GCperDepth[0])
goto hide_cursors;
/* Compute maximum scanout dimensions of active CRTCs */
for (i = 0; i < xf86_config->num_crtc; i++) {
crtc = xf86_config->crtc[i];
......@@ -2671,11 +2682,9 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn)
if (pScrn->is_gpu) {
if (drmmode_crtc->scanout[0].pixmap)
pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap,
None, pRADEONEnt);
pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap);
if (drmmode_crtc->scanout[1].pixmap)
pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap,
None, pRADEONEnt);
pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap);
} else {
drmmode_crtc_scanout_free(crtc);
}
......@@ -2695,18 +2704,20 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn)
(!clients[i] || clients[i]->clientState != ClientStateRunning))
continue;
FindClientResourcesByType(clients[i], RT_PIXMAP, pixmap_unref_fb,
pRADEONEnt);
FindClientResourcesByType(clients[i], RT_PIXMAP,
client_pixmap_unref_fb, pScreen);
}
pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None, pRADEONEnt);
pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen));
} else {
memset(info->front_buffer->bo.radeon->ptr, 0,
pScrn->displayWidth * info->pixel_bytes * pScrn->virtualY);
}
if (pScreen->GCperDepth[0])
TimerSet(NULL, 0, 1000, cleanup_black_fb, pScreen);
hide_cursors:
xf86_hide_cursors (pScrn);
radeon_drop_drm_master(pScrn);
......
......@@ -254,6 +254,7 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
xf86CrtcPtr xf86_crtc = crtc->devPrivate;
ScreenPtr screen = window->drawable.pScreen;
ScrnInfoPtr scrn = xf86_crtc->scrn;
struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
RADEONInfoPtr info = RADEONPTR(scrn);
PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
......@@ -277,6 +278,23 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
return FALSE;
#endif
if (priv && priv->fb_failed)
return FALSE;
if (!radeon_pixmap_get_fb(pixmap)) {
if (!priv)
priv = radeon_get_pixmap_private(pixmap);
if (priv && !priv->fb_failed) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Cannot get FB for Present flip (may be "
"normal if using PRIME render offloading)\n");
priv->fb_failed = TRUE;
}
return FALSE;
}
/* The kernel driver doesn't handle flipping between BOs with different
* tiling parameters correctly yet
*/
......