Bug 80868

Summary: Support screen scaling modes for external monitors
Product: DRI Reporter: Kamil Páral <kamil.paral>
Component: DRM/RadeonAssignee: Default DRI bug account <dri-devel>
Status: RESOLVED FIXED QA Contact:
Severity: enhancement    
Priority: medium    
Version: XOrg git   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments:
Description Flags
starter implementation
none
working patch
none
better patch none

Description Kamil Páral 2014-07-03 18:59:37 UTC
As we steadily progress into the year of Linux gaming, there will be many requests regarding games. This is one of them :)

Currently, it is possible to set scaling mode for a monitor only if the monitor is internal (LVDS, eDP). This is done through xrandr:

$ xrandr --prop
Screen 0: minimum 320 x 200, current 1680 x 1050, maximum 8192 x 8192
LVDS1 connected primary 1680x1050+0+0 (normal left inverted right x axis y axis) 331mm x 207mm
<snip>
	scaling mode: Full aspect 
		supported: None, Full, Center, Full aspect
<snip>

$ xrandr --output LVDS1 --set "scaling mode" "Center"

However, it is not possible to do this for external panels (VGA, DVI, HDMI, DP). The "scaling mode" property is not exported for these panels (this was confirmed to me by ckoenig and agd5f on the #radeon irc channel, many thanks).

Please allow users to set scaling mode even for external panels. There are many use cases for it, mainly related to gaming.

Note: Many panels provide options to do the scaling on their own, however, only the very expensive ones provide good options. For example, the majority of "mainstream" panels don't provide the "center" scaling mode - however, that is very useful when playing older lower-resolution games when you prefer smaller and sharp image instead of larger and blurry. Second example are certain panels 
which support "full aspect" mode only for a small selection or resolutions, otherwise they simply scale to "full" ignoring image aspect ratio. For these panels, GPU scaling is essential if the user doesn't want to see distorted aspect ratio image.

My personal use case is buying BenQ BL2411PT 1920x1200 panel, which *can not* display 1920x1080 resolution with correct aspect ratio - it always stretches it vertically. Yes, it's very dumb, yet that's how modern panels commonly work (and not just the cheap ones). This hasn't been a large issue in the past, because we had no games and opensource drivers were hardly able to run them anyway. Both things are changing rapidly.

The proprietary AMD and NVIDIA drivers have been offering GPU scaling functionality for a long time, both on Linux and Windows. Here's an example of their GUI configuration:
https://www.codeweavers.com/support/wiki/linux/faq/43_game_stretch

Please allow us to use GPU scaling even with radeon driver. Thank you.

There has been some technical details on the IRC, it is linked here:
http://paste.fedoraproject.org/115407/

It seems to me that this functionality could be implemented in a simple and straightforward way:
a) provide a single configuration option - "scaling mode"
b) on internal panels default to "Full aspect" (which you already do) - that is reasonable default, because these panels have no control buttons
c) on external panels default to "None" - that allows the user to easily configure scaling through the panel. Only if the user is dissatisfied, he/she can enable GPU scaling through xrandr.

And here's one more user seconding my thoughts on the IRC:
AbortRetryFail: 1:1 unscaled output for LCDs would be awesome.
AbortRetryFail: 1280x720 looks horrible scaled up to fit a 1366x768 LCD

Thanks.
Comment 1 Alex Deucher 2014-07-03 19:04:30 UTC
Created attachment 102216 [details] [review]
starter implementation

I'm not sure when I'll have time to implement this, but just about everything you need is already in place.  The attached patch should get you started and may even work...
Comment 2 Alex Deucher 2014-07-03 19:10:16 UTC
A deeper question is, why run non-native modes to begin with?  Whether it's the GPU or the monitor, it's always going to end up scaled.  Why do you want to run 1920x1080 when you can run 1920x1200?
Comment 3 Henri Verbeet 2014-07-03 20:53:30 UTC
Some of the games this applies to only know 640x480 and 800x600, and perhaps 1024x768.
Comment 4 Kamil Páral 2014-07-04 06:48:47 UTC
(In reply to comment #2)
> A deeper question is, why run non-native modes to begin with?  Whether it's
> the GPU or the monitor, it's always going to end up scaled.  Why do you want
> to run 1920x1080 when you can run 1920x1200?

I see several reasons:

1) Games do not support all resolutions. All old games (think Diablo or Starcraft) have a) fixed 4:3 ratio b) a fixed resolution around 800x600. Newer games (think Warcraft 3) didn't have fixed resolutions, but still had fixed aspect ratio. But even modern games sometimes do this - when Witcher 2 (AAA game from 2012) came out, it supported only 16:9 resolutions, but none of 16:10 resolutions (they fixed in afterwards with a patch). Moreover, there is often a resolution cap hardcoded in the game which is the maximum resolution the developers tested the game with. So if you buy 1440p or 2160p display today, you might be surprised how many games don't allow your native resolution to be selected, for no apparent reason.

