[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-nouveau: Changes to 'ubuntu'



 autogen.sh                |    4 
 configure.ac              |   15 +
 debian/patches/xmir.patch |  137 ++++++-------
 man/nouveau.man           |   31 ++-
 src/Makefile.am           |   12 +
 src/drmmode_display.c     |  300 ++++++++++++++---------------
 src/nouveau_copy.c        |  129 ++++++++++++
 src/nouveau_copy.h        |   18 +
 src/nouveau_copy85b5.c    |  104 ++++++++++
 src/nouveau_copy90b5.c    |  100 +++++++++
 src/nouveau_copya0b5.c    |   97 +++++++++
 src/nouveau_dri2.c        |  463 ++++++++++++++++++++++++++++++++--------------
 src/nouveau_exa.c         |   54 ++---
 src/nouveau_glamor.c      |  246 ++++++++++++++++++++++++
 src/nouveau_glamor.h      |   33 +++
 src/nouveau_present.c     |  350 ++++++++++++++++++++++++++++++++++
 src/nouveau_present.h     |   19 +
 src/nouveau_sync.c        |  117 +++++++++++
 src/nouveau_sync.h        |   34 +++
 src/nouveau_wfb.c         |   12 -
 src/nouveau_xv.c          |   21 +-
 src/nv04_exa.c            |    2 
 src/nv50_accel.c          |   23 --
 src/nv50_exa.c            |   59 -----
 src/nv50_xv.c             |    2 
 src/nv_accel_common.c     |  138 ++++++++-----
 src/nv_const.h            |    2 
 src/nv_dma.c              |  139 -------------
 src/nv_driver.c           |  245 ++++++++++++++++--------
 src/nv_proto.h            |   29 +-
 src/nv_type.h             |   32 ++-
 src/nvc0_accel.c          |   27 --
 src/nvc0_accel.h          |    2 
 src/nvc0_exa.c            |  112 -----------
 34 files changed, 2192 insertions(+), 916 deletions(-)

New commits:
commit 6b2de1e0e8ed425b6ae9e357295ef14a0ad84c1b
Author: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Date:   Wed Jul 16 16:15:18 2014 +0200

    refresh xmir patch

diff --git a/debian/patches/xmir.patch b/debian/patches/xmir.patch
index 45324eb..983e5b7 100644
--- a/debian/patches/xmir.patch
+++ b/debian/patches/xmir.patch
@@ -8,7 +8,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
 
 --- a/src/nouveau_dri2.c
 +++ b/src/nouveau_dri2.c
-@@ -267,7 +267,7 @@
+@@ -275,7 +275,7 @@
  	NVPtr pNv = NVPTR(scrn);
  	int i;
  
@@ -17,7 +17,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  		return FALSE;
  
  	for (i = 0; i < xf86_config->num_crtc; i++) {
-@@ -290,7 +290,7 @@
+@@ -298,7 +298,7 @@
  	ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen);
  	NVPtr pNv = NVPTR(scrn);
  
@@ -26,8 +26,8 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  		nv_window_belongs_to_crtc(scrn, draw->x, draw->y,
  					  draw->width, draw->height);
  }
-@@ -766,6 +766,19 @@
- 	free(flip);
+@@ -951,6 +951,19 @@
+ 	return TRUE;
  }
  
 +#if DRI2INFOREC_VERSION >= 8 && defined(XMIR)
@@ -46,7 +46,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  Bool
  nouveau_dri2_init(ScreenPtr pScreen)
  {
-@@ -804,6 +817,11 @@
+@@ -992,6 +1005,11 @@
  	dri2.GetParam = NULL;
  #endif
  
@@ -60,16 +60,25 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  	dri2.CreateBuffer2 = nouveau_dri2_create_buffer2;
 --- a/src/nv_driver.c
 +++ b/src/nv_driver.c
-@@ -226,6 +226,8 @@
+@@ -231,6 +231,8 @@
  	case GET_REQUIRED_HW_INTERFACES:
  	    flag = (CARD32 *)data;
  	    (*flag) = 0;
 +	    if (xorgMir)
 +		*flag |= HW_SKIP_CONSOLE;
  	    return TRUE;
- 	default:
- 	    return FALSE;
-@@ -333,6 +335,23 @@
+ #if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(1,15,99,0,0)
+ 	case SUPPORTS_SERVER_FDS:
+@@ -309,6 +311,8 @@
+ #endif
+ 	if (fd != -1)
+ 		ret = nouveau_device_wrap(fd, 0, &dev);
++	else if (xorgMir)
++		nouveau_device_wrap(xmir_get_drm_fd(busid), 0, &dev);
+ 	else
+ 		ret = nouveau_device_open(busid, &dev);
+ 	if (ret)
+@@ -372,6 +376,23 @@
  }
  
  static Bool
