Skip to content

Instantly share code, notes, and snippets.

@baryluk
Last active November 14, 2024 20:45
Show Gist options
  • Save baryluk/1041204eff4cc4fad6f1508afe67b562 to your computer and use it in GitHub Desktop.
Save baryluk/1041204eff4cc4fad6f1508afe67b562 to your computer and use it in GitHub Desktop.
Build Mesa from git and libdrm git for Debian. amdgpu build 64-bit and 32-bit for Debian stable, testing and unstable, and possibly Ubuntu, Mint, PopOS, etc. No root required. (well sudo to install some build dependencies required tho). Currently a bit borked on Debian stable (requires newer meson).
#!/usr/bin/env python3
# A simple script to build 64-bit and 32-bit Mesa and libdrm on amd64 Debian
# stable, Debian testing, Debian unstable, and possibly some Ubuntu versions
# with some tweaks.
#
# libdrm is build too, because often version right now in Debian sid and experimental
# is too old for current mesa git repo. Also it is nice to build debug
# versions of libdrm when troubleshooting some crashes and bugs.
#
# A situation with LLVM on Ubuntu was (is?) not perfect, so you are on your own.
#
# If you do not want to or can not use it, modify the script to install and use
# other LLVM and update LLVMVERSION variable below.
#
# It is too complex to handle fully automatically and be future proof. So just
# edit the script accordingly.
#
# By default only drivers for AMD, Intel and software rendering will be built.
# That will build radeon driver, radv (with ACO and LLVM), llvmpipe, swrast,
# lavapipe, and zink, with few other minor things.
#
# No Nvidia drivers will be compiled. This is to speed up compilation
# a bit. Modify MESA_COMMON_OPTS to change that.
#
# OpenCL support with clover will be built for 64-bit, but you should know
# the OpenCL support in Mesa still has some bugs, so be aware.
# Valgrind extra support will be built for 64-bit only too.
# Otherwise rest (Mesa, OpenGL, Vulkan, Mesa overlay layer, Mesa device selection
# layer, gallium-nine, zink, lavapipe), will be built for both
# 64-bit and 32-bit versions.
#
# OpenGL ES (GLES) and EGL are also built. Previously it was disabled, as
# I found not use for it, beyond making compilation slower, but as of 2022,
# few critical apps require it in some configurations.
#
# Similarlly a Wayland support is untested, and probably not enabled.
# Modify MESA_COMMON_OPTS if needed.
#
# Use --buildopt=1 to enable also debug builds, which can build
# together with optimized builds.
#
# The build will be performed in ~/mesa-git directory for you.
#
# The source tree will live in ~/mesa-git
# Built libraries and binaries will be in ~/mesa-git/builddir/build-{amd64,i386}-{dbg,opt}/
# Libraries and binaries will be installed into ~/mesa-git/installdir/build-{amd64,i386}-{dbg,opt}/
#
# After compilation is done, the script will perform a small test with glxinfo,
# vulkaninfo and vkcube for 2 seconds.
#
#
# After compilation is done, use '. ~/enable-new-mesa-opt.source'
# (without quotes) in your terminal to enable it.
# You can add it to your ~/.profile or ~/.bashrc file too.
#
# You need to use this '. ~/enable-new-mesa-opt.source' before any other
# OpenGL / Vulkan app is started from the same terminal. It is not enough to
# simply do '. ~/enable-new-mesa-opt.source' in a terminal, and the launch
# steam or some game via desktop shorcut, or other terminal. The changes are
# local to the terminal / shell you used it to. You can use it in many terminals
# as you wish.
#
# Note that `enable-new-mesa-opt.source` will also automatically enable ACO if
# available and enable Vulkan Mesa overlay, Gallium HUD, and DXVK HUD.
# Feel free to modify this script below (line ~280 and ~328) to not do that.
# Or source the `disable-new-mesa-hud.source` script to undo the HUD stuff.
#
# This script will not install libraries system wide, so it is safe to use in
# parallel with your distro libraries. And even have applications using one
# or another, or some using optimized libraries and some using debug libraries.
#
# To get rid of it simply run:
#
# rm -rf ~/mesa-git ~/libdrm-git ~/enable-new-mesa-*.source ~/disable-new-mesa-hud.source ~/mesa-{opt,dbg} ~/zink-{opt,dbg}
#
# If you want to use this Mesa's OpenGL / Vulkan for your desktop manager, like
# Gnome Shell, you are on your own, but it can be probably done some way by
# putting needed variables in /etc/environment. Maybe...
# Or tweak INSTALLDIR variable. But few more variables (`-Dprefix` for example)
# will be needed to be changed. See https://www.mesa3d.org/meson.html for details.
#
# By default rerunning this script will reuse builddir and installdirs,
# and perform incremental build. But it will not fetch new version.
#
# To fetch new version of mesa and drm, pass --git-pull=1
#
# To do rebuild from scratch. Pass --incremental=0
#
# Alternatively, you can do "git pull", then go into proper
# build subdirectory and recompile, i.e. using:
#
# cd ~/mesa-git/builddir/build-amd64-opt/ && ninja && ninja install
#
# Copyright: Witold Baryluk <[email protected]>, 2019-2024
# License: MIT style license
# Also thanks for bug reports, contributions and fixes, including, from:
# @serhii-nakon, @kofredwan13, @gremble
#
import argparse
import os
import shutil
import subprocess
import sys
assert os.getuid() != 0, "Do not run this script under root or using sudo!"
HOME = os.environ["HOME"]
assert HOME and not HOME.endswith("/")
os.chdir(HOME)
PWD = os.getcwd()
SOURCEDIR_LIBDRM = f"{HOME}/libdrm-git"
SOURCEDIR_MESA = f"{HOME}/mesa-git"
BUILDDIR = f"{PWD}/mesa-git/builddir"
# Aka prefix, but we put each build into separate subprefix.
# So in total there will be 4 subprefixes (64-bit optimized, 32-bit optimized,
# 64-bit debug, 32-bit debug)
INSTALLDIR = f"{PWD}/mesa-git/installdir"
USE_SYSTEM_LIBDRM = False # Set to True to use system libdrm-dev.
def str2bool(x) -> bool:
if x.lower() in {"true", "t", "yes", "y", "1"}:
return True
if x.lower() in {"false", "f", "no", "n", "0"}:
return False
raise Exception("boolean flags can only be true, True, t, yes, y, Y, 1, false, False, f, no, n, N, 0, etc")
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
# Show less output, but also do fully automatic apt-get setup not needing any confirmations.
parser.add_argument("--quiet", help="Run in quiet and automated mode", default=False, type=str2bool)
parser.add_argument("--debug", help="Run in debug mode", default=False, type=str2bool)
parser.add_argument("--apt-auto", help="Automatically install required dependencies. If 0, also skip some verifications.", default=True, type=str2bool)
parser.add_argument("--llvm", help="Select LLVM / libclc / libclang version to use. auto - try to autodetect.", default="auto")
parser.add_argument("--git-repo-mesa", help="If sourcedir doesn't exist, clone the repo with URL.", default="https://gitlab.freedesktop.org/mesa/mesa.git")
parser.add_argument("--git-branch-mesa", help="For --git-repo-mesa which branch to checkout.", default="")
parser.add_argument("--git-repo-libdrm", help="If sourcedir doesn't exist, clone the repo with URL.", default="https://gitlab.freedesktop.org/mesa/drm.git")
parser.add_argument("--git-branch-libdrm", help="For --git-repo-libdrm which branch to checkout.", default="main")
parser.add_argument("--git-depth", help="For --git-repo-mesa and --git-repo-libdrm what --depth=N to use.", default=1)
#parser.add_argument("--git-full-depth", help="For the clone, use full clone, instead of using --depth=1000.", default=False, type=str2bool)
parser.add_argument("--git-pull", help="Do a git pull for libdrm and mesa in existing git clones, before build.", default=False, type=str2bool)
#parser.add_argument("--no-clean", help="Don't remove builddir and installdir at the start.", default=False, type=str2bool)
parser.add_argument("--incremental", help="Don't remove builddir and installdir at the start, but invoke compile and install again.", default=True, type=str2bool)
#parser.add_argument("--sourcedir", help="Where to put mesa sources.", default=f"{HOME}/mesa-git")
#parser.add_argument("--builddir", help="Base for the build location.", default=BUILDDIR)
#parser.add_argument("--installdir", help="Base for the install location.", default=INSTALLDIR)
parser.add_argument("--build64", help="Build 64-bit version.", default=True, type=str2bool)
parser.add_argument("--build32", help="Build 32-bit version.", default=True, type=str2bool)
# Build optimized (-march=native -O2) binaries. If not, only separate debug
# build is built.
parser.add_argument("--buildopt", help="Build optimized (-O2 -march=native + debug code disabled) version. (can be enabled with --builddebug, two builds will be created)", default=True, type=str2bool)
# Build separate debug builds with -O1 -ggdb and Mesa debugging code (extra
# runtime checks and asserts) present. You can have both BUILDOPT and
# BUILDDEBUG enabled, and two versions of Mesa will be built, and you can
# switch between them per-app quickly. It is not recommended to use it in
# general unless you find an issue in some apps, crashes, or glitches.
# It is safe to enable building debug builds, even if you are only going to
# use optimized built. They are completly independent.
parser.add_argument("--builddebug", help="Build debug (-O1 -ggdb -g3 + asserts / checks enabled) version. (can be enabled with --buildopt, two builds will be created)", default=False, type=str2bool)
# Use heavy optimizations (-march=native -O3 -free-vectorize -flto -g0) in
# optimized build. This will take about twice as long to compile, might
# expose extra bugs in Mesa or GCC, and will make debugging a bit harder.
# I personally didn't notice any significant performance improvements,
# but in theory they are slightly faster.
parser.add_argument("--heavyopt", help="Use additionally -O3 -march=native -flto -g -mf16c -mfpmath=sse ... et al for --buildopt.", default=False, type=str2bool)
# Build Clover / OpenCL / OpenCL-SPRI-V support for 64-bit. This flag is ignored
# for 32-bit builds at the moment, but in future it will be used there too.
parser.add_argument("--buildopencl", help="Include OpenCL support (Clover)", default=True, type=str2bool)
#parser.add_argument("--buildextras", help="Build extras (i.e. fossilize, shader-db).", default=True, type=str2bool)
parser.add_argument("--gallium-drivers", help="Drivers to include.", default="radeonsi,r600,zink,virgl,softpipe,llvmpipe")
# r300 disabled, because it is a very old hardware (more than 20 years). It still works for basic use, but no point compiling it by default here.
# r600 disabled, because it requires LLVM, but we now try to build without LLVM by default (meson.build:1765:4: ERROR: Problem encountered: R600 requires LLVM AMD support.)
# 2024-02-13: Removed iris,crocus,i915 because of complex compilation issues related to meson native: true, intel_clc on amd64
parser.add_argument("--vulkan-drivers", help="Drivers to include.", default="amd,swrast,virtio")
# noveau disabled, because (and also because I do not use it) of some bindgen issues: Unable to generate bindings: ClangDiagnostic("/home/user/mesa-git/src/nouveau/winsys/./nouveau_bo.h:41:4: error: unknown type name 'atomic_uint_fast32_t'\n")
# Note: intel,intel_hasvk, # disabled due to issues with intel_clc on amd64
# gfxstream-experimental not enabled because: src/gfxstream/guest/meson.build:30:16: ERROR: Dependency "aemu_base" not found, tried pkgconfig
parser.add_argument("--wayland", help="Enable / disable wayland support.", default=True, type=str2bool)
# parser.add_argument("--endchecks", help="Perform post-install tests / sanity checks.", default=True, type=str2bool)
# parser.add_argument("--uninstall", help="Cleanup everything, sourcedir, builddir, installdir, and generated files, and exit. (Remember to pass --*dir options first, if needed).", default=False, type=str2bool)
args = parser.parse_args()
assert len(set([HOME, SOURCEDIR_MESA, SOURCEDIR_LIBDRM, BUILDDIR, INSTALLDIR])) == 5, "All used directories must be unique"
def maybeprint(*print_args):
if not args.quiet:
print(*print_args)
def run(cmd_args, *, env = None, check: bool = True) -> bool:
print("Running", *cmd_args)
try:
if args.quiet:
p = subprocess.run(cmd_args, stdout=subprocess.DEVNULL, env=env)
else:
p = subprocess.run(cmd_args, env=env)
except FileNotFoundError:
print("Command failed:", *cmd_args)
# I.e. sudo or lsb_release missing
print("Maybe", cmd_args[0], "is not installed?")
if check:
sys.exit(1)
if check:
if p.returncode != 0:
print("Command failed:", *cmd_args)
print("with exit code:", p.returncode)
sys.exit(1)
# p.check_returncode() # Throws exception, with not too pretty trace
return p.returncode == 0
def capture(cmd_args, *, env = None) -> bool:
p = subprocess.run(cmd_args, stdout=subprocess.PIPE, universal_newlines=True, env=env)
return p.stdout
def grep(cmd_stdout: str, pattern: str) -> list[str]:
assert isinstance(pattern, str)
return [line.rstrip() for line in cmd_stdout.splitlines() if line.startswith(pattern)]
# Run CPU intensive parts at low priority so they can run in background,
# with less interference to other apps.
NICE = ["nice", "--adjustment=20"]
assert args.buildopt or args.builddebug, "At least one of the --buildopt and --builddbg is required"
assert args.build32 or args.build64, "At least one of the --build32 and --build64 is required"
if args.build32:
print("Checking multiarch support ...")
maybeprint()
p = capture(["dpkg", "--print-foreign-architectures"])
if "i386" not in p.splitlines():
print("No multiarch enabled. Please run (as root) below command:")
print()
print("dpkg --add-architecture i386 && apt-get update")
print()
print("and then retry this script again.")
print()
print("Alternatively run this script with --build32=false option to disable building i386 (32-bit) mesa")
sys.exit(2)
APT_INSTALL = [
"apt-get",
"install",
"--option", "APT::Get::HideAutoRemove=1",
"--option", "quiet::NoProgress=1",
"--no-install-recommends",
]
if args.quiet:
APT_INSTALL.extend(["-qq", "--assume-yes", "--no-remove", "--option","Dpkg::Use-Pty=0"])
SUDO = ["sudo", "--preserve-env=DEBIAN_FRONTEND,APT_LISTCHANGES_FRONTEND,NEEDRESTART_MODE,NEEDRESTART_SUSPEND,DEBIAN_FRONT"]
new_env = dict(os.environ)
new_env.update({
"DEBIAN_FRONTEND": "noninteractive",
"APT_LISTCHANGES_FRONTEND": "none",
"NEEDRESTART_MODE": "l", # list only
"NEEDRESTART_SUSPEND": "1", # do not run at all temporarily from apt-get
"DEBIAN_FRONT": "noninteractive", # for needrestart, just in case.
})
def sudo(cmd_args, check: bool = True):
return run(SUDO + cmd_args, env=new_env, check=check)
def maybenewline():
if not args.quiet:
print()
if args.apt_auto and args.build32:
maybeprint()
print("Checking base dependency versions on amd64 and i386 ...")
maybeprint()
sudo(APT_INSTALL + ["libc6-dev:amd64", "libc6-dev:i386"])
# Sometimes some packages might reach only one architecture first, and it might
# be really hard to coinstall some package on both amd64 and i386, when they are
# out of sync. Check they are in sync first.
# Note: This can be done nicer using dctrl-tools package, but it is not
# installed by default or needed.
v1 = grep(capture(["dpkg", "-s", "linux-libc-dev:amd64"]), "Version")
v2 = grep(capture(["dpkg", "-s", "linux-libc-dev:i386"]), "Version")
if v1 != v2:
print("linux-libc-dev:amd64 and linux-libc-dev:i386 do have different versions!")
print("Please fix first and then retry.")
sys.exit(2)
v1 = grep(capture(["dpkg", "-s", "libc6-dev:amd64"]), "Version")
v2 = grep(capture(["dpkg", "-s", "libc6-dev:i386"]), "Version")
if v1 != v2:
print("libc6-dev:amd64 and libc6-dev:i386 do have different versions!")
print("Please fix first and then retry.")
sys.exit(2)
else:
maybeprint()
print("Checking base dependency versions on amd64 ...")
maybeprint()
sudo(APT_INSTALL + ["libc6-dev:amd64"])
try:
LSB_DIST = capture(["lsb_release", "-is"]).strip()
except FileNotFoundError as e:
print("Command failed:", "lsb_release", "-is")
print("Error:", e)
# TODO(baryluk): We can bypass lsb_release and read /etc/debian_version maybe
print("Maybe package lsb-release is not installed?")
sys.exit(1)
LSB_VERSION = capture(["lsb_release", "-sr"]).strip()
DIST_VERSION = LSB_DIST + "_" + LSB_VERSION
LLVMVERSION = "13"
GCCVERSION = "11"
LLVMREPO = []
LIBCLC_PACKAGES = ["libclc-dev"]
# Not installing libclc-14-dev will uninstall mesa-opencl-icd, and install pocl-opencl-icd
# This is suboptimal, but should still work, and OpenCL is not a big thing anyway.
if DIST_VERSION.startswith("Debian_9"): LLVMVERSION=7; GCCVERSION=6 # Stretch
elif DIST_VERSION.startswith("Debian_10"): LLVMVERSION=8; GCCVERSION=8 # Buster backports.
elif DIST_VERSION.startswith("Debian_11"): LLVMVERSION=13; GCCVERSION=10 # Bullseye
elif DIST_VERSION.startswith("Debian_12"): LLVMVERSION=14; GCCVERSION=12; LIBCLC_PACKAGES=["libclc-14-dev"] # Bookworm
elif DIST_VERSION.startswith("Debian_13"): LLVMVERSION=19; GCCVERSION=14; LIBCLC_PACKAGES=["libclc-19-dev"] # Trixie
elif DIST_VERSION == "Debian_testing": LLVMVERSION=19; GCCVERSION=14; LIBCLC_PACKAGES=["libclc-19-dev"] # currrently Trixie
elif DIST_VERSION == "Debian_n/a": LLVMVERSION=19; GCCVERSION=14; LIBCLC_PACKAGES=["libclc-19-dev"] # Could be testing or sid # Debian bug #1008735
elif DIST_VERSION == "Debian_unstable": LLVMVERSION=19; GCCVERSION=14; LIBCLC_PACKAGES=["libclc-19-dev"]
elif DIST_VERSION == "Ubuntu_16.04": LLVMVERSION="5.0"; GCCVERSION=5 # Good luck with that.
elif DIST_VERSION == "Ubuntu_18.04": LLVMVERSION="6.0"; GCCVERSION=8 # or with that.
elif DIST_VERSION == "Ubuntu_18.10": LLVMVERSION=7; GCCVERSION=8
elif DIST_VERSION == "Ubuntu_19.04": LLVMVERSION=8; GCCVERSION=9
elif DIST_VERSION == "Ubuntu_19.10": LLVMVERSION=9; GCCVERSION=9
elif DIST_VERSION == "Ubuntu_20.04": LLVMVERSION=10; GCCVERSION=9
elif DIST_VERSION == "Ubuntu_20.10": LLVMVERSION=11; GCCVERSION=10
elif DIST_VERSION == "Ubuntu_21.04": LLVMVERSION=12; GCCVERSION=10; LIBCLC_PACKAGES=["libclc-12-dev"]
elif DIST_VERSION == "Ubuntu_21.10": LLVMVERSION=12; GCCVERSION=11; LIBCLC_PACKAGES=["libclc-12-dev"]
elif DIST_VERSION == "Ubuntu_22.04": LLVMVERSION=14; GCCVERSION=12; LIBCLC_PACKAGES=["libclc-14-dev"]
elif DIST_VERSION == "Ubuntu_22.10": LLVMVERSION=15; GCCVERSION=12; LIBCLC_PACKAGES=["libclc-15-dev"]
elif DIST_VERSION == "Ubuntu_23.04": LLVMVERSION=16; GCCVERSION=13; LIBCLC_PACKAGES=["libclc-16-dev"]
elif DIST_VERSION == "Ubuntu_23.10": LLVMVERSION=16; GCCVERSION=13; LIBCLC_PACKAGES=["libclc-16-dev"]
elif DIST_VERSION == "Ubuntu_24.04": LLVMVERSION=17; GCCVERSION=13; LIBCLC_PACKAGES=["libclc-17-dev"]
elif DIST_VERSION == "Ubuntu_24.10": LLVMVERSION=18; GCCVERSION=14; LIBCLC_PACKAGES=["libclc-18-dev"]
elif DIST_VERSION == "Linuxmint_21.1": LLVMVERSION=15; GCCVERSION=12; LIBCLC_PACKAGES=["libclc-15-dev"]
elif DIST_VERSION == "Linuxmint_21.2": LLVMVERSION=15; GCCVERSION=12; LIBCLC_PACKAGES=["libclc-15-dev"]
elif DIST_VERSION == "Pop_22.04": LLVMVERSION=15; GCCVERSION=12; LIBCLC_PACKAGES=["libclc-15-dev"]
else:
print(f"Warning: Distribution '{DIST_VERSION}' is not supported by this script")
LLVMVERSION = 13
GCCVERSION = 12
if args.llvm != "auto":
LLVMVERSION = args.llvm
LIBCLC_PACKAGES = [f"libclc-{args.llvm}-dev"]
LLVMVERSION = str(LLVMVERSION)
# Main Mesa dependencies which we will install both on amd64 and i386
#
# wayland-protocols is :all, and dpkg will install no issues.
# But bison, flex, pkg-config, glslang-tools we only want amd64 for build.
#
# We keep the order in the list same as Meson configure output.
MAINDEPS = [
# "linux-libc-dev", # Probably will be pulled by gcc & co.
# linux-libc-dev is not libc-dev. It has Linux kernel headers,
# for use by userspace, 'uapi'.
"libvdpau-dev",
"libvulkan-dev",
# "glslang-tools", # We only want to install amd64 binary version.
# "libxvmc-dev",
"libxv-dev",
"libva-dev",
"zlib1g-dev",
"libzstd-dev",
"libexpat1-dev",
# "libdrm-dev", # We build our own by default now.
# LLVM stuff
"libelf-dev",
"libglvnd-dev",
# "libglvnd-core-dev",
# "bison", # We only want to install amd64 binary version.
# "flex", # We only want to install amd64 binary version.
# "libunwind-dev",
# pkg-config stuff # We install it separately, because it is a bit more complex.
# "libwayland-bin", # For wayland-scanner. Technically dependency of libwayland-dev
# We only want to install amd64 binary version.
"wayland-protocols",
"libwayland-dev",
"libwayland-egl-backend-dev",
"libx11-dev",
"libxext-dev",
"libxfixes-dev",
"libxcb-glx0-dev",
"libxcb-shm0-dev",
"libxcb1-dev",
"libx11-xcb-dev",
"libxcb-dri2-0-dev",
"libxcb-dri3-dev",
"libxcb-present-dev",
"libxcb-sync-dev",
"libxcb-keysyms1-dev", # Optional, not sure what is this for, but maybe for GALLIUMHUD hotkeys?
"libxshmfence-dev",
"x11proto-dev", # For glproto and dri2proto. Technically dependency of other libx* packages.
"libxxf86vm-dev",
"libxcb-xfixes0-dev",
"libxcb-randr0-dev",
"libxrandr-dev",
# "libxdamage-dev", # I do not see it Meson output, and I do not think is needed. Debian Build-Depends has it.
"libxcb-sync-dev", # I don't see it Meson output, but it is in Debian Build-Depends.
"libsensors-dev",
# libdrm dependencies from Debian.
#
# minus some that can be 64-bit,
# minus valgrind, minus quilt (debian specific patching) and xsltproc (docs).
# "meson", "quilt", "xsltproc",
"libx11-dev",
# "pkg-config",
# "xutils-dev", # X Window System utility programs for development # We can use 64-bit version for 32-bit.
"libudev-dev",
"libpciaccess-dev",
# "python3-docutils",
# "valgrind",
"libcunit1-dev", # Optional. For libdrm tests.
"liblua5.4-dev", # Optional. Used be Intel and Freedreno for some extra stuff.
]
if USE_SYSTEM_LIBDRM:
MAINDEPS.extend(["libdrm-dev"])
else:
MAINDEPS.extend(["libcairo-dev"]) # for some libdrm tests
MAINDEPS64 = []
MAINDEPS32 = []
for d in MAINDEPS:
assert ":" not in d
MAINDEPS64.append(f"{d}:amd64")
if args.build32:
MAINDEPS32.append(f"{d}:i386")
# For OpenCL support, one might need libclc-dev and libclang-XYZ-dev, to add a parser
# and some passes from LLVM. (See https://libclc.llvm.org for details). This is AFAIK
# for Clover subproject in Mesa, which is disabled, but might go forward, especially
# for Novoue driver, and possibly in the future as a SPIR-V target, which is then
# consumed by LLVM or by ACO, via NIR again.
OPENCL_DEPS = []
if args.buildopencl:
OPENCL_DEPS = [f"libclang-{LLVMVERSION}-dev:amd64", f"libclang-cpp{LLVMVERSION}-dev"]
OPENCL_DEPS.extend(LIBCLC_PACKAGES)
# Polly is optional, but enables various optimisations of OpenCL kernels
OPENCL_DEPS += [f"libpolly-{LLVMVERSION}-dev:amd64"]
# if args.builds32:
# # https://bugs.debian.org/1055371
# OPENCL_DEPS.extend([f"libpolly-{LLVMVERSION}-dev:i386"])
if args.apt_auto:
maybeprint()
if USE_SYSTEM_LIBDRM:
print("Ensuring dependencies for Mesa (and libdrm) build are installed ...")
else:
print("Ensuring dependencies for Mesa build are installed ...")
maybeprint()
ALL_PACKAGES = [
"mesa-utils", # for glxinfo
"vulkan-tools", # for vkcube
"git",
"ca-certificates", # for git, just in case, because it is only in Recommends, and is not in base system
f"gcc-{GCCVERSION}",
f"g++-{GCCVERSION}",
# "gcc", "g++", # for vkpipeline-db, otherwise cmake has issues.
"pkg-config",
"meson",
"ninja-build",
# "cmake", # for vkpipeline-db
"gettext",
"python3",
"python3-setuptools",
"python3-mako",
"valgrind",
"bison",
"flex",
"dpkg-dev", # is needed by multi-arch-aware pkg-config when cross-compiling
"glslang-tools",
*OPENCL_DEPS,
"xutils-dev:amd64", # for libdrm, but these are build utilities, only need amd64 version.
"bindgen", # rust ffi via C and C++. For building rusticl OpenCL stuff
"cbindgen", # Generates C bindings from Rust code - used by src/nouveau/nil/
"rustfmt",
"librust-paste-dev",
"librust-syn-dev",
]
if args.build64:
ALL_PACKAGES.extend([
*MAINDEPS64,
])
if args.build32:
ALL_PACKAGES.extend([
f"gcc-{GCCVERSION}-i686-linux-gnu",
f"g++-{GCCVERSION}-i686-linux-gnu",
*MAINDEPS32,
])
if args.buildopencl:
if LLVMVERSION == "11":
if args.build64:
ALL_PACKAGES.append("libllvmspirvlib-dev:amd64")
if args.build32:
ALL_PACKAGES.append("libllvmspirvlib-dev:i386")
elif LLVMVERSION == "13":
if args.build32:
ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:amd64")
# if args.build32:
# ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:i386")
elif LLVMVERSION == "14":
if args.build64:
ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:amd64")
if args.build32:
if DIST_VERSION not in {"Ubuntu_22.04", "Linuxmint_21.1", "Pop_22.04"}:
ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:i386")
else:
if args.build64:
ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:amd64")
ALL_PACKAGES.append(f"llvm-spirv-{LLVMVERSION}:amd64")
if args.build32:
ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:i386")
if args.wayland:
ALL_PACKAGES.extend([
"wayland-protocols",
"libwayland-bin",
])
# Install directx-headers-dev for amd64 only for now.
# Note: We need glslangValidator to compile trivial GLSL code into SPV for Vulkan Mesa overlay.
# Compilers and cross compilers. Will automatically install binutils (for ar, strip, etc.).
sudo(APT_INSTALL + ALL_PACKAGES)
# Allow installation of directx-headers-dev:amd64 to fail.
# It is now in testing (bookworm) and unstable, as of 2022-02-08.
# It is also in current stable (since release of bookworm, middle 2023).
# TODO: So maybe test with it included unconditionally.
if args.apt_auto:
if not sudo(APT_INSTALL + ["directx-headers-dev:amd64"], check=False):
print("Warning: Can not install directx-headers-dev:amd64. Consider switching to Debian unstable / Debian bookworm to get it.")
if not USE_SYSTEM_LIBDRM:
# TODO(baryluk): Separate dependencies for libdrm. I.e. xutils-dev:amd64, and libpciaccess-dev, libudev-dev.
pass
if args.apt_auto:
maybeprint()
maybeprint()
print(f"Attempting to install llvm{LLVMVERSION} ... If it fails, please read the source code how to add proper repos...")
maybeprint()
maybeprint()
LLVM_PACKAGES = [
f"libllvm{LLVMVERSION}",
f"libllvm{LLVMVERSION}:amd64",
f"llvm-{LLVMVERSION}-dev",
]
LLVM_PACKAGES_DBG=[
f"libllvm{LLVMVERSION}-dbgsym:amd64",
]
if args.build32:
LLVM_PACKAGES += [
f"libllvm{LLVMVERSION}:i386",
# f"llvm-{LLVMVERSION}:i386",
]
LLVM_PACKAGES_DBG += [
f"libllvm{LLVMVERSION}-dbgsym:i386",
]
sudo(APT_INSTALL + LLVMREPO + LLVM_PACKAGES)
if not sudo(APT_INSTALL + LLVMREPO + LLVM_PACKAGES_DBG, check=False):
print("Warning: Can't install debug symbols. Enable them: https://wiki.debian.org/HowToGetABacktrace")
# No need to install pkg-config:i386, it would conflict with pkg-config:amd64.
# Debian's pkg-config will automatically create symlinks to all supported
# archs to proper wrapper that sets proper paths.
# A 32-bit version of pkg-config, that actually is a wrapper, that knows how to
# filter various libraries and multiple versions of them.
# removes pkg-config:amd64, but kind of fine for a moment. We still can use the
# properly prefixed versions all the time!
GIT_QUIET_ARG = ["--quiet"] if args.quiet else []
if not USE_SYSTEM_LIBDRM:
maybeprint()
print("Checking libdrm git repo ...")
maybeprint()
if not os.path.exists(SOURCEDIR_LIBDRM):
if args.git_depth != "":
GIT_DEPTH_ARG = [f"--depth={args.git_depth}"]
if args.git_branch_libdrm:
GIT_BRANCH_ARG = [f"--branch={args.git_branch_libdrm}", "--single-branch"]
else:
GIT_BRANCH_ARG = []
run(["git", "clone", *GIT_QUIET_ARG, *GIT_DEPTH_ARG, *GIT_BRANCH_ARG, args.git_repo_libdrm, SOURCEDIR_LIBDRM])
if args.git_branch_libdrm:
run([*NICE, "git", "-C", SOURCEDIR_LIBDRM, "checkout", *GIT_QUIET_ARG, args.git_branch_libdrm])
else:
if args.git_pull:
run([*NICE, "git", "-C", SOURCEDIR_LIBDRM, "pull", *GIT_QUIET_ARG])
else:
print(f"libdrm-git repo already present. To update, use --git-pull=1 option or run \"cd '{SOURCEDIR_LIBDRM}' && git pull\" manually.")
maybeprint()
maybeprint()
print("Checking mesa git repo ...")
maybeprint()
if not os.path.exists(SOURCEDIR_MESA):
if args.git_depth != "":
GIT_DEPTH_ARG = [f"--depth={args.git_depth}"]
if args.git_branch_mesa:
GIT_BRANCH_ARG = [f"--branch={args.git_branch_mesa}", "--single-branch"]
else:
GIT_BRANCH_ARG = []
run(["git", "clone", *GIT_QUIET_ARG, *GIT_DEPTH_ARG, *GIT_BRANCH_ARG, args.git_repo_mesa, SOURCEDIR_MESA])
if args.git_branch_mesa:
run([*NICE, "git", "-C", SOURCEDIR_MESA, "checkout", *GIT_QUIET_ARG, args.git_branch_mesa])
else:
if args.git_pull:
run([*NICE, "git", "-C", SOURCEDIR_MESA, "pull", *GIT_QUIET_ARG])
else:
print(f"mesa-git repo already present. To update, use --git-pull=1 option or run \"cd '{SOURCEDIR_MESA}' && git pull\" manually.")
maybeprint()
# OPENCL_SUPPORT = ["-Dgallium-opencl=icd","-Dopencl-spirv=true"]
# For "-Dopencl-spirv=true". Also in Debian this version is based on LLVM8 at
# the moment.
if args.apt_auto:
# sudo(APT_INSTALL + ["libllvmspirvlib-dev"])
pass
# Required for parsing OpenCL when gallium-opencl is enabled.
# The clang-cpp component can be skipped, but helps with some stuff apparently.
if args.apt_auto:
sudo(APT_INSTALL + [f"libclang-{LLVMVERSION}-dev", f"libclang-cpp{LLVMVERSION}-dev:amd64"])
os.chdir(SOURCEDIR_MESA)
# These are roots of the build and install.
# Actuall build and install will happen in various
# subdirectories, for mesa, libdrm, 32-bit & 64-bit, opt & dbg.
if not args.incremental:
print()
print(f"Cleaning previous build directory {BUILDDIR}")
try:
shutil.rmtree(BUILDDIR)
except FileNotFoundError:
pass
print()
print(f"Cleaning previous install directory {INSTALLDIR}")
try:
shutil.rmtree(INSTALLDIR)
except FileNotFoundError:
pass
print()
COMMON_OPTS = []
COMMON_OPTS_64 = []
COMMON_OPTS_32 = []
MESA_COMMON_OPTS = []
MESA_COMMON_OPTS += (["-Dplatforms=x11,wayland"] if args.wayland else ["-Dplatforms=x11"])
MESA_COMMON_OPTS += [
"-Dgallium-extra-hud=true",
f"-Dvulkan-drivers={args.vulkan_drivers}",
f"-Dgallium-drivers={args.gallium_drivers}",
"-Dshader-cache=enabled",
"-Dvulkan-layers=device-select,overlay,screenshot", # intel-nullhw
"-Dopengl=true",
"-Dgles1=enabled",
"-Dgles2=enabled",
"-Degl=enabled",
"-Dllvm=enabled",
"-Dlmsensors=enabled",
"-Dtools=glsl,nir",
"-Dgallium-vdpau=enabled",
# "-Dgallium-xvmc=enabled",
"-Dgallium-va=enabled",
"-Dglvnd=enabled",
"-Dgbm=enabled",
#"-Dglx=gallium-xlib",
"-Dlibunwind=enabled", # (also need to disable unwind due to multi-arch issues)
"-Dosmesa=true",
"-Dgallium-nine=true",
"-Dvideo-codecs=vc1dec,h264dec,h264enc,h265dec,h265enc,av1dec,av1enc,vp9dec",
"-Dlegacy-x11=dri2",
"-Dteflon=true",
"-Dzstd=enabled",
# "-Dllvm-orcjit=true", # for llvmpipe
# "-Dintel-clc=enabled",
# "-Dintel-rt=enabled",
# "-Dvulkan-beta=true",
# "-Dshared-llvm=disabled", # Causes linking issues on 32-bit with llvm, because of extra linking to libz3.so, which (because we are using 64-bit llvmconfig), uses 64-bit version and fails to link.
# "-Damd-use-llvm=false", # Note, meson.build:1765:4: ERROR: Problem encountered: R600 requires LLVM AMD support.
"-Dspirv-to-dxil=true",
"-Dshader-cache-max-size=8G",
"-Dstatic-libclc=all",
# "-Dopencl-spirv=true", # This option is gone, because Clover was essentially removed from NIR in Mesa. Use Rusticl. # Old comment: Enabled separately only for 64-bit, and not for 32-bit. This is due to multi-arch bug https://bugs.debian.org/1023780
# "-Dgallium-opencl=icd", # This one causes issues on i386. So we enable it later only for amd64.
# "-Dgallium-rusticl=true", # Enabled seaprately only for 64-bit, and not for 32-bit. Various issues. rustc in debian not multi-arch, needing to use rustup, plus complications in spirv-tools and llvm libraries
# "-Dgallium-xa=enabled", # meson.build:680:3: ERROR: Feature gallium-xa cannot be enabled: XA state tracker requires at least one of the following gallium drivers: nouveau, freedreno, i915, svga.
# "-Dsplit-debug=enabled",
]
# TODO(baryluk):
# When doing --gallium-drivers=radeonsi,zink --vulkan-drivers=amd:
# meson.build:709:4: ERROR: Problem encountered: XVMC state tracker requires at least one of the following gallium drivers: r600, nouveau.
# meson.build:880:4: ERROR: Problem encountered: The nine state tracker requires gallium softpipe/llvmpipe.
# meson.build:1975:4: ERROR: Problem encountered: OSMesa gallium requires gallium softpipe or llvmpipe.
# Interesingly enough, "-Dopencl-spirv=true" compiles even without
# libllvmspirvlib-dev installed.
#"-Dintel-clc=enabled" causes issues:
# src/intel/compiler/meson.build:173:2: ERROR: Tried to mix libraries for machines 0 and 1 in target 'intel_clc' This is not possible in a cross build.
# When doing -Dsplit-debug=enabled we got:
# meson.build:934:3: ERROR: Feature split-debug cannot be enabled: split-debug requires the linker argument -Wl,--gdb-index
# When doing -Dgallium-xa=enabled we got:
# meson.build:679:3: ERROR: Feature gallium-xa cannot be enabled: XA state tracker requires at least one of the following gallium drivers: nouveau, freedreno, i915, svga.
# At the moment it is not possible to install valgrind i386 and amd64 at the
# same time in Debian, as it is using monolithic package.
# See https://bugs.debian.org/941160 for details
MESA_COMMON_OPTS_64 = ["-Dvalgrind=enabled"]
MESA_COMMON_OPTS_32 = ["-Dvalgrind=disabled"]
# libdrm also supports valigrind, so also disable it on 32-bit. But support
# of this flag might be removed in the future due to issues:
# https://gitlab.freedesktop.org/mesa/drm/-/issues/63
# Also the value names are different.
LIBDRM_COMMON_OPTS_64 = ["-Dvalgrind=enabled"]
LIBDRM_COMMON_OPTS_32 = ["-Dvalgrind=disabled"]
if args.buildopencl:
# Compile Clover/OpenCL only for 64-bit. 32-bit would require installing
# "libclang1-{LLVMVERSION}:i386", but it removes the
# "libclang1-{LLVMVERSION}:amd64" and header files!
# See https://bugs.debian.org/941755 for details.
MESA_COMMON_OPTS_64 += ["-Dgallium-opencl=icd"]
# Also see https://bugs.debian.org/1023780 about multi-arch issues with spirv-tool
# This option got removed in https://gitlab.freedesktop.org/mesa/mesa/-/commit/80c4ffb61a91ed252d45e38a96e893cec0771940
# https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27783
# Looks like Clover is being slowly removed from Mesa.
# Use Rusticl when possible.
# MESA_COMMON_OPTS_64 += ["-Dopencl-spirv=true"]
# MESA_COMMON_OPTS_32 += ["-Dopencl-spirv=false"]
MESA_COMMON_OPTS_64 += ["-Dgallium-rusticl=true"]
# Building rusticl for i386, requires cross-compiler, but rustc in Debian is
# not multi-arch. Solution is to uninstall rustc and install rustup, then
# manually install rustc. But this still causes issues due to spirv-tools
# and llvm multi-arch problems.
#
# For most practical purposes, 64-bit OpenCL should be enough for most
# people.
# MESA_COMMON_OPTS_32 += ["-Dgallium-rusticl=true"]
# Common opts for 32-bit and 64-bit, for libdrm and Mesa.
# Ones with _OPT suffix are for optimized build, ones with _DBG suffix are for debug build.
COMMON_OPTS_OPT = ["--buildtype=plain"]
COMMON_OPTS_OPT += ["-Db_ndebug=true"]
# If you really care about library size and maybe improve performance by 0.1%,
# enable stripping. We already are compiling with -g0, so stripping will save
# very little, and make stack traces or use in gdb / valgrind way harder.
# COMMON_OPTS_OPT+=("--strip")
#
# We explicitly pass -mfpmath=sse, otherwise when compiling 32-bit version,
# it will use x87 / non-see for almost everything, which is slower, and
# can't be vectorized, even when using -march=native -msse2, etc.
# With -mfpmath=sse, it will use sse and sse2 almost everywhere, modulo
# few places where the calling conventions (i.e. to glibc) requires passing
# stuff on x87 stack / registers.
COMPILERFLAGS_OPT = "-pipe -march=native -O2 -mfpmath=sse"
if args.heavyopt:
nproc = capture(["nproc", "--ignore=2"]).strip()
COMPILERFLAGS_OPT = f"-pipe -march=native -O3 -mfpmath=sse -ftree-vectorize -flto -flto={nproc} -g0 -fno-semantic-interposition"
COMMON_OPTS_OPT += [
f"-Dc_args={COMPILERFLAGS_OPT}",
f"-Dcpp_args=-std=c++17 {COMPILERFLAGS_OPT}",
]
# For i387, one can also use -mpc64, to set the 387 in "reduced precision" mode (32 or 64 bit).
# It could be faster than full 80-bit, but that is anecdotal.
COMMON_OPTS_DBG = ["--buildtype=debug"]
COMMON_OPTS_DBG += ["-Db_ndebug=false"]
#COMMON_OPTS_DBG += ["-Db_sanitize=thread"]
COMPILERFLAGS_DBG = "-pipe -march=native -O1 -mfpmath=sse -ggdb -g3 -gz"
# Note: This is working when doing 'meson configure', but I am not 100% sure
# this is correct when passing everything just to initial 'meson'.
# From testing it appears to be working.
COMMON_OPTS_DBG += [
f"-Dc_args={COMPILERFLAGS_DBG}",
f"-Dcpp_args=-std=c++17 {COMPILERFLAGS_DBG}",
]
# "-Db_sanitize=thread"
# Build tests.
# MESA_COMMON_OPTS += ["-Dbuild-tests=true"]
# -Ddri-drivers=r100,r200,swrast # Note that dri swrast, is different than gallium
# swrast. It is older rasterizer. the softpipe, llvmpipe are newer ones.
# TODO(baryluk): Add option to build with clang, and with thread / address
# sanitizers.
# Even if we do not build 32-bit version, prepare the cross-file anyway.
# This simplifies a bit of scripting.
# Also by BUILDDBG we could theoretically build optimized libdrm, and
# debug mesa, but that is kind of pointless, often you want debug in drm
# too, and it will perform well anyway one way or another.
if not os.path.exists(f"{SOURCEDIR_MESA}/llvm.ini") or not args.incremental:
with open(f"{SOURCEDIR_MESA}/llvm.ini", "w") as f:
print(f"""
[binaries]
c = '/usr/bin/x86_64-linux-gnu-gcc-{GCCVERSION}'
cpp = '/usr/bin/x86_64-linux-gnu-g++-{GCCVERSION}'
llvm-config = '/usr/bin/llvm-config-{LLVMVERSION}'
strip = '/usr/bin/x86_64-linux-gnu-strip'
""", file=f)
if not os.path.exists(f"{SOURCEDIR_MESA}/meson-cross-i386.ini") or not args.incremental:
with open(f"{SOURCEDIR_MESA}/meson-cross-i386.ini", "w") as f:
print(f"""
[binaries]
c = '/usr/bin/i686-linux-gnu-gcc-{GCCVERSION}'
cpp = '/usr/bin/i686-linux-gnu-g++-{GCCVERSION}'
ar = '/usr/bin/i686-linux-gnu-gcc-ar-{GCCVERSION}'
strip = '/usr/bin/i686-linux-gnu-strip'
pkg-config = '/usr/bin/i686-linux-gnu-pkg-config'
; We are cheating here. We are using 64-bit llvm-config. But we stars align
; it should work (same compiler and linker flags will be used).
llvm-config = '/usr/bin/llvm-config-{LLVMVERSION}'
; llvm-config = '/usr/lib/llvm-{LLVMVERSION}/bin/llvm-config'
rust_ld = '/usr/bin/i686-linux-gnu-gcc-{GCCVERSION}'
rust = ['rustc', '--target', 'i686-unknown-linux-gnu']
; -C linker=gcc -C link-arg=-m32
; set BINDGEN_EXTRA_CLANG_ARGS to either --target=i686-unknown-linux-gnu or -target i686-unknown-linux-gnu
[built-in options]
c_args = ['-m32']
c_link_args = ['-m32']
cpp_args = ['-m32']
cpp_link_args = ['-m32']
[host_machine]
system = 'linux'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'
""", file=f)
# opt / dbg, amd64 / i386
def common_build(BUILD_TYPE: str, ARCHITECTURE: str):
maybeprint()
if USE_SYSTEM_LIBDRM:
print(f"Configuring and building {ARCHITECTURE} {BUILD_TYPE} libdrm and Mesa ...")
else:
print(f"Configuring and building {ARCHITECTURE} {BUILD_TYPE} Mesa ...")
maybeprint()
if BUILD_TYPE == "opt":
COMMON_OPTS_BUILD_TYPE_SPECIFIC = COMMON_OPTS_OPT
elif BUILD_TYPE == "dbg":
COMMON_OPTS_BUILD_TYPE_SPECIFIC = COMMON_OPTS_DBG
else:
raise Exception(f"Unknown BUILD_TYPE passed to common_build: {BUILD_TYPE}")
if ARCHITECTURE == "amd64":
CC = f"gcc-{GCCVERSION}"
CXX = f"g++-{GCCVERSION}"
PKG_CONFIG_ARCH = "x86_64"
# We use the same cross file for libdrm and mesa. But we keep it in Mesa directory only for convinience.
CROSS_FILE = f"{SOURCEDIR_MESA}/llvm.ini"
COMMON_OPTS_ARCH_SPECIFIC = COMMON_OPTS_64
MESA_COMMON_OPTS_ARCH_SPECIFIC = MESA_COMMON_OPTS_64
LIBDRM_COMMON_OPTS_ARCH_SPECIFIC = LIBDRM_COMMON_OPTS_64
elif ARCHITECTURE == "i386":
CC = f"i686-linux-gnu-gcc-{GCCVERSION}"
CXX = f"i686-linux-gnu-g++-{GCCVERSION}"
PKG_CONFIG_ARCH = "i686"
CROSS_FILE = f"{SOURCEDIR_MESA}/meson-cross-i386.ini" # ditto.
COMMON_OPTS_ARCH_SPECIFIC = COMMON_OPTS_32
MESA_COMMON_OPTS_ARCH_SPECIFIC = MESA_COMMON_OPTS_32
LIBDRM_COMMON_OPTS_ARCH_SPECIFIC = LIBDRM_COMMON_OPTS_32
else:
raise Exception(f"Unknown ARCHITECTURE passed to common_build: {ARCHITECTURE}")
# So happens that libdrm and mesa both use meson and ninja, and we should be
# able to use same options and techiniques for both.
# We just separate the some mesa-specific meson options into MESA_COMMON_OPTS
# now.
# We set same --prefix for both libdrm and mesa, that makes it easier later
# to use pkgconfig, and setup LD_LIBRARY_PATH in general.
PREFIX = f"{INSTALLDIR}/build-{ARCHITECTURE}-{BUILD_TYPE}/install"
assert not PREFIX.endswith("/")
env2 = dict(os.environ)
env2["CC"] = CC
env2["CXX"] = CXX
env2["PKG_CONFIG"] = f"{PKG_CONFIG_ARCH}-linux-gnu-pkg-config"
if not USE_SYSTEM_LIBDRM:
maybeprint()
print(f"libdrm: Configuring and building {ARCHITECTURE} {BUILD_TYPE} build ...")
maybeprint()
os.chdir(SOURCEDIR_LIBDRM)
BUILDDIR_LIBDRM = f"{BUILDDIR}/build-{ARCHITECTURE}-{BUILD_TYPE}/libdrm"
# At the moment we do not have LIBDRM_COMMON_OPTS (i.e. to select libdrm features or drivers to build).
# libdrm even with everything enabled build so fast, that there is really no point to exclude things (like vmwgfx API or Nouveau API).
if not os.path.exists(f"{BUILDDIR_LIBDRM}/build.ninja") or not args.incremental:
run([*NICE,
"meson", "setup", f"{BUILDDIR_LIBDRM}/",
f"--prefix={PREFIX}",
f"--cross-file={CROSS_FILE}",
"-Dtests=false",
*COMMON_OPTS,
*COMMON_OPTS_ARCH_SPECIFIC,
*COMMON_OPTS_BUILD_TYPE_SPECIFIC,
*LIBDRM_COMMON_OPTS_ARCH_SPECIFIC], env=env2)
# run(NICE + ["meson", "configure", f"{BUILDDIR_LIBDRM}/"] + COMMON_OPTS + COMMON_OPTS_ARCH_SPECIFIC + COMMON_OPTS_BUILD_TYPE_SPECIFIC + LIBDRM_COMMON_OPTS_ARCH_SPECIFIC])
run(NICE + ["ninja", "--quiet", "-C", f"{BUILDDIR_LIBDRM}/"])
print(f"libdrm: Installing {ARCHITECTURE} {BUILD_TYPE} build ...")
run(NICE + ["ninja", "--quiet", "-C", f"{BUILDDIR_LIBDRM}/", "install"])
# Now libdrm is installed, we need to tell PKG_CONFIG to also look for the
# extra .pc files in the installed directory.
# Note: This only prepends extra paths. Default paths will still be searched after it.
# We do not use 'export' and pass it as env variable to meson instead
# (probably not needed to pass it to ninja).
PKG_CONFIG_PATH = f"{PREFIX}/lib/pkgconfig"
else:
PKG_CONFIG_PATH = None
maybeprint()
print(f"mesa: Configuring and building {ARCHITECTURE} {BUILD_TYPE} build ...")
maybeprint()
os.chdir(SOURCEDIR_MESA)
BUILDDIR_MESA = f"{BUILDDIR}/build-{ARCHITECTURE}-{BUILD_TYPE}/mesa"
# if ARCHITECTURE == "i386":
# PKG_CONFIG_PATH = f"/usr/lib/i386-linux-gnu/pkgconfig:{PKG_CONFIG_PATH}" if PKG_CONFIG_PATH else "/usr/lib/i386-linux-gnu/pkgconfig"
if PKG_CONFIG_PATH is not None:
env2["PKG_CONFIG_PATH"] = PKG_CONFIG_PATH
if not os.path.exists(f"{BUILDDIR_MESA}/build.ninja") or not args.incremental:
run([*NICE,
"meson", "setup", f"{BUILDDIR_MESA}/",
f"--prefix={PREFIX}",
f"--cross-file={CROSS_FILE}",
*COMMON_OPTS,
*MESA_COMMON_OPTS,
*COMMON_OPTS_ARCH_SPECIFIC,
*COMMON_OPTS_BUILD_TYPE_SPECIFIC,
*MESA_COMMON_OPTS_ARCH_SPECIFIC], env=env2)
# run(NICE + ["meson", "configure", f"{BUILDDIR_MESA}/", *COMMON_OPTS, *MESA_COMMON_OPTS, *COMMON_OPTS_ARCH_SPECIFIC, *COMMON_OPTS_BUILD_TYPE_SPECIFIC, *MESA_COMMON_OPTS_ARCH_SPECIFIC])
run(NICE + ["ninja", "--quiet", "-C", f"{BUILDDIR_MESA}/"])
print(f"mesa: Installing {ARCHITECTURE} {BUILD_TYPE} build ...")
run(NICE + ["ninja", "--quiet", "-C", f"{BUILDDIR_MESA}/", "install"])
if args.build64:
if args.buildopt:
common_build("opt", "amd64")
if args.builddebug:
common_build("dbg", "amd64")
if args.build32:
# ar is symlink to x86_64-linux-gnu-ar
# gcc-ar is symlink to gcc-ar-10, and it is symlink to x86_64-linux-gnu-gcc-ar-10
if args.buildopt:
common_build("opt", "i386")
if args.builddebug:
common_build("dbg", "i386")
maybeprint()
print("Generating source files with environmental variable overrides ...")
maybeprint()
def chmodx(filename):
os.chmod(filename, mode=0o755) # -rwxr-xr-x
def generate_wrapper_files(BUILD_TYPE: str) -> None:
assert BUILD_TYPE in {"opt", "dbg"}
LD_LIBRARY_PATH = []
LIBGL_DRIVERS_PATH = []
VK_LAYER_PATH = []
VK_ICD_FILENAMES = []
OCL_ICD_VENDORS = []
LIBVA_DRIVERS_PATH = []
PATH_EXTRA = []
if args.build64:
LD_LIBRARY_PATH.append(f"{INSTALLDIR}/build-amd64-{BUILD_TYPE}/install/lib")
LD_LIBRARY_PATH.append(f"{INSTALLDIR}/build-amd64-{BUILD_TYPE}/install/lib/vdpau")
LIBGL_DRIVERS_PATH.append(f"{INSTALLDIR}/build-amd64-{BUILD_TYPE}/install/lib/dri")
VK_LAYER_PATH.append(f"{INSTALLDIR}/build-amd64-{BUILD_TYPE}/install/share/vulkan/explicit_layer.d")
VK_ICD_FILENAMES.append(f"{INSTALLDIR}/build-amd64-{BUILD_TYPE}/install/share/vulkan/icd.d/radeon_icd.x86_64.json")
VK_ICD_FILENAMES.append(f"{INSTALLDIR}/build-amd64-{BUILD_TYPE}/install/share/vulkan/icd.d/lvp_icd.x86_64.json")
OCL_ICD_VENDORS.append(f"{INSTALLDIR}/build-amd64-{BUILD_TYPE}/install/etc/OpenCL/vendors/mesa.icd")
LIBVA_DRIVERS_PATH.append(f"{INSTALLDIR}/build-amd64-{BUILD_TYPE}/install/lib/dri")
PATH_EXTRA.append(f"{INSTALLDIR}/build-amd64-{BUILD_TYPE}/install/bin")
if args.build32:
LD_LIBRARY_PATH.append(f"{INSTALLDIR}/build-i386-{BUILD_TYPE}/install/lib")
LD_LIBRARY_PATH.append(f"{INSTALLDIR}/build-i386-{BUILD_TYPE}/install/lib/vdpau")
LIBGL_DRIVERS_PATH.append(f"{INSTALLDIR}/build-i386-{BUILD_TYPE}/install/lib/dri")
VK_LAYER_PATH.append(f"{INSTALLDIR}/build-i386-{BUILD_TYPE}/install/share/vulkan/explicit_layer.d")
VK_ICD_FILENAMES.append(f"{INSTALLDIR}/build-i386-{BUILD_TYPE}/install/share/vulkan/icd.d/radeon_icd.i686.json")
VK_ICD_FILENAMES.append(f"{INSTALLDIR}/build-i386-{BUILD_TYPE}/install/share/vulkan/icd.d/lvp_icd.i686.json")
OCL_ICD_VENDORS.append(f"{INSTALLDIR}/build-i386-{BUILD_TYPE}/install/etc/OpenCL/vendors/mesa.icd")
LIBVA_DRIVERS_PATH.append(f"{INSTALLDIR}/build-i386-{BUILD_TYPE}/install/lib/dri")
PATH_EXTRA.append(f"{INSTALLDIR}/build-i386-{BUILD_TYPE}/install/bin")
with open(f"{HOME}/enable-new-mesa-{BUILD_TYPE}.source", "w") as f:
print(f"""#!/bin/sh
# Do not execute this file in your shell, instead "source" it using:
# . ~/enable-new-mesa-{BUILD_TYPE}.source
# or
# source ~/enable-new-mesa-{BUILD_TYPE}.source
#
# This will have effects only once in the current shell. It will not apply to
# other shells, terminals, users, whole desktop, other running programs, or once
# you close this shell, logout, reboot, etc. It is temporary.
#
# If you want you get remove eventually. It will be regenerated every time you
# run "mesa-build.sh" script to build new Mesa.
echo "Warning: Will remove existing LD_LIBRARY_PATH." >&2
export LD_LIBRARY_PATH="{':'.join(LD_LIBRARY_PATH)}"
export LIBGL_DRIVERS_PATH="{':'.join(LIBGL_DRIVERS_PATH)}"
export VK_LAYER_PATH="{':'.join(VK_LAYER_PATH)}:/usr/share/vulkan/explicit_layer.d"
export VK_ICD_FILENAMES="{':'.join(VK_ICD_FILENAMES)}"
export OCL_ICD_VENDORS="{':'.join(OCL_ICD_VENDORS)}"
export LIBVA_DRIVERS_PATH="{':'.join(LIBVA_DRIVERS_PATH)}"
export PATH="{':'.join(PATH_EXTRA)}:${{PATH}}"
export VK_INSTANCE_LAYERS=VK_LAYER_MESA_overlay
# To enable frametime outputs uncommend next line. It requires modified Mesa.
#export VK_LAYER_MESA_OVERLAY_CONFIG=output_relative_time,fps,frame,frame_timing,gpu_timing,pipeline_graphics,graph_y_zero,output_csv=0,output_per_frame=1,output_flush=0,position=top-right,width=300,output_file=/tmp/mesa_overlay_%T_%p.txt
# This uses some extra modified features, but they will only produce warnings in
# normal Mesa.
# export VK_LAYER_MESA_OVERLAY_CONFIG=output_relative_time,fps,frame,frame_timing,gpu_timing,pipeline_graphics,graph_y_zero,output_csv=0,output_per_frame=1,output_flush=0,position=top-right,width=300
export VK_LAYER_MESA_OVERLAY_CONFIG=fps,frame,frame_timing,gpu_timing,pipeline_graphics,position=top-right,width=300
export GALLIUM_HUD=fps
export DXVK_HUD=full
# If one wishes to use exported dev files, one can use /home/user/mesa/build-i386/install/lib/pkgconfig
# And possible /home/user/mesa/build-i386/install/include , for some state trackers, vulkan_intel.h,
# GL, GLEX, KHR headers.
# Enable NV_mesh_shader
export RADV_PERFTEST=nv_ms
""", end="", file=f)
with open(f"{HOME}/mesa-{BUILD_TYPE}", "w") as f:
print(f"""#!/bin/sh
# We keep the existing LD_LIBRARY_PATH and VK_LAYER_PATH, and not erase it unconditionally.
# This is beacuse user might have other libs and layers installed, and want to use them.
# Also, a steam often will provide its own very verbose LD_LIBRARY_PATH to own runtime libraries,
# and they might be required for games to work properly.
export LD_LIBRARY_PATH="{':'.join(LD_LIBRARY_PATH)}:${{LD_LIBRARY_PATH}}"
export LIBGL_DRIVERS_PATH="{':'.join(LIBGL_DRIVERS_PATH)}"
export VK_LAYER_PATH="{':'.join(VK_LAYER_PATH)}:/usr/share/vulkan/explicit_layer.d:${{VK_LAYER_PATH}}"
export VK_ICD_FILENAMES="{':'.join(VK_ICD_FILENAMES)}"
export OCL_ICD_VENDORS="{':'.join(OCL_ICD_VENDORS)}"
export LIBVA_DRIVERS_PATH="{':'.join(LIBVA_DRIVERS_PATH)}"
export PATH="{':'.join(PATH_EXTRA)}:${{PATH}}"
# Enable NV_mesh_shader
export RADV_PERFTEST=nv_ms
# TODO(baryluk): If the path has no "/", maybe use 'env'?
#if which gamemoderun >/dev/null; then
# exec env gamemoderun "$@"
#else
exec env "$@"
#fi
""", end="", file=f)
chmodx(f"{HOME}/mesa-{BUILD_TYPE}")
# A handy wrapper to run with zink.
with open(f"{HOME}/zink-{BUILD_TYPE}", "w") as f:
print(f"""#!/bin/sh
exec env MESA_LOADER_DRIVER_OVERRIDE=zink "${{HOME}}/mesa-{BUILD_TYPE}" "$@"
""", end="", file=f)
chmodx(f"{HOME}/zink-{BUILD_TYPE}")
if args.buildopt:
generate_wrapper_files("opt")
if args.builddebug:
generate_wrapper_files("dbg")
with open(f"{HOME}/disable-new-mesa-hud.source", "w") as f:
print("""#!/bin/sh
unset DXVK_HUD
unset GALLIUM_HUD
unset VK_LAYER_MESA_OVERLAY_CONFIG
unset VK_INSTANCE_LAYERS
""", end="", file=f)
if "DISPLAY" in os.environ:
maybeprint()
print("Testing installation ...")
maybeprint()
if args.buildopt:
runner = f"{HOME}/mesa-opt"
else:
assert args.buildebug
runner = f"{HOME}/mesa-dbg"
test_env = dict(os.environ)
glxinfo = capture([runner, "glxinfo"], env=test_env)
if not glxinfo:
maybeprint()
print("glxinfo failed! Bad installation of DRI, gallium or other component.", file=sys.stderr)
maybeprint()
# See https://gitlab.freedesktop.org/mesa/mesa/-/issues/4236 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96817#c17 for details.
# sys.exit(2)
print("\n".join(grep(glxinfo, "OpenGL renderer string")))
if "OpenGL renderer string" not in glxinfo:
raise Exception("glxinfo failed")
vulkaninfo = capture([runner, "vulkaninfo"], env=test_env)
print("\n".join(grep(vulkaninfo, "GPU id")))
# test_env["RADV_DEBUG"] = "llvm"
# vulkaninfo_llvm = capture([runner, "vulkaninfo"], env=test_env)
# print("\n".join(grep(vulkaninfo_llvm, "GPU id")))
test_env.update({"VK_INSTANCE_LAYERS": "VK_LAYER_MESA_overlay"})
if not run([runner, "vkcube", "--c", "60"], env=test_env):
maybeprint()
print("vkcube failed! Bad installation of vulkan drivers or Mesa overlay layer.", file=sys.stderr)
maybeprint()
# sys.exit(2)
# export VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation
else:
maybeprint()
print("Skipping testing because we are running headless (no X server running?)")
maybeprint()
# Testing SSE, AVX support:
# $ objdump -d "${INSTALLDIR}/install-amd64-opt/install/lib/libvulkan_radeon.so" | grep %ymm | wc -l
# 12225
# $ objdump -d "${INSTALLDIR}/install-amd64-opt/install/lib/libvulkan_radeon.so" | grep %xmm | wc -l
# 41859
# $ objdump -d "${INSTALLDIR}/install-amd64-opt/install/lib/libvulkan_radeon.so" | grep %ymm | grep %xmm | wc -l
# 966
# $
# Good.
# $ objdump -d "${INSTALLDIR}/install-i386-opt/install/lib/libvulkan_radeon.so" | grep %xmm | wc -l
# 0
# $
# BAD.
#cd $HOME && git clone git://anongit.freedesktop.org/mesa/rbug-gui rbug-gui
#sudo([*APT_INSTALL, "libgtkgl2.0-dev", "libgtkglext1-dev"])
#sudo(["apt-get", "clean"])
print()
print("Build complete and passed basic tests!")
print("Execute one of the following shell commands to enable proper Mesa")
print("library paths and variables in the current shell:")
if args.buildopt:
maybeprint()
print(f". \"{HOME}/enable-new-mesa-opt.source\" # Optimized Mesa build")
if args.builddebug:
maybeprint()
print(f". \"{HOME}/enable-new-mesa-dbg.source\" # Debug Mesa build")
print()
maybeprint()
print("To disable GALLIUM_HUD , DXVK_HUD and MESA_OVERLAY execute (AFTER above):")
print(f". \"{HOME}/disable-new-mesa-hud.source\"")
print()
maybeprint()
print("Alternative run your application with one of these wrapper scripts:")
maybeprint()
if args.buildopt:
print(f"{HOME}/mesa-opt")
print(f"{HOME}/zink-opt")
maybeprint()
if args.builddebug:
print(f"{HOME}/mesa-dbg")
print(f"{HOME}/zink-dbg")
maybeprint()
maybeprint()
print("All generated scripts use absolute paths, so you can move / relocate them")
print("as you wish (i.e. into your PATH, like ~/bin, or ~/.local/bin). Or safely remove.")
maybeprint()
maybeprint()
maybeprint("Bye!")
@compellingbytes
Copy link

