Linux seems to be finally becoming a viable gaming platform. That brings us into uncharted territories and we start to discover some deficiencies which were solved on other platforms a long time ago. One of those is GPU-based screen scaling.
What is GPU-based screen scaling?
If you want to display a non-native (lower) resolution on your monitor, you have several options how to do that:
- Center image – Display the image in the center using 1:1 pixel mapping (one pixel from the image is 1 pixel on the screen). Add black bars from all 4 sides to fill the rest of the screen. This produces smaller but perfectly sharp image.
- Scale image while keeping aspect ratio – Enlarge the image as much as possible, and (if the image has a different aspect ratio than the monitor) add black bars from the remaining 2 sides (usually top and bottom for movies, left and right for old games). This produces large but blurrier image.
- Scale image fully ignoring aspect ratio – Simply fill the whole screen. This produces full-sized, but blurrier and distorted image (e.g. text is stretched, human bodies have incorrect proportions, etc).
Some of this can be configured through your external monitor’s OSD menu. Centered image is usually not available, and aspect-based scaling is often available only for certain resolutions. Full scaling seems to be (sadly) both the default and the only option available in many cases. Because I’ve just recently bought a new monitor, I investigated a bit and even pricier monitors more often than not offer only the described limited set of options. That is of course unfortunate.
For that reason (and also to be able to configure scaling for fixed notebook screens), graphical drivers offer options to scale the image for you, any way you like. Instead of the monitor, the graphics card does it. This allows you to use any scaling mode that fits your purpose, not just those implemented by the manufacturer of your monitor.
Why do I need screen scaling?
I have described some reasons here. Usually it’s because of either old games (wrong aspect ratio) or too modern games (your hardware doesn’t keep up).
How can I configure GPU-based screen scaling?
For fixed notebook screens, you can do that through xrandr. See the properties of your monitor:
$ xrandr --prop Screen 0: minimum 320 x 200, current 1920 x 1968, maximum 8192 x 8192 LVDS1 connected 1366x768+289+1200 (normal left inverted right x axis y axis) 277mm x 156mm BACKLIGHT: 11 range: (0, 15) Backlight: 11 range: (0, 15) scaling mode: Full aspect supported: None, Full, Center, Full aspect 1366x768 60.10*+ 1024x768 60.00 800x600 60.32 56.25 640x480 59.94
The default seems to be Full aspect. If you set None, it means the image should be sent unaltered into your monitor. You can configure different scaling like this:
$ xrandr --output LVDS1 --set "scaling mode" "Center"
This setting seems to be reset on machine reboot, and I haven’t investigated how to keep it permanent yet. Also, I tested this just on Intel, but I assume all drivers should support it.
For external monitors, I have a bad news for you – you can’t do it (yet). This is the deficiency I was talking about. The properties are not visible through xrandr. The proprietary AMD and NVIDIA drivers have supported it for a long time (example), but it seems there haven’t been enough demand in open source drivers yet (at least intel and radeon drivers can’t do it, I haven’t tested nouveau). So, I requested this functionality as Freedesktop bug 80868 and to my surprise there’s a tentative patch already (thanks Alex Deucher). If you’re skilled with C and hardware development, any help would be highly welcome. IIUIC, the patch will enable this functionality only for radeon driver – there will need to be a similar patch for intel (and possibly nouveau) driver.
Now you can do this even for external monitors!