@@ -93,27 +102,28 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  NVPciProbe(DriverPtr drv, int entity_num, struct pci_device *pci_dev,
  	   intptr_t match_data)
  {
-@@ -343,6 +362,9 @@
+@@ -382,6 +403,10 @@
  	};
  	ScrnInfoPtr pScrn = NULL;
  
++
 +	if (xorgMir && !NVHasMirSupport(pci_dev))
 +		return FALSE;
 +
- 	if (!NVHasKMS(pci_dev))
+ 	if (!NVHasKMS(pci_dev, NULL))
  		return FALSE;
  
-@@ -367,6 +389,9 @@
+@@ -406,6 +431,9 @@
  	if (!dev->pdev)
  		return FALSE;
  
 +	if (xorgMir && !NVHasMirSupport(dev->pdev))
 +		return FALSE;
 +
- 	if (!NVHasKMS(dev->pdev))
+ 	if (!NVHasKMS(dev->pdev, dev))
  		return FALSE;
  
-@@ -406,7 +431,8 @@
+@@ -445,7 +473,8 @@
  NVAdjustFrame(ADJUST_FRAME_ARGS_DECL)
  {
  	SCRN_INFO_PTR(arg);
@@ -123,24 +133,28 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  }
  
  /*
-@@ -424,9 +450,11 @@
+@@ -462,7 +491,7 @@
+ #ifdef XF86_PDEV_SERVER_FD
+ 	NVEntPtr pNVEnt = NVEntPriv(pScrn);
+ #endif
+-	int ret;
++	int ret = 0;
  
  	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVEnterVT is called.\n");
  
--	ret = drmSetMaster(pNv->dev->fd);
--	if (ret)
--		ErrorF("Unable to get master: %s\n", strerror(errno));
-+	if (!xorgMir) {
-+		ret = drmSetMaster(pNv->dev->fd);
-+		if (ret)
-+			ErrorF("Unable to get master: %s\n", strerror(errno));
-+	}
- 
- 	if (XF86_CRTC_CONFIG_PTR(pScrn)->num_crtc && !xf86SetDesiredModes(pScrn))
- 		return FALSE;
-@@ -452,6 +480,9 @@
- 
- 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVLeaveVT is called.\n");
+@@ -471,7 +500,8 @@
+ 	      (pNVEnt->platform_dev->flags & XF86_PDEV_SERVER_FD)))
+ #endif
+ 	{
+-		ret = drmSetMaster(pNv->dev->fd);
++		if (!xorgMir)
++			ret = drmSetMaster(pNv->dev->fd);
+ 		if (ret)
+ 			ErrorF("Unable to get master: %s\n", strerror(errno));
+ 	}
+@@ -509,6 +539,9 @@
+ 		return;
+ #endif
  
 +	if (xorgMir)
 +		return;
@@ -148,7 +162,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  	ret = drmDropMaster(pNv->dev->fd);
  	if (ret && errno != EIO && errno != ENODEV)
  		ErrorF("Error dropping master: %i(%m)\n", -errno);
-@@ -501,6 +532,50 @@
+@@ -557,6 +590,50 @@
  }
  #endif
  
@@ -199,7 +213,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  static void 
  NVBlockHandler (BLOCKHANDLER_ARGS_DECL)
  {
-@@ -516,6 +591,11 @@
+@@ -572,12 +649,29 @@
  	nouveau_dirty_update(pScreen);
  #endif
  
@@ -208,10 +222,9 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
 +		xmir_screen_for_each_damaged_window(pNv->xmir, nouveau_xmir_copy_to_mir);
 +#endif
 +
- 	if (pScrn->vtSema && !pNv->NoAccel)
- 		nouveau_pushbuf_kick(pNv->pushbuf, pNv->pushbuf->channel);
+ 	NVFlushCallback(NULL, pScrn, NULL);
  
-@@ -523,6 +603,18 @@
+ 	if (pNv->VideoTimerCallback) 
  		(*pNv->VideoTimerCallback)(pScrn, currentTime.milliseconds);
  }
  
@@ -230,7 +243,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  static Bool
  NVCreateScreenResources(ScreenPtr pScreen)
  {
-@@ -535,7 +627,10 @@
+@@ -589,7 +683,10 @@
  		return FALSE;
  	pScreen->CreateScreenResources = NVCreateScreenResources;
  
@@ -242,7 +255,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  	if (!NVEnterVT(VT_FUNC_ARGS(0)))
  		return FALSE;
  
-@@ -561,7 +656,7 @@
+@@ -618,7 +715,7 @@
  	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
  	NVPtr pNv = NVPTR(pScrn);
  
@@ -250,32 +263,10 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
 +	if (!xorgMir && XF86_CRTC_CONFIG_PTR(pScrn)->num_crtc)
  		drmmode_screen_fini(pScreen);
  
- 	if (!pNv->NoAccel)
-@@ -688,7 +783,7 @@
- 	NVPtr pNv = NVPTR(pScrn);
- 	NVEntPtr pNVEnt = NVEntPriv(pScrn);
- 	struct pci_device *dev = pNv->PciInfo;
--	char *busid;
-+	char *busid = NULL;
- 	drmSetVersion sv;
- 	int err;
- 	int ret;
-@@ -712,8 +807,11 @@
- 	busid = XNFprintf("pci:%04x:%02x:%02x.%d",
- 			  dev->domain, dev->bus, dev->dev, dev->func);
- #endif
-+	if (!xorgMir)
-+		ret = nouveau_device_open(busid, &pNv->dev);
-+	else
-+		ret = nouveau_device_wrap(xmir_get_drm_fd(busid), 0, &pNv->dev);
- 
--	ret = nouveau_device_open(busid, &pNv->dev);
- 	if (ret) {
- 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- 			   "[drm] Failed to open DRM device for %s: %d\n",
-@@ -723,6 +821,9 @@
- 	}
- 	free(busid);
+ 	nouveau_present_fini(pScreen);
+@@ -766,6 +863,9 @@
+ 	if (!pNv->dev)
+ 		return FALSE;
  
 +	if (xorgMir)
 +		return TRUE;
@@ -283,7 +274,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  	sv.drm_di_major = 1;
  	sv.drm_di_minor = 1;
  	sv.drm_dd_major = -1;
-@@ -818,6 +919,14 @@
+@@ -861,6 +961,14 @@
  		)
  		return FALSE;
  
@@ -298,7 +289,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  	if (xf86IsEntityShared(pScrn->entityList[0])) {
  		if(!xf86IsPrimInitDone(pScrn->entityList[0])) {
  			pNv->Primary = TRUE;
-@@ -965,6 +1074,8 @@
+@@ -1012,6 +1120,8 @@
  		from = X_CONFIG;
  		pNv->HWCursor = FALSE;
  	}
@@ -307,7 +298,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  	xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
  		pNv->HWCursor ? "HW" : "SW");
  
-@@ -997,7 +1108,7 @@
+@@ -1072,7 +1182,7 @@
  				      &pNv->glx_vblank))
  			from = X_CONFIG;
  		else
@@ -316,9 +307,9 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  
  		xf86DrvMsg(pScrn->scrnIndex, from, "GLX sync to VBlank %s.\n",
  			   pNv->glx_vblank ? "enabled" : "disabled");
-@@ -1062,7 +1173,13 @@
- 	xf86DrvMsg(pScrn->scrnIndex, from, "Swap limit set to %d [Max allowed %d]%s\n",
- 		   pNv->swap_limit, pNv->max_swap_limit, reason);
+@@ -1148,7 +1258,13 @@
+ 			   pNv->has_async_pageflip ? "kernel" : "ddx");
+ #endif
  
 -	ret = drmmode_pre_init(pScrn, pNv->dev->fd, pScrn->bitsPerPixel >> 3);
 +#ifdef XMIR
@@ -331,7 +322,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  	if (ret == FALSE)
  		NVPreInitFail("Kernel modesetting failed to initialize\n");
  
-@@ -1170,7 +1287,8 @@
+@@ -1245,7 +1361,8 @@
  {
  	NVPtr pNv = NVPTR(pScrn);
  
@@ -341,7 +332,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  
  	nouveau_bo_ref(NULL, &pNv->transfer);
  	nouveau_bo_ref(NULL, &pNv->scanout);
-@@ -1384,6 +1502,11 @@
+@@ -1467,6 +1584,11 @@
  	 */
  	miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
  
