It is currently Sun Dec 15, 2019 3:03 am



 [ 19 posts ] 
 DDC glasses activation for NVIDIA graphics cards under Linux 
Author Message
Petrif-Eyed
User avatar

Joined: Sat Jan 09, 2010 2:06 pm
Posts: 2255
Location: Perpignan, France
Hi,

I'm very happy to announce that after several sleepless nights, I finally succeeded in sending a DDC signal to the VGA port of my graphics card (GeForce 8400 GS PCI) under Linux (Debian/unstable). For the time beeing, it does make my eDimensional glasses flicker in quite an erratic way, but it's probably because I didn't yet synchronize the DDC signal with the vertical retrace.

Here is how I did it :
- from the command line, create a nvclock directory and go to it : mkdir nvclock ; cd nvclock ;
- obtain the nvclock source (version 0.8b4 for me) : apt-get source nvclock ;
- go to this directory : cd nvclock-0.8b4 ;
- open the src/backend/xf86i2c.c file, with gedit for example ;
- search for these lines in the file :
Code:
static Bool
I2CStart(I2CBusPtr b, int timeout)
{
    int i, scl, sda;
- insert the following code :
Code:
int j;

for (j = 0 ; j < 10 ; j++)
{
   b->I2CPutBits(b, 0 , 1); // set the SDA bit of the DDC interface to 1
   b->I2CUDelay(b, 8333); // wait 8.3 ms (for a 120 Hz screen refresh)
   b->I2CGetBits(b, &scl, &sda); // read the value written to the SDA bit

   b->I2CPutBits(b, 0 , 0); // set the SDA bit of the DDC interface to 0
   b->I2CUDelay(b, 8333); // wait 8.3 ms (for a 120 Hz screen refresh)
   b->I2CGetBits(b, &scl, &sda); // read the value written to the SDA bit
}
- compile nvclock : fakeroot debian/rules binary ;
- run nvclock : ./src/nvclock -i ;
- the glasses should flicker for some seconds before the card info is displayed.

This code should work on any NV50 card (GeForce 8, GeForce 9, GeForce GTX2x0) and I guess it should also work under Windows with some modifications, since nvclock is available on this platform. When I'm happy with my implementation, I may have a go at adapting it to other systems/graphics cards if nobody beats me to it.

Since I send the signal on every I2C port available, it should work for dual screen configurations (TwinView) and shutter glasses connected to the DVI port with homebrew hardware. Don't hesitate to test this code and please report back if it does work (or not) for you, giving the following informations :
- operating system (distribution, 32/64 bits) ;
- graphics card model ;
- graphics card connection (PCI, AGP, PCIe) ;
- shutter glasses model ;
- display connection (VGA, DVI) ;
- screen configuration (one screen, TwinView, Xinerama).

Thank you.

Best regards,
Frédéric Lopez.


Thu Mar 18, 2010 7:08 pm
3D Angel Eyes (Moderator)
User avatar

Joined: Sat Apr 12, 2008 8:18 pm
Posts: 11394
Wow! Very cool. I run strictly Windows so I can't test this myself but I imagine it will help some people.

_________________
check my blog - cybereality.com


Thu Mar 18, 2010 9:49 pm
Petrif-Eyed
User avatar

Joined: Sat Jan 09, 2010 2:06 pm
Posts: 2255
Location: Perpignan, France
Yeah, I guess only developers writing drivers like iZ3D or TriDef would be interested in this code for now. I'll keep you informed when I come up with something interesting for end users.


Fri Mar 19, 2010 8:43 am
Petrif-Eyed
User avatar

Joined: Sat Apr 07, 2007 4:34 pm
Posts: 2909
Location: Sweden
It doesn't seem that easy though. You never know where the actual rendering train from the card is, which mean you don't know WHEN to alter the ddc-signal even if you know how...
So besides of knowing how to control the ddc-pin you also need a way to figure out when the graphiccard is finished with one frame to set the ddc accordingly. I'm only a very babycrawling coder but i've got this impression after lurking on the iz3d-forums.

_________________
Mb: Asus P5W DH Deluxe
Cpu: C2D E6600
Gb: Nvidia 7900GT + 8800GTX
3D:100" passive projector polarized setup + 22" IZ3D
Image


Fri Mar 19, 2010 10:39 am
Petrif-Eyed
User avatar

Joined: Sat Jan 09, 2010 2:06 pm
Posts: 2255
Location: Perpignan, France
Hem, yes, I think it's THAT easy... ;)

I have adapted my code to display a moving square in OpenGL, and now I can easily synchronise the DDC signal with the vertical retrace using glXSwapBuffers. The images are always rendered to the correct eye, even when there are hiccups in the rendering. In fact it does work exactly the same way as BLC/WLC, only without having to pollute the screen with a blue/white line at the bottom and with support for glasses that can't handle BLC/WLC.

Still, it's not going to resolve the problem of frames taking more than one vertical refresh to render, but that's part 2 of the problem and I'll address it later. I've already got some pointers to handle this case with OpenGL though. In the mean time, if adapted to Windows, I think this technique could still be valuable for iZ3D and other stereo 3D drivers.


Fri Mar 19, 2010 11:40 am
Cross Eyed!

Joined: Sun Feb 15, 2009 12:50 pm
Posts: 131
Hey, how does your code work? you're writing to an I2C port/address right? Are these some internal registers on the card, or something set in a chip external to the GPU? Do you think the addresses will be the same on older cards too?


Sun Mar 21, 2010 7:10 pm
Petrif-Eyed
User avatar

Joined: Sat Jan 09, 2010 2:06 pm
Posts: 2255
Location: Perpignan, France
The code writes directly to a memory address mapped to the /dev/nvidia0 device of the graphics card. The address is specific to NV50 hardware as said in the nv50.c file, but I think the code found in i2c.c may work for all hardware prior to NV50. Here is the relevant function :
Code:
static void NV_I2CPutBits(I2CBusPtr b, int clock, int data)
{
   unsigned char val;
   int DDCBase = (int)b->DriverPrivate.val;

   nv_card->PCIO[0x3d4] = DDCBase + 1;
   val = nv_card->PCIO[0x3d5] & 0xf0;
   if (clock)
      val |= DDC_SCL_WRITE_MASK;
   else
      val &= ~DDC_SCL_WRITE_MASK;

   if (data)
      val |= DDC_SDA_WRITE_MASK;
   else
      val &= ~DDC_SDA_WRITE_MASK;

   nv_card->PCIO[0x3d4] = DDCBase + 1;
   nv_card->PCIO[0x3d5] = val | 0x1;
}

You may have to unprotect VGA registers to be able to call this code though (NVLockUnlock in i2c.c). If I find time, I may try with my old GeForce 7600 GT (NV40 hardware) and write a library to handle this. What's the model of your graphics card by the way ?


Sun Mar 21, 2010 8:10 pm
Cross Eyed!

Joined: Sun Feb 15, 2009 12:50 pm
Posts: 131
Hi, I am using 7900GTX (G71) on one PC, 7900GT on another (I like to boot into XP for old-school gaming sometimes). Both are PCI Express. I will have a play with this code when I get some time. I also have a 8400GS in a drawer somewhere, may try with that if it only works with >= NV50.

On another note, I tried the stereo player you have been writing (the one on your blog). The GUI loads but when I try to open a file, it bombs out with an error saying 'mplayer not found' despite mplayer definitely being installed and in my $PATH. How far along is the code? I notice that many of the menus seem to do nothing...


Mon Mar 22, 2010 10:22 am
Petrif-Eyed
User avatar

Joined: Sat Jan 09, 2010 2:06 pm
Posts: 2255
Location: Perpignan, France
In fact the code available on my blog was not supposed to be public, I just did create some test web pages for several projects I'm working on. The video player is not really functionnal at this time, it does work only for side-by-side half res videos with the eDimensional activator and a modified MPlayer, I'll let you know when it's ready.

For the DDC signal, I've started writing a small library to handle it, I'll try to incorporate the infos I've found for other graphics cards.


Mon Mar 22, 2010 11:21 am
Cross Eyed!

Joined: Sun Feb 15, 2009 12:50 pm
Posts: 131
Yeah I thought it might be unfinished. How are you currently controlling your E-D dongle by the way? Have you seen the info on my wiki about how E-D activation works? (http://magicbox.org.uk/mediawiki/index.php/Coloured_GIFs). I have already added support for E-D activation to magestik's Tux-Stereo-Viewer, and I will release a standalone replacement for the old E-D.exe soon. It will be written in python, and will support being called from the command line e.g
Code:
ed_activate --enable-interlaced
or via a GTK+ dialog (if called with no arguments). It should be available by the end of the week.

You can set interlaced, page flipping (dumb flippping left/right every frame), sync doubling etc just by drawing line codes on the screen. Sync doubling is especially interesting because it enables the possibility of full resolution shutter glasses viewing in Linux. You simply set a display mode with slightly more than twice the number of lines and exactly half the refresh rate that you want, then draw over/under on the screen. This is the method I use with VRizer for gaming, and mplayer for watching movies. You need to add a few blank lines between the top/left and bottom/right view, as a few lines get lost in the vertical retrace. In my experience, sync doubling works up to ~1280x1024@140hz (set x server to 1280x~2100@70hz). Any higher than this and the display starts to become unstable - I already killed one dongle by trying to turn the dongle on when I already had the disply set too high. I think it is the max hsync rate you have to worry about. I seem to remember 110khz being quoted as the max an e-dim dongle is rated to.


Mon Mar 22, 2010 11:45 am
Petrif-Eyed
User avatar

Joined: Sat Jan 09, 2010 2:06 pm
Posts: 2255
Location: Perpignan, France
Quote:
How are you currently controlling your E-D dongle by the way?
I use the eDimensional activator with Wine for now.
Quote:
Have you seen the info on my wiki about how E-D activation works?
Yes, and thanks for that. I'll use this info in my player for graphics cards I don't know how to send the DDC signal to.
Quote:
I will release a standalone replacement for the old E-D.exe soon. It will be written in python, and will support being called from the command line or via a GTK+ dialog.
It would be nice, even if I'm not a great supporter of Python for such tasks, I've had a lot of compatibility problems with it.
Quote:
Sync doubling is especially interesting because it enables the possibility of full resolution shutter glasses viewing in Linux.
When my application is ready, it should be able to play movies in full resolution in page flipping mode. It does work in some cases for now when there is a light load on the CPU, but I'll adapt my code to handle more cases.

While we are on the subject, some years ago I wrote an OpenGL interceptor to enable stereo in 3D games under Linux, the code is available here : http://frederic.lopez.free.fr/linux/glstereo-0.1.tar.gz . It was more or less functionnal with quake 3 and several Open Source games (there were some problems in the off-axis matrix code) but unfortunately it doesn't compile anymore on recent systems. I'll continue to work on it with all the things I've learned recently.

Anyway, it's nice to see people interested in 3D on Linux. :)


Mon Mar 22, 2010 12:41 pm
Two Eyed Hopeful

Joined: Tue Dec 22, 2009 11:48 am
Posts: 79
Of course we are ;)
So, about your glstereo : it's work ? Interlaced ? Anaglyph ?
It could be great to make a big project for Stereo 3D apps on Linux.


Wed Mar 24, 2010 2:20 pm
Petrif-Eyed
User avatar

Joined: Sat Jan 09, 2010 2:06 pm
Posts: 2255
Location: Perpignan, France
Before it ceased working, there was support for anaglyph and White Line Code shutter glasses (Simuleyes VR). I guess it could be adapted to interlaced with a little bit more work, with the added benefit of avoiding vsync issues though.

I didn't have time to make it work again yet, I'm still trying to get the vblank detection right but without success for now (seems Likay was right :/). In fact the glxSwapBuffers OpenGL command does not react like it should, it misses quite a lot of vblanks on NVIDIA cards.

I've tried using glXSwapIntervalSGI and glXGetVideoSyncSGI/glXWaitVideoSyncSGI but to no avail. I'll continue to investigate with well-crafted timers, but I'm afraid I'll be forced to directly modify 3D drivers (Nouveau for NVIDIA cards), modify the kernel (like the SoftGenlock/Genlock projects did) or try the KMS page flip IOCTL newly introduced in the 2.6.33 kernel.


Wed Mar 24, 2010 10:40 pm
Cross Eyed!

Joined: Sun Feb 15, 2009 12:50 pm
Posts: 131
Quote:
modify the kernel (like the SoftGenlock/Genlock projects did)


Hey, i had almost forgotten about these projects. Did you ever have any luck compiling either against a modern kernel? I spent a couple of weekends on it once before giving up. I managed to get the userspace version to work, but you need to run it SUID root and it sometimes hangs the whole system. I also seem to remember there being code in there for DDC activation on the older NVIDIA cards by writing directly to the VGA registers or something. Maybe the time has come to pick this up for another look. PS i also have a tarball of the Genlock code somewhere (The original site is long gone) give me a shout if you want a copy.


Thu Mar 25, 2010 10:11 am
Petrif-Eyed
User avatar

Joined: Sat Jan 09, 2010 2:06 pm
Posts: 2255
Location: Perpignan, France
Quote:
Did you ever have any luck compiling either against a modern kernel?
I didn't try yet.
Quote:
I also seem to remember there being code in there for DDC activation on the older NVIDIA cards by writing directly to the VGA registers or something.
Yes I saw that, that's what got me started finding a solution for my current hardware. Their solution does only work for very old hardware, before GeForce 4 Ti I think since it didn't work on this hardware when the Genlock guys used the SoftGenlock code.
Quote:
i also have a tarball of the Genlock code somewhere (The original site is long gone) give me a shout if you want a copy.
I found it too thanks to archive.org, but thanks anyway ;)