Hi,
Are the Intel drivers included with this build script?

@kofredwan13
Copy link

Hi,
Current mesa-git requires llvm version >= 15.0.0. After adjusting, it built nicely for both amd64 and i386 architectures in my Debian 12 Bookworm system. Would you please make LLVMVERSION=15 default for Debian bookworm? Also add Python3-docutils as dependency otherwise build failes at doc generation step. Thanks for this awesome script.

@serhii-nakon
Copy link

Hello,
@baryluk I added minor fixes and improvements, here is patch

diff --git a/mesa-build.py b/mesa-build.py
index ea7e240..3a96b09 100644
--- a/mesa-build.py
+++ b/mesa-build.py
@@ -188,12 +188,12 @@ args = parser.parse_args()
 assert len(set([HOME, SOURCEDIR_MESA, SOURCEDIR_LIBDRM, BUILDDIR, INSTALLDIR])) == 5, "All used directories must be unique"
 
 def maybeprint(*print_args):
-    if not args.quiet:
+    if not args.quiet or args.debug:
         print(*print_args)
 
 def run(cmd_args, *, env = None, check: bool = True) -> bool:
     print("Running", *cmd_args)
-    if args.quiet:
+    if args.quiet and not args.debug:
         p = subprocess.run(cmd_args, stdout=subprocess.DEVNULL, env=env)
     else:
         p = subprocess.run(cmd_args, env=env)
