Home 10-bit color on Ubuntu 20.04 with AMDGPU driver
Post
Cancel

10-bit color on Ubuntu 20.04 with AMDGPU driver

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: Denon AVR HDMI Signal 8bits

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: Denon AVR HDMI Signal 10bits

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.

This post is licensed under CC BY 4.0 by the author.