Re: [PATCH 5/5] modesetting: Implement page flipping support for Present.

2015-05-04 Thread Mario Kleiner

On 04/28/2015 06:31 AM, Kenneth Graunke wrote:

On Tuesday, April 21, 2015 05:58:44 PM Kenneth Graunke wrote:

Based on code by Keith Packard, Eric Anholt, and Jason Ekstrand.

v2:
- Fix double free and flip_count underrun (caught by Mario Kleiner).
- Don't leak flip_vblank_event on the error_out path (Mario).
- Use the updated ms_flush_drm_events API (Mario, Ken).

v3: Hack around DPMS shenanigans.  If all monitors are DPMS off, then
 there is no active framebuffer; attempting to pageflip will hit the
 error_undo paths, causing us to drmModeRmFB with no framebuffer,
 which confuses the kernel into doing full modesets and generally
 breaks things.  To avoid this, make ms_present_check_flip check that
 some CRTCs are enabled and DPMS on.  This is an ugly hack that would
 get better with atomic modesetting, or some core Present work.

v4:
- Don't do pageflipping if CRTCs are rotated (caught by Jason Ekstrand).
- Make pageflipping optional (Option PageFlip in xorg.conf.d), but
   enabled by default.

Signed-off-by: Kenneth Graunke kenn...@whitecape.org


Upon further testing, there are still nasty DPMS bugs affecting this
patch.  We no longer crash the X server, but clients appear to
occasionally get stuck.

I guess we just need to bite the bullet and unflip on DPMS off.
Or switch to atomic modesetting...



I retested v4 + the attached patch with some small improvements applied. 
The patch adds async page flip cap support, fixes that missing zero init 
which Michel also reported and fixes some small inconsistency in the 
ms_present_unflip routine.


Everything worked nicely, except for the not quite resolved DPMS off 
bug. No more crashes, but page-flipped clients reliably hang after DPMS 
off - on. KDE with composition on and page flipping on (Setting 
Tearing prevention set to Full scene repaints) hangs after each 
off-on cycle, my own fullscreen app hangs reliably as well if 
page-flipped swaps are used.


Looking at stack traces it seems to me as if somehow after a dpms 
off/on, a present_event_notify() somehow doesn't get delivered to the 
server / gets lost somewhere, so clients like mine which wait for swap 
completion or vblank events hang, and KDE hangs in Mesa when Mesa tries 
to get a new backbuffer for rendering, runs out of buffers and then 
waits infinitely for a present notify event from the server in order to 
reuse one of its busy buffers.


-mario
From 3d1e2383d7bcd35cf0838f32f26b82b8118a17d5 Mon Sep 17 00:00:00 2001
From: Mario Kleiner mario.kleiner...@gmail.com
Date: Fri, 1 May 2015 09:01:41 +0200
Subject: [PATCH 8/8] modesetting: Add async flip support, fix small bugs.

Detect if kms driver is async flip capable.
Add missing zero init for number of crtc's on counting.
Fix small inconsistency.

Signed-off-by: Mario Kleiner mario.kleiner...@gmail.com
---
 hw/xfree86/drivers/modesetting/present.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c