@@ -252,7 +252,7 @@ def sudo(cmd_args):
     return run(SUDO + cmd_args, env=new_env)
 
 def maybenewline():
-    if not args.quiet:
+    if not args.quiet or args.debug:
         print()
 
 if args.apt_auto and args.build32:
@@ -493,26 +493,27 @@ if args.apt_auto:
             *MAINDEPS32,
         ])
 
-    if LLVMVERSION == "11":
-        if args.build64:
-            ALL_PACKAGES.append("libllvmspirvlib-dev:amd64")
-        if args.build32:
-            ALL_PACKAGES.append("libllvmspirvlib-dev:i386")
-    elif LLVMVERSION == "13":
-        ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:amd64")
-        # if args.build32:
-        #     ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:i386")
-    elif LLVMVERSION == "14":
-        if args.build64:
+    if args.buildopencl:
+        if LLVMVERSION == "11":
+            if args.build64:
+                ALL_PACKAGES.append("libllvmspirvlib-dev:amd64")
+            if args.build32:
+                ALL_PACKAGES.append("libllvmspirvlib-dev:i386")
+        elif LLVMVERSION == "13":
             ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:amd64")
-        if args.build32:
-            if DIST_VERSION not in {"Ubuntu_22.04", "Linuxmint_21.1", "Pop_22.04"}:
+            # if args.build32:
+            #     ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:i386")
+        elif LLVMVERSION == "14":
+            if args.build64:
+                ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:amd64")
+            if args.build32:
+                if DIST_VERSION not in {"Ubuntu_22.04", "Linuxmint_21.1", "Pop_22.04"}:
+                    ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:i386")
+        else:
+            if args.build64:
+                ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:amd64")
+            if args.build32:
                 ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:i386")
