diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/autogen.sh xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/autogen.sh --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/autogen.sh 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/autogen.sh 2014-07-14 14:55:28.000000000 +0000 @@ -9,4 +9,6 @@ autoreconf -v --install || exit 1 cd $ORIGDIR || exit $? -$srcdir/configure "$@" +if test -z "$NOCONFIGURE"; then + $srcdir/configure "$@" +fi diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/ChangeLog xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/ChangeLog --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/ChangeLog 2014-02-20 22:01:59.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/ChangeLog 2014-07-14 14:55:38.000000000 +0000 @@ -1,9 +1,351 @@ -commit 5f17b12355a5dbf931e50a36d6435faa6d845f4c +commit def4c2e9dc390c33492f16e5b165ef664ddea033 Author: Robert Hooker -Date: Thu Feb 20 17:01:50 2014 -0500 +Date: Mon Jul 14 10:55:28 2014 -0400 Add debian tree from origin/ubuntu +commit edd1608c397ebcf487b84948031f7807178e5e4d +Author: Emil Velikov +Date: Tue Jul 1 22:31:47 2014 +0100 + + xorg_list: define the xorg_list* symbols + + ...when building against pre 1.12 x. + The build will fail as earlier versions of X were missing the xorg_ + prefix of the symbols - struct and util functions. + + Reported-by: Pali Rohár + Signed-off-by: Emil Velikov + Signed-off-by: Ben Skeggs + +commit f6c1c755d8230494c8115e2c7899a85663f5c176 +Author: Ben Skeggs +Date: Tue Jul 1 12:56:49 2014 +1000 + + fix a harmless typo + + fdo#80738 + + Reported-by: Paulo Sérgio Travaglia + Signed-off-by: Ben Skeggs + +commit 096fb1ebc10b14ba1b747832efe378369bcf44e6 +Author: Mario Kleiner +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 + Signed-off-by: Ben Skeggs + +commit 4771ff5c668047a2dc56e4c6131175eed837e757 +Author: Marcin Slusarz +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 + Signed-off-by: Ben Skeggs + +commit 41c1c4ee867753422d6486f13bf20b45905a5dd5 +Author: Marcin Slusarz +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 + Signed-off-by: Ben Skeggs + +commit f0fa8313714c2a5b16e784b257b5ff79da3a443b +Author: Mario Kleiner +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 + Signed-off-by: Ben Skeggs + +commit 02d7e647ce3a4a5d48c4ee94c94bebcac2d4827d +Author: Mario Kleiner +Date: Sat Jun 21 01:26:16 2014 +0200 + + dri2: Fix kms pageflip completion timestamping. + + Signed-off-by: Mario Kleiner + Signed-off-by: Ben Skeggs + +commit 4d92001ebe6bec8c5eaab8156421e62a7e4dedc8 +Author: Mario Kleiner +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 + Signed-off-by: Ben Skeggs + +commit 54dfbb2fed393b65d846e6ed9672acb47e0f19de +Author: Mario Kleiner +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 + Signed-off-by: Ben Skeggs + +commit 303402e00d55b5296311738184cd61f4aadab74d +Author: Mario Kleiner +Date: Sat Jun 21 00:09:39 2014 +0200 + + Fix nouveau_copy_init() + + Signed-off-by: Mario Kleiner + Signed-off-by: Ben Skeggs + +commit 65a70c4edd1f0df808a3a4dea6e8c9846cc7c920 +Author: Ben Skeggs +Date: Fri Jun 20 16:57:18 2014 +1000 + + another build fix... + +commit 882ebb4000803f6025e1bb3213a31b19f6d1a2c6 +Author: Ben Skeggs +Date: Mon Nov 18 14:42:02 2013 +1000 + + present: initial support + + Until glamor grows its own implementation. + + Signed-off-by: Ben Skeggs + +commit 0d94f32fce2759c4b0f4d22b99f3ced09c2aa5a0 +Author: Ben Skeggs +Date: Fri Jun 20 09:47:39 2014 +1000 + + kms: implement a more generic event mechanism + + Present wants to use this too. + + Signed-off-by: Ben Skeggs + +commit 97feb3b2104287eb385ffba8329f304e2808d808 +Author: Ben Skeggs +Date: Fri Jun 20 09:29:08 2014 +1000 + + dri2: move page flip handling out of drmmode + + Nothing to see here... This is to (hopefully) avoid busting DRI2 while + implementing Present support. + + Signed-off-by: Ben Skeggs + +commit 60b876eab3708f1c277027addb5514974452644c +Author: Ben Skeggs +Date: Fri Jun 20 09:20:37 2014 +1000 + + dri2: move away from directly touching drmmode on page flips + + Signed-off-by: Ben Skeggs + +commit 36dda1341008dd87a6b5459f0616776097d11d9f +Author: Ben Skeggs +Date: Fri Jun 20 09:04:30 2014 +1000 + + dri2: shuffle some functions around + + Nothing to see here... + + Signed-off-by: Ben Skeggs + +commit 8bdec8ebd68ba5eaa696d8a666e18774bff3b2ad +Author: Ben Skeggs +Date: Fri Jun 20 12:37:33 2014 +1000 + + glamor: fix randr resize + + Signed-off-by: Ben Skeggs + +commit 3c45b590a31157abca140096b141aa83fecb671f +Author: Ben Skeggs +Date: Fri Jun 20 08:28:30 2014 +1000 + + sync: fix build against DRI3-less server + + Signed-off-by: Ben Skeggs + +commit 88ae58d786b0c41148e692dbfe8e2646e7533d9e +Author: Ilia Mirkin +Date: Thu Jun 19 02:37:45 2014 -0400 + + update man page with new chips, AccelMethod option + + Signed-off-by: Ben Skeggs + +commit 5cb36ba57493bf7edf560bf370c87eff79f1d1a6 +Author: Ben Skeggs +Date: Thu Jun 19 14:54:20 2014 +1000 + + default to glamor on maxwell + + We have no RENDER/Xv acceleration in EXA for Maxwell. + + Signed-off-by: Ben Skeggs + +commit 81148bb1dbc7007c021c59411d56cb31cfc74ef2 +Author: Ben Skeggs +Date: Thu Jun 19 14:54:20 2014 +1000 + + glamor: provide dri3 support when enabled + + Signed-off-by: Ben Skeggs + +commit 86024ceef015ffe31a204cc5bc6c326a19363ff1 +Author: Ben Skeggs +Date: Thu Jun 19 14:54:20 2014 +1000 + + glamor: initial support (no dri) + + Signed-off-by: Ben Skeggs + +commit fd0ce8839f307693d86c7602dd926ce79e6b777d +Author: Ben Skeggs +Date: Thu Jun 19 14:54:20 2014 +1000 + + add support for maxwell, minus Xv/renderaccel + + More extensive acceleration will be via glamor, at least to begin with. It + seems to make sense to jump on the bandwagon now, and deal with any issues + that arise before it it becomes the standard for XWayland. + + Signed-off-by: Ben Skeggs + +commit 8ad0465e15bfc502abc259e886d6dcb448e0141a +Author: Ben Skeggs +Date: Thu Jun 19 14:54:20 2014 +1000 + + 50/c0/e0 -> tesla/fermi/kepler + + Signed-off-by: Ben Skeggs + +commit 4b138ab18f58c6d459e21dc319615f536c8e69c8 +Author: Ben Skeggs +Date: Thu Jun 19 14:54:20 2014 +1000 + + merge nv_dma.c into nv_accel_common.c + + Signed-off-by: Ben Skeggs + +commit 5c44e6b86195c22e092db5dae06e70208e8b66a0 +Author: Ben Skeggs +Date: Thu Jun 19 14:54:20 2014 +1000 + + pull copy engine handling into one place, a place that isn't also exa + + As a side-effect, we now allow Kepler to use async copies too. + + Signed-off-by: Ben Skeggs + +commit c375bacbdaeabd0288855c13b4717d0694be9e56 +Author: Ben Skeggs +Date: Thu Jun 19 14:54:20 2014 +1000 + + exa: move module load into nouveau_exa_init + + Signed-off-by: Ben Skeggs + +commit b24cae0bf5db6ece21439d4c6ff3668aed4c78d6 +Author: Ben Skeggs +Date: Thu Jun 19 14:54:20 2014 +1000 + + dri2: move "is supported" checks out of nv_driver.c + + Signed-off-by: Ben Skeggs + +commit 07c26a0670dd2558acf8e1159f2f68989a7f753d +Author: Ben Skeggs +Date: Thu Jun 19 14:54:20 2014 +1000 + + replace NoAccel with AccelMethod in preparation for glamor support + + Signed-off-by: Ben Skeggs + +commit e7cf48d9529160f7add2fef72d2e42be9370594a +Author: Ben Skeggs +Date: Thu Jun 19 14:54:20 2014 +1000 + + silence a warning + + Signed-off-by: Ben Skeggs + +commit 4a18dd74c0cc6e75937eb78347e8ea6c81d1373a +Author: Dave Airlie +Date: Mon May 26 17:30:24 2014 +1000 + + autogen: add support for gnome autobuilder + + Signed-off-by: Dave Airlie + +commit 8604a741baa5360164a882bd9f3c8474840744db +Author: Hans de Goede +Date: Fri Apr 11 14:20:43 2014 +0200 + + Fix building on older servers without xf86platformBus.h + + Signed-off-by: Hans de Goede + +commit 0c13843e300d1a9db2bfed18dc1b5df38c5adfdf +Author: Hans de Goede +Date: Mon Mar 17 17:37:31 2014 +0100 + + Add support for server managed fds + + v2 (Martin Peres): + - Do not define "NVEntPtr pNVEnt" if not needed to avoid some warnings + + Signed-off-by: Hans de Goede + Signed-off-by: Martin Peres + +commit 47f08aa6d713da4e6ae9c35ce691e790ffaed09d +Author: Hans de Goede +Date: Mon Mar 17 17:37:30 2014 +0100 + + Add a NVOpenNouveauDevice helper function + + This is a preparation patch for adding support for server managed fds + + Signed-off-by: Hans de Goede + Signed-off-by: Martin Peres + commit 480f0998ffed6d9a5c6656dba75182f00fd88a1b Author: Ben Skeggs Date: Thu Nov 7 14:56:48 2013 +1000 diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/config.h.in xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/config.h.in --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/config.h.in 2014-02-20 22:01:58.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/config.h.in 2014-07-14 14:55:37.000000000 +0000 @@ -5,12 +5,18 @@ /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H +/* Build support for glamor acceleration */ +#undef HAVE_GLAMOR + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* libudev support */ #undef HAVE_LIBUDEV +/* Define to 1 if you have the header file. */ +#undef HAVE_LIST_H + /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H @@ -38,6 +44,9 @@ /* xextproto 7.1 available */ #undef HAVE_XEXTPROTO_71 +/* Have xorg_list API */ +#undef HAVE_XORG_LIST + /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/configure xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/configure --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/configure 2014-02-20 22:01:57.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/configure 2014-07-14 14:55:36.000000000 +0000 @@ -19620,6 +19620,71 @@ +for ac_header in list.h +do : + ac_fn_c_check_header_compile "$LINENO" "list.h" "ac_cv_header_list_h" "#include + #include \"xorg-server.h\" +" +if test "x$ac_cv_header_list_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIST_H 1 +_ACEOF + have_list_h="yes" +else + have_list_h="no" +fi + +done + + +if test "x$have_list_h" = xyes; then + ac_fn_c_check_decl "$LINENO" "xorg_list_init" "ac_cv_have_decl_xorg_list_init" "#include + #include \"xorg-server.h\" + #include \"list.h\" +" +if test "x$ac_cv_have_decl_xorg_list_init" = xyes; then : + +$as_echo "#define HAVE_XORG_LIST 1" >>confdefs.h + +fi + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include GLAMOR support" >&5 +$as_echo_n "checking whether to include GLAMOR support... " >&6; } + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + found_glamor_header=yes +else + found_glamor_header=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test "$found_glamor_header" = "yes" && pkg-config --exists "xorg-server >= 1.15.99.901" +then + +$as_echo "#define HAVE_GLAMOR 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + ac_config_files="$ac_config_files Makefile src/Makefile man/Makefile" cat >confcache <<\_ACEOF diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/configure.ac xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/configure.ac --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/configure.ac 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/configure.ac 2014-07-14 14:55:28.000000000 +0000 @@ -127,6 +127,34 @@ XORG_MANPAGE_SECTIONS XORG_RELEASE_VERSION +AC_CHECK_HEADERS([list.h], + [have_list_h="yes"], [have_list_h="no"], + [#include + #include "xorg-server.h"]) + +if test "x$have_list_h" = xyes; then + AC_CHECK_DECL(xorg_list_init, + [AC_DEFINE(HAVE_XORG_LIST, 1, [Have xorg_list API])], [], + [#include + #include "xorg-server.h" + #include "list.h"]) +fi + +AC_MSG_CHECKING([whether to include GLAMOR support]) + +AC_COMPILE_IFELSE(AC_LANG_PROGRAM( +[[ + #include +]],[[]]),[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]) +else + AC_MSG_RESULT([no]) +fi + AC_CONFIG_FILES([ Makefile src/Makefile diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/debian/changelog xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/debian/changelog --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/debian/changelog 2014-07-14 14:58:14.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/debian/changelog 2014-07-14 14:58:15.000000000 +0000 @@ -1,11 +1,12 @@ -xserver-xorg-video-nouveau (1:1.0.10+git20140220.480f0998-0ubuntu0sarvatt) trusty; urgency=high +xserver-xorg-video-nouveau (1:1.0.10+git20140714.edd1608c-0ubuntu0sarvatt~trusty) trusty; urgency=high - * Checkout from git 20140220 (master branch) up to commit - 480f0998ffed6d9a5c6656dba75182f00fd88a1b + * Checkout from git 20140714 (master branch) up to commit + edd1608c397ebcf487b84948031f7807178e5e4d * Only added debian/ tree from origin/ubuntu * hook: Drop 01-set-NV_DRIVER_DATE-from-ChangeLog.diff (unneeded) + * hook: Drop xmir.patch (fails) - -- Robert Hooker Thu, 20 Feb 2014 17:01:59 -0500 + -- Robert Hooker Mon, 14 Jul 2014 10:55:39 -0400 xserver-xorg-video-nouveau (1:1.0.10-1ubuntu1) trusty; urgency=low diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/debian/patches/series xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/debian/patches/series --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/debian/patches/series 2014-07-14 14:58:14.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/debian/patches/series 2014-07-14 14:58:15.000000000 +0000 @@ -3,4 +3,4 @@ # Ubuntu patches 100-vblank-on.diff -xmir.patch +#xmir.patch diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/.lastcommit xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/.lastcommit --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/.lastcommit 2014-02-20 22:01:50.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/.lastcommit 2014-07-14 14:55:28.000000000 +0000 @@ -1 +1 @@ -commit 480f0998ffed6d9a5c6656dba75182f00fd88a1b +commit edd1608c397ebcf487b84948031f7807178e5e4d diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/man/nouveau.man xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/man/nouveau.man --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/man/nouveau.man 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/man/nouveau.man 2014-07-14 14:55:28.000000000 +0000 @@ -13,7 +13,7 @@ .fi .SH DESCRIPTION .B nouveau -is an __xservername__ driver for NVIDIA video cards. The driver supports 2D +is an __xservername__ driver for NVIDIA video cards. The driver supports 2D acceleration and provides support for the following framebuffer depths: (15,) 16 and 24. TrueColor visuals are supported for these depths. @@ -28,11 +28,11 @@ .B RIVA TNT2 NV5 .TP 22 -.B GeForce 256, QUADRO +.B GeForce 256, QUADRO NV10 .TP 22 .B GeForce2, QUADRO2 -NV11 & NV15 +NV11 & NV15 .TP 22 .B GeForce3, QUADRO DCC NV20 @@ -44,13 +44,26 @@ NV17, NV18, NV25, NV28 .TP 22 .B GeForce FX, QUADRO FX -NV30, NV31, NV34, NV35, NV36, NV37, NV38 +NV30, NV31, NV34, NV35, NV36, NV37, NV38 .TP 22 .B GeForce 6XXX -NV40, NV41, NV43, NV44, NV45, C51 +NV40, NV41, NV43, NV44, NV45, C51, MCP61 .TP 22 .B GeForce 7XXX -G70, G71, G72, G73 +G70, G71, G72, G73, MCP67, MCP68, MCP73 +.TP 22 +.B GeForce 8XXX, 9XXX, 2XX, 3XX +G80, G84, G86, G92, G94, G96, G98, G200, GT215, GT216, GT218, MCP77, +MCP79, MCP89 +.TP 22 +.B GeForce 4XX, 5XX +GF100, GF104, GF106, GF108, GF110, GF114, GF116, GF117, GF119 +.TP 22 +.B GeForce 6XX, 7XX +GK104, GK106, GK107, GK110, GK208 +.TP 22 +.B GeForce GTX 750 +GM107 .SH CONFIGURATION DETAILS Please refer to __xconfigfile__(__filemansuffix__) for general configuration @@ -67,6 +80,10 @@ .BI "Option \*qHWCursor\*q \*q" boolean \*q Enable or disable the HW cursor. Default: on. .TP +.BI "Option \*qAccelMethod\*q \*q" string \*q +Specify the acceleration method. One of \*qnone\*q, \*qexa\*q, or +\*qglamor\*q. Default: exa, except for GMxxx which default to glamor. +.TP .BI "Option \*qNoAccel\*q \*q" boolean \*q Disable or enable acceleration. Default: acceleration is enabled. .TP @@ -79,7 +96,7 @@ .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 -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/drmmode_display.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/drmmode_display.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/drmmode_display.c 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/drmmode_display.c 2014-07-14 14:55:28.000000000 +0000 @@ -42,6 +42,8 @@ #include "libudev.h" #endif +#include "nouveau_glamor.h" + static Bool drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height); typedef struct { int fd; @@ -85,21 +87,6 @@ drmmode_prop_ptr props; } drmmode_output_private_rec, *drmmode_output_private_ptr; -typedef struct { - drmmode_ptr drmmode; - unsigned old_fb_id; - int flip_count; - void *event_data; - unsigned int fe_frame; - unsigned int fe_tv_sec; - unsigned int fe_tv_usec; -} drmmode_flipdata_rec, *drmmode_flipdata_ptr; - -typedef struct { - drmmode_flipdata_ptr flipdata; - Bool dispatch_me; -} drmmode_flipevtcarrier_rec, *drmmode_flipevtcarrier_ptr; - static void drmmode_output_dpms(xf86OutputPtr output, int mode); static drmmode_ptr @@ -115,6 +102,134 @@ return NULL; } +static inline struct nouveau_pixmap * +drmmode_pixmap(PixmapPtr ppix) +{ + NVPtr pNv = NVPTR(xf86ScreenToScrn(ppix->drawable.pScreen)); + if (pNv->AccelMethod == GLAMOR) + return nouveau_glamor_pixmap_get(ppix); + return nouveau_pixmap(ppix); +} + +int +drmmode_head(xf86CrtcPtr crtc) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + return drmmode_crtc->mode_crtc->crtc_id; +} + +void +drmmode_swap(ScrnInfoPtr scrn, uint32_t next, uint32_t *prev) +{ + drmmode_ptr drmmode = drmmode_from_scrn(scrn); + *prev = drmmode->fb_id; + drmmode->fb_id = next; +} + +#if !HAVE_XORG_LIST +#define xorg_list list +#define xorg_list_for_each_entry list_for_each_entry +#define xorg_list_for_each_entry_safe list_for_each_entry_safe +#define xorg_list_append list_append +#define xorg_list_del list_del +#endif + +struct drmmode_event { + struct xorg_list head; + drmmode_ptr drmmode; + uint64_t name; + void (*func)(void *, uint64_t, uint64_t, uint32_t); +}; + +static struct xorg_list +drmmode_events = { + .next = &drmmode_events, + .prev = &drmmode_events, +}; + +static void +drmmode_event_handler(int fd, unsigned int frame, unsigned int tv_sec, + unsigned int tv_usec, void *event_data) +{ + const uint64_t ust = (uint64_t)tv_sec * 1000000 + tv_usec; + struct drmmode_event *e = event_data; + + xorg_list_for_each_entry(e, &drmmode_events, head) { + if (e == event_data) { + xorg_list_del(&e->head); + e->func((void *)(e + 1), e->name, ust, frame); + free(e); + break; + } + } +} + +void +drmmode_event_abort(ScrnInfoPtr scrn, uint64_t name, bool pending) +{ + drmmode_ptr drmmode = drmmode_from_scrn(scrn); + struct drmmode_event *e, *t; + + xorg_list_for_each_entry_safe(e, t, &drmmode_events, head) { + if (e->drmmode == drmmode && e->name == name) { + xorg_list_del(&e->head); + if (!pending) + free(e); + break; + } + } +} + +void * +drmmode_event_queue(ScrnInfoPtr scrn, uint64_t name, unsigned size, + void (*func)(void *, uint64_t, uint64_t, uint32_t), + void **event_data) +{ + drmmode_ptr drmmode = drmmode_from_scrn(scrn); + struct drmmode_event *e; + + e = *event_data = calloc(1, sizeof(*e) + size); + if (e) { + e->drmmode = drmmode; + e->name = name; + e->func = func; + xorg_list_append(&e->head, &drmmode_events); + return (void *)(e + 1); + } + + return NULL; +} + +int +drmmode_event_flush(ScrnInfoPtr scrn) +{ + drmmode_ptr drmmode = drmmode_from_scrn(scrn); + return drmHandleEvent(drmmode->fd, &drmmode->event_context); +} + +void +drmmode_event_fini(ScrnInfoPtr scrn) +{ + drmmode_ptr drmmode = drmmode_from_scrn(scrn); + struct drmmode_event *e, *t; + + xorg_list_for_each_entry_safe(e, t, &drmmode_events, head) { + if (e->drmmode == drmmode) { + xorg_list_del(&e->head); + free(e); + } + } +} + +void +drmmode_event_init(ScrnInfoPtr scrn) +{ + drmmode_ptr drmmode = drmmode_from_scrn(scrn); + drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION; + drmmode->event_context.vblank_handler = drmmode_event_handler; + drmmode->event_context.page_flip_handler = drmmode_event_handler; +} + static PixmapPtr drmmode_pixmap_wrap(ScreenPtr pScreen, int width, int height, int depth, int bpp, int pitch, struct nouveau_bo *bo, void *data) @@ -122,7 +237,7 @@ NVPtr pNv = NVPTR(xf86ScreenToScrn(pScreen)); PixmapPtr ppix; - if (!pNv->NoAccel) + if (pNv->AccelMethod > NONE) data = NULL; ppix = pScreen->CreatePixmap(pScreen, 0, 0, depth, 0); @@ -131,8 +246,8 @@ pScreen->ModifyPixmapHeader(ppix, width, height, depth, bpp, pitch, data); - if (!pNv->NoAccel) - nouveau_bo_ref(bo, &nouveau_pixmap(ppix)->bo); + if (pNv->AccelMethod > NONE) + nouveau_bo_ref(bo, &drmmode_pixmap(ppix)->bo); return ppix; } @@ -214,7 +329,7 @@ unsigned w = pScrn->virtualX, h = pScrn->virtualY; int i, ret, fbcon_id = 0; - if (pNv->NoAccel) + if (pNv->AccelMethod != EXA) goto fallback; for (i = 0; i < xf86_config->num_crtc; i++) { @@ -1221,16 +1336,16 @@ } ppix = screen->GetScreenPixmap(screen); - if (!pNv->NoAccel) - nouveau_bo_ref(pNv->scanout, &nouveau_pixmap(ppix)->bo); + if (pNv->AccelMethod >= NONE) + nouveau_bo_ref(pNv->scanout, &drmmode_pixmap(ppix)->bo); screen->ModifyPixmapHeader(ppix, width, height, -1, -1, pitch, - (!pNv->NoAccel || pNv->ShadowPtr) ? + (pNv->AccelMethod > NONE || pNv->ShadowPtr) ? pNv->ShadowPtr : pNv->scanout->map); #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 9 scrn->pixmapPrivate.ptr = ppix->devPrivate.ptr; #endif - if (!pNv->NoAccel) { + if (pNv->AccelMethod == EXA) { pNv->EXADriverPtr->PrepareSolid(ppix, GXcopy, ~0, 0); pNv->EXADriverPtr->Solid(ppix, 0, 0, width, height); pNv->EXADriverPtr->DoneSolid(ppix); @@ -1249,6 +1364,9 @@ crtc->rotation, crtc->x, crtc->y); } + if (pNv->AccelMethod == GLAMOR) + nouveau_glamor_create_screen_resources(scrn->pScreen); + if (old_fb_id) drmModeRmFB(drmmode->fd, old_fb_id); nouveau_bo_ref(NULL, &old_bo); @@ -1362,90 +1480,6 @@ return xf86_cursors_init(pScreen, size, size, flags); } -Bool -drmmode_page_flip(DrawablePtr draw, PixmapPtr back, void *priv, - unsigned int ref_crtc_hw_id) -{ - ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen); - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - drmmode_crtc_private_ptr crtc = config->crtc[0]->driver_private; - drmmode_ptr mode = crtc->drmmode; - int ret, i, old_fb_id; - int emitted = 0; - drmmode_flipdata_ptr flipdata; - drmmode_flipevtcarrier_ptr flipcarrier; - - old_fb_id = mode->fb_id; - ret = drmModeAddFB(mode->fd, scrn->virtualX, scrn->virtualY, - scrn->depth, scrn->bitsPerPixel, - scrn->displayWidth * scrn->bitsPerPixel / 8, - nouveau_pixmap_bo(back)->handle, &mode->fb_id); - if (ret) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "add fb failed: %s\n", strerror(errno)); - return FALSE; - } - - flipdata = calloc(1, sizeof(drmmode_flipdata_rec)); - if (!flipdata) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "flip queue: data alloc failed.\n"); - goto error_undo; - } - - flipdata->event_data = priv; - flipdata->drmmode = mode; - - for (i = 0; i < config->num_crtc; i++) { - crtc = config->crtc[i]->driver_private; - - if (!config->crtc[i]->enabled) - continue; - - flipdata->flip_count++; - - flipcarrier = calloc(1, sizeof(drmmode_flipevtcarrier_rec)); - if (!flipcarrier) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "flip queue: carrier alloc failed.\n"); - if (emitted == 0) - free(flipdata); - goto error_undo; - } - - /* Only the reference crtc will finally deliver its page flip - * completion event. All other crtc's events will be discarded. - */ - flipcarrier->dispatch_me = ((1 << i) == ref_crtc_hw_id); - flipcarrier->flipdata = flipdata; - - ret = drmModePageFlip(mode->fd, crtc->mode_crtc->crtc_id, - mode->fb_id, DRM_MODE_PAGE_FLIP_EVENT, - flipcarrier); - if (ret) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "flip queue failed: %s\n", strerror(errno)); - - free(flipcarrier); - if (emitted == 0) - free(flipdata); - goto error_undo; - } - - emitted++; - } - - /* Will release old fb after all crtc's completed flip. */ - flipdata->old_fb_id = old_fb_id; - - return TRUE; - -error_undo: - drmModeRmFB(mode->fd, mode->fb_id); - mode->fb_id = old_fb_id; - return FALSE; -} - #ifdef HAVE_LIBUDEV static void drmmode_handle_uevents(ScrnInfoPtr scrn) @@ -1510,42 +1544,6 @@ } static void -drmmode_flip_handler(int fd, unsigned int frame, unsigned int tv_sec, - unsigned int tv_usec, void *event_data) -{ - drmmode_flipevtcarrier_ptr flipcarrier = event_data; - drmmode_flipdata_ptr flipdata = flipcarrier->flipdata; - drmmode_ptr drmmode = flipdata->drmmode; - - /* Is this the event whose info shall be delivered to higher level? */ - if (flipcarrier->dispatch_me) { - /* Yes: Cache msc, ust for later delivery. */ - flipdata->fe_frame = frame; - flipdata->fe_tv_sec = tv_sec; - flipdata->fe_tv_usec = tv_usec; - } - free(flipcarrier); - - /* Last crtc completed flip? */ - flipdata->flip_count--; - if (flipdata->flip_count > 0) - return; - - /* Release framebuffer */ - drmModeRmFB(drmmode->fd, flipdata->old_fb_id); - - if (flipdata->event_data == NULL) { - free(flipdata); - return; - } - - /* Deliver cached msc, ust from reference crtc to flip event handler */ - nouveau_dri2_flip_event_handler(flipdata->fe_frame, flipdata->fe_tv_sec, - flipdata->fe_tv_usec, flipdata->event_data); - free(flipdata); -} - -static void drmmode_wakeup_handler(pointer data, int err, pointer p) { ScrnInfoPtr scrn = data; @@ -1570,18 +1568,14 @@ ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); drmmode_ptr drmmode = drmmode_from_scrn(scrn); - drmmode_uevent_init(scrn); - - /* Plug in a vblank event handler */ - drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION; - drmmode->event_context.vblank_handler = nouveau_dri2_vblank_handler; + /* Setup handler for DRM events */ + drmmode_event_init(scrn); - /* Plug in a pageflip completion event handler */ - drmmode->event_context.page_flip_handler = drmmode_flip_handler; - - AddGeneralSocket(drmmode->fd); + /* Setup handler for udevevents */ + drmmode_uevent_init(scrn); /* Register a wakeup handler to get informed on DRM events */ + AddGeneralSocket(drmmode->fd); RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, drmmode_wakeup_handler, scrn); } @@ -1592,10 +1586,14 @@ ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); drmmode_ptr drmmode = drmmode_from_scrn(scrn); - drmmode_uevent_fini(scrn); - - /* Register a wakeup handler to get informed on DRM events */ + /* Unregister wakeup handler */ RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, drmmode_wakeup_handler, scrn); RemoveGeneralSocket(drmmode->fd); + + /* Tear down udev event handler */ + drmmode_uevent_fini(scrn); + + /* Tear down DRM event handler */ + drmmode_event_fini(scrn); } diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/Makefile.am xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/Makefile.am --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/Makefile.am 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/Makefile.am 2014-07-14 14:55:28.000000000 +0000 @@ -30,10 +30,16 @@ nouveau_drv_ladir = @moduledir@/drivers nouveau_drv_la_SOURCES = \ + nouveau_copy.c \ + nouveau_copy85b5.c \ + nouveau_copy90b5.c \ + nouveau_copya0b5.c \ nouveau_exa.c nouveau_xv.c nouveau_dri2.c \ + nouveau_glamor.c \ + nouveau_present.c \ + nouveau_sync.c \ nouveau_wfb.c \ nv_accel_common.c \ - nv_dma.c \ nv_driver.c \ nv_shadow.c \ nv04_exa.c \ @@ -116,6 +122,10 @@ shader/xfrm2nvf0.vpc \ shader/Makefile \ nouveau_local.h \ + nouveau_copy.h \ + nouveau_glamor.h \ + nouveau_present.h \ + nouveau_sync.h \ nv_const.h \ nv_dma.h \ nv_include.h \ diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/Makefile.in xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/Makefile.in --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/Makefile.in 2014-02-20 22:01:59.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/Makefile.in 2014-07-14 14:55:38.000000000 +0000 @@ -139,13 +139,15 @@ am__installdirs = "$(DESTDIR)$(nouveau_drv_ladir)" LTLIBRARIES = $(nouveau_drv_la_LTLIBRARIES) nouveau_drv_la_LIBADD = -am_nouveau_drv_la_OBJECTS = nouveau_exa.lo nouveau_xv.lo \ - nouveau_dri2.lo nouveau_wfb.lo nv_accel_common.lo nv_dma.lo \ - nv_driver.lo nv_shadow.lo nv04_exa.lo nv04_xv_ovl.lo \ - nv04_xv_blit.lo nv10_exa.lo nv10_xv_ovl.lo nv30_exa.lo \ - nv30_xv_tex.lo nv40_exa.lo nv40_xv_tex.lo nv50_accel.lo \ - nv50_exa.lo nv50_xv.lo nvc0_accel.lo nvc0_exa.lo nvc0_xv.lo \ - drmmode_display.lo vl_hwmc.lo +am_nouveau_drv_la_OBJECTS = nouveau_copy.lo nouveau_copy85b5.lo \ + nouveau_copy90b5.lo nouveau_copya0b5.lo nouveau_exa.lo \ + nouveau_xv.lo nouveau_dri2.lo nouveau_glamor.lo \ + nouveau_present.lo nouveau_sync.lo nouveau_wfb.lo \ + nv_accel_common.lo nv_driver.lo nv_shadow.lo nv04_exa.lo \ + nv04_xv_ovl.lo nv04_xv_blit.lo nv10_exa.lo nv10_xv_ovl.lo \ + nv30_exa.lo nv30_xv_tex.lo nv40_exa.lo nv40_xv_tex.lo \ + nv50_accel.lo nv50_exa.lo nv50_xv.lo nvc0_accel.lo nvc0_exa.lo \ + nvc0_xv.lo drmmode_display.lo vl_hwmc.lo nouveau_drv_la_OBJECTS = $(am_nouveau_drv_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -379,10 +381,16 @@ nouveau_drv_ladir = @moduledir@/drivers nouveau_drv_la_SOURCES = \ + nouveau_copy.c \ + nouveau_copy85b5.c \ + nouveau_copy90b5.c \ + nouveau_copya0b5.c \ nouveau_exa.c nouveau_xv.c nouveau_dri2.c \ + nouveau_glamor.c \ + nouveau_present.c \ + nouveau_sync.c \ nouveau_wfb.c \ nv_accel_common.c \ - nv_dma.c \ nv_driver.c \ nv_shadow.c \ nv04_exa.c \ @@ -465,6 +473,10 @@ shader/xfrm2nvf0.vpc \ shader/Makefile \ nouveau_local.h \ + nouveau_copy.h \ + nouveau_glamor.h \ + nouveau_present.h \ + nouveau_sync.h \ nv_const.h \ nv_dma.h \ nv_include.h \ @@ -558,8 +570,15 @@ -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drmmode_display.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nouveau_copy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nouveau_copy85b5.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nouveau_copy90b5.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nouveau_copya0b5.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nouveau_dri2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nouveau_exa.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nouveau_glamor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nouveau_present.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nouveau_sync.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nouveau_wfb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nouveau_xv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nv04_exa.Plo@am__quote@ @@ -575,7 +594,6 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nv50_exa.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nv50_xv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nv_accel_common.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nv_dma.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nv_driver.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nv_shadow.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nvc0_accel.Plo@am__quote@ diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_copy85b5.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_copy85b5.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_copy85b5.c 1970-01-01 00:00:00.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_copy85b5.c 2014-07-14 14:55:28.000000000 +0000 @@ -0,0 +1,104 @@ +/* + * Copyright 2014 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 + */ + +#include "nouveau_copy.h" + +#include "hwdefs/nv_object.xml.h" +#include "nv50_accel.h" + +static Bool +nouveau_copy85b5_rect(struct nouveau_pushbuf *push, struct nouveau_object *copy, + int w, int h, int cpp, + struct nouveau_bo *src, uint32_t src_off, int src_dom, + int src_pitch, int src_h, int src_x, int src_y, + struct nouveau_bo *dst, uint32_t dst_off, int dst_dom, + int dst_pitch, int dst_h, int dst_x, int dst_y) +{ + struct nouveau_pushbuf_refn refs[] = { + { src, src_dom | NOUVEAU_BO_RD }, + { dst, dst_dom | NOUVEAU_BO_WR }, + }; + unsigned exec; + + if (nouveau_pushbuf_space(push, 64, 0, 0) || + nouveau_pushbuf_refn (push, refs, 2)) + return FALSE; + + exec = 0x00000000; + if (!src->config.nv50.memtype) { + src_off += src_y * src_pitch + src_x * cpp; + exec |= 0x00000010; + } + if (!dst->config.nv50.memtype) { + dst_off += dst_y * dst_pitch + dst_x * cpp; + exec |= 0x00000100; + } + + BEGIN_NV04(push, SUBC_COPY(0x0200), 7); + PUSH_DATA (push, src->config.nv50.tile_mode); + PUSH_DATA (push, src_pitch); + PUSH_DATA (push, src_h); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, src_x * cpp); + PUSH_DATA (push, src_y); + BEGIN_NV04(push, SUBC_COPY(0x0220), 7); + PUSH_DATA (push, dst->config.nv50.tile_mode); + PUSH_DATA (push, dst_pitch); + PUSH_DATA (push, dst_h); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, dst_x * cpp); + PUSH_DATA (push, dst_y); + BEGIN_NV04(push, SUBC_COPY(0x030c), 8); + PUSH_DATA (push, (src->offset + src_off) >> 32); + PUSH_DATA (push, (src->offset + src_off)); + PUSH_DATA (push, (dst->offset + dst_off) >> 32); + PUSH_DATA (push, (dst->offset + dst_off)); + PUSH_DATA (push, src_pitch); + PUSH_DATA (push, dst_pitch); + PUSH_DATA (push, w * cpp); + PUSH_DATA (push, h); + BEGIN_NV04(push, SUBC_COPY(0x0300), 1); + PUSH_DATA (push, exec); + return TRUE; +} + +Bool +nouveau_copy85b5_init(NVPtr pNv) +{ + struct nouveau_pushbuf *push = pNv->ce_pushbuf; + struct nv04_fifo *fifo = pNv->ce_channel->data; + if (PUSH_SPACE(push, 8)) { + BEGIN_NV04(push, NV01_SUBC(COPY, OBJECT), 1); + PUSH_DATA (push, pNv->NvCopy->handle); + BEGIN_NV04(push, SUBC_COPY(0x0180), 3); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, fifo->vram); + PUSH_DATA (push, fifo->vram); + pNv->ce_rect = nouveau_copy85b5_rect; + return TRUE; + } + return FALSE; +} diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_copy90b5.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_copy90b5.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_copy90b5.c 1970-01-01 00:00:00.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_copy90b5.c 2014-07-14 14:55:28.000000000 +0000 @@ -0,0 +1,100 @@ +/* + * Copyright 2014 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 + */ + +#include "nouveau_copy.h" + +#include "hwdefs/nv_object.xml.h" +#include "nvc0_accel.h" + +static Bool +nouveau_copy90b5_rect(struct nouveau_pushbuf *push, struct nouveau_object *copy, + int w, int h, int cpp, + struct nouveau_bo *src, uint32_t src_off, int src_dom, + int src_pitch, int src_h, int src_x, int src_y, + struct nouveau_bo *dst, uint32_t dst_off, int dst_dom, + int dst_pitch, int dst_h, int dst_x, int dst_y) +{ + struct nouveau_pushbuf_refn refs[] = { + { src, src_dom | NOUVEAU_BO_RD }, + { dst, dst_dom | NOUVEAU_BO_WR }, + }; + unsigned exec; + + if (nouveau_pushbuf_space(push, 64, 0, 0) || + nouveau_pushbuf_refn (push, refs, 2)) + return FALSE; + + exec = 0x00000000; + if (!src->config.nvc0.memtype) { + src_off += src_y * src_pitch + src_x * cpp; + exec |= 0x00000010; + } + if (!dst->config.nvc0.memtype) { + dst_off += dst_y * dst_pitch + dst_x * cpp; + exec |= 0x00000100; + } + + BEGIN_NVC0(push, SUBC_COPY(0x0200), 7); + PUSH_DATA (push, src->config.nvc0.tile_mode); + PUSH_DATA (push, src_pitch); + PUSH_DATA (push, src_h); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, src_x * cpp); + PUSH_DATA (push, src_y); + BEGIN_NVC0(push, SUBC_COPY(0x0220), 7); + PUSH_DATA (push, dst->config.nvc0.tile_mode); + PUSH_DATA (push, dst_pitch); + PUSH_DATA (push, dst_h); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, dst_x * cpp); + PUSH_DATA (push, dst_y); + BEGIN_NVC0(push, SUBC_COPY(0x030c), 8); + PUSH_DATA (push, (src->offset + src_off) >> 32); + PUSH_DATA (push, (src->offset + src_off)); + PUSH_DATA (push, (dst->offset + dst_off) >> 32); + PUSH_DATA (push, (dst->offset + dst_off)); + PUSH_DATA (push, src_pitch); + PUSH_DATA (push, dst_pitch); + PUSH_DATA (push, w * cpp); + PUSH_DATA (push, h); + BEGIN_NVC0(push, SUBC_COPY(0x0300), 1); + PUSH_DATA (push, exec); + + return TRUE; +} + +Bool +nouveau_copy90b5_init(NVPtr pNv) +{ + struct nouveau_pushbuf *push = pNv->ce_pushbuf; + if (PUSH_SPACE(push, 8)) { + BEGIN_NVC0(push, NV01_SUBC(COPY, OBJECT), 1); + PUSH_DATA (push, pNv->NvCopy->handle); + pNv->ce_rect = nouveau_copy90b5_rect; + return TRUE; + } + return FALSE; +} diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_copya0b5.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_copya0b5.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_copya0b5.c 1970-01-01 00:00:00.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_copya0b5.c 2014-07-14 14:55:28.000000000 +0000 @@ -0,0 +1,97 @@ +/* + * Copyright 2014 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 + */ + +#include "nouveau_copy.h" + +#include "hwdefs/nv_object.xml.h" +#include "nvc0_accel.h" + +Bool +nouveau_copya0b5_rect(struct nouveau_pushbuf *push, struct nouveau_object *copy, + int w, int h, int cpp, + struct nouveau_bo *src, uint32_t src_off, int src_dom, + int src_pitch, int src_h, int src_x, int src_y, + struct nouveau_bo *dst, uint32_t dst_off, int dst_dom, + int dst_pitch, int dst_h, int dst_x, int dst_y) +{ + struct nouveau_pushbuf_refn refs[] = { + { src, src_dom | NOUVEAU_BO_RD }, + { dst, dst_dom | NOUVEAU_BO_WR }, + }; + unsigned exec; + + if (nouveau_pushbuf_space(push, 64, 0, 0) || + nouveau_pushbuf_refn (push, refs, 2)) + return FALSE; + + exec = 0x00000206; + if (!src->config.nvc0.memtype) { + src_off += src_y * src_pitch + src_x * cpp; + exec |= 0x00000080; + } + if (!dst->config.nvc0.memtype) { + dst_off += dst_y * dst_pitch + dst_x * cpp; + exec |= 0x00000100; + } + + BEGIN_NVC0(push, SUBC_COPY(0x0728), 6); + PUSH_DATA (push, 0x00001000 | src->config.nvc0.tile_mode); + PUSH_DATA (push, src_pitch); + PUSH_DATA (push, src_h); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, (src_y << 16) | src_x * cpp); + BEGIN_NVC0(push, SUBC_COPY(0x070c), 6); + PUSH_DATA (push, 0x000001000 | dst->config.nvc0.tile_mode); + PUSH_DATA (push, dst_pitch); + PUSH_DATA (push, dst_h); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, (dst_y << 16) | dst_x * cpp); + BEGIN_NVC0(push, SUBC_COPY(0x0400), 8); + PUSH_DATA (push, (src->offset + src_off) >> 32); + PUSH_DATA (push, (src->offset + src_off)); + PUSH_DATA (push, (dst->offset + dst_off) >> 32); + PUSH_DATA (push, (dst->offset + dst_off)); + PUSH_DATA (push, src_pitch); + PUSH_DATA (push, dst_pitch); + PUSH_DATA (push, w * cpp); + PUSH_DATA (push, h); + BEGIN_NVC0(push, SUBC_COPY(0x0300), 1); + PUSH_DATA (push, exec); + return TRUE; +} + +Bool +nouveau_copya0b5_init(NVPtr pNv) +{ + struct nouveau_pushbuf *push = pNv->ce_pushbuf; + if (PUSH_SPACE(push, 8)) { + BEGIN_NVC0(push, NV01_SUBC(COPY, OBJECT), 1); + PUSH_DATA (push, pNv->NvCopy->handle); + pNv->ce_rect = nouveau_copya0b5_rect; + return TRUE; + } + return FALSE; +} diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_copy.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_copy.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_copy.c 1970-01-01 00:00:00.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_copy.c 2014-07-14 14:55:28.000000000 +0000 @@ -0,0 +1,129 @@ +/* + * Copyright 2014 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 + */ + +#include "nouveau_copy.h" + +void +nouveau_copy_fini(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + NVPtr pNv = NVPTR(pScrn); + nouveau_object_del(&pNv->NvCopy); + nouveau_pushbuf_del(&pNv->ce_pushbuf); + nouveau_object_del(&pNv->ce_channel); +} + +Bool +nouveau_copy_init(ScreenPtr pScreen) +{ + static const struct { + CARD32 oclass; + int engine; + Bool (*init)(NVPtr); + } methods[] = { + { 0xa0b5, 0, nouveau_copya0b5_init }, + { 0x90b8, 5, nouveau_copy90b5_init }, + { 0x90b5, 4, nouveau_copy90b5_init }, + { 0x85b5, 0, nouveau_copy85b5_init }, + {} + }, *method = methods; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + NVPtr pNv = NVPTR(pScrn); + void *data; + int ret, size; + + if (pNv->AccelMethod == NONE) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "[COPY] acceleration disabled\n"); + return FALSE; + } + + switch (pNv->Architecture) { + case NV_TESLA: + data = &(struct nv04_fifo) { + .vram = NvDmaFB, + .gart = NvDmaTT, + }; + size = sizeof(struct nv04_fifo); + break; + case NV_FERMI: + data = &(struct nvc0_fifo) {}; + size = sizeof(struct nvc0_fifo); + break; + case NV_KEPLER: + data = &(struct nve0_fifo) { + .engine = NVE0_FIFO_ENGINE_CE0 | + NVE0_FIFO_ENGINE_CE1, + }; + size = sizeof(struct nvc0_fifo); + break; + default: + return FALSE; + } + + ret = nouveau_object_new(&pNv->dev->object, 0, + NOUVEAU_FIFO_CHANNEL_CLASS, data, size, + &pNv->ce_channel); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[COPY} error allocating channel: %d\n", ret); + return FALSE; + } + + ret = nouveau_pushbuf_new(pNv->client, pNv->ce_channel, 4, + 32 * 1024, true, &pNv->ce_pushbuf); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[COPY] error allocating pushbuf: %d\n", ret); + nouveau_copy_fini(pScreen); + return FALSE; + } + + while (method->init) { + ret = nouveau_object_new(pNv->ce_channel, + method->engine << 16 | method->oclass, + method->oclass, NULL, 0, + &pNv->NvCopy); + if (ret == 0) { + if (!method->init(pNv)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[COPY] failed to initialise.\n"); + nouveau_copy_fini(pScreen); + return FALSE; + } + break; + } + method++; + } + + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[COPY] failed to allocate class.\n"); + nouveau_copy_fini(pScreen); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[COPY] async initialised.\n"); + return TRUE; +} diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_copy.h xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_copy.h --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_copy.h 1970-01-01 00:00:00.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_copy.h 2014-07-14 14:55:28.000000000 +0000 @@ -0,0 +1,18 @@ +#ifndef __NVDDX_COPY_H__ +#define __NVDDX_COPY_H__ + +#include "nv_include.h" +#include "nouveau_local.h" + +Bool nouveau_copy_init(ScreenPtr); +void nouveau_copy_fini(ScreenPtr); + +Bool nouveau_copy85b5_init(NVPtr); +Bool nouveau_copy90b5_init(NVPtr); +Bool nouveau_copya0b5_init(NVPtr); +Bool nouveau_copya0b5_rect(struct nouveau_pushbuf *, struct nouveau_object *, + int, int, int, struct nouveau_bo *, uint32_t, int, + int, int, int, int, struct nouveau_bo *, uint32_t, + int, int, int, int, int); + +#endif diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_dri2.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_dri2.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_dri2.c 2014-02-20 22:02:02.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_dri2.c 2014-07-14 14:55:28.000000000 +0000 @@ -11,6 +11,8 @@ #error "This driver requires a DRI2-enabled X server" #endif +#include "xf86drmMode.h" + struct nouveau_dri2_buffer { DRI2BufferRec base; PixmapPtr ppix; @@ -228,6 +230,12 @@ unsigned int frame; }; +struct dri2_vblank { + struct nouveau_dri2_vblank_state *s; +}; + +static uint64_t dri2_sequence; + static Bool update_front(DrawablePtr draw, DRI2BufferPtr front) { @@ -295,6 +303,263 @@ draw->width, draw->height); } +#if DRI2INFOREC_VERSION >= 6 +static Bool +nouveau_dri2_swap_limit_validate(DrawablePtr draw, int swap_limit) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen); + NVPtr pNv = NVPTR(scrn); + + if ((swap_limit < 1 ) || (swap_limit > pNv->max_swap_limit)) + return FALSE; + + return TRUE; +} +#endif + +/* Shall we intentionally violate the OML_sync_control spec to + * get some sort of triple-buffering behaviour on a pre 1.12.0 + * x-server? + */ +static Bool violate_oml(DrawablePtr draw) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen); + NVPtr pNv = NVPTR(scrn); + + return (DRI2INFOREC_VERSION < 6) && (pNv->swap_limit > 1); +} + +typedef struct { + int fd; + unsigned old_fb_id; + int flip_count; + void *event_data; + unsigned int fe_msc; + uint64_t fe_ust; +} dri2_flipdata_rec, *dri2_flipdata_ptr; + +typedef struct { + dri2_flipdata_ptr flipdata; + Bool dispatch_me; +} dri2_flipevtcarrier_rec, *dri2_flipevtcarrier_ptr; + +static void +nouveau_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec, + unsigned int tv_usec, void *event_data) +{ + struct nouveau_dri2_vblank_state *flip = event_data; + DrawablePtr draw; + ScreenPtr screen; + ScrnInfoPtr scrn; + int status; + + status = dixLookupDrawable(&draw, flip->draw, serverClient, + M_ANY, DixWriteAccess); + if (status != Success) { + free(flip); + return; + } + + screen = draw->pScreen; + scrn = xf86ScreenToScrn(screen); + + /* We assume our flips arrive in order, so we don't check the frame */ + switch (flip->action) { + case SWAP: + /* Check for too small vblank count of pageflip completion, + * taking wraparound into account. This usually means some + * defective kms pageflip completion, causing wrong (msc, ust) + * return values and possible visual corruption. + * Skip test for frame == 0, as this is a valid constant value + * reported by all Linux kernels at least up to Linux 3.0. + */ + if ((frame != 0) && + (frame < flip->frame) && (flip->frame - frame < 5)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "%s: Pageflip has impossible msc %d < target_msc %d\n", + __func__, frame, flip->frame); + /* All-Zero values signal failure of (msc, ust) + * timestamping to client. + */ + frame = tv_sec = tv_usec = 0; + } + + DRI2SwapComplete(flip->client, draw, frame, tv_sec, tv_usec, + DRI2_FLIP_COMPLETE, flip->func, + flip->data); + break; + default: + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "%s: unknown vblank event received\n", __func__); + /* Unknown type */ + break; + } + + free(flip); +} + +static void +nouveau_dri2_flip_handler(void *priv, uint64_t name, uint64_t ust, uint32_t msc) +{ + dri2_flipevtcarrier_ptr flipcarrier = priv; + dri2_flipdata_ptr flipdata = flipcarrier->flipdata; + + /* Is this the event whose info shall be delivered to higher level? */ + if (flipcarrier->dispatch_me) { + /* Yes: Cache msc, ust for later delivery. */ + flipdata->fe_msc = msc; + flipdata->fe_ust = ust; + } + + /* Last crtc completed flip? */ + flipdata->flip_count--; + if (flipdata->flip_count > 0) + return; + + /* Release framebuffer */ + drmModeRmFB(flipdata->fd, flipdata->old_fb_id); + + if (flipdata->event_data == NULL) { + free(flipdata); + return; + } + + /* Deliver cached msc, ust from reference crtc to flip event handler */ + nouveau_dri2_flip_event_handler(flipdata->fe_msc, + flipdata->fe_ust / 1000000, + flipdata->fe_ust % 1000000, + flipdata->event_data); + free(flipdata); +} + +static Bool +dri2_page_flip(DrawablePtr draw, PixmapPtr back, void *priv, + unsigned int ref_crtc_hw_id) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + NVPtr pNv = NVPTR(scrn); + uint32_t next_fb; + int emitted = 0; + int ret, i; + dri2_flipdata_ptr flipdata; + dri2_flipevtcarrier_ptr flipcarrier; + + ret = drmModeAddFB(pNv->dev->fd, scrn->virtualX, scrn->virtualY, + scrn->depth, scrn->bitsPerPixel, + scrn->displayWidth * scrn->bitsPerPixel / 8, + nouveau_pixmap(back)->bo->handle, &next_fb); + if (ret) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "add fb failed: %s\n", strerror(errno)); + return FALSE; + } + + flipdata = calloc(1, sizeof(dri2_flipdata_rec)); + if (!flipdata) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "flip queue: data alloc failed.\n"); + goto error_undo; + } + + flipdata->event_data = priv; + flipdata->fd = pNv->dev->fd; + + for (i = 0; i < config->num_crtc; i++) { + int head = drmmode_head(config->crtc[i]); + void *token; + + if (!config->crtc[i]->enabled) + continue; + + flipdata->flip_count++; + + flipcarrier = drmmode_event_queue(scrn, ++dri2_sequence, + sizeof(*flipcarrier), + nouveau_dri2_flip_handler, + &token); + if (!flipcarrier) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "flip queue: carrier alloc failed.\n"); + if (emitted == 0) + free(flipdata); + goto error_undo; + } + + /* Only the reference crtc will finally deliver its page flip + * completion event. All other crtc's events will be discarded. + */ + flipcarrier->dispatch_me = ((1 << i) == ref_crtc_hw_id); + flipcarrier->flipdata = flipdata; + + ret = drmModePageFlip(pNv->dev->fd, head, next_fb, + DRM_MODE_PAGE_FLIP_EVENT, token); + if (ret) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "flip queue failed: %s\n", strerror(errno)); + drmmode_event_abort(scrn, dri2_sequence--, false); + if (emitted == 0) + free(flipdata); + goto error_undo; + } + + emitted++; + } + + /* Will release old fb after all crtc's completed flip. */ + drmmode_swap(scrn, next_fb, &flipdata->old_fb_id); + return TRUE; + +error_undo: + drmModeRmFB(pNv->dev->fd, next_fb); + return FALSE; +} + +static void +nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame, + unsigned int tv_sec, unsigned int tv_usec, + struct nouveau_dri2_vblank_state *s); + +static void +nouveau_dri2_vblank_handler(void *priv, uint64_t name, uint64_t ust, uint32_t frame) +{ + struct dri2_vblank *event = priv; + struct nouveau_dri2_vblank_state *s = event->s; + uint32_t tv_sec = ust / 1000000; + uint32_t tv_usec = ust % 1000000; + DrawablePtr draw; + int ret; + + ret = dixLookupDrawable(&draw, s->draw, serverClient, + M_ANY, DixWriteAccess); + if (ret) { + free(s); + return; + } + + switch (s->action) { + case SWAP: + nouveau_dri2_finish_swap(draw, frame, tv_sec, tv_usec, s); +#if DRI2INFOREC_VERSION >= 6 + /* Restore real swap limit on drawable, now that it is safe. */ + ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen); + DRI2SwapLimit(draw, NVPTR(scrn)->swap_limit); +#endif + break; + + case WAIT: + DRI2WaitMSCComplete(s->client, draw, frame, tv_sec, tv_usec); + free(s); + break; + + case BLIT: + DRI2SwapComplete(s->client, draw, frame, tv_sec, tv_usec, + DRI2_BLIT_COMPLETE, s->func, s->data); + free(s); + break; + } +} + static int nouveau_wait_vblank(DrawablePtr draw, int type, CARD64 msc, CARD64 *pmsc, CARD64 *pust, void *data) @@ -304,16 +569,47 @@ int crtcs = nv_window_belongs_to_crtc(scrn, draw->x, draw->y, draw->width, draw->height); drmVBlank vbl; + struct dri2_vblank *event = NULL; + void *token = NULL; int ret; - vbl.request.type = type | (crtcs == 2 ? DRM_VBLANK_SECONDARY : 0); + if (type & DRM_VBLANK_EVENT) { + event = drmmode_event_queue(scrn, ++dri2_sequence, + sizeof(*event), + nouveau_dri2_vblank_handler, + &token); + if (!event) + return -ENOMEM; + + event->s = data; + } + + /* 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)data; + vbl.request.signal = (unsigned long)token; ret = drmWaitVBlank(pNv->dev->fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Wait for VBlank failed: %s\n", strerror(errno)); + if (event) + drmmode_event_abort(scrn, dri2_sequence--, false); return ret; } @@ -325,32 +621,6 @@ return 0; } -#if DRI2INFOREC_VERSION >= 6 -static Bool -nouveau_dri2_swap_limit_validate(DrawablePtr draw, int swap_limit) -{ - ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen); - NVPtr pNv = NVPTR(scrn); - - if ((swap_limit < 1 ) || (swap_limit > pNv->max_swap_limit)) - return FALSE; - - return TRUE; -} -#endif - -/* Shall we intentionally violate the OML_sync_control spec to - * get some sort of triple-buffering behaviour on a pre 1.12.0 - * x-server? - */ -static Bool violate_oml(DrawablePtr draw) -{ - ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen); - NVPtr pNv = NVPTR(scrn); - - return (DRI2INFOREC_VERSION < 6) && (pNv->swap_limit > 1); -} - static void nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, @@ -365,7 +635,7 @@ 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); @@ -376,11 +646,11 @@ 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. @@ -394,17 +664,28 @@ /* 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, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD }, 1); - if (pNv->Architecture >= NV_ARCH_C0) + if (pNv->Architecture >= NV_FERMI) NVC0SyncToVBlank(dst_pix, REGION_EXTENTS(0, ®)); else - if (pNv->Architecture >= NV_ARCH_50) + if (pNv->Architecture >= NV_TESLA) NV50SyncToVBlank(dst_pix, REGION_EXTENTS(0, ®)); else NV11SyncToVBlank(dst_pix, REGION_EXTENTS(0, ®)); @@ -412,15 +693,14 @@ 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, ®); if (nouveau_exa_pixmap_is_onscreen(dst_pix)) { type = DRI2_FLIP_COMPLETE; - ret = drmmode_page_flip(draw, src_pix, - violate_oml(draw) ? NULL : s, - ref_crtc_hw_id); + ret = dri2_page_flip(draw, src_pix, violate_oml(draw) ? + NULL : s, ref_crtc_hw_id); if (!ret) goto out; } @@ -671,101 +951,6 @@ return TRUE; } -void -nouveau_dri2_vblank_handler(int fd, unsigned int frame, - unsigned int tv_sec, unsigned int tv_usec, - void *event_data) -{ - struct nouveau_dri2_vblank_state *s = event_data; - DrawablePtr draw; - int ret; - - ret = dixLookupDrawable(&draw, s->draw, serverClient, - M_ANY, DixWriteAccess); - if (ret) { - free(s); - return; - } - - switch (s->action) { - case SWAP: - nouveau_dri2_finish_swap(draw, frame, tv_sec, tv_usec, s); -#if DRI2INFOREC_VERSION >= 6 - /* Restore real swap limit on drawable, now that it is safe. */ - ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen); - DRI2SwapLimit(draw, NVPTR(scrn)->swap_limit); -#endif - - break; - - case WAIT: - DRI2WaitMSCComplete(s->client, draw, frame, tv_sec, tv_usec); - free(s); - break; - - case BLIT: - DRI2SwapComplete(s->client, draw, frame, tv_sec, tv_usec, - DRI2_BLIT_COMPLETE, s->func, s->data); - free(s); - break; - } -} - -void -nouveau_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec, - unsigned int tv_usec, void *event_data) -{ - struct nouveau_dri2_vblank_state *flip = event_data; - DrawablePtr draw; - ScreenPtr screen; - ScrnInfoPtr scrn; - int status; - - status = dixLookupDrawable(&draw, flip->draw, serverClient, - M_ANY, DixWriteAccess); - if (status != Success) { - free(flip); - return; - } - - screen = draw->pScreen; - scrn = xf86ScreenToScrn(screen); - - /* We assume our flips arrive in order, so we don't check the frame */ - switch (flip->action) { - case SWAP: - /* Check for too small vblank count of pageflip completion, - * taking wraparound into account. This usually means some - * defective kms pageflip completion, causing wrong (msc, ust) - * return values and possible visual corruption. - * Skip test for frame == 0, as this is a valid constant value - * reported by all Linux kernels at least up to Linux 3.0. - */ - if ((frame != 0) && - (frame < flip->frame) && (flip->frame - frame < 5)) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "%s: Pageflip has impossible msc %d < target_msc %d\n", - __func__, frame, flip->frame); - /* All-Zero values signal failure of (msc, ust) - * timestamping to client. - */ - frame = tv_sec = tv_usec = 0; - } - - DRI2SwapComplete(flip->client, draw, frame, tv_sec, tv_usec, - DRI2_FLIP_COMPLETE, flip->func, - flip->data); - break; - default: - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "%s: unknown vblank event received\n", __func__); - /* Unknown type */ - break; - } - - free(flip); -} - Bool nouveau_dri2_init(ScreenPtr pScreen) { @@ -777,6 +962,9 @@ { "nouveau_vieux", "nouveau_vieux" } }; + if (pNv->AccelMethod != EXA) + return FALSE; + if (pNv->Architecture >= NV_ARCH_30) dri2.driverNames = drivernames[0]; else @@ -816,5 +1004,8 @@ void nouveau_dri2_fini(ScreenPtr pScreen) { - DRI2CloseScreen(pScreen); + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + NVPtr pNv = NVPTR(pScrn); + if (pNv->AccelMethod == EXA) + DRI2CloseScreen(pScreen); } diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_exa.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_exa.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_exa.c 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_exa.c 2014-07-14 14:55:28.000000000 +0000 @@ -47,26 +47,22 @@ struct nouveau_bo *src, int sd, int sp, int sh, int sx, int sy, struct nouveau_bo *dst, int dd, int dp, int dh, int dx, int dy) { - if (pNv->Architecture >= NV_ARCH_E0) + if (pNv->ce_rect && pNv->ce_enabled) + return pNv->ce_rect(pNv->ce_pushbuf, pNv->NvCopy, w, h, cpp, + src, srcoff, sd, sp, sh, sx, sy, + dst, dstoff, dd, dp, dh, dx, dy); + else + if (pNv->Architecture >= NV_KEPLER) return NVE0EXARectCopy(pNv, w, h, cpp, src, srcoff, sd, sp, sh, sx, sy, dst, dstoff, dd, dp, dh, dx, dy); else - if (pNv->Architecture >= NV_ARCH_C0 && pNv->NvCopy) - return NVC0EXARectCopy(pNv, w, h, cpp, - src, srcoff, sd, sp, sh, sx, sy, - dst, dstoff, dd, dp, dh, dx, dy); - if (pNv->Architecture >= NV_ARCH_C0) + if (pNv->Architecture >= NV_FERMI) return NVC0EXARectM2MF(pNv, w, h, cpp, src, srcoff, sd, sp, sh, sx, sy, dst, dstoff, dd, dp, dh, dx, dy); else - if (pNv->Architecture >= NV_ARCH_50 && pNv->NvCopy) - return NVA3EXARectCopy(pNv, w, h, cpp, - src, srcoff, sd, sp, sh, sx, sy, - dst, dstoff, dd, dp, dh, dx, dy); - else - if (pNv->Architecture >= NV_ARCH_50) + if (pNv->Architecture >= NV_TESLA) return NV50EXARectM2MF(pNv, w, h, cpp, src, srcoff, sd, sp, sh, sx, sy, dst, dstoff, dd, dp, dh, dx, dy); @@ -206,7 +202,7 @@ ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen); NVPtr pNv = NVPTR(pScrn); - return pNv->Architecture >= NV_ARCH_50 && + return pNv->Architecture >= NV_TESLA && nouveau_pixmap_bo(ppix)->config.nv50.memtype; } @@ -323,13 +319,13 @@ /* try hostdata transfer */ if (w * h * cpp < 16*1024) /* heuristic */ { - if (pNv->Architecture < NV_ARCH_50) { + if (pNv->Architecture < NV_TESLA) { if (NV04EXAUploadIFC(pScrn, src, src_pitch, pdpix, x, y, w, h, cpp)) { return TRUE; } } else - if (pNv->Architecture < NV_ARCH_C0) { + if (pNv->Architecture < NV_FERMI) { if (NV50EXAUploadSIFC(src, src_pitch, pdpix, x, y, w, h, cpp)) { return TRUE; @@ -401,6 +397,13 @@ return FALSE; } +static void +nouveau_exa_flush(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + nouveau_pushbuf_kick(pNv->pushbuf, pNv->pushbuf->channel); +} + Bool nouveau_exa_init(ScreenPtr pScreen) { @@ -408,11 +411,12 @@ NVPtr pNv = NVPTR(pScrn); ExaDriverPtr exa; + if (!xf86LoadSubModule(pScrn, "exa")) + return FALSE; + exa = exaDriverAlloc(); - if (!exa) { - pNv->NoAccel = TRUE; + if (!exa) return FALSE; - } exa->exa_major = EXA_VERSION_MAJOR; exa->exa_minor = EXA_VERSION_MINOR; @@ -437,7 +441,7 @@ exa->SetSharedPixmapBacking = nouveau_exa_set_shared_pixmap_backing; #endif - if (pNv->Architecture >= NV_ARCH_50) { + if (pNv->Architecture >= NV_TESLA) { exa->maxX = 8192; exa->maxY = 8192; } else @@ -455,7 +459,7 @@ exa->DownloadFromScreen = nouveau_exa_download_from_screen; exa->UploadToScreen = nouveau_exa_upload_to_screen; - if (pNv->Architecture < NV_ARCH_50) { + if (pNv->Architecture < NV_TESLA) { exa->PrepareCopy = NV04EXAPrepareCopy; exa->Copy = NV04EXACopy; exa->DoneCopy = NV04EXADoneCopy; @@ -464,7 +468,7 @@ exa->Solid = NV04EXASolid; exa->DoneSolid = NV04EXADoneSolid; } else - if (pNv->Architecture < NV_ARCH_C0) { + if (pNv->Architecture < NV_FERMI) { exa->PrepareCopy = NV50EXAPrepareCopy; exa->Copy = NV50EXACopy; exa->DoneCopy = NV50EXADoneCopy; @@ -502,19 +506,20 @@ exa->Composite = NV40EXAComposite; exa->DoneComposite = NV40EXADoneComposite; break; - case NV_ARCH_50: + case NV_TESLA: exa->CheckComposite = NV50EXACheckComposite; exa->PrepareComposite = NV50EXAPrepareComposite; exa->Composite = NV50EXAComposite; exa->DoneComposite = NV50EXADoneComposite; break; - case NV_ARCH_C0: - case NV_ARCH_E0: + case NV_FERMI: + case NV_KEPLER: exa->CheckComposite = NVC0EXACheckComposite; exa->PrepareComposite = NVC0EXAPrepareComposite; exa->Composite = NVC0EXAComposite; exa->DoneComposite = NVC0EXADoneComposite; break; + case NV_MAXWELL: default: break; } @@ -523,5 +528,6 @@ return FALSE; pNv->EXADriverPtr = exa; + pNv->Flush = nouveau_exa_flush; return TRUE; } diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_glamor.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_glamor.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_glamor.c 1970-01-01 00:00:00.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_glamor.c 2014-07-14 14:55:28.000000000 +0000 @@ -0,0 +1,246 @@ +/* + * Copyright 2014 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 + */ + +#include "nouveau_glamor.h" +#ifdef HAVE_GLAMOR + +static DevPrivateKeyRec glamor_private; + +void +nouveau_glamor_pixmap_set(PixmapPtr pixmap, struct nouveau_pixmap *priv) +{ + dixSetPrivate(&pixmap->devPrivates, &glamor_private, priv); +} + +struct nouveau_pixmap * +nouveau_glamor_pixmap_get(PixmapPtr pixmap) +{ + return dixGetPrivate(&pixmap->devPrivates, &glamor_private); +} + +static Bool +nouveau_glamor_destroy_pixmap(PixmapPtr pixmap) +{ + struct nouveau_pixmap *priv = nouveau_glamor_pixmap_get(pixmap); + if (pixmap->refcnt == 1) { + glamor_egl_destroy_textured_pixmap(pixmap); + if (priv) + nouveau_bo_ref(NULL, &priv->bo); + } + fbDestroyPixmap(pixmap); + return TRUE; +} + +static PixmapPtr +nouveau_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, + unsigned usage) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct nouveau_pixmap *priv; + PixmapPtr pixmap; + int pitch; + + if (usage != CREATE_PIXMAP_USAGE_SHARED) + return glamor_create_pixmap(screen, w, h, depth, usage); + if (depth == 1) + return fbCreatePixmap(screen, w, h, depth, usage); + if (w > 32767 || h > 32767) + return NullPixmap; + + pixmap = fbCreatePixmap(screen, 0, 0, depth, usage); + if (pixmap == NullPixmap || !w || !h) + return pixmap; + + priv = calloc(1, sizeof(*priv)); + if (!priv) + goto fail_priv; + + if (!nouveau_allocate_surface(scrn, w, h, + pixmap->drawable.bitsPerPixel, + usage, &pitch, &priv->bo)) + goto fail_bo; + + nouveau_glamor_pixmap_set(pixmap, priv); + screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL); + + if (!glamor_egl_create_textured_pixmap(pixmap, priv->bo->handle, + pixmap->devKind)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "[GLAMOR] failed to create textured PRIME pixmap."); + return pixmap; + } + + return pixmap; +fail_bo: + free(priv); +fail_priv: + fbDestroyPixmap(pixmap); + return fbCreatePixmap(screen, w, h, depth, usage); +} + +static Bool +nouveau_glamor_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, + void **phandle) +{ + struct nouveau_pixmap *priv = nouveau_glamor_pixmap_get(pixmap); + int ret, handle; + + ret = nouveau_bo_set_prime(priv->bo, &handle); + if (ret) + return FALSE; + + priv->shared = TRUE; + *phandle = (void *)(long)handle; + return TRUE; +} + +static Bool +nouveau_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void *_handle) +{ + struct nouveau_pixmap *priv = nouveau_glamor_pixmap_get(pixmap); + ScreenPtr screen = pixmap->drawable.pScreen; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + NVPtr pNv = NVPTR(scrn); + struct nouveau_bo *bo; + int ret, handle = (int)(long)_handle; + + ret = nouveau_bo_prime_handle_ref(pNv->dev, handle, &bo); + if (ret) + return FALSE; + + priv->bo = bo; + priv->shared = TRUE; + close(handle); + + if (!glamor_egl_create_textured_pixmap(pixmap, priv->bo->handle, + pixmap->devKind)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "[GLAMOR] failed to get PRIME drawable\n"); + return FALSE; + } + + return TRUE; +} + +static void +nouveau_glamor_flush(ScrnInfoPtr pScrn) +{ + glamor_block_handler(pScrn->pScreen); +} + +Bool +nouveau_glamor_create_screen_resources(ScreenPtr screen) +{ + PixmapPtr ppix = screen->GetScreenPixmap(screen); + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + NVPtr pNv = NVPTR(scrn); + + if (!glamor_glyphs_init(screen)) + return FALSE; + + if (!glamor_egl_create_textured_screen_ext(screen, + pNv->scanout->handle, + scrn->displayWidth * + scrn->bitsPerPixel / 8, + NULL)) + return FALSE; + + if (!nouveau_glamor_pixmap_get(ppix)) { + struct nouveau_pixmap *priv = calloc(1, sizeof(*priv)); + if (priv) { + nouveau_bo_ref(pNv->scanout, &priv->bo); + nouveau_glamor_pixmap_set(ppix, priv); + } + } + + return TRUE; +} + +Bool +nouveau_glamor_pre_init(ScrnInfoPtr scrn) +{ + NVPtr pNv = NVPTR(scrn); + pointer glamor_module; + + if (scrn->depth < 24) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "[GLAMOR] requires depth >= 24\n"); + return FALSE; + } + + if ((glamor_module = xf86LoadSubModule(scrn, GLAMOR_EGL_MODULE_NAME))) { + if (!glamor_egl_init(scrn, pNv->dev->fd)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "[GLAMOR] failed to initialise EGL\n"); + return FALSE; + } + } else { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, "[GLAMOR] unavailable\n"); + return FALSE; + } + + xf86DrvMsg(scrn->scrnIndex, X_INFO, "[GLAMOR] EGL initialised\n"); + return TRUE; +} + +Bool +nouveau_glamor_init(ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + NVPtr pNv = NVPTR(scrn); + + if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS | + GLAMOR_USE_EGL_SCREEN | + GLAMOR_USE_SCREEN | + GLAMOR_USE_PICTURE_SCREEN)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "[GLAMOR] failed to initialise\n"); + return FALSE; + } + + if (!glamor_egl_init_textured_pixmap(screen)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "[GLAMOR] failed to initialize screen pixmap\n"); + return FALSE; + } + + if (!dixRegisterPrivateKey(&glamor_private, PRIVATE_PIXMAP, 0)) + return FALSE; + + screen->CreatePixmap = nouveau_glamor_create_pixmap; + screen->DestroyPixmap = nouveau_glamor_destroy_pixmap; + screen->SharePixmapBacking = nouveau_glamor_share_pixmap_backing; + screen->SetSharedPixmapBacking = nouveau_glamor_set_shared_pixmap_backing; + + xf86DrvMsg(scrn->scrnIndex, X_INFO, "[GLAMOR] initialised\n"); + pNv->Flush = nouveau_glamor_flush; + return TRUE; +} + +XF86VideoAdaptorPtr +nouveau_glamor_xv_init(ScreenPtr pScreen, int num_adapt) +{ + return glamor_xv_init(pScreen, num_adapt); +} +#endif diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_glamor.h xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_glamor.h --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_glamor.h 1970-01-01 00:00:00.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_glamor.h 2014-07-14 14:55:28.000000000 +0000 @@ -0,0 +1,33 @@ +#ifndef __NOUVEAU_GLAMOR_H__ +#define __NOUVEAU_GLAMOR_H__ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "xf86xv.h" + +#ifdef HAVE_GLAMOR +#include "nv_include.h" +#define GLAMOR_FOR_XORG 1 +#include "glamor.h" + +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 pixmap, void *priv) { } +static inline struct nouveau_pixmap * +nouveau_glamor_pixmap_get(PixmapPtr pixmap) { return NULL; } +static inline XF86VideoAdaptorPtr +nouveau_glamor_xv_init(ScreenPtr pScreen, int num_adapt) { return NULL; } +#endif + +#endif diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_present.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_present.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_present.c 1970-01-01 00:00:00.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_present.c 2014-07-14 14:55:28.000000000 +0000 @@ -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 + */ + +#include "nouveau_present.h" +#if defined(DRI3) && defined(HAVE_GLAMOR) +#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) { + int fd = glamor_fd_from_pixmap(screen, pixmap, &stride, &size); + if (fd < 0) + return FALSE; + + priv = calloc(1, sizeof(*priv)); + if (!priv) + return FALSE; + + ret = nouveau_bo_prime_handle_ref(pNv->dev, fd, &priv->bo); + if (ret) { + free(priv); + return FALSE; + } + + nouveau_glamor_pixmap_set(pixmap, priv); + } + + ret = drmModeAddFB(pNv->dev->fd, pixmap->drawable.width, + pixmap->drawable.height, pixmap->drawable.depth, + pixmap->drawable.bitsPerPixel, pixmap->devKind, + priv->bo->handle, &next_fb); + if (ret == 0) { + struct nouveau_present_flip *flip = + drmmode_event_queue(scrn, event_id, sizeof(*flip), + nouveau_present_flip, &token); + if (flip) { + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int last = 0, i; + + drmmode_swap(scrn, next_fb, &flip->old); + flip->fd = pNv->dev->fd; + flip->msc = target_msc; + + for (i = 0; i < config->num_crtc; i++) { + if (config->crtc[i]->enabled) + last = i; + } + + for (i = 0; i < config->num_crtc; i++) { + int type = vsync ? 0 : DRM_MODE_PAGE_FLIP_ASYNC; + int head = drmmode_head(config->crtc[i]); + void *user = NULL; + + if (!config->crtc[i]->enabled) + continue; + + if (token && ((head == sync) || (i == last))) { + type |= DRM_MODE_PAGE_FLIP_EVENT; + user = token; + } + + ret = drmModePageFlip(pNv->dev->fd, head, + next_fb, type, user); + if (ret == 0 && user) { + token = NULL; + } + } + + if (token == NULL) { + return TRUE; + } + + drmmode_swap(scrn, flip->old, &next_fb); + drmmode_event_abort(scrn, event_id, false); + } + + drmModeRmFB(pNv->dev->fd, next_fb); + } + + return FALSE; +} + +static Bool +nouveau_present_flip_next(RRCrtcPtr rrcrtc, uint64_t event_id, + uint64_t target_msc, PixmapPtr pixmap, Bool vsync) +{ + xf86CrtcPtr crtc = rrcrtc->devPrivate; + ScrnInfoPtr scrn = crtc->scrn; + return nouveau_present_flip_exec(scrn, event_id, drmmode_head(crtc), + target_msc, pixmap, vsync); +} + +static void +nouveau_present_flip_stop(ScreenPtr screen, uint64_t event_id) +{ + PixmapPtr pixmap = screen->GetScreenPixmap(screen); + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + nouveau_present_flip_exec(scrn, event_id, 0, 0, pixmap, TRUE); +} + +void +nouveau_present_fini(ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + NVPtr pNv = NVPTR(scrn); + if (pNv->present) { + free(pNv->present); + pNv->present = NULL; + } +} + +int +nouveau_present_init(ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + NVPtr pNv = NVPTR(scrn); + struct nouveau_present *present; + uint64_t value; + int ret; + + if (pNv->AccelMethod != GLAMOR) + return -ENOSYS; + + present = pNv->present = calloc(1, sizeof(*present)); + if (!present) + return -ENOMEM; + + present->info.version = PRESENT_SCREEN_INFO_VERSION; + present->info.get_crtc = nouveau_present_crtc; + present->info.get_ust_msc = nouveau_present_ust_msc; + present->info.queue_vblank = nouveau_present_vblank_queue; + present->info.abort_vblank = nouveau_present_vblank_abort; + present->info.flush = nouveau_present_flush; + + if (pNv->has_pageflip) { +#ifdef DRM_CAP_ASYNC_PAGE_FLIP + ret = drmGetCap(pNv->dev->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value); + if (ret == 0 && value == 1) + present->info.capabilities |= PresentCapabilityAsync; +#endif + present->info.check_flip = nouveau_present_flip_check; + present->info.flip = nouveau_present_flip_next; + present->info.unflip = nouveau_present_flip_stop; + } + + return present_screen_init(screen, &present->info); +} +#endif diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_present.h xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_present.h --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_present.h 1970-01-01 00:00:00.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_present.h 2014-07-14 14:55:28.000000000 +0000 @@ -0,0 +1,19 @@ +#ifndef __NOUVEAU_PRESENT_H__ +#define __NOUVEAU_PRESENT_H__ + +#include "xorg-server.h" +#include "scrnintstr.h" + +#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); +#else +static inline Bool nouveau_present_init(ScreenPtr pScreen) { return FALSE; } +static inline void nouveau_present_fini(ScreenPtr pScreen) { } +#endif +#endif diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_sync.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_sync.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_sync.c 1970-01-01 00:00:00.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_sync.c 2014-07-14 14:55:28.000000000 +0000 @@ -0,0 +1,117 @@ +/* + * Copyright © 2013-2014 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "nouveau_sync.h" +#ifdef DRI3 +#include "nv_include.h" + +static DevPrivateKeyRec nouveau_syncobj_key; + +struct nouveau_syncobj { + SyncFenceSetTriggeredFunc SetTriggered; +}; + +#define nouveau_syncobj(fence) \ + dixLookupPrivate(&(fence)->devPrivates, &nouveau_syncobj_key) + +struct nouveau_syncctx { + SyncScreenCreateFenceFunc CreateFence; +}; + +#define nouveau_syncctx(screen) ({ \ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); \ + NVPtr pNv = NVPTR(scrn); \ + pNv->sync; \ +}) + +static void +nouveau_syncobj_flush(SyncFence *fence) +{ + struct nouveau_syncobj *pobj = nouveau_syncobj(fence); + ScrnInfoPtr scrn = xf86ScreenToScrn(fence->pScreen); + NVPtr pNv = NVPTR(scrn); + SyncFenceFuncsPtr func = &fence->funcs; + + if (pNv->Flush) + pNv->Flush(scrn); + + swap(pobj, func, SetTriggered); + func->SetTriggered(fence); + swap(pobj, func, SetTriggered); +} + +static void +nouveau_syncobj_new(ScreenPtr screen, SyncFence *fence, Bool triggered) +{ + struct nouveau_syncctx *priv = nouveau_syncctx(screen); + struct nouveau_syncobj *pobj = nouveau_syncobj(fence); + SyncScreenFuncsPtr sync = miSyncGetScreenFuncs(screen); + SyncFenceFuncsPtr func = &fence->funcs; + + swap(priv, sync, CreateFence); + sync->CreateFence(screen, fence, triggered); + swap(priv, sync, CreateFence); + + wrap(pobj, func, SetTriggered, nouveau_syncobj_flush); +} + +void +nouveau_sync_fini(ScreenPtr screen) +{ + struct nouveau_syncctx *priv = nouveau_syncctx(screen); + SyncScreenFuncsPtr sync = miSyncGetScreenFuncs(screen); + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + NVPtr pNv = NVPTR(scrn); + + unwrap(priv, sync, CreateFence); + + pNv->sync = NULL; + free(priv); +} + +Bool +nouveau_sync_init(ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + NVPtr pNv = NVPTR(scrn); + struct nouveau_syncctx *priv; + SyncScreenFuncsPtr sync; + + priv = pNv->sync = calloc(1, sizeof(*priv)); + if (!priv) + return FALSE; + + if (!miSyncShmScreenInit(screen)) + return FALSE; + + if (!dixPrivateKeyRegistered(&nouveau_syncobj_key)) { + if (!dixRegisterPrivateKey(&nouveau_syncobj_key, + PRIVATE_SYNC_FENCE, + sizeof(struct nouveau_syncobj))) + return FALSE; + } + + sync = miSyncGetScreenFuncs(screen); + wrap(priv, sync, CreateFence, nouveau_syncobj_new); + return TRUE; +} +#endif diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_sync.h xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_sync.h --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_sync.h 1970-01-01 00:00:00.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_sync.h 2014-07-14 14:55:28.000000000 +0000 @@ -0,0 +1,34 @@ +#ifndef __NOUVEAU_SYNC_H__ +#define __NOUVEAU_SYNC_H__ + +#include "xorg-server.h" +#include "scrnintstr.h" + +#ifdef DRI3 +#include "misync.h" +#include "misyncshm.h" +#include "misyncstr.h" + +#define wrap(priv, parn, name, func) { \ + priv->name = parn->name; \ + parn->name = func; \ +} + +#define unwrap(priv, parn, name) { \ + if (priv && priv->name) \ + parn->name = priv->name; \ +} + +#define swap(priv, parn, name) { \ + void *tmp = priv->name; \ + priv->name = parn->name; \ + parn->name = tmp; \ +} + +Bool nouveau_sync_init(ScreenPtr pScreen); +void nouveau_sync_fini(ScreenPtr pScreen); +#else +static inline Bool nouveau_sync_init(ScreenPtr pScreen) { return FALSE; } +static inline void nouveau_sync_fini(ScreenPtr pScreen) { } +#endif +#endif diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_wfb.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_wfb.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_wfb.c 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_wfb.c 2014-07-14 14:55:28.000000000 +0000 @@ -26,6 +26,7 @@ */ #include "nv_include.h" +#include "nouveau_glamor.h" struct wfb_pixmap { PixmapPtr ppix; @@ -134,8 +135,15 @@ return; ppix = NVGetDrawablePixmap(pDraw); - if (ppix) - bo = nouveau_pixmap_bo(ppix); + if (ppix) { + NVPtr pNv = NVPTR(xf86ScreenToScrn(pDraw->pScreen)); + struct nouveau_pixmap *priv; + if (pNv->AccelMethod == GLAMOR) + priv = nouveau_glamor_pixmap_get(ppix); + else + priv = nouveau_pixmap(ppix); + bo = priv ? priv->bo : NULL; + } if (!ppix || !bo) { for (i = 0; i < 6; i++) diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_xv.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_xv.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nouveau_xv.c 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nouveau_xv.c 2014-07-14 14:55:28.000000000 +0000 @@ -38,7 +38,7 @@ #include "nv_include.h" #include "nv_dma.h" - +#include "nouveau_glamor.h" #include "vl_hwmc.h" @@ -257,10 +257,10 @@ } if (flags & NOUVEAU_BO_VRAM) { - if (pNv->Architecture == NV_ARCH_50) + if (pNv->Architecture == NV_TESLA) config.nv50.memtype = 0x70; else - if (pNv->Architecture >= NV_ARCH_C0) + if (pNv->Architecture >= NV_FERMI) config.nvc0.memtype = 0xfe; } flags |= NOUVEAU_BO_MAP; @@ -729,7 +729,7 @@ { int tmp; - if (pNv->Architecture >= NV_ARCH_50) { + if (pNv->Architecture >= NV_TESLA) { npixels = (npixels + 7) & ~7; nlines = (nlines + 7) & ~7; } @@ -1080,7 +1080,7 @@ pPriv->TT_mem_chunk[pPriv->currentHostBuffer]; } if (!destination_buffer) { - if (pNv->Architecture >= NV_ARCH_50) { + if (pNv->Architecture >= NV_TESLA) { NOUVEAU_ERR("No scratch buffer for tiled upload\n"); return BadAlloc; } @@ -1283,7 +1283,7 @@ src_w, src_h, drw_w, drw_h, clipBoxes, ppix, pPriv); } else - if (pNv->Architecture == NV_ARCH_50) { + if (pNv->Architecture == NV_TESLA) { ret = nv50_xv_image_put(pScrn, pPriv->video_mem, offset, uv_offset, id, dstPitch, &dstBox, 0, 0, @@ -2048,7 +2048,7 @@ textureAdaptor[0] = NV40SetupTexturedVideo(pScreen, FALSE); textureAdaptor[1] = NV40SetupTexturedVideo(pScreen, TRUE); } else - if (pNv->Architecture >= NV_ARCH_50) { + if (pNv->Architecture >= NV_TESLA && pNv->Architecture < NV_MAXWELL) { textureAdaptor[0] = NV50SetupTexturedVideo(pScreen); } } @@ -2079,15 +2079,18 @@ * might work without accel, we also disable it for now when * acceleration is disabled: */ - if (pScrn->bitsPerPixel != 8 && !pNv->NoAccel) { + if (pScrn->bitsPerPixel != 8 && pNv->AccelMethod == EXA) { xvSyncToVBlank = MAKE_ATOM("XV_SYNC_TO_VBLANK"); - if (pNv->Architecture < NV_ARCH_50) { + if (pNv->Architecture < NV_TESLA) { overlayAdaptor = NVSetupOverlayVideo(pScreen); blitAdaptor = NVSetupBlitVideo(pScreen); } NVSetupTexturedVideo(pScreen, textureAdaptor); + } else + if (pNv->AccelMethod == GLAMOR) { + blitAdaptor = nouveau_glamor_xv_init(pScreen, 16); } num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv04_exa.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv04_exa.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv04_exa.c 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv04_exa.c 2014-07-14 14:55:28.000000000 +0000 @@ -289,7 +289,7 @@ int padbytes; Bool ret = FALSE; - if (pNv->Architecture >= NV_ARCH_50) + if (pNv->Architecture >= NV_TESLA) return FALSE; if (h > 1024) diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv50_accel.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv50_accel.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv50_accel.c 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv50_accel.c 2014-07-14 14:55:28.000000000 +0000 @@ -84,29 +84,6 @@ } Bool -NVAccelInitCopy_NV50(ScrnInfoPtr pScrn) -{ - NVPtr pNv = NVPTR(pScrn); - struct nouveau_pushbuf *push = pNv->ce_pushbuf; - struct nv04_fifo *fifo = pNv->ce_channel->data; - - if (nouveau_object_new(pNv->ce_channel, 0xbeef85b5, 0x85b5, - NULL, 0, &pNv->NvCopy)) - return FALSE; - - if (!PUSH_SPACE(push, 8)) - return FALSE; - - BEGIN_NV04(push, NV01_SUBC(COPY, OBJECT), 1); - PUSH_DATA (push, pNv->NvCopy->handle); - BEGIN_NV04(push, SUBC_COPY(0x0180), 3); - PUSH_DATA (push, fifo->vram); - PUSH_DATA (push, fifo->vram); - PUSH_DATA (push, fifo->vram); - return TRUE; -} - -Bool NVAccelInit2D_NV50(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv50_exa.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv50_exa.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv50_exa.c 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv50_exa.c 2014-07-14 14:55:28.000000000 +0000 @@ -1011,62 +1011,3 @@ return TRUE; } - -Bool -NVA3EXARectCopy(NVPtr pNv, int w, int h, int cpp, - struct nouveau_bo *src, uint32_t src_off, int src_dom, - int src_pitch, int src_h, int src_x, int src_y, - struct nouveau_bo *dst, uint32_t dst_off, int dst_dom, - int dst_pitch, int dst_h, int dst_x, int dst_y) -{ - struct nouveau_pushbuf *push = pNv->ce_pushbuf; - struct nouveau_pushbuf_refn refs[] = { - { src, src_dom | NOUVEAU_BO_RD }, - { dst, dst_dom | NOUVEAU_BO_WR }, - }; - unsigned exec; - - if (nouveau_pushbuf_space(push, 64, 0, 0) || - nouveau_pushbuf_refn (push, refs, 2)) - return FALSE; - - exec = 0x00000000; - if (!src->config.nv50.memtype) { - src_off += src_y * src_pitch + src_x * cpp; - exec |= 0x00000010; - } - if (!dst->config.nv50.memtype) { - dst_off += dst_y * dst_pitch + dst_x * cpp; - exec |= 0x00000100; - } - - BEGIN_NV04(push, SUBC_COPY(0x0200), 7); - PUSH_DATA (push, src->config.nv50.tile_mode); - PUSH_DATA (push, src_pitch); - PUSH_DATA (push, src_h); - PUSH_DATA (push, 1); - PUSH_DATA (push, 0); - PUSH_DATA (push, src_x * cpp); - PUSH_DATA (push, src_y); - BEGIN_NV04(push, SUBC_COPY(0x0220), 7); - PUSH_DATA (push, dst->config.nv50.tile_mode); - PUSH_DATA (push, dst_pitch); - PUSH_DATA (push, dst_h); - PUSH_DATA (push, 1); - PUSH_DATA (push, 0); - PUSH_DATA (push, dst_x * cpp); - PUSH_DATA (push, dst_y); - BEGIN_NV04(push, SUBC_COPY(0x030c), 8); - PUSH_DATA (push, (src->offset + src_off) >> 32); - PUSH_DATA (push, (src->offset + src_off)); - PUSH_DATA (push, (dst->offset + dst_off) >> 32); - PUSH_DATA (push, (dst->offset + dst_off)); - PUSH_DATA (push, src_pitch); - PUSH_DATA (push, dst_pitch); - PUSH_DATA (push, w * cpp); - PUSH_DATA (push, h); - BEGIN_NV04(push, SUBC_COPY(0x0300), 1); - PUSH_DATA (push, exec); - - return TRUE; -} diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv50_xv.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv50_xv.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv50_xv.c 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv50_xv.c 2014-07-14 14:55:28.000000000 +0000 @@ -326,7 +326,7 @@ off[1] = Loff * yco + Coff * (uco[1] + vco[1]) + bright; off[2] = Loff * yco + Coff * (uco[2] + vco[2]) + bright; - if (pNv->Architecture >= NV_ARCH_C0) { + if (pNv->Architecture >= NV_FERMI) { nvc0_xv_csc_update(pNv, yco, off, uco, vco); return; } diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv_accel_common.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv_accel_common.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv_accel_common.c 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv_accel_common.c 2014-07-14 14:55:28.000000000 +0000 @@ -48,7 +48,7 @@ if (bpp >= 8) flags |= shared ? NOUVEAU_BO_GART : NOUVEAU_BO_VRAM; - if (pNv->Architecture >= NV_ARCH_50) { + if (pNv->Architecture >= NV_TESLA) { if (scanout) { if (pNv->tiled_scanout) { tiled = TRUE; @@ -68,7 +68,7 @@ } if (tiled) { - if (pNv->Architecture >= NV_ARCH_C0) { + if (pNv->Architecture >= NV_FERMI) { if (height > 64) cfg.nvc0.tile_mode = 0x040; else if (height > 32) cfg.nvc0.tile_mode = 0x030; else if (height > 16) cfg.nvc0.tile_mode = 0x020; @@ -81,8 +81,8 @@ cfg.nvc0.memtype = 0xfe; height = NOUVEAU_ALIGN(height, - NVC0_TILE_HEIGHT(cfg.nv50.tile_mode)); - } else if (pNv->Architecture >= NV_ARCH_50) { + NVC0_TILE_HEIGHT(cfg.nvc0.tile_mode)); + } else if (pNv->Architecture >= NV_TESLA) { if (height > 32) cfg.nv50.tile_mode = 0x040; else if (height > 16) cfg.nv50.tile_mode = 0x030; else if (height > 8) cfg.nv50.tile_mode = 0x020; @@ -108,7 +108,7 @@ } } - if (pNv->Architecture < NV_ARCH_50) { + if (pNv->Architecture < NV_TESLA) { if (bpp == 16) cfg.nv04.surf_flags |= NV04_BO_16BPP; if (bpp == 32) @@ -592,14 +592,86 @@ } \ } while(0) +void +NVAccelCommonFini(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + + nouveau_object_del(&pNv->notify0); + nouveau_object_del(&pNv->vblank_sem); + + nouveau_object_del(&pNv->NvContextSurfaces); + nouveau_object_del(&pNv->NvContextBeta1); + nouveau_object_del(&pNv->NvContextBeta4); + nouveau_object_del(&pNv->NvImagePattern); + nouveau_object_del(&pNv->NvRop); + nouveau_object_del(&pNv->NvRectangle); + nouveau_object_del(&pNv->NvImageBlit); + nouveau_object_del(&pNv->NvScaledImage); + nouveau_object_del(&pNv->NvClipRectangle); + nouveau_object_del(&pNv->NvImageFromCpu); + nouveau_object_del(&pNv->Nv2D); + nouveau_object_del(&pNv->NvMemFormat); + nouveau_object_del(&pNv->NvSW); + nouveau_object_del(&pNv->Nv3D); + nouveau_object_del(&pNv->NvCOPY); + + nouveau_bo_ref(NULL, &pNv->scratch); + + nouveau_bufctx_del(&pNv->bufctx); + nouveau_pushbuf_del(&pNv->pushbuf); + nouveau_object_del(&pNv->channel); +} + Bool NVAccelCommonInit(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - Bool ret; + struct nv04_fifo nv04_data = { .vram = NvDmaFB, + .gart = NvDmaTT }; + struct nvc0_fifo nvc0_data = { }; + struct nouveau_object *device = &pNv->dev->object; + int size, ret; + void *data; - if (pNv->NoAccel) - return TRUE; + if (pNv->dev->drm_version < 0x01000000 && pNv->dev->chipset >= 0xc0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Fermi acceleration not supported on old kernel\n"); + return FALSE; + } + + if (pNv->Architecture < NV_FERMI) { + data = &nv04_data; + size = sizeof(nv04_data); + } else { + data = &nvc0_data; + size = sizeof(nvc0_data); + } + + ret = nouveau_object_new(device, 0, NOUVEAU_FIFO_CHANNEL_CLASS, + data, size, &pNv->channel); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Error creating GPU channel: %d\n", ret); + return FALSE; + } + + ret = nouveau_pushbuf_new(pNv->client, pNv->channel, 4, 32 * 1024, + true, &pNv->pushbuf); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Error allocating DMA push buffer: %d\n",ret); + NVAccelCommonFini(pScrn); + return FALSE; + } + + ret = nouveau_bufctx_new(pNv->client, 1, &pNv->bufctx); + if (ret) { + NVAccelCommonFini(pScrn); + return FALSE; + } + + pNv->pushbuf->user_priv = pNv->bufctx; /* Scratch buffer */ ret = nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, @@ -613,13 +685,13 @@ } /* General engine objects */ - if (pNv->Architecture < NV_ARCH_C0) { + if (pNv->Architecture < NV_FERMI) { INIT_CONTEXT_OBJECT(DmaNotifier0); INIT_CONTEXT_OBJECT(Null); } /* 2D engine */ - if (pNv->Architecture < NV_ARCH_50) { + if (pNv->Architecture < NV_TESLA) { INIT_CONTEXT_OBJECT(ContextSurfaces); INIT_CONTEXT_OBJECT(ContextBeta1); INIT_CONTEXT_OBJECT(ContextBeta4); @@ -631,23 +703,19 @@ INIT_CONTEXT_OBJECT(ClipRectangle); INIT_CONTEXT_OBJECT(ImageFromCpu); } else - if (pNv->Architecture < NV_ARCH_C0) { + if (pNv->Architecture < NV_FERMI) { INIT_CONTEXT_OBJECT(2D_NV50); - if (pNv->ce_enabled) - INIT_CONTEXT_OBJECT(Copy_NV50); } else { INIT_CONTEXT_OBJECT(2D_NVC0); - if (pNv->ce_enabled) - INIT_CONTEXT_OBJECT(Copy_NVC0); } - if (pNv->Architecture < NV_ARCH_50) + if (pNv->Architecture < NV_TESLA) INIT_CONTEXT_OBJECT(MemFormat); else - if (pNv->Architecture < NV_ARCH_C0) + if (pNv->Architecture < NV_FERMI) INIT_CONTEXT_OBJECT(M2MF_NV50); else - if (pNv->Architecture < NV_ARCH_E0) + if (pNv->Architecture < NV_KEPLER) INIT_CONTEXT_OBJECT(M2MF_NVC0); else { INIT_CONTEXT_OBJECT(P2MF_NVE0); @@ -656,11 +724,11 @@ /* 3D init */ switch (pNv->Architecture) { - case NV_ARCH_C0: - case NV_ARCH_E0: + case NV_FERMI: + case NV_KEPLER: INIT_CONTEXT_OBJECT(3D_NVC0); break; - case NV_ARCH_50: + case NV_TESLA: INIT_CONTEXT_OBJECT(NV50TCL); break; case NV_ARCH_40: @@ -677,34 +745,6 @@ break; } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Channel setup complete.\n"); return TRUE; } - -void NVAccelFree(ScrnInfoPtr pScrn) -{ - NVPtr pNv = NVPTR(pScrn); - - if (pNv->NoAccel) - return; - - nouveau_object_del(&pNv->notify0); - nouveau_object_del(&pNv->vblank_sem); - - nouveau_object_del(&pNv->NvContextSurfaces); - nouveau_object_del(&pNv->NvContextBeta1); - nouveau_object_del(&pNv->NvContextBeta4); - nouveau_object_del(&pNv->NvImagePattern); - nouveau_object_del(&pNv->NvRop); - nouveau_object_del(&pNv->NvRectangle); - nouveau_object_del(&pNv->NvImageBlit); - nouveau_object_del(&pNv->NvScaledImage); - nouveau_object_del(&pNv->NvClipRectangle); - nouveau_object_del(&pNv->NvImageFromCpu); - nouveau_object_del(&pNv->Nv2D); - nouveau_object_del(&pNv->NvMemFormat); - nouveau_object_del(&pNv->NvSW); - nouveau_object_del(&pNv->Nv3D); - nouveau_object_del(&pNv->NvCOPY); - - nouveau_bo_ref(NULL, &pNv->scratch); -} diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nvc0_accel.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nvc0_accel.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nvc0_accel.c 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nvc0_accel.c 2014-07-14 14:55:28.000000000 +0000 @@ -121,27 +121,6 @@ } Bool -NVAccelInitCopy_NVC0(ScrnInfoPtr pScrn) -{ - NVPtr pNv = NVPTR(pScrn); - struct nouveau_pushbuf *push = pNv->ce_pushbuf; - int ret; - - ret = nouveau_object_new(pNv->ce_channel, 0x000490b5, 0x90b5, - NULL, 0, &pNv->NvCopy); - if (ret) - return FALSE; - - if (!PUSH_SPACE(push, 2)) - return FALSE; - - BEGIN_NVC0(push, NV01_SUBC(COPY, OBJECT), 1); - PUSH_DATA (push, pNv->NvCopy->handle); - - return TRUE; -} - -Bool NVAccelInitP2MF_NVE0(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); @@ -232,7 +211,7 @@ uint32_t class, handle; int ret; - if (pNv->Architecture < NV_ARCH_E0) { + if (pNv->Architecture < NV_KEPLER) { class = 0x9097; handle = 0x001f906e; } else @@ -300,7 +279,7 @@ PUSH_DATA (push, 0); BEGIN_NVC0(push, NVC0_3D(LINKED_TSC), 1); PUSH_DATA (push, 1); - if (pNv->Architecture < NV_ARCH_E0) { + if (pNv->Architecture < NV_KEPLER) { BEGIN_NVC0(push, NVC0_3D(TEX_LIMITS(4)), 1); PUSH_DATA (push, 0x54); BEGIN_NIC0(push, NVC0_3D(BIND_TIC(4)), 2); @@ -328,7 +307,7 @@ BEGIN_NVC0(push, NVC0_3D(CODE_ADDRESS_HIGH), 2); PUSH_DATA (push, (bo->offset + CODE_OFFSET) >> 32); PUSH_DATA (push, (bo->offset + CODE_OFFSET)); - if (pNv->Architecture < NV_ARCH_E0) { + if (pNv->Architecture < NV_KEPLER) { NVC0PushProgram(pNv, PVP_PASS, NVC0VP_Transform2); NVC0PushProgram(pNv, PFP_S, NVC0FP_Source); NVC0PushProgram(pNv, PFP_C, NVC0FP_Composite); diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nvc0_accel.h xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nvc0_accel.h --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nvc0_accel.h 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nvc0_accel.h 2014-07-14 14:55:28.000000000 +0000 @@ -34,7 +34,7 @@ #define MISC_OFFSET 0x10000 /* vertex/fragment programs */ -#define SPO ((pNv->Architecture < NV_ARCH_E0) ? 0x0000 : 0x0030) +#define SPO ((pNv->Architecture < NV_KEPLER) ? 0x0000 : 0x0030) #define PVP_PASS (0x0000 + SPO) /* vertex pass-through shader */ #define PFP_S (0x0200 + SPO) /* (src) */ #define PFP_C (0x0400 + SPO) /* (src IN mask) */ diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nvc0_exa.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nvc0_exa.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nvc0_exa.c 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nvc0_exa.c 2014-07-14 14:55:28.000000000 +0000 @@ -24,6 +24,7 @@ #include "nv_include.h" #include "nv_rop.h" #include "nvc0_accel.h" +#include "nouveau_copy.h" #define NOUVEAU_BO(a, b, c) (NOUVEAU_BO_##a | NOUVEAU_BO_##b | NOUVEAU_BO_##c) @@ -1024,117 +1025,14 @@ } Bool -NVC0EXARectCopy(NVPtr pNv, int w, int h, int cpp, - struct nouveau_bo *src, uint32_t src_off, int src_dom, - int src_pitch, int src_h, int src_x, int src_y, - struct nouveau_bo *dst, uint32_t dst_off, int dst_dom, - int dst_pitch, int dst_h, int dst_x, int dst_y) -{ - struct nouveau_pushbuf *push = pNv->ce_pushbuf; - struct nouveau_pushbuf_refn refs[] = { - { src, src_dom | NOUVEAU_BO_RD }, - { dst, dst_dom | NOUVEAU_BO_WR }, - }; - unsigned exec; - - if (nouveau_pushbuf_space(push, 64, 0, 0) || - nouveau_pushbuf_refn (push, refs, 2)) - return FALSE; - - exec = 0x00000000; - if (!src->config.nvc0.memtype) { - src_off += src_y * src_pitch + src_x * cpp; - exec |= 0x00000010; - } - if (!dst->config.nvc0.memtype) { - dst_off += dst_y * dst_pitch + dst_x * cpp; - exec |= 0x00000100; - } - - BEGIN_NVC0(push, SUBC_COPY(0x0200), 7); - PUSH_DATA (push, src->config.nvc0.tile_mode); - PUSH_DATA (push, src_pitch); - PUSH_DATA (push, src_h); - PUSH_DATA (push, 1); - PUSH_DATA (push, 0); - PUSH_DATA (push, src_x * cpp); - PUSH_DATA (push, src_y); - BEGIN_NVC0(push, SUBC_COPY(0x0220), 7); - PUSH_DATA (push, dst->config.nvc0.tile_mode); - PUSH_DATA (push, dst_pitch); - PUSH_DATA (push, dst_h); - PUSH_DATA (push, 1); - PUSH_DATA (push, 0); - PUSH_DATA (push, dst_x * cpp); - PUSH_DATA (push, dst_y); - BEGIN_NVC0(push, SUBC_COPY(0x030c), 8); - PUSH_DATA (push, (src->offset + src_off) >> 32); - PUSH_DATA (push, (src->offset + src_off)); - PUSH_DATA (push, (dst->offset + dst_off) >> 32); - PUSH_DATA (push, (dst->offset + dst_off)); - PUSH_DATA (push, src_pitch); - PUSH_DATA (push, dst_pitch); - PUSH_DATA (push, w * cpp); - PUSH_DATA (push, h); - BEGIN_NVC0(push, SUBC_COPY(0x0300), 1); - PUSH_DATA (push, exec); - - return TRUE; -} - -Bool NVE0EXARectCopy(NVPtr pNv, int w, int h, int cpp, struct nouveau_bo *src, uint32_t src_off, int src_dom, int src_pitch, int src_h, int src_x, int src_y, struct nouveau_bo *dst, uint32_t dst_off, int dst_dom, int dst_pitch, int dst_h, int dst_x, int dst_y) { - struct nouveau_pushbuf *push = pNv->pushbuf; - struct nouveau_pushbuf_refn refs[] = { - { src, src_dom | NOUVEAU_BO_RD }, - { dst, dst_dom | NOUVEAU_BO_WR }, - }; - unsigned exec; - - if (nouveau_pushbuf_space(push, 64, 0, 0) || - nouveau_pushbuf_refn (push, refs, 2)) - return FALSE; - - exec = 0x00000206; - if (!src->config.nvc0.memtype) { - src_off += src_y * src_pitch + src_x * cpp; - exec |= 0x00000080; - } - if (!dst->config.nvc0.memtype) { - dst_off += dst_y * dst_pitch + dst_x * cpp; - exec |= 0x00000100; - } - - BEGIN_NVC0(push, SUBC_COPY(0x0728), 6); - PUSH_DATA (push, 0x00001000 | src->config.nvc0.tile_mode); - PUSH_DATA (push, src_pitch); - PUSH_DATA (push, src_h); - PUSH_DATA (push, 1); - PUSH_DATA (push, 0); - PUSH_DATA (push, (src_y << 16) | src_x * cpp); - BEGIN_NVC0(push, SUBC_COPY(0x070c), 6); - PUSH_DATA (push, 0x000001000 | dst->config.nvc0.tile_mode); - PUSH_DATA (push, dst_pitch); - PUSH_DATA (push, dst_h); - PUSH_DATA (push, 1); - PUSH_DATA (push, 0); - PUSH_DATA (push, (dst_y << 16) | dst_x * cpp); - BEGIN_NVC0(push, SUBC_COPY(0x0400), 8); - PUSH_DATA (push, (src->offset + src_off) >> 32); - PUSH_DATA (push, (src->offset + src_off)); - PUSH_DATA (push, (dst->offset + dst_off) >> 32); - PUSH_DATA (push, (dst->offset + dst_off)); - PUSH_DATA (push, src_pitch); - PUSH_DATA (push, dst_pitch); - PUSH_DATA (push, w * cpp); - PUSH_DATA (push, h); - BEGIN_NVC0(push, SUBC_COPY(0x0300), 1); - PUSH_DATA (push, exec); - - return TRUE; + return nouveau_copya0b5_rect(pNv->pushbuf, pNv->NvCOPY, w, h, cpp, + src, src_off, src_dom, src_pitch, + src_h, src_x, src_y, dst, dst_off, + dst_dom, dst_pitch, dst_h, dst_x, dst_y); } diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv_const.h xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv_const.h --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv_const.h 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv_const.h 2014-07-14 14:55:28.000000000 +0000 @@ -17,6 +17,7 @@ OPTION_PAGE_FLIP, OPTION_SWAP_LIMIT, OPTION_ASYNC_COPY, + OPTION_ACCELMETHOD, } NVOpts; @@ -32,6 +33,7 @@ { OPTION_PAGE_FLIP, "PageFlip", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_SWAP_LIMIT, "SwapLimit", OPTV_INTEGER, {0}, FALSE }, { OPTION_ASYNC_COPY, "AsyncUTSDFS", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv_dma.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv_dma.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv_dma.c 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv_dma.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,139 +0,0 @@ -/* - * Copyright 2007 Ben Skeggs - * Copyright 2007 Stephane Marchesin - * - * 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 AUTHORS 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. - */ - -#include -#include "nv_include.h" - -Bool -NVInitDma(ScrnInfoPtr pScrn) -{ - NVPtr pNv = NVPTR(pScrn); - struct nv04_fifo nv04_data = { .vram = NvDmaFB, - .gart = NvDmaTT }; - struct nvc0_fifo nvc0_data = { }; - struct nouveau_object *device = &pNv->dev->object; - struct nouveau_fifo *fifo; - int size, ret; - void *data; - - if (pNv->dev->drm_version < 0x01000000 && pNv->dev->chipset >= 0xc0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Fermi acceleration not supported on old kernel\n"); - return FALSE; - } - - if (pNv->Architecture < NV_ARCH_C0) { - data = &nv04_data; - size = sizeof(nv04_data); - } else { - data = &nvc0_data; - size = sizeof(nvc0_data); - } - - ret = nouveau_object_new(device, 0, NOUVEAU_FIFO_CHANNEL_CLASS, - data, size, &pNv->channel); - if (ret) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Error creating GPU channel: %d\n", ret); - return FALSE; - } - - fifo = pNv->channel->data; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Opened GPU channel %d\n", fifo->channel); - - ret = nouveau_pushbuf_new(pNv->client, pNv->channel, 4, 32 * 1024, - true, &pNv->pushbuf); - if (ret) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Error allocating DMA push buffer: %d\n",ret); - NVTakedownDma(pScrn); - return FALSE; - } - - ret = nouveau_bufctx_new(pNv->client, 1, &pNv->bufctx); - if (ret) { - NVTakedownDma(pScrn); - return FALSE; - } - - pNv->pushbuf->user_priv = pNv->bufctx; - - if (pNv->ce_enabled) { - ret = nouveau_object_new(device, 0, NOUVEAU_FIFO_CHANNEL_CLASS, - data, size, &pNv->ce_channel); - if (ret) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Error creating CE channel: %d\n", ret); - NVTakedownDma(pScrn); - return FALSE; - } - - fifo = pNv->ce_channel->data; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Opened GPU CE channel %d\n", fifo->channel); - - ret = nouveau_pushbuf_new(pNv->client, pNv->ce_channel, 4, - 32 * 1024, true, &pNv->ce_pushbuf); - if (ret) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Error allocating CE pushbuf: %d\n", ret); - NVTakedownDma(pScrn); - return FALSE; - } - } - - return TRUE; -} - -void -NVTakedownDma(ScrnInfoPtr pScrn) -{ - NVPtr pNv = NVPTR(pScrn); - - if (pNv->ce_channel) { - struct nouveau_fifo *fifo = pNv->ce_channel->data; - int chid = fifo->channel; - - nouveau_pushbuf_del(&pNv->ce_pushbuf); - nouveau_object_del(&pNv->ce_channel); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Closed GPU CE channel %d\n", chid); - } - - if (pNv->channel) { - struct nouveau_fifo *fifo = pNv->channel->data; - int chid = fifo->channel; - - nouveau_bufctx_del(&pNv->bufctx); - nouveau_pushbuf_del(&pNv->pushbuf); - nouveau_object_del(&pNv->channel); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Closed GPU channel %d\n", chid); - } -} - diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv_driver.c xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv_driver.c --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv_driver.c 2014-02-20 22:02:02.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv_driver.c 2014-07-14 14:55:41.000000000 +0000 @@ -32,6 +32,16 @@ #include "dri2.h" #endif +#include "nouveau_copy.h" +#include "nouveau_glamor.h" +#include "nouveau_present.h" +#include "nouveau_sync.h" + +#if !HAVE_XORG_LIST +#define xorg_list_is_empty list_is_empty +#define xorg_list_for_each_entry list_for_each_entry +#endif + /* * Forward definitions for the functions that make up the driver. */ @@ -227,15 +237,21 @@ flag = (CARD32 *)data; (*flag) = 0; return TRUE; +#if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(1,15,99,0,0) + case SUPPORTS_SERVER_FDS: + return TRUE; +#endif default: return FALSE; } } static void -NVInitScrn(ScrnInfoPtr pScrn, int entity_num) +NVInitScrn(ScrnInfoPtr pScrn, struct xf86_platform_device *platform_dev, + int entity_num) { DevUnion *pPriv; + NVEntPtr pNVEnt; pScrn->driverVersion = NV_VERSION; pScrn->driverName = NV_DRIVER_NAME; @@ -258,19 +274,21 @@ NVEntityIndex); if (!pPriv->ptr) { pPriv->ptr = xnfcalloc(sizeof(NVEntRec), 1); + pNVEnt = pPriv->ptr; + pNVEnt->platform_dev = platform_dev; } xf86SetEntityInstanceForScreen(pScrn, entity_num, xf86GetNumEntityInstances(entity_num) - 1); } -static Bool -NVHasKMS(struct pci_device *pci_dev) +static struct nouveau_device * +NVOpenNouveauDevice(struct pci_device *pci_dev, + struct xf86_platform_device *platform_dev, int scrnIndex, Bool probe) { struct nouveau_device *dev = NULL; - drmVersion *version; char *busid; - int chipset, ret; + int ret, fd = -1; #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,9,99,901,0) XNFasprintf(&busid, "pci:%04x:%02x:%02x.%d", @@ -280,19 +298,43 @@ pci_dev->domain, pci_dev->bus, pci_dev->dev, pci_dev->func); #endif - ret = drmCheckModesettingSupported(busid); - if (ret) { - xf86DrvMsg(-1, X_ERROR, "[drm] KMS not enabled\n"); - free(busid); - return FALSE; + if (probe) { + ret = drmCheckModesettingSupported(busid); + if (ret) { + xf86DrvMsg(scrnIndex, X_ERROR, "[drm] KMS not enabled\n"); + free(busid); + return NULL; + } } - ret = nouveau_device_open(busid, &dev); +#if defined(ODEV_ATTRIB_FD) + if (platform_dev) + fd = xf86_get_platform_device_int_attrib(platform_dev, + ODEV_ATTRIB_FD, -1); +#endif + if (fd != -1) + ret = nouveau_device_wrap(fd, 0, &dev); + else + ret = nouveau_device_open(busid, &dev); + if (ret) + xf86DrvMsg(scrnIndex, X_ERROR, + "[drm] Failed to open DRM device for %s: %d\n", + busid, ret); + free(busid); - if (ret) { - xf86DrvMsg(-1, X_ERROR, "[drm] failed to open device\n"); + return dev; +} + +static Bool +NVHasKMS(struct pci_device *pci_dev, struct xf86_platform_device *platform_dev) +{ + struct nouveau_device *dev = NULL; + drmVersion *version; + int chipset; + + dev = NVOpenNouveauDevice(pci_dev, platform_dev, -1, TRUE); + if (!dev) return FALSE; - } /* Check the version reported by the kernel module. In theory we * shouldn't have to do this, as libdrm_nouveau will do its own checks. @@ -325,6 +367,7 @@ case 0xe0: case 0xf0: case 0x100: + case 0x110: break; default: xf86DrvMsg(-1, X_ERROR, "Unknown chipset: NV%02x\n", chipset); @@ -344,7 +387,7 @@ }; ScrnInfoPtr pScrn = NULL; - if (!NVHasKMS(pci_dev)) + if (!NVHasKMS(pci_dev, NULL)) return FALSE; pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, NVChipsets, @@ -352,7 +395,7 @@ if (!pScrn) return FALSE; - NVInitScrn(pScrn, entity_num); + NVInitScrn(pScrn, NULL, entity_num); return TRUE; } @@ -368,7 +411,7 @@ if (!dev->pdev) return FALSE; - if (!NVHasKMS(dev->pdev)) + if (!NVHasKMS(dev->pdev, dev)) return FALSE; if (flags & PLATFORM_PROBE_GPU_SCREEN) @@ -382,7 +425,7 @@ xf86SetEntityShared(entity_num); xf86AddEntityToScreen(scrn, entity_num); - NVInitScrn(scrn, entity_num); + NVInitScrn(scrn, dev, entity_num); return TRUE; } @@ -421,13 +464,22 @@ { SCRN_INFO_PTR(arg); NVPtr pNv = NVPTR(pScrn); +#ifdef XF86_PDEV_SERVER_FD + NVEntPtr pNVEnt = NVEntPriv(pScrn); +#endif int ret; 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)); +#ifdef XF86_PDEV_SERVER_FD + if (!(pNVEnt->platform_dev && + (pNVEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))) +#endif + { + 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; @@ -449,10 +501,19 @@ { SCRN_INFO_PTR(arg); NVPtr pNv = NVPTR(pScrn); +#ifdef XF86_PDEV_SERVER_FD + NVEntPtr pNVEnt = NVEntPriv(pScrn); +#endif int ret; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVLeaveVT is called.\n"); +#ifdef XF86_PDEV_SERVER_FD + if (pNVEnt->platform_dev && + (pNVEnt->platform_dev->flags & XF86_PDEV_SERVER_FD)) + return; +#endif + ret = drmDropMaster(pNv->dev->fd); if (ret && errno != EIO && errno != ENODEV) ErrorF("Error dropping master: %i(%m)\n", -errno); @@ -463,9 +524,8 @@ { ScrnInfoPtr pScrn = user_data; NVPtr pNv = NVPTR(pScrn); - - if (pScrn->vtSema && !pNv->NoAccel) - nouveau_pushbuf_kick(pNv->pushbuf, pNv->pushbuf->channel); + if (pScrn->vtSema && pNv->Flush) + pNv->Flush(pScrn); } #ifdef NOUVEAU_PIXMAP_SHARING @@ -517,8 +577,7 @@ nouveau_dirty_update(pScreen); #endif - if (pScrn->vtSema && !pNv->NoAccel) - nouveau_pushbuf_kick(pNv->pushbuf, pNv->pushbuf->channel); + NVFlushCallback(NULL, pScrn, NULL); if (pNv->VideoTimerCallback) (*pNv->VideoTimerCallback)(pScrn, currentTime.milliseconds); @@ -529,7 +588,6 @@ { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); NVPtr pNv = NVPTR(pScrn); - PixmapPtr ppix; pScreen->CreateScreenResources = pNv->CreateScreenResources; if (!(*pScreen->CreateScreenResources)(pScreen)) @@ -540,9 +598,12 @@ if (!NVEnterVT(VT_FUNC_ARGS(0))) return FALSE; - if (!pNv->NoAccel) { - ppix = pScreen->GetScreenPixmap(pScreen); + if (pNv->AccelMethod == EXA) { + PixmapPtr ppix = pScreen->GetScreenPixmap(pScreen); nouveau_bo_ref(pNv->scanout, &nouveau_pixmap(ppix)->bo); + } else + if (pNv->AccelMethod == GLAMOR) { + nouveau_glamor_create_screen_resources(pScreen); } return TRUE; @@ -565,17 +626,18 @@ if (XF86_CRTC_CONFIG_PTR(pScrn)->num_crtc) drmmode_screen_fini(pScreen); - if (!pNv->NoAccel) - nouveau_dri2_fini(pScreen); + nouveau_present_fini(pScreen); + nouveau_dri2_fini(pScreen); + nouveau_sync_fini(pScreen); + nouveau_copy_fini(pScreen); if (pScrn->vtSema) { NVLeaveVT(VT_FUNC_ARGS(0)); pScrn->vtSema = FALSE; } - NVAccelFree(pScrn); NVTakedownVideo(pScrn); - NVTakedownDma(pScrn); + NVAccelCommonFini(pScrn); NVUnmapMem(pScrn); xf86_cursors_fini(pScreen); @@ -688,8 +750,6 @@ { NVPtr pNv = NVPTR(pScrn); NVEntPtr pNVEnt = NVEntPriv(pScrn); - struct pci_device *dev = pNv->PciInfo; - char *busid; drmSetVersion sv; int err; int ret; @@ -706,23 +766,10 @@ return TRUE; } -#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,9,99,901,0) - XNFasprintf(&busid, "pci:%04x:%02x:%02x.%d", - dev->domain, dev->bus, dev->dev, dev->func); -#else - busid = XNFprintf("pci:%04x:%02x:%02x.%d", - dev->domain, dev->bus, dev->dev, dev->func); -#endif - - ret = nouveau_device_open(busid, &pNv->dev); - if (ret) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "[drm] Failed to open DRM device for %s: %d\n", - busid, ret); - free(busid); + pNv->dev = NVOpenNouveauDevice(pNv->PciInfo, pNVEnt->platform_dev, + pScrn->scrnIndex, FALSE); + if (!pNv->dev) return FALSE; - } - free(busid); sv.drm_di_major = 1; sv.drm_di_minor = 1; @@ -772,7 +819,7 @@ struct nouveau_device *dev; NVPtr pNv; MessageType from; - const char *reason; + const char *reason, *string; uint64_t v; int ret; int defaultDepth = 0; @@ -837,7 +884,7 @@ dev = pNv->dev; pScrn->chipset = malloc(sizeof(char) * 25); - sprintf(pScrn->chipset, "NVIDIA NV%02X", dev->chipset); + sprintf((char *)pScrn->chipset, "NVIDIA NV%02X", dev->chipset); xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Chipset: \"%s\"\n", pScrn->chipset); switch (dev->chipset & ~0xf) { @@ -861,16 +908,19 @@ case 0x80: case 0x90: case 0xa0: - pNv->Architecture = NV_ARCH_50; + pNv->Architecture = NV_TESLA; break; case 0xc0: case 0xd0: - pNv->Architecture = NV_ARCH_C0; + pNv->Architecture = NV_FERMI; break; case 0xe0: case 0xf0: case 0x100: - pNv->Architecture = NV_ARCH_E0; + pNv->Architecture = NV_KEPLER; + break; + case 0x110: + pNv->Architecture = NV_MAXWELL; break; default: return FALSE; @@ -896,7 +946,7 @@ break; case 30: /* OK on NV50 KMS */ - if (pNv->Architecture < NV_ARCH_50) + if (pNv->Architecture < NV_TESLA) NVPreInitFail("Depth 30 supported on G80+ only\n"); break; case 15: /* 15 may get done one day, so leave any code for it in place */ @@ -970,31 +1020,59 @@ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", pNv->HWCursor ? "HW" : "SW"); + string = xf86GetOptValString(pNv->Options, OPTION_ACCELMETHOD); + if (string) { + if (!strcmp(string, "none")) pNv->AccelMethod = NONE; + else if (!strcmp(string, "exa")) pNv->AccelMethod = EXA; +#ifdef HAVE_GLAMOR + else if (!strcmp(string, "glamor")) pNv->AccelMethod = GLAMOR; +#endif + else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Invalid AccelMethod specified\n"); + } + } + + if (pNv->AccelMethod == UNKNOWN) { +#ifdef HAVE_GLAMOR + if (pNv->Architecture >= NV_MAXWELL) + pNv->AccelMethod = GLAMOR; + else +#endif + pNv->AccelMethod = EXA; + } + if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) { - pNv->NoAccel = TRUE; + pNv->AccelMethod = NONE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); } if (xf86ReturnOptValBool(pNv->Options, OPTION_SHADOW_FB, FALSE)) { pNv->ShadowFB = TRUE; - pNv->NoAccel = TRUE; + pNv->AccelMethod = NONE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using \"Shadow Framebuffer\" - acceleration disabled\n"); } - if (!pNv->NoAccel) { - if (pNv->Architecture >= NV_ARCH_50) + if (pNv->AccelMethod > NONE) { + if (pNv->Architecture >= NV_TESLA) pNv->wfb_enabled = xf86ReturnOptValBool( pNv->Options, OPTION_WFB, FALSE); pNv->tiled_scanout = TRUE; } + if (pNv->AccelMethod == GLAMOR) { + if (!nouveau_glamor_pre_init(pScrn)) + pNv->AccelMethod = EXA; + } + pNv->ce_enabled = xf86ReturnOptValBool(pNv->Options, OPTION_ASYNC_COPY, FALSE); - if (!pNv->NoAccel && pNv->dev->chipset >= 0x11) { + 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; @@ -1062,6 +1140,17 @@ 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"); @@ -1080,7 +1169,7 @@ * The driver will not work as gpu screen without acceleration enabled. * To support this usecase modesetting ddx can be used instead. */ - if (pNv->NoAccel || pNv->ShadowFB) { + if (pNv->AccelMethod <= NONE || pNv->ShadowFB) { /* * Optimus mode requires acceleration enabled. * So if no mode is found, or the screen is created @@ -1122,13 +1211,6 @@ if (xf86LoadSubModule(pScrn, "fb") == NULL) NVPreInitFail("\n"); - /* Load EXA if needed */ - if (!pNv->NoAccel) { - if (!xf86LoadSubModule(pScrn, "exa")) { - NVPreInitFail("\n"); - } - } - /* Load shadowfb */ if (!xf86LoadSubModule(pScrn, "shadowfb")) NVPreInitFail("\n"); @@ -1154,10 +1236,6 @@ } pScrn->displayWidth = pitch / (pScrn->bitsPerPixel / 8); - - if (pNv->NoAccel) - return TRUE; - return TRUE; } @@ -1248,12 +1326,12 @@ unsigned char *FBStart; int displayWidth; - if (!pNv->NoAccel) { - if (!NVInitDma(pScrn) || !NVAccelCommonInit(pScrn)) { + if (pNv->AccelMethod == EXA) { + if (!NVAccelCommonInit(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Error initialising acceleration. " "Falling back to NoAccel\n"); - pNv->NoAccel = TRUE; + pNv->AccelMethod = NONE; pNv->ShadowFB = TRUE; pNv->wfb_enabled = FALSE; pNv->tiled_scanout = FALSE; @@ -1263,8 +1341,10 @@ } } - if (!pNv->NoAccel) - nouveau_dri2_init(pScreen); + nouveau_copy_init(pScreen); + nouveau_sync_init(pScreen); + nouveau_dri2_init(pScreen); + nouveau_present_init(pScreen); /* Allocate and map memory areas we need */ if (!NVMapMem(pScrn)) @@ -1316,7 +1396,7 @@ displayWidth = pNv->ShadowPitch / (pScrn->bitsPerPixel >> 3); FBStart = pNv->ShadowPtr; } else - if (pNv->NoAccel) { + if (pNv->AccelMethod <= NONE) { pNv->ShadowPtr = NULL; displayWidth = pScrn->displayWidth; nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR, pNv->client); @@ -1372,8 +1452,14 @@ xf86SetBlackWhitePixels(pScreen); - if (!pNv->NoAccel && !nouveau_exa_init(pScreen)) - return FALSE; + if (pNv->AccelMethod == GLAMOR) { + if (!nouveau_glamor_init(pScreen)) + return FALSE; + } else + if (pNv->AccelMethod == EXA) { + if (!nouveau_exa_init(pScreen)) + return FALSE; + } xf86SetBackingStore(pScreen); xf86SetSilkenMouse(pScreen); diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv_proto.h xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv_proto.h --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv_proto.h 2014-02-20 22:01:48.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv_proto.h 2014-07-14 14:55:28.000000000 +0000 @@ -12,23 +12,27 @@ void drmmode_screen_init(ScreenPtr pScreen); void drmmode_screen_fini(ScreenPtr pScreen); +int drmmode_head(xf86CrtcPtr crtc); +void drmmode_swap(ScrnInfoPtr, uint32_t, uint32_t *); + +void *drmmode_event_queue(ScrnInfoPtr, uint64_t name, unsigned size, + void (*)(void *, uint64_t, uint64_t, uint32_t), + void **token); +void drmmode_event_abort(ScrnInfoPtr, uint64_t name, bool pending); +int drmmode_event_flush(ScrnInfoPtr); + /* in nv_accel_common.c */ Bool NVAccelCommonInit(ScrnInfoPtr pScrn); +void NVAccelCommonFini(ScrnInfoPtr pScrn); Bool NVAccelGetCtxSurf2DFormatFromPixmap(PixmapPtr pPix, int *fmt_ret); Bool NVAccelGetCtxSurf2DFormatFromPicture(PicturePtr pPix, int *fmt_ret); PixmapPtr NVGetDrawablePixmap(DrawablePtr pDraw); -void NVAccelFree(ScrnInfoPtr pScrn); void NV11SyncToVBlank(PixmapPtr ppix, BoxPtr box); Bool nouveau_allocate_surface(ScrnInfoPtr scrn, int width, int height, int bpp, int usage_hint, int *pitch, struct nouveau_bo **bo); /* in nouveau_dri2.c */ -void nouveau_dri2_vblank_handler(int fd, unsigned int frame, - unsigned int tv_sec, unsigned int tv_usec, - void *event_data); -void nouveau_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec, - unsigned int tv_usec, void *event_data); Bool nouveau_dri2_init(ScreenPtr pScreen); void nouveau_dri2_fini(ScreenPtr pScreen); @@ -39,10 +43,6 @@ void NVXVComputeBicubicFilter(struct nouveau_bo *, unsigned, unsigned); unsigned int nv_window_belongs_to_crtc(ScrnInfoPtr, int, int, int, int); -/* in nv_dma.c */ -Bool NVInitDma(ScrnInfoPtr pScrn); -void NVTakedownDma(ScrnInfoPtr pScrn); - /* in nouveau_exa.c */ Bool nouveau_exa_init(ScreenPtr pScreen); Bool nouveau_exa_pixmap_is_onscreen(PixmapPtr pPixmap); @@ -144,14 +144,12 @@ /* in nv50_accel.c */ void NV50SyncToVBlank(PixmapPtr ppix, BoxPtr box); Bool NVAccelInitM2MF_NV50(ScrnInfoPtr pScrn); -Bool NVAccelInitCopy_NV50(ScrnInfoPtr pScrn); Bool NVAccelInit2D_NV50(ScrnInfoPtr pScrn); Bool NVAccelInitNV50TCL(ScrnInfoPtr pScrn); /* in nvc0_accel.c */ void NVC0SyncToVBlank(PixmapPtr ppix, BoxPtr box); Bool NVAccelInitM2MF_NVC0(ScrnInfoPtr pScrn); -Bool NVAccelInitCopy_NVC0(ScrnInfoPtr pScrn); Bool NVAccelInitP2MF_NVE0(ScrnInfoPtr pScrn); Bool NVAccelInitCOPY_NVE0(ScrnInfoPtr pScrn); Bool NVAccelInit2D_NVC0(ScrnInfoPtr pScrn); @@ -174,9 +172,6 @@ Bool NV50EXARectM2MF(NVPtr pNv, int, int, int, struct nouveau_bo *, uint32_t, int, int, int, int, int, struct nouveau_bo *, uint32_t, int, int, int, int, int); -Bool NVA3EXARectCopy(NVPtr pNv, int, int, int, - struct nouveau_bo *, uint32_t, int, int, int, int, int, - struct nouveau_bo *, uint32_t, int, int, int, int, int); /* in nvc0_exa.c */ Bool NVC0AccelUploadM2MF(PixmapPtr pdpix, int x, int y, int w, int h, @@ -200,9 +195,7 @@ Bool NVC0EXARectM2MF(NVPtr pNv, int, int, int, struct nouveau_bo *, uint32_t, int, int, int, int, int, struct nouveau_bo *, uint32_t, int, int, int, int, int); -Bool NVC0EXARectCopy(NVPtr pNv, int, int, int, - struct nouveau_bo *, uint32_t, int, int, int, int, int, - struct nouveau_bo *, uint32_t, int, int, int, int, int); + Bool NVE0EXARectCopy(NVPtr pNv, int, int, int, struct nouveau_bo *, uint32_t, int, int, int, int, int, struct nouveau_bo *, uint32_t, int, int, int, int, int); diff -Nru xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv_type.h xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv_type.h --- xserver-xorg-video-nouveau-1.0.10+git20140220.480f0998/src/nv_type.h 2014-02-20 22:02:02.000000000 +0000 +++ xserver-xorg-video-nouveau-1.0.10+git20140714.edd1608c/src/nv_type.h 2014-07-14 14:55:28.000000000 +0000 @@ -19,17 +19,23 @@ #define NV_ARCH_20 0x20 #define NV_ARCH_30 0x30 #define NV_ARCH_40 0x40 -#define NV_ARCH_50 0x50 -#define NV_ARCH_C0 0xc0 -#define NV_ARCH_E0 0xe0 +#define NV_TESLA 0x50 +#define NV_FERMI 0xc0 +#define NV_KEPLER 0xe0 +#define NV_MAXWELL 0x110 + +struct xf86_platform_device; /* NV50 */ typedef struct _NVRec *NVPtr; typedef struct { int fd; + struct xf86_platform_device *platform_dev; } NVEntRec, *NVEntPtr; +NVEntPtr NVEntPriv(ScrnInfoPtr pScrn); + typedef struct _NVRec { uint32_t Architecture; EntityInfoPtr pEnt; @@ -39,7 +45,14 @@ struct nouveau_bo * scanout; - Bool NoAccel; + enum { + UNKNOWN = 0, + NONE, + EXA, + GLAMOR, + } AccelMethod; + void (*Flush)(ScrnInfoPtr); + Bool HWCursor; Bool ShadowFB; unsigned char * ShadowPtr; @@ -50,6 +63,7 @@ Bool wfb_enabled; Bool tiled_scanout; Bool glx_vblank; + Bool has_async_pageflip; Bool has_pageflip; int swap_limit; int max_swap_limit; @@ -107,6 +121,16 @@ struct nouveau_object *ce_channel; struct nouveau_pushbuf *ce_pushbuf; struct nouveau_object *NvCopy; + Bool (*ce_rect)(struct nouveau_pushbuf *, struct nouveau_object *, + int, int, int, + struct nouveau_bo *, uint32_t, int, int, int, int, int, + struct nouveau_bo *, uint32_t, int, int, int, int, int); + + /* SYNC extension private */ + void *sync; + + /* Present extension private */ + void *present; /* Acceleration context */ PixmapPtr pspix, pmpix, pdpix;