@@ -353,7 +344,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  	/*
  	 * Initialize HW cursor layer. 
  	 * Must follow software cursor initialization.
-@@ -1427,6 +1550,8 @@
+@@ -1510,6 +1632,8 @@
  	pNv->CreateScreenResources = pScreen->CreateScreenResources;
  	pScreen->CreateScreenResources = NVCreateScreenResources;
  
@@ -362,7 +353,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  #ifdef NOUVEAU_PIXMAP_SHARING
  	pScreen->StartPixmapTracking = PixmapStartDirtyTracking;
  	pScreen->StopPixmapTracking = PixmapStopDirtyTracking;
-@@ -1443,19 +1568,19 @@
+@@ -1526,19 +1650,19 @@
  	 * Initialize colormap layer.
  	 * Must follow initialization of the default colormap 
  	 */
@@ -402,7 +393,7 @@ Date:   Mon Jul 22 17:46:58 2013 +1000
  #if XF86_CRTC_VERSION >= 5
  #define NOUVEAU_PIXMAP_SHARING 1
  #endif
-@@ -112,6 +120,8 @@
+@@ -136,6 +144,8 @@
  	PixmapPtr pspix, pmpix, pdpix;
  	PicturePtr pspict, pmpict;
  	Pixel fg_colour;

commit 096fb1ebc10b14ba1b747832efe378369bcf44e6
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date:   Mon May 26 05:39:50 2014 +0200

    dri2: Add support for handling more than 2 crtc's
    
    Need to use the DRM_VBLANK_HIGH_CRTC bits to allow
    selecting crtc's with id > 1 on latest gpu's with
    up to four display engines.
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c
index adb0b22..7446122 100644
--- a/src/nouveau_dri2.c
+++ b/src/nouveau_dri2.c
@@ -584,7 +584,23 @@ nouveau_wait_vblank(DrawablePtr draw, int type, CARD64 msc,
 		event->s = data;
 	}
 