-    else:
-        if args.build64:
-            ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:amd64")
-        if args.build32:
-            ALL_PACKAGES.append(f"libllvmspirvlib-{LLVMVERSION}-dev:i386")
 
     if args.wayland:
         ALL_PACKAGES.extend([
@@ -574,7 +575,7 @@ if args.apt_auto:
 # removes pkg-config:amd64, but kind of fine for a moment. We still can use the
 # properly prefixed versions all the time!
 
-GIT_QUIET_ARG = ["--quiet"] if args.quiet else []
+GIT_QUIET_ARG = ["--quiet"] if args.quiet and not args.debug else []
 
 if not USE_SYSTEM_LIBDRM:
     maybeprint()
@@ -607,7 +608,7 @@ if not os.path.exists(SOURCEDIR_MESA):
     if args.git_depth != "":
         GIT_DEPTH_ARG = [f"--depth={args.git_depth}"]
     if args.git_branch_mesa:
-        GIT_BRANCH_ARG = ["--branch={args.git_branch_mesa}", "--single-branch"]
+        GIT_BRANCH_ARG = [f"--branch={args.git_branch_mesa}", "--single-branch"]
     else:
         GIT_BRANCH_ARG = []
     run(["git", "clone", *GIT_QUIET_ARG, *GIT_DEPTH_ARG, *GIT_BRANCH_ARG, args.git_repo_mesa, SOURCEDIR_MESA])
@@ -1003,6 +1004,7 @@ export LIBGL_DRIVERS_PATH="{INSTALLDIR}/build-amd64-opt/install/lib/dri:{INSTALL
 export VK_LAYER_PATH="{INSTALLDIR}/build-amd64-opt/install/share/vulkan/explicit_layer.d:{INSTALLDIR}/build-i386-opt/install/share/vulkan/explicit_layer.d:/usr/share/vulkan/explicit_layer.d"
 export VK_ICD_FILENAMES="{INSTALLDIR}/build-amd64-opt/install/share/vulkan/icd.d/radeon_icd.x86_64.json:{INSTALLDIR}/build-i386-opt/install/share/vulkan/icd.d/radeon_icd.i686.json:{INSTALLDIR}/build-amd64-opt/install/share/vulkan/icd.d/lvp_icd.x86_64.json:{INSTALLDIR}/build-i386-opt/install/share/vulkan/icd.d/lvp_icd.i686.json"
 export OCL_ICD_VENDORS="{INSTALLDIR}/build-amd64-opt/install/etc/OpenCL/vendors/mesa.icd:{INSTALLDIR}/build-i386-opt/install/etc/OpenCL/vendors/mesa.icd"
+export LIBVA_DRIVERS_PATH="{INSTALLDIR}/build-amd64-opt/install/lib/dri:{INSTALLDIR}/build-i386-opt/install/lib/dri"
 export VK_INSTANCE_LAYERS=VK_LAYER_MESA_overlay
 # To enable frametime outputs uncommend next line. It requires modified Mesa.
 #export VK_LAYER_MESA_OVERLAY_CONFIG=output_relative_time,fps,frame,frame_timing,gpu_timing,pipeline_graphics,graph_y_zero,output_csv=0,output_per_frame=1,output_flush=0,position=top-right,width=300,output_file=/tmp/mesa_overlay_%T_%p.txt
@@ -1035,6 +1037,7 @@ export LIBGL_DRIVERS_PATH="{INSTALLDIR}/build-amd64-opt/install/lib/dri:{INSTALL
 export VK_LAYER_PATH="{INSTALLDIR}/build-amd64-opt/install/share/vulkan/explicit_layer.d:{INSTALLDIR}/build-i386-opt/install/share/vulkan/explicit_layer.d:/usr/share/vulkan/explicit_layer.d:${{VK_LAYER_PATH}}"
 export VK_ICD_FILENAMES="{INSTALLDIR}/build-amd64-opt/install/share/vulkan/icd.d/radeon_icd.x86_64.json:{INSTALLDIR}/build-i386-opt/install/share/vulkan/icd.d/radeon_icd.i686.json:{INSTALLDIR}/build-amd64-opt/install/share/vulkan/icd.d/lvp_icd.x86_64.json:{INSTALLDIR}/build-i386-opt/install/share/vulkan/icd.d/lvp_icd.i686.json"
 export OCL_ICD_VENDORS="{INSTALLDIR}/build-amd64-opt/install/etc/OpenCL/vendors/mesa.icd:{INSTALLDIR}/build-i386-opt/install/etc/OpenCL/vendors/mesa.icd"
+export LIBVA_DRIVERS_PATH="{INSTALLDIR}/build-amd64-opt/install/lib/dri:{INSTALLDIR}/build-i386-opt/install/lib/dri"
 
 # Enable NV_mesh_shader
 export RADV_PERFTEST=nv_ms
@@ -1081,6 +1084,7 @@ export LIBGL_DRIVERS_PATH="{INSTALLDIR}/build-amd64-dbg/install/lib/dri:{INSTALL
 export VK_LAYER_PATH="{INSTALLDIR}/build-amd64-dbg/install/share/vulkan/explicit_layer.d:{INSTALLDIR}/build-i386-dbg/install/share/vulkan/explicit_layer.d:/usr/share/vulkan/explicit_layer.d"
 export VK_ICD_FILENAMES="{INSTALLDIR}/build-amd64-dbg/install/share/vulkan/icd.d/radeon_icd.x86_64.json:{INSTALLDIR}/build-i386-dbg/install/share/vulkan/icd.d/radeon_icd.i686.json:{INSTALLDIR}/build-amd64-dbg/install/share/vulkan/icd.d/lvp_icd.x86_64.json:{INSTALLDIR}/build-i386-dbg/install/share/vulkan/icd.d/lvp_icd.i686.json"
 export OCL_ICD_VENDORS="{INSTALLDIR}/build-amd64-dbg/install/etc/OpenCL/vendors/mesa.icd:{INSTALLDIR}/build-i386-dbg/install/etc/OpenCL/vendors/mesa.icd"
+export LIBVA_DRIVERS_PATH="{INSTALLDIR}/build-amd64-opt/install/lib/dri:{INSTALLDIR}/build-i386-opt/install/lib/dri"
 export VK_INSTANCE_LAYERS=VK_LAYER_MESA_overlay
 # To enable frametime outputs uncommend next line. It requires modified Mesa.
 #export VK_LAYER_MESA_OVERLAY_CONFIG=output_relative_time,fps,frame,frame_timing,gpu_timing,pipeline_graphics,graph_y_zero,output_csv=0,output_per_frame=1,output_flush=0,position=top-right,width=300,output_file=/tmp/mesa_overlay_%T_%p.txt
@@ -1112,6 +1116,7 @@ export LIBGL_DRIVERS_PATH="{INSTALLDIR}/build-amd64-dbg/install/lib/dri:{INSTALL
 export VK_LAYER_PATH="{INSTALLDIR}/build-amd64-dbg/install/share/vulkan/explicit_layer.d:{INSTALLDIR}/build-i386-dbg/install/share/vulkan/explicit_layer.d:/usr/share/vulkan/explicit_layer.d:${{VK_LAYER_PATH}}"
 export VK_ICD_FILENAMES="{INSTALLDIR}/build-amd64-dbg/install/share/vulkan/icd.d/radeon_icd.x86_64.json:{INSTALLDIR}/build-i386-dbg/install/share/vulkan/icd.d/radeon_icd.i686.json:{INSTALLDIR}/build-amd64-dbg/install/share/vulkan/icd.d/lvp_icd.x86_64.json:{INSTALLDIR}/build-i386-dbg/install/share/vulkan/icd.d/lvp_icd.i686.json"
 export OCL_ICD_VENDORS="{INSTALLDIR}/build-amd64-dbg/install/etc/OpenCL/vendors/mesa.icd:{INSTALLDIR}/build-i386-dbg/install/etc/OpenCL/vendors/mesa.icd"
+export LIBVA_DRIVERS_PATH="{INSTALLDIR}/build-amd64-opt/install/lib/dri:{INSTALLDIR}/build-i386-opt/install/lib/dri"
 
 # Enable NV_mesh_shader
 export RADV_PERFTEST=nv_ms

@serhii-nakon
Copy link

Also to every one, you can install latest LLVM packages that prebuilt especially for Debian stable, oldstable, oldoldstable and for Ubuntu releases from official LLVM APT repository https://apt.llvm.org/ (https://llvm.org/)

@baryluk
Copy link
Author

baryluk commented Apr 13, 2024

Hi @compellingbytes

Are the Intel drivers included with this build script?

They were included since the beginning, but...

Unfortunately we needed to disable Intel drivers few weeks ago.

Because their build now requires code generation that uses the built binaries itself, which make cross-compilation impossible, or close to impossible (without rewriting the script entirely probably). Meson people are working on fixing the issue, so the code generation tool can be compiled natively, and run, even if it is also a part of final build and cross compiled, but that MR to do so was open for few years, so I do not expect much progress.

As I only use amd/radv, zink and virtio drivers, I have very little incentive at the moment to address this issue in the script to fix intel drivers. (As it would complicate rest of the script only for this reason)

Sorry.

@baryluk
Copy link
Author

baryluk commented Apr 13, 2024

@serhii-nakon Thank you for spotting bugs and adding LIBVA env vars! I tough I had it before, but apparently the version that had it fixed was lost and never uploaded to gist :D I adjusted your patch as there were some typos in dbg vs opt, but otherwise it looks good.

I added most of your fixes (but not the args.debug changes) to the current script. Looks to be working nicely:

.... # compile
user@debian:~$ ~/mesa-opt vainfo
libva info: VA-API version 1.20.0
libva info: Trying to open /home/user/mesa-git/installdir/build-amd64-opt/install/lib/dri/radeonsi_drv_video.so
libva info: Found init function __vaDriverInit_1_20
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.20 (libva 2.12.0)
vainfo: Driver version: Mesa Gallium driver 24.1.0-devel for AMD Radeon RX 6900 XT (radeonsi, navi21, LLVM 17.0.6, DRM 3.54, 6.6.15-amd64)
....

Thanks again. I mentioned your github loging name in the script for reference as contributor.

@baryluk
Copy link
Author

baryluk commented Apr 13, 2024

Current mesa-git requires llvm version >= 15.0.0. After adjusting, it built nicely for both amd64 and i386 architectures in my Debian 12 Bookworm system.

@kofredwan13 I am not sure how you are building mesa-git with this script on Debian stable, as current mesa git master branch requires newer meson version than is available in a normal Debian bookworm repos. And there are no newer meson in bookworm-backports.

Debian bookworm has 1.0.1-5, but current mesa requires 1.1.0 or newer.

If you already modified environment, to fix that, then you can equally just pass --llvm=15 to the mesa-build.py script, which will override default (of llvm 14), and use llvm 15.

If you could tell me how you get newer meson on Debian stable, then I should be able to test it on Debian stable (in VM for example).

@baryluk
Copy link
Author

baryluk commented Apr 13, 2024

@kofredwan13

Also add Python3-docutils as dependency otherwise build failes at doc generation step.

As of python3-docutils. I am not sure. I just tried this on a fresh minimal (not even standard system tools) install of Debian testing, (after which I needed to install python3 and sudo with no recommended or suggested packages, so truly minimal install). And script worked without needing to use python3-docutils.

Can you still reproduce the issue? (i.e. by removing temporarily python3-docutils` package - as long as it does not break other things for you).

@serhii-nakon
Copy link

@baryluk You can install new meson using pip3 install --break-system-packages meson it will install the latest one.
I forgot to say that better to add into script information that need remove mesa-vdpau packages due some applications like VLC try to load default one and crash but if remove mesa-vdpau it works just fine and use new mesa.

Also I found one problem with this script that I unable to build mesa in i386 environment because it anyway try to install amd64 packages and it problem because LLVM packages in official repository built in way that i386 and amd64 packages use exactly the same directory and file naming - so apt fail to install libllvm:i386 and libllvm:amd64 at the same time. So I used commands from your script to build own Docker container in way to install what need but without suffix like :amd64 or :i386 and it fine works if build it in different environments and than copy libllvm to mesa x86 or x64 directory (so technically I have the newest mesa, libdrm and llvm on Debian stable without tricks and workaround like using unstable repositories). I going to upload this Dockerfiles after simple refactor.

PS: If use Docker you technically can build it on any version of Ubuntu or Debian within few minutes and even test it by adding into container /dev/dri and /dev/kfd and minor group settings.

@baryluk
Copy link
Author

baryluk commented Apr 14, 2024

@serhii-nakon I am, not going to support this configuration in this script. That is not Debian stable. Installing meson this way, or llvm is not supported. If you know what you are doing you you can do it yourself, but this script in this repo does not need to be changed.

I suggest updating to Debian testing if you want to use mesa git.

@serhii-nakon
Copy link

@baryluk OK, I got it.

@redwanwork13
Copy link

@baryluk, I don't know how I missed the --llvm=15 flag. Thanks for pointing this out 😅😅.
As for meson, I had to install meson from testing repo using sudo apt install -t testing meson. Yes, definitely not an ideal thing to do but it did the job in my case.
And as for python3-docutils package, every time it failed to build due to not being able to generate the docs without this package in my Debian Bookworm system. I can't say about Debian testing since currently I don't have any way to test it. I think it uses some scripts provided in python3-docutils package to generate the docs, I really don't understand the details 😕. Anyway, thank you so much for this awesome script, it really helped me a lot 😊

@gremble
Copy link

gremble commented Jun 30, 2024

Default llvm in testing (trixie, future Debian 13), changed to llvm-17. This also means unstable (sid) also will use llvm-17 (previously at llvm-16 in both, because it is not possible to reliably distinguish between testing and unstable from scripts). llvm-17 was in unstable for 2 months, and in testing for about a month. I was using it for 2 months without issues.

Be sure to remove existing ~/mesa-git or pass --incremental=0 on first run after, because meson needs to be rerun with new parameters.

On unstable, after enabling Debian experimental repos, one can try --llvm=18 to force LLVM 18 snapshot pre-release. It will fail for now (due to missing libllvmspirvlib-18-dev, but with some extra hacks, can be bypassed by manually modifying the script a little to not try to install it, as well pass --buildopencl=0 to the script. Expect OpenCL / Clover and OpenGL GL_ARB_gl_spirv extensions to not work - but they are very rarely used).

I might be completely behind the curve here, but I noticed a selection of meson changes in Mesa git recently and tried to build with Open CL and it now appears to work again.

@baryluk
Copy link
Author

baryluk commented Jul 3, 2024

I might be completely behind the curve here, but I noticed a selection of meson changes in Mesa git recently and tried to build with Open CL and it now appears to work again.

Yes, they just fixed one of the reported bugs ( https://gitlab.freedesktop.org/mesa/mesa/-/issues/10674 ) few days ago in https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29646 . I was able to compile OpenCL too.

Thanks.

The Intel drivers cross compilation is still broken tho. And will be disabled for now, until meson gains some better support (there is a bug open on it, and some pull requests sent, but no progress recently). One can still compile Intel by enabling it and only compiling for 64-bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment