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, ®, (&(BoxRec){ 0, 0, draw->width, draw->height }), 0);
REGION_TRANSLATE(0, ®, 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, ®);
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: