Wie ich SDL-Games unter TwinView auf nur einem Bildschirm spiele
Wie ich bereits in einem früheren Post schrieb, nenne ich jetzt eine Dell Precision M4500 Mobile Workstation mein Eigen. Ich betreibe das Gerät gedockt mit dem Euro 1 Port Replicatorvon Dell an zwei Full HD-Displays. Auf dem Gerät läuft Fedora 14, die nVidia Corporation GT216 [Quadro FX 880M] treibt der Herstellertreiber an (nvidia.ko) den ich von rpmfusion nachinstalliert habe.
Nachdem ich anfängliche Problemen mit dem Compositing (Desktop-Effekte) im KDE Windowmanager gelöst hatte, wollte ich zur Entspannung eine kleine Spielsession einlegen, allerdings kam schnell Ernüchterung. Spiele die im Vollbildmodus starteten, breiteten sich über die voll Breite von 3840×1080 Pixeln über die beiden Displays aus. Dies hatte zum Effekt, dass die Spielhandlung von der Lücke zwischen den Displays unterbrochen wurde – unschön.
Eine erste Suche brachte zutage, dass das Problem ein Protokoll namens „TwinView“ ist, welches mehrere Displays an der selben Karte zu einem einzigen Desktop zusammenfasst. Während KWin hier noch die einzelnen Displays zu differenzieren vermag, sehen XRandR basierte Programme, vor allem also auch SDL-basierte Spiele, nur ein Display, wovon man sich durch folgenden Shell-Befehl überzeugen kann:
<td>
<div class="text codecolorer">
$ xrandr --query<br /> xrandr: Failed to get size of gamma for output default<br /> Screen 0: minimum 3840 x 1080, current 3840 x 1080, maximum 3840 x 1080<br /> default connected 3840x1080+0+0 0mm x 0mm<br /> 3840x1080 50.0*<br /> [(/cc]<br /> <br /> Ich startete die Konfigurationssoftware von NVidia um die Optionen zu prüfen, die diese mir zur Verfügung stellt. Als erstes probierte ich die X11-Erweiterung Xinerama, welche vor TwinView die einzige offizielle Möglichkeit für den Mehrmonitorbetrieb war. Leider war das nicht von Erfolg gekrönt, da der 3D-Beschleunigung und Xinerama sich im Moment gegenseitig ausschließen.<br /> <br /> Also versuchte ich das Problem mit TwinView zu lösen. Ich habe es letztendlich damit umgesetzt, indem ich weitere MetaModes in die Datei /etc/X11/xorg,conf eingetragen habe:<br /> <br /> [cc]<br /> <br /> # nvidia-settings: X configuration file generated by nvidia-settings<br /> # nvidia-settings: version 260.19.29 (mockbuild@hephaestus.wilsonet.com) Thu Dec 16 04:43:59 EST 2010<br /> <br /> # nvidia-xconfig: X configuration file generated by nvidia-xconfig<br /> # nvidia-xconfig: version 260.19.36 (mockbuild@) Sat Jan 22 06:36:47 EST 2011<br /> # RPM Fusion - nvidia-xorg.conf<br /> #<br /> <br /> Section "ServerLayout"<br /> <br /> Identifier "Default Layout"<br /> Screen 0 "Screen0" 0 0<br /> InputDevice "Keyboard0" "CoreKeyboard"<br /> InputDevice "Mouse0" "CorePointer"<br /> Option "Xinerama" "0"<br /> EndSection<br /> <br /> Section "InputDevice"<br /> <br /> # generated from data in "/etc/sysconfig/keyboard"<br /> Identifier "Keyboard0"<br /> Driver "keyboard"<br /> Option "XkbLayout" "de"<br /> Option "XkbModel" "pc105"<br /> Option "XkbVariant" "nodeadkeys"<br /> EndSection<br /> <br /> Section "InputDevice"<br /> <br /> # generated from default<br /> Identifier "Mouse0"<br /> Driver "mouse"<br /> Option "Protocol" "auto"<br /> Option "Device" "/dev/input/mice"<br /> Option "Emulate3Buttons" "no"<br /> Option "ZAxisMapping" "4 5"<br /> EndSection<br /> <br /> Section "Monitor"<br /> Identifier "Monitor0"<br /> VendorName "Unknown"<br /> ModelName "LG Electronics W2443"<br /> HorizSync 30.0 - 83.0<br /> VertRefresh 56.0 - 75.0<br /> Option "DPMS"<br /> EndSection<br /> <br /> Section "Monitor"<br /> Identifier "Monitor1"<br /> VendorName "Unknown"<br /> ModelName "LG Electronics W2443"<br /> HorizSync 30.0 - 83.0<br /> VertRefresh 56.0 - 75.0<br /> Option "DPMS"<br /> EndSection<br /> <br /> Section "Device"<br /> Identifier "Videocard0"<br /> Driver "nvidia"<br /> EndSection<br /> <br /> Section "Device"<br /> Identifier "Device0"<br /> Driver "nvidia"<br /> VendorName "NVIDIA Corporation"<br /> BoardName "Quadro FX 880M"<br /> Option "RenderAccel" "true"<br /> Option "AllowGLXWithComposite" "true"<br /> EndSection<br /> <br /> Section "Device"<br /> Identifier "Device1"<br /> Driver "nvidia"<br /> VendorName "NVIDIA Corporation"<br /> BoardName "Quadro FX 880M"<br /> BusID "PCI:1:0:0"<br /> Screen 1<br /> Option "RenderAccel" "true"<br /> Option "AllowGLXWithComposite" "true"<br /> EndSection<br /> <br /> Section "Screen"<br /> Identifier "Default Screen"<br /> Device "Videocard0"<br /> Monitor "Monitor0"<br /> SubSection "Display"<br /> Modes "nvidia-auto-select"<br /> EndSubSection<br /> EndSection<br /> <br /> Section "Screen"<br /> <br /> Identifier "Screen0"<br /> Device "Device0"<br /> Monitor "Monitor0"<br /> DefaultDepth 24<br /> Option "TwinView" "1"<br /> Option "metamodes" "DFP-0: nvidia-auto-select +0+0, DFP-1: nvidia-auto-select +1920+0;NULL, DFP-1: nvidia-auto-select +0+0"<br /> SubSection "Display"<br /> Depth 24<br /> EndSubSection<br /> EndSection<br /> <br /> Section "Screen"<br /> Identifier "Screen1"<br /> Device "Device1"<br /> Monitor "Monitor1"<br /> DefaultDepth 24<br /> Option "TwinView" "0"<br /> Option "metamodes" "DFP-1: nvidia-auto-select +0+0"<br /> SubSection "Display"<br /> Depth 24<br /> EndSubSection<br /> EndSection<br /> <br /> Section "Extensions"<br /> Option "Composite" "Enabled"<br /> EndSection
</div>
</td>
</tr>
Der wesentliche Eintrag findet sich in Zeile 111:
<td>
<div class="text codecolorer">
...<br /> <br /> Option "metamodes" "DFP-0: nvidia-auto-select +0+0, DFP-1: nvidia-auto-select +1920+0;NULL, DFP-1: nvidia-auto-select +0+0"<br /> <br /> ...
</div>
</td>
</tr>
Das Semikolon trennt dabei die verfügbaren Modi. Für jeden Modus sind die aktiven Displays, deren Auflösung und deren Relative Position zueinander angegeben. Nehmen wir also die erste Definition „DFP-0: nvidia-auto-select +0+0, DFP-1: nvidia-auto-select +1920+0“, so sagt diese, dass es zwei Displays – DFP-0 und DFP-1 – gibt, deren Auflösung automatisch ermittelt werden soll und wobei das Display DFP-1 das Gesamtbild ab dem 1920. Pixel horizontal darstellt. Diese Angabe ist der Standard und sagt nichts weiter, als dass das Display DFP-1 rechts von DFP-0 steht, wobei DFP-0 eine horizontale Auflösung von 1920 Pixeln hat.
Für die Lösung meines Eingangs beschriebenen Problems ist die rechte Defintion die interessantere. „NULL, DFP-1: nvidia-auto-select +0+0“ sagt nämlich, dass das erste Display – das Linke – ausgeschaltet werden soll (NULL) und das rechte den Bildinhalt ab der linken oberen Ecke des Gesamtbildes mit der automatisch ermittelten Auflösung darstellen soll.
Mit dieser Defintion gibt XRandR folgendes aus:
<td>
<div class="text codecolorer">
$ xrandr --query<br /> <br /> xrandr: Failed to get size of gamma for output default<br /> Screen 0: minimum 1920 x 1080, current 3840 x 1080, maximum 3840 x 1080<br /> default connected 3840x1080+0+0 0mm x 0mm<br /> 3840x1080 50.0*<br /> 1920x1080 51.0
</div>
</td>
</tr>
Wie man sieht stehen nun zwei Auflösungen bereit. Einmal die (derzeit aktive) Auflösung über beide Displays (Doppeltes horizontales Full-HD) und einmal nur die normale Full-HD-Auflösung. Über die Tastenkombination Strg-Alt-+ lässt sich auf die nächste verfügbare Auflösung umschalten, mit Strg-Alt– (Minus) auf die Vorherige. Auch in Spielen und anderen Programme, welche XRandR verwenden, stehen diese Auflösungen nun in den Optionen zur Auswahl.
Und damit wünsche ich viel Spaß beim Zocken (Oder Arbeiten) 🙂