Bug 32789

Summary: [RADEON:KMS:DDX] VSync loss after rotation to portrait mode
Product: xorg Reporter: Stephen A. <stapostol>
Component: Driver/RadeonAssignee: xf86-video-ati maintainers <xorg-driver-ati>
Status: RESOLVED FIXED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium    
Version: unspecified   
Hardware: x86 (IA32)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments:
Description Flags
Xorg log file
none
add vline waits for rotated buffers
none
updated patch none

Description Stephen A. 2011-01-03 00:53:33 UTC
Created attachment 41580 [details]
Xorg log file

I have a monitor that can be rotated from landscape (1920x1080) to portrait mode (1080x1920) and vice versa. When I use the monitor in landscape mode, I can see a perfectly vsynced desktop. Once I move to portrait mode (xrandr -o left), the vsync is lost and scrolling or moving windows becomes a tearing fest.

Compiz is running in both cases, with its "sync to vblank" setting enabled. (If I disable compiz, I get tearing in both landscape and portrait mode - even worse!)

This is on Ubuntu 10.10:
- 'uname' gives Linux 2.6.35-24-generic
- 'glxinfo' gives
OpenGL vendor string: Advanced Micro Devices, Inc.
OpenGL renderer string: Mesa DRI R600 (RV770 9442) 20090101  TCL DRI2
OpenGL version string: 2.1 Mesa 7.9-devel

My Xorg.0.log is attached.
Comment 1 Maarten Maathuis 2011-01-03 06:11:26 UTC
Landscape mode is the default rendering mode (it's called normal), anything else causes the X server to create a new frontbuffer and render with a transform onto this rotated frontbuffer (this process isn't backbuffered last time i checked). Everytime the X server receives "damage" on the "normal" frontbuffer it will update the rotated frontbuffer. This transform happens outside compiz/opengl (which was used to get the vsync). This is just a generic story, not sure if this is easy to fix for amd hardware.
Comment 2 Michel Dänzer 2011-01-03 07:46:34 UTC
Option "EXAVSync" might fix the tearing but will slow things down.
Comment 3 Stephen A. 2011-01-03 11:39:24 UTC
(In reply to comment #2)
> Option "EXAVSync" might fix the tearing but will slow things down.

I tested this on my ArchLinux installation (2.6.36 and Mesa 7.9) but didn't notice a difference. I also tested with the nvidia and fglrx blobs and both tear equally (only difference, fglrx also tears in normal mode whereas radeon & nvidia don't).

If I understand correctly, the X server is responsible for this? Efficiency issues aside, I guess the simplest approach would be to patch X to wait for vblank before drawing to the rotated frontbuffer? Is this approach feasible?

