Today I wanted to see if I can build mesa on FreeBSD. I had to do a few fixes in the code of libdrm and mesa, but the rest of the process was very similar to the steps I follow to build mesa on Linux. Only some paths and a few commands and settings had to be slightly different.
Below you can find the steps to build mesa on FreeBSD.
Prerequisites:
Mesa has similar package requirements on FreeBSD and Linux. The prerequisite packages can be found either in the official documentation or by running pkg info -dx mesa to find the mesa package dependencies.
The kernel driver must be installed in the system otherwise the software rasterizer is going to be used:
1 |
sudo pkg install drm-kmod |
The user that is going to use OpenGL must be added in the video group in /etc/group. This group is used for all graphics, there’s no separate render group like on Linux.
File /etc/rc.conf needs to be modified to contain the following line for the kernel module to be automatically loaded:
1 |
kld_list="/boot/modules/i915kms.ko" |
I’ve written a minimal Xorg.conf
in /etc/X11
to force the use of DRI3. This is not required by the OpenGL driver as far as I remember, but I created it because I plan to experiment with the Vulkan driver too.
1 2 3 4 5 6 |
Section "Device" Identifier "Card0" Driver "intel" Option "SwapBuffersWait" "0" Option "DRI" "3" EndSection |
Enabling DRI3 is recommended for the anv (Vulkan) driver to work well.
Environment:
My setup is similar to the one I use on Linux. On FreeBSD I use bash with sh scripts because I want to reuse my scripts on both FreeBSD and Linux. In case you are using another shell on FreeBSD you might need to replace all export FOO=bar with setenv FOO bar below.
I usually create a “code” directory where I clone repositories and an installation directory where I install everything I build. I set the library path to include this directory so that I can link with all the libraries I’ve built instead of the system ones.
So for i965, I have a directory mesastuff
where I checkout every repository I’ll need to build for the mesa drivers to work. The mesastuff
directory tree is this:
1 2 3 4 5 6 7 8 9 10 |
qurashee:[eleni]/usr/home/eleni/code/mesastuff$ tree -d -L 2 . βββ code βΒ Β βββ drm βΒ Β βββ mesa βββ install βββ include βββ lib βββ libdata βββ share |
I checkout the git repositories in code
and I use the path to the directory install
as install prefix when I build repositories from code
. Directories include
, lib
, libdata
, and share
are generated later from the installation scripts, I’ve only created code
and install
and then cloned drm
and mesa
in the first one.
I am using the following environment variables:
1 2 3 4 5 |
export PATH=$PATH:$HOME/code/mesastuff/install/bin export LD_LIBRARY_PATH=$HOME/code/mesastuff/install/lib:$HOME/code/mesastuff/install/lib/dri export LD_RUN_PATH=$LD_LIBRARY_PATH export XDG_DATA_DIRS=$XDG_DATA_DIRS:$HOME/code/mesastuff/install/share export LIBGL_DRIVERS_PATH=$HOME/code/mesastuff/install/lib/dri |
Note that the paths are different for Linux, on FreeBSD everything is installed under lib/ and there’s no separate x86_64 directory.
Getting the source code:
Inside the code
directory I clone the git repositories for drm and mesa:
1 2 |
git clone https://gitlab.freedesktop.org/mesa/drm.git git clone https://gitlab.freedesktop.org/mesa/mesa.git |
Or you can do:
1 2 |
git@gitlab.freedesktop.org:mesa/drm.git git clone git@gitlab.freedesktop.org:mesa/mesa.git |
if you have an account on Freedesktop.
Building drm and mesa:
The instructions are for the i965 driver but the process to build other drivers is similar. Because gcc and g++ that are the recommended tools for mesa aren’t installed by default on FreeBSD (clang is the default compiler), it’s recommended you install gcc and export (or setenv) the following variables:
1 2 |
export CC=gcc export CXX=g++ |
To build and install libdrm enter the drm directory and run:
1 2 3 4 5 6 7 8 |
cd <...>/mesatuff/code/drm mkdir build meson ~/code/mesastuff/code/drm/build -Dplatforms=x11,drm -Ddri-drivers=i965,swrast -Dgallium-drivers=swrast,i965 -Dbuildtype=debug -Dvulkan-drivers=intel -Dglvnd=true -Dgles1=true -Dgles2=true -Degl=true -Dgallium-extra-hud=true -Dgallium-nine=true -Dtexture-float=true -Dgallium-vdpau=true -Dgallium-va=true -Dgallium-omx=auto meson configure --buildtype=debug --prefix=~/code/mesastuff/install/ ~/code/mesastuff/code/drm/build ninja -C build/ install |
After that the dri drivers shared libraries should be found under install/lib/dri:
1 2 3 |
$ ls lib/dri/ i965_dri.so* kms_swrast_dri.so* iris_dri.so* swrast_dri.so* |
Mesa will find them because this directory is in the LD_LIBRARY_PATH
we’ve set above.
This is how I build mesa:
1 2 3 4 5 |
cd <...>/mesastuff/code/mesa mkdir build meson ~/code/mesastuff/code/mesa/build -Dplatforms=x11 -Ddri-drivers=i965 -Dgallium-drivers=swrast,iris -Dbuildtype=debug -Dvulkan-drivers=intel -Dglvnd=true -Degl=enabled -Ddraw-use-llvm=false meson configure --buildtype=debug --prefix=/home/eleni/code/mesastuff/install/ ~/code/mesastuff/code/mesa/build ninja -C build/ install |
Note that I’ve built the iris driver (the gallium replacement of i965) for this example, although I can’t enable it on my card which is a 9 year old Ivybridge. I am going to try crocus at some point (crocus is a gallium i965 replacement driver for older cards).
[UPDATE]: When crocus was merged into mesa, I replaced iris
with crocus
above, and removed the -Dglvnd=true
option. Then, I built the driver and at runtime I forced the use of crocus over i965 by running:
export MESA_LOADER_DRIVER_OVERRIDE=crocus.
Testing the installation using glxinfo and glxgears:
To test the installation:
In the same terminal where we’ve set the environment variables (I’ve put all the above commands in a script) we can run:
1 |
glxinfo -B |
If the renderer string is softpipe, something is wrong with hardware acceleration (most probably the kernel module wasn’t loaded)._
If the OpenGL version string ends in something like Mesa <a number>-devel (git-dc883225c5) (ends with the last git commit hash) then the mesa driver from git is being used (the one we’ve just built).
Next run glxgears. _GL_SYNC_TO_VBLANK doesn’t seem to work as expected so if you want to check the FPS with the vsync being disabled you must run:
1 |
vblank_mode=0 glxgears |
And this is how the glxinfo output and glxgears look on my FreeBSD desktop:
[UPDATE]: If you check the renderer string a few lines above the highlighted one in the screenshot above you’ll see that it’s:
OpenGL renderer string: Mesa DRI Intel(R) HD Graphics 4000 (IVB GT2)
. Forcing crocus over i965 (see UPDATE above) and in general gallium drivers over non gallium ones would change the string to be Mesa Intel(R) HD Graphics 4000 (IVB GT2)
. Note that the DRI
part is missing from the gallium drivers renderer strings, and this is an easy way to tell if you are running on crocus or the i965.
Patches:
I had to make a few fixes in drm and mesa before the build was successful on FreeBSD. I am writing this post right after having sent the patches and so, they aren’t upstream yet. You can grab them from their merge requests to build mesa but keep in mind that changes might not be the final ones as they haven’t been reviewed yet!:
DRM patch: MR 173
Mesa patch: MR 11203
See you next time!
NICE WRITEUP — i will try this as my Xorg.0.log says it couldnt load i965 as it doesnt exist,