Thu Mar 25, 2010 11:13 am
Petrif-Eyed
User avatar

Joined: Sat Jan 09, 2010 2:06 pm
Posts: 2255
Location: Perpignan, France
Just reinstalled my old GeForce 7600 GT and it seems the modification I posted for nvclock in my first post does still work. I'll find the corresponding code in nvclock and insert it into my DDC library.

Concerning glStereo, I've played with it a little bit more and now it's functionnal again. As I feared, my off-axis projection calculation was way off, I'll see how they did it in StereoGL. I added interception code for the SDL_GL_SwapBuffers function, which seems to be used quite more often than glXSwapBuffers in recent 3D Open Source games.

For now, anaglyph (red/cyan) and white/blue line code are almost functionnal, but I'll try to support more anaglyph glasses, interlaced and maybe sync doubling modes for a first release.

The next step will be to correct temporal incoherencies. For now I'm only modifying one frame after the other, which can produce unaligned images for each eye. I'll try to include offscreen rendering with fbo to be able to render two frames at the same period in time.


Fri Mar 26, 2010 6:39 pm
Cross Eyed!

Joined: Sun Feb 15, 2009 12:50 pm
Posts: 131
Cool. I look forward to seeing this working! I downloaded your earlier version, but had no time to look at it yet. I will wait now until you make another post.

