Software-based Genlock for Active Stereo NVIDIA Cards
02.05.2005: HLRS upgraded the CUBE to Fedora Core 3 with Linux 2.6.11, get a new genlock that actually works with kernel 2.6: genlock-20050502.tar.gz. But make sure that the kernel modules "parport_pc" and "lp" are not loaded.
10.01.2005: The CUBE was upgraded to Quadro FX3000 boards, genlock also works with those.
01.03.2004: genlock now compiles with Linux 2.6: genlock-20040301.tar.gz.
05.06.2003: genlock was updated, now modifying of the pixelclock is available as an additional method of doing small corrections (new module parameter "pixelclock"): genlock-20030605.tar.gz.
What Is genlock?
genlock can provide:
- genlocking/framelocking of up to 7 NVIDIA based graphics cards with automatic active stereo synchronization,
- page-flip active stereo with consumer NVIDIA cards (but this is not very well tested).
An extension to genlocked page-flipped active stereo is a simple exercise for the reader (however, if you implement it, we would like to hear from you).
What you need:
- a Linux 2.4 kernel for which you can compile modules,
- the closed source NVIDIA binary-only driver,
- for page-flip stereo, an NVIDIA board,
- for reliable genlocking using active stereo, an NVIDIA graphics card supporting active stereo, i. e. a Quadro,
- special cables plugging into the parallel port:
- for page-flip stereo, a SoftGenLock style cable for connecting your stereo glasses to the parallel port,
- for genlocking, a special parallel cable (see below).
How Does It Work?
For a rough explanation of how it works, have a look at our slides for the Commodity Clusters for Virtual Reality Workshop at the IEEE VR 2003. Additional information may be found in the SoftGenLock sources (we have copied a lot of code from them, especially the code for manipulating the VGA hardware).
The Parallel Synchronization Cable
If you want to genlock several graphics cards you have to build a special cable that you plug into your parallel ports.
The Plugs You Need (at Least)
You will at least need:
- 1 male SUB-D 25 pin plug for the master,
- 1 male SUB-D 25 pin plug for each slave,
- 1 male mini-DIN 3 pin plug for the stereo on the master,
- 1 male mini-DIN 3 pin plug for the stereo on each slave,
- 1 mini-DIN 3 pin Y-cable with one male and two female plugs (if you actually want to connect stereo glasses).
The Stereo Jack
/ 3 \
/ 2 1 \
\ # /
The female 3-pin mini-DIN stereo connector found on many stereo capable graphics boards
(ASCII art stolen from the IRIX stereo(7) man page)
The pins are used as follows:
|Pin||Name||Description||Function in genlock|
|1||Power||Power, +5 or +12 V||-|
|2||Ground||Ground||Ground for parallel port|
|3||Stereo||Stereo sync||Stereo, connect to parallel port|
The Stereo signal alternates between 0V and 5V at the vertical retrace, depending on the eye the image currently shown is destined for.
For more information on stereo cabling consult the stereo(7) man page on IRIX or look at SGI's documentation site. You can also have a look at the Stereo3D Hardware Developer's Handbook at www.stereographics.com.
The Plug for the Parallel Port
\ 13 12 11 10 9 8 7 6 5 4 3 2 1 /
\ 25 24 23 22 21 20 19 18 17 16 15 14 /
|The female parallel port found on most PCs|
|Pin||Name||Register/Bit||Function on master||Function on slave|
|1||Strobe||-C0||Stereo state for slave 3||-|
|2||Data Bit 0||D0||Retrace interrupt for slave 1||-|
|3||Data Bit 1||D1||Retrace interrupt for slave 2||-|
|4||Data Bit 2||D2||Retrace interrupt for slave 3||-|
|5||Data Bit 3||D3||Retrace interrupt for slave 4||-|
|6||Data Bit 4||D4||Retrace interrupt for slave 5||-|
|7||Data Bit 5||D5||Retrace interrupt for slave 6||-|
|8||Data Bit 6||D6||Stereo state for slave 1||-|
|9||Data Bit 7||D7||Stereo state for slave 2||-|
|10||Acknowledge||S6||-||Vertical retrace from master|
|12||Paper End||S5||-||Stereo state from master|
|13||Select||S4||Own stereo state from graphics board||Own stereo state from graphics board|
|14||Auto Feed||-C1||Stereo state for slave 4||-|
|16||Initialize||C2||Stereo state for slave 5||-|
|17||Select Input||-C3||Stereo state for slave 6||-|
|19||Ground||-||Ground for slave 6||-|
|20||Ground||-||Ground for slave 5||-|
|21||Ground||-||Ground for slave 4||-|
|22||Ground||-||Ground for slave 3||-|
|23||Ground||-||Ground for slave 2||-|
|24||Ground||-||Ground for slave 1||Ground for master|
|25||Ground||-||Ground for stereo on own graphics board||Ground for stereo on own graphics board|
A minus sign (-) before the register/bit designation indicates that this value gets inverted on its way from the registers to the pin.
Look here, for a nice picture and more information on the PC parallel port.
So, How Should You Solder Your Cables?
On each computer connect the Stereo sync from your graphics board with Pin 13 on its parallel port and connect the Ground on the stereo jack to a Ground pin on the parallel port.
Then for each slave, connect a Ground pin of its parallel port with a Ground pin on the master. Then connect for each slave its Acknowledge pin (pin 10) with the corresponding retrace interrupt pin on the master. Each time the Acknowledge pin goes HIGH on a slave, it will trigger an interrupt on the parallel port. Finally, connect Paper End on the slave to its corresponding stereo state pin on the master.
Actually, all slaves and all pins for the slaves on the master are the same, so you can connect them as you please (as long as you connect Ground to Ground, ...).
Building the genlock Kernel Module
Proceed as follows:
- unpack the source code: <tt>tar xzvf genlock-XXXXXXXX.tar.gz</tt>,
- change to the newly created directory: <tt>cd genlock-XXXXXXXX</tt>,
- build it: <tt>make</tt>,
- install it (with super-user privileges): <tt>make install</tt>.
If you don't want to build it for the kernel you are currently using, or if the <tt>build</tt> directory in the modules directory of your kernel does not point to your configured kernel sources, then you have to adapt the <tt>KERNEL=</tt> line in the <tt>Makefile</tt>.
Loading the genlock Module
The most important parameters that the genlock module accepts are:
|<tt>debug</tt>||Debug level, higher values log more information to syslog|
|<tt>nv_irq</tt>||NVIDIA interrupt, number of the interrupt line the graphics board uses (look at <tt>/proc/interrupts</tt> for finding it)|
|<tt>lp_irq</tt>||Parallel port interrupt, number of the interrupt line your parallel port uses|
|<tt>lp_base</tt>||Parallel port base address, (look at <tt>/proc/ioports</tt>)|
|<tt>master</tt>||Set to <tt>1</tt>, if you want to be this host the master|
|<tt>sharedirq</tt>||Set to <tt>1</tt>, if the interrupt line of the graphics board is shared with another device|
|<tt>lp_genlock</tt>||Set to <tt>1</tt>, if you want to do frame synchronization/genlocking via the printer port|
|<tt>lp_stereo</tt>||Set to <tt>1</tt>, if you have your stereo glasses connected to the parallel port (does not work together with <tt>lp_genlock=1</tt>)|
|<tt>pixelclock</tt>||Set to <tt>0</tt>, if you want to disable pixelclock modifications for small adjustments|
<tt>modinfo genlock</tt> will provide a list of all accepted module parameters.
You could put a line like
<tt>genlock lp_genlock=1 nv_irq=15</tt>
into your <tt>/etc/modules.conf</tt>, so that the genlock module gets all the necessary parameters passed automatically when you issue <tt>modprobe genlock</tt>.
Using the /proc-Interface to genlock
The <tt>/proc</tt>-Interface to genlock enables you to view and change the state of genlock. The genlock driver creates the following files in the directory <tt>/proc/driver/genlock</tt>:
|<tt>config</tt>||configuration of the parameters for small adjustments; you can change each parameter displayed in this file by writing <tt>parameter=value</tt> to this file|
|<tt>info</tt>||statistics, such as the duration of one frame, the number of interrupts and corrections, ...|
|<tt>interrupts</tt>||the interrupt lines used by genlock|
|<tt>options</tt>||the parameters passed at module load time|
|<tt>ioports</tt>||the i/o ports used by the driver|
|<tt>state</tt>||the current state, i. e. if it is working as a master or slave, if it is enabled or disabled, and if it is in stereo or mono mode; you can enable or disable the genlock driver and you can switch it to stereo or mono mode by writing <tt>enable</tt>, <tt>disable</tt>, <tt>stereo</tt>, and resp. <tt>mono</tt> to this file|
How We Use It
Our Performer based virtual reality renderer COVER, which is part of COVISE, can be set up to issue arbitrary commands when starting and shutting down. For using it with genlock we configured it to issue <tt>echo stereo > /proc/driver/genlock/state</tt> when starting and <tt>echo mono > /proc/driver/genlock/state</tt> when quiting. At start up it takes a while until all four PCs are synchronized, but then you have active stereo on all four walls ouf our cave.
We load the genlock module automatically at system boot time. We configured the Xservers on all machines to use the same video mode and to start them automatically.
We designed a video mode with a rather long front porch:
<tt>Modeline "1056x1056" 226.00 1056 1136 1480 1740 1056 1060 1064 1139</tt>
This would let us minimize the number of corrections necessary, as these randomly cause flicker on our Electrohome Marquee 8500 CRT projectors.
We plugged a Y-cable into the stereo output of the master and use it to feed the stereo emitters as well as the parallel port.