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.lankho...@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...@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...@gmail.com> Signed-off-by: Ben Skeggs <bske...@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.slus...@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.slus...@gmail.com> Signed-off-by: Ben Skeggs <bske...@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.slus...@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.slus...@gmail.com> Signed-off-by: Ben Skeggs <bske...@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...@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...@gmail.com> Signed-off-by: Ben Skeggs <bske...@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...@gmail.com> Date: Sat Jun 21 01:26:16 2014 +0200 dri2: Fix kms pageflip completion timestamping. Signed-off-by: Mario Kleiner <mario.kleiner...@gmail.com> Signed-off-by: Ben Skeggs <bske...@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...@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...@gmail.com> Signed-off-by: Ben Skeggs <bske...@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...@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...@gmail.com> Signed-off-by: Ben Skeggs <bske...@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...@gmail.com> Date: Sat Jun 21 00:09:39 2014 +0200 Fix nouveau_copy_init() Signed-off-by: Mario Kleiner <mario.kleiner...@gmail.com> Signed-off-by: Ben Skeggs <bske...@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 <bske...@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 <bske...@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 <bske...@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 <bske...@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) { -- To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: https://lists.debian.org/e1x7qvb-0004dg...@moszumanska.debian.org