-	vbl.request.type = type | (crtcs == 2 ? DRM_VBLANK_SECONDARY : 0);
+	/* Select crtc with smallest index from bitmask of crtcs */
+	crtcs = ffs(crtcs) - 1;
+
+	if (crtcs == 1)
+		type |= DRM_VBLANK_SECONDARY;
+	else if (crtcs > 1)
+#ifdef DRM_VBLANK_HIGH_CRTC_SHIFT
+		type |= (crtcs << DRM_VBLANK_HIGH_CRTC_SHIFT) &
+				DRM_VBLANK_HIGH_CRTC_MASK;
+#else
+	xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+			   "Wait for VBlank failed: Called for CRTC %d > 1, but "
+			   "DRM_VBLANK_HIGH_CRTC_SHIFT not defined at build time.\n",
+			   crtcs);
+#endif
+
+	vbl.request.type = type;
 	vbl.request.sequence = msc;
 	vbl.request.signal = (unsigned long)token;
 
@@ -630,11 +646,11 @@ nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame,
 								draw->width,
 								draw->height);
 
-	/* Whenever first crtc is involved, choose it as reference, as
-	 * its vblank event triggered this swap.
+	/* Choose crtc with smallest index as reference, as its
+	 * vblank event triggered this swap. ref_crtc_hw_id is
+	 * a bit field (crtc 0 = bit 0, crtc 1 = bit 1 ...)
 	 */
-	if (ref_crtc_hw_id & 1)
-		ref_crtc_hw_id = 1;
+	ref_crtc_hw_id = 1 << (ffs(ref_crtc_hw_id) - 1);
 
 	/* Update frontbuffer pixmap and name: Could have changed due to
 	 * window (un)redirection as part of compositing.

commit 4771ff5c668047a2dc56e4c6131175eed837e757
Author: Marcin Slusarz <marcin.slusarz@gmail.com>
Date:   Sun Jun 22 01:32:42 2014 +0200

    present: build only when glamor is enabled
    
    nouveau_present_flip_exec references glamor_fd_from_pixmap,
    which do not exist when glamor is disabled
    
    Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/src/nouveau_present.c b/src/nouveau_present.c
index b294bbe..38f2cac 100644
--- a/src/nouveau_present.c
+++ b/src/nouveau_present.c
@@ -23,7 +23,7 @@
  */
 
 #include "nouveau_present.h"
-#ifdef DRI3
+#if defined(DRI3) && defined(HAVE_GLAMOR)
 #include "nv_include.h"
 #include "nouveau_glamor.h"
 #include "xf86drmMode.h"
diff --git a/src/nouveau_present.h b/src/nouveau_present.h
index dea19ce..958c2f7 100644
--- a/src/nouveau_present.h
+++ b/src/nouveau_present.h
@@ -4,7 +4,11 @@
 #include "xorg-server.h"
 #include "scrnintstr.h"
 
-#ifdef DRI3
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if defined(DRI3) && defined(HAVE_GLAMOR)
 #include "present.h"
 Bool nouveau_present_init(ScreenPtr pScreen);
 void nouveau_present_fini(ScreenPtr pScreen);

commit 41c1c4ee867753422d6486f13bf20b45905a5dd5
Author: Marcin Slusarz <marcin.slusarz@gmail.com>
Date:   Sun Jun 22 01:31:46 2014 +0200

    glamor: fix build without glamor.h
    
    xorg-server can be built without glamor, which leads to:
    
      CC       nouveau_xv.lo
    In file included from nouveau_xv.c:41:0:
    nouveau_glamor.h:12:20: fatal error: glamor.h: No such file or directory
    compilation terminated.
    
    Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/configure.ac b/configure.ac
