xf86-video-amdgpu: Branch 'master' - 3 commits
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Dec 13 11:21:12 UTC 2018
src/amdgpu_kms.c | 96 +++++++++++++++++++++++++++++++++++++++++---------
src/drmmode_display.c | 16 +++++---
src/drmmode_display.h | 7 +++
3 files changed, 97 insertions(+), 22 deletions(-)
New commits:
commit bcfa6c258fdf41a9928f8a3c78fc528d0fafee25
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Wed Nov 21 18:32:04 2018 +0100
Automatically try re-enabling TearFree after a flip failed
Specifically, after both the page flip and vblank ioctls failed, but
then the vblank ioctl started working again. This can happen
intermittently e.g. when hotplugging a DP display. Previously, TearFree
would stay disabled in that case until a modeset was triggered somehow.
Bugzilla: https://bugs.freedesktop.org/103791
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 44a3c8a..506e5f7 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -748,15 +748,32 @@ amdgpu_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
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));
+ 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(pAMDGPUEnt->fd,
0, 0, 0,
(void*)drm_queue_seq);
drmmode_crtc->wait_flip_nesting_level++;
amdgpu_drm_queue_handle_deferred(xf86_crtc);
+ return;
+ }
+
+ 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
@@ -807,12 +824,22 @@ amdgpu_prime_scanout_flip(PixmapDirtyUpdatePtr ent)
if (drmmode_page_flip_target_relative(pAMDGPUEnt, 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));
+ 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;
+ }
+
amdgpu_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;
}
@@ -1029,15 +1056,32 @@ amdgpu_scanout_update(xf86CrtcPtr xf86_crtc)
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));
+ 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(pAMDGPUEnt->fd,
0, 0, 0,
(void*)drm_queue_seq);
drmmode_crtc->wait_flip_nesting_level++;
amdgpu_drm_queue_handle_deferred(xf86_crtc);
+ return;
+ }
+
+ 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
@@ -1089,9 +1133,13 @@ amdgpu_scanout_flip(ScreenPtr pScreen, AMDGPUInfoPtr info,
if (drmmode_page_flip_target_relative(pAMDGPUEnt, 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));
+ 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;
+ }
+
amdgpu_drm_abort_entry(drm_queue_seq);
RegionCopy(DamageRegion(drmmode_crtc->scanout_damage),
&drmmode_crtc->scanout_last_region);
@@ -1103,6 +1151,11 @@ amdgpu_scanout_flip(ScreenPtr pScreen, AMDGPUInfoPtr 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;
}
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index b2b16df..aab330c 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -91,6 +91,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 amdgpu_buffer *bo;
PixmapPtr pixmap;
@@ -110,6 +116,7 @@ typedef struct {
unsigned scanout_id;
uintptr_t scanout_update_pending;
Bool tear_free;
+ enum drmmode_scanout_status scanout_status;
Bool vrr_enabled;
PixmapPtr prime_scanout_pixmap;
commit 4e7a24ac5a64e402146953ec5850d13c05742116
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Wed Nov 21 17:54:18 2018 +0100
Cancel pending scanout update in drmmode_crtc_scanout_update
drmmode_crtc_scanout_update does the equivalent of a scanout update,
so no need to do it again. This might also avoid issues if there's a
pending scanout update at this point.
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index bd5eb5e..2a22777 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -790,11 +790,17 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode,
*fb = amdgpu_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap);
*x = *y = 0;
- amdgpu_scanout_do_update(crtc, scanout_id,
- screen->GetWindowPixmap(screen->root),
- extents);
- RegionEmpty(DamageRegion(drmmode_crtc->scanout_damage));
- amdgpu_glamor_finish(scrn);
+ if (amdgpu_scanout_do_update(crtc, scanout_id,
+ screen->GetWindowPixmap(screen->root),
+ extents)) {
+ RegionEmpty(DamageRegion(drmmode_crtc->scanout_damage));
+ amdgpu_glamor_finish(scrn);
+
+ if (!drmmode_crtc->flip_pending) {
+ amdgpu_drm_abort_entry(drmmode_crtc->
+ scanout_update_pending);
+ }
+ }
}
}
commit 500fadb16285146e91f62fce3a0ce1360ca684ba
Author: Michel Dänzer <michel.daenzer at amd.com>
Date: Wed Nov 21 12:42:22 2018 +0100
Perform scanout buffer update immediately if drmmode_wait_vblank fails
Otherwise the damaged screen contents may never be displayed in that
case.
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 92782de..44a3c8a 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -717,6 +717,7 @@ amdgpu_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
{
ScreenPtr screen = dirty->slave_dst->drawable.pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
xf86CrtcPtr xf86_crtc = amdgpu_prime_dirty_to_crtc(dirty);
drmmode_crtc_private_ptr drmmode_crtc;
uintptr_t drm_queue_seq;
@@ -739,19 +740,23 @@ amdgpu_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
if (drm_queue_seq == AMDGPU_DRM_QUEUE_ERROR) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"amdgpu_drm_queue_alloc failed for PRIME update\n");
+ amdgpu_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));
- amdgpu_drm_abort_entry(drm_queue_seq);
- return;
+ drmmode_crtc->drmmode->event_context.vblank_handler(pAMDGPUEnt->fd,
+ 0, 0, 0,
+ (void*)drm_queue_seq);
+ drmmode_crtc->wait_flip_nesting_level++;
+ amdgpu_drm_queue_handle_deferred(xf86_crtc);
}
-
- drmmode_crtc->scanout_update_pending = drm_queue_seq;
}
static void
@@ -979,8 +984,9 @@ static void
amdgpu_scanout_update(xf86CrtcPtr xf86_crtc)
{
drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
+ ScrnInfoPtr scrn = xf86_crtc->scrn;
+ AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
uintptr_t drm_queue_seq;
- ScrnInfoPtr scrn;
DamagePtr pDamage;
RegionPtr pRegion;
BoxRec extents;
@@ -1005,7 +1011,6 @@ amdgpu_scanout_update(xf86CrtcPtr xf86_crtc)
return;
}
- scrn = xf86_crtc->scrn;
drm_queue_seq = amdgpu_drm_queue_alloc(xf86_crtc,
AMDGPU_DRM_QUEUE_CLIENT_DEFAULT,
AMDGPU_DRM_QUEUE_ID_DEFAULT,
@@ -1016,19 +1021,23 @@ amdgpu_scanout_update(xf86CrtcPtr xf86_crtc)
if (drm_queue_seq == AMDGPU_DRM_QUEUE_ERROR) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"amdgpu_drm_queue_alloc failed for scanout update\n");
+ amdgpu_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));
- amdgpu_drm_abort_entry(drm_queue_seq);
- return;
+ drmmode_crtc->drmmode->event_context.vblank_handler(pAMDGPUEnt->fd,
+ 0, 0, 0,
+ (void*)drm_queue_seq);
+ drmmode_crtc->wait_flip_nesting_level++;
+ amdgpu_drm_queue_handle_deferred(xf86_crtc);
}
-
- drmmode_crtc->scanout_update_pending = drm_queue_seq;
}
static void
More information about the xorg-commit
mailing list