Compare commits
67 Commits
atiVersion
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b93246bced | ||
![]() |
68e1819b88 | ||
![]() |
7dcd280d44 | ||
![]() |
210c6a8a54 | ||
![]() |
6fab1faca5 | ||
![]() |
ab5c39d32e | ||
![]() |
e7039bfb2c | ||
![]() |
410cd5b482 | ||
![]() |
339c6c5795 | ||
![]() |
5f330c2185 | ||
![]() |
7bb080c0e5 | ||
![]() |
76196e5da3 | ||
![]() |
4c09910428 | ||
![]() |
b5660a81bd | ||
![]() |
4fb0203a54 | ||
![]() |
7aa1cce7c6 | ||
![]() |
7f934a88ce | ||
![]() |
3df3a471ae | ||
![]() |
06f91bf67e | ||
![]() |
9348b49674 | ||
![]() |
0564a32785 | ||
![]() |
e2cc0101af | ||
![]() |
d0379a8673 | ||
![]() |
3db9b5d12a | ||
![]() |
ace3193d44 | ||
![]() |
17c1ec63b9 | ||
![]() |
201b4facf5 | ||
![]() |
122026d20c | ||
![]() |
701dfc8c6e | ||
![]() |
a02035314b | ||
![]() |
d05a776200 | ||
![]() |
7009c94a93 | ||
![]() |
ae5bc98bb7 | ||
![]() |
237b47397f | ||
![]() |
66c92824ab | ||
![]() |
d5c0d28968 | ||
![]() |
1ba64e0199 | ||
![]() |
3ef7bffcae | ||
![]() |
33282d65db | ||
![]() |
d67944d5ae | ||
![]() |
66d99ddb67 | ||
![]() |
f3b50205ef | ||
![]() |
ea7c1d70fc | ||
![]() |
13352162de | ||
![]() |
5ba3174763 | ||
![]() |
04a6b0833f | ||
![]() |
a02970d696 | ||
![]() |
fa08b64b31 | ||
![]() |
9e33a6ecb1 | ||
![]() |
4088ce159e | ||
![]() |
2021895c3f | ||
![]() |
df9d0ecc16 | ||
![]() |
21764c9926 | ||
![]() |
2b9e5fb6ed | ||
![]() |
ed31333b05 | ||
![]() |
69644dd5da | ||
![]() |
d78549fef3 | ||
![]() |
624ea697ac | ||
![]() |
fe935edb01 | ||
![]() |
6ffe3132e3 | ||
![]() |
8fda8f8642 | ||
![]() |
0ba511aeb3 | ||
![]() |
5df6048ead | ||
![]() |
dcf12c42d1 | ||
![]() |
2388c2ff41 | ||
![]() |
ee5d1d4eee | ||
![]() |
08873181af |
13
.github/workflows/test.yml
vendored
Normal file
13
.github/workflows/test.yml
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
name: 'Test'
|
||||
|
||||
on: [ push, pull_request ]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: 'Test'
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: cachix/install-nix-action@v8
|
||||
- run: nix-build all.nix
|
||||
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/result
|
208
README.md
208
README.md
|
@ -1,27 +1,15 @@
|
|||
This tool tries to solve the "OpenGL" problem on nix. Works with Nvidia cards (with bumblebee) and intel cards.
|
||||
# NixGL
|
||||
|
||||
# Quick start
|
||||
|
||||
Suppose you have a configuration with an nvidia card, host driver version `390.25`
|
||||
|
||||
```
|
||||
# clone the repository
|
||||
git clone https://github.com/guibou/nixGL
|
||||
cd nixGL
|
||||
|
||||
# build and install the wrapper
|
||||
nix-build -A nixGLNvidia --argstr nvidiaVersion 390.25
|
||||
nix-env -i ./result
|
||||
|
||||
# use it with any OpenGL application
|
||||
nixGLNvidia blender
|
||||
```
|
||||
NixGL solve the "OpenGL" problem with [nix](https://nixos.org/nix/). Works all mesa
|
||||
drivers (intel cards and "free" version fro Nvidia or AMD cards), Nvidia
|
||||
proprietary drivers, even with hybrid configuration (with bumblebee). It works
|
||||
for Vulkan programs too.
|
||||
|
||||
# Motivation
|
||||
|
||||
You use Nix on any distribution, and any GL application installed fails with this error:
|
||||
|
||||
```
|
||||
```bash
|
||||
$ program
|
||||
libGL error: unable to load driver: i965_dri.so
|
||||
libGL error: driver pointer missing
|
||||
|
@ -33,93 +21,153 @@ libGL error: unable to load driver: swrast_dri.so
|
|||
libGL error: failed to load driver: swrast
|
||||
```
|
||||
|
||||
This library contains a wrapper which is able to launch GL application:
|
||||
NixGL provides a set of wrappers able to launch GL or Vulkan applications:
|
||||
|
||||
```
|
||||
nixGLXXX program
|
||||
```bash
|
||||
$ nixGLXXX program
|
||||
$ nixVulkanXXX program
|
||||
```
|
||||
|
||||
# Installation / Usage
|
||||
# Installation
|
||||
|
||||
Clone this git repository:
|
||||
|
||||
```
|
||||
git clone https://github.com/guibou/nixGL
|
||||
cd nixGL
|
||||
```bash
|
||||
$ git clone https://github.com/guibou/nixGL
|
||||
$ cd nixGL
|
||||
```
|
||||
|
||||
## Optional (if NVIDIA): Grab your NVIDIA driver version
|
||||
Many wrappers are available, depending on your hardware and the graphical API
|
||||
you want to use (i.e. Vulkan or OpenGL). You may want to install a few of them,
|
||||
for example if you want to support OpenGL and Vulkan on a laptop with an hybrid
|
||||
configuration.
|
||||
|
||||
Using `glxinfo` from your host system, grab the driver version, here `390.25`:
|
||||
## OpenGL wrappers
|
||||
|
||||
```
|
||||
$ glxinfo | grep NVIDIA
|
||||
...
|
||||
OpenGL core profile version string: 4.5.0 NVIDIA 390.25
|
||||
...
|
||||
```
|
||||
- `nix-env -f ./ -iA nixGLIntel`: Mesa OpenGL implementation (intel, amd, nouveau, ...).
|
||||
- `nix-env -f ./ -iA nixGLNvidiaBumblebee`: Proprietary Nvidia driver on hybrid hardware.
|
||||
- `nix-env -f ./ -iA nixGLNvidia`: Proprietary Nvidia driver.
|
||||
- `nix-env -f ./ -iA nixGLDefault`: Tries to auto-detect and install Nvidia,
|
||||
if not, fallback to mesa.
|
||||
|
||||
## Build
|
||||
## Vulkan wrappers
|
||||
|
||||
For intel:
|
||||
|
||||
```
|
||||
nix-build -A nixGLIntel
|
||||
```
|
||||
|
||||
For NVIDIA alone:
|
||||
|
||||
```
|
||||
nix-build -A nixGLNvidia --argstr nvidiaVersion 390.25
|
||||
```
|
||||
|
||||
(replace `390.25` with the host driver version gathered earlier.)
|
||||
|
||||
For Nvidia with bumblebee:
|
||||
|
||||
```
|
||||
nix-build -A nixGLNvidiaBumblebee --argstr nvidiaVersion 390.25
|
||||
```
|
||||
|
||||
(replace `390.25` with the host driver version gathered earlier.)
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
nix-env -i ./result
|
||||
```
|
||||
|
||||
(Note, you can iterate many time on this process to install as many driver as needed. Common example are `nixGLIntel` with `nixGLNvidiaBumblebee`)
|
||||
- `nix-env -f ./ -iA nixVulkanNvidia`: Proprietary Nvidia driver.
|
||||
- `nix-env -f ./ -iA nixVulkanIntel`: Mesa Vulkan implementation.
|
||||
|
||||
The Vulkan wrapper also sets `VK_LAYER_PATH` the validation layers in the nix store.
|
||||
|
||||
# Usage
|
||||
|
||||
```
|
||||
nixGLXXX program args
|
||||
```
|
||||
Just launch the program you want prefixed by the right wrapped.
|
||||
|
||||
For example (on my dual GPU laptop):
|
||||
For OpenGL programs:
|
||||
|
||||
```bash
|
||||
$ nixGLIntel glxinfo | grep -i 'OpenGL version string'
|
||||
$ nixGLXXX program args
|
||||
```
|
||||
|
||||
For Vulkan programs:
|
||||
|
||||
```bash
|
||||
$ nixVulkanXXX program args
|
||||
```
|
||||
|
||||
Replace `XXX` by the implementation pour previously selected, such as `nixGLIntel` or `nixGLNvidia`.
|
||||
|
||||
## Examples
|
||||
|
||||
# OpenGL - Hybrid Intel + Nvidia laptop
|
||||
|
||||
After installing `nixGLIntel` and `nixGLNvidiaBumblebee`.
|
||||
|
||||
```bash
|
||||
$ nixGLIntel $(nix run nixpkgs.glxinfo -c glxinfo) | grep -i 'OpenGL version string'
|
||||
OpenGL version string: 3.0 Mesa 17.3.3
|
||||
$ nixGLNvidiaBumblebee glxinfo | grep -i 'OpenGL version string'
|
||||
$ nixGLNvidiaBumblebee $(nix run nixpkgs.glxinfo -c glxinfo) | grep -i 'OpenGL version string'
|
||||
OpenGL version string: 4.6.0 NVIDIA 390.25
|
||||
```
|
||||
|
||||
If the program you'd like to run is already installed by nix in your current environment, you can simply run it with the wrapper, for example:
|
||||
|
||||
```bash
|
||||
$ nixGLIntel blender
|
||||
```
|
||||
|
||||
# Vulkan - Intel GPU
|
||||
|
||||
After installing `nixVulkanIntel`.
|
||||
|
||||
```bash
|
||||
$ sudo apt install mesa-vulkan-drivers
|
||||
...
|
||||
$ nixVulkanIntel $(nix-build '<nixpkgs>' --no-out-link -A vulkan-tools)/bin/vulkaninfo | grep VkPhysicalDeviceProperties -A 7
|
||||
VkPhysicalDeviceProperties:
|
||||
===========================
|
||||
apiVersion = 0x400036 (1.0.54)
|
||||
driverVersion = 71311368 (0x4402008)
|
||||
vendorID = 0x8086
|
||||
deviceID = 0x591b
|
||||
deviceType = INTEGRATED_GPU
|
||||
deviceName = Intel(R) HD Graphics 630 (Kaby Lake GT2)
|
||||
```
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
## Nvidia auto detection does not work
|
||||
|
||||
```bash
|
||||
building '/nix/store/ijs5h6h07faai0k74diiy5b2xlxh891g-auto-detect-nvidia.drv'...
|
||||
pcregrep: Failed to open /proc/driver/nvidia/ersion: No such file or directory
|
||||
builder for '/nix/store/ijs5h6h07faai0k74diiy5b2xlxh891g-auto-detect-nvidia.drv' failed with exit code 2
|
||||
error: build of '/nix/store/ijs5h6h07faai0k74diiy5b2xlxh891g-auto-detect-nvidia.drv' faile
|
||||
```
|
||||
|
||||
You can run the Nvidia installer using an explicit version string instead of the automatic detection method:
|
||||
|
||||
```bash
|
||||
nix-build -A nixGLNvidia --argstr nvidiaVersion 440.82
|
||||
```
|
||||
|
||||
The version of your driver can be found using `glxinfo` from your system default package manager, or `nvidia-settings`.
|
||||
|
||||
## On nixOS
|
||||
|
||||
`nixGL` can also be used on nixOS if the system is installed with a different
|
||||
nixpkgs clone than the one your application are installed with. Override the
|
||||
`pkgs` argument of the script with the correct nixpkgs clone:
|
||||
|
||||
```bash
|
||||
nix-build ./default.nix -A nixGLIntel --arg pkgs "import path_to_your_nixpkgs {}".
|
||||
```
|
||||
|
||||
## Old nvidia drivers
|
||||
|
||||
Users of Nvidia legacy driver should use the `backport/noGLVND` branch. This branch is not tested and may not work well, please open a bug report, it will be taken care of as soon as possible.
|
||||
|
||||
# `nixGLCommon`
|
||||
|
||||
`nixGLCommon nixGLXXX` can be used to get `nixGL` executable which fallsback to `nixGLXXX`. It is a shorter name for people with only one OpenGL configuration.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
nix-build -E "with import ./default.nix {}; nixGLCommon nixGLIntel"
|
||||
```
|
||||
|
||||
# Using nixGL in your project
|
||||
|
||||
|
||||
|
||||
|
||||
# Limitations
|
||||
|
||||
Does not work now for AMD drivers because I dont' have the hardware.
|
||||
`nixGL` is badly tested, mostly because it is difficult to test automatically in a continuous integration context because you need access to different type of hardware.
|
||||
|
||||
# Comparaison with similar tools
|
||||
Some OpenGL configurations may not work, for example AMD proprietary drivers. There is no fundamental limitation, so if you want support for theses configurations, open an issue.
|
||||
|
||||
[nix-install-vendor-gl.sh](https://github.com/deepfire/nix-install-vendor-gl)
|
||||
provides a similar system with a different approach:
|
||||
# Hacking
|
||||
|
||||
- it auto detect the host driver
|
||||
- it needs root access and set your system for a specific driver
|
||||
- it only provides wrappers for nvidia (without bumblebee)
|
||||
|
||||
Both projects are now really similar and the only reason I did not
|
||||
contributed to `nix-install-vendor-gl.sh` was because initial `nixGL`
|
||||
had a totally different approach.
|
||||
One great way to contribute to nixGL is to run the test suite. Just run
|
||||
`./Test.hs` in the main directory and check that all the test relevant to your
|
||||
hardware are green.
|
||||
|
|
110
Test.hs
Executable file
110
Test.hs
Executable file
|
@ -0,0 +1,110 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i runhaskell -p "haskellPackages.ghcWithPackages(p: with p; [hspec process])" -p nix
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
import Test.Hspec
|
||||
import System.Process
|
||||
import qualified Data.Text as Text
|
||||
import Data.Text (Text)
|
||||
import Control.Monad.IO.Class (liftIO)
|
||||
import Data.List (find)
|
||||
|
||||
-- nixos-19-09 is used so hopefully it will have a different libc than
|
||||
-- the current `<nixpkgs>` used in a current nixOS system, so it will trigger the
|
||||
-- driver failure.
|
||||
-- Run `./Test.hs --match "/Sanity/"` to ensure that non wrapped
|
||||
-- binaries fails on NixOS.
|
||||
|
||||
currentChannel = "channel:nixos-19.09-small"
|
||||
|
||||
-- | Utils function: run a command and returns its output.
|
||||
processOutput p args = Text.strip . Text.pack <$> readCreateProcess ((proc (Text.unpack p) (Text.unpack <$> args)) { std_err = Inherit }) ""
|
||||
|
||||
-- * OpenGL
|
||||
|
||||
-- | Returns the path to the nixGLXXX binary.
|
||||
getNixGLBin version = (<>("/bin/"<>version)) <$> processOutput "nix-build" ["./", "-A", version, "-I", "nixpkgs=" <> currentChannel]
|
||||
|
||||
-- | Returns the vendor string associated with a glxinfo wrapped by a nixGL.
|
||||
getVendorString io = do
|
||||
output <- Text.lines <$> io
|
||||
pure $ Text.unpack <$> find ("OpenGL version string"`Text.isPrefixOf`) output
|
||||
|
||||
-- | Checks that a nixGL wrapper works with glxinfo 32 & 64 bits.
|
||||
checkOpenGL_32_64 glxinfo32 glxinfo64 vendorName nixGLName = do
|
||||
beforeAll (getNixGLBin nixGLName) $ do
|
||||
it "32 bits" $ \nixGLBin -> do
|
||||
Just vendorString <- getVendorString (processOutput nixGLBin [glxinfo32, "-B"])
|
||||
vendorString `shouldContain` vendorName
|
||||
|
||||
it "64 bits" $ \nixGLBin -> do
|
||||
Just vendorString <- getVendorString (processOutput nixGLBin [glxinfo64, "-B"])
|
||||
vendorString `shouldContain` vendorName
|
||||
|
||||
-- * Vulkan
|
||||
|
||||
-- | Heuristic to detect if vulkan work. `driverName` must appears in the output
|
||||
checkVulkanIsWorking io = do
|
||||
res <- io
|
||||
res `shouldSatisfy` ("driverName"`Text.isInfixOf`)
|
||||
|
||||
-- | Checks that a nixGL wrapper works with glxinfo 32 & 64 bits.
|
||||
checkVulkan_32_64 vulkaninfo32 vulkaninfo64 vendorName nixGLName = do
|
||||
beforeAll (getNixGLBin nixGLName) $ do
|
||||
it "32 bits" $ \nixGLBin -> do
|
||||
checkVulkanIsWorking (processOutput nixGLBin [vulkaninfo32])
|
||||
|
||||
it "64 bits" $ \nixGLBin -> do
|
||||
checkVulkanIsWorking (processOutput nixGLBin [vulkaninfo64])
|
||||
|
||||
|
||||
main = do
|
||||
putStrLn "Running tests for nixGL"
|
||||
putStrLn "It can take a while, this will build and test all drivers in the background"
|
||||
glxinfo64 <- (<>"/bin/glxinfo") <$> processOutput "nix-build" [currentChannel, "-A", "glxinfo"]
|
||||
glxinfo32 <- (<>"/bin/glxinfo") <$> processOutput "nix-build" [currentChannel, "-A", "pkgsi686Linux.glxinfo"]
|
||||
|
||||
vulkaninfo64 <- (<>"/bin/vulkaninfo") <$> processOutput "nix-build" [currentChannel, "-A", "vulkan-tools"]
|
||||
vulkaninfo32 <- (<>"/bin/vulkaninfo") <$> processOutput "nix-build" [currentChannel, "-A", "pkgsi686Linux.vulkan-tools"]
|
||||
|
||||
let checkOpenGL = checkOpenGL_32_64 glxinfo32 glxinfo64
|
||||
checkVulkan = checkVulkan_32_64 vulkaninfo32 vulkaninfo64
|
||||
|
||||
hspec $ do
|
||||
-- This category ensure that tests are failing if not run with nixGL
|
||||
-- This allows testing on nixOS
|
||||
describe "Sanity" $ do
|
||||
describe "OpenGL" $ do
|
||||
it "fails with unwrapped glxinfo64" $ do
|
||||
vendorString <- getVendorString (processOutput glxinfo64 ["-B"])
|
||||
vendorString `shouldBe` Nothing
|
||||
|
||||
it "fails with unwrapped glxinfo32" $ do
|
||||
vendorString <- getVendorString (processOutput glxinfo32 ["-B"])
|
||||
vendorString `shouldBe` Nothing
|
||||
describe "Vulkan" $ do
|
||||
it "fails with unwrapped vulkaninfo64" $ do
|
||||
processOutput vulkaninfo64 [] `shouldThrow` anyIOException
|
||||
|
||||
it "fails with unwrapped vulkaninfo32" $ do
|
||||
processOutput vulkaninfo32 [] `shouldThrow` anyIOException
|
||||
|
||||
describe "NixGL" $ do
|
||||
describe "Mesa" $ do
|
||||
describe "OpenGL" $ do
|
||||
checkOpenGL "Mesa" "nixGLIntel"
|
||||
describe "Vulkan" $ do
|
||||
checkVulkan "Mesa" "nixVulkanIntel"
|
||||
|
||||
describe "Nvidia - Bumblebee" $ do
|
||||
describe "OpenGL" $ do
|
||||
checkOpenGL "NVIDIA" "nixGLNvidiaBumblebee"
|
||||
xdescribe "Vulkan" $ do
|
||||
-- Not tested: I don't have the hardware (@guibou)
|
||||
checkVulkan "NVIDIA" "nixVulkanNvidiaBumblebee"
|
||||
|
||||
-- TODO: check Nvidia (I don't have this hardware)
|
||||
describe "Nvidia" $ do
|
||||
describe "OpenGL" $ do
|
||||
checkOpenGL "NVIDIA" "nixGLNvidia"
|
||||
describe "Vulkan" $ do
|
||||
checkVulkan "NVIDIA" "nixVulkanNvidia"
|
16
all.nix
Normal file
16
all.nix
Normal file
|
@ -0,0 +1,16 @@
|
|||
let
|
||||
pkgs = import <nixpkgs> { config = { allowUnfree = true; }; };
|
||||
in
|
||||
{
|
||||
pure = pkgs.recurseIntoAttrs (pkgs.callPackage ./nixGL.nix {
|
||||
nvidiaVersion = "440.82";
|
||||
nvidiaHash = "edd415acf2f75a659e0f3b4f27c1fab770cf21614e84a18152d94f0d004a758e";
|
||||
});
|
||||
|
||||
versionFile = pkgs.recurseIntoAttrs (pkgs.callPackage ./nixGL.nix {
|
||||
nvidiaVersionFile = pkgs.writeText "nvidia-version-440.82" ''
|
||||
NVRM version: NVIDIA UNIX x86_64 Kernel Module 440.82 Wed Apr 1 20:04:33 UTC 2020
|
||||
GCC version: gcc version 9.3.0 (Arch Linux 9.3.0-1)
|
||||
'';
|
||||
});
|
||||
}
|
77
default.nix
77
default.nix
|
@ -1,77 +0,0 @@
|
|||
{ system ? builtins.currentSystem,
|
||||
nvidiaVersion ? null
|
||||
}:
|
||||
|
||||
let
|
||||
pkgs = import <nixpkgs> { inherit system; };
|
||||
|
||||
version = "1.0.0";
|
||||
in
|
||||
with pkgs;
|
||||
rec {
|
||||
nvidiaLibsOnly = (linuxPackages.nvidia_x11.override {
|
||||
libsOnly = true;
|
||||
kernel = null;
|
||||
}).overrideAttrs(oldAttrs: rec {
|
||||
name = "nvidia-${nvidiaVersion}";
|
||||
src = fetchurl {
|
||||
url = "http://download.nvidia.com/XFree86/Linux-x86_64/${nvidiaVersion}/NVIDIA-Linux-x86_64-${nvidiaVersion}.run";
|
||||
sha256 = null;
|
||||
};
|
||||
useGLVND = 0;
|
||||
});
|
||||
|
||||
nixGLNvidiaBumblebee = runCommand "nixGLNvidiaBumblebee-${version}" {
|
||||
buildInputs = [ nvidiaLibsOnly bumblebee ];
|
||||
|
||||
meta = with pkgs.stdenv.lib; {
|
||||
description = "A tool to launch OpenGL application on system other than NixOS - Nvidia bumblebee version";
|
||||
homepage = "https://github.com/guibou/nixGL";
|
||||
};
|
||||
} ''
|
||||
mkdir -p $out/bin
|
||||
cat > $out/bin/nixGLNvidiaBumblebee << FOO
|
||||
#!/usr/bin/env sh
|
||||
export LD_LIBRARY_PATH=${nvidiaLibsOnly}/lib
|
||||
${bumblebee}/bin/optirun "\$@"
|
||||
FOO
|
||||
|
||||
chmod u+x $out/bin/nixGLNvidiaBumblebee
|
||||
'';
|
||||
|
||||
nixGLNvidia = runCommand "nixGLNvidia-${version}" {
|
||||
buildInputs = [ nvidiaLibsOnly ];
|
||||
|
||||
meta = with pkgs.stdenv.lib; {
|
||||
description = "A tool to launch OpenGL application on system other than NixOS - Nvidia version";
|
||||
homepage = "https://github.com/guibou/nixGL";
|
||||
};
|
||||
} ''
|
||||
mkdir -p $out/bin
|
||||
cat > $out/bin/nixGLNvidia << FOO
|
||||
#!/usr/bin/env sh
|
||||
export LD_LIBRARY_PATH=${nvidiaLibsOnly}/lib
|
||||
"\$@"
|
||||
FOO
|
||||
|
||||
chmod u+x $out/bin/nixGLNvidia
|
||||
'';
|
||||
|
||||
nixGLIntel = runCommand "nixGLIntel-${version}" {
|
||||
buildInputs = [ mesa_drivers ];
|
||||
|
||||
meta = with pkgs.stdenv.lib; {
|
||||
description = "A tool to launch OpenGL application on system other than NixOS - Intel version";
|
||||
homepage = "https://github.com/guibou/nixGL";
|
||||
};
|
||||
} ''
|
||||
mkdir -p $out/bin
|
||||
cat > $out/bin/nixGLIntel << FOO
|
||||
#!/usr/bin/env sh
|
||||
export LIBGL_DRIVERS_PATH=${mesa_drivers}/lib/dri
|
||||
"\$@"
|
||||
FOO
|
||||
|
||||
chmod u+x $out/bin/nixGLIntel
|
||||
'';
|
||||
}
|
72
flake.lock
Normal file
72
flake.lock
Normal file
|
@ -0,0 +1,72 @@
|
|||
{
|
||||
"nodes": {
|
||||
"lowdown-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1598695561,
|
||||
"narHash": "sha256-gyH/5j+h/nWw0W8AcR2WKvNBUsiQ7QuxqSJNXAwV+8E=",
|
||||
"owner": "kristapsdz",
|
||||
"repo": "lowdown",
|
||||
"rev": "1705b4a26fbf065d9574dce47a94e8c7c79e052f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "kristapsdz",
|
||||
"repo": "lowdown",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix": {
|
||||
"inputs": {
|
||||
"lowdown-src": "lowdown-src",
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1604964115,
|
||||
"narHash": "sha256-ANcswniHS4eYeMNyCGdiG3z0M35vEyvWoCsdLnTvObA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nix",
|
||||
"rev": "0ed7c957bed18d963df65d55f0c0ffc79dee656d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nix",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1602702596,
|
||||
"narHash": "sha256-fqJ4UgOb4ZUnCDIapDb4gCrtAah5Rnr2/At3IzMitig=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ad0d20345219790533ebe06571f82ed6b034db31",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-20.09-small",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"narHash": "sha256-wLDweKqbmufa2wonCKBf4Wfl8I0eS1CGS7WdR5tPHKo=",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/60330b60655b3fa3a18624bdd7069855bb37af99.tar.gz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/60330b60655b3fa3a18624bdd7069855bb37af99.tar.gz"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nix": "nix",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
49
flake.nix
Normal file
49
flake.nix
Normal file
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
description = "";
|
||||
inputs = {
|
||||
nixpkgs.url = https://github.com/NixOS/nixpkgs/archive/60330b60655b3fa3a18624bdd7069855bb37af99.tar.gz;
|
||||
};
|
||||
outputs = { nixpkgs, nix, self, ... }@inputs : {
|
||||
defaultPackage.x86_64-linux =
|
||||
let pkgs = import nixpkgs { system = "x86_64-linux"; config = { allowUnfree = true; }; }; in
|
||||
(pkgs.callPackage ./nixGL.nix {
|
||||
nvidiaVersionFile = null;
|
||||
nvidiaVersion = "455.28"; nvidiaHash = "03ysf61qrb272yqkn7bhn9d65lcfhmqc2c0dbh5prp5f2ndlkqg4";
|
||||
# nvidiaVersion = "455.23.04"; nvidiaHash = "0rvbb9s4ijb0gyiscd93chbgim4lqmy4ksfy15b4abf078qk7q4g";
|
||||
# …
|
||||
enable32bits = true;
|
||||
}).nixGLIntel; # nixGLNvidia;
|
||||
# nixpkgs.stdenv.mkDerivation {
|
||||
# builsInputs = [];
|
||||
# { ## Nvidia informations.
|
||||
# # Version of the system kernel module. Let it to null to enable auto-detection.
|
||||
# nvidiaVersion ? null,
|
||||
# # Hash of the Nvidia driver .run file. null is fine, but fixing a value here
|
||||
# # will be more reproducible and more efficient.
|
||||
# nvidiaHash ? null,
|
||||
# # Alternatively, you can pass a path that points to a nvidia version file
|
||||
# # and let nixGL extract the version from it. That file must be a copy of
|
||||
# # /proc/driver/nvidia/version. Nix doesn't like zero-sized files (see
|
||||
# # https://github.com/NixOS/nix/issues/3539 ).
|
||||
# nvidiaVersionFile ? null,
|
||||
# # Enable 32 bits driver
|
||||
# # This is one by default, you can switch it to off if you want to reduce a
|
||||
# # bit the size of nixGL closure.
|
||||
# enable32bits ? true,
|
||||
# # Make sure to enable config.allowUnfree to the instance of nixpkgs to be
|
||||
# # able to access the nvidia drivers.
|
||||
# pkgs ? import <nixpkgs> {
|
||||
# config = { allowUnfree = true; };
|
||||
# }
|
||||
# }:
|
||||
# pkgs.callPackage ./nixGL.nix {
|
||||
# inherit
|
||||
# nvidiaVersion
|
||||
# nvidiaVersionFile
|
||||
# nvidiaHash
|
||||
# enable32bits
|
||||
# ;
|
||||
# };
|
||||
# };
|
||||
};
|
||||
}
|
199
nixGL.nix
Normal file
199
nixGL.nix
Normal file
|
@ -0,0 +1,199 @@
|
|||
{ ## Nvidia informations.
|
||||
# Version of the system kernel module. Let it to null to enable auto-detection.
|
||||
nvidiaVersion ? null,
|
||||
# Hash of the Nvidia driver .run file. null is fine, but fixing a value here
|
||||
# will be more reproducible and more efficient.
|
||||
nvidiaHash ? null,
|
||||
# Alternatively, you can pass a path that points to a nvidia version file
|
||||
# and let nixGL extract the version from it. That file must be a copy of
|
||||
# /proc/driver/nvidia/version. Nix doesn't like zero-sized files (see
|
||||
# https://github.com/NixOS/nix/issues/3539 ).
|
||||
nvidiaVersionFile ? null,
|
||||
# Enable 32 bits driver
|
||||
# This is one by default, you can switch it to off if you want to reduce a
|
||||
# bit the size of nixGL closure.
|
||||
enable32bits ? true,
|
||||
writeTextFile, shellcheck, pcre, runCommand, linuxPackages, fetchurl, lib,
|
||||
runtimeShell, bumblebee, libglvnd, vulkan-validation-layers, mesa_drivers,
|
||||
pkgsi686Linux,zlib, libdrm, xorg, wayland, gcc
|
||||
}:
|
||||
|
||||
let
|
||||
_nvidiaVersionFile =
|
||||
if nvidiaVersionFile != null then
|
||||
nvidiaVersionFile
|
||||
else
|
||||
# HACK: Get the version from /proc. It turns out that /proc is mounted
|
||||
# inside of the build sandbox and varies from machine to machine.
|
||||
#
|
||||
# builtins.readFile is not able to read /proc files. See
|
||||
# https://github.com/NixOS/nix/issues/3539.
|
||||
runCommand "impure-nvidia-version-file" {
|
||||
# To avoid sharing the build result over time or between machine,
|
||||
# Add an impure parameter to force the rebuild on each access.
|
||||
time = builtins.currentTime;
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
}
|
||||
"cp /proc/driver/nvidia/version $out || touch $out";
|
||||
|
||||
# The nvidia version. Either fixed by the `nvidiaVersion` argument, or
|
||||
# auto-detected. Auto-detection is impure.
|
||||
_nvidiaVersion =
|
||||
if nvidiaVersion != null then
|
||||
nvidiaVersion
|
||||
else
|
||||
# Get if from the nvidiaVersionFile
|
||||
let
|
||||
data = builtins.readFile _nvidiaVersionFile;
|
||||
versionMatch = builtins.match ".*Module +([0-9]+\\.[0-9]+).*" data;
|
||||
in
|
||||
if versionMatch != null then
|
||||
builtins.head versionMatch
|
||||
else
|
||||
null;
|
||||
|
||||
addNvidiaVersion = drv: drv.overrideAttrs(oldAttrs: {
|
||||
name = oldAttrs.name + "-${_nvidiaVersion}";
|
||||
});
|
||||
|
||||
writeExecutable = { name, text } : writeTextFile {
|
||||
inherit name text;
|
||||
|
||||
executable = true;
|
||||
destination = "/bin/${name}";
|
||||
|
||||
|
||||
checkPhase = ''
|
||||
${shellcheck}/bin/shellcheck "$out/bin/${name}"
|
||||
|
||||
# Check that all the files listed in the output binary exists
|
||||
for i in $(${pcre}/bin/pcregrep -o0 '/nix/store/.*?/[^ ":]+' $out/bin/${name})
|
||||
do
|
||||
ls $i > /dev/null || (echo "File $i, referenced in $out/bin/${name} does not exists."; exit -1)
|
||||
done
|
||||
'';
|
||||
};
|
||||
in
|
||||
rec {
|
||||
nvidia = (linuxPackages.nvidia_x11.override {
|
||||
}).overrideAttrs(oldAttrs: rec {
|
||||
name = "nvidia-${_nvidiaVersion}";
|
||||
src = let url ="http://download.nvidia.com/XFree86/Linux-x86_64/${_nvidiaVersion}/NVIDIA-Linux-x86_64-${_nvidiaVersion}.run";
|
||||
in if nvidiaHash != null
|
||||
then fetchurl {
|
||||
inherit url;
|
||||
sha256 = nvidiaHash;
|
||||
} else
|
||||
builtins.fetchurl url;
|
||||
useGLVND = true;
|
||||
});
|
||||
|
||||
nvidiaLibsOnly = nvidia.override {
|
||||
libsOnly = true;
|
||||
kernel = null;
|
||||
};
|
||||
|
||||
nixGLNvidiaBumblebee = addNvidiaVersion (writeExecutable {
|
||||
name = "nixGLNvidiaBumblebee";
|
||||
text = ''
|
||||
#!${runtimeShell}
|
||||
export LD_LIBRARY_PATH=${lib.makeLibraryPath [nvidia]}:$LD_LIBRARY_PATH
|
||||
${bumblebee.override {nvidia_x11 = nvidia; nvidia_x11_i686 = nvidia.lib32;}}/bin/optirun --ldpath ${lib.makeLibraryPath ([libglvnd nvidia] ++ lib.optionals enable32bits [nvidia.lib32 pkgsi686Linux.libglvnd])} "$@"
|
||||
'';
|
||||
});
|
||||
|
||||
# TODO: 32bit version? Not tested.
|
||||
nixNvidiaWrapper = api: addNvidiaVersion (writeExecutable {
|
||||
name = "nix${api}Nvidia";
|
||||
text = ''
|
||||
#!${runtimeShell}
|
||||
${lib.optionalString (api == "Vulkan") ''export VK_LAYER_PATH=${vulkan-validation-layers}/share/vulkan/explicit_layer.d''}
|
||||
|
||||
${lib.optionalString (api == "Vulkan") ''export VK_ICD_FILENAMES=${nvidiaLibsOnly}/share/vulkan/icd.d/nvidia.json${lib.optionalString enable32bits ":${nvidiaLibsOnly.lib32}/share/vulkan/icd.d/nvidia.json"}:$VK_ICD_FILENAMES''}
|
||||
export LD_LIBRARY_PATH=${lib.makeLibraryPath ([
|
||||
libglvnd
|
||||
nvidiaLibsOnly
|
||||
] ++ lib.optional (api == "Vulkan") vulkan-validation-layers
|
||||
++ lib.optionals enable32bits [nvidiaLibsOnly.lib32 pkgsi686Linux.libglvnd])
|
||||
}:''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
|
||||
"$@"
|
||||
'';
|
||||
});
|
||||
|
||||
# TODO: 32bit version? Not tested.
|
||||
nixGLNvidia = nixNvidiaWrapper "GL";
|
||||
|
||||
# TODO: 32bit version? Not tested.
|
||||
nixVulkanNvidia = nixNvidiaWrapper "Vulkan";
|
||||
|
||||
nixGLIntel = writeExecutable {
|
||||
name = "nixGLIntel";
|
||||
# add the 32 bits drivers if needed
|
||||
text = let
|
||||
drivers = [mesa_drivers] ++ lib.optional enable32bits pkgsi686Linux.mesa_drivers;
|
||||
in ''
|
||||
#!${runtimeShell}
|
||||
export LIBGL_DRIVERS_PATH=${lib.makeSearchPathOutput "lib" "lib/dri" drivers}
|
||||
export LD_LIBRARY_PATH=${
|
||||
lib.makeLibraryPath drivers
|
||||
}:$LD_LIBRARY_PATH
|
||||
"$@"
|
||||
'';
|
||||
};
|
||||
|
||||
nixVulkanIntel = writeExecutable {
|
||||
name = "nixVulkanIntel";
|
||||
text = let
|
||||
# generate a file with the listing of all the icd files
|
||||
icd = runCommand "mesa_icd" {}
|
||||
(
|
||||
# 64 bits icd
|
||||
''ls ${mesa_drivers}/share/vulkan/icd.d/*.json > f
|
||||
''
|
||||
# 32 bits ones
|
||||
+ lib.optionalString enable32bits ''ls ${pkgsi686Linux.mesa_drivers}/share/vulkan/icd.d/*.json >> f
|
||||
''
|
||||
# concat everything as a one line string with ":" as seperator
|
||||
+ ''cat f | xargs | sed "s/ /:/g" > $out''
|
||||
);
|
||||
in ''
|
||||
#!${runtimeShell}
|
||||
if [ -n "$LD_LIBRARY_PATH" ]; then
|
||||
echo "Warning, nixVulkanIntel overwriting existing LD_LIBRARY_PATH" 1>&2
|
||||
fi
|
||||
export VK_LAYER_PATH=${vulkan-validation-layers}/share/vulkan/explicit_layer.d
|
||||
ICDS=$(cat ${icd})
|
||||
export VK_ICD_FILENAMES=$ICDS:$VK_ICD_FILENAMES
|
||||
export LD_LIBRARY_PATH=${lib.makeLibraryPath [
|
||||
zlib
|
||||
libdrm
|
||||
xorg.libX11
|
||||
xorg.libxcb
|
||||
xorg.libxshmfence
|
||||
wayland
|
||||
gcc.cc
|
||||
]}:$LD_LIBRARY_PATH
|
||||
exec "$@"
|
||||
'';
|
||||
};
|
||||
|
||||
nixGLCommon = nixGL:
|
||||
runCommand "nixGLCommon" {
|
||||
buildInuts = [nixGL];
|
||||
}
|
||||
''
|
||||
mkdir -p "$out/bin"
|
||||
# star because nixGLNvidia... have version prefixed name
|
||||
cp ${nixGL}/bin/* "$out/bin/nixGL";
|
||||
'';
|
||||
|
||||
# The output derivation contains nixGL which point either to
|
||||
# nixGLNvidia or nixGLIntel using an heuristic.
|
||||
nixGLDefault =
|
||||
if _nvidiaVersion != null then
|
||||
nixGLCommon nixGLNvidia
|
||||
else
|
||||
nixGLCommon nixGLIntel
|
||||
;
|
||||
}
|
Loading…
Reference in New Issue
Block a user