Recently I had some trouble getting Ubuntu 20.04 and the AMDGPU driver to output 10-bit color over HDMI on my HTPC with AMD Ryzen 3 3200G.
The Problem
Somehow the max bpc
property for the HDMI output is being limited to 8-bit by, even if DefaultDepth 30
is set in xorg.conf
.
According to man pages, the driver should select the highest supported bit depth by default, I haven’t been able to figure out the reason why it doesn’t do it for my setup, yet.
How I fixed it
Configuring DefaultDepth 30
First create the file /usr/share/X11/xorg.conf.d/20-amdgpu.conf
to enable 10-bit color depth. The identifier can be anything you like.
1
2
3
4
Section "Screen"
Identifier "OLED"
DefaultDepth 30
EndSection
After a reboot check that depth is now 30:
1
2
3
4
$ grep -i 'depth\|bits' ~/.local/share/xorg/Xorg.0.log
[ 19.052] (**) AMDGPU(0): Depth 30, (--) framebuffer bpp 32
[ 19.052] (II) AMDGPU(0): Pixel depth = 30 bits stored in 4 bytes (32 bpp pixmaps)
[ 19.052] (II) AMDGPU(0): Using 10 bits per RGB (8 bit DAC)
As we can see, depth 30 is enabled and it is using 10 bits per color.
Don’t worry about the 8 bit DAC message in parenthesis, it always prints 8 as long as dac6bits is disabled.
See the relevant code:
1
2
3
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Using %d bits per RGB (%d bit DAC)\n",
pScrn->rgbBits, info->dac6bits ? 6 : 8);
Checking the HDMI Signal
It should be working now, but after checking the HDMI signal on my Denon AVR, it appears that the GPU is still outputting only 8-bit:
With the AMDGPU driver we can also check this through the kernel debugfs. For the 3200g the HDMI output is called HDMI-A-1 here.
1
2
3
$ sudo cat /sys/kernel/debug/dri/0/HDMI-A-1/output_bpc
Current: 8
Maximum: 12
So it appears that the driver selected 8-bit even though up to 12-bit is possible.
Change max bpc with xrandr
Fortunately we can change it with xrandr
. For some reason the HDMI port is numbered differently here than in the debugfs. You can find the name by running xrandr -q
1
2
3
4
5
6
$ xrandr -q | grep connected
HDMI-A-0 connected primary 3840x2160+0+0 (normal left inverted right x axis y axis) 1600mm x 900mm
DVI-D-0 disconnected (normal left inverted right x axis y axis)
DisplayPort-0 disconnected (normal left inverted right x axis y axis)
$ xrandr --output HDMI-A-0 --set "max bpc" 10
The screen should now go blank for a second while the change takes effect.
Checking the HDMI Signal again
After it comes back we can check the output_bpc
again.
1
2
3
$ sudo cat /sys/kernel/debug/dri/0/HDMI-A-1/output_bpc
Current: 10
Maximum: 12
And the HDMI signal received by the AVR is now 10-bit as well:
Make it persistent
The easiest way to make the max bpc
setting persistent is to create a .xprofile
file in your home directory and put the xrandr
command there. Alternatively you can enable it system-wide by creating/editing /etc/X11/Xsession.d/45x11-custom_xrandr-settings
instead.
1
xrandr --output HDMI-A-0 --set "max bpc" 10
Extra bits
Trying a bit depth test image didn’t seem to work in browsers and the Ubuntu image viewer, I recommend using
mpv
with a test clip. You should be using it to play all your videos anyway.If you are somehow wondering if using the xrandr.lua plugin for mpv does reset the
max bpc
setting when it switches refresh rates, I can confirm that it does not. Both work fine together.
I hope this post helps at least 1 person with the same problem, it seems quit rare though.