From 5da892d21cb31f5546b74021026d43f5a6eb5ec2 Mon Sep 17 00:00:00 2001 From: K900 Date: Wed, 5 Mar 2025 11:51:28 +0300 Subject: [PATCH] mesa: output cleanup, part 2 - build with out-of-tree libgbm - $drivers -> $out, since $out is basically empty now --- doc/packages/opengl.section.md | 2 +- nixos/modules/hardware/graphics.nix | 4 +- pkgs/development/libraries/mesa/default.nix | 117 +++-------- .../libraries/mesa/llvmpipe-hook.sh | 6 +- .../libraries/mesa/system-gbm.patch | 195 ++++++++++++++++++ pkgs/top-level/aliases.nix | 2 +- 6 files changed, 236 insertions(+), 90 deletions(-) create mode 100644 pkgs/development/libraries/mesa/system-gbm.patch diff --git a/doc/packages/opengl.section.md b/doc/packages/opengl.section.md index f4d282267a07..581e309909c9 100644 --- a/doc/packages/opengl.section.md +++ b/doc/packages/opengl.section.md @@ -10,6 +10,6 @@ The NixOS desktop or other non-headless configurations are the primary target fo ## Nix on GNU/Linux {#nix-on-gnulinux} -If you are using a non-NixOS GNU/Linux/X11 desktop with free software video drivers, consider launching OpenGL-dependent programs from Nixpkgs with Nixpkgs versions of `libglvnd` and `mesa.drivers` in `LD_LIBRARY_PATH`. For Mesa drivers, the Linux kernel version doesn't have to match nixpkgs. +If you are using a non-NixOS GNU/Linux/X11 desktop with free software video drivers, consider launching OpenGL-dependent programs from Nixpkgs with Nixpkgs versions of `libglvnd` and `mesa` in `LD_LIBRARY_PATH`. For Mesa drivers, the Linux kernel version doesn't have to match nixpkgs. For proprietary video drivers, you might have luck with also adding the corresponding video driver package. diff --git a/nixos/modules/hardware/graphics.nix b/nixos/modules/hardware/graphics.nix index 10a72b423e83..b896abb4685e 100644 --- a/nixos/modules/hardware/graphics.nix +++ b/nixos/modules/hardware/graphics.nix @@ -120,7 +120,7 @@ in { "r" = {}; }; }; - hardware.graphics.package = lib.mkDefault pkgs.mesa.drivers; - hardware.graphics.package32 = lib.mkDefault pkgs.pkgsi686Linux.mesa.drivers; + hardware.graphics.package = lib.mkDefault pkgs.mesa; + hardware.graphics.package32 = lib.mkDefault pkgs.pkgsi686Linux.mesa; }; } diff --git a/pkgs/development/libraries/mesa/default.nix b/pkgs/development/libraries/mesa/default.nix index 476144ae8b8a..c636a32cf13f 100644 --- a/pkgs/development/libraries/mesa/default.nix +++ b/pkgs/development/libraries/mesa/default.nix @@ -13,6 +13,7 @@ , intltool , jdupes , libdrm +, libgbm , libglvnd , libunwind , libva-minimal @@ -139,19 +140,12 @@ in stdenv.mkDerivation { patches = [ ./opencl.patch + ./system-gbm.patch ]; postPatch = '' patchShebangs . - # The drirc.d directory cannot be installed to $drivers as that would cause a cyclic dependency: - substituteInPlace src/util/xmlconfig.c --replace \ - 'DATADIR "/drirc.d"' '"${placeholder "out"}/share/drirc.d"' - substituteInPlace src/util/meson.build --replace \ - "get_option('datadir')" "'${placeholder "out"}/share'" - substituteInPlace src/amd/vulkan/meson.build --replace \ - "get_option('datadir')" "'${placeholder "out"}/share'" - for header in ${toString mesa-gl-headers.headers}; do if ! diff -q $header ${mesa-gl-headers}/$header; then echo "File $header does not match between mesa and mesa-gl-headers, please update mesa-gl-headers first!" @@ -163,8 +157,7 @@ in stdenv.mkDerivation { ''; outputs = [ - "out" "dev" - "drivers" + "out" # OpenCL drivers pull in ~1G of extra LLVM stuff, so don't install them # if the user didn't explicitly ask for it "opencl" @@ -193,7 +186,6 @@ in stdenv.mkDerivation { mesonFlags = [ "--sysconfdir=/etc" - "--datadir=${placeholder "drivers"}/share" # What to build (lib.mesonOption "platforms" (lib.concatStringsSep "," eglPlatforms)) @@ -201,17 +193,10 @@ in stdenv.mkDerivation { (lib.mesonOption "vulkan-drivers" (lib.concatStringsSep "," vulkanDrivers)) (lib.mesonOption "vulkan-layers" (lib.concatStringsSep "," vulkanLayers)) - # Make sure we know where to put all the drivers - (lib.mesonOption "dri-drivers-path" "${placeholder "drivers"}/lib/dri") - (lib.mesonOption "vdpau-libs-path" "${placeholder "drivers"}/lib/vdpau") - (lib.mesonOption "va-libs-path" "${placeholder "drivers"}/lib/dri") - (lib.mesonOption "d3d-drivers-path" "${placeholder "drivers"}/lib/d3d") - - # Set search paths for non-Mesa drivers (e.g. Nvidia) - (lib.mesonOption "gbm-backends-path" "${libglvnd.driverLink}/lib/gbm:${placeholder "out"}/lib/gbm") - # Enable glvnd for dynamic libGL dispatch (lib.mesonEnable "glvnd" true) + (lib.mesonEnable "gbm" true) + (lib.mesonBool "libgbm-external" true) (lib.mesonBool "gallium-nine" false) # Direct3D9 in Wine, largely supplanted by DXVK (lib.mesonBool "osmesa" false) # deprecated upstream @@ -260,6 +245,8 @@ in stdenv.mkDerivation { elfutils expat spirv-tools + libdrm + libgbm libglvnd libunwind libva-minimal @@ -326,109 +313,73 @@ in stdenv.mkDerivation { (buildPackages.mesa.cross_tools or null) ]; - propagatedBuildInputs = [ libdrm ]; - doCheck = false; postInstall = '' - # Move driver-related bits to $drivers - moveToOutput "lib/gallium-pipe" $drivers - moveToOutput "lib/gbm" $drivers - moveToOutput "lib/lib*_mesa*" $drivers - moveToOutput "lib/libgallium*" $drivers - moveToOutput "lib/libglapi*" $drivers - moveToOutput "lib/libpowervr_rogue*" $drivers - moveToOutput "lib/libvulkan_*" $drivers - moveToOutput "lib/libteflon.so" $drivers - - # Update search path used by glvnd (it's pointing to $out but drivers are in $drivers) - for js in $drivers/share/glvnd/egl_vendor.d/*.json; do - substituteInPlace "$js" --replace-fail '"libEGL_' '"'"$drivers/lib/libEGL_" - done - - # And same for Vulkan - for js in $drivers/share/vulkan/icd.d/*.json; do - substituteInPlace "$js" --replace-fail "$out" "$drivers" - done - - # Move Vulkan layers to $drivers and update manifests - moveToOutput "lib/libVkLayer*" $drivers - for js in $drivers/share/vulkan/{im,ex}plicit_layer.d/*.json; do - substituteInPlace "$js" --replace '"libVkLayer_' '"'"$drivers/lib/libVkLayer_" - done - - # Construct our own .icd files that contain absolute paths. - mkdir -p $opencl/etc/OpenCL/vendors/ - echo $opencl/lib/libMesaOpenCL.so > $opencl/etc/OpenCL/vendors/mesa.icd - echo $opencl/lib/libRusticlOpenCL.so > $opencl/etc/OpenCL/vendors/rusticl.icd - moveToOutput bin/intel_clc $cross_tools moveToOutput bin/mesa_clc $cross_tools moveToOutput bin/vtn_bindgen $cross_tools moveToOutput "lib/lib*OpenCL*" $opencl + # Construct our own .icd files that contain absolute paths. + mkdir -p $opencl/etc/OpenCL/vendors/ + echo $opencl/lib/libMesaOpenCL.so > $opencl/etc/OpenCL/vendors/mesa.icd + echo $opencl/lib/libRusticlOpenCL.so > $opencl/etc/OpenCL/vendors/rusticl.icd moveToOutput bin/spirv2dxil $spirv2dxil moveToOutput "lib/libspirv_to_dxil*" $spirv2dxil ''; postFixup = '' - # set the default search path for DRI drivers; used e.g. by X server - for pc in lib/pkgconfig/{dri,d3d}.pc; do - [ -f "$dev/$pc" ] && substituteInPlace "$dev/$pc" --replace "$drivers" "${libglvnd.driverLink}" + # set full path in EGL driver manifest + for js in $out/share/glvnd/egl_vendor.d/*.json; do + substituteInPlace "$js" --replace-fail '"libEGL_' '"'"$out/lib/libEGL_" done - # remove pkgconfig files for GL/EGL; they are provided by libGL. - rm -f $dev/lib/pkgconfig/{gl,egl}.pc + # and in Vulkan layer manifests + for js in $out/share/vulkan/{im,ex}plicit_layer.d/*.json; do + substituteInPlace "$js" --replace '"libVkLayer_' '"'"$out/lib/libVkLayer_" + done + + # remove DRI pkg-config file, provided by dri-pkgconfig-stub + rm -f $out/lib/pkgconfig/dri.pc # remove headers moved to mesa-gl-headers for header in ${toString mesa-gl-headers.headers}; do - rm -f $dev/$header + rm -f $out/$header done - # update symlinks pointing to libgallium in $out - for link in $drivers/lib/dri/*_drv_video.so $drivers/lib/vdpau/*.so.1.0.0; do - ln -sf $drivers/lib/libgallium*.so $link - done + # clean up after removing stuff + find $out -type d -empty -delete # Don't depend on build python patchShebangs --host --update $out/bin/* # NAR doesn't support hard links, so convert them to symlinks to save space. - jdupes --hard-links --link-soft --recurse "$drivers" - - # add RPATH so the drivers can find the moved libgallium and libdricore9 - # moved here to avoid problems with stripping patchelfed files - for lib in $drivers/lib/*.so* $drivers/lib/*/*.so*; do - if [[ ! -L "$lib" ]]; then - patchelf --set-rpath "$(patchelf --print-rpath $lib):$drivers/lib" "$lib" - fi - done + jdupes --hard-links --link-soft --recurse "$out" # add RPATH here so Zink can find libvulkan.so - patchelf --add-rpath ${vulkan-loader}/lib $drivers/lib/libgallium*.so + patchelf --add-rpath ${vulkan-loader}/lib $out/lib/libgallium*.so ''; - env.NIX_CFLAGS_COMPILE = toString ([ - "-UPIPE_SEARCH_DIR" - "-DPIPE_SEARCH_DIR=\"${placeholder "drivers"}/lib/gallium-pipe\"" - ]); - passthru = { inherit (libglvnd) driverLink; inherit llvmPackages; - tests.devDoesNotDependOnLLVM = stdenv.mkDerivation { - name = "mesa-dev-does-not-depend-on-llvm"; + # for compatibility + drivers = lib.warn "`mesa.drivers` is deprecated, use `mesa` instead" mesa; + + tests.outDoesNotDependOnLLVM = stdenv.mkDerivation { + name = "mesa-does-not-depend-on-llvm"; buildCommand = '' - echo ${mesa.dev} >>$out + echo ${mesa} >>$out ''; - disallowedRequisites = [ llvmPackages.llvm mesa.drivers ]; + disallowedRequisites = [ llvmPackages.llvm ]; }; llvmpipeHook = makeSetupHook { name = "llvmpipe-hook"; - substitutions.drivers = mesa.drivers; + substitutions.mesa = mesa; } ./llvmpipe-hook.sh; }; } diff --git a/pkgs/development/libraries/mesa/llvmpipe-hook.sh b/pkgs/development/libraries/mesa/llvmpipe-hook.sh index 6217182b15e8..35979eaa5cb6 100644 --- a/pkgs/development/libraries/mesa/llvmpipe-hook.sh +++ b/pkgs/development/libraries/mesa/llvmpipe-hook.sh @@ -2,13 +2,13 @@ # https://docs.mesa3d.org/envvars.html export LIBGL_ALWAYS_SOFTWARE=true -export LIBGL_DRIVERS_PATH=@drivers@/lib/dri +export LIBGL_DRIVERS_PATH=@mesa@/lib/dri # https://github.com/NVIDIA/libglvnd/blob/master/src/EGL/icd_enumeration.md -export __EGL_VENDOR_LIBRARY_FILENAMES=@drivers@/share/glvnd/egl_vendor.d/50_mesa.json +export __EGL_VENDOR_LIBRARY_FILENAMES=@mesa@/share/glvnd/egl_vendor.d/50_mesa.json # https://github.com/KhronosGroup/Vulkan-Loader/blob/main/docs/LoaderInterfaceArchitecture.md # glob because the filenames contain an architecture suffix # echo is needed to force-expand the glob -VK_DRIVER_FILES="$(echo @drivers@/share/vulkan/icd.d/lvp_icd.*.json)" +VK_DRIVER_FILES="$(echo @mesa@/share/vulkan/icd.d/lvp_icd.*.json)" export VK_DRIVER_FILES diff --git a/pkgs/development/libraries/mesa/system-gbm.patch b/pkgs/development/libraries/mesa/system-gbm.patch new file mode 100644 index 000000000000..7f16ff7469c7 --- /dev/null +++ b/pkgs/development/libraries/mesa/system-gbm.patch @@ -0,0 +1,195 @@ +commit 69914d79c3d86b0aee80665c51074cf8cc55f660 +Author: K900 +Date: 2025-03-05 13:14:02 +0300 + + meson: support building with system libgbm + + This is the next step towards making libgbm just a loader. + +diff --git a/meson.build b/meson.build +index 4766ce838ba..300a6bb0cc8 100644 +--- a/meson.build ++++ b/meson.build +@@ -2377,7 +2377,7 @@ summary(egl_summary, section: 'EGL', bool_yn: true, list_sep: ' ') + + gbm_summary = {'Enabled': with_gbm} + if with_gbm +- gbm_summary += {'Backends path': gbm_backends_path} ++ gbm_summary += {'External libgbm': get_option('libgbm-external'), 'Backends path': gbm_backends_path} + endif + summary(gbm_summary, section: 'GBM', bool_yn: true, list_sep: ' ') + +diff --git a/meson_options.txt b/meson_options.txt +index 2622cf1d235..7bf8ae8a1c5 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -329,6 +329,13 @@ option( + description : 'Build support for gbm platform' + ) + ++option( ++ 'libgbm-external', ++ type: 'boolean', ++ value: false, ++ description: 'Whether to use external libgbm (default: use in-tree copy)' ++) ++ + option( + 'gbm-backends-path', + type : 'string', +diff --git a/src/egl/meson.build b/src/egl/meson.build +index a02b83419c4..ae4b0c5e063 100644 +--- a/src/egl/meson.build ++++ b/src/egl/meson.build +@@ -108,9 +108,8 @@ if with_dri + endif + if with_gbm and not with_platform_android + files_egl += files('drivers/dri2/platform_drm.c') +- link_for_egl += libgbm +- incs_for_egl += [inc_gbm, include_directories('../gbm/main')] +- deps_for_egl += dep_libdrm ++ incs_for_egl += [include_directories('../gbm/backends/dri')] ++ deps_for_egl += [dep_libdrm, dep_gbm] + endif + if with_platform_wayland + deps_for_egl += [dep_wayland_client, dep_wayland_server, dep_wayland_egl_headers] +diff --git a/src/gallium/targets/dril/dril_target.c b/src/gallium/targets/dril/dril_target.c +index 339e9376c3d..f1a0bb18ed8 100644 +--- a/src/gallium/targets/dril/dril_target.c ++++ b/src/gallium/targets/dril/dril_target.c +@@ -25,7 +25,7 @@ + #include + #include + #include +-#include "gbm/main/gbm.h" ++#include + #include "drm-uapi/drm_fourcc.h" + + #define EGL_PLATFORM_GBM_MESA 0x31D7 +diff --git a/src/gallium/targets/dril/meson.build b/src/gallium/targets/dril/meson.build +index 7cfa982ffe1..22b955b9074 100644 +--- a/src/gallium/targets/dril/meson.build ++++ b/src/gallium/targets/dril/meson.build +@@ -51,10 +51,10 @@ dril_dri = shared_library( + link_depends : dril_link_depends, + link_with : [ + libgallium, +- libgbm, + ], + dependencies : [ + idep_mesautil, ++ dep_gbm, + ], + # Will be deleted during installation, see install_megadrivers.py + install : true, +diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c +index a51e3cb3b8d..f1a5e0f7649 100644 +--- a/src/gbm/backends/dri/gbm_dri.c ++++ b/src/gbm/backends/dri/gbm_dri.c +@@ -43,7 +43,7 @@ + + #include "mesa_interface.h" + #include "gbm_driint.h" +-#include "gbmint.h" ++#include + #include "loader_dri_helper.h" + #include "kopper_interface.h" + #include "loader.h" +diff --git a/src/gbm/backends/dri/gbm_driint.h b/src/gbm/backends/dri/gbm_driint.h +index 9b324aeaf12..9c7588e5726 100644 +--- a/src/gbm/backends/dri/gbm_driint.h ++++ b/src/gbm/backends/dri/gbm_driint.h +@@ -31,7 +31,7 @@ + #include + #include + #include +-#include "gbmint.h" ++#include + #include "c11/threads.h" + + #include /* mesa_interface needs GL types */ +diff --git a/src/gbm/backends/dri/meson.build b/src/gbm/backends/dri/meson.build +index 9b5d13e9db8..84a40656980 100644 +--- a/src/gbm/backends/dri/meson.build ++++ b/src/gbm/backends/dri/meson.build +@@ -11,10 +11,10 @@ endif + shared_library( + 'dri_gbm', + files('gbm_dri.c', 'gbm_driint.h'), +- include_directories : [incs_gbm, incs_gbm_dri, inc_st_dri, inc_gallium_aux], ++ include_directories : [inc_gallium, incs_gbm_dri, inc_loader, inc_st_dri, inc_gallium_aux], + link_args : [ld_args_gc_sections], + link_with : [libloader, libgallium_dri], +- dependencies : [deps_gbm_dri, dep_dl, dep_libdrm, idep_mesautil, idep_xmlconfig], ++ dependencies : [deps_gbm_dri, dep_dl, dep_gbm, dep_libdrm, idep_mesautil, idep_xmlconfig], + gnu_symbol_visibility : 'hidden', + install : true, + install_dir: join_paths(get_option('libdir'), 'gbm'), +diff --git a/src/gbm/meson.build b/src/gbm/meson.build +index eaed028d049..97e8d5fa044 100644 +--- a/src/gbm/meson.build ++++ b/src/gbm/meson.build +@@ -15,10 +15,6 @@ args_gbm = [ + ] + incs_gbm = [include_directories('main'), inc_loader, inc_gallium] + +-if with_dri2 +- subdir('backends/dri') +-endif +- + libgbm_name = 'gbm' + + if with_platform_android and get_option('platform-sdk-version') >= 30 +@@ -43,7 +39,7 @@ if with_tests + test('gbm-abi-check', abi_check, suite : ['gbm']) + endif + +-install_headers('main/gbm.h') ++install_headers('main/gbm.h', 'main/gbm_backend_abi.h') + + pkg.generate( + name : 'gbm', +@@ -67,3 +63,8 @@ if with_symbols_check + suite : ['gbm'], + ) + endif ++ ++dep_gbm = declare_dependency( ++ link_with : libgbm, ++ include_directories : inc_gbm, ++) +diff --git a/src/meson.build b/src/meson.build +index d443d2b41bb..74250ed2148 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -127,11 +127,17 @@ endif + if with_glx == 'dri' + subdir('glx') + endif ++ + if with_gbm +- subdir('gbm') ++ if get_option('libgbm-external') ++ dep_gbm = dependency('gbm') ++ else ++ subdir('gbm') ++ endif + else +- inc_gbm = [] ++ dep_gbm = null_dep + endif ++ + if with_egl + subdir('egl') + endif +@@ -141,6 +147,10 @@ if with_gallium and with_gbm + endif + endif + ++if with_gbm and with_dri2 ++ subdir('gbm/backends/dri') ++endif ++ + # This must be after at least mesa, glx, and gallium, since libgl will be + # defined in one of those subdirs depending on the glx provider. + if with_glx != 'disabled' and not with_glvnd diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index 5dce88abc459..ad3cea12d00b 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -990,7 +990,7 @@ mapAliases { mutter43 = throw "'mutter43' has been removed since it is no longer used by Pantheon."; # Added 2024-09-22 mysql-client = hiPrio mariadb.client; mysql = throw "'mysql' has been renamed to/replaced by 'mariadb'"; # Converted to throw 2024-10-17 - mesa_drivers = throw "'mesa_drivers' has been removed, use 'pkgs.mesa' or 'pkgs.mesa.drivers' depending on target use case."; # Converted to throw 2024-07-11 + mesa_drivers = throw "'mesa_drivers' has been removed, use 'pkgs.mesa' instead."; # Converted to throw 2024-07-11 ### N ###