Compare commits

...

67 Commits

Author SHA1 Message Date
Suzanne Soy
b93246bced regenerated flake.lock, added another Nvidia version & hash in a comment 2020-11-10 20:13:19 +00:00
Suzanne Soy
68e1819b88 flake (part 2 with changes to flake.nix) 2020-11-10 01:51:06 +00:00
Suzanne Soy
7dcd280d44 flake (part 1 with rename) 2020-11-10 01:50:48 +00:00
Guillaume Bouchard
210c6a8a54
Merge pull request #59 from tudurom/master
Use runtimeShell instead of #!/usr/bin/env sh
2020-07-27 11:12:54 +02:00
Guillaume Bouchard
6fab1faca5
Merge pull request #57 from yilinwei/patch-1
Update README.md
2020-07-24 22:56:58 +02:00
Yilin Wei
ab5c39d32e
Update README.md
vulkan-loader doesn't have vulkaninfo
2020-07-19 18:30:37 +01:00
Guillaume Bouchard
e7039bfb2c
Merge pull request #56 from guibou/nvidia_main_libs_only
Do not build nvidia linux module for nixGLNvidia
2020-07-02 17:23:34 +02:00
Guillaume Bouchard
410cd5b482 Do not build nvidia linux module for nixGLNvidia
Partial fix for #55.

This commit does not build the nvidia kernel module for `nixGLNvidia`
using `libsOnly = true`.

This cannot be applied to `nixGLNvidiaBumblebee` which needs some stuffs
in `nvidia_x11.bin` which only appears if it is built with `libsOnly =
false`.
2020-06-10 17:23:31 +02:00
Tudor Roman
339c6c5795
use runtimeShell instead of #!/usr/bin/env sh 2020-06-08 14:05:27 +03:00
Guillaume Bouchard
5f330c2185
Merge pull request #45 from lopsided98/nvidia-local-build
Test.hs: make sure to build the impure NVIDIA version derivation locally
2020-04-30 18:55:59 +02:00
Ben Wolsieffer
7bb080c0e5 Test.hs: make sure to build the impure NVIDIA version derivation locally 2020-04-29 23:45:54 -04:00
Guillaume Bouchard
76196e5da3
Merge pull request #40 from zimbatm/nvidia-version-file
Nvidia version file
2020-04-28 17:12:48 +02:00
zimbatm
4c09910428
handle nixGLDefault with nvidiaVersionFile 2020-04-28 16:57:16 +02:00
Guillaume Bouchard
b5660a81bd
Merge pull request #42 from zimbatm/readme
README: document nixGLDefault
2020-04-28 16:39:07 +02:00
zimbatm
4fb0203a54
README: document nixGLDefault 2020-04-28 16:02:50 +02:00
zimbatm
7aa1cce7c6
allow to pass a nvidiaVersionFile
This allows to better control which driver is being loaded.
2020-04-28 15:27:24 +02:00
Guillaume Bouchard
7f934a88ce
Merge pull request #41 from zimbatm/github-actions
add Github Action to run the tests
2020-04-28 13:55:15 +02:00
Guillaume Bouchard
3df3a471ae
Merge pull request #39 from zimbatm/test-fixes
Test.hs: fixes the default.nix invocation
2020-04-28 13:54:10 +02:00
zimbatm
06f91bf67e
add Github Action to run the tests
CircleCI doesn't seem to be running on the repository. This also makes
it easy for people who fork the repo to run the CI since it is enabled
by default on all the repositories.
2020-04-28 13:07:15 +02:00
zimbatm
9348b49674
Test.hs: fixes the default.nix invocation
This has been broken by me in d0379a8673
2020-04-28 13:05:53 +02:00
zimbatm
0564a32785
Test.hs: inherit stderr from the parent
This allows to show the progress while building the tests
2020-04-28 12:57:18 +02:00
Guillaume Bouchard
e2cc0101af
Merge pull request #38 from zimbatm/pass-nixpkgs
break: change how nixpkgs is passed to the project
2020-04-28 11:44:59 +02:00
zimbatm
d0379a8673
break: change how nixpkgs is passed to the project
Evaluating nixpkgs is quite expensive and should be done only once if
possible. This allows to pass a correctly-configured instance of nixpkgs
(with allowUnfree = true).

