- U_01-* ... U_20-* : Include patches that haven't made it into the 7.7.1 release. This means almost all commits between xf86-video-ati-7.7.0 and 12d30eeb9711bd2b1609d6bbb74c4a1760596f72. Fixes (bsc#990066). OBS-URL: https://build.opensuse.org/request/show/438260 OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xf86-video-ati?expand=0&rev=51
137 lines
4.3 KiB
Diff
137 lines
4.3 KiB
Diff
From: Michel Dänzer <michel.daenzer@amd.com>
|
|
Date: Fri Nov 27 16:31:21 2015 +0900
|
|
Subject: [PATCH 13/20]Handle RandR 1.4 slave dirty updates via radeon_drm_queue
|
|
Patch-mainline: Upstream
|
|
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
|
Git-commit: ad0a0656dd0e74683e6d7789decba827aa29c221
|
|
References: bsc#990066
|
|
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
|
|
|
This reduces PCIe bandwidth usage and tearing.
|
|
|
|
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
|
---
|
|
src/radeon_kms.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
|
|
1 file changed, 90 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
|
index 53994c9..07ba362 100644
|
|
--- a/src/radeon_kms.c
|
|
+++ b/src/radeon_kms.c
|
|
@@ -383,9 +383,9 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
|
|
|
|
#ifdef RADEON_PIXMAP_SHARING
|
|
static void
|
|
-redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
|
|
+redisplay_dirty(PixmapDirtyUpdatePtr dirty)
|
|
{
|
|
- ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
|
|
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(dirty->src->drawable.pScreen);
|
|
RegionRec pixregion;
|
|
|
|
PixmapRegionInit(&pixregion, dirty->slave_dst);
|
|
@@ -399,6 +399,90 @@ redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
|
|
radeon_cs_flush_indirect(pScrn);
|
|
DamageRegionProcessPending(&dirty->slave_dst->drawable);
|
|
RegionUninit(&pixregion);
|
|
+
|
|
+ DamageEmpty(dirty->damage);
|
|
+}
|
|
+
|
|
+static void
|
|
+radeon_prime_scanout_update_abort(xf86CrtcPtr crtc, void *event_data)
|
|
+{
|
|
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
|
+
|
|
+ drmmode_crtc->scanout_update_pending = FALSE;
|
|
+}
|
|
+
|
|
+void
|
|
+radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
|
|
+ void *event_data)
|
|
+{
|
|
+ ScrnInfoPtr scrn = crtc->scrn;
|
|
+ ScreenPtr screen = scrn->pScreen;
|
|
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
|
+ PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap;
|
|
+ PixmapDirtyUpdatePtr dirty;
|
|
+
|
|
+ xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
|
|
+ if (dirty->src == scanoutpix &&
|
|
+ dirty->slave_dst == drmmode_crtc->scanout[0].pixmap) {
|
|
+ redisplay_dirty(dirty);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ drmmode_crtc->scanout_update_pending = FALSE;
|
|
+}
|
|
+
|
|
+static void
|
|
+radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
|
|
+{
|
|
+ ScreenPtr screen = dirty->slave_dst->drawable.pScreen;
|
|
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
|
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
|
|
+ xf86CrtcPtr xf86_crtc = NULL;
|
|
+ drmmode_crtc_private_ptr drmmode_crtc = NULL;
|
|
+ uintptr_t drm_queue_seq;
|
|
+ drmVBlank vbl;
|
|
+ int c;
|
|
+
|
|
+ /* Find the CRTC which is scanning out from this slave pixmap */
|
|
+ for (c = 0; c < xf86_config->num_crtc; c++) {
|
|
+ xf86_crtc = xf86_config->crtc[c];
|
|
+ drmmode_crtc = xf86_crtc->driver_private;
|
|
+ if (drmmode_crtc->scanout[0].pixmap == dirty->slave_dst)
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (c == xf86_config->num_crtc ||
|
|
+ !xf86_crtc->enabled ||
|
|
+ drmmode_crtc->scanout_update_pending ||
|
|
+ !drmmode_crtc->scanout[0].pixmap ||
|
|
+ drmmode_crtc->pending_dpms_mode != DPMSModeOn)
|
|
+ return;
|
|
+
|
|
+ drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc,
|
|
+ RADEON_DRM_QUEUE_CLIENT_DEFAULT,
|
|
+ RADEON_DRM_QUEUE_ID_DEFAULT, NULL,
|
|
+ radeon_prime_scanout_update_handler,
|
|
+ radeon_prime_scanout_update_abort);
|
|
+ if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
|
|
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
|
|
+ "radeon_drm_queue_alloc failed for PRIME update\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT;
|
|
+ vbl.request.type |= radeon_populate_vbl_request_type(xf86_crtc);
|
|
+ vbl.request.sequence = 1;
|
|
+ vbl.request.signal = drm_queue_seq;
|
|
+ if (drmWaitVBlank(RADEONPTR(scrn)->dri2.drm_fd, &vbl)) {
|
|
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
|
|
+ "drmWaitVBlank failed for PRIME update: %s\n",
|
|
+ strerror(errno));
|
|
+ radeon_drm_abort_entry(drm_queue_seq);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ drmmode_crtc->scanout_update_pending = TRUE;
|
|
}
|
|
|
|
static void
|
|
@@ -413,8 +497,10 @@ radeon_dirty_update(ScreenPtr screen)
|
|
xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
|
|
region = DamageRegion(ent->damage);
|
|
if (RegionNotEmpty(region)) {
|
|
- redisplay_dirty(screen, ent);
|
|
- DamageEmpty(ent->damage);
|
|
+ if (screen->isGPU)
|
|
+ radeon_prime_scanout_update(ent);
|
|
+ else
|
|
+ redisplay_dirty(ent);
|
|
}
|
|
}
|
|
}
|