Summary: | [RADEON:KMS:DDX] VSync loss after rotation to portrait mode | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Product: | xorg | Reporter: | Stephen A. <stapostol> | ||||||||
Component: | Driver/Radeon | Assignee: | 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: |
|
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. Option "EXAVSync" might fix the tearing but will slow things down. (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?) (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. 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. (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. Created attachment 41636 [details] [review] add vline waits for rotated buffers Does this patch fix the issue? 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)) Created attachment 41639 [details] [review] updated patch I think the logic works fine in either case, but your suggestion is probably more efficient. (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. 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. (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. 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? 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.
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.