index c34e575..92e047a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -128,7 +128,13 @@ XORG_MANPAGE_SECTIONS
 XORG_RELEASE_VERSION
 
 AC_MSG_CHECKING([whether to include GLAMOR support])
-if pkg-config --exists "xorg-server >= 1.15.99.901"
+
+AC_COMPILE_IFELSE(AC_LANG_PROGRAM(
+[[
+  #include <glamor.h>
+]],[[]]),[found_glamor_header=yes],[found_glamor_header=no])
+
+if test "$found_glamor_header" = "yes" && pkg-config --exists "xorg-server >= 1.15.99.901"
 then
 	AC_DEFINE(HAVE_GLAMOR, 1, [Build support for glamor acceleration])
 	AC_MSG_RESULT([yes])

commit f0fa8313714c2a5b16e784b257b5ff79da3a443b
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date:   Thu Jun 19 17:11:34 2014 +0200

    dri2: Enable sync of bufferswaps to Vblank by default.
    
    Make this consistent with other drivers default behaviour.
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/man/nouveau.man b/man/nouveau.man
index a8dfacd..0bf6e1e 100644
--- a/man/nouveau.man
+++ b/man/nouveau.man
@@ -96,7 +96,7 @@ Enable or disable wfb, only affects nv50+. Useful for some legacy configurations
 .BI "Option \*qGLXVBlank\*q \*q" boolean \*q
 Synchronize GLX clients to VBlank. Useful where tearing is a problem,
 harmful if the GPU isn't fast enough to keep up with the monitor