(Actually, why doesn't X allocate a 1080x1920 frontbuffer from the beginning and prefers to allocate a second one and copy+rotate its contents?)
Comment 4 Michel Dänzer 2011-01-04 02:35:47 UTC
(In reply to comment #3)
> If I understand correctly, the X server is responsible for this?

The X driver. The X server doesn't have any concept of tearing avoidance yet.

> Efficiency issues aside, I guess the simplest approach would be to patch X to
> wait for vblank before drawing to the rotated frontbuffer? Is this approach feasible?

Option "EXAVSync" does almost that, except it doesn't wait for vblank but just for scanout to be outside of the rectangle being updated. The tearing you're still seing may be due to several conceptually related rectangles ending up being updated during different scanout frames. Or maybe there's a problem which prevents the updates from happening outside of scanout in all cases.

Either way, waiting for vblank might be a solution for the tearing, but the driver doesn't have enough knowledge to do that without murdering performance when there's lots of rectangles to update. It would have to be done more explicitly at a higher level. One possible solution being discussed is to make the compositing manager responsible for rendering the rotated output.

> (Actually, why doesn't X allocate a 1080x1920 frontbuffer from the beginning
> and prefers to allocate a second one and copy+rotate its contents?)

Different RandR CRTCs can have different rotations.
Comment 5 Alex Deucher 2011-01-04 09:30:01 UTC
FWIW, the vline stuff in the driver only works if the pixmap is the screen pixmap which may not be the case when rotation is active.
Comment 6 Michel Dänzer 2011-01-04 09:47:24 UTC
(In reply to comment #5)
> FWIW, the vline stuff in the driver only works if the pixmap is the screen
> pixmap which may not be the case when rotation is active.

A rotated scanout pixmap is definitely not the screen pixmap... Thanks for pointing this out!

So there might be a relatively simple fix after all: Always use vline waits for rotated scanout pixmaps.
Comment 7 Alex Deucher 2011-01-04 11:00:05 UTC
Created attachment 41636 [details] [review]
add vline waits for rotated buffers

Does this patch fix the issue?
Comment 8 Michel Dänzer 2011-01-04 11:08:45 UTC
Review of attachment 41636 [details] [review]:

::: src/evergreen_accel.c
@@ -262,2 +262,3 @@
     if (info->cs) {
-        if (pPix != pScrn->pScreen->GetScreenPixmap(pScrn->pScreen))
+        if ((pPix != pScrn->pScreen->GetScreenPixmap(pScrn->pScreen)) &&
+	    (drmmode_crtc->rotate_bo && (drmmode_crtc->rotate_bo != radeon_get_pixmap_bo(pPix))))

I think these should be

(!drmmode_crtc->rotate_bo || drmmode_crtc->rotate_bo != radeon_get_pixmap_bo(pPix))
Comment 9 Alex Deucher 2011-01-04 11:24:20 UTC
Created attachment 41639 [details] [review]
updated patch

I think the logic works fine in either case, but your suggestion is probably more efficient.
Comment 10 Michel Dänzer 2011-01-05 01:26:58 UTC
(In reply to comment #9)
> I think the logic works fine in either case, but your suggestion is probably
> more efficient.

The previous logic would skip the vline wait for the screen pixmap in the no rotation case.

Thinking about it more, I'm afraid this still isn't quite right though. E.g. this may also use a vline waits for the screen pixmap even if the CRTC is actually scanning out from a rotated pixmap. I'm afraid the whole vline related code will need to be overhauled a bit to handle this properly. For starters, radeon_pick_best_crtc() should only return a CRTC that is actually scanning out from the destination pixmap.
Comment 11 meng.oux.ooi 2013-10-11 07:58:55 UTC
This bug have been detected in Intel NUC Ivy Bridge Platform running on Ubuntu 13.04 with the latest Intel Linux Graphic Driver. Please refer to URL posted in the forum https://01.org/linuxgraphics/node/224
The bug can be duplicated in rotated clockwise mode with fast scrolling, tearing can be detected.
Comment 12 Daniel Vetter 2013-10-11 08:07:07 UTC
(In reply to comment #11)
> This bug have been detected in Intel NUC Ivy Bridge Platform running on
> Ubuntu 13.04 with the latest Intel Linux Graphic Driver. Please refer to URL
> posted in the forum https://01.org/linuxgraphics/node/224
> The bug can be duplicated in rotated clockwise mode with fast scrolling,
> tearing can be detected.

Please file a new bug report against the intel driver instead of hijacking a radeon bug report. Really.
Comment 13 Furkan 2015-04-16 07:43:39 UTC
I hope it's OK here to reply to old bug reports:

I also get really bad tearing (easily visible when moving around windows or scrolling) on my portrait display with both fglrx and radeon. No problems with Catalyst on Windows, so if this is an X issue, I'm just wondering if there is even a possibility of a fix?
Comment 14 Michel Dänzer 2016-03-10 03:22:59 UTC
With https://cgit.freedesktop.org/xorg/driver/xf86-video-ati/commit/?id=798c4fd16d339b1ad5fd729cc884be084c60e38b (and xserver >= 1.16), Option "TearFree" eliminates tearing with rotation.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.