Skip to content

Instantly share code, notes, and snippets.

@croberts81
Forked from Venemo/mesa-howto.md
Created October 24, 2021 03:10
Show Gist options
  • Save croberts81/9e712c0377f2d72d78bc501d9910e033 to your computer and use it in GitHub Desktop.
Save croberts81/9e712c0377f2d72d78bc501d9910e033 to your computer and use it in GitHub Desktop.
How to build and use mesa from source

Building and using mesa for development and testing

This explains how to build mesa from source, and how to use the custom built mesa to run some apps and games, without needing to replace the mesa libraries that your operating system runs on.

Let's assume that you are using an x86_64 system.

Install dependencies

This is how to install them on Fedora. You can substitute with other distros' package managers, the packages are named similarly but maybe have a different naming convention (eg. -dev vs. -devel, etc.).

dnf install meson ninja-build cmake bison flex gcc gcc-c++ glslang-devel.x86_64 glslang-devel.i686 libzstd-devel.i686 libzstd-devel.x86_64 libvdpau-devel.x86_64 libvdpau-devel.i686 llvm-devel.x86_64 llvm-devel.i686 elfutils-libelf-devel.x86_64 elfutils-libelf-devel.i686 libva-devel.x86_64 libva-devel.i686 libomxil-bellagio-devel.x86_64 libomxil-bellagio-devel.i686 bison-devel.x86_64 bison-devel.i686 valgrind-devel.x86_64 valgrind-devel.i686 wayland-devel.x86_64 wayland-devel.i686 wayland-protocols-devel libxshmfence-devel.x86_64 libxshmfence-devel.i686 lm_sensors-devel.x86_64 lm_sensors-devel.i686 zlib-devel.x86_64 zlib-devel.i686 pkgconf-pkg-config.x86_64 pkgconf-pkg-config.i686 expat-devel.x86_64 expat-devel.i686 glib-devel.x86_64 glib-devel.i686 glibc-devel.x86_64 glibc-devel.i686 libdrm-devel.x86_64 libdrm-devel.i686 libX*-devel.x86_64 libX*-devel.i686 libunwind-devel.x86_64 libxcb-devel.x86_64 libxcb-devel.i686 binutils-devel.x86_64 libstdc++-static.x86_64 multilib-rpm-config python3-devel.x86_64 python3-recommonmark python3-sphinx libffi-devel.x86_64 libffi-devel.i686

64-bit build

We're assuming that your distro uses lib64 for the 64-bit libraries. If not, adjust the meson command below. The compiled libraries will go into ~/mesa for the sake of simplicity.

# Enter the mesa root directory
cd mesa
# Configure the build with meson
meson build64 --libdir lib64 --prefix $HOME/mesa -Ddri-drivers= -Dgallium-drivers=radeonsi,swrast,iris,zink -Dvulkan-drivers=intel,amd -Dgallium-nine=true -Dosmesa=false -Dtools=nir -Dvulkan-device-select-layer=true -Dvulkan-overlay-layer=true -Dbuildtype=release
# Compile with ninja
ninja -C build64 install

Config with AMD drivers only:

meson build64 --libdir lib64 --prefix $HOME/mesa -Ddri-drivers= -Dgallium-drivers=radeonsi,swrast,zink -Dvulkan-drivers=amd -Dgallium-nine=true -Dosmesa=false -Dvulkan-device-select-layer=true -Dvulkan-overlay-layer=true -Dbuildtype=release

Config with RADV only:

meson build64 --libdir lib64 --prefix $HOME/mesa -Ddri-drivers= -Dgallium-drivers= -Dvulkan-drivers=amd -Dvulkan-device-select-layer=true -Dvulkan-overlay-layer=true -Dbuild-aco-tests=true -Dbuildtype=release

You can also have multiple configurations at the same time, eg. maybe a RADV debug build:

meson build64radvdebug --libdir lib64 --prefix $HOME/mesa -Ddri-drivers= -Dgallium-drivers= -Dvulkan-drivers=amd -Dvulkan-device-select-layer=true -Dvulkan-overlay-layer=true -Dbuild-aco-tests=true -Dbuildtype=debug

Then you can compile one with ninja -C build64radvdebug and the other with ninja -C build64 - they don't interfere with each other. Of course if you use the same install prefix they will overwrite each other when you install them.

32-bit build on an x86_64 system

If you don't use Fedora (or another Red Hat family distro), replace i686-redhat-linux-gnu-pkg-config with the correct 32-bit pkg-config executable for your distro. Also verify the location of llvm-config-32 which might be different on another distro.

Create a meson cross file here: ~/.local/share/meson/cross/gcc-i686 with the following content:

[binaries]
c='gcc'
cpp='g++'
ar='ar'
strip='strip'
pkgconfig='i686-redhat-linux-gnu-pkg-config'
llvm-config='/usr/bin/llvm-config-32'

[properties]
c_args=['-m32', '-march=native']
c_link_args=['-m32']
cpp_args=['-m32', '-march=native']
cpp_link_args=['-m32']

[host_machine]
system='linux'
cpu_family='x86'
cpu='x86'
endian='little'

Now you can use it to build 32-bit mesa libs:

cd mesa
meson build32 --cross-file gcc-i686 --libdir lib --prefix $HOME/mesa -Ddri-drivers= -Dgallium-drivers=radeonsi,swrast,iris,zink -Dvulkan-drivers=intel,amd -Dgallium-nine=true -Dosmesa=false -Dtools=nir -Dvulkan-device-select-layer=true -Dvulkan-overlay-layer=true -Dbuildtype=release
ninja -C build32 install

