diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/aclocal.m4 xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/aclocal.m4 --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/aclocal.m4 2016-11-27 15:39:53.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/aclocal.m4 2017-02-08 16:46:37.000000000 +0000 @@ -9767,17 +9767,24 @@ fi]) # Test for the ability of xmlto to generate a text target +# +# NOTE: xmlto 0.0.27 or higher return a non-zero return code in the +# following test for empty XML docbook files. +# For compatibility reasons use the following empty XML docbook file and if +# it fails try it again with a non-empty XML file. have_xmlto_text=no cat > conftest.xml << "EOF" - - - EOF AS_IF([test "$have_xmlto" = yes], [AS_IF([$XMLTO --skip-validation txt conftest.xml >/dev/null 2>&1], [have_xmlto_text=yes], - [AC_MSG_WARN([xmlto cannot generate text format, this format skipped])])]) + [# Try it again with a non-empty XML file. + cat > conftest.xml << "EOF" + +EOF + AS_IF([$XMLTO --skip-validation txt conftest.xml >/dev/null 2>&1], + [have_xmlto_text=yes], + [AC_MSG_WARN([xmlto cannot generate text format, this format skipped])])])]) rm -f conftest.xml AM_CONDITIONAL([HAVE_XMLTO_TEXT], [test $have_xmlto_text = yes]) AM_CONDITIONAL([HAVE_XMLTO], [test "$have_xmlto" = yes]) diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/autogen.sh xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/autogen.sh --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/autogen.sh 2016-11-27 15:39:36.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/autogen.sh 2017-02-08 16:46:15.000000000 +0000 @@ -1,14 +1,14 @@ #! /bin/sh -srcdir=`dirname $0` +srcdir=`dirname "$0"` test -z "$srcdir" && srcdir=. ORIGDIR=`pwd` -cd $srcdir +cd "$srcdir" autoreconf -v --install || exit 1 -cd $ORIGDIR || exit $? +cd "$ORIGDIR" || exit $? if test -z "$NOCONFIGURE"; then - $srcdir/configure "$@" + exec "$srcdir"/configure "$@" fi diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/ChangeLog xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/ChangeLog --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/ChangeLog 2016-11-27 15:39:56.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/ChangeLog 2017-02-08 16:46:40.000000000 +0000 @@ -1,9 +1,180 @@ -commit 87ad573da3aae6812c7666c9e12039df7b390543 +commit 7d14e4a9e140af6cd9b123a918b92d5d5691e2c5 Author: Rico Tzschichholz -Date: Sun Nov 27 16:39:36 2016 +0100 +Date: Wed Feb 8 17:46:15 2017 +0100 Add debian tree from origin/debian-unstable +commit 49b092563cb3958911d28a006f155b4f4e38ed73 +Author: Emil Velikov +Date: Thu Jan 26 11:10:12 2017 +0900 + + autogen.sh: use quoted string variables + + Place quotes around the $srcdir, $ORIGDIR and $0 variables to prevent + fall-outs, when they contain space. + + Signed-off-by: Emil Velikov + Reviewed-by: Peter Hutterer + Signed-off-by: Peter Hutterer + +commit 457fcc5935c659aab5b88cf26d065180b47ed632 +Author: Peter Hutterer +Date: Thu Jan 26 11:09:07 2017 +0900 + + autogen.sh: use exec instead of waiting for configure to finish + + Syncs the invocation of configure with the one from the server. + + Signed-off-by: Peter Hutterer + Reviewed-by: Emil Velikov + +commit 5f712380883357d03c9934a753ef302e109aeb14 +Author: Michel Dänzer +Date: Fri Jan 6 17:42:25 2017 +0900 + + Pass pitch from drmmode_crtc_scanout_allocate to drmmode_create_bo_pixmap + + Mostly to align with radeon commit + ea30d856ba5e7274c8ea499293b8b0e721b8e082, but also gets rid of a + gbm_bo_get_stride call. + + Reviewed-by: Alex Deucher + +commit b5c189473dba2cffc9e4df310ce5c86ceca99a94 +Author: Jammy Zhou +Date: Tue Dec 13 12:32:39 2016 +0900 + + Use render node for DRI3 if available + + Signed-off-by: Jammy Zhou + Reviewed-by: Michel Dänzer + [ Second attempt, let's see if there's any fallout this time... ] + +commit edd276185d42962a13faf9ec9eeebc754ef284e7 +Author: Michel Dänzer +Date: Thu Dec 15 12:42:44 2016 +0900 + + Simplify drmmode_handle_uevents + + No functional change intended. + + Reviewed-by: Jim Qu + +commit 732cf4d3a248b288532ad0f3443da49e08dc7507 +Author: jimqu +Date: Tue Dec 13 16:33:26 2016 +0800 + + udev_monitor_receive_device() will block when hotplug monitor + + udev_monitor_receive_device() will block and wait for the event of udev + use select() to ensure that this will not block. + + Signed-off-by: JimQu + Reviewed-by: Michel Dänzer + +commit d60ea478cf2215ded7e1acf5817a0dae07e54026 +Author: Michel Dänzer +Date: Wed Nov 30 16:28:27 2016 +0900 + + Call amdgpu_drm_abort_entry on failure to flip to a scanout pixmap + + Fixes leaking the corresponding struct amdgpu_drm_queue list entry in + that case. + + (Ported from radeon commit e2942449171fe628a7726e59bcaab65e27d88563) + Reviewed-by: Alex Deucher + +commit aea70298ef0d53fc81aa1fd22c8566920a856223 +Author: Michel Dänzer +Date: Wed Nov 30 16:27:10 2016 +0900 + + Call ValidateGC after ChangeClip in amdgpu_sync_scanout_pixmaps + + The wrong order meant that the clipping region wasn't actually applied, + so it always copied the full contents from the other scanout pixmap. + + (Ported from radeon commit 14c3f59f5157885ad8f941f0bad6c0c5e3db12f8) + Reviewed-by: Alex Deucher + +commit 0f79c30619168c6845b143c6ed94ade307383068 +Author: Michel Dänzer +Date: Wed Nov 30 16:25:52 2016 +0900 + + Fix amdgpu_scanout_extents_intersect for GPU screens + + Fixes incorrect screen updates with TearFree enabled on PRIME slave + outputs which are not located at (0, 0). + + (Ported from radeon commit a995f5830916a0fee5126263d1bfe48632be3a15) + Reviewed-by: Alex Deucher + +commit 082b6b8ca1878f4b7ab0b25d16b85ba40748ac57 +Author: Michel Dänzer +Date: Wed Nov 30 16:21:28 2016 +0900 + + Take current scanout_id into account everywhere involved with TearFree + + Fixes various potential issues with TearFree enabled, e.g. outputs + freezing after display configuration changes. + + (Ported from radeon commit e543ef3a2fb304cbe3a965fb780632af2e4186f4) + Reviewed-by: Alex Deucher + +commit 82729b1f3b9d57f3002ac2689bfbf37ece0bc3f2 +Author: Michel Dänzer +Date: Mon Nov 28 17:47:17 2016 +0900 + + Add amdgpu_is_gpu_screen helper + + This will hopefully decrease the chance of accidentally breaking the + build against xserver < 1.13 in the future. + + (Ported from radeon commit f130b10e63f7526360b41aa0918b4940f63f662a) + Reviewed-by: Alex Deucher + +commit 7fe2a8ed67ef82916a1eb5b241c5a602a26e10b2 +Author: Michel Dänzer +Date: Tue Nov 22 16:50:59 2016 +0900 + + Don't install Flush/EventCallback for GPU screens + + Their purpose is to flush GPU rendering commands corresponding to damage + events, but there can be no damage events corresponding to GPU screen + rendering operations. + + (Ported from radeon commits 13c6bc5e382765fe567091e1c616c0a26eec04ca and + 487aa62a2a23b86e4ea4714fdfd465c9e513141f) + + v2: Squash in radeon fix for build against xserver < 1.13 + + Reviewed-by: Alex Deucher (v1) + +commit ff31320644b4d17b9b3f0abd612c99769d3d9643 +Author: Michel Dänzer +Date: Fri Nov 25 18:34:40 2016 +0900 + + Make libdrm >= 2.4.72 requirement explicit + + And drop compatibility code for older versions. + + Reviewed-by: Alex Deucher + +commit f9ba1e8fd48cd967a09c4e083b277505d08d3849 +Author: Michel Dänzer +Date: Tue Nov 22 16:30:59 2016 +0900 + + Use DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags when available + + (Ported from radeon commits 1106b2f773ad0611c729b27f4c192a26b43ef1e7 + and 5fea5ef2f07eee4a0f94baab427010b936f1d4b4) + + v2: + * Squash in radeon fix for TearFree regression + * Remove preprocessor guards for compatibility with libdrm < 2.4.72 + (Emil Velikov) + + Reviewed-by: Alex Deucher + commit e8aa4e7ea59f00d5527654b7181a05aab8c78928 Author: Michel Dänzer Date: Wed Oct 26 18:38:20 2016 +0900 diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/configure xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/configure --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/configure 2016-11-27 15:39:54.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/configure 2017-02-08 16:46:38.000000000 +0000 @@ -18896,12 +18896,12 @@ pkg_cv_LIBDRM_CFLAGS="$LIBDRM_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdrm >= 2.4.58\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libdrm >= 2.4.58") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdrm >= 2.4.72\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libdrm >= 2.4.72") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_LIBDRM_CFLAGS=`$PKG_CONFIG --cflags "libdrm >= 2.4.58" 2>/dev/null` + pkg_cv_LIBDRM_CFLAGS=`$PKG_CONFIG --cflags "libdrm >= 2.4.72" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -18913,12 +18913,12 @@ pkg_cv_LIBDRM_LIBS="$LIBDRM_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdrm >= 2.4.58\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libdrm >= 2.4.58") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdrm >= 2.4.72\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libdrm >= 2.4.72") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_LIBDRM_LIBS=`$PKG_CONFIG --libs "libdrm >= 2.4.58" 2>/dev/null` + pkg_cv_LIBDRM_LIBS=`$PKG_CONFIG --libs "libdrm >= 2.4.72" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -18939,14 +18939,14 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - LIBDRM_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libdrm >= 2.4.58" 2>&1` + LIBDRM_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libdrm >= 2.4.72" 2>&1` else - LIBDRM_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libdrm >= 2.4.58" 2>&1` + LIBDRM_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libdrm >= 2.4.72" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$LIBDRM_PKG_ERRORS" >&5 - as_fn_error $? "Package requirements (libdrm >= 2.4.58) were not met: + as_fn_error $? "Package requirements (libdrm >= 2.4.72) were not met: $LIBDRM_PKG_ERRORS diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/configure.ac xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/configure.ac --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/configure.ac 2016-11-27 15:39:36.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/configure.ac 2017-02-08 16:46:15.000000000 +0000 @@ -69,7 +69,7 @@ XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) # Checks for libraries. -PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.58]) +PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.72]) PKG_CHECK_MODULES(LIBDRM_AMDGPU, [libdrm_amdgpu >= 2.4.72]) PKG_CHECK_MODULES(GBM, [gbm]) diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/debian/changelog xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/debian/changelog --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/debian/changelog 2017-02-08 16:53:24.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/debian/changelog 2017-02-08 16:53:24.000000000 +0000 @@ -1,10 +1,10 @@ -xserver-xorg-video-amdgpu (1.2.99+git20161127.e8aa4e7e-0ubuntu0ricotz~yakkety) yakkety; urgency=medium +xserver-xorg-video-amdgpu (1.2.99+git20170208.49b09256-0ubuntu0ricotz~yakkety) yakkety; urgency=medium - * Checkout from git 20161127 (master branch) up to commit - e8aa4e7ea59f00d5527654b7181a05aab8c78928 + * Checkout from git 20170208 (master branch) up to commit + 49b092563cb3958911d28a006f155b4f4e38ed73 * Only added debian/ tree from origin/debian-unstable - -- Rico Tzschichholz Sun, 27 Nov 2016 16:39:56 +0100 + -- Rico Tzschichholz Wed, 08 Feb 2017 17:46:40 +0100 xserver-xorg-video-amdgpu (1.2.0-1) unstable; urgency=medium diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/.lastcommit xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/.lastcommit --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/.lastcommit 2016-11-27 15:39:36.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/.lastcommit 2017-02-08 16:46:15.000000000 +0000 @@ -1 +1 @@ -commit e8aa4e7ea59f00d5527654b7181a05aab8c78928 +commit 49b092563cb3958911d28a006f155b4f4e38ed73 diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/amdgpu_dri2.c xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/amdgpu_dri2.c --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/amdgpu_dri2.c 2016-11-27 15:39:36.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/amdgpu_dri2.c 2017-02-08 16:46:15.000000000 +0000 @@ -563,7 +563,8 @@ AMDGPU_DRM_QUEUE_ID_DEFAULT, flip_info, ref_crtc_hw_id, amdgpu_dri2_flip_event_handler, - amdgpu_dri2_flip_event_abort, FLIP_VSYNC)) { + amdgpu_dri2_flip_event_abort, FLIP_VSYNC, + target_msc - amdgpu_get_msc_delta(draw, crtc))) { info->drmmode.dri2_flipping = TRUE; return TRUE; } @@ -783,14 +784,8 @@ if (crtc_id == 1) type |= DRM_VBLANK_SECONDARY; else if (crtc_id > 1) -#ifdef DRM_VBLANK_HIGH_CRTC_SHIFT type |= (crtc_id << DRM_VBLANK_HIGH_CRTC_SHIFT) & DRM_VBLANK_HIGH_CRTC_MASK; -#else - ErrorF("amdgpu driver bug: %s called for CRTC %d > 1, but " - "DRM_VBLANK_HIGH_CRTC_MASK not defined at build time\n", - __func__, crtc_id); -#endif return type; } @@ -1365,7 +1360,6 @@ dri2_info.CopyRegion = amdgpu_dri2_copy_region; if (info->drmmode.count_crtcs > 2) { -#ifdef DRM_CAP_VBLANK_HIGH_CRTC uint64_t cap_value; if (drmGetCap @@ -1380,12 +1374,6 @@ "handle VBLANKs on CRTC > 1\n"); scheduling_works = FALSE; } -#else - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "You need to rebuild against a " - "newer libdrm to handle VBLANKs on CRTC > 1\n"); - scheduling_works = FALSE; -#endif } if (scheduling_works) { diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/amdgpu_dri3.c xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/amdgpu_dri3.c --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/amdgpu_dri3.c 2016-11-27 15:39:36.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/amdgpu_dri3.c 2017-02-08 16:46:15.000000000 +0000 @@ -40,9 +40,7 @@ #include #include - -static int -amdgpu_dri3_open(ScreenPtr screen, RRProviderPtr provider, int *out) +static int open_master_node(ScreenPtr screen, int *out) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn); @@ -88,6 +86,36 @@ return Success; } +static int open_render_node(ScreenPtr screen, int *out) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn); + int fd; + + fd = open(pAMDGPUEnt->render_node, O_RDWR | O_CLOEXEC); + if (fd < 0) + return BadAlloc; + + *out = fd; + return Success; +} + +static int +amdgpu_dri3_open(ScreenPtr screen, RRProviderPtr provider, int *out) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn); + int ret = BadAlloc; + + if (pAMDGPUEnt->render_node) + ret = open_render_node(screen, out); + + if (ret != Success) + ret = open_master_node(screen, out); + + return ret; +} + #if DRI3_SCREEN_INFO_VERSION >= 1 && XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(1,18,99,1,0) static int @@ -229,6 +257,9 @@ amdgpu_dri3_screen_init(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn); + + pAMDGPUEnt->render_node = drmGetRenderDeviceNameFromFd(pAMDGPUEnt->fd); if (!dri3_screen_init(screen, &amdgpu_dri3_screen_info)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/amdgpu_drv.h xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/amdgpu_drv.h --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/amdgpu_drv.h 2016-11-27 15:39:36.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/amdgpu_drv.h 2017-02-08 16:46:15.000000000 +0000 @@ -149,6 +149,9 @@ #if XF86_CRTC_VERSION >= 5 #define AMDGPU_PIXMAP_SHARING 1 +#define amdgpu_is_gpu_screen(screen) (screen)->isGPU +#else +#define amdgpu_is_gpu_screen(screen) 0 #endif #define AMDGPU_VSYNC_TIMEOUT 20000 /* Maximum wait for VSYNC (in usecs) */ @@ -289,8 +292,7 @@ Bool amdgpu_dri3_screen_init(ScreenPtr screen); /* amdgpu_kms.c */ -void amdgpu_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, - uint64_t usec, void *event_data); +Bool amdgpu_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id); /* amdgpu_present.c */ Bool amdgpu_present_screen_init(ScreenPtr screen); diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/amdgpu_kms.c xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/amdgpu_kms.c --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/amdgpu_kms.c 2016-11-27 15:39:36.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/amdgpu_kms.c 2017-02-08 16:46:15.000000000 +0000 @@ -223,7 +223,7 @@ static Bool AMDGPUCreateScreenResources_KMS(ScreenPtr pScreen) { - ExtensionEntry *damage_ext = CheckExtension("DAMAGE"); + ExtensionEntry *damage_ext; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); AMDGPUInfoPtr info = AMDGPUPTR(pScrn); PixmapPtr pixmap; @@ -237,10 +237,7 @@ if (dixPrivateKeyRegistered(rrPrivKey)) { rrScrPrivPtr rrScrPriv = rrGetScrPriv(pScreen); - if ( -#ifdef AMDGPU_PIXMAP_SHARING - !pScreen->isGPU && -#endif + if (!amdgpu_is_gpu_screen(pScreen) && !rrScrPriv->primaryOutput) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); @@ -277,7 +274,8 @@ amdgpu_glamor_create_screen_resources(pScreen); info->callback_event_type = -1; - if (damage_ext) { + if (!amdgpu_is_gpu_screen(pScreen) && + (damage_ext = CheckExtension("DAMAGE"))) { info->callback_event_type = damage_ext->eventBase + XDamageNotify; if (!AddCallback(&FlushCallback, amdgpu_flush_callback, pScrn)) @@ -302,11 +300,21 @@ static Bool amdgpu_scanout_extents_intersect(xf86CrtcPtr xf86_crtc, BoxPtr extents) { - extents->x1 -= xf86_crtc->filter_width >> 1; - extents->x2 += xf86_crtc->filter_width >> 1; - extents->y1 -= xf86_crtc->filter_height >> 1; - extents->y2 += xf86_crtc->filter_height >> 1; - pixman_f_transform_bounds(&xf86_crtc->f_framebuffer_to_crtc, extents); +#ifdef AMDGPU_PIXMAP_SHARING + if (xf86_crtc->scrn->is_gpu) { + extents->x1 -= xf86_crtc->x; + extents->y1 -= xf86_crtc->y; + extents->x2 -= xf86_crtc->x; + extents->y2 -= xf86_crtc->y; + } else +#endif + { + extents->x1 -= xf86_crtc->filter_width >> 1; + extents->x2 += xf86_crtc->filter_width >> 1; + extents->y1 -= xf86_crtc->filter_height >> 1; + extents->y2 += xf86_crtc->filter_height >> 1; + pixman_f_transform_bounds(&xf86_crtc->f_framebuffer_to_crtc, extents); + } extents->x1 = max(extents->x1, 0); extents->y1 = max(extents->y1, 0); @@ -395,8 +403,8 @@ gc = GetScratchGC(dst->depth, pScreen); if (gc) { - ValidateGC(dst, gc); gc->funcs->ChangeClip(gc, CT_REGION, sync_region, 0); + ValidateGC(dst, gc); sync_region = NULL; gc->ops->CopyArea(src, dst, gc, 0, 0, dst->width, dst->height, 0, 0); FreeScratchGC(gc); @@ -584,7 +592,7 @@ return ret; } -void +static void amdgpu_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data) { @@ -701,11 +709,12 @@ return; } - if (drmModePageFlip(pAMDGPUEnt->fd, drmmode_crtc->mode_crtc->crtc_id, - drmmode_crtc->scanout[scanout_id].fb_id, - DRM_MODE_PAGE_FLIP_EVENT, (void*)drm_queue_seq)) { + if (drmmode_page_flip_target_relative(pAMDGPUEnt, drmmode_crtc, + drmmode_crtc->scanout[scanout_id].fb_id, + 0, drm_queue_seq, 0) != 0) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n", __func__, strerror(errno)); + amdgpu_drm_abort_entry(drm_queue_seq); return; } @@ -759,7 +768,7 @@ } #endif -static Bool +Bool amdgpu_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id) { drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; @@ -865,7 +874,7 @@ drmmode_crtc->scanout_update_pending = FALSE; } -void +static void amdgpu_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data) { @@ -949,8 +958,8 @@ xf86CrtcPtr xf86_crtc) { drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; - ScrnInfoPtr scrn; - AMDGPUEntPtr pAMDGPUEnt; + ScrnInfoPtr scrn = xf86_crtc->scrn; + AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn); uintptr_t drm_queue_seq; unsigned scanout_id; @@ -961,7 +970,6 @@ if (!amdgpu_scanout_do_update(xf86_crtc, scanout_id)) return; - scrn = xf86_crtc->scrn; drm_queue_seq = amdgpu_drm_queue_alloc(xf86_crtc, AMDGPU_DRM_QUEUE_CLIENT_DEFAULT, AMDGPU_DRM_QUEUE_ID_DEFAULT, @@ -973,12 +981,12 @@ return; } - pAMDGPUEnt = AMDGPUEntPriv(scrn); - if (drmModePageFlip(pAMDGPUEnt->fd, drmmode_crtc->mode_crtc->crtc_id, - drmmode_crtc->scanout[scanout_id].fb_id, - DRM_MODE_PAGE_FLIP_EVENT, (void*)drm_queue_seq)) { + if (drmmode_page_flip_target_relative(pAMDGPUEnt, drmmode_crtc, + drmmode_crtc->scanout[scanout_id].fb_id, + 0, drm_queue_seq, 0) != 0) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n", __func__, strerror(errno)); + amdgpu_drm_abort_entry(drm_queue_seq); return; } @@ -999,9 +1007,7 @@ (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); pScreen->BlockHandler = AMDGPUBlockHandler_KMS; -#ifdef AMDGPU_PIXMAP_SHARING - if (!pScreen->isGPU) -#endif + if (!amdgpu_is_gpu_screen(pScreen)) { for (c = 0; c < xf86_config->num_crtc; c++) { if (info->tear_free) diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/amdgpu_present.c xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/amdgpu_present.c --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/amdgpu_present.c 2016-11-27 15:39:36.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/amdgpu_present.c 2017-02-08 16:46:15.000000000 +0000 @@ -329,7 +329,8 @@ pixmap, event_id, event, crtc_id, amdgpu_present_flip_event, amdgpu_present_flip_abort, - sync_flip ? FLIP_VSYNC : FLIP_ASYNC); + sync_flip ? FLIP_VSYNC : FLIP_ASYNC, + target_msc); if (!ret) xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present flip failed\n"); else @@ -366,7 +367,7 @@ if (amdgpu_do_pageflip(scrn, AMDGPU_DRM_QUEUE_CLIENT_DEFAULT, pixmap, event_id, event, -1, amdgpu_present_flip_event, - amdgpu_present_flip_abort, FLIP_VSYNC)) + amdgpu_present_flip_abort, FLIP_VSYNC, 0)) return; modeset: diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/amdgpu_probe.h xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/amdgpu_probe.h --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/amdgpu_probe.h 2016-11-27 15:39:36.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/amdgpu_probe.h 2017-02-08 16:46:15.000000000 +0000 @@ -56,6 +56,7 @@ typedef struct { Bool HasCRTC2; /* All cards except original Radeon */ + Bool has_page_flip_target; amdgpu_device_handle pDev; @@ -67,6 +68,7 @@ ScrnInfoPtr primary_scrn; ScrnInfoPtr secondary_scrn; struct xf86_platform_device *platform_dev; + char *render_node; } AMDGPUEntRec, *AMDGPUEntPtr; extern const OptionInfoRec *AMDGPUOptionsWeak(void); diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/drmmode_display.c xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/drmmode_display.c --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/drmmode_display.c 2016-11-27 15:39:36.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/drmmode_display.c 2017-02-08 16:46:15.000000000 +0000 @@ -497,14 +497,13 @@ static void * drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, - int width, int height) + int width, int height, int *pitch) { ScrnInfoPtr pScrn = crtc->scrn; AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; int ret; - int pitch; union gbm_bo_handle bo_handle; if (scanout->bo) { @@ -515,8 +514,8 @@ } scanout->bo = amdgpu_alloc_pixmap_bo(pScrn, width, height, - pScrn->depth, 0, - pScrn->bitsPerPixel, &pitch); + pScrn->depth, 0, + pScrn->bitsPerPixel, pitch); if (!scanout->bo) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate rotation buffer memory\n"); @@ -525,7 +524,7 @@ bo_handle = gbm_bo_get_handle(scanout->bo->bo.gbm); ret = drmModeAddFB(pAMDGPUEnt->fd, width, height, pScrn->depth, - pScrn->bitsPerPixel, pitch, + pScrn->bitsPerPixel, *pitch, bo_handle.u32, &scanout->fb_id); if (ret) { ErrorF("failed to add rotate fb\n"); @@ -547,7 +546,7 @@ ScrnInfoPtr pScrn = crtc->scrn; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; - unsigned long rotate_pitch; + int pitch; if (scanout->pixmap) { if (scanout->width == width && scanout->height == height) @@ -557,18 +556,16 @@ } if (!scanout->bo) { - if (!drmmode_crtc_scanout_allocate(crtc, scanout, width, height)) + if (!drmmode_crtc_scanout_allocate(crtc, scanout, width, height, + &pitch)) return NULL; } - rotate_pitch = gbm_bo_get_stride(scanout->bo->bo.gbm); - scanout->pixmap = drmmode_create_bo_pixmap(pScrn, width, height, pScrn->depth, pScrn->bitsPerPixel, - rotate_pitch, - scanout->bo); + pitch, scanout->bo); if (scanout->pixmap == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't allocate shadow pixmap for rotated CRTC\n"); @@ -663,6 +660,7 @@ AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + unsigned scanout_id = drmmode_crtc->scanout_id ^ info->tear_free; drmmode_ptr drmmode = drmmode_crtc->drmmode; int saved_x, saved_y; Rotation saved_rotation; @@ -714,17 +712,15 @@ fb_id = drmmode->fb_id; #ifdef AMDGPU_PIXMAP_SHARING if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) { - fb_id = drmmode_crtc->scanout[0].fb_id; + fb_id = drmmode_crtc->scanout[scanout_id].fb_id; x = y = 0; } else #endif if (drmmode_crtc->rotate.fb_id) { fb_id = drmmode_crtc->rotate.fb_id; x = y = 0; - } else if ( -#ifdef AMDGPU_PIXMAP_SHARING - !pScreen->isGPU && -#endif + + } else if (!amdgpu_is_gpu_screen(pScreen) && (info->tear_free || #if XF86_CRTC_VERSION >= 4 crtc->driverIsPerformingTransform || @@ -760,11 +756,10 @@ pBox->x2 = max(pBox->x2, pScrn->virtualX); pBox->y2 = max(pBox->y2, pScrn->virtualY); - drmmode_crtc->scanout_id = 0; - fb_id = drmmode_crtc->scanout[0].fb_id; + fb_id = drmmode_crtc->scanout[scanout_id].fb_id; x = y = 0; - amdgpu_scanout_update_handler(crtc, 0, 0, drmmode_crtc); + amdgpu_scanout_do_update(crtc, scanout_id); amdgpu_glamor_finish(pScrn); } } @@ -847,7 +842,7 @@ } else { crtc->active = TRUE; - if (fb_id != drmmode_crtc->scanout[0].fb_id) + if (fb_id != drmmode_crtc->scanout[scanout_id].fb_id) drmmode_crtc_scanout_free(drmmode_crtc); } @@ -1056,9 +1051,10 @@ int height) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + int pitch; return drmmode_crtc_scanout_allocate(crtc, &drmmode_crtc->rotate, - width, height); + width, height, &pitch); } static PixmapPtr @@ -1098,13 +1094,13 @@ static Bool drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + unsigned scanout_id = drmmode_crtc->scanout_id; AMDGPUInfoPtr info = AMDGPUPTR(crtc->scrn); ScreenPtr screen = crtc->scrn->pScreen; PixmapDirtyUpdatePtr dirty; xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { - if (dirty->slave_dst != - drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap) + if (dirty->slave_dst != drmmode_crtc->scanout[scanout_id].pixmap) continue; PixmapStopDirtyTracking(dirty->src, dirty->slave_dst); @@ -1129,13 +1125,13 @@ } #ifdef HAS_DIRTYTRACKING_ROTATION - PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[0].pixmap, + PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[scanout_id].pixmap, 0, 0, 0, 0, RR_Rotate_0); #elif defined(HAS_DIRTYTRACKING2) - PixmapStartDirtyTracking2(ppix, drmmode_crtc->scanout[0].pixmap, + PixmapStartDirtyTracking2(ppix, drmmode_crtc->scanout[scanout_id].pixmap, 0, 0, 0, 0); #else - PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[0].pixmap, 0, 0); + PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[scanout_id].pixmap, 0, 0); #endif return TRUE; } @@ -2132,6 +2128,59 @@ } #endif +static Bool drmmode_probe_page_flip_target(AMDGPUEntPtr pAMDGPUEnt) +{ + uint64_t cap_value; + + return drmGetCap(pAMDGPUEnt->fd, DRM_CAP_PAGE_FLIP_TARGET, + &cap_value) == 0 && cap_value != 0; +} + +static int +drmmode_page_flip(AMDGPUEntPtr pAMDGPUEnt, drmmode_crtc_private_ptr drmmode_crtc, + int fb_id, uint32_t flags, uintptr_t drm_queue_seq) +{ + flags |= DRM_MODE_PAGE_FLIP_EVENT; + return drmModePageFlip(pAMDGPUEnt->fd, drmmode_crtc->mode_crtc->crtc_id, + fb_id, flags, (void*)drm_queue_seq); +} + +int +drmmode_page_flip_target_absolute(AMDGPUEntPtr pAMDGPUEnt, + drmmode_crtc_private_ptr drmmode_crtc, + int fb_id, uint32_t flags, + uintptr_t drm_queue_seq, uint32_t target_msc) +{ + if (pAMDGPUEnt->has_page_flip_target) { + flags |= DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE; + return drmModePageFlipTarget(pAMDGPUEnt->fd, + drmmode_crtc->mode_crtc->crtc_id, + fb_id, flags, (void*)drm_queue_seq, + target_msc); + } + + return drmmode_page_flip(pAMDGPUEnt, drmmode_crtc, fb_id, flags, + drm_queue_seq); +} + +int +drmmode_page_flip_target_relative(AMDGPUEntPtr pAMDGPUEnt, + drmmode_crtc_private_ptr drmmode_crtc, + int fb_id, uint32_t flags, + uintptr_t drm_queue_seq, uint32_t target_msc) +{ + if (pAMDGPUEnt->has_page_flip_target) { + flags |= DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_PAGE_FLIP_TARGET_RELATIVE; + return drmModePageFlipTarget(pAMDGPUEnt->fd, + drmmode_crtc->mode_crtc->crtc_id, + fb_id, flags, (void*)drm_queue_seq, + target_msc); + } + + return drmmode_page_flip(pAMDGPUEnt, drmmode_crtc, fb_id, flags, + drm_queue_seq); +} + Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) { AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn); @@ -2198,6 +2247,8 @@ drmmode->event_context.vblank_handler = amdgpu_drm_queue_handler; drmmode->event_context.page_flip_handler = amdgpu_drm_queue_handler; + pAMDGPUEnt->has_page_flip_target = drmmode_probe_page_flip_target(pAMDGPUEnt); + drmModeFreeResources(mode_res); return TRUE; } @@ -2475,10 +2526,20 @@ ScrnInfoPtr scrn = drmmode->scrn; struct udev_device *dev; Bool received = FALSE; + struct timeval tv = { 0, 0 }; + fd_set readfd; - while ((dev = udev_monitor_receive_device(drmmode->uevent_monitor))) { - udev_device_unref(dev); - received = TRUE; + FD_ZERO(&readfd); + FD_SET(fd, &readfd); + + while (select(fd + 1, &readfd, NULL, NULL, &tv) > 0 && + FD_ISSET(fd, &readfd)) { + /* select() ensured that this will not block */ + dev = udev_monitor_receive_device(drmmode->uevent_monitor); + if (dev) { + udev_device_unref(dev); + received = TRUE; + } } if (received) @@ -2535,7 +2596,8 @@ PixmapPtr new_front, uint64_t id, void *data, int ref_crtc_hw_id, amdgpu_drm_handler_proc handler, amdgpu_drm_abort_proc abort, - enum drmmode_flip_sync flip_sync) + enum drmmode_flip_sync flip_sync, + uint32_t target_msc) { AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); @@ -2543,7 +2605,7 @@ drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; int i; - uint32_t flip_flags = DRM_MODE_PAGE_FLIP_EVENT; + uint32_t flip_flags = flip_sync == FLIP_ASYNC ? DRM_MODE_PAGE_FLIP_ASYNC : 0; drmmode_flipdata_ptr flipdata; uintptr_t drm_queue_seq = 0; uint32_t new_front_handle; @@ -2585,9 +2647,6 @@ flipdata->handler = handler; flipdata->abort = abort; - if (flip_sync == FLIP_ASYNC) - flip_flags |= DRM_MODE_PAGE_FLIP_ASYNC; - for (i = 0; i < config->num_crtc; i++) { crtc = config->crtc[i]; @@ -2613,13 +2672,23 @@ goto error; } - if (drmModePageFlip(pAMDGPUEnt->fd, drmmode_crtc->mode_crtc->crtc_id, - drmmode->fb_id, flip_flags, - (void*)drm_queue_seq)) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "flip queue failed: %s\n", strerror(errno)); - goto error; + if (drmmode_crtc->hw_id == ref_crtc_hw_id) { + if (drmmode_page_flip_target_absolute(pAMDGPUEnt, + drmmode_crtc, + drmmode->fb_id, + flip_flags, + drm_queue_seq, + target_msc) != 0) + goto flip_error; + } else { + if (drmmode_page_flip_target_relative(pAMDGPUEnt, + drmmode_crtc, + drmmode->fb_id, + flip_flags, + drm_queue_seq, 0) != 0) + goto flip_error; } + drmmode_crtc->flip_pending = TRUE; drm_queue_seq = 0; } @@ -2627,6 +2696,10 @@ if (flipdata->flip_count > 0) return TRUE; +flip_error: + xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed: %s\n", + strerror(errno)); + error: if (flipdata && flipdata->flip_count <= 1) { drmModeRmFB(pAMDGPUEnt->fd, drmmode->fb_id); diff -Nru xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/drmmode_display.h xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/drmmode_display.h --- xserver-xorg-video-amdgpu-1.2.99+git20161127.e8aa4e7e/src/drmmode_display.h 2016-11-27 15:39:36.000000000 +0000 +++ xserver-xorg-video-amdgpu-1.2.99+git20170208.49b09256/src/drmmode_display.h 2017-02-08 16:46:15.000000000 +0000 @@ -36,10 +36,6 @@ #include "amdgpu_probe.h" #include "amdgpu.h" -#ifndef DRM_CAP_TIMESTAMP_MONOTONIC -#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 -#endif - typedef struct { unsigned fb_id; drmModeFBPtr mode_fb; @@ -130,6 +126,16 @@ }; +extern int drmmode_page_flip_target_absolute(AMDGPUEntPtr pAMDGPUEnt, + drmmode_crtc_private_ptr drmmode_crtc, + int fb_id, uint32_t flags, + uintptr_t drm_queue_seq, + uint32_t target_msc); +extern int drmmode_page_flip_target_relative(AMDGPUEntPtr pAMDGPUEnt, + drmmode_crtc_private_ptr drmmode_crtc, + int fb_id, uint32_t flags, + uintptr_t drm_queue_seq, + uint32_t target_msc); extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp); extern void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode); extern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode); @@ -153,7 +159,8 @@ PixmapPtr new_front, uint64_t id, void *data, int ref_crtc_hw_id, amdgpu_drm_handler_proc handler, amdgpu_drm_abort_proc abort, - enum drmmode_flip_sync flip_sync); + enum drmmode_flip_sync flip_sync, + uint32_t target_msc); int drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc); int drmmode_get_current_ust(int drm_fd, CARD64 * ust);