Unfortunately this requires to break the current interface.
2020-04-28 11:37:39 +02:00
Guillaume Bouchard
3db9b5d12a Update test bench for vulkan
- Just check for `driverName` in the output string
2020-04-28 11:04:08 +02:00
Guillaume Bouchard
ace3193d44 Mesa Vulkan: set icd files for all drivers 2020-04-28 11:04:08 +02:00
Guillaume Bouchard
17c1ec63b9 Ignore stderr on tests 2020-04-27 18:01:41 +02:00
Guillaume Bouchard
201b4facf5 A few test cleanup
- disable test for vulkan bumblebee, there is no implementation
2020-04-27 18:01:41 +02:00
Guillaume Bouchard
122026d20c Add nixGLDefault 2020-04-27 18:01:41 +02:00
Guillaume Bouchard
701dfc8c6e Add a bunch of tests for Vulkan 2020-04-27 18:01:41 +02:00
Guillaume Bouchard
a02035314b Add a few VK_ICD_FILENAMES
This is a tentative fix for #28.

I cannot test nvidia, however I confirm it works for Intel (Mesa) cards.
2020-04-27 18:01:41 +02:00
Guillaume Bouchard
d05a776200 Tests:
- Add failure test (to test on nixos, we ensure that it fails with
another libc implementation).
2020-04-27 18:01:41 +02:00
Guillaume Bouchard
7009c94a93 Move to nixGL.nix 2020-04-27 18:01:41 +02:00
Guillaume Bouchard
ae5bc98bb7 Remove the need for an overlay
nvidia_x11 was overrode in an overlay. It is no longer the case and the
override is now explicit.

This will allows the creation of a `nixGL.nix` file callable with
`callPackage`. This change is a preliminary work for inclusion in
`nixpkgs`, as requested in #16.

It will also highly improve the use on nixGL in other project because
user won't have to pass a non initialized `nixpkgs`.
2020-04-27 18:01:41 +02:00
Guillaume Bouchard
237b47397f Add a manual test suite 2020-04-26 23:55:24 +02:00
Guillaume Bouchard
66c92824ab Fix 32 bits for nvidia and nvidia bumblebee
I was able to test for nvidia bumblebee.
2020-04-26 23:55:24 +02:00
Guillaume Bouchard
d5c0d28968 Nvidia: automatic detection of the version
The automatic detection uses the /proc interface proposed by the Nvidia
kernel module.

Having autodetection inside nix, I also changed the way the driver is
fetched, so everything is done inside nix. So no more `nvidiaInstall`
wrapper script.

I updated the `README` accordingly.
2020-04-26 19:51:32 +02:00
Guillaume Bouchard
1ba64e0199 Add support for 32bit in nixGLIntel
This closes #30. OpenGL support for 32bit is unconditionnally added to
nixGLIntel.

- Nvidia with bumblebee seems to work out of the box. I don't know why.
- I don't have the hardware to test vulkan.
- I don't have the hardware to test pure nvidia.
2020-04-26 16:35:07 +02:00
Guillaume Bouchard
3ef7bffcae Use makeLibraryPath when appropriate 2020-04-26 16:35:07 +02:00
Guillaume Bouchard
33282d65db Add simple CI. At least it checks that all targets build 2020-04-26 15:11:58 +02:00
Guillaume Bouchard
d67944d5ae Add a missing separator in the Nvidia wrapper 2020-04-26 15:11:58 +02:00
Joe Hermaszewski
66d99ddb67 Correct vulkan/gl wrapper information in readme 2020-03-22 12:18:48 +01:00
Guillaume Bouchard
f3b50205ef Restore the shellcheck phase and fix it 2020-03-03 20:57:43 +01:00
Guillaume Bouchard
ea7c1d70fc Factorize the writeTextFile common parts 2020-03-03 20:57:43 +01:00
Guillaume Bouchard
13352162de Rewrite all rules using pkgs.writeTextFile
- It is more compact and easier to read
- Escaping is correctly done

This fixs #21 and #22
2020-03-03 20:57:43 +01:00
Joe Hermaszewski
5ba3174763 Add Vulkan validation layers to Nvidia wrapper 2020-02-23 16:52:47 +01:00
Guillaume Bouchard
04a6b0833f Preserve system LD_LIBRARY_PATH 2018-09-27 16:07:00 +02:00
Guillaume Bouchard
a02970d696 Add documentation for legacy driver now that we switch to GLVND 2018-07-10 03:35:54 +02:00
Guillaume Bouchard
fa08b64b31 Use GLVND
This fixes missing symbols
2018-07-10 03:35:54 +02:00
Guillaume Bouchard
9e33a6ecb1 Set --ldrun path for bumblebee.
Instead, optirun looks inside `/usr/lib`.
2018-07-10 02:16:58 +02:00
Guillaume Bouchard
4088ce159e Allow unfree by default 2018-07-10 02:16:42 +02:00
Guillaume Bouchard
2021895c3f Bumblebee now only uses one opengl implementation
Thanks to the `overlay`, `nvidia-x11` is the same across all `nixpkgs`.
2018-07-10 00:50:33 +02:00
Guillaume Bouchard
df9d0ecc16 Add nixGLCommon 2018-06-30 13:10:59 +02:00
Guillaume Bouchard
21764c9926 Nixpkgs version can now be specified as the pkgs argument 2018-06-30 11:32:58 +02:00
Guillaume Bouchard
2b9e5fb6ed Remove version flag
Not really used
2018-06-30 11:32:24 +02:00
Guillaume Bouchard
ed31333b05 Add a note in the readme about nixpkgs versions 2018-06-26 23:49:42 +02:00
Guillaume Bouchard
69644dd5da Fix for bug #10
Recently, most packages which were previously depending on `mesa`
switched to `libGL`, which is supposed to find the host system opengl
library, as long as it is available in the library search path.
2018-05-19 21:52:27 +02:00
Guillaume Bouchard
d78549fef3 Create a wrapper for nvidia install
Hash of nvidia driver is not known because it depends on the driver version
(argument `nvidiaVersion`). However, since nix 2.0 and when using `useSandbox`,
`sha256 = null` is not allowed anymore.

The new wrapper script, `nvidiaInstall.py` uses `nix-prefetch-url` to compute
the hash and call `nix`.

This is a fix for #9
2018-05-19 21:37:45 +02:00
Joe Hermaszewski
624ea697ac Fix vulkan nvidia wrapper (make the wrapper executable) 2018-04-20 09:43:14 +02:00
Guillaume Bouchard
fe935edb01 Update README to tell that it works with most of mesa driver 2018-04-15 14:27:49 +02:00
Guillaume Bouchard
6ffe3132e3
Merge pull request #7 from expipiplus1/vulkan
Add Vulkan support
2018-04-08 17:53:16 +02:00
Joe Hermaszewski
8fda8f8642 Whitespace change in readme 2018-04-07 16:05:15 +08:00
Joe Hermaszewski
0ba511aeb3 Add mesa-vulkan-drivers step to readme 2018-04-07 16:04:24 +08:00
Joe Hermaszewski
5df6048ead Factor out commonalities between NVIDIA wrappers 2018-04-07 16:04:24 +08:00
Joe Hermaszewski
dcf12c42d1 Add information about Vulkan wrappers to readme 2018-04-07 15:57:48 +08:00
Joe Hermaszewski
2388c2ff41 Add nixVulkanNvidia 2018-04-07 15:48:26 +08:00
Joe Hermaszewski
ee5d1d4eee Make nixVulkanIntel more like the other derivations 2018-04-07 15:46:06 +08:00
Joe Hermaszewski
08873181af Add nixVulkanIntel wrapper 2018-04-07 15:40:43 +08:00
9 changed files with 588 additions and 157 deletions

13
.github/workflows/test.yml vendored Normal file
View 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
View File

@ -0,0 +1 @@
/result

208
README.md
View File

@ -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
View 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
View 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)
'';
});
}

View File

@ -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
View 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
View 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
View 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
;
}