diff options
24 files changed, 1782 insertions, 522 deletions
diff --git a/driver/xf86-video-ati/ChangeLog b/driver/xf86-video-ati/ChangeLog index 3aa14d6e1..a907ec709 100644 --- a/driver/xf86-video-ati/ChangeLog +++ b/driver/xf86-video-ati/ChangeLog @@ -1,3 +1,755 @@ +commit d6f89352f64f4eff858b671e49b732f9973f6e11 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Sep 15 17:44:21 2016 +0900 + + Bump version for 7.7.1 release + +commit e890402d14ea7c4b22ef7f19d0679fb45d4eac4e +Author: Qiang Yu <Qiang.Yu@amd.com> +Date: Thu Sep 15 16:51:00 2016 +0900 + + DRI2: Fix radeon_dri2_exchange_buffers width/height copy'n'paste error + + Signed-off-by: Qiang Yu <Qiang.Yu@amd.com> + (Ported from amdgpu commit 73c8dc000ad6b2b53ba3aa7155f5e8f6b55623b7) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit 12d30eeb9711bd2b1609d6bbb74c4a1760596f72) + +commit b95ddb39c1154b3231cefd4e99046e7fb89f1e99 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Sep 15 16:50:24 2016 +0900 + + DRI2: Add interpolated_vblanks in radeon_dri2_get_crtc_msc + + We need that in radeon_dri2_drawable_crtc as well for priv->vblank_delta + to work as intended. + + radeon_dri2_get_msc was already doing this. + + Fixes hangs in some cases when using VDPAU via DRI2 and moving the + window between CRTCs. + + (Ported from amdgpu commit abd1a7901c95e4bc78415cf1b7923623b9177152) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit 11cc6843aa3b745aa1361f1a65e465e16696b914) + +commit 6cca7d529c3bb07bc78a49ae5085028ac743fe1d +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Sep 15 16:49:48 2016 +0900 + + Destroy all dedicated scanout buffers during CloseScreen + + Fixes leaking active scanout buffers across a server reset, which also + fixes server reset with glamor and active scanout buffers. + + (Ported from amdgpu commit d96dabc71b1b32dc4b422a9633cdd4e0e95da052) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit 4a5fa37f74c233c6b9c6a08306688628a8e216e8) + +commit 05f3735131e8fa8c2d1adbca70dab7967e3be58c +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Sep 15 16:49:10 2016 +0900 + + glamor: Reallocate linear pixmap BO if necessary for DRI2 PRIME + + Fixes corruption when using DRI2 PRIME render offloading with the master + screen using this driver. + + (Ported from amdgpu commit 0007c2f018ba663303d91d847e7c085269a23062) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit cc2555835cd4c5fd2ae4f999a4bf7c18cdb1dda4) + +commit 6babf4d2205543a61fcd62c75fd88e49d0ed7cf1 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Sep 15 16:48:20 2016 +0900 + + Move DRI2's local fixup_glamor helper to radeon_glamor_set_pixmap_bo + + So it can be used outside of the DRI2 code. + + (Ported from amdgpu commit 5518bf5d793439b5bab369e5fc18de9a4a3b9dd6) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit b3e5259e60157fdbdf46ee59b1b78995c2b15f72) + +commit a3d8e717d5dba8495d6b9934b0804342106e90f5 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Sep 15 16:47:54 2016 +0900 + + Consolidate get_drawable_pixmap helper + + There were two static helpers for the same purpose. Consolidate them + into a single inline helper which can be used anywhere. + + (Ported from amdgpu commit 641f4647b7f51dfd2da330376cd10fa9702b6423) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit 38632bbd5ff80a9cf8ce584b2bc499d17d15befe) + +commit 00a988a811741ee4e4af265deb68b97cc7e5c985 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Sep 15 16:47:23 2016 +0900 + + glamor: Fix radeon_glamor_share_pixmap_backing for priv->bo == NULL + + Fixes crash when running a compositor and DRI_PRIME client via DRI2. + + Reported-by: Qiang Yu <qiang.yu@amd.com> + (Ported from amdgpu commit b36c77695ba77b59a0ccd868454e3af4fc04d5ff) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit e91858e435672c32f9c4a854b3dec048199d6f7f) + +commit 953b4c2cdf3ea2dcf2d7cc0b1fa0fabefcc49afd +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Sep 15 16:46:35 2016 +0900 + + Also handle disabled CRTCs in drmmode_clear_pending_flip + + If disabling a CRTC had to be deferred due to a pending flip in + drmmode_crtc_dpms, there may no longer be any outputs associated with + the CRTC when we get here. So we have to check for !crtc->enabled and + call drmmode_crtc_dpms in that case as well. + + Fixes: 9090309e057d ("Wait for pending flips to complete before turning + off an output or CRTC") + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit 4bd2d01552f18153afa03a8947b22eebf3d67c6b) + +commit 13f3fe45a4026801f61fb6429ca6e239a1b8c081 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Sep 15 16:46:04 2016 +0900 + + Don't override crtc parameter value in drmmode_flip_handler/abort + + When overriding the crtc parameter value of the last pending CRTC, + drmmode_clear_pending_flip would work on the wrong CRTC, and the last + pending CRTC's flip_pending flag might never get cleared. This would + prevent that CRTC from properly turning off and back on again. + + Fixes: 9090309e057d ("Wait for pending flips to complete before turning + off an output or CRTC") + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97392 + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit a36fdaff40d5b4795a1400c348a80eee94892212) + +commit 08672d31a616060d23a2e1543643eafa97bfe236 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Aug 25 18:22:34 2016 +0900 + + Also call drmmode_clear_pending_flip from radeon_scanout_flip_abort + + Not doing so could break DPMS with TearFree. + + Reported-and-Tested-by: furkan on IRC + Fixes: 9090309e057d ("Wait for pending flips to complete before turning + off an output or CRTC") + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit e520ce0ec0adf91ddce5c932d4b3f9477fd49304) + +commit a12ff1c6aec4453a6f64878cc64961488e803ed1 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Sep 15 16:44:13 2016 +0900 + + Wait for pending flips to complete before turning off an output or CRTC + + At least with older kernels, the flip may never complete otherwise, + which can result in us hanging in drmmode_set_mode_major. + + Fixes: https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-ati/+bug/1577170 + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit 9090309e057dc703d1a5bffd88e6cae14108cfc3) + +commit 4d377fd007d9a39178e318a8cf8bee5d68415c56 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Sep 15 16:42:05 2016 +0900 + + Don't enable micro-tiling for scanout buffers on pre-R600 + + The display engine didn't support it. + + Fixes display corruption with options "TearFree" and "ShadowPrimary" + (and rotation or transforms with current xserver) on pre-R600. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit 6d91fb4fc701895473ff675f440a8eef655e80ca) + +commit 16135cc8b5d302cf89e174c52e455b64c2c84237 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Sep 15 16:41:15 2016 +0900 + + Only use RandR APIs if RandR is enabled + + Fixes crash with Xinerama enabled, which disables RandR. + + Fixes: https://bugs.debian.org/827984 + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit 3be841d0ae7d505cef325993205b12d15e98dba9) + +commit 948f592259f2f0c0ff331b869fb8f73ce0b29193 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Sep 15 16:40:32 2016 +0900 + + Explicitly set the fbcon pixmap pitch again + + The kernel driver returns 0 as the pitch of the fbcon BO via the + DRM_RADEON_GEM_GET_TILING ioctl, so we ended up using an incorrect + pitch in some cases. + + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94901 + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit 040a7b80e1fcbaa93ac17f7113d696d9b853cf8a) + +commit d1e74e357278d1227425b12a4a1be2b337a6051d +Author: Qiang Yu <Qiang.Yu@amd.com> +Date: Thu Sep 15 16:39:37 2016 +0900 + + Fix radeon_mode_hotplug crash on multi GPU platform. + + On multi GPU platform, some screen is created by other GPU DDX. + + Signed-off-by: Qiang Yu <Qiang.Yu@amd.com> + (Ported from amdgpu commit 978242977e5dc905e1d5a46b1b0d34b356c7af26) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit 380daff43cfefe2a8e4d496eaf65673f2815c878) + +commit 3f4cba12b71206aa60271ac435c3709ee335a371 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Sep 15 16:38:52 2016 +0900 + + Handle Zaphod mode correctly in radeon_mode_hotplug + + We need to scan both screens of the entity for existing connectors, and + enumerate DVI & HDMI connectors consistently regardless of which screen + they're assigned to. + + Fixes crash when hot-(un)plugging connectors in Zaphod mode. + + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93415 + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit c801f9f10a5d72d935faf21e72f7e7808fb4f05f) + +commit 470538c354977e2ef5256029433d2e28e4a1f7e8 +Author: Qiang Yu <Qiang.Yu@amd.com> +Date: Thu Sep 15 16:37:57 2016 +0900 + + Remove RR_Capability_SinkOutput for GPU without CRTC + + Signed-off-by: Qiang Yu <Qiang.Yu@amd.com> + (Ported from amdgpu commit a0bbb373f902e0ffc14570c85faec7e44134f62e) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + (Cherry picked from commit ba8b6288c8e6fc4be5d7144ecbe9a1f241881674) + +commit df6662864b56d1aeeea4c67d9b668e64197afb20 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Apr 7 11:44:05 2016 +0900 + + Bump version for 7.7.0 release + +commit c12614cfdc5729041c204e3ead1dbfde38011f0c +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Mon Apr 4 14:59:41 2016 +0900 + + Update manpage entry for Option "TearFree" + + It's now effective for rotation as well. + + (Ported from amdgpu commit faf9d720b7d650f5f1ea657a874d08eac3972e60) + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 4693b1bd5b5c381e8b7b68a6f7f0c6696d6a68df +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Mar 31 17:02:55 2016 +0900 + + Identify DRM event queue entries by sequence number instead of by pointer + + If the memory for an entry was allocated at the same address as that for + a previously cancelled entry, the handler could theoretically be called + prematurely, triggered by the DRM event which was submitted for the + cancelled entry. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 83734317e6bdaeebb4462a63f541e73a1d7c2f77 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Wed Mar 30 11:44:09 2016 +0900 + + Update pixmap pitch in radeon_set_pixmap_bo + + Stop second guessing it in drmmode_crtc_scanout_create. + + Fixes display corruption in some cases with TearFree enabled. + + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94751 + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 0b3aac1de9db42bfca545fa331e4985836682ec7 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Mon Mar 28 18:43:36 2016 +0900 + + DRI3: Refuse to open DRM file descriptor for ssh clients (v2) + + Fixes hangs when attempting to use DRI3 on display connections forwarded + via SSH. + + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93261 + + v2: Don't do this for Xorg > 1.18.99.1 since the corresponding xserver + change has landed in Git master. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> (v1) + +commit 8a6cd4bda05b9569b3dd0a5a75b2cc385b9ecba9 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Fri Mar 25 11:50:15 2016 +0900 + + Revert "Use render node for DRI3 if available" + + This reverts commit cd94248ffa7d8fe0b57476f79e7e860dee66d1b0. + + It broke VDPAU<->GL interop with DRI3 enabled, because the Gallium VDPAU + code doesn't support DRI3 yet. We can consider re-enabling this once + there is a Mesa release where the Gallium VDPAU code supports DRI3. + + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94675 + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit ed31cffba0d1bd4b14e5348a1456e4377277059c +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Mar 24 18:08:22 2016 +0900 + + Call RADEONBlockHandler_KMS before setting initial modes + + Doing it the other way around meant that there was still a possibility + for the front buffer contents to be uninitialized when they start being + scanned out. + + (Ported from amdgpu commit 4a60b4b1851a3cbc2d8ad9048d68eeb6947cf132) + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit e592f32f8b5f5873fcc18b10a69dd5e4ccf11073 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Wed Mar 23 18:25:48 2016 +0900 + + Require xserver 1.9 or newer + + 1.9.0 was released in August 2010. + + We were already unintentionally relying on things not available in 1.8 + for at least a year, and nobody has complained. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit bde466e5d44cad64b4e4eceaa5de80fdbf86356e +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Wed Mar 23 18:16:42 2016 +0900 + + Fix build against older versions of xserver + + Also slightly clean up the error handling in radeon_scanout_do_update. + + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94614 + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit b2b079be0e7ef2704c3df9ee25fe46166e450e83 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Wed Mar 23 17:29:47 2016 +0900 + + Use radeon_alloc_pixmap_bo for allocating scanout BOs + + This enables tiling for scanout BOs used for TearFree / ShadowPrimary, + and simplifies the code a little. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit d21ac4669a8b2cdd4eec5e5a94d1950b7423b8b5 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Wed Mar 23 17:27:27 2016 +0900 + + DRI3 only works with acceleration + + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94214 + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit eb1a2c57e6c45d7ca57b2e2be643194243b7aae1 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Wed Mar 23 17:23:31 2016 +0900 + + TearFree can only work with acceleration + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit d670c5c9851b4eff21c845d26c7d7e4eb5ee0fa9 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Fri Mar 18 16:46:08 2016 +0900 + + Check for xf86CursorResetCursor + + If it's available, Xorg calls it on each mode configuration change. It + does what xf86_reload_cursors does (and more), so we don't need to call + the latter anymore. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 7f3d0780ca65a90117c2a61362dbc0899bd9c0b0 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Wed Mar 9 18:28:47 2016 +0900 + + Don't try DRI2/Present flipping while the HW cursor can't be used + + Flipping doesn't interact correctly with SW cursor: A flip makes the SW + cursor disappear. It will only appear again when the cursor is moved, + but it will be surrounded by corruption, because the SW cursor code + will restore stale screen contents at the old cursor location before + drawing the cursor at the new location. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 3de480e83c0a1824838d662d6d67c9fe85277298 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Wed Mar 9 16:44:32 2016 +0900 + + Factor out HW cursor checking code into drmmode_can_use_hw_cursor + + And add a check for RandR 1.4 multihead. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 2e0b458e747c7df81dd5f9579a762262af3350e1 +Author: Ryan Kennedy <Ryan.Kennedy@amd.com> +Date: Sun Mar 20 17:57:56 2016 -0400 + + Use correct tiling in drmmode_create_bo_pixmap + + The callers were using 0 for the tiling flags, causing surfaces to be + incorrectly treated as linear. This issue was causing corruption on Cayman + just after login with GNOME3. The kernel was rejecting the cs in + drmmode_copy_fb due to invalid texture pitch. + + Signed-off-by: Ryan Kennedy <Ryan.Kennedy@amd.com> + Reviewed-by: Michel Dänzer <michel.daenzer@amd.com> + +commit a03271de5ecdaa7790d1316e993c4450b91fe936 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Wed Mar 9 18:23:10 2016 +0900 + + present: Return rotated CRTCs from radeon_present_get_crtc + + Sync-to-vblank works fine with rotation. We're still checking for + rotation in radeon_present_check_flip. + + Returning NULL from here resulted in the xserver present code falling + back to the fake CRTC running at 1 fps. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 40191d82370eb7e58bd34c44966cbf44c3703229 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Wed Mar 9 18:15:57 2016 +0900 + + present: Clear drmmode->fb_id before calling set_mode_major for unflip + + Without this, drmmode_set_mode_major may just re-set the FB for the + last flipped BO, in which case the display will probably freeze. + + Reproduction recipe: Enable rotation while a fullscreen client is + flipping. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 798c4fd16d339b1ad5fd729cc884be084c60e38b +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Fri Dec 25 18:57:42 2015 +0900 + + Make Option "TearFree" effective for rotated/reflected outputs as well (v2) + + Support varies by xserver version: + + < 1.12: No support for the driver handling rotation/reflection + 1.12-1.15: Support for driver handling rotation/reflection, but there's + a bug preventing the HW cursor from being visible everywhere + it should be on rotated outputs, so we can only support + TearFree for reflection. + >= 1.16: While the bug above is still there (fixes pending review), + the driver can force SW cursor for rotated outputs, so we + can support TearFree for rotation as well. + + v2: Don't set crtc->driverIsPerformingTransform after xf86CrtcRotate if + it wasn't set before. Fixes breaking rotation with TearFree disabled. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> (v1) + +commit eb611a2e4ecce7a1ab85fd72b9b78e3269311dd5 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Tue Feb 2 18:04:11 2016 +0900 + + Consolidate pScreen usage in drmmode_set_mode_major + + We were already relying on pScrn->pScreen being non-NULL in some cases, + which is supposedly always true ever since this function is no longer + getting called from ScreenInit. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 06602171386e538081c298645fb7ca1a70fe80cc +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Feb 4 17:13:57 2016 +0900 + + Remove check for XF86_CRTC_VERSION 3 + + We require xserver >= 1.8, which was already at version 3. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit a88985f5d1e39caca49ceb65678aaa9cb622a0d2 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Mon Feb 29 18:12:43 2016 +0900 + + Deal with modesets and page flips crossing on a CRTC + + If we set a mode while a flip is pending, the kernel driver may program + the flip to the hardware after the modeset. If that happens, the hardware + will display the BO from the flip, whereas we will assume it displays the + BO from the modeset. In other words, the display will most likely freeze, + at least until another modeset. + + Prevent this condition by waiting for a pending flip to finish before + setting a mode. + + Fixes display freezing when setting rotation or a transform with + TearFree enabled. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit f5d968cbba3c9b7ec202161f2157d8d64778c817 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu May 21 12:54:31 2015 +0900 + + Make DRM event queue xf86CrtcPtr based instead of ScrnInfoPtr based + + This allows for a minor simplification of the code. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit e87365117acbd80b7d80fbb5eb30890ef7153291 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Feb 25 16:49:16 2016 +0900 + + DRI2: Also clear dri2_flipping when client disconnects before event + + Fixes the following problem: + + With DRI3 enabled, run glxgears with LIBGL_DRI3_DISABLE=1, make it + fullscreen and press Escape while it's still fullscreen. This could + result in dri2_flipping not getting cleared, spuriously preventing apps + using DRI3 from flipping. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit d5dbb07db22d5420c81dfebc060f0dd86e7b8a20 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Feb 25 18:02:12 2016 +0900 + + Remove radeon_scanout_flip_handler + + No longer necessary now that radeon_drm_queue_handler can handle + e->handler == NULL. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 3989766edde85d1abe7024577b98fc9b007bc02a +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Feb 25 16:43:48 2016 +0900 + + drm_queue: Don't abort events immediately from radeon_drm_abort_client + + Keep them around until the DRM event arrives, but then call the abort + functions instead of the handler functions. + + This is a prerequisite for the following fix. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 7bc089ee9740a3ef91f16e36786d8ed64e165acd +Author: jimqu <Jim.Qu@amd.com> +Date: Tue Feb 16 17:05:48 2016 +0900 + + glamor: Return NullPixmap on failure to create shareable pixmap + + If we were asked to create a shareable pixmap, it doesn't make sense + to return a pixmap which isn't shareable. Doing so caused trouble down + the line such as a crash with older versions of glamor when trying to + use GLX pixmaps of bpp < 32 via DRI2. + + Signed-off-by: JimQu <jim.qu@amd.com> + (ported from amdgpu commit 2fcb7dadd3c71cd405cbbaafc777697538ca9c29) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 4cc32031467157ab8788f5c684fb1ac67ae96ff9 +Author: jimqu <Jim.Qu@amd.com> +Date: Tue Feb 16 17:03:24 2016 +0900 + + Move radeon_glamor_destroy_pixmap before radeon_glamor_create_pixmap + + The next commit will call the former from the latter. No functional + change. + + Signed-off-by: JimQu <jim.qu@amd.com> + (ported from amdgpu commit 5269a2228bff6023c1a7f3e8534027e1d7addc25) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit a9b181083d56b5de9b6822d0ed89fcc86de777a6 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Tue Feb 16 16:59:40 2016 +0900 + + Remove pci_dev test from radeon_get_scrninfo + + The pci_dev parameter can never be NULL since we only support KMS. + + Reported-by: Tom St Denis <tom.stdenis@amd.com> + (ported from amdgpu commit 6e42c58375a4c3229da93c27bbd104af145c6163) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 2c7f068b0a0493daae86e5eacdf8d9812fcd28dc +Author: Mykola Lysenko <Mykola.Lysenko@amd.com> +Date: Mon Feb 15 18:21:39 2016 +0900 + + Initialize drmmode_crtc dpms_mode to DPMSModeOff + + This disables query of disabled pipes for drmWaitVBlank on X start + + Signed-off-by: Mykola Lysenko <Mykola.Lysenko@amd.com> + (ported from amdgpu commit 4eb9cedca080b30c57ded349a397620ee7d0cd46) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 9358e44f03c95396b7f7a4f7398f5b24d2559bb2 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Mon Feb 15 18:20:31 2016 +0900 + + sync: Check if miSyncShmScreenInit symbol is resolved at runtime + + It may be disabled in the Xorg build, either explicitly or because the + xshmfence library isn't available. + + (ported from amdgpu commit 1d0b0c1794e65e581a48aa9fb19679d928d82a5d) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit cd94248ffa7d8fe0b57476f79e7e860dee66d1b0 +Author: Jammy Zhou <Jammy.Zhou@amd.com> +Date: Tue Feb 16 16:36:33 2016 +0900 + + Use render node for DRI3 if available + + Signed-off-by: Jammy Zhou <Jammy.Zhou@amd.com> + (ported from amdgpu commit ea558e645786b08d75307716036045170e97b43e) + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit d41fcccf2f11d0393d252e76bbbe6d233c4ac443 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Wed Jan 20 11:20:30 2016 +0900 + + Set RADEON_GEM_NO_CPU_ACCESS flag for BOs which don't need CPU access + + Failing to do this was resulting in the kernel driver unnecessarily + leaving open the possibility of CPU access to those BOs. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 9483a3d777919b224f70c3b4d01e4b320a57db31 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Fri Jan 15 16:48:46 2016 +0900 + + Fix RandR CRTC transforms + + Currently, Xorg will only transform the cursor as of the first time the + cursor image changes after a transform is set. + + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80678 + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit b16856b25086ffb27365ac2249b8da921066ce62 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Jan 14 17:32:54 2016 +0900 + + Set the RandR primary output on startup if Xorg hasn't + + Fixes xrandr (XRRGetOutputPrimary) not reporting any output as primary + after startup. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit c7cf00487cd6d4a5d0f39d5b92ff04f6420d6a32 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Fri Nov 27 12:52:28 2015 +0900 + + Build RandR 1.4 provider name from chipset name and bus ID + + Instead of just "radeon", it's now e.g. "KAVERI @ pci:0000:00:01.0". + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit ff9a6b6f079a8419f4e6fadfee778060618bf735 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Fri Dec 11 17:21:27 2015 +0900 + + HAS_DIRTYTRACKING_ROTATION also supports multiple CRTCs + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 78fbca095ae9887a2d3de48bb07975e2d1126e68 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Tue Dec 1 15:38:13 2015 +0900 + + Load fb module before glamoregl/shadow modules + + Fixes unresolved symbols on some systems. + + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93105 + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit b19417e2fddf4df725951aea5ad5e9558338f59e +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Fri Nov 20 18:48:56 2015 +0900 + + Don't advertise any PRIME offloading capabilities without acceleration + + Acceleration is required even for display offloading. Trying to enable + display offloading without acceleration resulted in a crash. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 10b7c3def58bb34acc38f076bc230e25b454ab79 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Tue Nov 10 16:31:09 2015 +0900 + + glamor: Deal with glamor_egl_destroy_textured_pixmap being removed + + When it's not available, it's safe to call down to the glamor + DestroyPixmap hook instead. + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit 535e5438b2c32f774b9c8c27ee0289b4749548ef +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Tue Nov 10 17:31:52 2015 +0900 + + glamor: Restore all ScreenRec hooks during CloseScreen + + Reviewed-by: Alex Deucher <alexander.deucher@amd.com> + +commit dfb52777e43f3855476cff812d64de687a199674 +Author: Michel Dänzer <michel.daenzer@amd.com> +Date: Thu Nov 12 13:49:04 2015 +0900 + + Post 7.6.1 release version bump + commit 99cb8c3faf1a4ce368b7500f17a2a7868c15e8e8 Author: Michel Dänzer <michel.daenzer@amd.com> Date: Thu Nov 12 13:38:14 2015 +0900 @@ -1057,7 +1809,7 @@ Date: Tue Mar 10 16:53:11 2015 +0900 Must be enabled with - Option "DRI3" + Option "DRI3" in xorg.conf. @@ -3491,7 +4243,7 @@ Date: Wed Jun 20 08:40:07 2012 +0200 Enable at build time with --enable-glamor and runtime with - Option "AccelMethod" "glamor" + Option "AccelMethod" "glamor" The most notable lack of functionality is XVideo. Use something like VDPAU for now. @@ -3578,7 +4330,7 @@ Date: Fri Jun 29 14:59:47 2012 +0100 ... Conflicts: - configure.ac + configure.ac commit 6a60fcdf060a0f553d8d4f7939c2a05aa04bedfa Author: Dave Airlie <airlied@redhat.com> @@ -9752,7 +10504,7 @@ Date: Fri Oct 9 20:08:31 2009 +1000 Conflicts: - src/drmmode_display.c + src/drmmode_display.c commit a493feb94c0d84aaf5bfd84c6940d7f03974dd86 Author: Dave Airlie <airlied@redhat.com> @@ -13661,7 +14413,7 @@ Date: Wed Jan 28 13:13:13 2009 -0500 Conflicts: - src/radeon_atombios.c + src/radeon_atombios.c commit 1a62360e8260eaf5f98fa6be3f89f64c8cae7d32 Author: Alex Deucher <alexdeucher@gmail.com> @@ -14108,7 +14860,7 @@ Date: Mon Dec 22 02:18:43 2008 -0500 R5xx: always use single clipped triangle R3xx/R4xx: use single clipped triangle up to guardband limit, - then use quad. + then use quad. commit 4d009d14c9c72f6e1bc8100ec8d9b8037ee4e514 Merge: d52882d 4e96278 @@ -15864,7 +16616,7 @@ Date: Sat Jun 21 10:57:05 2008 -0400 See bug 14289 - com_bios_scratch.diff + com_bios_scratch.diff commit 38ce8a984f96056b7345bcc06505ba27e0e6d5b4 Author: Dave Airlie <airlied@redhat.com> @@ -16527,9 +17279,9 @@ Date: Thu Apr 10 16:20:17 2008 -0400 Conflicts: - src/radeon_commonfuncs.c - src/radeon_exa_render.c - src/radeon_textured_videofuncs.c + src/radeon_commonfuncs.c + src/radeon_exa_render.c + src/radeon_textured_videofuncs.c commit 0032c80bf30bab189204e3e6929e18a19d753138 Author: Alex Deucher <alex@botch2.com> @@ -16625,8 +17377,8 @@ Date: Thu Apr 3 22:11:48 2008 -0400 Conflicts: - src/radeon.h - src/radeon_driver.c + src/radeon.h + src/radeon_driver.c This rework seems to have caused more trouble than it was worth. @@ -16640,7 +17392,7 @@ Date: Thu Apr 3 22:04:43 2008 -0400 Conflicts: - src/radeon_driver.c + src/radeon_driver.c commit c40a7aa3989576a8144213e2f31b892d21df8686 Author: Owen W. Taylor <otaylor@fishsoup.net> @@ -17666,7 +18418,7 @@ Date: Sun Feb 24 05:37:22 2008 -0500 Conflicts: - src/radeon_commonfuncs.c + src/radeon_commonfuncs.c commit 27ddb39b12a0b54e099fd5274c4c91f08e2d2822 Author: Alex Deucher <alex@samba.(none)> @@ -18762,8 +19514,8 @@ Date: Fri Dec 21 09:36:22 2007 +1000 Conflicts: - src/radeon_display.c - src/radeon_driver.c + src/radeon_display.c + src/radeon_driver.c commit eb99c3c5c9a2249cb84920f0f225e525fc3a4144 Author: Alex Deucher <alex@botch2.(none)> @@ -19143,10 +19895,10 @@ Date: Mon Dec 10 15:18:03 2007 +1000 Conflicts: - src/radeon.h - src/radeon_crtc.c - src/radeon_driver.c - src/radeon_output.c + src/radeon.h + src/radeon_crtc.c + src/radeon_driver.c + src/radeon_output.c commit 6451ea2dcc4fac762442f699935864f4a8d445f7 Merge: 0d89556 5896ca4 @@ -19217,7 +19969,7 @@ Date: Thu Dec 6 14:22:03 2007 +1000 Conflicts: - src/radeon_output.c + src/radeon_output.c commit 21ed435398e4a398dd8a0a5d7c1d4cc45e916332 Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net> @@ -19724,9 +20476,9 @@ Date: Tue Nov 20 13:02:43 2007 +1000 Conflicts: - src/radeon_chipset.h - src/radeon_driver.c - src/radeon_probe.c + src/radeon_chipset.h + src/radeon_driver.c + src/radeon_probe.c commit 0d1e0c7805b3d8e56ccb49465e6b144afb7bdc51 Author: Dave Airlie <airlied@redhat.com> @@ -19749,8 +20501,8 @@ Date: Tue Nov 20 08:04:32 2007 +1000 Conflicts: - src/radeon_cursor.c - src/radeon_output.c + src/radeon_cursor.c + src/radeon_output.c commit 744c8cb6c293fcaa687566f52901644e699baace Merge: e258fbe e530af7 @@ -20961,7 +21713,7 @@ Date: Tue Aug 28 16:01:12 2007 +0300 Conflicts: - src/ati.c + src/ati.c commit 673f799729824f4439dd5f681f75dd5aab50947f Author: Alex Deucher <alex@botch2.(none)> @@ -21232,14 +21984,14 @@ Date: Thu Aug 23 19:42:19 2007 +1000 Conflicts: - src/radeon.h - src/radeon_bios.c - src/radeon_display.c - src/radeon_dri.c - src/radeon_driver.c - src/radeon_modes.c - src/radeon_probe.h - src/radeon_video.c + src/radeon.h + src/radeon_bios.c + src/radeon_display.c + src/radeon_dri.c + src/radeon_driver.c + src/radeon_modes.c + src/radeon_probe.h + src/radeon_video.c commit 53a67e31904bec9a3aa1bd24de8034dcafea1d2a Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net> @@ -22105,9 +22857,9 @@ Date: Wed May 30 17:27:22 2007 +1000 Conflicts: - src/radeon_cursor.c - src/radeon_display.c - src/radeon_driver.c + src/radeon_cursor.c + src/radeon_display.c + src/radeon_driver.c commit 800bf53279e2c2bf854682bbfd6fa16d03afed00 Author: Matthieu Herrb <matthieu@deville.herrb.com> @@ -23093,8 +23845,8 @@ Date: Sun Feb 25 23:27:19 2007 +1100 Conflicts: - src/radeon_display.c - src/radeon_driver.c + src/radeon_display.c + src/radeon_driver.c commit 3b43788c45f51ad2d3e8e64383c412f4ddd97207 Author: Dave Airlie <airlied@linux.ie> @@ -24604,7 +25356,7 @@ Date: Fri Sep 22 06:00:04 2006 +1000 Conflicts: - src/radeon_driver.c + src/radeon_driver.c commit 9fa176c7989030e7340cc9b85d0b6a7b34303091 Author: Alex Deucher <alex@samba.(none)> diff --git a/driver/xf86-video-ati/config.h.in b/driver/xf86-video-ati/config.h.in index ba7522f06..7a90f2044 100644 --- a/driver/xf86-video-ati/config.h.in +++ b/driver/xf86-video-ati/config.h.in @@ -14,6 +14,9 @@ /* Have fbGlyphs API */ #undef HAVE_FBGLYPHS +/* Have glamor_egl_destroy_textured_pixmap API */ +#undef HAVE_GLAMOR_EGL_DESTROY_TEXTURED_PIXMAP + /* Have glamor_glyphs_init API */ #undef HAVE_GLAMOR_GLYPHS_INIT @@ -59,6 +62,9 @@ /* xextproto 7.1 available */ #undef HAVE_XEXTPROTO_71 +/* Have xf86CursorResetCursor API */ +#undef HAVE_XF86_CURSOR_RESET_CURSOR + /* Have xorg_list API */ #undef HAVE_XORG_LIST diff --git a/driver/xf86-video-ati/configure b/driver/xf86-video-ati/configure index 829bb3b61..0944a05d0 100644 --- a/driver/xf86-video-ati/configure +++ b/driver/xf86-video-ati/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for xf86-video-ati 7.6.1. +# Generated by GNU Autoconf 2.69 for xf86-video-ati 7.7.1. # # Report bugs to <https://bugs.freedesktop.org/enter_bug.cgi?product=xorg>. # @@ -591,8 +591,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='xf86-video-ati' PACKAGE_TARNAME='xf86-video-ati' -PACKAGE_VERSION='7.6.1' -PACKAGE_STRING='xf86-video-ati 7.6.1' +PACKAGE_VERSION='7.7.1' +PACKAGE_STRING='xf86-video-ati 7.7.1' PACKAGE_BUGREPORT='https://bugs.freedesktop.org/enter_bug.cgi?product=xorg' PACKAGE_URL='' @@ -1386,7 +1386,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures xf86-video-ati 7.6.1 to adapt to many kinds of systems. +\`configure' configures xf86-video-ati 7.7.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1456,7 +1456,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of xf86-video-ati 7.6.1:";; + short | recursive ) echo "Configuration of xf86-video-ati 7.7.1:";; esac cat <<\_ACEOF @@ -1609,7 +1609,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -xf86-video-ati configure 7.6.1 +xf86-video-ati configure 7.7.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2024,7 +2024,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by xf86-video-ati $as_me 7.6.1, which was +It was created by xf86-video-ati $as_me 7.7.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2855,7 +2855,7 @@ fi # Define the identity of the package. PACKAGE='xf86-video-ati' - VERSION='7.6.1' + VERSION='7.7.1' cat >>confdefs.h <<_ACEOF @@ -18461,12 +18461,12 @@ if test -n "$XORG_CFLAGS"; then pkg_cv_XORG_CFLAGS="$XORG_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xorg-server >= 1.8 xproto fontsproto xf86driproto \$REQUIRED_MODULES\""; } >&5 - ($PKG_CONFIG --exists --print-errors "xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xorg-server >= 1.9 xproto fontsproto xf86driproto \$REQUIRED_MODULES\""; } >&5 + ($PKG_CONFIG --exists --print-errors "xorg-server >= 1.9 xproto fontsproto xf86driproto $REQUIRED_MODULES") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_XORG_CFLAGS=`$PKG_CONFIG --cflags "xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>/dev/null` + pkg_cv_XORG_CFLAGS=`$PKG_CONFIG --cflags "xorg-server >= 1.9 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -18478,12 +18478,12 @@ if test -n "$XORG_LIBS"; then pkg_cv_XORG_LIBS="$XORG_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xorg-server >= 1.8 xproto fontsproto xf86driproto \$REQUIRED_MODULES\""; } >&5 - ($PKG_CONFIG --exists --print-errors "xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xorg-server >= 1.9 xproto fontsproto xf86driproto \$REQUIRED_MODULES\""; } >&5 + ($PKG_CONFIG --exists --print-errors "xorg-server >= 1.9 xproto fontsproto xf86driproto $REQUIRED_MODULES") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_XORG_LIBS=`$PKG_CONFIG --libs "xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>/dev/null` + pkg_cv_XORG_LIBS=`$PKG_CONFIG --libs "xorg-server >= 1.9 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -18504,14 +18504,14 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - XORG_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>&1` + XORG_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "xorg-server >= 1.9 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>&1` else - XORG_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>&1` + XORG_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "xorg-server >= 1.9 xproto fontsproto xf86driproto $REQUIRED_MODULES" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$XORG_PKG_ERRORS" >&5 - as_fn_error $? "Package requirements (xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES) were not met: + as_fn_error $? "Package requirements (xorg-server >= 1.9 xproto fontsproto xf86driproto $REQUIRED_MODULES) were not met: $XORG_PKG_ERRORS @@ -18771,6 +18771,16 @@ $as_echo "#define HAVE_GLAMOR_GLYPHS_INIT 1" >>confdefs.h fi + + ac_fn_c_check_decl "$LINENO" "glamor_egl_destroy_textured_pixmap" "ac_cv_have_decl_glamor_egl_destroy_textured_pixmap" "#include \"xorg-server.h\" + #include \"glamor.h\" +" +if test "x$ac_cv_have_decl_glamor_egl_destroy_textured_pixmap" = xyes; then : + +$as_echo "#define HAVE_GLAMOR_EGL_DESTROY_TEXTURED_PIXMAP 1" >>confdefs.h + +fi + fi if test "x$GLAMOR_XSERVER" != xyes; then @@ -18988,6 +18998,16 @@ $as_echo "#define HAVE_FBGLYPHS 1" >>confdefs.h fi +ac_fn_c_check_decl "$LINENO" "xf86CursorResetCursor" "ac_cv_have_decl_xf86CursorResetCursor" "#include <xorg-server.h> + #include <xf86Cursor.h> +" +if test "x$ac_cv_have_decl_xf86CursorResetCursor" = xyes; then : + +$as_echo "#define HAVE_XF86_CURSOR_RESET_CURSOR 1" >>confdefs.h + +fi + + ac_fn_c_check_decl "$LINENO" "xorg_list_init" "ac_cv_have_decl_xorg_list_init" "#include <X11/Xdefs.h> #include \"xorg-server.h\" #include \"list.h\" @@ -19844,7 +19864,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by xf86-video-ati $as_me 7.6.1, which was +This file was extended by xf86-video-ati $as_me 7.7.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -19910,7 +19930,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -xf86-video-ati config.status 7.6.1 +xf86-video-ati config.status 7.7.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/driver/xf86-video-ati/configure.ac b/driver/xf86-video-ati/configure.ac index c024d484b..e5c0e6752 100644 --- a/driver/xf86-video-ati/configure.ac +++ b/driver/xf86-video-ati/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], - [7.6.1], + [7.7.1], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xf86-video-ati]) @@ -75,7 +75,7 @@ PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.58]) PKG_CHECK_MODULES(LIBDRM_RADEON, [libdrm_radeon]) # Obtain compiler/linker options for the driver dependencies -PKG_CHECK_MODULES(XORG, [xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES]) +PKG_CHECK_MODULES(XORG, [xorg-server >= 1.9 xproto fontsproto xf86driproto $REQUIRED_MODULES]) PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1], HAVE_XEXTPROTO_71="yes"; AC_DEFINE(HAVE_XEXTPROTO_71, 1, [xextproto 7.1 available]), HAVE_XEXTPROTO_71="no") @@ -119,6 +119,12 @@ if test "x$GLAMOR" != "xno"; then [Have glamor_glyphs_init API])], [], [#include "xorg-server.h" #include "glamor.h"]) + + AC_CHECK_DECL(glamor_egl_destroy_textured_pixmap, + [AC_DEFINE(HAVE_GLAMOR_EGL_DESTROY_TEXTURED_PIXMAP, 1, + [Have glamor_egl_destroy_textured_pixmap API])], [], + [#include "xorg-server.h" + #include "glamor.h"]) fi if test "x$GLAMOR_XSERVER" != xyes; then @@ -141,6 +147,12 @@ AC_CHECK_DECL(fbGlyphs, #include <glyphstr.h> #include <fbpict.h>]) +AC_CHECK_DECL(xf86CursorResetCursor, + [AC_DEFINE(HAVE_XF86_CURSOR_RESET_CURSOR, 1, + [Have xf86CursorResetCursor API])], [], + [#include <xorg-server.h> + #include <xf86Cursor.h>]) + AC_CHECK_DECL(xorg_list_init, [AC_DEFINE(HAVE_XORG_LIST, 1, [Have xorg_list API])], [], [#include <X11/Xdefs.h> diff --git a/driver/xf86-video-ati/man/radeon.man b/driver/xf86-video-ati/man/radeon.man index fa55c6d14..1acdc639a 100644 --- a/driver/xf86-video-ati/man/radeon.man +++ b/driver/xf86-video-ati/man/radeon.man @@ -279,9 +279,10 @@ Pageflipping is supported on all radeon hardware. .TP .BI "Option \*qTearFree\*q \*q" boolean \*q Enable tearing prevention using the hardware page flipping mechanism. This -option currently doesn't have any effect for rotated CRTCs. It requires -allocating two separate scanout buffers for each non-rotated CRTC. Enabling -this option currently disables Option \*qEnablePageFlip\*q. The default is +option currently doesn't have any effect for CRTCs using transforms other than +rotation or reflection. It requires allocating two separate scanout buffers for +each supported CRTC. Enabling this option currently disables Option +\*qEnablePageFlip\*q. The default is .B off. .TP .BI "Option \*qAccelMethod\*q \*q" "string" \*q diff --git a/driver/xf86-video-ati/src/compat-api.h b/driver/xf86-video-ati/src/compat-api.h index b299f83ce..80a3ac466 100644 --- a/driver/xf86-video-ati/src/compat-api.h +++ b/driver/xf86-video-ati/src/compat-api.h @@ -73,8 +73,13 @@ #define SCREEN_INIT_ARGS_DECL ScreenPtr pScreen, int argc, char **argv +#if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(23, 0) +#define BLOCKHANDLER_ARGS_DECL ScreenPtr arg, pointer pTimeout +#define BLOCKHANDLER_ARGS arg, pTimeout +#else #define BLOCKHANDLER_ARGS_DECL ScreenPtr arg, pointer pTimeout, pointer pReadmask #define BLOCKHANDLER_ARGS arg, pTimeout, pReadmask +#endif #define CLOSE_SCREEN_ARGS_DECL ScreenPtr pScreen #define CLOSE_SCREEN_ARGS pScreen diff --git a/driver/xf86-video-ati/src/drmmode_display.c b/driver/xf86-video-ati/src/drmmode_display.c index 4c8931eea..63d99b1a8 100644 --- a/driver/xf86-video-ati/src/drmmode_display.c +++ b/driver/xf86-video-ati/src/drmmode_display.c @@ -36,10 +36,17 @@ #include "damagestr.h" #include "micmap.h" #include "xf86cmap.h" +#include "xf86Priv.h" #include "radeon.h" +#include "radeon_bo_helper.h" #include "radeon_glamor.h" +#include "radeon_list.h" #include "radeon_reg.h" +#ifdef RADEON_PIXMAP_SHARING +#include <dri.h> +#endif + #include "drmmode_display.h" /* DPMS */ @@ -91,19 +98,28 @@ RADEONZaphodStringMatches(ScrnInfoPtr pScrn, const char *s, char *output_name) static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, int width, int height, int depth, int bpp, - int pitch, int tiling, + int pitch, struct radeon_bo *bo, struct radeon_surface *psurf) { RADEONInfoPtr info = RADEONPTR(pScrn); ScreenPtr pScreen = pScrn->pScreen; PixmapPtr pixmap; struct radeon_surface *surface; + uint32_t tiling; pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, RADEON_CREATE_PIXMAP_SCANOUT); if (!pixmap) return NULL; + if (pitch <= 0 && + (radeon_bo_get_tiling(bo, &tiling, (uint32_t*)&pitch) != 0 || + pitch <= 0)) { + ErrorF("radeon_bo_get_tiling failed to determine pitch\n"); + pScreen->DestroyPixmap(pixmap); + return NULL; + } + if (!(*pScreen->ModifyPixmapHeader)(pixmap, width, height, depth, bpp, pitch, NULL)) { return NULL; @@ -133,6 +149,7 @@ static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE); + tiling = radeon_get_pixmap_tiling_flags(pixmap); if (tiling & RADEON_TILING_MICRO) { surface->flags = RADEON_SURF_CLR(surface->flags, MODE); surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); @@ -286,9 +303,15 @@ drmmode_do_crtc_dpms(xf86CrtcPtr crtc, int mode) CARD64 ust; int ret; + drmmode_crtc->pending_dpms_mode = mode; + if (drmmode_crtc->dpms_mode == DPMSModeOn && mode != DPMSModeOn) { drmVBlank vbl; + /* Wait for any pending flip to finish */ + if (drmmode_crtc->flip_pending) + return; + /* * On->Off transition: record the last vblank time, * sequence number and frame period. @@ -346,14 +369,20 @@ drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) drmmode_ptr drmmode = drmmode_crtc->drmmode; /* Disable unused CRTCs */ - if (!crtc->enabled || mode != DPMSModeOn) + if (!crtc->enabled || mode != DPMSModeOn) { + /* Wait for any pending flip to finish */ + if (drmmode_crtc->flip_pending) + return; + drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 0, 0, NULL, 0, NULL); - else if (drmmode_crtc->dpms_mode != DPMSModeOn) + } else if (drmmode_crtc->dpms_mode != DPMSModeOn) crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y); } +#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10 + static PixmapPtr create_pixmap_for_fbcon(drmmode_ptr drmmode, ScrnInfoPtr pScrn, int fbcon_id) @@ -391,8 +420,8 @@ create_pixmap_for_fbcon(drmmode_ptr drmmode, } pixmap = drmmode_create_bo_pixmap(pScrn, fbcon->width, fbcon->height, - fbcon->depth, fbcon->bpp, - fbcon->pitch, 0, bo, NULL); + fbcon->depth, fbcon->bpp, fbcon->pitch, + bo, NULL); info->fbcon_pixmap = pixmap; radeon_bo_unref(bo); out_free_fb: @@ -417,8 +446,6 @@ destroy_pixmap_for_fbcon(ScrnInfoPtr pScrn) info->fbcon_pixmap = NULL; } -#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10 - void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); @@ -522,13 +549,13 @@ drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc, int width, int height) { ScrnInfoPtr pScrn = crtc->scrn; + RADEONInfoPtr info = RADEONPTR(pScrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; - int aligned_height; - int size; + struct radeon_surface surface; + uint32_t tiling = RADEON_CREATE_PIXMAP_TILING_MACRO; int ret; - unsigned long rotate_pitch; - int base_align; + int pitch; if (scanout->bo) { if (scanout->width == width && scanout->height == height) @@ -537,22 +564,18 @@ drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc, drmmode_crtc_scanout_destroy(drmmode, scanout); } - rotate_pitch = - RADEON_ALIGN(width, drmmode_get_pitch_align(pScrn, drmmode->cpp, 0)) - * drmmode->cpp; - aligned_height = RADEON_ALIGN(height, drmmode_get_height_align(pScrn, 0)); - base_align = drmmode_get_base_align(pScrn, drmmode->cpp, 0); - size = RADEON_ALIGN(rotate_pitch * aligned_height, RADEON_GPU_PAGE_SIZE); - - scanout->bo = radeon_bo_open(drmmode->bufmgr, 0, size, base_align, - RADEON_GEM_DOMAIN_VRAM, 0); + if (info->ChipFamily >= CHIP_FAMILY_R600) + tiling |= RADEON_CREATE_PIXMAP_TILING_MICRO; + scanout->bo = radeon_alloc_pixmap_bo(pScrn, width, height, pScrn->depth, + tiling, pScrn->bitsPerPixel, + &pitch, &surface, &tiling); if (scanout->bo == NULL) return NULL; radeon_bo_map(scanout->bo, 1); ret = drmModeAddFB(drmmode->fd, width, height, pScrn->depth, - pScrn->bitsPerPixel, rotate_pitch, + pScrn->bitsPerPixel, pitch, scanout->bo->handle, &scanout->fb_id); if (ret) { @@ -574,7 +597,6 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, ScrnInfoPtr pScrn = crtc->scrn; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; - unsigned long rotate_pitch; if (scanout->pixmap) { if (scanout->width == width && scanout->height == height) @@ -588,15 +610,11 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, return NULL; } - rotate_pitch = RADEON_ALIGN(width, drmmode_get_pitch_align(pScrn, drmmode->cpp, 0)) - * drmmode->cpp; - scanout->pixmap = drmmode_create_bo_pixmap(pScrn, width, height, pScrn->depth, pScrn->bitsPerPixel, - rotate_pitch, - 0, scanout->bo, NULL); + -1, scanout->bo, NULL); if (scanout->pixmap == NULL) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't allocate scanout pixmap for CRTC\n"); @@ -613,10 +631,70 @@ radeon_screen_damage_report(DamagePtr damage, RegionPtr region, void *closure) } static Bool +drmmode_can_use_hw_cursor(xf86CrtcPtr crtc) +{ + RADEONInfoPtr info = RADEONPTR(crtc->scrn); + + /* Check for Option "SWcursor" */ + if (xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) + return FALSE; + + /* Fall back to SW cursor if the CRTC is transformed */ + if (crtc->transformPresent) + return FALSE; + +#if XF86_CRTC_VERSION >= 4 + /* Xorg doesn't correctly handle cursor position transform in the + * rotation case + */ + if (crtc->driverIsPerformingTransform && + (crtc->rotation & 0xf) != RR_Rotate_0) + return FALSE; +#endif + +#ifdef RADEON_PIXMAP_SHARING + /* HW cursor not supported yet with RandR 1.4 multihead */ + if (!xorg_list_is_empty(&crtc->scrn->pScreen->pixmap_dirty_list)) + return FALSE; +#endif + + return TRUE; +} + +#if XF86_CRTC_VERSION >= 4 + +static Bool +drmmode_handle_transform(xf86CrtcPtr crtc) +{ + RADEONInfoPtr info = RADEONPTR(crtc->scrn); + Bool ret; + + crtc->driverIsPerformingTransform = info->tear_free && + !crtc->transformPresent && crtc->rotation != RR_Rotate_0; + + ret = xf86CrtcRotate(crtc); + + crtc->driverIsPerformingTransform &= ret && crtc->transform_in_use; + + return ret; +} + +#else + +static Bool +drmmode_handle_transform(xf86CrtcPtr crtc) +{ + return xf86CrtcRotate(crtc); +} + +#endif + +static Bool drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, int x, int y) { ScrnInfoPtr pScrn = crtc->scrn; + ScreenPtr pScreen = pScrn->pScreen; RADEONInfoPtr info = RADEONPTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; @@ -669,7 +747,6 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, crtc->x = x; crtc->y = y; crtc->rotation = rotation; - crtc->transformPresent = FALSE; output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); if (!output_ids) { @@ -677,8 +754,6 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, goto done; } - ScreenPtr pScreen = pScrn->pScreen; - for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; drmmode_output_private_ptr drmmode_output; @@ -691,9 +766,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, output_count++; } - if (!xf86CrtcRotate(crtc)) { + if (!drmmode_handle_transform(crtc)) goto done; - } + crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, crtc->gamma_blue, crtc->gamma_size); @@ -715,7 +790,11 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[0]); drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[1]); - } else if (info->tear_free || info->shadow_primary) { + } else if (info->tear_free || +#if XF86_CRTC_VERSION >= 4 + crtc->driverIsPerformingTransform || +#endif + info->shadow_primary) { for (i = 0; i < (info->tear_free ? 2 : 1); i++) { drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[i], @@ -741,8 +820,17 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, pBox = RegionExtents(pRegion); pBox->x1 = min(pBox->x1, x); pBox->y1 = min(pBox->y1, y); - pBox->x2 = max(pBox->x2, x + mode->HDisplay); - pBox->y2 = max(pBox->y2, y + mode->VDisplay); + + switch (crtc->rotation & 0xf) { + case RR_Rotate_90: + case RR_Rotate_270: + pBox->x2 = max(pBox->x2, x + mode->VDisplay); + pBox->y2 = max(pBox->y2, y + mode->HDisplay); + break; + default: + pBox->x2 = max(pBox->x2, x + mode->HDisplay); + pBox->y2 = max(pBox->y2, y + mode->VDisplay); + } } } @@ -752,10 +840,16 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, fb_id = drmmode_crtc->scanout[0].fb_id; x = y = 0; - radeon_scanout_update_handler(pScrn, 0, 0, crtc); + radeon_scanout_update_handler(crtc, 0, 0, drmmode_crtc); radeon_bo_wait(drmmode_crtc->scanout[0].bo); } } + + /* Wait for any pending flip to finish */ + do {} while (drmmode_crtc->flip_pending && + drmHandleEvent(drmmode->fd, + &drmmode->event_context) > 0); + if (drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, fb_id, x, y, output_ids, @@ -767,8 +861,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, } else ret = TRUE; - if (crtc->scrn->pScreen) - xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen); + if (pScreen) + xf86CrtcSetScreenSubpixelOrder(pScreen); drmmode_crtc->need_modeset = FALSE; @@ -783,9 +877,23 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, } } - if (pScrn->pScreen && - !xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) - xf86_reload_cursors(pScrn->pScreen); + /* Compute index of this CRTC into xf86_config->crtc */ + for (i = 0; i < xf86_config->num_crtc; i++) { + if (xf86_config->crtc[i] != crtc) + continue; + + if (!crtc->enabled || drmmode_can_use_hw_cursor(crtc)) + info->hwcursor_disabled &= ~(1 << i); + else + info->hwcursor_disabled |= 1 << i; + + break; + } + +#ifndef HAVE_XF86_CURSOR_RESET_CURSOR + if (!info->hwcursor_disabled) + xf86_reload_cursors(pScreen); +#endif done: if (!ret) { @@ -793,11 +901,9 @@ done: crtc->y = saved_y; crtc->rotation = saved_rotation; crtc->mode = saved_mode; - } -#if defined(XF86_CRTC_VERSION) && XF86_CRTC_VERSION >= 3 - else + } else crtc->active = TRUE; -#endif + free(output_ids); return ret; @@ -815,26 +921,103 @@ drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y) drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; +#if XF86_CRTC_VERSION >= 4 + if (crtc->driverIsPerformingTransform) { + x += crtc->x; + y += crtc->y; + xf86CrtcTransformCursorPos(crtc, &x, &y); + } +#endif + drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); } +#if XF86_CRTC_VERSION >= 4 + +static int +drmmode_cursor_src_offset(Rotation rotation, int width, int height, + int x_dst, int y_dst) +{ + int t; + + switch (rotation & 0xf) { + case RR_Rotate_90: + t = x_dst; + x_dst = height - y_dst - 1; + y_dst = t; + break; + case RR_Rotate_180: + x_dst = width - x_dst - 1; + y_dst = height - y_dst - 1; + break; + case RR_Rotate_270: + t = x_dst; + x_dst = y_dst; + y_dst = width - t - 1; + break; + } + + if (rotation & RR_Reflect_X) + x_dst = width - x_dst - 1; + if (rotation & RR_Reflect_Y) + y_dst = height - y_dst - 1; + + return y_dst * height + x_dst; +} + +#endif + static void drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) { ScrnInfoPtr pScrn = crtc->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - int i; uint32_t *ptr; - uint32_t cursor_size = info->cursor_w * info->cursor_h; /* cursor should be mapped already */ ptr = (uint32_t *)(drmmode_crtc->cursor_bo->ptr); - for (i = 0; i < cursor_size; i++) - ptr[i] = cpu_to_le32(image[i]); +#if XF86_CRTC_VERSION >= 4 + if (crtc->driverIsPerformingTransform) { + uint32_t cursor_w = info->cursor_w, cursor_h = info->cursor_h; + int dstx, dsty; + int srcoffset; + + for (dsty = 0; dsty < cursor_h; dsty++) { + for (dstx = 0; dstx < cursor_w; dstx++) { + srcoffset = drmmode_cursor_src_offset(crtc->rotation, + cursor_w, + cursor_h, + dstx, dsty); + + ptr[dsty * info->cursor_w + dstx] = + cpu_to_le32(image[srcoffset]); + } + } + } else +#endif + { + uint32_t cursor_size = info->cursor_w * info->cursor_h; + int i; + + for (i = 0; i < cursor_size; i++) + ptr[i] = cpu_to_le32(image[i]); + } +} + +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,903,0) + +static Bool drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 * image) +{ + if (!drmmode_can_use_hw_cursor(crtc)) + return FALSE; + + drmmode_load_cursor_argb(crtc, image); + return TRUE; } +#endif static void drmmode_hide_cursor (xf86CrtcPtr crtc) @@ -952,7 +1135,7 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) if (max_height < iter->mode.VDisplay) max_height = iter->mode.VDisplay; } -#ifndef HAS_DIRTYTRACKING2 +#if !defined(HAS_DIRTYTRACKING_ROTATION) && !defined(HAS_DIRTYTRACKING2) if (iter != crtc) { ErrorF("Cannot do multiple crtcs without X server dirty tracking 2 interface\n"); return FALSE; @@ -991,6 +1174,9 @@ static xf86CrtcFuncsRec drmmode_crtc_funcs = { .show_cursor = drmmode_show_cursor, .hide_cursor = drmmode_hide_cursor, .load_cursor_argb = drmmode_load_cursor_argb, +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,903,0) + .load_cursor_argb_check = drmmode_load_cursor_argb_check, +#endif .gamma_set = drmmode_crtc_gamma_set, .shadow_create = drmmode_crtc_shadow_create, @@ -1043,6 +1229,8 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, mode_res->crtcs[num]); drmmode_crtc->drmmode = drmmode; + drmmode_crtc->dpms_mode = DPMSModeOff; + drmmode_crtc->pending_dpms_mode = DPMSModeOff; crtc->driver_private = drmmode_crtc; drmmode_crtc_hw_id(crtc); @@ -1168,9 +1356,16 @@ drmmode_output_dpms(xf86OutputPtr output, int mode) if (!koutput) return; - if (mode != DPMSModeOn && crtc) + if (mode != DPMSModeOn && crtc) { + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_do_crtc_dpms(crtc, mode); + /* Wait for any pending flip to finish */ + if (drmmode_crtc->flip_pending) + return; + } + drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id, drmmode_output->dpms_enum_id, mode); @@ -1898,7 +2093,8 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size, base_align, info->shadow_primary ? RADEON_GEM_DOMAIN_GTT : - RADEON_GEM_DOMAIN_VRAM, 0); + RADEON_GEM_DOMAIN_VRAM, + tiling_flags ? RADEON_GEM_NO_CPU_ACCESS : 0); if (!info->front_bo) goto fail; @@ -1999,56 +2195,77 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { drmmode_xf86crtc_resize }; -static void -drmmode_flip_free(drmmode_flipevtcarrier_ptr flipcarrier) +void +drmmode_clear_pending_flip(xf86CrtcPtr crtc) { - drmmode_flipdata_ptr flipdata = flipcarrier->flipdata; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - free(flipcarrier); + drmmode_crtc->flip_pending = FALSE; - if (--flipdata->flip_count > 0) - return; + if (!crtc->enabled || + (drmmode_crtc->pending_dpms_mode != DPMSModeOn && + drmmode_crtc->dpms_mode != drmmode_crtc->pending_dpms_mode)) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + int o; + + for (o = 0; o < xf86_config->num_output; o++) { + xf86OutputPtr output = xf86_config->output[o]; - free(flipdata); + if (output->crtc != crtc) + continue; + + drmmode_output_dpms(output, drmmode_crtc->pending_dpms_mode); + } + + drmmode_crtc_dpms(crtc, drmmode_crtc->pending_dpms_mode); + } } static void -drmmode_flip_abort(ScrnInfoPtr scrn, void *event_data) +drmmode_flip_abort(xf86CrtcPtr crtc, void *event_data) { - drmmode_flipevtcarrier_ptr flipcarrier = event_data; - drmmode_flipdata_ptr flipdata = flipcarrier->flipdata; + drmmode_flipdata_ptr flipdata = event_data; - if (flipdata->flip_count == 1) - flipdata->abort(scrn, flipdata->event_data); + if (--flipdata->flip_count == 0) { + if (!flipdata->fe_crtc) + flipdata->fe_crtc = crtc; + flipdata->abort(flipdata->fe_crtc, flipdata->event_data); + free(flipdata); + } - drmmode_flip_free(flipcarrier); + drmmode_clear_pending_flip(crtc); } static void -drmmode_flip_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec, void *event_data) +drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data) { - drmmode_flipevtcarrier_ptr flipcarrier = event_data; - drmmode_flipdata_ptr flipdata = flipcarrier->flipdata; + RADEONInfoPtr info = RADEONPTR(crtc->scrn); + drmmode_flipdata_ptr flipdata = event_data; /* Is this the event whose info shall be delivered to higher level? */ - if (flipcarrier->dispatch_me) { + if (crtc == flipdata->fe_crtc) { /* Yes: Cache msc, ust for later delivery. */ flipdata->fe_frame = frame; flipdata->fe_usec = usec; } - if (flipdata->flip_count == 1) { - /* Deliver cached msc, ust from reference crtc to flip event handler */ - if (flipdata->event_data) - flipdata->handler(scrn, flipdata->fe_frame, - flipdata->fe_usec, - flipdata->event_data); + if (--flipdata->flip_count == 0) { + /* Deliver MSC & UST from reference/current CRTC to flip event + * handler + */ + if (flipdata->fe_crtc) + flipdata->handler(flipdata->fe_crtc, flipdata->fe_frame, + flipdata->fe_usec, flipdata->event_data); + else + flipdata->handler(crtc, frame, usec, flipdata->event_data); /* Release framebuffer */ - drmModeRmFB(flipdata->drmmode->fd, flipdata->old_fb_id); + drmModeRmFB(info->drmmode.fd, flipdata->old_fb_id); + + free(flipdata); } - drmmode_flip_free(flipcarrier); + drmmode_clear_pending_flip(crtc); } @@ -2070,6 +2287,9 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) int i, num_dvi = 0, num_hdmi = 0; drmModeResPtr mode_res; unsigned int crtcs_needed = 0; +#ifdef RADEON_PIXMAP_SHARING + char *bus_id_string, *provider_name; +#endif xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs); @@ -2112,7 +2332,11 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) drmmode_clones_init(pScrn, drmmode, mode_res); #ifdef RADEON_PIXMAP_SHARING - xf86ProviderSetup(pScrn, NULL, "radeon"); + bus_id_string = DRICreatePCIBusID(info->PciInfo); + XNFasprintf(&provider_name, "%s @ %s", pScrn->chipset, bus_id_string); + free(bus_id_string); + xf86ProviderSetup(pScrn, NULL, provider_name); + free(provider_name); #endif xf86InitialConfiguration(pScrn, TRUE); @@ -2146,8 +2370,10 @@ void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode) void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode) { + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); + int c; if (info->dri2.pKernelDRMVersion->version_minor < 4 || !info->drmmode_inited) return; @@ -2158,6 +2384,14 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode) RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, drm_wakeup_handler, drmmode); } + + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + drmmode_crtc_scanout_destroy(&info->drmmode, &drmmode_crtc->scanout[0]); + drmmode_crtc_scanout_destroy(&info->drmmode, &drmmode_crtc->scanout[1]); + } } @@ -2251,8 +2485,8 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, crtc->rotation = crtc->desiredRotation; crtc->x = crtc->desiredX; crtc->y = crtc->desiredY; - if (!xf86CrtcRotate(crtc)) - return FALSE; + if (!drmmode_handle_transform(crtc)) + return FALSE; } } return TRUE; @@ -2347,10 +2581,12 @@ void radeon_mode_hotplug(ScrnInfoPtr scrn, drmmode_ptr drmmode) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); drmModeResPtr mode_res; - int i, j; + int i, j, s; Bool found; Bool changed = FALSE; + int num_dvi = 0, num_hdmi = 0; mode_res = drmModeGetResources(drmmode->fd); if (!mode_res) @@ -2386,25 +2622,53 @@ restart_destroy: for (i = 0; i < mode_res->count_connectors; i++) { found = FALSE; - for (j = 0; j < config->num_output; j++) { - xf86OutputPtr output = config->output[j]; - drmmode_output_private_ptr drmmode_output; + for (s = 0; !found && s < xf86NumScreens; s++) { + ScrnInfoPtr loop_scrn = xf86Screens[s]; + xf86CrtcConfigPtr loop_config = + XF86_CRTC_CONFIG_PTR(loop_scrn); - drmmode_output = output->driver_private; - if (mode_res->connectors[i] == drmmode_output->output_id) { - found = TRUE; - break; + if (strcmp(loop_scrn->driverName, scrn->driverName) || + RADEONEntPriv(loop_scrn) != pRADEONEnt) + continue; + + for (j = 0; !found && j < loop_config->num_output; j++) { + xf86OutputPtr output = loop_config->output[j]; + drmmode_output_private_ptr drmmode_output; + + drmmode_output = output->driver_private; + if (mode_res->connectors[i] == + drmmode_output->output_id) { + found = TRUE; + + switch(drmmode_output->mode_output->connector_type) { + case DRM_MODE_CONNECTOR_DVII: + case DRM_MODE_CONNECTOR_DVID: + case DRM_MODE_CONNECTOR_DVIA: + num_dvi++; + break; + case DRM_MODE_CONNECTOR_HDMIA: + case DRM_MODE_CONNECTOR_HDMIB: + num_hdmi++; + break; + } + } } } if (found) continue; - changed = TRUE; - drmmode_output_init(scrn, drmmode, mode_res, i, NULL, NULL, 1); + if (drmmode_output_init(scrn, drmmode, mode_res, i, &num_dvi, + &num_hdmi, 1) != 0) + changed = TRUE; } - if (changed) { + if (changed && dixPrivateKeyRegistered(rrPrivKey)) { +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,2,0) RRSetChanged(xf86ScrnToScreen(scrn)); +#else + rrScrPrivPtr rrScrPriv = rrGetScrPriv(scrn->pScreen); + rrScrPriv->changed = TRUE; +#endif RRTellChanged(xf86ScrnToScreen(scrn)); } @@ -2484,14 +2748,14 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, { RADEONInfoPtr info = RADEONPTR(scrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CrtcPtr crtc = NULL; drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; unsigned int pitch; int i; uint32_t tiling_flags = 0; drmmode_flipdata_ptr flipdata; - drmmode_flipevtcarrier_ptr flipcarrier = NULL; - struct radeon_drm_queue_entry *drm_queue = NULL; + uintptr_t drm_queue_seq = 0; if (info->allowColorTiling) { if (info->ChipFamily >= CHIP_FAMILY_R600) @@ -2533,35 +2797,29 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, */ flipdata->event_data = data; - flipdata->drmmode = drmmode; flipdata->handler = handler; flipdata->abort = abort; for (i = 0; i < config->num_crtc; i++) { - if (!config->crtc[i]->enabled) + crtc = config->crtc[i]; + + if (!crtc->enabled) continue; flipdata->flip_count++; - drmmode_crtc = config->crtc[i]->driver_private; - - flipcarrier = calloc(1, sizeof(drmmode_flipevtcarrier_rec)); - if (!flipcarrier) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "flip queue: carrier alloc failed.\n"); - goto error; - } + drmmode_crtc = crtc->driver_private; /* Only the reference crtc will finally deliver its page flip * completion event. All other crtc's events will be discarded. */ - flipcarrier->dispatch_me = (drmmode_crtc->hw_id == ref_crtc_hw_id); - flipcarrier->flipdata = flipdata; - - drm_queue = radeon_drm_queue_alloc(scrn, client, id, - flipcarrier, - drmmode_flip_handler, - drmmode_flip_abort); - if (!drm_queue) { + if (drmmode_crtc->hw_id == ref_crtc_hw_id) + flipdata->fe_crtc = crtc; + + drm_queue_seq = radeon_drm_queue_alloc(crtc, client, id, + flipdata, + drmmode_flip_handler, + drmmode_flip_abort); + if (!drm_queue_seq) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Allocating DRM queue event entry failed.\n"); goto error; @@ -2569,13 +2827,13 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, if (drmModePageFlip(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, drmmode->fb_id, DRM_MODE_PAGE_FLIP_EVENT, - drm_queue)) { + (void*)drm_queue_seq)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed: %s\n", strerror(errno)); goto error; } - flipcarrier = NULL; - drm_queue = NULL; + drmmode_crtc->flip_pending = TRUE; + drm_queue_seq = 0; } if (flipdata->flip_count > 0) @@ -2587,10 +2845,10 @@ error: drmmode->fb_id = flipdata->old_fb_id; } - if (drm_queue) - radeon_drm_abort_entry(drm_queue); - else if (flipcarrier) - drmmode_flip_abort(scrn, flipcarrier); + if (drm_queue_seq) + radeon_drm_abort_entry(drm_queue_seq); + else if (crtc) + drmmode_flip_abort(crtc, flipdata); else if (flipdata && flipdata->flip_count <= 1) free(flipdata); diff --git a/driver/xf86-video-ati/src/drmmode_display.h b/driver/xf86-video-ati/src/drmmode_display.h index ab6c5908a..bbb827ce5 100644 --- a/driver/xf86-video-ati/src/drmmode_display.h +++ b/driver/xf86-video-ati/src/drmmode_display.h @@ -60,21 +60,16 @@ typedef struct { } drmmode_rec, *drmmode_ptr; typedef struct { - drmmode_ptr drmmode; unsigned old_fb_id; int flip_count; void *event_data; unsigned int fe_frame; uint64_t fe_usec; + xf86CrtcPtr fe_crtc; radeon_drm_handler_proc handler; radeon_drm_abort_proc abort; } drmmode_flipdata_rec, *drmmode_flipdata_ptr; -typedef struct { - drmmode_flipdata_ptr flipdata; - Bool dispatch_me; -} drmmode_flipevtcarrier_rec, *drmmode_flipevtcarrier_ptr; - struct drmmode_scanout { struct radeon_bo *bo; PixmapPtr pixmap; @@ -93,6 +88,8 @@ typedef struct { unsigned scanout_id; Bool scanout_update_pending; int dpms_mode; + /* For when a flip is pending when DPMS off requested */ + int pending_dpms_mode; CARD64 dpms_last_ust; uint32_t dpms_last_seq; int dpms_last_fps; @@ -100,8 +97,12 @@ typedef struct { uint16_t lut_r[256], lut_g[256], lut_b[256]; int prime_pixmap_x; - /* Modeset needed for DPMS on */ + /* Modeset needed (for DPMS on or after a page flip crossing with a + * modeset) + */ Bool need_modeset; + /* A flip is pending for this CRTC */ + Bool flip_pending; } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr; typedef struct { @@ -148,6 +149,7 @@ extern int drmmode_get_crtc_id(xf86CrtcPtr crtc); extern int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling); extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling); extern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling); +extern void drmmode_clear_pending_flip(xf86CrtcPtr crtc); Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, uint32_t new_front_handle, uint64_t id, void *data, diff --git a/driver/xf86-video-ati/src/radeon.h b/driver/xf86-video-ati/src/radeon.h index e2fd41cfd..37d5fb60d 100644 --- a/driver/xf86-video-ati/src/radeon.h +++ b/driver/xf86-video-ati/src/radeon.h @@ -66,6 +66,10 @@ #include "xf86drm.h" #include "radeon_drm.h" +#ifndef RADEON_GEM_NO_CPU_ACCESS +#define RADEON_GEM_NO_CPU_ACCESS (1 << 4) +#endif + #ifdef DAMAGE #include "damage.h" #include "globals.h" @@ -157,6 +161,10 @@ typedef enum { } RADEONOpts; +#if XF86_CRTC_VERSION >= 5 +#define RADEON_PIXMAP_SHARING 1 +#endif + #define RADEON_VSYNC_TIMEOUT 20000 /* Maximum wait for VSYNC (in usecs) */ /* Buffer are aligned on 4096 byte boundaries */ @@ -264,19 +272,11 @@ struct radeon_pixmap { uint32_t handle; }; -#if HAS_DEVPRIVATEKEYREC extern DevPrivateKeyRec glamor_pixmap_index; -#else -extern int glamor_pixmap_index; -#endif static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap) { -#if HAS_DEVPRIVATEKEYREC return dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_index); -#else - return dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_index); -#endif } static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pixmap *priv) @@ -539,6 +539,11 @@ typedef struct { int cursor_w; int cursor_h; + /* If bit n of this field is set, xf86_config->crtc[n] currently can't + * use the HW cursor + */ + unsigned hwcursor_disabled; + #ifdef USE_GLAMOR struct { CreateGCProcPtr SavedCreateGC; @@ -561,6 +566,10 @@ typedef struct { AddTrapsProcPtr SavedAddTraps; UnrealizeGlyphProcPtr SavedUnrealizeGlyph; #endif +#ifdef RADEON_PIXMAP_SHARING + SharePixmapBackingProcPtr SavedSharePixmapBacking; + SetSharedPixmapBackingProcPtr SavedSetSharedPixmapBacking; +#endif } glamor; #endif /* USE_GLAMOR */ } RADEONInfoRec, *RADEONInfoPtr; @@ -596,7 +605,7 @@ extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, Bool radeon_dri3_screen_init(ScreenPtr screen); /* radeon_kms.c */ -void radeon_scanout_update_handler(ScrnInfoPtr scrn, uint32_t frame, +void radeon_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data); /* radeon_present.c */ @@ -623,10 +632,6 @@ extern RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn); drmVBlankSeqType radeon_populate_vbl_request_type(xf86CrtcPtr crtc); -#if XF86_CRTC_VERSION >= 5 -#define RADEON_PIXMAP_SHARING 1 -#endif - static inline struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix) { #ifdef USE_GLAMOR diff --git a/driver/xf86-video-ati/src/radeon_bo_helper.c b/driver/xf86-video-ati/src/radeon_bo_helper.c index ce964e0ea..531bc4502 100644 --- a/driver/xf86-video-ati/src/radeon_bo_helper.c +++ b/driver/xf86-video-ati/src/radeon_bo_helper.c @@ -74,7 +74,7 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, int pitch, base_align; uint32_t size, heighta; int cpp = bitsPerPixel / 8; - uint32_t tiling = 0; + uint32_t tiling = 0, flags = 0; struct radeon_surface surface; struct radeon_bo *bo; int domain = RADEON_GEM_DOMAIN_VRAM; @@ -181,8 +181,11 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, } } + if (tiling) + flags |= RADEON_GEM_NO_CPU_ACCESS; + bo = radeon_bo_open(info->bufmgr, 0, size, base_align, - domain, 0); + domain, flags); if (bo && tiling && radeon_bo_set_tiling(bo, tiling, pitch) == 0) *new_tiling = tiling; diff --git a/driver/xf86-video-ati/src/radeon_bo_helper.h b/driver/xf86-video-ati/src/radeon_bo_helper.h index d4a4ee018..f1aed5516 100644 --- a/driver/xf86-video-ati/src/radeon_bo_helper.h +++ b/driver/xf86-video-ati/src/radeon_bo_helper.h @@ -41,4 +41,20 @@ extern Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle, struct radeon_surface *surface); +/** + * get_drawable_pixmap() returns the backing pixmap for a given drawable. + * + * @param drawable the drawable being requested. + * + * This function returns the backing pixmap for a drawable, whether it is a + * redirected window, unredirected window, or already a pixmap. + */ +static inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable) +{ + if (drawable->type == DRAWABLE_PIXMAP) + return (PixmapPtr)drawable; + else + return drawable->pScreen->GetWindowPixmap((WindowPtr)drawable); +} + #endif /* RADEON_BO_HELPER_H */ diff --git a/driver/xf86-video-ati/src/radeon_dri2.c b/driver/xf86-video-ati/src/radeon_dri2.c index d30bbd0bd..0cd6b2419 100644 --- a/driver/xf86-video-ati/src/radeon_dri2.c +++ b/driver/xf86-video-ati/src/radeon_dri2.c @@ -70,86 +70,14 @@ struct dri2_window_priv { int vblank_delta; }; -#if HAS_DEVPRIVATEKEYREC - static DevPrivateKeyRec dri2_window_private_key_rec; #define dri2_window_private_key (&dri2_window_private_key_rec) -#else - -static int dri2_window_private_key_index; -DevPrivateKey dri2_window_private_key = &dri2_window_private_key_index; - -#endif /* HAS_DEVPRIVATEKEYREC */ - #define get_dri2_window_priv(window) \ ((struct dri2_window_priv*) \ dixLookupPrivate(&(window)->devPrivates, dri2_window_private_key)) -static PixmapPtr get_drawable_pixmap(DrawablePtr drawable) -{ - if (drawable->type == DRAWABLE_PIXMAP) - return (PixmapPtr)drawable; - else - return (*drawable->pScreen->GetWindowPixmap)((WindowPtr)drawable); -} - - -static PixmapPtr fixup_glamor(DrawablePtr drawable, PixmapPtr pixmap) -{ - PixmapPtr old = get_drawable_pixmap(drawable); -#ifdef USE_GLAMOR - ScreenPtr screen = drawable->pScreen; - struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); - GCPtr gc; - - /* With a glamor pixmap, 2D pixmaps are created in texture - * and without a static BO attached to it. To support DRI, - * we need to create a new textured-drm pixmap and - * need to copy the original content to this new textured-drm - * pixmap, and then convert the old pixmap to a coherent - * textured-drm pixmap which has a valid BO attached to it - * and also has a valid texture, thus both glamor and DRI2 - * can access it. - * - */ - - /* Copy the current contents of the pixmap to the bo. */ - gc = GetScratchGC(drawable->depth, screen); - if (gc) { - ValidateGC(&pixmap->drawable, gc); - gc->ops->CopyArea(&old->drawable, &pixmap->drawable, - gc, - 0, 0, - old->drawable.width, - old->drawable.height, - 0, 0); - FreeScratchGC(gc); - } - - radeon_set_pixmap_private(pixmap, NULL); - - /* And redirect the pixmap to the new bo (for 3D). */ - glamor_egl_exchange_buffers(old, pixmap); - radeon_set_pixmap_private(old, priv); - old->refcnt++; - - screen->ModifyPixmapHeader(old, - old->drawable.width, - old->drawable.height, - 0, 0, - pixmap->devKind, - NULL); - old->devPrivate.ptr = NULL; - - screen->DestroyPixmap(pixmap); - -#endif /* USE_GLAMOR*/ - - return old; -} - /* Get GEM flink name for a pixmap */ static Bool radeon_get_flink_name(RADEONInfoPtr info, PixmapPtr pixmap, uint32_t *name) @@ -319,10 +247,11 @@ radeon_dri2_create_buffer2(ScreenPtr pScreen, /* this happen if pixmap is non accelerable */ goto error; } + } else if (is_glamor_pixmap) { + pixmap = radeon_glamor_set_pixmap_bo(drawable, pixmap); + pixmap->refcnt++; } - if (is_glamor_pixmap) - pixmap = fixup_glamor(drawable, pixmap); if (!radeon_get_flink_name(info, pixmap, &buffers->name)) goto error; } @@ -525,7 +454,7 @@ typedef struct _DRI2FrameEvent { unsigned frame; xf86CrtcPtr crtc; OsTimerPtr timer; - struct radeon_drm_queue_entry *drm_queue; + uintptr_t drm_queue_seq; /* for swaps & flips only */ DRI2SwapEventPtr event_complete; @@ -587,10 +516,11 @@ static uint32_t radeon_get_msc_delta(DrawablePtr pDraw, xf86CrtcPtr crtc) */ static Bool radeon_dri2_get_crtc_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc) { + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + if (!radeon_crtc_is_enabled(crtc) || drmmode_crtc_get_ust_msc(crtc, ust, msc) != Success) { /* CRTC is not running, extrapolate MSC and timestamp */ - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; ScrnInfoPtr scrn = crtc->scrn; RADEONInfoPtr info = RADEONPTR(scrn); CARD64 now, delta_t, delta_seq; @@ -615,6 +545,8 @@ static Bool radeon_dri2_get_crtc_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc) *msc += delta_seq; } + *msc += drmmode_crtc->interpolated_vblanks; + return TRUE; } @@ -645,17 +577,20 @@ xf86CrtcPtr radeon_dri2_drawable_crtc(DrawablePtr pDraw, Bool consider_disabled) } static void -radeon_dri2_flip_event_abort(ScrnInfoPtr scrn, void *event_data) +radeon_dri2_flip_event_abort(xf86CrtcPtr crtc, void *event_data) { + RADEONInfoPtr info = RADEONPTR(crtc->scrn); + + info->drmmode.dri2_flipping = FALSE; free(event_data); } static void -radeon_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec, +radeon_dri2_flip_event_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data) { - RADEONInfoPtr info = RADEONPTR(scrn); DRI2FrameEventPtr flip = event_data; + ScrnInfoPtr scrn = crtc->scrn; unsigned tv_sec, tv_usec; DrawablePtr drawable; ScreenPtr screen; @@ -667,9 +602,7 @@ radeon_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec, if (status != Success) goto abort; - if (!flip->crtc) - goto abort; - frame += radeon_get_msc_delta(drawable, flip->crtc); + frame += radeon_get_msc_delta(drawable, crtc); screen = scrn->pScreen; pixmap = screen->GetScreenPixmap(screen); @@ -698,7 +631,6 @@ radeon_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec, DRI2SwapComplete(flip->client, drawable, frame, tv_sec, tv_usec, DRI2_FLIP_COMPLETE, flip->event_complete, flip->event_data); - info->drmmode.dri2_flipping = FALSE; break; default: xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: unknown vblank event received\n", __func__); @@ -707,22 +639,21 @@ radeon_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec, } abort: - radeon_dri2_flip_event_abort(scrn, event_data); + radeon_dri2_flip_event_abort(crtc, event_data); } static Bool -radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr client, +radeon_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client, DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPtr back, DRI2SwapEventPtr func, void *data, unsigned int target_msc) { + ScrnInfoPtr scrn = crtc->scrn; RADEONInfoPtr info = RADEONPTR(scrn); struct dri2_buffer_priv *back_priv; struct radeon_bo *bo; DRI2FrameEventPtr flip_info; - /* Main crtc for this drawable shall finally deliver pageflip event. */ - xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, FALSE); - int ref_crtc_hw_id = crtc ? drmmode_get_crtc_id(crtc) : -1; + int ref_crtc_hw_id = drmmode_get_crtc_id(crtc); flip_info = calloc(1, sizeof(DRI2FrameEventRec)); if (!flip_info) @@ -824,6 +755,7 @@ can_flip(ScrnInfoPtr pScrn, DrawablePtr draw, return draw->type == DRAWABLE_WINDOW && info->allowPageFlip && + !info->hwcursor_disabled && !info->drmmode.present_flipping && pScrn->vtSema && DRI2CanFlip(draw) && @@ -843,7 +775,7 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt region.extents.x1 = region.extents.y1 = 0; region.extents.x2 = front_priv->pixmap->drawable.width; - region.extents.y2 = front_priv->pixmap->drawable.width; + region.extents.y2 = front_priv->pixmap->drawable.height; region.data = NULL; DamageRegionAppend(&front_priv->pixmap->drawable, ®ion); @@ -873,7 +805,7 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt DamageRegionProcessPending(&front_priv->pixmap->drawable); } -static void radeon_dri2_frame_event_abort(ScrnInfoPtr scrn, void *event_data) +static void radeon_dri2_frame_event_abort(xf86CrtcPtr crtc, void *event_data) { DRI2FrameEventPtr event = event_data; @@ -884,30 +816,28 @@ static void radeon_dri2_frame_event_abort(ScrnInfoPtr scrn, void *event_data) free(event); } -static void radeon_dri2_frame_event_handler(ScrnInfoPtr scrn, uint32_t seq, +static void radeon_dri2_frame_event_handler(xf86CrtcPtr crtc, uint32_t seq, uint64_t usec, void *event_data) { DRI2FrameEventPtr event = event_data; + ScrnInfoPtr scrn = crtc->scrn; DrawablePtr drawable; int status; int swap_type; BoxRec box; RegionRec region; - if (!event->crtc) - goto cleanup; - status = dixLookupDrawable(&drawable, event->drawable_id, serverClient, M_ANY, DixWriteAccess); if (status != Success) goto cleanup; - seq += radeon_get_msc_delta(drawable, event->crtc); + seq += radeon_get_msc_delta(drawable, crtc); switch (event->type) { case DRI2_FLIP: if (can_flip(scrn, drawable, event->front, event->back) && - radeon_dri2_schedule_flip(scrn, + radeon_dri2_schedule_flip(crtc, event->client, drawable, event->front, @@ -951,7 +881,7 @@ static void radeon_dri2_frame_event_handler(ScrnInfoPtr scrn, uint32_t seq, } cleanup: - radeon_dri2_frame_event_abort(scrn, event_data); + radeon_dri2_frame_event_abort(crtc, event_data); } drmVBlankSeqType radeon_populate_vbl_request_type(xf86CrtcPtr crtc) @@ -1064,7 +994,8 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc) if (!radeon_dri2_get_crtc_msc(crtc, ust, msc)) return FALSE; - *msc += radeon_get_msc_delta(draw, crtc); + if (draw && draw->type == DRAWABLE_WINDOW) + *msc += get_dri2_window_priv((WindowPtr)draw)->vblank_delta; *msc &= 0xffffffff; return TRUE; } @@ -1090,8 +1021,8 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data) */ if (!event_info->crtc) { ErrorF("%s no crtc\n", __func__); - if (event_info->drm_queue) - radeon_drm_abort_entry(event_info->drm_queue); + if (event_info->drm_queue_seq) + radeon_drm_abort_entry(event_info->drm_queue_seq); else radeon_dri2_frame_event_abort(NULL, data); return 0; @@ -1103,11 +1034,11 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data) if (ret) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "%s cannot get current time\n", __func__); - if (event_info->drm_queue) + if (event_info->drm_queue_seq) radeon_drm_queue_handler(info->dri2.drm_fd, 0, 0, 0, - event_info->drm_queue); + (void*)event_info->drm_queue_seq); else - radeon_dri2_frame_event_handler(scrn, 0, 0, data); + radeon_dri2_frame_event_handler(crtc, 0, 0, data); return 0; } /* @@ -1119,11 +1050,12 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data) delta_seq = delta_t * drmmode_crtc->dpms_last_fps; delta_seq /= 1000000; frame = (CARD64)drmmode_crtc->dpms_last_seq + delta_seq; - if (event_info->drm_queue) + if (event_info->drm_queue_seq) radeon_drm_queue_handler(info->dri2.drm_fd, frame, drm_now / 1000000, - drm_now % 1000000, event_info->drm_queue); + drm_now % 1000000, + (void*)event_info->drm_queue_seq); else - radeon_dri2_frame_event_handler(scrn, frame, drm_now, data); + radeon_dri2_frame_event_handler(crtc, frame, drm_now, data); return 0; } @@ -1152,7 +1084,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, ScrnInfoPtr scrn = xf86ScreenToScrn(screen); RADEONInfoPtr info = RADEONPTR(scrn); DRI2FrameEventPtr wait_info = NULL; - struct radeon_drm_queue_entry *wait = NULL; + uintptr_t drm_queue_seq = 0; xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE); uint32_t msc_delta; drmVBlank vbl; @@ -1208,15 +1140,15 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, current_msc = vbl.reply.sequence + msc_delta; current_msc &= 0xffffffff; - wait = radeon_drm_queue_alloc(scrn, client, RADEON_DRM_QUEUE_ID_DEFAULT, - wait_info, radeon_dri2_frame_event_handler, - radeon_dri2_frame_event_abort); - if (!wait) { + drm_queue_seq = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT, + wait_info, radeon_dri2_frame_event_handler, + radeon_dri2_frame_event_abort); + if (!drm_queue_seq) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Allocating DRM queue event entry failed.\n"); goto out_complete; } - wait_info->drm_queue = wait; + wait_info->drm_queue_seq = drm_queue_seq; /* * If divisor is zero, or current_msc is smaller than target_msc, @@ -1235,7 +1167,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; vbl.request.type |= radeon_populate_vbl_request_type(crtc); vbl.request.sequence = target_msc - msc_delta; - vbl.request.signal = (unsigned long)wait; + vbl.request.signal = drm_queue_seq; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, @@ -1266,7 +1198,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, if ((current_msc % divisor) >= remainder) vbl.request.sequence += divisor; - vbl.request.signal = (unsigned long)wait; + vbl.request.signal = drm_queue_seq; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, @@ -1318,7 +1250,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, drmVBlank vbl; int ret, flip = 0; DRI2FrameEventPtr swap_info = NULL; - struct radeon_drm_queue_entry *swap; + uintptr_t drm_queue_seq; CARD64 current_msc; BoxRec box; RegionRec region; @@ -1355,15 +1287,15 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, swap_info->back = back; swap_info->crtc = crtc; - swap = radeon_drm_queue_alloc(scrn, client, RADEON_DRM_QUEUE_ID_DEFAULT, - swap_info, radeon_dri2_frame_event_handler, - radeon_dri2_frame_event_abort); - if (!swap) { + drm_queue_seq = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT, + swap_info, radeon_dri2_frame_event_handler, + radeon_dri2_frame_event_abort); + if (!drm_queue_seq) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Allocating DRM queue entry failed.\n"); goto blit_fallback; } - swap_info->drm_queue = swap; + swap_info->drm_queue_seq = drm_queue_seq; /* * CRTC is in DPMS off state, fallback to blit, but calculate @@ -1432,7 +1364,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, *target_msc = current_msc; vbl.request.sequence = *target_msc - msc_delta; - vbl.request.signal = (unsigned long)swap; + vbl.request.signal = drm_queue_seq; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, @@ -1477,7 +1409,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, /* Account for 1 frame extra pageflip delay if flip > 0 */ vbl.request.sequence -= flip; - vbl.request.signal = (unsigned long)swap; + vbl.request.signal = drm_queue_seq; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, @@ -1590,14 +1522,9 @@ radeon_dri2_screen_init(ScreenPtr pScreen) driverNames[1] = NULL; /* no VDPAU support */ if (DRI2InfoCnt == 0) { -#if HAS_DIXREGISTERPRIVATEKEY if (!dixRegisterPrivateKey(dri2_window_private_key, PRIVATE_WINDOW, sizeof(struct dri2_window_priv))) { -#else - if (!dixRequestPrivate(dri2_window_private_key, - sizeof(struct dri2_window_priv))) { -#endif xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to get DRI2 window private\n"); return FALSE; diff --git a/driver/xf86-video-ati/src/radeon_dri3.c b/driver/xf86-video-ati/src/radeon_dri3.c index 1415a0df7..43a073be5 100644 --- a/driver/xf86-video-ati/src/radeon_dri3.c +++ b/driver/xf86-video-ati/src/radeon_dri3.c @@ -38,6 +38,7 @@ #include <sys/stat.h> #include <fcntl.h> #include <errno.h> +#include <libgen.h> static int @@ -86,6 +87,38 @@ radeon_dri3_open(ScreenPtr screen, RRProviderPtr provider, int *out) return Success; } +#if DRI3_SCREEN_INFO_VERSION >= 1 && XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(1,18,99,1,0) + +static int +radeon_dri3_open_client(ClientPtr client, ScreenPtr screen, + RRProviderPtr provider, int *out) +{ + const char *cmdname = GetClientCmdName(client); + Bool is_ssh = FALSE; + + /* If the executable name is "ssh", assume that this client connection + * is forwarded from another host via SSH + */ + if (cmdname) { + char *cmd = strdup(cmdname); + + /* Cut off any colon and whatever comes after it, see + * https://lists.freedesktop.org/archives/xorg-devel/2015-December/048164.html + */ + cmd = strtok(cmd, ":"); + + is_ssh = strcmp(basename(cmd), "ssh") == 0; + free(cmd); + } + + if (!is_ssh) + return radeon_dri3_open(screen, provider, out); + + return BadAccess; +} + +#endif /* DRI3_SCREEN_INFO_VERSION >= 1 && XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(1,18,99,1,0) */ + static PixmapPtr radeon_dri3_pixmap_from_fd(ScreenPtr screen, int fd, CARD16 width, @@ -179,9 +212,13 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen, } static dri3_screen_info_rec radeon_dri3_screen_info = { +#if DRI3_SCREEN_INFO_VERSION >= 1 && XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(1,18,99,1,0) + .version = 1, + .open_client = radeon_dri3_open_client, +#else .version = 0, - .open = radeon_dri3_open, +#endif .pixmap_from_fd = radeon_dri3_pixmap_from_fd, .fd_from_pixmap = radeon_dri3_fd_from_pixmap }; diff --git a/driver/xf86-video-ati/src/radeon_drm_queue.c b/driver/xf86-video-ati/src/radeon_drm_queue.c index 5e54ef8bb..0d999dde9 100644 --- a/driver/xf86-video-ati/src/radeon_drm_queue.c +++ b/driver/xf86-video-ati/src/radeon_drm_queue.c @@ -40,15 +40,17 @@ struct radeon_drm_queue_entry { struct xorg_list list; uint64_t id; + uintptr_t seq; void *data; ClientPtr client; - ScrnInfoPtr scrn; + xf86CrtcPtr crtc; radeon_drm_handler_proc handler; radeon_drm_abort_proc abort; }; static int radeon_drm_queue_refcnt; static struct xorg_list radeon_drm_queue; +static uintptr_t radeon_drm_queue_seq; /* @@ -58,14 +60,18 @@ void radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *user_ptr) { - struct radeon_drm_queue_entry *user_data = user_ptr; + uintptr_t seq = (uintptr_t)user_ptr; struct radeon_drm_queue_entry *e, *tmp; xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) { - if (e == user_data) { + if (e->seq == seq) { xorg_list_del(&e->list); - e->handler(e->scrn, frame, - (uint64_t)sec * 1000000 + usec, e->data); + if (e->handler) + e->handler(e->crtc, frame, + (uint64_t)sec * 1000000 + usec, + e->data); + else + e->abort(e->crtc, e->data); free(e); break; } @@ -76,8 +82,8 @@ radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec, * Enqueue a potential drm response; when the associated response * appears, we've got data to pass to the handler from here */ -struct radeon_drm_queue_entry * -radeon_drm_queue_alloc(ScrnInfoPtr scrn, ClientPtr client, +uintptr_t +radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, uint64_t id, void *data, radeon_drm_handler_proc handler, radeon_drm_abort_proc abort) @@ -88,8 +94,11 @@ radeon_drm_queue_alloc(ScrnInfoPtr scrn, ClientPtr client, if (!e) return NULL; + if (!radeon_drm_queue_seq) + radeon_drm_queue_seq = 1; + e->seq = radeon_drm_queue_seq++; e->client = client; - e->scrn = scrn; + e->crtc = crtc; e->id = id; e->data = data; e->handler = handler; @@ -97,7 +106,7 @@ radeon_drm_queue_alloc(ScrnInfoPtr scrn, ClientPtr client, xorg_list_add(&e->list, &radeon_drm_queue); - return e; + return e->seq; } /* @@ -109,21 +118,25 @@ static void radeon_drm_abort_one(struct radeon_drm_queue_entry *e) { xorg_list_del(&e->list); - e->abort(e->scrn, e->data); + e->abort(e->crtc, e->data); free(e); } /* * Abort drm queue entries for a client + * + * NOTE: This keeps the entries in the list until the DRM event arrives, + * but then it calls the abort functions instead of the handler + * functions. */ void radeon_drm_abort_client(ClientPtr client) { - struct radeon_drm_queue_entry *e, *tmp; + struct radeon_drm_queue_entry *e; - xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) { + xorg_list_for_each_entry(e, &radeon_drm_queue, list) { if (e->client == client) - radeon_drm_abort_one(e); + e->handler = NULL; } } @@ -131,9 +144,16 @@ radeon_drm_abort_client(ClientPtr client) * Abort specific drm queue entry */ void -radeon_drm_abort_entry(struct radeon_drm_queue_entry *entry) +radeon_drm_abort_entry(uintptr_t seq) { - radeon_drm_abort_one(entry); + struct radeon_drm_queue_entry *e, *tmp; + + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) { + if (e->seq == seq) { + radeon_drm_abort_one(e); + break; + } + } } /* @@ -173,7 +193,7 @@ radeon_drm_queue_close(ScrnInfoPtr scrn) struct radeon_drm_queue_entry *e, *tmp; xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) { - if (e->scrn == scrn) + if (e->crtc->scrn == scrn) radeon_drm_abort_one(e); } diff --git a/driver/xf86-video-ati/src/radeon_drm_queue.h b/driver/xf86-video-ati/src/radeon_drm_queue.h index 8fc1c42e0..0d9d278d3 100644 --- a/driver/xf86-video-ati/src/radeon_drm_queue.h +++ b/driver/xf86-video-ati/src/radeon_drm_queue.h @@ -34,21 +34,19 @@ struct radeon_drm_queue_entry; -typedef void (*radeon_drm_handler_proc)(ScrnInfoPtr scrn, uint32_t seq, +typedef void (*radeon_drm_handler_proc)(xf86CrtcPtr crtc, uint32_t seq, uint64_t usec, void *data); -typedef void (*radeon_drm_abort_proc)(ScrnInfoPtr scrn, void *data); +typedef void (*radeon_drm_abort_proc)(xf86CrtcPtr crtc, void *data); void radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, void *user_ptr); -struct radeon_drm_queue_entry *radeon_drm_queue_alloc(ScrnInfoPtr scrn, - ClientPtr client, - uint64_t id, - void *data, - radeon_drm_handler_proc handler, - radeon_drm_abort_proc abort); +uintptr_t radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, + uint64_t id, void *data, + radeon_drm_handler_proc handler, + radeon_drm_abort_proc abort); void radeon_drm_abort_client(ClientPtr client); -void radeon_drm_abort_entry(struct radeon_drm_queue_entry *entry); +void radeon_drm_abort_entry(uintptr_t seq); void radeon_drm_abort_id(uint64_t id); void radeon_drm_queue_init(); void radeon_drm_queue_close(ScrnInfoPtr scrn); diff --git a/driver/xf86-video-ati/src/radeon_glamor.c b/driver/xf86-video-ati/src/radeon_glamor.c index fdd5aeac4..7a6bf5340 100644 --- a/driver/xf86-video-ati/src/radeon_glamor.c +++ b/driver/xf86-video-ati/src/radeon_glamor.c @@ -34,11 +34,7 @@ #include "radeon_bo_helper.h" #include "radeon_glamor.h" -#if HAS_DEVPRIVATEKEYREC DevPrivateKeyRec glamor_pixmap_index; -#else -int glamor_pixmap_index; -#endif void radeon_glamor_exchange_buffers(PixmapPtr src, @@ -159,6 +155,41 @@ radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_pixmap *pri pixmap->devKind); } +static Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap) +{ +#ifndef HAVE_GLAMOR_EGL_DESTROY_TEXTURED_PIXMAP + ScreenPtr screen = pixmap->drawable.pScreen; + RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen)); + Bool ret; +#endif + + if (pixmap->refcnt == 1) { + if (pixmap->devPrivate.ptr) { + struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap); + + if (bo) + radeon_bo_unmap(bo); + } + +#ifdef HAVE_GLAMOR_EGL_DESTROY_TEXTURED_PIXMAP + glamor_egl_destroy_textured_pixmap(pixmap); +#endif + radeon_set_pixmap_bo(pixmap, NULL); + } + +#ifdef HAVE_GLAMOR_EGL_DESTROY_TEXTURED_PIXMAP + fbDestroyPixmap(pixmap); + return TRUE; +#else + screen->DestroyPixmap = info->glamor.SavedDestroyPixmap; + ret = screen->DestroyPixmap(pixmap); + info->glamor.SavedDestroyPixmap = screen->DestroyPixmap; + screen->DestroyPixmap = radeon_glamor_destroy_pixmap; + + return ret; +#endif +} + static PixmapPtr radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned usage) @@ -227,7 +258,9 @@ fallback_glamor: */ xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Failed to create textured DRI2/PRIME pixmap."); - return pixmap; + + radeon_glamor_destroy_pixmap(pixmap); + return NullPixmap; } /* Create textured pixmap failed means glamor failed to * create a texture from current BO for some reasons. We turn @@ -250,21 +283,52 @@ fallback_pixmap: return fbCreatePixmap(screen, w, h, depth, usage); } -static Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap) +PixmapPtr +radeon_glamor_set_pixmap_bo(DrawablePtr drawable, PixmapPtr pixmap) { - if (pixmap->refcnt == 1) { - if (pixmap->devPrivate.ptr) { - struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap); - - if (bo) - radeon_bo_unmap(bo); - } + PixmapPtr old = get_drawable_pixmap(drawable); + ScreenPtr screen = drawable->pScreen; + struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); + GCPtr gc; + + /* With a glamor pixmap, 2D pixmaps are created in texture + * and without a static BO attached to it. To support DRI, + * we need to create a new textured-drm pixmap and + * need to copy the original content to this new textured-drm + * pixmap, and then convert the old pixmap to a coherent + * textured-drm pixmap which has a valid BO attached to it + * and also has a valid texture, thus both glamor and DRI2 + * can access it. + * + */ - glamor_egl_destroy_textured_pixmap(pixmap); - radeon_set_pixmap_bo(pixmap, NULL); + /* Copy the current contents of the pixmap to the bo. */ + gc = GetScratchGC(drawable->depth, screen); + if (gc) { + ValidateGC(&pixmap->drawable, gc); + gc->ops->CopyArea(&old->drawable, &pixmap->drawable, + gc, + 0, 0, + old->drawable.width, + old->drawable.height, 0, 0); + FreeScratchGC(gc); } - fbDestroyPixmap(pixmap); - return TRUE; + + radeon_set_pixmap_private(pixmap, NULL); + + /* And redirect the pixmap to the new bo (for 3D). */ + glamor_egl_exchange_buffers(old, pixmap); + radeon_set_pixmap_private(old, priv); + + screen->ModifyPixmapHeader(old, + old->drawable.width, + old->drawable.height, + 0, 0, pixmap->devKind, NULL); + old->devPrivate.ptr = NULL; + + screen->DestroyPixmap(pixmap); + + return old; } #ifdef RADEON_PIXMAP_SHARING @@ -273,12 +337,37 @@ static Bool radeon_glamor_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, void **handle_p) { - struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); + ScreenPtr screen = pixmap->drawable.pScreen; + CARD16 stride; + CARD32 size; + int fd; + + if ((radeon_get_pixmap_tiling_flags(pixmap) & + RADEON_TILING_MASK) != RADEON_TILING_LINEAR) { + PixmapPtr linear; + + /* We don't want to re-allocate the screen pixmap as + * linear, to avoid trouble with page flipping + */ + if (screen->GetScreenPixmap(screen) == pixmap) + return FALSE; - if (!priv) + linear = screen->CreatePixmap(screen, pixmap->drawable.width, + pixmap->drawable.height, + pixmap->drawable.depth, + CREATE_PIXMAP_USAGE_SHARED); + if (!linear) + return FALSE; + + radeon_glamor_set_pixmap_bo(&pixmap->drawable, linear); + } + + fd = glamor_fd_from_pixmap(screen, pixmap, &stride, &size); + if (fd < 0) return FALSE; - return radeon_share_pixmap_backing(priv->bo, handle_p); + *handle_p = (void *)(long)fd; + return TRUE; } static Bool @@ -350,11 +439,7 @@ radeon_glamor_init(ScreenPtr screen) return FALSE; } -#if HAS_DIXREGISTERPRIVATEKEY if (!dixRegisterPrivateKey(&glamor_pixmap_index, PRIVATE_PIXMAP, 0)) -#else - if (!dixRequestPrivate(&glamor_pixmap_index, 0)) -#endif return FALSE; if (info->shadow_primary) @@ -368,10 +453,14 @@ radeon_glamor_init(ScreenPtr screen) ps->UnrealizeGlyph = SavedUnrealizeGlyph; #endif + info->glamor.SavedCreatePixmap = screen->CreatePixmap; screen->CreatePixmap = radeon_glamor_create_pixmap; + info->glamor.SavedDestroyPixmap = screen->DestroyPixmap; screen->DestroyPixmap = radeon_glamor_destroy_pixmap; #ifdef RADEON_PIXMAP_SHARING + info->glamor.SavedSharePixmapBacking = screen->SharePixmapBacking; screen->SharePixmapBacking = radeon_glamor_share_pixmap_backing; + info->glamor.SavedSetSharedPixmapBacking = screen->SetSharedPixmapBacking; screen->SetSharedPixmapBacking = radeon_glamor_set_shared_pixmap_backing; #endif @@ -380,6 +469,22 @@ radeon_glamor_init(ScreenPtr screen) return TRUE; } +void +radeon_glamor_fini(ScreenPtr screen) +{ + RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen)); + + if (!info->use_glamor) + return; + + screen->CreatePixmap = info->glamor.SavedCreatePixmap; + screen->DestroyPixmap = info->glamor.SavedDestroyPixmap; +#ifdef RADEON_PIXMAP_SHARING + screen->SharePixmapBacking = info->glamor.SavedSharePixmapBacking; + screen->SetSharedPixmapBacking = info->glamor.SavedSetSharedPixmapBacking; +#endif +} + XF86VideoAdaptorPtr radeon_glamor_xv_init(ScreenPtr pScreen, int num_adapt) { return glamor_xv_init(pScreen, num_adapt); diff --git a/driver/xf86-video-ati/src/radeon_glamor.h b/driver/xf86-video-ati/src/radeon_glamor.h index 246336b18..fdc4e577f 100644 --- a/driver/xf86-video-ati/src/radeon_glamor.h +++ b/driver/xf86-video-ati/src/radeon_glamor.h @@ -64,12 +64,14 @@ struct radeon_pixmap; Bool radeon_glamor_pre_init(ScrnInfoPtr scrn); Bool radeon_glamor_init(ScreenPtr screen); +void radeon_glamor_fini(ScreenPtr screen); void radeon_glamor_screen_init(ScreenPtr screen); Bool radeon_glamor_create_screen_resources(ScreenPtr screen); void radeon_glamor_free_screen(int scrnIndex, int flags); Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_pixmap *priv); void radeon_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst); +PixmapPtr radeon_glamor_set_pixmap_bo(DrawablePtr drawable, PixmapPtr pixmap); XF86VideoAdaptorPtr radeon_glamor_xv_init(ScreenPtr pScreen, int num_adapt); @@ -77,12 +79,14 @@ XF86VideoAdaptorPtr radeon_glamor_xv_init(ScreenPtr pScreen, int num_adapt); static inline Bool radeon_glamor_pre_init(ScrnInfoPtr scrn) { return FALSE; } static inline Bool radeon_glamor_init(ScreenPtr screen) { return FALSE; } +static inline void radeon_glamor_fini(ScreenPtr screen) { } static inline Bool radeon_glamor_create_screen_resources(ScreenPtr screen) { return FALSE; } static inline void radeon_glamor_free_screen(int scrnIndex, int flags) { } static inline Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_pixmap *priv) { return TRUE; } static inline void radeon_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst) {} +static inline PixmapPtr radeon_glamor_set_pixmap_bo(DrawablePtr drawable, PixmapPtr pixmap) { return pixmap; } static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap) { return NULL; } diff --git a/driver/xf86-video-ati/src/radeon_glamor_wrappers.c b/driver/xf86-video-ati/src/radeon_glamor_wrappers.c index ec81560cc..5f165ebe1 100644 --- a/driver/xf86-video-ati/src/radeon_glamor_wrappers.c +++ b/driver/xf86-video-ati/src/radeon_glamor_wrappers.c @@ -35,27 +35,10 @@ #ifdef USE_GLAMOR #include "radeon.h" +#include "radeon_bo_helper.h" #include "radeon_glamor.h" -/** - * get_drawable_pixmap() returns the backing pixmap for a given drawable. - * - * @param pDrawable the drawable being requested. - * - * This function returns the backing pixmap for a drawable, whether it is a - * redirected window, unredirected window, or already a pixmap. - */ -static PixmapPtr -get_drawable_pixmap(DrawablePtr pDrawable) -{ - if (pDrawable->type == DRAWABLE_WINDOW) - return pDrawable->pScreen-> - GetWindowPixmap((WindowPtr) pDrawable); - else - return (PixmapPtr) pDrawable; -} - /* Are there any outstanding GPU operations for this pixmap? */ static Bool radeon_glamor_gpu_pending(uint_fast32_t gpu_synced, uint_fast32_t gpu_access) @@ -917,8 +900,6 @@ radeon_glamor_close_screen(CLOSE_SCREEN_ARGS_DECL) pScreen->CloseScreen = info->glamor.SavedCloseScreen; pScreen->GetImage = info->glamor.SavedGetImage; pScreen->GetSpans = info->glamor.SavedGetSpans; - pScreen->CreatePixmap = info->glamor.SavedCreatePixmap; - pScreen->DestroyPixmap = info->glamor.SavedDestroyPixmap; pScreen->CopyWindow = info->glamor.SavedCopyWindow; pScreen->ChangeWindowAttributes = info->glamor.SavedChangeWindowAttributes; @@ -962,9 +943,6 @@ radeon_glamor_screen_init(ScreenPtr screen) info->glamor.SavedGetSpans = screen->GetSpans; screen->GetSpans = radeon_glamor_get_spans; - info->glamor.SavedCreatePixmap = screen->CreatePixmap; - info->glamor.SavedDestroyPixmap = screen->DestroyPixmap; - info->glamor.SavedCopyWindow = screen->CopyWindow; screen->CopyWindow = radeon_glamor_copy_window; diff --git a/driver/xf86-video-ati/src/radeon_kms.c b/driver/xf86-video-ati/src/radeon_kms.c index 8aa763327..f9abc098a 100644 --- a/driver/xf86-video-ati/src/radeon_kms.c +++ b/driver/xf86-video-ati/src/radeon_kms.c @@ -249,6 +249,24 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) return FALSE; pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS; + /* Set the RandR primary output if Xorg hasn't */ + if (dixPrivateKeyRegistered(rrPrivKey)) { + rrScrPrivPtr rrScrPriv = rrGetScrPriv(pScreen); + + if ( +#ifdef RADEON_PIXMAP_SHARING + !pScreen->isGPU && +#endif + !rrScrPriv->primaryOutput) + { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + rrScrPriv->primaryOutput = xf86_config->output[0]->randr_output; + RROutputChanged(rrScrPriv->primaryOutput, FALSE); + rrScrPriv->layoutChanged = TRUE; + } + } + if (!drmmode_set_desired_modes(pScrn, &info->drmmode, FALSE)) return FALSE; @@ -319,12 +337,22 @@ radeon_dirty_update(ScreenPtr screen) #endif static Bool -radeon_scanout_extents_intersect(BoxPtr extents, int x, int y, int w, int h) +radeon_scanout_extents_intersect(xf86CrtcPtr xf86_crtc, BoxPtr extents, int w, + int h) { - extents->x1 = max(extents->x1 - x, 0); - extents->y1 = max(extents->y1 - y, 0); - extents->x2 = min(extents->x2 - x, w); - extents->y2 = min(extents->y2 - y, h); + extents->x1 = max(extents->x1 - xf86_crtc->x, 0); + extents->y1 = max(extents->y1 - xf86_crtc->y, 0); + + switch (xf86_crtc->rotation & 0xf) { + case RR_Rotate_90: + case RR_Rotate_270: + extents->x2 = min(extents->x2 - xf86_crtc->x, h); + extents->y2 = min(extents->y2 - xf86_crtc->y, w); + break; + default: + extents->x2 = min(extents->x2 - xf86_crtc->x, w); + extents->y2 = min(extents->y2 - xf86_crtc->y, h); + } return (extents->x1 < extents->x2 && extents->y1 < extents->y2); } @@ -338,13 +366,12 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id) RegionPtr pRegion; DrawablePtr pDraw; ScreenPtr pScreen; - GCPtr gc; BoxRec extents; RADEONInfoPtr info; Bool force; if (!xf86_crtc->enabled || - drmmode_crtc->dpms_mode != DPMSModeOn || + drmmode_crtc->pending_dpms_mode != DPMSModeOn || !drmmode_crtc->scanout[scanout_id].pixmap) return FALSE; @@ -357,57 +384,117 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id) return FALSE; pDraw = &drmmode_crtc->scanout[scanout_id].pixmap->drawable; + pScreen = pDraw->pScreen; extents = *RegionExtents(pRegion); RegionEmpty(pRegion); - if (!radeon_scanout_extents_intersect(&extents, xf86_crtc->x, xf86_crtc->y, - pDraw->width, pDraw->height)) + if (!radeon_scanout_extents_intersect(xf86_crtc, &extents, pDraw->width, + pDraw->height)) return FALSE; - pScreen = pDraw->pScreen; - gc = GetScratchGC(pDraw->depth, pScreen); scrn = xf86_crtc->scrn; info = RADEONPTR(scrn); force = info->accel_state->force; info->accel_state->force = TRUE; - ValidateGC(pDraw, gc); - (*gc->ops->CopyArea)(&pScreen->GetScreenPixmap(pScreen)->drawable, - pDraw, gc, - xf86_crtc->x + extents.x1, xf86_crtc->y + extents.y1, - extents.x2 - extents.x1, extents.y2 - extents.y1, - extents.x1, extents.y1); - FreeScratchGC(gc); +#if XF86_CRTC_VERSION >= 4 + if (xf86_crtc->driverIsPerformingTransform) { + SourceValidateProcPtr SourceValidate = pScreen->SourceValidate; + PictFormatPtr format = PictureWindowFormat(pScreen->root); + int error; + PicturePtr src, dst; + XID include_inferiors = IncludeInferiors; + + src = CreatePicture(None, + &pScreen->root->drawable, + format, + CPSubwindowMode, + &include_inferiors, serverClient, &error); + if (!src) { + ErrorF("Failed to create source picture for transformed scanout " + "update\n"); + goto out; + } - info->accel_state->force = force; + dst = CreatePicture(None, pDraw, format, 0L, NULL, serverClient, &error); + if (!dst) { + ErrorF("Failed to create destination picture for transformed scanout " + "update\n"); + goto free_src; + } + + error = SetPictureTransform(src, &xf86_crtc->crtc_to_framebuffer); + if (error) { + ErrorF("SetPictureTransform failed for transformed scanout " + "update\n"); + goto free_dst; + } + + if (xf86_crtc->filter) + SetPicturePictFilter(src, xf86_crtc->filter, xf86_crtc->params, + xf86_crtc->nparams); + + extents.x1 += xf86_crtc->x - (xf86_crtc->filter_width >> 1); + extents.x2 += xf86_crtc->x + (xf86_crtc->filter_width >> 1); + extents.y1 += xf86_crtc->y - (xf86_crtc->filter_height >> 1); + extents.y2 += xf86_crtc->y + (xf86_crtc->filter_height >> 1); + pixman_f_transform_bounds(&xf86_crtc->f_framebuffer_to_crtc, &extents); + + pScreen->SourceValidate = NULL; + CompositePicture(PictOpSrc, + src, NULL, dst, + extents.x1, extents.y1, 0, 0, extents.x1, + extents.y1, extents.x2 - extents.x1, + extents.y2 - extents.y1); + pScreen->SourceValidate = SourceValidate; + + free_dst: + FreePicture(dst, None); + free_src: + FreePicture(src, None); + } else + out: +#endif /* XF86_CRTC_VERSION >= 4 */ + { + GCPtr gc = GetScratchGC(pDraw->depth, pScreen); + + ValidateGC(pDraw, gc); + (*gc->ops->CopyArea)(&pScreen->GetScreenPixmap(pScreen)->drawable, + pDraw, gc, + xf86_crtc->x + extents.x1, xf86_crtc->y + extents.y1, + extents.x2 - extents.x1, extents.y2 - extents.y1, + extents.x1, extents.y1); + FreeScratchGC(gc); + } radeon_cs_flush_indirect(scrn); + info->accel_state->force = force; + return TRUE; } static void -radeon_scanout_update_abort(ScrnInfoPtr scrn, void *event_data) +radeon_scanout_update_abort(xf86CrtcPtr crtc, void *event_data) { - xf86CrtcPtr xf86_crtc = event_data; - drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; + drmmode_crtc_private_ptr drmmode_crtc = event_data; drmmode_crtc->scanout_update_pending = FALSE; } void -radeon_scanout_update_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec, +radeon_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data) { - radeon_scanout_do_update(event_data, 0); + radeon_scanout_do_update(crtc, 0); - radeon_scanout_update_abort(scrn, event_data); + radeon_scanout_update_abort(crtc, event_data); } static void radeon_scanout_update(xf86CrtcPtr xf86_crtc) { drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; - struct radeon_drm_queue_entry *drm_queue_entry; + uintptr_t drm_queue_seq; ScrnInfoPtr scrn; drmVBlank vbl; DamagePtr pDamage; @@ -418,7 +505,7 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) if (!xf86_crtc->enabled || drmmode_crtc->scanout_update_pending || !drmmode_crtc->scanout[0].pixmap || - drmmode_crtc->dpms_mode != DPMSModeOn) + drmmode_crtc->pending_dpms_mode != DPMSModeOn) return; pDamage = drmmode_crtc->scanout[0].damage; @@ -431,17 +518,18 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) pDraw = &drmmode_crtc->scanout[0].pixmap->drawable; extents = *RegionExtents(pRegion); - if (!radeon_scanout_extents_intersect(&extents, xf86_crtc->x, xf86_crtc->y, - pDraw->width, pDraw->height)) + if (!radeon_scanout_extents_intersect(xf86_crtc, &extents, pDraw->width, + pDraw->height)) return; scrn = xf86_crtc->scrn; - drm_queue_entry = radeon_drm_queue_alloc(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, - RADEON_DRM_QUEUE_ID_DEFAULT, - xf86_crtc, - radeon_scanout_update_handler, - radeon_scanout_update_abort); - if (!drm_queue_entry) { + drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, + RADEON_DRM_QUEUE_CLIENT_DEFAULT, + RADEON_DRM_QUEUE_ID_DEFAULT, + drmmode_crtc, + radeon_scanout_update_handler, + radeon_scanout_update_abort); + if (!drm_queue_seq) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "radeon_drm_queue_alloc failed for scanout update\n"); return; @@ -450,12 +538,12 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT; vbl.request.type |= radeon_populate_vbl_request_type(xf86_crtc); vbl.request.sequence = 1; - vbl.request.signal = (unsigned long)drm_queue_entry; + vbl.request.signal = drm_queue_seq; if (drmWaitVBlank(RADEONPTR(scrn)->dri2.drm_fd, &vbl)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "drmWaitVBlank failed for scanout update: %s\n", strerror(errno)); - radeon_drm_abort_entry(drm_queue_entry); + radeon_drm_abort_entry(drm_queue_seq); return; } @@ -463,17 +551,12 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) } static void -radeon_scanout_flip_abort(ScrnInfoPtr scrn, void *event_data) +radeon_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data) { drmmode_crtc_private_ptr drmmode_crtc = event_data; drmmode_crtc->scanout_update_pending = FALSE; -} - -static void -radeon_scanout_flip_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec, void *event_data) -{ - radeon_scanout_flip_abort(scrn, event_data); + drmmode_clear_pending_flip(crtc); } static void @@ -482,7 +565,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, { drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; ScrnInfoPtr scrn; - struct radeon_drm_queue_entry *drm_queue_entry; + uintptr_t drm_queue_seq; unsigned scanout_id; if (drmmode_crtc->scanout_update_pending) @@ -493,12 +576,12 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, return; scrn = xf86_crtc->scrn; - drm_queue_entry = radeon_drm_queue_alloc(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, - RADEON_DRM_QUEUE_ID_DEFAULT, - drmmode_crtc, - radeon_scanout_flip_handler, - radeon_scanout_flip_abort); - if (!drm_queue_entry) { + drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, + RADEON_DRM_QUEUE_CLIENT_DEFAULT, + RADEON_DRM_QUEUE_ID_DEFAULT, + drmmode_crtc, NULL, + radeon_scanout_flip_abort); + if (!drm_queue_seq) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Allocating DRM event queue entry failed.\n"); return; @@ -506,7 +589,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, if (drmModePageFlip(drmmode_crtc->drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, drmmode_crtc->scanout[scanout_id].fb_id, - DRM_MODE_PAGE_FLIP_EVENT, drm_queue_entry)) { + DRM_MODE_PAGE_FLIP_EVENT, (void*)drm_queue_seq)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n", __func__, strerror(errno)); return; @@ -514,6 +597,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, drmmode_crtc->scanout_id = scanout_id; drmmode_crtc->scanout_update_pending = TRUE; + drmmode_crtc->flip_pending = TRUE; } static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) @@ -521,21 +605,22 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) SCREEN_PTR(arg); ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int c; pScreen->BlockHandler = info->BlockHandler; (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); pScreen->BlockHandler = RADEONBlockHandler_KMS; - if (info->tear_free || info->shadow_primary) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int c; - - for (c = 0; c < xf86_config->num_crtc; c++) { - if (info->tear_free) - radeon_scanout_flip(pScreen, info, xf86_config->crtc[c]); - else - radeon_scanout_update(xf86_config->crtc[c]); - } + for (c = 0; c < xf86_config->num_crtc; c++) { + if (info->tear_free) + radeon_scanout_flip(pScreen, info, xf86_config->crtc[c]); + else if (info->shadow_primary +#if XF86_CRTC_VERSION >= 4 + || xf86_config->crtc[c]->driverIsPerformingTransform +#endif + ) + radeon_scanout_update(xf86_config->crtc[c]); } radeon_cs_flush_indirect(pScrn); @@ -551,9 +636,9 @@ static void RADEONBlockHandler_oneshot(BLOCKHANDLER_ARGS_DECL) ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); RADEONInfoPtr info = RADEONPTR(pScrn); - drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE); - RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS); + + drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE); } static void @@ -1017,17 +1102,19 @@ static void RADEONSetupCapabilities(ScrnInfoPtr pScrn) int ret; pScrn->capabilities = 0; + + /* PRIME offloading requires acceleration */ + if (info->r600_shadow_fb) + return; + ret = drmGetCap(info->dri2.drm_fd, DRM_CAP_PRIME, &value); if (ret == 0) { - if (value & DRM_PRIME_CAP_EXPORT) { - pScrn->capabilities |= RR_Capability_SourceOutput; - if (!info->r600_shadow_fb && info->dri2.available) - pScrn->capabilities |= RR_Capability_SinkOffload; - } + if (value & DRM_PRIME_CAP_EXPORT) + pScrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SinkOffload; if (value & DRM_PRIME_CAP_IMPORT) { - pScrn->capabilities |= RR_Capability_SinkOutput; - if (!info->r600_shadow_fb && info->dri2.available) - pScrn->capabilities |= RR_Capability_SourceOffload; + pScrn->capabilities |= RR_Capability_SourceOffload; + if (info->drmmode.count_crtcs) + pScrn->capabilities |= RR_Capability_SinkOutput; } } #endif @@ -1137,14 +1224,16 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) goto fail; } + /* Get ScreenInit function */ + if (!xf86LoadSubModule(pScrn, "fb")) + return FALSE; + if (!RADEONPreInitAccel_KMS(pScrn)) goto fail; radeon_drm_queue_init(); info->allowColorTiling2D = FALSE; - RADEONSetupCapabilities(pScrn); - /* don't enable tiling if accel is not enabled */ if (!info->r600_shadow_fb) { Bool colorTilingDefault = @@ -1201,22 +1290,27 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) } #endif - info->tear_free = xf86ReturnOptValBool(info->Options, OPTION_TEAR_FREE, - FALSE); + if (!info->r600_shadow_fb) { + info->tear_free = xf86ReturnOptValBool(info->Options, OPTION_TEAR_FREE, + FALSE); - if (info->tear_free) - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TearFree enabled\n"); + if (info->tear_free) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TearFree enabled\n"); + } if (info->dri2.pKernelDRMVersion->version_minor >= 8) { + Bool sw_cursor = xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE); + info->allowPageFlip = xf86ReturnOptValBool(info->Options, OPTION_PAGE_FLIP, TRUE); - if (info->tear_free || info->shadow_primary) { + if (sw_cursor || info->tear_free || info->shadow_primary) { xf86DrvMsg(pScrn->scrnIndex, info->allowPageFlip ? X_WARNING : X_DEFAULT, "KMS Pageflipping: disabled%s\n", info->allowPageFlip ? - " because of ShadowPrimary/TearFree" : ""); + (sw_cursor ? " because of SWcursor" : + " because of ShadowPrimary/TearFree") : ""); info->allowPageFlip = FALSE; } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -1238,6 +1332,8 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) goto fail; } + RADEONSetupCapabilities(pScrn); + if (info->drmmode.count_crtcs == 1) pRADEONEnt->HasCRTC2 = FALSE; else @@ -1315,9 +1411,6 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) /* Set display resolution */ xf86SetDpi(pScrn, 0, 0); - /* Get ScreenInit function */ - if (!xf86LoadSubModule(pScrn, "fb")) return FALSE; - if (!xf86SetGamma(pScrn, zeros)) return FALSE; if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) { @@ -1490,6 +1583,8 @@ static Bool RADEONCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL) if (info->dri2.enabled) radeon_dri2_close_screen(pScreen); + radeon_glamor_fini(pScreen); + pScrn->vtSema = FALSE; xf86ClearPrimInitDone(info->pEnt->index); pScreen->BlockHandler = info->BlockHandler; @@ -1632,13 +1727,16 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL) value = FALSE; from = X_DEFAULT; - if (xf86GetOptValBool(info->Options, OPTION_DRI3, &value)) - from = X_CONFIG; - if (xf86GetOptValInteger(info->Options, OPTION_DRI, &driLevel) && - (driLevel == 2 || driLevel == 3)) { - from = X_CONFIG; - value = driLevel == 3; + if (!info->r600_shadow_fb) { + if (xf86GetOptValBool(info->Options, OPTION_DRI3, &value)) + from = X_CONFIG; + + if (xf86GetOptValInteger(info->Options, OPTION_DRI, &driLevel) && + (driLevel == 2 || driLevel == 3)) { + from = X_CONFIG; + value = driLevel == 3; + } } if (value) { @@ -1964,7 +2062,8 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) base_align, info->shadow_primary ? RADEON_GEM_DOMAIN_GTT : - RADEON_GEM_DOMAIN_VRAM, 0); + RADEON_GEM_DOMAIN_VRAM, + tiling_flags ? RADEON_GEM_NO_CPU_ACCESS : 0); if (info->r600_shadow_fb == TRUE) { if (radeon_bo_map(info->front_bo, 1)) { ErrorF("Failed to map cursor buffer memory\n"); diff --git a/driver/xf86-video-ati/src/radeon_list.h b/driver/xf86-video-ati/src/radeon_list.h index 77f74affc..a0038c96c 100644 --- a/driver/xf86-video-ati/src/radeon_list.h +++ b/driver/xf86-video-ati/src/radeon_list.h @@ -30,6 +30,7 @@ #if !HAVE_XORG_LIST #define xorg_list list #define xorg_list_init list_init +#define xorg_list_is_empty list_is_empty #define xorg_list_add list_add #define xorg_list_del list_del #define xorg_list_for_each_entry list_for_each_entry diff --git a/driver/xf86-video-ati/src/radeon_present.c b/driver/xf86-video-ati/src/radeon_present.c index bd4d8f284..2389c7faf 100644 --- a/driver/xf86-video-ati/src/radeon_present.c +++ b/driver/xf86-video-ati/src/radeon_present.c @@ -50,7 +50,7 @@ struct radeon_present_vblank_event { uint64_t event_id; - xf86CrtcPtr crtc; + Bool unflip; }; static uint32_t crtc_select(int crtc_id) @@ -77,8 +77,7 @@ radeon_present_get_crtc(WindowPtr window) window->drawable.y, window->drawable.y + window->drawable.height); - /* Make sure the CRTC is valid and this is the real front buffer */ - if (crtc != NULL && !crtc->rotatedData) + if (crtc) randr_crtc = crtc->randr_crtc; return randr_crtc; @@ -124,7 +123,7 @@ radeon_present_flush_drm_events(ScreenPtr screen) * Called when the queued vblank event has occurred */ static void -radeon_present_vblank_handler(ScrnInfoPtr scrn, unsigned int msc, +radeon_present_vblank_handler(xf86CrtcPtr crtc, unsigned int msc, uint64_t usec, void *data) { struct radeon_present_vblank_event *event = data; @@ -137,7 +136,7 @@ radeon_present_vblank_handler(ScrnInfoPtr scrn, unsigned int msc, * Called when the queued vblank is aborted */ static void -radeon_present_vblank_abort(ScrnInfoPtr scrn, void *data) +radeon_present_vblank_abort(xf86CrtcPtr crtc, void *data) { struct radeon_present_vblank_event *event = data; @@ -157,7 +156,7 @@ radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) RADEONInfoPtr info = RADEONPTR(scrn); int crtc_id = drmmode_get_crtc_id(xf86_crtc); struct radeon_present_vblank_event *event; - struct radeon_drm_queue_entry *queue; + uintptr_t drm_queue_seq; drmVBlank vbl; int ret; @@ -165,24 +164,25 @@ radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) if (!event) return BadAlloc; event->event_id = event_id; - queue = radeon_drm_queue_alloc(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, - event_id, event, - radeon_present_vblank_handler, - radeon_present_vblank_abort); - if (!queue) { + drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, + RADEON_DRM_QUEUE_CLIENT_DEFAULT, + event_id, event, + radeon_present_vblank_handler, + radeon_present_vblank_abort); + if (!drm_queue_seq) { free(event); return BadAlloc; } vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | crtc_select(crtc_id); vbl.request.sequence = msc; - vbl.request.signal = (unsigned long)queue; + vbl.request.signal = drm_queue_seq; for (;;) { ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (!ret) break; if (errno != EBUSY || !radeon_present_flush_drm_events(screen)) { - radeon_drm_abort_entry(queue); + radeon_drm_abort_entry(drm_queue_seq); return BadAlloc; } } @@ -245,6 +245,9 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, if (!info->allowPageFlip) return FALSE; + if (info->hwcursor_disabled) + return FALSE; + if (!sync_flip) return FALSE; @@ -268,7 +271,7 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, if (!drmmode_crtc || drmmode_crtc->rotate.bo != NULL) return FALSE; - if (drmmode_crtc->dpms_mode == DPMSModeOn) + if (drmmode_crtc->pending_dpms_mode == DPMSModeOn) num_crtcs_on++; } @@ -280,12 +283,12 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, * extension code telling it when that happened */ static void -radeon_present_flip_event(ScrnInfoPtr scrn, uint32_t msc, uint64_t ust, void *pageflip_data) +radeon_present_flip_event(xf86CrtcPtr crtc, uint32_t msc, uint64_t ust, void *pageflip_data) { - RADEONInfoPtr info = RADEONPTR(scrn); + RADEONInfoPtr info = RADEONPTR(crtc->scrn); struct radeon_present_vblank_event *event = pageflip_data; - if (!event->crtc) + if (event->unflip) info->drmmode.present_flipping = FALSE; present_event_notify(event->event_id, ust, msc); @@ -296,7 +299,7 @@ radeon_present_flip_event(ScrnInfoPtr scrn, uint32_t msc, uint64_t ust, void *pa * The flip has been aborted, free the structure */ static void -radeon_present_flip_abort(ScrnInfoPtr scrn, void *pageflip_data) +radeon_present_flip_abort(xf86CrtcPtr crtc, void *pageflip_data) { struct radeon_present_vblank_event *event = pageflip_data; @@ -331,7 +334,6 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, return FALSE; event->event_id = event_id; - event->crtc = xf86_crtc; ret = radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle, event_id, event, crtc_id, @@ -375,6 +377,7 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) } event->event_id = event_id; + event->unflip = TRUE; if (radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle, event_id, event, -1, radeon_present_flip_event, @@ -382,6 +385,12 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) return; modeset: + /* info->drmmode.fb_id still points to the FB for the last flipped BO. + * Clear it, drmmode_set_mode_major will re-create it + */ + drmModeRmFB(info->drmmode.fd, info->drmmode.fb_id); + info->drmmode.fb_id = 0; + for (i = 0; i < config->num_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; @@ -389,7 +398,7 @@ modeset: if (!crtc->enabled) continue; - if (drmmode_crtc->dpms_mode == DPMSModeOn) + if (drmmode_crtc->pending_dpms_mode == DPMSModeOn) crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y); else diff --git a/driver/xf86-video-ati/src/radeon_probe.c b/driver/xf86-video-ati/src/radeon_probe.c index 65cf0c9fa..6d6d8c549 100644 --- a/driver/xf86-video-ati/src/radeon_probe.c +++ b/driver/xf86-video-ati/src/radeon_probe.c @@ -127,11 +127,8 @@ radeon_get_scrninfo(int entity_num, void *pci_dev) if (!pScrn) return FALSE; - if (pci_dev) { - if (!radeon_kernel_mode_enabled(pScrn, pci_dev)) { + if (!radeon_kernel_mode_enabled(pScrn, pci_dev)) return FALSE; - } - } pScrn->driverVersion = RADEON_VERSION_CURRENT; pScrn->driverName = RADEON_DRIVER_NAME; diff --git a/driver/xf86-video-ati/src/radeon_sync.c b/driver/xf86-video-ati/src/radeon_sync.c index d9ffbaf8e..86e0283f9 100644 --- a/driver/xf86-video-ati/src/radeon_sync.c +++ b/driver/xf86-video-ati/src/radeon_sync.c @@ -85,6 +85,13 @@ radeon_sync_init(ScreenPtr screen) RADEONInfoPtr info = RADEONPTR(scrn); SyncScreenFuncsPtr screen_funcs; + if (!xf86LoaderCheckSymbol("miSyncShmScreenInit")) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "SYNC extension fences disabled because " + "miSyncShmScreenInit symbol unresolved\n"); + return FALSE; + } + if (!miSyncShmScreenInit(screen)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "SYNC extension fences disabled because " diff --git a/driver/xf86-video-ati/src/radeon_video.c b/driver/xf86-video-ati/src/radeon_video.c index 48b06e26d..d058986a8 100644 --- a/driver/xf86-video-ati/src/radeon_video.c +++ b/driver/xf86-video-ati/src/radeon_video.c @@ -71,7 +71,7 @@ radeon_box_area(BoxPtr box) Bool radeon_crtc_is_enabled(xf86CrtcPtr crtc) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - return drmmode_crtc->dpms_mode == DPMSModeOn; + return drmmode_crtc->pending_dpms_mode == DPMSModeOn; } xf86CrtcPtr @@ -94,9 +94,7 @@ radeon_pick_best_crtc(ScrnInfoPtr pScrn, Bool consider_disabled, best_coverage = 0; /* Prefer the CRTC of the primary output */ -#ifdef HAS_DIXREGISTERPRIVATEKEY if (dixPrivateKeyRegistered(rrPrivKey)) -#endif { primary_output = RRFirstOutput(pScrn->pScreen); } |