2) Performance reasons. If your system is not able to run modern games in your native resolution even with low details, you simply need to use a lower one, there is no other choice. Lowering your resolution is the number one approach how to make the game faster. It is very common.

3) Some people might prefer to run in a lower resolution to make things "bigger". This might not be too common and probably not apply to games, rather desktop. But I personally know some older people with a bit worse eyesight, who prefer blurry but bigger text and widgets, rather than small and sharp.


(In reply to comment #1)
> I'm not sure when I'll have time to implement this, but just about
> everything you need is already in place.  The attached patch should get you
> started and may even work...

Thanks a lot! I'm not able to finalize this patch, but I hope someone more capable will (I can blog about it to get some attention).
Comment 5 Alex Deucher 2014-07-07 13:42:14 UTC
(In reply to comment #4)
> 
> Thanks a lot! I'm not able to finalize this patch, but I hope someone more
> capable will (I can blog about it to get some attention).

Does the patch work?
Comment 6 Kamil Páral 2014-07-07 22:11:18 UTC
I tried this on a Fedora Rawhide, I tried to rebuild the provided 3.16.0-0.rc4 kernel with the patch. After reboot, I still don't see scaling mode in xrandr properties, so no, it doesn't work for me. But maybe I did something wrong somewhere, that's very possible.
Comment 7 Alex Deucher 2014-07-07 22:27:46 UTC
(In reply to comment #6)
> I tried this on a Fedora Rawhide, I tried to rebuild the provided
> 3.16.0-0.rc4 kernel with the patch. After reboot, I still don't see scaling
> mode in xrandr properties, so no, it doesn't work for me. But maybe I did
> something wrong somewhere, that's very possible.

I suspect you aren't using the patch version of the driver.  You should see the property.  drm_object_attach_property() is what attaches the property to the connector.
Comment 8 Kamil Páral 2014-07-07 23:34:35 UTC
Yes, you seem to be right. I put the patch into the spec file, but it probably didn't apply. I'm trying to find out why.
Comment 9 Kamil Páral 2014-07-08 01:06:37 UTC
OK, once I learned how to work with spec files properly, I compiled it with the patch applied. The scaling mode is now visible for external displays (yay!) and defaults to None. However, when I try to change it (I tried to set it to Center), my monitor goes black and I receive "no signal detected" error message. I had to restart to restore the picture. This happens over both DVI and DP.

The journal says:

Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): EDID vendor "BNQ", prod id 32785
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Using hsync ranges from config file
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Using vrefresh ranges from config file
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Printing DDC gathered Modelines:
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1920x1200"x0.0  154.00  1920 1968 2000 2080  1200 1203 1209 1235 +hsync -vsync (74.0 kHz eP)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "720x480"x0.0   27.00  720 736 798 858  480 489 495 525 -hsync -vsync (31.5 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1280x720"x0.0   74.25  1280 1390 1430 1650  720 725 730 750 +hsync +vsync (45.0 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "720x576"x0.0   27.00  720 732 796 864  576 581 586 625 -hsync -vsync (31.2 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "800x600"x0.0   40.00  800 840 968 1056  600 601 605 628 +hsync +vsync (37.9 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "640x480"x0.0   31.50  640 656 720 840  480 481 484 500 -hsync -vsync (37.5 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "640x480"x0.0   25.18  640 656 752 800  480 490 492 525 -hsync -vsync (31.5 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "720x400"x0.0   28.32  720 738 846 900  400 412 414 449 -hsync +vsync (31.5 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1280x1024"x0.0  135.00  1280 1296 1440 1688  1024 1025 1028 1066 +hsync +vsync (80.0 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1024x768"x0.0   78.75  1024 1040 1136 1312  768 769 772 800 +hsync +vsync (60.0 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1024x768"x0.0   65.00  1024 1048 1184 1344  768 771 777 806 -hsync -vsync (48.4 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "832x624"x0.0   57.28  832 864 928 1152  624 625 628 667 -hsync -vsync (49.7 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "800x600"x0.0   49.50  800 816 896 1056  600 601 604 625 +hsync +vsync (46.9 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1152x864"x0.0  108.00  1152 1216 1344 1600  864 865 868 900 +hsync +vsync (67.5 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1024x576"x60.0   46.99  1024 1064 1168 1312  576 577 580 597 -hsync +vsync (35.8 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1280x800"x0.0   83.50  1280 1352 1480 1680  800 803 809 831 -hsync +vsync (49.7 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1280x1024"x0.0  108.00  1280 1328 1440 1688  1024 1025 1028 1066 +hsync +vsync (64.0 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1440x900"x0.0  106.50  1440 1520 1672 1904  900 903 909 934 -hsync +vsync (55.9 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1920x1080"x60.0  172.80  1920 2040 2248 2576  1080 1081 1084 1118 -hsync +vsync (67.1 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1680x1050"x0.0  146.25  1680 1784 1960 2240  1050 1053 1059 1089 -hsync +vsync (65.3 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1600x1200"x0.0  162.00  1600 1664 1856 2160  1200 1201 1204 1250 +hsync +vsync (75.0 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1920x1080"x0.0   74.25  1920 2558 2602 2750  1080 1084 1089 1125 +hsync +vsync (27.0 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1920x1080i"x0.0   74.25  1920 2008 2052 2200  1080 1084 1094 1125 interlace +hsync +vsync (33.8 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1920x1080i"x0.0   74.25  1920 2448 2492 2640  1080 1084 1094 1125 interlace +hsync +vsync (28.1 kHz e)
Jul 08 03:02:40 rawhide gdm-Xorg-:0[846]: (II) RADEON(0): Modeline "1280x720"x0.0   74.25  1280 1720 1760 1980  720 725 730 750 +hsync +vsync (37.5 kHz e)
Jul 08 03:02:40 rawhide kernel: [drm:drm_calc_timestamping_constants] *ERROR* crtc 14: Can't calculate constants, dotclock = 0!

The last line seems important.
Comment 10 Alex Deucher 2014-07-09 17:46:54 UTC
Created attachment 102491 [details] [review]
working patch

This patch works for me.
Comment 11 Kamil Páral 2014-07-10 16:17:00 UTC
Alex, this is great! It works perfectly for me. I tried all available modes. Thanks a lot.

A follow up question: Is this setting supposed to be reset on reboot or remembered? It is reset for me. If one would like to have this remembered, in which tool should one ask for such a feature (kernel, X, DE, somewhere else)? Thanks.
Comment 12 Alex Deucher 2014-07-10 16:21:10 UTC
(In reply to comment #11)
> Alex, this is great! It works perfectly for me. I tried all available modes.
> Thanks a lot.
> 
> A follow up question: Is this setting supposed to be reset on reboot or
> remembered? It is reset for me. If one would like to have this remembered,
> in which tool should one ask for such a feature (kernel, X, DE, somewhere
> else)? Thanks.

It's up to the desktop environment.  It should be saved as part of the display configuration (e.g., along with display modes, orientations, etc., etc.).
Comment 13 Alex Deucher 2014-07-10 17:13:13 UTC
Created attachment 102565 [details] [review]
better patch

This version handles the no modes case properly.
Comment 14 Kamil Páral 2014-07-11 13:46:20 UTC
(In reply to comment #13)
> Created attachment 102565 [details] [review] [review]
> better patch
> 
> This version handles the no modes case properly.

I re-tried it, still works for me.
Comment 15 Alex Deucher 2014-07-11 13:47:21 UTC
I've added the patch to my 3.17 queue.
Comment 16 Kamil Páral 2015-01-26 16:12:22 UTC
I believe this can be closed. It seems to work well on my kernel 3.18. Thanks, Alex.
Comment 17 Oleg 2016-01-06 13:49:57 UTC
Maybe I'm late to the party, but this doesn't seem to work for me no matter how I try.
My video card is Radeon 7770, kernel is 4.2.0 (it didn't work with any older ones either), Ubuntu 15.10 running open source driver stack, 22" monitor 1680x1050 native resolution which is 16:10 I believe.

Even if set "scaling mode" to "full aspect" (or "center" for that matter) and then switch to a non-native resolution the image is still stretched to full screen without respect to the aspect ratio.
I've tried to change the connection (I'm using a DVI -> HDMI cable, tried a straight DVI -> DVI one), the monitor, and even the distro (tested with the latest Fedora Live), to no avail. It seems that the setting is simply ignored.

Can anybody kindly suggest how I should go about it eg debug it somehow? Overall I have a gut feeling there's something that needs to be tweaked besides the xrandr setting, but have no idea what.

Here's what seems to be an identical complaint: https://bbs.archlinux.org/viewtopic.php?id=192423

Thanks in advance.
Comment 18 Kamil Páral 2016-01-06 18:14:31 UTC
Hi Oleg, I checked and this still works for me (Radeon R9 270, Fedora 23, kernel-4.2.8-300.fc23.x86_64, mesa-dri-drivers-11.1.0-1.20151218.fc23.x86_64, DisplayPort cable). Please note that you need to specify the scaling exactly as printed out on "supported:" line, i.e. with the first letter in upper case. It is not case insensitive, and if you have the case wrong, the scaling mode is ignored. Maybe that's the issue?
(It would be nice to have this case insensitive, because it has bitten me in the past as well. Maybe someone could create an RFE ticket for this?)
Comment 19 Oleg 2016-01-06 19:28:21 UTC
Hi, Kamil. Indeed it worked as you suggested. I feel dumb now. But I can swear I've tried it that way too. Although some time ago. Maybe even before Alex included this patch?
Anyway thanks man you saved me. If we're ever to meet, the beer's on me :)
Comment 20 Kamil Páral 2016-01-07 10:36:16 UTC
Glad that it helped :) I have created an RFE for xrandr to ignore case for scaling mode values - bug 93624.

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.