Non default graphic card on OpenBSD

on 2023-01-08

In my current configuration, I have two graphic cards: a nvidia card that I mainly use for playing AAA games on Linux (NixOS) and a AMD radeon for OpenBSD (my daily driver). When I boot my computer, it picks the nvidia card by default which does not work well with OpenBSD (to say the least). So I have configured xorg (by creating a /etc/xorg.conf) to use the second card instead. As an exemple, here is my /etc/xorg.conf:

Section "Device"
  Identifier "Radeon HD 6450"
  BusID "PCI:27@0:0"
  Driver "radeon"
EndSection

The BusID is given by pcidump(8) and the different options for my card are listed in radeon(4). If you use a recent graphic card, you probably need to have a look at amdgpu(4) intead.

Recently I wanted to play Dead Cells on OpenBSD (another post on this) but I was greeted by an error at launch about acces to my graphic card:

Loading assets... Loading pak assets... done.
libGL error: MESA-LOADER: failed to retrieve device information
libGL error: image driver extension not found
libGL error: failed to load driver: radeon
libGL error: failed to open /dev/dri/card1: Permission denied
libGL error: failed to open /dev/dri/card1: Permission denied
libGL error: failed to load driver: r600
518 shaders loaded in 0.7877

Thanks to @thfr on #openbsd-gaming, the problem was quickly identified: my configuration for using the non default graphic card was imcomplete.

When using the non default card, you need of course to create a xorg.conf file, but you also need to edit the /etc/X11/xenodm/GiveConsole and /etc/X11/xenodm/TakeConsole. Here is the content of /etc/X11/xenodm/GiveConsole before modifications:

  #!/bin/sh
# Assign ownership of the console to the invoking user
# $OpenBSD: GiveConsole.in,v 1.2 2022/01/06 23:35:41 jsg Exp $
#
# By convention, both xconsole and xterm -C check that the
# console is owned by the invoking user and is readable before attaching
# the console output.  This way a random user can invoke xterm -C without
# causing serious grief.
#
prefix="/usr/X11R6"
exec_prefix="${prefix}"

chown $USER /dev/console
if [ -c /dev/dri/card0 ]; then
    chown $USER /dev/dri/card0
fi
if [ -c /dev/dri/renderD128 ]; then
    chown $USER /dev/dri/renderD128
fi
${exec_prefix}/bin/sessreg -a -l $DISPLAY -u none $USER

The first script makes sure that the device file (I am not sure this is the right term) of the graphic cards is owned by the current user of the X11 session and the second script makes sure that the ownership is set back to root when the X11 session is terminated.

In these two files, you need to add similar lines for card1 and maybe for renderD129 (it does not seem necessary, but I did it for "symmetry" reasons), for example in GiveConsole:

if [ -c /dev/dri/card1 ]; then
    chown $USER /dev/dri/card1
fi
if [ -c /dev/dri/renderD129 ]; then
    chown $USER /dev/dri/renderD129
fi

If you use GNOME with GDM, the files to modify are /etc/gdm/PreSession/Default and /etc/gdm/PostSession/Default.