NVIDIA / egl-wayland

The EGLStream-based Wayland external platform
MIT License
275 stars 44 forks source link

Overriding the `egl_externalplatform.d` search paths? #39

Closed colemickens closed 2 months ago

colemickens commented 2 years ago

I am examining the NVIDIA driver setup for NixOS. It seems that we might not have EGL setup to work out of the box currently and I'd like to fix that.

We patch our libglvnd to search for drivers in /run/opengl-driver/lib/..., and redirect the egl egl_vendor.d/ and vulkan {icd.d,implicit_layer.d}/ json files to install in /run/opengl-driver/share/{glvnd,vulkan}.

Now I need to get libEGL_nvidia.so to look in /run/opengl-driver/share/egl_externalplatform.d.

To demonstrate:

# this is after I've fixed where `egl_external_platform.d` is placed
❯ tree /run/opengl-driver/share   
/run/opengl-driver/share
├── egl
│   └── egl_external_platform.d
│       └── 10_nvidia_wayland.json
├── glvnd
│   └── egl_vendor.d
│       └── 10_nvidia.json
└── vulkan
    ├── icd.d
    │   └── nvidia_icd.json
    └── implicit_layer.d
        └── nvidia_layers.json

7 directories, 4 files

# just for extra detail as to how Nix tries to handle things:
❯ cat /run/opengl-driver/share/egl/egl_external_platform.d/10_nvidia_wayland.json
{
    "file_format_version" : "1.0.0",
    "ICD" : {
        "library_path" : "/nix/store/q166dlhkm9bdvcwjp2vmlvxwn6gvaawx-nvidia-x11-470.63.01-5.13.16/lib/libnvidia-egl-wayland.so.1"
    }
}

❯ strings $(nix path-info -r /run/current-system | rg libglvnd | rg -v dev | head -1)/lib/libEGL.so | rg "egl_vendor"
/run/opengl-driver/share/glvnd/egl_vendor.d:/etc/glvnd/egl_vendor.d:/usr/share/glvnd/egl_vendor.d
# great!

❯ strings $(nix path-info -r /run/current-system | rg nvidia-x11 | rg -v lib32 | rg -v bin)/lib/libEGL_nvidia.so | rg "egl_extern"
/etc/egl/egl_external_platform.d:/usr/share/egl/egl_external_platform.d
# not so great

Symlinking the json file into the /etc/... search path does seem to get EGL working in Wayland, but that's not really ideal, and we've got to great lengths already to handle things in a Nix-oriented way (in fact, when I squint, this indirection/loader looks somewhat similar in spirit to NixOS's /run/opengl-driver construct).

However, we don't get to build libEGL_nvidia.so, so we can't configure it like we do libglvnd. Are there options for how we can override these search paths at runtime or otherwise?

erik-kz commented 2 years ago

Hi Cole, unfortunately they're not documented AFAICT, but we do support two environment variables that might be helpful here. EGL_EXTERNAL_PLATFORM_CONFIG_FILENAMES specifies a list of platform config files to load and if that is not set, EGL_EXTERNAL_PLATFORM_CONFIG_DIRS specifies a list of directories to search (defaulting to /etc/egl/egl_external_platform.d and /usr/share/egl/egl_external_platform.d). Both use colon as a separator.

cubanismo commented 2 years ago

A note on these env variables: They will not work in setuid/setgid processes to avoid .so injection attacks.

smcv commented 2 years ago

Hi Cole, unfortunately they're not documented AFAICT, but we do support two environment variables that might be helpful here. EGL_EXTERNAL_PLATFORM_CONFIG_FILENAMES specifies a list of platform config files to load and if that is not set, EGL_EXTERNAL_PLATFORM_CONFIG_DIRS specifies a list of directories to search (defaulting to /etc/egl/egl_external_platform.d and /usr/share/egl/egl_external_platform.d). Both use colon as a separator.

As requested in https://github.com/NVIDIA/eglexternalplatform/issues/3 before that repository was archived, it would be great if this could be documented somewhere, so that other modules can interoperate with what libEGL_nvidia.so.0 expects.

My interest in this is that Steam's pressure-vessel (Steam Linux Runtime) tool needs to know how this works so that we can insert the host system's graphics stack (including EGL ICDs and external platforms) into a per-game container (https://github.com/ValveSoftware/steam-runtime/issues/485).