32-bit config with AMD drivers only:

meson build32 --cross-file gcc-i686 --libdir lib --prefix $HOME/mesa -Ddri-drivers= -Dgallium-drivers=radeonsi,swrast,zink -Dvulkan-drivers=amd -Dgallium-nine=true -Dosmesa=false -Dbuildtype=release

Note that you can build both the x86_64 and the i686 libraries together and they can all go to ~/mesa, and then you can use all of that with either 32-bit or 64-bit games.

Building LLVM and using it with mesa

Sometimes you need to test the very latest LLVM and use it without messing up your system packages.

Here are some useful cmake options:

  • CMAKE_INSTALL_PREFIX - for simplicity, let's just use the same prefix as used by your mesa build
  • LLVM_LIBDIR_SUFFIX - for distros that use /usr/lib64 or a similar convention, eg. set this to 64 on Fedora

Example:

cd llvm-project/llvm
mkdir build
cd build
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$HOME/mesa -DLLVM_LIBDIR_SUFFIX=64 -DLLVM_TARGETS_TO_BUILD="AMDGPU" -DLLVM_OPTIMIZED_TABLEGEN=ON -DLLVM_BUILD_LLVM_DYLIB=ON -DLLVM_LINK_LLVM_DYLIB=ON -DLLVM_INCLUDE_EXAMPLES=OFF
ninja
ninja install

After this, you need to rebuild mesa. First, tell mesa's meson to use the LLVM that you just built.

Create a meson native file at $HOME/.local/share/meson/native/my-llvm-x64 with the following content. Substitute Timur with your own username.

[binaries]
llvm-config = "/home/Timur/mesa/bin/llvm-config"

Finally, specify this to meson using the --native-file=my-llvm-x64 argument, for example:

meson build64 --libdir lib64 --prefix $HOME/mesa -Ddri-drivers= -Dgallium-drivers=radeonsi,swrast -Dvulkan-drivers=amd -Dgallium-nine=true -Dosmesa=false -Dbuildtype=release --native-file=my-llvm-x64

Using the compiled mesa

sourcing a script method

Create a script at ~/mesa.sh with the following content:

#!/bin/sh

MESA=$HOME/mesa

export LD_LIBRARY_PATH=$MESA/lib64:$MESA/lib:$LD_LIBRARY_PATH
export LIBGL_DRIVERS_PATH=$MESA/lib64/dri:$MESA/lib/dri
export VK_ICD_FILENAMES=$MESA/share/vulkan/icd.d/radeon_icd.x86_64.json:$MESA/share/vulkan/icd.d/radeon_icd.i686.json
export D3D_MODULE_PATH=$MESA/lib64/d3d/d3dadapter9.so.1:$MESA/lib/d3d/d3dadapter9.so.1

Now you can just source mesa.sh and then anything launched from that terminal will use the mesa libs you just built.

For example:

source ~/mesa.sh
vkcube

To verify that it uses the version of mesa you want:

source ~/mesa.sh
vulkaninfo

running through a script method

This way you don't need to source a script, but rather just run an individual app through a script. Create a script file like this, eg. nano ~/mesa-run.sh

#!/bin/sh

MESA=$HOME/mesa \
LD_LIBRARY_PATH=$MESA/lib64:$MESA/lib:$LD_LIBRARY_PATH \
LIBGL_DRIVERS_PATH=$MESA/lib64/dri:$MESA/lib/dri \
VK_ICD_FILENAMES=$MESA/share/vulkan/icd.d/radeon_icd.x86_64.json:$MESA/share/vulkan/icd.d/radeon_icd.x86.json \
D3D_MODULE_PATH=$MESA/lib64/d3d/d3dadapter9.so.1:$MESA/lib/d3d/d3dadapter9.so.1 \
    exec "$@"

Now you can run your games like:

~/mesa-run.sh vkcube

Using RADV with RGP

source ~/mesa.sh

# Run RADV with pipeline tracing enabled, and specify a trigger file
RADV_THREAD_TRACE_PIPELINE=1 RADV_THREAD_TRACE_TRIGGER=/tmp/trigger ./bin/triangle

# From a different terminal, touch the trigger file. This will make RADV create an RGP capture in /tmp
touch /tmp/trigger

Running Starcraft 2

Assuming that you completed all the steps so far, and you use a Wine prefix ~/.wineSC2 the following will launch SC2 using the specified mesa version:

source ~/mesa.sh
WINEDEBUG=-all NIR_VALIDATE=0 WINEPREFIX=/home/Timur/.wineSC2 wine64 "C:\Program Files (x86)\StarCraft II\Support64\SC2Switcher_x64.exe"

If you want to use iris:

source ~/mesa.sh
MESA_LOADER_DRIVER_OVERRIDE=iris WINEDEBUG=-all NIR_VALIDATE=0 WINEPREFIX=/home/Timur/.wineSC2 wine64 "C:\Program Files (x86)\StarCraft II\Support64\SC2Switcher_x64.exe"

Useful environment variables for debugging

  • MESA_VK_WSI_PRESENT_MODE=fifo forces V-sync in Vulkan apps, so that your GPU won't heat up from rendering the demo apps in 5000 fps
  • RADV_DEBUG=nongg disables NGG on Navi
  • RADV_DEBUG=shaders enables shader debugging on RADV
  • RADV_DEBUG=nocachedisables caching on RADV
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment