summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/amdgpu_dri2.c3
-rw-r--r--src/amdgpu_kms.c15
-rw-r--r--src/amdgpu_present.c6
-rw-r--r--src/amdgpu_probe.h1
-rw-r--r--src/drmmode_display.c39
-rw-r--r--src/drmmode_display.h3
6 files changed, 62 insertions, 5 deletions
diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index bd04256..b63d48c 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -563,7 +563,8 @@ amdgpu_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client,
AMDGPU_DRM_QUEUE_ID_DEFAULT, flip_info,
ref_crtc_hw_id,
amdgpu_dri2_flip_event_handler,
- amdgpu_dri2_flip_event_abort, FLIP_VSYNC)) {
+ amdgpu_dri2_flip_event_abort, FLIP_VSYNC,
+ target_msc - amdgpu_get_msc_delta(draw, crtc))) {
info->drmmode.dri2_flipping = TRUE;
return TRUE;
}
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 9ee48df..d1d86cd 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -487,6 +487,21 @@ amdgpu_scanout_flip(ScreenPtr pScreen, AMDGPUInfoPtr info,
}
pAMDGPUEnt = AMDGPUEntPriv(scrn);
+#ifdef DRM_MODE_PAGE_FLIP_TARGET_RELATIVE
+ if (pAMDGPUEnt->has_page_flip_target) {
+ if (drmModePageFlipTarget(pAMDGPUEnt->fd,
+ drmmode_crtc->mode_crtc->crtc_id,
+ drmmode_crtc->scanout[scanout_id].fb_id,
+ DRM_MODE_PAGE_FLIP_EVENT |
+ DRM_MODE_PAGE_FLIP_TARGET_RELATIVE,
+ (void*)drm_queue_seq, 0)) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "flip queue failed in %s: %s\n",
+ __func__, strerror(errno));
+ return;
+ }
+ } else
+#endif
if (drmModePageFlip(pAMDGPUEnt->fd, drmmode_crtc->mode_crtc->crtc_id,
drmmode_crtc->scanout[scanout_id].fb_id,
DRM_MODE_PAGE_FLIP_EVENT, (void*)drm_queue_seq)) {
diff --git a/src/amdgpu_present.c b/src/amdgpu_present.c
index edfccb1..51ce732 100644
--- a/src/amdgpu_present.c
+++ b/src/amdgpu_present.c
@@ -322,7 +322,8 @@ amdgpu_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc,
pixmap, event_id, event, crtc_id,
amdgpu_present_flip_event,
amdgpu_present_flip_abort,
- sync_flip ? FLIP_VSYNC : FLIP_ASYNC);
+ sync_flip ? FLIP_VSYNC : FLIP_ASYNC,
+ target_msc);
if (!ret)
xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present flip failed\n");
else
@@ -359,7 +360,8 @@ amdgpu_present_unflip(ScreenPtr screen, uint64_t event_id)
if (amdgpu_do_pageflip(scrn, AMDGPU_DRM_QUEUE_CLIENT_DEFAULT, pixmap,
event_id, event, -1, amdgpu_present_flip_event,
- amdgpu_present_flip_abort, FLIP_VSYNC))
+ amdgpu_present_flip_abort, FLIP_VSYNC,
+ 0))
return;
modeset:
diff --git a/src/amdgpu_probe.h b/src/amdgpu_probe.h
index 1e6b99e..8e09ffa 100644
--- a/src/amdgpu_probe.h
+++ b/src/amdgpu_probe.h
@@ -79,6 +79,7 @@ typedef struct {
typedef struct {
Bool HasCRTC2; /* All cards except original Radeon */
+ Bool has_page_flip_target;
amdgpu_device_handle pDev;
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index fdd5922..867d1b0 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -2067,6 +2067,17 @@ static void drm_wakeup_handler(pointer data, int err, pointer p)
}
#endif
+static void drmmode_probe_page_flip_target(AMDGPUEntPtr pAMDGPUEnt)
+{
+#ifdef DRM_CAP_PAGE_FLIP_TARGET
+ uint64_t cap_value;
+
+ pAMDGPUEnt->has_page_flip_target =
+ drmGetCap(pAMDGPUEnt->fd, DRM_CAP_PAGE_FLIP_TARGET,
+ &cap_value) == 0 && cap_value != 0;
+#endif
+}
+
Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
{
AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
@@ -2133,6 +2144,8 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
drmmode->event_context.vblank_handler = amdgpu_drm_queue_handler;
drmmode->event_context.page_flip_handler = amdgpu_drm_queue_handler;
+ drmmode_probe_page_flip_target(pAMDGPUEnt);
+
drmModeFreeResources(mode_res);
return TRUE;
}
@@ -2465,7 +2478,8 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
PixmapPtr new_front, uint64_t id, void *data,
int ref_crtc_hw_id, amdgpu_drm_handler_proc handler,
amdgpu_drm_abort_proc abort,
- enum drmmode_flip_sync flip_sync)
+ enum drmmode_flip_sync flip_sync,
+ uint32_t target_msc)
{
AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -2543,6 +2557,29 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
goto error;
}
+#ifdef DRM_MODE_PAGE_FLIP_TARGET
+ if (pAMDGPUEnt->has_page_flip_target) {
+ uint32_t target_flip_flags = flip_flags;
+
+ if (drmmode_crtc->hw_id == ref_crtc_hw_id)
+ target_flip_flags |= DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE;
+ else
+ target_flip_flags |= DRM_MODE_PAGE_FLIP_TARGET_RELATIVE;
+
+ if (drmModePageFlipTarget(pAMDGPUEnt->fd,
+ drmmode_crtc->mode_crtc->crtc_id,
+ drmmode->fb_id,
+ target_flip_flags,
+ (void*)drm_queue_seq,
+ drmmode_crtc->hw_id == ref_crtc_hw_id ?
+ target_msc : 0) != 0) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "flip queue failed: %s\n",
+ strerror(errno));
+ goto error;
+ }
+ } else
+#endif
if (drmModePageFlip(pAMDGPUEnt->fd, drmmode_crtc->mode_crtc->crtc_id,
drmmode->fb_id, flip_flags,
(void*)drm_queue_seq)) {
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 617f2bc..704fd76 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -152,7 +152,8 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
PixmapPtr new_front, uint64_t id, void *data,
int ref_crtc_hw_id, amdgpu_drm_handler_proc handler,
amdgpu_drm_abort_proc abort,
- enum drmmode_flip_sync flip_sync);
+ enum drmmode_flip_sync flip_sync,
+ uint32_t target_msc);
int drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc);
int drmmode_get_current_ust(int drm_fd, CARD64 * ust);