Skip to main content

Dolphin pour RomM

RomM — Emulator Streaming avec Dolphin sur Unraid (GPU NVIDIA)

Ce tutoriel explique comment ajouter un conteneur Dolphin (GameCube/Wii) à une instance RomM 5.1.0+ existante pour utiliser la fonctionnalité Emulator Streaming : lancer un jeu depuis l'interface RomM et y jouer dans le navigateur, avec rendu et encodage sur le GPU NVIDIA.

Architecture : RomM ne pilote pas Dolphin directement. Un Docker Mod (maintenu par LoneAngelFayt) injecte dans le conteneur Dolphin un broker HTTP (port 8000) que RomM contacte pour lancer/piloter les jeux. L'image et le son sont diffusés par Selkies (le bureau web intégré aux images LinuxServer), en H.264 NVENC.

⚠️ Testé avec : Unraid 7, RTX 3060, driver NVIDIA 610.x, lscr.io/linuxserver/dolphin:latest (base Selkies/Wayland), RomM 5.1.0.


1. Prérequis Unraid

1.1 Plugin Nvidia Driver

  • Installer le plugin Nvidia Driver (Community Applications).
  • Driver propriétaire 580 ou supérieur requis. LinuxServer recommande la branche Production pour Unraid.
  • Le GPU ne doit pas être réservé au VFIO (il doit être disponible pour Docker).
  • Sur un serveur headless (sans écran), la doc LinuxServer indique qu'un dummy plug HDMI/DP branché sur la carte est requis pour que DRM s'initialise correctement.

1.2 Paramètres noyau (Syslinux)

Menu Main → Flash → Syslinux Config (vue Raw), ajouter à la fin de la ligne append de l'entrée « Unraid OS » (et « Unraid OS GUI Mode » si utilisée) :

nvidia-drm.modeset=1 nvidia_drm.fbdev=1

Redémarrer le serveur, puis vérifier :

cat /proc/cmdline                                    # les 2 paramètres doivent apparaître
cat /sys/module/nvidia_drm/parameters/modeset        # doit renvoyer Y
nvidia-smi -L                                        # liste le(s) GPU + UUID

Notez l'UUID du GPU (GPU-xxxxxxxx-...), il servira dans le template.

1.3 Limite inotify (optionnel mais recommandé)

Les images Selkies consomment beaucoup d'instances inotify. Pour éviter l'avertissement « Too many open files » :

sysctl -w fs.inotify.max_user_instances=1024
echo 'sysctl -w fs.inotify.max_user_instances=1024' >> /boot/config/go

2. ⚠️ Correctif indispensable : composant NVIDIA egl-x11

C'est le point qui fait échouer la plupart des installations (symptôme : interface Dolphin visible, mais zone de jeu noire avec le son, ou jeu qui rame énormément en rendu logiciel).

Le runtime NVIDIA d'Unraid injecte dans les conteneurs les plateformes EGL wayland, wayland2 et gbm, mais pas les deux plateformes X11 (xlib/xcb) — pourtant livrées par le driver et indispensables à Dolphin, qui crée son contexte OpenGL via EGL sur X11. Sans elles, l'EGL NVIDIA ne peut pas créer de surface et Dolphin retombe en rendu logiciel (ou écran noir via Zink : MESA: error: zink: could not create swapchain).

Vérifier que le driver de l'hôte fournit bien les fichiers :

ls /var/local/overlay/usr/lib64/ | grep egl-x
ls /var/local/overlay/usr/share/egl/egl_external_platform.d/ | grep -E "xlib|xcb"

Vous devez voir libnvidia-egl-xlib.so.1.X.X, libnvidia-egl-xcb.so.1.X.X, 20_nvidia_xlib.json et 20_nvidia_xcb.json. Notez le numéro de version exact des .so (ex. 1.0.5) : il est utilisé dans les montages ci-dessous, et il change à chaque mise à jour du driver (voir §7).

Le correctif consiste en 4 montages en lecture seule + 1 variable, intégrés au template Dolphin de la section suivante.


3. Conteneur Dolphin

Ajouter un conteneur avec l'image lscr.io/linuxserver/dolphin et la configuration suivante.

3.1 Générer un secret partagé

Ce secret authentifie les échanges RomM ↔ broker. Générez-le une fois :

openssl rand -hex 32

3.2 Ports (host:container)

Port hôte Port conteneur Rôle
37003000 3000 Selkies HTTP (peu utile)
37013001 3001 Selkies HTTPS (le flux de jeu)
8000 8000 Broker RomM

Adaptez les ports hôte s'ils sont déjà pris.pris par un autre conteneur (dans ce cas, reportez le port choisi dans le bloc streaming du §4.2).

3.3 Variables d'environnement

Variable Valeur Remarque
DOCKER_MODS ghcr.io/loneangelfayt/dolphin-romm-integration-mod:latest installe le broker
ROM_ROOT /romm/library racine de la bibliothèque vue par le broker
BROKER_SECRET (votre secret) même valeur que côté RomM
NVIDIA_VISIBLE_DEVICES (UUID du GPU) ou all si un seul GPU
NVIDIA_DRIVER_CAPABILITIES all
DRINODE /dev/dri/renderD128 GPU de rendu (vérifier avec ls -l /dev/dri/by-path/ que c'est bien la carte NVIDIA)
DRI_NODE /dev/dri/renderD128 GPU d'encodage — identique = mode Zero-Copy
SELKIES_MANUAL_WIDTH 1920 bride la résolution du flux
SELKIES_MANUAL_HEIGHT 1080 sinon elle suit la fenêtre du navigateur (coûteux)
__EGL_VENDOR_LIBRARY_FILENAMES /usr/share/glvnd/egl_vendor.d/10_nvidia.json force l'EGL NVIDIA (fait partie du correctif §2)
PUID / PGID 99 / 100 standard Unraid

3.4 Extra Parameters

--gpus all --runtime nvidia --shm-size=1gb

3.5 Volumes

Host Path Container Path Mode
(votre dossier de ROMs — le même que celui monté dans RomM) /romm/library ro
(votre appdata, ex. /mnt/user/appdata/dolphin) /config rw
/var/local/overlay/usr/lib64/libnvidia-egl-xlib.so.1.X.X /usr/lib64/libnvidia-egl-xlib.so.1 ro
/var/local/overlay/usr/lib64/libnvidia-egl-xcb.so.1.X.X /usr/lib64/libnvidia-egl-xcb.so.1 ro
/var/local/overlay/usr/share/egl/egl_external_platform.d/20_nvidia_xlib.json /usr/share/egl/egl_external_platform.d/20_nvidia_xlib.json ro
/var/local/overlay/usr/share/egl/egl_external_platform.d/20_nvidia_xcb.json /usr/share/egl/egl_external_platform.d/20_nvidia_xcb.json ro

Remplacez 1.X.X par la version relevée au §2. Le Container Path des libs est volontairement le nom court .so.1 : c'est celui que le loader EGL recherche (déclaré dans les JSON), ce qui évite d'avoir à créer des symlinks.

💡 Important : le chemin de la bibliothèque doit être identique dans RomM et dans Dolphin (/romm/library des deux côtés), sinon le broker ne retrouvera pas les fichiers que RomM lui demande de lancer.

3.6 Vérifications après démarrage

docker logs dolphin 2>&1 | grep -iE "broker|NVENC|Zero-Copy"

Attendu : ROM broker listening on port 8000, Shared secret auth enabled, NVENC ... Initialized successfully, Decision: Zero-Copy path active.

curl -s http://localhost:8000/health        # → {"status":"ok"}
docker exec dolphin sh -c 'ldconfig -p | grep egl-x'   # → les 2 libs xlib/xcb

4. Côté RomM

4.1 Variable d'environnement

Ajouter au conteneur RomM :

Variable Valeur
STREAMING_BROKER_SECRET (le même secret qu'au §3.1)

4.2 config.yml

Dans le config.yml de RomM (dossier config), ajouter le bloc streaming (adapter l'IP du serveur et les ports choisis) :

streaming:
  enabled: true
  containers:
    - platform: ngc
      host: https://IP_DU_SERVEUR:37013001
      broker_host: http://IP_DU_SERVEUR:8000
      label: Dolphin
      memory_card_sync: true
    - platform: wii
      host: https://IP_DU_SERVEUR:37013001
      broker_host: http://IP_DU_SERVEUR:8000
      label: Dolphin

Redémarrer RomM après modification.

4.3 Structure de la bibliothèque

  • Le dossier de plateforme doit correspondre au fs_slug de RomM : ngc pour la GameCube, wii pour la Wii (pas gc, pas gamecube) — sinon prévoir un mappage dans config.yml.
  • Les ROMs doivent être des fichiers directs (.rvz, .iso) — pas d'archives .zip/.7z, Dolphin ne peut pas les lancer via le broker.
  • ⚠️ RomM supporte deux structures (library/roms/<plateforme>/ ou library/<plateforme>/roms/) mais la simple présence d'un dossier library/roms/ fait basculer toute la bibliothèque sur la première : ne mélangez pas les deux, ou toutes vos autres plateformes deviendront invisibles au scan.

Rescanner la plateforme dans RomM après tout changement.


5. Premier lancement

  1. Ouvrir une première fois https://IP_DU_SERVEUR:37013001 et accepter le certificat auto-signé (sinon le flux ne se chargera pas dans RomM).
  2. Dans RomM, ouvrir la fiche d'un jeu GameCube → bouton Play on Dolphin.
  3. Le jeu doit s'afficher, fluide, avec le son.

Vérifier que le GPU est bien utilisé (pendant qu'un jeu tourne) :

docker exec -u abc dolphin sh -c 'for p in /proc/[0-9]*; do ls -l $p/fd 2>/dev/null | grep -q nvidia && echo "$(basename $p) $(tr "\0" " " < $p/cmdline | cut -c1-60)"; done'

dolphin-emu doit apparaître dans la liste. S'il n'y a que selkies, labwc et Xwayland, Dolphin est en rendu logiciel → revoir le §2.

Note : lancez bien ce test avec -u abc — en root, la lecture de /proc/<pid>/fd des processus de l'utilisateur abc échoue silencieusement.


6. Réglages Dolphin utiles

Le fichier de configuration est <appdata>/. config/dolphin-emu/Dolphin.ini. Toujours éditer conteneur arrêté (Dolphin réécrit ses fichiers en se fermant), et savoir que le mod réimpose GFXBackend = OpenGL à chaque recréation du conteneur — c'est le bon backend ici (c'est le chemin EGL corrigé au §2), ne pas chercher à le changer.

Réglage recommandé (section [Core]) :

CPUThread = True

C'est le mode « Dual Core » de Dolphin ; selon les versions il peut être désactivé par défaut, et son absence coûte très cher en performances.


7. Maintenance et limites connues

  • À chaque mise à jour du driver NVIDIA de l'hôte, le nom des libs (libnvidia-egl-*.so.1.X.X) change : mettre à jour les 2 Host Path correspondants dans le template Dolphin, sinon écran noir / rendu logiciel au retour.
  • Une seule session à la fois par conteneur : un conteneur = une instance Dolphin = un flux. Pour du multi-joueurs simultané, dupliquer le conteneur (autres ports, autre secret possible) et ajouter une entrée dans streaming.containers.
  • Sessions fantômes : fermer l'onglet du navigateur ne tue pas Dolphin ; la session peut rester occupée. En attendant mieux : docker exec dolphin pkill dolphin-emu.
  • Les paquets installés à la main dans le conteneur (apt-get) ne survivent pas à une recréation. Pour des outils de diagnostic permanents, chaîner le mod universal-package-install : DOCKER_MODS=ghcr.io/loneangelfayt/dolphin-romm-integration-mod:latest|linuxserver/mods:universal-package-install + INSTALL_PACKAGES=vulkan-tools|mesa-utils|x11-utils.

8. Dépannage rapide

Symptôme Cause probable Solution
« ROMs not found » au scan Nom de dossier ≠ fs_slug, ou structures mélangées §4.3
Pas de bouton « Play on Dolphin » Bloc streaming absent/invalide, ou secret différent §4.1–4.2
Flux ne se charge pas dans RomM Certificat auto-signé jamais accepté §5.1
Jeu très lent, dolphin-emu absent du test des fd Rendu logiciel (egl-x11 manquant) §2
Zone de jeu noire, interface et son OK Idem — Zink sans présentation possible §2 (et retirer d'éventuelles variables MESA_LOADER_DRIVER_OVERRIDE/GALLIUM_DRIVER)
Écran noir après une mise à jour du driver Version des libs changée §7
« Failed to initialize video backend » Variables graphiques parasites ou backend forcé à Vulkan Revenir à la config §3, GFXBackend = OpenGL