OpenGL without X on Raspberry Pi 4 (Part 1)


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.


The canonical OpenGL without X example code is given in a program called KMSCube. Source code is available at but you can install a binary version using

sudo apt install kmscube

Your first instinct will be to try to run


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.

No worries, kmscube has your back,

/usr/bin/kmscube -D /dev/dri/card1

but boom!

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)"
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.

/usr/bin/kmscube -D /dev/dri/card1

And the reported information is more what you would expect

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"

In future blogs I’ll take a look at the actual code.

Tagged with: , , ,
Posted in Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: