4

I need OpenGL 4.5 to be supported by my graphics card's driver, and as far as I know Mesa is actually able to run it.
glxinfo gives me this:

$ glxinfo | grep "OpenGL"
OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) Haswell Mobile 
OpenGL core profile version string: 3.3 (Core Profile) Mesa 13.0.6
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 3.0 Mesa 13.0.6
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 3.1 Mesa 13.0.6
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.10
OpenGL ES profile extensions:

So this means it can only run OpenGL 3.0. So I tried to update it, but I ran into several problems:

If I try to update it through apt, i.e. sudo apt-get upgrade libgl1-mesa-dri -t testing, it is broken:

$ sudo apt-get upgrade libgl1-mesa-dri -t testing
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Calculating upgrade... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 libsnmp30 : Depends: libsensors4 (>= 1:3.0.0) but it is not going to be installed
 mesa-va-drivers : Depends: libsensors4 (>= 1:3.0.0) but it is not going to be installed
 mesa-va-drivers:i386 : Depends: libsensors4:i386 (>= 1:3.0.0) but it is not going to be installed
E: Broken packages

Okay, but:

$ apt-cache policy libsensors4
libsensors4:
  Installed: 1:3.4.0-4
  Candidate: 1:3.4.0-4
  Version table:
 *** 1:3.4.0-4 900
        900 http://ftp.ru.debian.org/debian stretch/main amd64 Packages
        100 /var/lib/dpkg/status

So it depends on the lib version >=1:3.0.0, but I have version 1:3.4.0-4, which is really strange.

Generally, I don't understand how should I upgrade Mesa. If using apt, I don't know which packages should I update. If from source, I don't know how will it interact with apt and if it won't be reverted by an update.

I am using Debian 9 Stretch, and my graphics card is Intel HD Graphics 5000.

0

3 Answers 3

6

Don't try to install testing directly on stable! or you'll end up with a FrankenDebian (at best) or will lose a lot of packages due to unrealistic dependencies.

The good news is that those updated packages are available in stretch-backports. Debian's mesa had several packaging changes in testing so also in stretch-backports, related to the vendor neutral's GL dispatch library turning this non-trivial. Also, since you are using multi-arch with both amd64 and i386 packages, those packages must be upgraded in lockstep or you'll get some of the errors you've seen.

I thus can't tell the exact command on how to upgrade mesa only, without upgrading everything (which you should not do: stretch-backports doesn't have security support) but I will give a procedure.

First please follow Debian's instructions on how to add stretch-backports properly. I'll put a simplified summary here:

# echo 'deb http://deb.debian.org/debian/ stretch-backports main contrib non-free' >> /etc/apt/sources.list.d/stretch-backports.list
# apt-get update

And DO remove buster/testing/sid entries if you added them.

Some packages might have disappeared (eg libgles1-mesa isn't provided anymore) and others appeared. You will have to upgrade all involved packages in one single apt-get command, so you'd first have to look at the most involved packages with their current version, and let the dependency resolver pick the missing parts (eg: libdrm2). You should do things manually, not in a script because you have to check nothing bad happens (like apt-get offering to delete 100 packages). So something like this:

dpkg -l | fgrep 13.0.6-1+b2

or even:

dpkg -l | awk '/^.i/ && $3 == "13.0.6-1+b2" { print $2 }' | xargs

to get the main part of the list of packages. DO NOTE that for installed multi-arch packages you must provide both the amd64 package (which is by default so doesn't require the extra :amd64 but you can leave it from the cut/paste) and again the same i386 package (using :i386 appended to the package name) if it was also found in the previous dpkg command. So the final installation command should probably look like:

apt-get -t stretch-backports install libgl1-mesa-dri:amd64 libgl1-mesa-dri:i386 mesa-opencl-icd:amd64 mesa-opencl-icd:i386 ...

You get the idea. Now check the number of to be removed packages that are offered. If there are some mesa related packages to be removed (eg: libgles1-mesa) that's fine, if most of them or many unrelated packages are offered to be removed, abort and ponder what might be missing. Of course many others should be offered in addition as upgrade (eg: libdrm2 and libdrm2:i386). It's probably those that might still cause trouble because of multi-arch, so you might have to add them manually twice (once for each arch) to the growing one-liner list if apt-get isn't smart enough.

As suggested by @Stephen Kitt, other useful and related packages, dealing with an improved usage of the hardware, including graphics support, are also available in stretch-backports, and should probably also be upgraded. Among them:

  • linux-image-amd64 which will currently pull linux-image-4.19.0-0.bpo.2-amd64
  • Various firmware packages (anyway all those that are currently installed should be upgraded), like firmware-misc-nonfree which might include upgraded graphical support and anyway which might have to be upgraded as a (perhaps hidden) dependency for the newer kernel for best results.
6
  • 3
    See here for a recipe to upgrade all currently installed Mesa packages to the backported version. Mar 29, 2019 at 19:37
  • Thanks. I wonder if my answer is still that useful now
    – A.B
    Mar 29, 2019 at 19:40
  • 1
    Yours explains how to add the backport repo, which is useful. You could also mention that a newer kernel from backports would help too, along with the matching firmware. Mar 29, 2019 at 19:49
  • @StephenKitt Thanks, your solution worked. This answer still can be counted as the correct one since it has the right idea.
    – Verloren
    Mar 29, 2019 at 19:52
  • 1
    @genpfault: you can rebuild packages from Debian unstable source or from Debian git source (or even adapt from upstream source + modified debian/ subdir from previous). As usual you might have to recursively build (build-)dependencies. Some wiki pages (to adapt to the case): BuildingTutorial, SimpleBackportCreation. Someone else might give a better answer in an actual question rather than comment.
    – A.B
    Apr 30, 2022 at 6:33
2

In the event Mesa & co. aren't in backports you can build from source:

Schroot Setup


  1. Host setup:

    sudo apt install --yes schroot debootstrap
    
  2. Make directories for schroots:

    sudo mkdir -p /srv/chroot/debian32
    sudo mkdir -p /srv/chroot/debian64
    
  3. Create & populate config files for schroots:

    # /etc/schroot/chroot.d/debian32.conf
    [debian32]
    description=Debian i386
    directory=/srv/chroot/debian32
    personality=linux32
    type=directory
    users=yourusername
    
    # /etc/schroot/chroot.d/debian64.conf
    [debian64]
    description=Debian amd64
    directory=/srv/chroot/debian64
    personality=linux
    type=directory
    users=yourusername
    
  4. Add /usr/local to /etc/schroot/default/fstab so that the build scripts inside the schroots can install files there:

    /usr/local    /usr/local    none    rw,bind    0    0
    
  5. Populate schroot directories with Debian installs:

    # install debian in schroots
    sudo debootstrap --arch=i386 $(lsb_release --short --codename) /srv/chroot/debian32
    sudo debootstrap --arch=amd64 $(lsb_release --short --codename) /srv/chroot/debian64
    
    # add deb-src lines to sources.list
    echo "deb-src http://deb.debian.org/debian $(lsb_release --short --codename) main" | sudo tee --append /srv/chroot/debian32/etc/apt/sources.list
    echo "deb-src http://deb.debian.org/debian $(lsb_release --short --codename) main" | sudo tee --append /srv/chroot/debian64/etc/apt/sources.list
    
    # install sudo in schroots:
    sudo schroot -c debian32 -- apt install --yes sudo
    sudo schroot -c debian64 -- apt install --yes sudo
    
    # update package lists:
    sudo schroot -c debian32 -- apt update
    sudo schroot -c debian64 -- apt update
    

Compilation


On the host system, clone the source repositories:

# set source directory
export SRC=$HOME/mesa-sources

# install git
sudo apt install --yes git

# these branches/tags Work For Me™ on Debian 11 for a RX 6700 XT.
mkdir -p $SRC && \
cd $SRC && \
git clone --branch 1.20.0         https://gitlab.freedesktop.org/wayland/wayland.git && \
git clone --branch 1.25           https://gitlab.freedesktop.org/wayland/wayland-protocols.git && \
git clone --branch libdrm-2.4.110 https://gitlab.freedesktop.org/mesa/drm.git && \
git clone --branch mesa-22.0.2    https://gitlab.freedesktop.org/mesa/mesa.git && \
git clone --branch 20220411       https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git && \
git clone --branch v5.17.4        https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git $SRC/linux-src/linux

# grab host kernel config
cp /boot/config-$(uname -r) $SRC/linux-src/linux/.config

Then enter each schroot in turn with schroot -c debian32/schroot -c debian64 and do the following:

  1. Install build dependencies:

    sudo apt build-dep --yes wayland wayland-protocols libdrm mesa linux && \
    sudo apt install --yes cmake meson 
    
  2. Set up environment variables:

    export SRC=$HOME/mesa-sources
    export PREFIX=/usr/local
    
  3. Install wayland:

    cd $SRC/wayland && \
    meson build-$HOSTTYPE --prefix=$PREFIX --buildtype=release \
    -D documentation=false && \
    ninja -C build-$HOSTTYPE && sudo ninja -C build-$HOSTTYPE install
    
  4. Install wayland-protocols:

    cd $SRC/wayland-protocols && \
    meson build-$HOSTTYPE --prefix=$PREFIX --buildtype=release && \
    ninja -C build-$HOSTTYPE && sudo ninja -C build-$HOSTTYPE install
    
  5. Install drm:

    cd $SRC/drm && \
    meson build-$HOSTTYPE --prefix=$PREFIX --buildtype=release && \
    ninja -C build-$HOSTTYPE && sudo ninja -C build-$HOSTTYPE install
    
  6. Install mesa:

    cd $SRC/mesa && \
    meson build-$HOSTTYPE --prefix=$PREFIX --buildtype=release \
    -D gallium-vdpau=enabled \
    -D shared-llvm=disabled \
    -D vulkan-layers=device-select,intel-nullhw,overlay && \
    ninja -C build-$HOSTTYPE && sudo ninja -C build-$HOSTTYPE install
    
  7. (64-bit schroot only) Compile kernel (with integrated AMD and Intel GPU firmware):

    # collect firmware
    cd $SRC/linux-firmware && \
    ./copy-firmware.sh $SRC/linux-firmware-bin
    
    # compile linux & generate Debian packages
    cd $SRC/linux-src/linux && \
    ./scripts/config --set-val DEBUG_INFO n && \
    ./scripts/config --set-str EXTRA_FIRMWARE_DIR $SRC/linux-firmware-bin && \
    ./scripts/config --set-str EXTRA_FIRMWARE "$(cd $SRC/linux-firmware-bin; find * -type f | grep -E "amdgpu/|i915/" | paste -sd " " -)" && \
    yes "" | make oldconfig && \
    make -j$(nproc) bindeb-pkg
    

    While compiling in (nearly) all the firmware is technically possible I would recommend against it.

Install Packages On Host


Back on the host system do the following:

  1. Host setup:

    sudo dpkg --add-architecture i386 && \
    sudo apt update && \
    sudo apt install --yes apt-file gcc-multilib && \
    sudo apt-file update
    
  2. Scan /usr/local for missing libraries & install the packages that provide them:

    # 64-bit
    sudo apt install --yes $(\
    find /usr/local/lib/x86_64-linux-gnu/ -type f -exec ldd {} \; | \
    grep "not found" | \
    awk '{print "x86_64-linux-gnu/" $1 "$"}' | \
    sort | uniq | \
    apt-file --regexp --from-file search - | \
    awk -v ORS=" " -F ":" '{print $1}' )
    
    # 32-bit
    sudo apt install --yes $(\
    find /usr/local/lib/i386-linux-gnu/ -type f -exec ldd {} \; | \
    grep "not found" | \
    awk '{print "i386-linux-gnu/" $1 "$"}' | \
    sort | uniq | \
    apt-file --architecture i386 --regexp --from-file search - | \
    awk -v ORS=" " -F ":" '{print $1 ":i386"}' )
    
  3. Install kernel packages:

    # set source directory
    export SRC=$HOME/mesa-sources && \
    sudo dpkg -i $SRC/linux-src/linux-headers-*.deb && \
    sudo dpkg -i $SRC/linux-src/linux-image-*.deb && \
    sudo dpkg -i $SRC/linux-src/linux-libc-dev*.deb
    

System Setup


  1. Add a profile.d script to ensure (most) shells and shell types use the new DRI drivers:

    # /etc/profile.d/local-mesa.sh
    export LIBGL_DRIVERS_PATH=/usr/local/lib/x86_64-linux-gnu/dri:/usr/local/lib/i386-linux-gnu/dri
    
  2. Add a systemd config override so that when KDE's SDDM starts Xorg AIGLX also uses the new DRI drivers:

    # /etc/systemd/system/sddm.service.d/local-mesa.conf
    [Service]
    Environment="LIBGL_DRIVERS_PATH=/usr/local/lib/x86_64-linux-gnu/dri:/usr/local/lib/i386-linux-gnu/dri"
    

    (Greeters from other desktop environments require the same config file in the corresponding service.d directories)

  3. (Optional) Remove old Mesa Vulkan driver:

    sudo apt remove mesa-vulkan-drivers mesa-vulkan-drivers:i386
    

    This prevents the Vulkan loader from picking up the old Debian-provided Vulkan driver files (if any) and possibly returning one of them as the "first" GPU.

    While Mesa does have the MESA_VK_DEVICE_SELECT environment variable to help re-order the device list it only lets you choose a particular PCI device to prioritize, not choose between multiple drivers for the same device. If you want to leave the Debian-provided Vulkan drivers installed and need to choose between them try vkdevicechooser.

  4. Finally, reboot to:

    • Load the new amdgpu kernel module & firmware
    • Refresh the ldconfig cache
    • Force systemd to load the new unit override for SDDM
    • Restart Xorg so it can pick up the new DRI libraries
0

In the event Mesa & co. aren't in backports you can create backported packages yourself:

Setup


  1. Set environment variables:

    # point this somewhere convenient, needs ~23 GiB of space
    export MESA_SRC=$HOME/mesa-backports
    
    # it *is* possible to build mesa with bullseye's llvm-toolchain-11,
    # albeit with a slightly more involved patch for mesa
    export MESA_PACKAGES="\
    wayland \
    wayland-protocols \
    libdrm \
    directx-headers \
    llvm-toolchain-14 \
    mesa \
    firmware-nonfree"
    
  2. Install proot from source (due to bug#1011348):

    sudo apt install curl && \
    sudo apt build-dep proot && \
    mkdir -p $MESA_SRC && cd $MESA_SRC && \
    curl -L "https://github.com/proot-me/proot/archive/refs/tags/v5.3.1.tar.gz" | tar xzf - && \
    cd proot-*/ && 
    make -C src loader.elf loader-m32.elf build.h && \
    make -C src proot && \
    sudo make -C src install 
    

Chroots


  1. Set up i386 & amd64 chroots using mmdebstrap:

    sudo apt install mmdebstrap && \
    time \
    for ARCH in i386 amd64; do \
    mkdir -p $MESA_SRC && cd $MESA_SRC && \
    mmdebstrap --mode=proot --format=directory --arch=$ARCH bullseye debian-$ARCH && \
    proot -S debian-$ARCH apt update && \
    proot -S debian-$ARCH apt install --yes locales eatmydata && \
    proot -S debian-$ARCH sh -c 'echo "en_US.UTF-8 UTF-8" > /etc/locale.gen' && \
    proot -S debian-$ARCH /usr/sbin/locale-gen && \
    proot -S debian-$ARCH eatmydata apt install --yes \
    devscripts equivs local-apt-repository && \
    proot -S debian-$ARCH mkdir -p /srv/local-apt-repository ; \
    done
    

Sources


  1. Add sources for unstable:

    { sudo tee /etc/apt/sources.list.d/unstable-sources.list > /dev/null << HEREDOCDELIM
    deb-src http://deb.debian.org/debian unstable main contrib non-free
    HEREDOCDELIM
    } && \
    sudo apt update
    
  2. Download source packages & update changelogs:

    for PKG in $MESA_PACKAGES; do \
    mkdir -p $MESA_SRC/$PKG && cd $MESA_SRC/$PKG && \
    apt source $PKG/unstable && \
    cd $MESA_SRC/$PKG/$PKG-*/ && \
    DEBFULLNAME="Example User" \
    DEBEMAIL="[email protected]" \
    dch --bpo " " ; \
    done
    
  3. Apply patches:

    cd $MESA_SRC/firmware-nonfree/firmware-nonfree-*/ && \
    { base64 -d << 'HEREDOCDELIM'
    LS0tIGEvZGViaWFuL3J1bGVzCisrKyBiL2RlYmlhbi9ydWxlcwpAQCAtMzgsMTQgKzM4LDYgQEAK
    IAlta2RpciAtcCAkKEBEKQogCXByaW50ZiA+JEAgJ1NvdXJjZTogJXNcblZlcnNpb246ICVzXG4n
    ICQoU09VUkNFKSAkKFZFUlNJT05fU09VUkNFKQogCi1kZWJpYW4vY29udHJvbCBkZWJpYW4vcnVs
    ZXMuZ2VuOiAkKEdFTkNPTlRST0wpICQoQ09OVFJPTF9GSUxFUykKLWlmZXEgKCQod2lsZGNhcmQg
    ZGViaWFuL2NvbnRyb2wubWQ1c3VtKSwpCi0JJChNQUtFKSAtZiBkZWJpYW4vcnVsZXMgZGViaWFu
    L2NvbnRyb2wtcmVhbAotZWxzZQotCW1kNXN1bSAtLWNoZWNrIGRlYmlhbi9jb250cm9sLm1kNXN1
    bSAtLXN0YXR1cyB8fCBcCi0JCSQoTUFLRSkgLWYgZGViaWFuL3J1bGVzIGRlYmlhbi9jb250cm9s
    LXJlYWwKLWVuZGlmCi0KIGRlYmlhbi9jb250cm9sLXJlYWw6ICQoR0VOQ09OVFJPTCkgJChDT05U
    Uk9MX0ZJTEVTKQogIyBXZSBjdXJyZW50bHkgbmVlZCB0byBydW4gY29weS1maXJtd2FyZS5zaCB0
    byBnZXQgYSBjb21wbGV0ZSBsaXN0IG9mCiAjIHN5bWxpbmtzIHRvIGluY2x1ZGUgaW4gcGFja2Fn
    ZSBkZXNjcmlwdGlvbnMuCg==
    HEREDOCDELIM
    } | patch -p1 && \
    cd $MESA_SRC/mesa/mesa-*/ && \
    { base64 -d << 'HEREDOCDELIM'
    LS0tIGEvZGViaWFuL2NvbnRyb2wKKysrIGIvZGViaWFuL2NvbnRyb2wKQEAgLTQxNSw3ICs0MTUs
    NyBAQAogQXJjaGl0ZWN0dXJlOiBhbWQ2NCBhcm02NCBhcm1lbCBhcm1oZiBpMzg2IG1pcHM2NGVs
    IG1pcHNlbCBwb3dlcnBjIHBwYzY0IHBwYzY0ZWwgczM5MHggc3BhcmM2NAogUHJlLURlcGVuZHM6
    ICR7bWlzYzpQcmUtRGVwZW5kc30KIERlcGVuZHM6Ci0gbGliY2xjLTEzLAorIGxpYmNsYy0xNCwK
    ICBvY2wtaWNkLWxpYm9wZW5jbDEgfCBsaWJvcGVuY2wxLAogICR7c2hsaWJzOkRlcGVuZHN9LAog
    ICR7bWlzYzpEZXBlbmRzfSwK
    HEREDOCDELIM
    } | patch -p1
    

    (Apologies for the opaque base64 blobs, the firmware-nonfree patch needed tabs but Markdown code blocks eat tabs and even if you fixed that pasting tab-containing text into a Bash prompt causes it to consume the tabs while trying to tab-complete :()

Build


  1. Build packages (takes ~90 minutes on a 12-core Ryzen 5900x):

    time \
    for ARCH in i386 amd64; do \
    for PKG in $MESA_PACKAGES; do \
    cd $MESA_SRC/$PKG/$PKG-*/ && \
    proot -S $MESA_SRC/debian-$ARCH /usr/lib/local-apt-repository/rebuild && \
    proot -S $MESA_SRC/debian-$ARCH apt update && \
    PATH=/sbin:/usr/sbin:$PATH \
    proot -S $MESA_SRC/debian-$ARCH eatmydata mk-build-deps --install --remove \
    --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' && \
    DEB_BUILD_OPTIONS="nostrip nocheck nodoc noautodbgsym noddebs" \
    DEB_BUILD_PROFILES="nostrip nocheck nodoc noautodbgsym noddebs" \
    proot -R $MESA_SRC/debian-$ARCH dpkg-buildpackage --build=binary -us -uc && \
    proot -S $MESA_SRC/debian-$ARCH cp ../*.deb /srv/local-apt-repository \
    ; done \
    ; done
    
  2. Copy packages into the local-apt-repository package depot (needs ~1 GiB):

    sudo apt install local-apt-repository && \
    sudo mkdir -p /srv/local-apt-repository && \
    for PKG in $MESA_PACKAGES; do \
    sudo cp $MESA_SRC/$PKG/*.deb /srv/local-apt-repository/ \
    ; done && \
    sudo /usr/lib/local-apt-repository/rebuild
    

Upgrade


  1. Upgrade to the new packages:

    sudo apt update && \
    sudo apt upgrade -o Dpkg::Options::="--force-overwrite"
    
  2. Install kernel from backports:

    { sudo tee /etc/apt/sources.list.d/bullseye-backports.list > /dev/null << HEREDOCDELIM
    deb http://deb.debian.org/debian bullseye-backports main
    HEREDOCDELIM
    } && \
    sudo apt update && \
    sudo apt install linux-image-amd64/bullseye-backports
    
  3. Reboot

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .