Introduction
Many people wanting to use OpenGL on a Raspberry Pi will be happy to boot into the graphical desktop and use OpenGL inside an X11 window. If you are new to graphics programming then these are not the blogs you are looking for.
If you have previously used RPi0-3 without X11 then you may have used DispmanX to obtain a Native Window. Using a variety of intertube sources, it now seems that with the advent of the RPi4, the use of the DispmanX library has moved from discouraged to the wrong way. So what do you use? The answer seems to be, use the Linux Direct Rendering Manager (DRM).
I should fess up and let you know that I have never used libDRM before so this blog is an account of my stumblings around in the dark.
KMSCube
The canonical OpenGL without X example code is given in a program called KMSCube. Source code is available at https://github.com/robclark/kmscube but you can install a binary version using
sudo apt install kmscube
Your first instinct will be to try to run
/usr/bin/kmscube
which will fail with
drmModeGetResources failed: Invalid argument
failed to initialize legacy DRM
What is going on here is that by default kmscube tries to use /dev/dri/card0 as the default, whereas the hardware we want to use is card1.
Pi0-3 you only have the vc4 driver, therefore render is via /dev/dri/card0. Pi4 has both vc4 for render, and v3d for 3D. You can probe the devices for their capabilities – only one should acknowledge that it has DRIVER_RENDER or DRIVER_MODESET capabilities.
https://www.raspberrypi.org/forums/viewtopic.php?t=247540#p1511538
No worries, kmscube has your back,
/usr/bin/kmscube -D /dev/dri/card1
but boom!
<snip>
OpenGL ES 2.x information:
version: "OpenGL ES 3.1 Mesa 19.3.2"
shading language version: "OpenGL ES GLSL ES 3.10"
vendor: "VMware, Inc."
renderer: "llvmpipe (LLVM 9.0.1, 128 bits)"
<snip>
failed to set mode: Invalid argument
One of the unexpected outputs in the above is that the renderer is the software renderer, llvmpipe, rather than the Raspberry Pi V3D engine. I also note that it failed to “set mode” which makes me think “permissions!” So let’s take a look at the permissions of card1 and our own groups:
$ ls -al /dev/dri/card1
crw-rw---- 1 root video 226, 1 Jan 31 11:42 /dev/dri/card1
$ groups
pi adm dialout cdrom sudo audio video plugdev games users input netdev gpio i2c spi
That appears to be right to me, I’m in group video and group video has read/write access on card1. However if I just hit it with a hammer
$ sudo /usr/bin/kmscube -D /dev/dri/card1
then suddenly I have the beautiful rotating cube.
If I look slightly wider, I see that /dev/dri/renderD128 is in group render. Adding user pi to group render,
$ sudo usermod -a -G render pi
do the logout/login dance to pick up the new groups and suddenly the no-sudo kmscube works.

And the reported information is more what you would expect
<snip>
OpenGL ES 2.x information:
version: "OpenGL ES 3.1 Mesa 19.3.2"
shading language version: "OpenGL ES GLSL ES 3.10"
vendor: "Broadcom"
renderer: "V3D 4.2"
<snip>
In future blogs I’ll take a look at the actual code.
Leave a Reply