index 0ec0f40..693d4f3 100644
--- a/hw/xfree86/drivers/modesetting/present.c
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -504,7 +504,7 @@ ms_present_check_flip(RRCrtcPtr crtc,
 ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 modesettingPtr ms = modesettingPTR(scrn);
 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
-int num_crtcs_on;
+int num_crtcs_on = 0;
 int i;
 
 if (!ms-drmmode.pageflip)
@@ -579,7 +579,7 @@ ms_present_unflip(ScreenPtr screen, uint64_t event_id)
 PixmapPtr pixmap = screen-GetScreenPixmap(screen);
 Bool ret;
 
-if (!ms_present_check_flip(NULL, screen-root, pixmap, FALSE))
+if (!ms_present_check_flip(NULL, screen-root, pixmap, TRUE))
 return;
 
 ret = ms_do_pageflip(screen, pixmap, -1, FALSE, event_id);
@@ -609,5 +609,14 @@ static present_screen_info_rec ms_present_screen_info = {
 Bool
 ms_present_screen_init(ScreenPtr screen)
 {
+ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+modesettingPtr ms = modesettingPTR(scrn);
+uint64_t value;
+int ret;
+
+ret = drmGetCap(ms-fd, DRM_CAP_ASYNC_PAGE_FLIP, value);
+if (ret == 0  value == 1)
+ms_present_screen_info.capabilities |= PresentCapabilityAsync;
+
 return present_screen_init(screen, ms_present_screen_info);
 }
-- 
1.9.1

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Re: [PATCH 5/5] modesetting: Implement page flipping support for Present.

2015-04-30 Thread Michel Dänzer
On 22.04.2015 09:58, Kenneth Graunke wrote:
 +/*
 + * Test to see if page flipping is possible on the target crtc
 + */
 +static Bool
 +ms_present_check_flip(RRCrtcPtr crtc,
 +  WindowPtr window,
 +  PixmapPtr pixmap,
 +  Bool sync_flip)
 +{
 +ScreenPtr screen = window-drawable.pScreen;
 +ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 +modesettingPtr ms = modesettingPTR(scrn);
 +xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
 +int num_crtcs_on;
 +int i;
 +
 +if (!ms-drmmode.pageflip)
 +return FALSE;
 +
 +if (!scrn-vtSema)
 +return FALSE;
 +
 +for (i = 0; i  config-num_crtc; i++) {
 +drmmode_crtc_private_ptr drmmode_crtc = 
 config-crtc[i]-driver_private;
 +
 +/* Don't do pageflipping if CRTCs are rotated. */
 +if (drmmode_crtc-rotate_bo.gbm)
 +return FALSE;
 +
 +if (ms_crtc_on(config-crtc[i]))
 +num_crtcs_on++;
 +}
 +
 +/* We can't do pageflipping if all the CRTCs are off. */
 +if (num_crtcs_on == 0)
 +return FALSE;
 +
 +/* Check stride, can't change that on flip */
 +if (pixmap-devKind != drmmode_bo_get_pitch(ms-drmmode.front_bo))
 +return FALSE;
 +
 +/* Make sure there's a bo we can get to */
 +/* XXX: actually do this.  also...is it sufficient?
 + * if (!glamor_get_pixmap_private(pixmap))
 + * return FALSE;
 + */
 +
 +return TRUE;
 +}

num_crtcs_on is used uninitialized.


-- 
Earthling Michel Dänzer   |   http://www.amd.com
Libre software enthusiast | Mesa and X developer
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Re: [PATCH 5/5] modesetting: Implement page flipping support for Present.

2015-04-27 Thread Kenneth Graunke
On Tuesday, April 21, 2015 05:58:44 PM Kenneth Graunke wrote:
 Based on code by Keith Packard, Eric Anholt, and Jason Ekstrand.
 
 v2:
 - Fix double free and flip_count underrun (caught by Mario Kleiner).
 - Don't leak flip_vblank_event on the error_out path (Mario).
 - Use the updated ms_flush_drm_events API (Mario, Ken).
 
 v3: Hack around DPMS shenanigans.  If all monitors are DPMS off, then
 there is no active framebuffer; attempting to pageflip will hit the
 error_undo paths, causing us to drmModeRmFB with no framebuffer,
 which confuses the kernel into doing full modesets and generally
 breaks things.  To avoid this, make ms_present_check_flip check that
 some CRTCs are enabled and DPMS on.  This is an ugly hack that would
 get better with atomic modesetting, or some core Present work.
 
 v4:
 - Don't do pageflipping if CRTCs are rotated (caught by Jason Ekstrand).
 - Make pageflipping optional (Option PageFlip in xorg.conf.d), but
   enabled by default.
 
 Signed-off-by: Kenneth Graunke kenn...@whitecape.org

Upon further testing, there are still nasty DPMS bugs affecting this
patch.  We no longer crash the X server, but clients appear to
occasionally get stuck.

I guess we just need to bite the bullet and unflip on DPMS off.
Or switch to atomic modesetting...


signature.asc
Description: This is a digitally signed message part.
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

[PATCH 5/5] modesetting: Implement page flipping support for Present.

2015-04-21 Thread Kenneth Graunke
Based on code by Keith Packard, Eric Anholt, and Jason Ekstrand.

v2:
- Fix double free and flip_count underrun (caught by Mario Kleiner).
- Don't leak flip_vblank_event on the error_out path (Mario).
- Use the updated ms_flush_drm_events API (Mario, Ken).

v3: Hack around DPMS shenanigans.  If all monitors are DPMS off, then
there is no active framebuffer; attempting to pageflip will hit the
error_undo paths, causing us to drmModeRmFB with no framebuffer,
which confuses the kernel into doing full modesets and generally
breaks things.  To avoid this, make ms_present_check_flip check that
some CRTCs are enabled and DPMS on.  This is an ugly hack that would
get better with atomic modesetting, or some core Present work.

v4:
- Don't do pageflipping if CRTCs are rotated (caught by Jason Ekstrand).
- Make pageflipping optional (Option PageFlip in xorg.conf.d), but
  enabled by default.

Signed-off-by: Kenneth Graunke kenn...@whitecape.org
---
 hw/xfree86/drivers/modesetting/driver.c  |   7 +
 hw/xfree86/drivers/modesetting/driver.h  |  10 +
 hw/xfree86/drivers/modesetting/drmmode_display.c |  33 +-
 hw/xfree86/drivers/modesetting/drmmode_display.h |   5 +
 hw/xfree86/drivers/modesetting/present.c | 376 ++-
 5 files changed, 426 insertions(+), 5 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/driver.c 
b/hw/xfree86/drivers/modesetting/driver.c
index e2f3846..bca0a5f 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -123,6 +123,7 @@ typedef enum {
 OPTION_DEVICE_PATH,
 OPTION_SHADOW_FB,
 OPTION_ACCEL_METHOD,
+OPTION_PAGEFLIP,
 } modesettingOpts;
 
 static const OptionInfoRec Options[] = {
@@ -130,6 +131,7 @@ static const OptionInfoRec Options[] = {
 {OPTION_DEVICE_PATH, kmsdev, OPTV_STRING, {0}, FALSE},
 {OPTION_SHADOW_FB, ShadowFB, OPTV_BOOLEAN, {0}, FALSE},
 {OPTION_ACCEL_METHOD, AccelMethod, OPTV_STRING, {0}, FALSE},
+{OPTION_PAGEFLIP, PageFlip, OPTV_BOOLEAN, {0}, FALSE},
 {-1, NULL, OPTV_NONE, {0}, FALSE}
 };
 
@@ -783,6 +785,9 @@ PreInit(ScrnInfoPtr pScrn, int flags)
 
 if (ms-drmmode.glamor) {
 xf86LoadSubModule(pScrn, dri2);
+
+ms-drmmode.pageflip =
+xf86ReturnOptValBool(ms-Options, OPTION_PAGEFLIP, TRUE);
 } else {
 Bool prefer_shadow = TRUE;
 
@@ -799,6 +804,8 @@ PreInit(ScrnInfoPtr pScrn, int flags)
ShadowFB: preferred %s, enabled %s\n,
prefer_shadow ? YES : NO,
ms-drmmode.shadow_enable ? YES : NO);
+
+ms-drmmode.pageflip = FALSE;
 }
 
 if (drmmode_pre_init(pScrn, ms-drmmode, pScrn-bitsPerPixel / 8) == 
FALSE) {
diff --git a/hw/xfree86/drivers/modesetting/driver.h 
b/hw/xfree86/drivers/modesetting/driver.h
index 843a105..2d63cae 100644
--- a/hw/xfree86/drivers/modesetting/driver.h
+++ b/hw/xfree86/drivers/modesetting/driver.h
@@ -101,6 +101,16 @@ typedef struct _modesettingRec {
 
 drmEventContext event_context;
 
+/**
+ * Page flipping stuff.
+ *  @{
+ */
+int flip_count;
+uint64_t fe_msc;
+uint64_t fe_usec;
+struct ms_present_vblank_event *flip_vblank_event;
+/** @} */
+
 DamagePtr damage;
 Bool dirty_enabled;
 
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c 
b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 1ea799b..7fd8669 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -50,7 +50,7 @@
 
 #include driver.h
 
-static int
+int
 drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
 {
 int ret;
@@ -71,7 +71,7 @@ drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
 return 0;
 }
 
-static uint32_t
+uint32_t
 drmmode_bo_get_pitch(drmmode_bo *bo)
 {
 #ifdef GLAMOR_HAS_GBM
@@ -142,6 +142,35 @@ drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
 }
 
 Bool
+drmmode_bo_for_pixmap(drmmode_ptr drmmode, drmmode_bo *bo, PixmapPtr pixmap)
+{
+ScreenPtr screen = xf86ScrnToScreen(drmmode-scrn);
+uint16_t pitch;
+uint32_t size;
+int fd;
+
+#ifdef GLAMOR_HAS_GBM
+if (drmmode-glamor) {
+bo-gbm = glamor_gbm_bo_from_pixmap(screen, pixmap);
+bo-dumb = NULL;
+return bo-gbm != NULL;
+}
+#endif
+
+fd = glamor_fd_from_pixmap(screen, pixmap, pitch, size);
+if (fd  0) {
+xf86DrvMsg(drmmode-scrn-scrnIndex, X_ERROR,
+   Failed to get fd for flip to new front.\n);
+return FALSE;
+}
+
+bo-dumb = dumb_get_bo_from_fd(drmmode-fd, fd, pitch, size);
+close(fd);
+
+return bo-dumb != NULL;
+}
+
+Bool
 drmmode_SetSlaveBO(PixmapPtr ppix,
drmmode_ptr drmmode, int fd_handle, int pitch, int size)
 {
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h 
b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 3a8959a..2cbf8be 100644
---