Also, I would be grateful if you could test my E-D activator replacement. I wrote it as a Gnome panel app in python in the end. It is attached to the other thread: http://www.mtbs3d.com/phpBB/download/file.php?id=520

You need to run
Code:
sudo ./install
then log out / log back in for it to appear in the "Add to panel..." menu, or you can run ed_activator.py like so:
Code:
./ed_activator.py run-in-window
to run in a window (not as a panel app).


Sat Mar 27, 2010 11:22 am
Petrif-Eyed
User avatar

Joined: Sat Jan 09, 2010 2:06 pm
Posts: 2255
Location: Perpignan, France
mickeyjaw wrote:
Hey, i had almost forgotten about these projects [SoftGenLock/Genlock]. Did you ever have any luck compiling either against a modern kernel? I spent a couple of weekends on it once before giving up. I managed to get the userspace version to work, but you need to run it SUID root and it sometimes hangs the whole system.
I don't know if you're still interested in the subject, but I've adapted Genlock to compile on my machine (kernel 2.6.32). I can load the module and communicate with it (show the state and activate modes), but I've no idea about what to do to make it do something usable. The documentation is a bit lacking on this side, so if you've got any idea you're welcome....

You'll find the modified file genlock.c as an attachement to this message.


You do not have the required permissions to view the files attached to this post.


Mon Jun 14, 2010 9:01 pm
Petrif-Eyed
User avatar

Joined: Sat Jan 09, 2010 2:06 pm
Posts: 2255
Location: Perpignan, France
Woot ! Found out how to make this module work, in fact you just need to create a virtual screen as specified in the SoftGenLock documentation. I've tried with a 1024x768 screen defined with a virtual size of 2048x768 and it does indeed work when I use 60 Hz vertical refresh. No success with higher refresh rates for now though... :/

I've posted a small tutorial in this thread : viewtopic.php?f=6&t=10625


Tue Jun 15, 2010 12:26 am
Display posts from previous:  Sort by  
   [ 19 posts ] 

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by STSoftware.