-refresh rate. Default: off.
+refresh rate. Default: on.
 .TP
 .BI "Option \*qZaphodHeads\*q \*q" string \*q
 Specify the randr output(s) to use with zaphod mode for a particular driver
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 3ca65c5..44a0963 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -1067,6 +1067,7 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
 
 	if (pNv->AccelMethod > NONE && pNv->dev->chipset >= 0x11) {
 		from = X_DEFAULT;
+		pNv->glx_vblank = TRUE;
 		if (xf86GetOptValBool(pNv->Options, OPTION_GLX_VBLANK,
 				      &pNv->glx_vblank))
 			from = X_CONFIG;

commit 02d7e647ce3a4a5d48c4ee94c94bebcac2d4827d
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date:   Sat Jun 21 01:26:16 2014 +0200

    dri2: Fix kms pageflip completion timestamping.
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c
index a9851cb..adb0b22 100644
--- a/src/nouveau_dri2.c
+++ b/src/nouveau_dri2.c
@@ -335,7 +335,7 @@ typedef struct {
     int flip_count;
     void *event_data;
     unsigned int fe_msc;
-    unsigned int fe_ust;
+    uint64_t fe_ust;
 } dri2_flipdata_rec, *dri2_flipdata_ptr;
 
 typedef struct {

commit 4d92001ebe6bec8c5eaab8156421e62a7e4dedc8
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date:   Fri Mar 14 18:27:53 2014 +0100

    Add kernel async_flip cap detection. Part II of double-sync fix.
    
    Query if kernel supports the async_flip cap, thereby needs the
    new sync behavior. Linux 3.13+ nouveau-kms have this cap and
    need this fix.
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/src/nv_driver.c b/src/nv_driver.c
index db66de6..3ca65c5 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -1134,6 +1134,17 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
 	xf86DrvMsg(pScrn->scrnIndex, from, "Swap limit set to %d [Max allowed %d]%s\n",
 		   pNv->swap_limit, pNv->max_swap_limit, reason);
 
+	/* Does kernel do the sync of pageflips to vblank? */
+	pNv->has_async_pageflip = FALSE;
+#ifdef DRM_CAP_ASYNC_PAGE_FLIP
+	ret = drmGetCap(pNv->dev->fd, DRM_CAP_ASYNC_PAGE_FLIP, &v);
+	if (ret == 0 && v == 1) {
+		pNv->has_async_pageflip = TRUE;
+	}
+	xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Page flipping synced to vblank by %s.\n",
+			   pNv->has_async_pageflip ? "kernel" : "ddx");
+#endif
+
 	ret = drmmode_pre_init(pScrn, pNv->dev->fd, pScrn->bitsPerPixel >> 3);
 	if (ret == FALSE)
 		NVPreInitFail("Kernel modesetting failed to initialize\n");

commit 54dfbb2fed393b65d846e6ed9672acb47e0f19de
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date:   Fri Mar 14 18:23:04 2014 +0100

    dri2: Fix double-sync of pageflips on Linux 3.13+ - Part I
    
    Linux 3.13 and later sync kms pageflips to vblank in the kms
    driver, so we must not emit a sync to vblank pushbuf in the ddx
    on such kernels, or maximum framerate will be cut into half!
    
    A sync-to-vblank-pushbuf is emitted for copyswaps as in the past,
    also for older kernels which don't support async_pageflip's and
    don't sync by themselves.
    
    This adds the implementation, but not the detection logic for
    async_pageflip support in the kernel.
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c
index 5848966..a9851cb 100644
--- a/src/nouveau_dri2.c
+++ b/src/nouveau_dri2.c
@@ -619,7 +619,7 @@ nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame,
 	struct nouveau_pushbuf *push = pNv->pushbuf;
 	RegionRec reg;
 	int type, ret;
-	Bool front_updated;
+	Bool front_updated, will_exchange;
 
 	REGION_INIT(0, &reg, (&(BoxRec){ 0, 0, draw->width, draw->height }), 0);
 	REGION_TRANSLATE(0, &reg, draw->x, draw->y);
@@ -648,7 +648,18 @@ nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame,
 	/* Throttle on the previous frame before swapping */
 	nouveau_bo_wait(dst_bo, NOUVEAU_BO_RD, push->client);
 
-	if (can_sync_to_vblank(draw)) {
+	/* Swap by buffer exchange possible? */
+	will_exchange = front_updated && can_exchange(draw, dst_pix, src_pix);
+
+	/* Only emit a wait for vblank pushbuf here if this is a copy-swap, or
+	 * if it is a kms pageflip-swap on an old kernel. Pure exchange swaps
+	 * don't need sync to vblank. kms pageflip-swaps on Linux 3.13+ are
+	 * synced to vblank in the kms driver, so we must not sync here, or
+	 * framerate will be cut in half!
+	 */
+	if (can_sync_to_vblank(draw) &&
+		(!will_exchange ||
+		(!pNv->has_async_pageflip && nouveau_exa_pixmap_is_onscreen(dst_pix)))) {
 		/* Reference the back buffer to sync it to vblank */
 		nouveau_pushbuf_refn(push, &(struct nouveau_pushbuf_refn) {
 					   src_bo,
@@ -666,7 +677,7 @@ nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame,
 		nouveau_pushbuf_kick(push, push->channel);
 	}
 
-	if (front_updated && can_exchange(draw, dst_pix, src_pix)) {
+	if (will_exchange) {
 		type = DRI2_EXCHANGE_COMPLETE;
 		DamageRegionAppend(draw, &reg);
 
diff --git a/src/nv_type.h b/src/nv_type.h
index 3c52e4e..b4889bf 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -63,6 +63,7 @@ typedef struct _NVRec {
     Bool		wfb_enabled;
     Bool		tiled_scanout;
     Bool		glx_vblank;
+    Bool		has_async_pageflip;
     Bool		has_pageflip;
     int 		swap_limit;
     int 		max_swap_limit;

commit 303402e00d55b5296311738184cd61f4aadab74d
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date:   Sat Jun 21 00:09:39 2014 +0200

    Fix nouveau_copy_init()
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/src/nouveau_copy.c b/src/nouveau_copy.c
index c737834..f46f0c3 100644
--- a/src/nouveau_copy.c
+++ b/src/nouveau_copy.c
@@ -114,6 +114,7 @@ nouveau_copy_init(ScreenPtr pScreen)
 			}
 			break;
 		}
+		method++;
 	}
 
 	if (ret) {

commit 65a70c4edd1f0df808a3a4dea6e8c9846cc7c920
Author: Ben Skeggs <bskeggs@redhat.com>
Date:   Fri Jun 20 16:57:18 2014 +1000

    another build fix...

diff --git a/src/nouveau_glamor.h b/src/nouveau_glamor.h
index 45c1b0a..fb6565d 100644
--- a/src/nouveau_glamor.h
+++ b/src/nouveau_glamor.h
@@ -23,7 +23,7 @@ static inline Bool nouveau_glamor_init(ScreenPtr screen) { return FALSE; }
 static inline Bool
 nouveau_glamor_create_screen_resources(ScreenPtr screen) { return FALSE; }
 static inline void
-nouveau_glamor_pixmap_set(PixmapPtr, struct nouveau_pixmap *) { }
+nouveau_glamor_pixmap_set(PixmapPtr pixmap, void *priv) { }
 static inline struct nouveau_pixmap *
 nouveau_glamor_pixmap_get(PixmapPtr pixmap) { return NULL; }
 static inline XF86VideoAdaptorPtr

commit 882ebb4000803f6025e1bb3213a31b19f6d1a2c6
Author: Ben Skeggs <bskeggs@redhat.com>
Date:   Mon Nov 18 14:42:02 2013 +1000

    present: initial support
    
    Until glamor grows its own implementation.
    
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/src/Makefile.am b/src/Makefile.am
index a787db0..9d39a00 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,8 +36,9 @@ nouveau_drv_la_SOURCES = \
 			 nouveau_copya0b5.c \
 			 nouveau_exa.c nouveau_xv.c nouveau_dri2.c \
 			 nouveau_glamor.c \
-			 nouveau_wfb.c \
+			 nouveau_present.c \
 			 nouveau_sync.c \
+			 nouveau_wfb.c \
 			 nv_accel_common.c \
 			 nv_driver.c \
 			 nv_shadow.c \
@@ -123,6 +124,7 @@ EXTRA_DIST = hwdefs/nv_3ddefs.xml.h \
 	     nouveau_local.h \
 	     nouveau_copy.h \
 	     nouveau_glamor.h \
+	     nouveau_present.h \
 	     nouveau_sync.h \
 	     nv_const.h \
 	     nv_dma.h \
diff --git a/src/nouveau_glamor.c b/src/nouveau_glamor.c
index 9c88e77..ec6ebf9 100644
--- a/src/nouveau_glamor.c
+++ b/src/nouveau_glamor.c
@@ -27,7 +27,7 @@
 
 static DevPrivateKeyRec glamor_private;
 
-static inline void
+void
 nouveau_glamor_pixmap_set(PixmapPtr pixmap, struct nouveau_pixmap *priv)
 {
 	dixSetPrivate(&pixmap->devPrivates, &glamor_private, priv);
diff --git a/src/nouveau_glamor.h b/src/nouveau_glamor.h
index ef01317..45c1b0a 100644
--- a/src/nouveau_glamor.h
+++ b/src/nouveau_glamor.h
@@ -15,12 +15,15 @@ Bool nouveau_glamor_pre_init(ScrnInfoPtr scrn);
 Bool nouveau_glamor_init(ScreenPtr screen);
 Bool nouveau_glamor_create_screen_resources(ScreenPtr screen);
 XF86VideoAdaptorPtr nouveau_glamor_xv_init(ScreenPtr pScreen, int num_adapt);
+void nouveau_glamor_pixmap_set(PixmapPtr pixmap, struct nouveau_pixmap *priv);
 struct nouveau_pixmap *nouveau_glamor_pixmap_get(PixmapPtr pixmap);
 #else
 static inline Bool nouveau_glamor_pre_init(ScrnInfoPtr scrn) { return FALSE; }
 static inline Bool nouveau_glamor_init(ScreenPtr screen) { return FALSE; }
 static inline Bool
 nouveau_glamor_create_screen_resources(ScreenPtr screen) { return FALSE; }
+static inline void
+nouveau_glamor_pixmap_set(PixmapPtr, struct nouveau_pixmap *) { }
 static inline struct nouveau_pixmap *
 nouveau_glamor_pixmap_get(PixmapPtr pixmap) { return NULL; }
 static inline XF86VideoAdaptorPtr
diff --git a/src/nouveau_present.c b/src/nouveau_present.c
new file mode 100644
index 0000000..b294bbe
--- /dev/null
+++ b/src/nouveau_present.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nouveau_present.h"
+#ifdef DRI3
+#include "nv_include.h"
+#include "nouveau_glamor.h"
+#include "xf86drmMode.h"
+
+struct nouveau_present {
+	struct present_screen_info info;
+};
+
+static RRCrtcPtr
+nouveau_present_crtc(WindowPtr window)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(window->drawable.pScreen);
+	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+	xf86CrtcPtr crtc;
+	unsigned mask;
+	int head;
+
+	mask = nv_window_belongs_to_crtc(scrn, window->drawable.x,
+					       window->drawable.y,
+					       window->drawable.width,
+					       window->drawable.height);
+
+	head = ffs(mask) - 1;
+	if (head < 0 || head >= xf86_config->num_crtc)
+		return NULL;
+
+	crtc = xf86_config->crtc[head];
+	if (crtc->rotatedData)
+		return NULL;
+
+	return crtc->randr_crtc;
+}
+
+static int
+nouveau_present_ust_msc(RRCrtcPtr rrcrtc, uint64_t *ust, uint64_t *msc)
+{
+	xf86CrtcPtr crtc = rrcrtc->devPrivate;
+	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+	NVPtr pNv = NVPTR(crtc->scrn);
+	drmVBlank args;
+	int ret, i;
+
+	for (i = 0; i < xf86_config->num_crtc; i++) {
+		if (xf86_config->crtc[i] == crtc)
+			break;
+	}
+
+	if (i == xf86_config->num_crtc)
+		return BadMatch;
+
+	args.request.type = DRM_VBLANK_RELATIVE;
+	args.request.type |= i << DRM_VBLANK_HIGH_CRTC_SHIFT;
+	args.request.sequence = 0,
+	args.request.signal = 0,
+
+	ret = drmWaitVBlank(pNv->dev->fd, &args);
+	if (ret) {
+		*ust = *msc = 0;
+		return BadMatch;
+	}
+
+	*ust = (CARD64)args.reply.tval_sec * 1000000 + args.reply.tval_usec;
+	*msc = args.reply.sequence;
+	return Success;
+}
+
+struct nouveau_present_vblank {
+	uint64_t msc;
+};
+
+static void
+nouveau_present_vblank(void *priv, uint64_t name, uint64_t ust, uint32_t msc_lo)
+{
+	struct nouveau_present_vblank *event = priv;
+	uint64_t msc;
+
+	msc = (event->msc & 0xffffffff00000000ULL) | msc_lo;
+	if (msc < event->msc)
+		event->msc += 1ULL << 32;
+
+	present_event_notify(name, ust, msc);
+}
+
+static int
+nouveau_present_vblank_queue(RRCrtcPtr rrcrtc, uint64_t event_id, uint64_t msc)
+{
+	xf86CrtcPtr crtc = rrcrtc->devPrivate;
+	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+	NVPtr pNv = NVPTR(crtc->scrn);
+	drmVBlank args;
+	struct nouveau_present_vblank *event;
+	void *token;
+	int ret, i;
+
+	for (i = 0; i < xf86_config->num_crtc; i++) {
+		if (xf86_config->crtc[i] == crtc)
+			break;
+	}
+
+	if (i == xf86_config->num_crtc)
+		return BadMatch;
+
+	event = drmmode_event_queue(crtc->scrn, event_id, sizeof(*event),
+				    nouveau_present_vblank, &token);
+	if (!event)
+		return BadAlloc;
+
+	event->msc = msc;
+
+	args.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
+	args.request.type |= i << DRM_VBLANK_HIGH_CRTC_SHIFT;
+	args.request.sequence = msc;
+	args.request.signal = (unsigned long)token;
+
+	while ((ret = drmWaitVBlank(pNv->dev->fd, &args)) != 0) {
+		if (errno != EBUSY || drmmode_event_flush(crtc->scrn) < 0)
+			return BadAlloc;
+	}
+
+	return Success;
+}
+
+static void
+nouveau_present_vblank_abort(RRCrtcPtr rrcrtc, uint64_t event_id, uint64_t msc)
+{
+	xf86CrtcPtr crtc = rrcrtc->devPrivate;
+	drmmode_event_abort(crtc->scrn, event_id, true);
+}
+
+static void
+nouveau_present_flush(WindowPtr window)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(window->drawable.pScreen);
+	NVPtr pNv = NVPTR(scrn);
+	if (pNv->Flush)
+		pNv->Flush(scrn);
+}
+
+struct nouveau_present_flip {
+	uint64_t msc;
+	uint32_t old;
+	int fd;
+};
+
+static Bool
+nouveau_present_flip_check(RRCrtcPtr rrcrtc, WindowPtr window,
+			   PixmapPtr pixmap, Bool sync_flip)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(window->drawable.pScreen);
+	xf86CrtcPtr crtc = rrcrtc->devPrivate;
+
+	if (!scrn->vtSema || !crtc->enabled)
+		return FALSE;
+
+	return TRUE;
+}
+
+static void
+nouveau_present_flip(void *priv, uint64_t name, uint64_t ust, uint32_t msc_lo)
+{
+	struct nouveau_present_flip *flip = priv;
+	uint64_t msc;
+
+	msc = (flip->msc & ~0xffffffffULL) | msc_lo;
+	if (msc < flip->msc)
+		msc += 1ULL << 32;
+
+	present_event_notify(name, ust, msc);
+	drmModeRmFB(flip->fd, flip->old);
+}
+
+static Bool
+nouveau_present_flip_exec(ScrnInfoPtr scrn, uint64_t event_id, int sync,
+			  uint64_t target_msc, PixmapPtr pixmap, Bool vsync)
+{
+	ScreenPtr screen = scrn->pScreen;
+	struct nouveau_pixmap *priv;
+	NVPtr pNv = NVPTR(scrn);
+	uint32_t next_fb;
+	CARD16 stride;
+	CARD32 size;
+	void *token;
+	int ret;
+
+	priv = nouveau_glamor_pixmap_get(pixmap);
+	if (priv == NULL) {


Reply to: