diff --git a/internal/discover/graphics.go b/internal/discover/graphics.go index b7efec8b..c1768149 100644 --- a/internal/discover/graphics.go +++ b/internal/discover/graphics.go @@ -56,6 +56,9 @@ func NewGraphicsMountsDiscoverer(logger logger.Interface, driver *root.Driver, n driver.Root, []string{ "libnvidia-egl-gbm.so.*", + "libnvidia-egl-wayland.so.*", + "libnvidia-allocator.so.*", + "libnvidia-vulkan-producer.so.*", }, ) @@ -74,17 +77,75 @@ func NewGraphicsMountsDiscoverer(logger logger.Interface, driver *root.Driver, n }, ) + symlinks := newGraphicsDriverSymlinks(logger, libraries, nvidiaCDIHookPath) xorg := optionalXorgDiscoverer(logger, driver, nvidiaCDIHookPath) discover := Merge( libraries, jsonMounts, + symlinks, xorg, ) return discover, nil } +type graphicsDriverSymlinks struct { + None + logger logger.Interface + libraries Discover + nvidiaCDIHookPath string +} + +var _ Discover = (*graphicsDriverSymlinks)(nil) + +func newGraphicsDriverSymlinks(logger logger.Interface, libraries Discover, nvidiaCDIHookPath string) Discover { + return &graphicsDriverSymlinks{ + logger: logger, + libraries: libraries, + nvidiaCDIHookPath: nvidiaCDIHookPath, + } +} + +// Create necessary library symlinks for graphics drivers +func (d graphicsDriverSymlinks) Hooks() ([]Hook, error) { + mounts, err := d.libraries.Mounts() + + if err != nil { + return nil, fmt.Errorf("failed to get library mounts: %v", err) + } + + links := []string{} + + for _, mount := range mounts { + filename := filepath.Base(mount.HostPath) + + // nvidia-drm_gbm.so is a symlink to libnvidia-allocator.so + // Make sure this is actually available + if strings.HasPrefix(filename, "libnvidia-allocator.so.") { + linkDir := filepath.Dir(mount.Path) + linkPath := filepath.Join(linkDir, "gbm", "nvidia-drm_gbm.so") + target := filepath.Join("..", filename) + links = append(links, fmt.Sprintf("%s::%s", target, linkPath)) + } + + // Address the vulkan-producer lib for nvidia drivers prior driver version 545 + if strings.HasPrefix(filename, "libnvidia-vulkan-producer.so.") { + linkDir := filepath.Dir(mount.Path) + linkPath := filepath.Join(linkDir, "libnvidia-vulkan-producer.so") + links = append(links, fmt.Sprintf("%s::%s", filename, linkPath)) + } + } + + if len(links) == 0 { + return nil, nil + } + + hooks := CreateCreateSymlinkHook(d.nvidiaCDIHookPath, links) + + return hooks.Hooks() +} + type drmDevicesByPath struct { None logger logger.Interface @@ -251,6 +312,26 @@ func optionalXorgDiscoverer(logger logger.Interface, driver *root.Driver, nvidia return xorg } +func buildXOrgSearchPaths(libRoot string) []string { + paths := []string{ + libRoot + "/nvidia/xorg", + } + + directories := []string{"drivers", "extensions"} + pathOptions := []string{"modules", "modules/updates"} + prefixes := []string{libRoot + "/xorg", "/usr/lib/xorg", "/usr/lib64/xorg", "/usr/X11R6/lib", "/usr/X11R6/lib64"} + + for _, prefix := range prefixes { + for _, pathOption := range pathOptions { + for _, directory := range directories { + paths = append(paths, prefix+"/"+pathOption+"/"+directory) + } + } + } + + return paths +} + func newXorgDiscoverer(logger logger.Interface, driver *root.Driver, nvidiaCDIHookPath string) (Discover, error) { libCudaPaths, err := cuda.New( driver.Libraries(), @@ -271,13 +352,13 @@ func newXorgDiscoverer(logger logger.Interface, driver *root.Driver, nvidiaCDIHo lookup.NewFileLocator( lookup.WithLogger(logger), lookup.WithRoot(driver.Root), - lookup.WithSearchPaths(libRoot, "/usr/lib/x86_64-linux-gnu"), + lookup.WithSearchPaths(buildXOrgSearchPaths(libRoot)...), lookup.WithCount(1), ), driver.Root, []string{ - "nvidia/xorg/nvidia_drv.so", - fmt.Sprintf("nvidia/xorg/libglxserver_nvidia.so.%s", version), + "nvidia_drv.so", + fmt.Sprintf("libglxserver_nvidia.so.%s", version), }, ) xorgHooks := xorgHooks{ @@ -290,7 +371,10 @@ func newXorgDiscoverer(logger logger.Interface, driver *root.Driver, nvidiaCDIHo logger, driver.Configs(), driver.Root, - []string{"X11/xorg.conf.d/10-nvidia.conf"}, + []string{ + "X11/xorg.conf.d/10-nvidia.conf", + "X11/xorg.conf.d/nvidia-drm-outputclass.conf", + }, ) d := Merge(