Sunday, March 2, 2008

The OpenGL virtual Linux desktop

One of the holy grails of desktop virtualization is graphics card virtualization. Linux users everywhere (me included) drool at the thought of being able to use Windows games in Linux desktops without dual-booting.

There's a Google Summer of Code project called VMGL that moved us closer to making this a reality. Right now, however, it's more of a proof of concept than anything else: it allows a Unix guest using X11 to have the host do its OpenGL processing. Nonetheless, it's a very impressive proof of concept, and there's esentially nothing in the approach that would make it incompatible with a Windows guest (though it would take a lot more work).

The basic idea is to have the OpenGL library in the guest contact a component in the host to process the OpenGL commands, instead of doing that in the guest. The connection between the host and guest is network-based, which allows for a certain level of hypervisor independence. In fact, it was orignally planned for Xen, but I've successfully run it using KVM (and so have others).

So, I downloaded the project's tarball and tried to build it on my 64-bit Ubuntu host. It built a bunch of libraries and then it failed when it came to build the VNC stuff. Turns out that there are 3 basic ways of using VMGL:

  • VNC

  • Patched SDL viewer for Xen

  • X forwarding, either using X itself or SSH

The VNC options use a patched version of TightVNC that's included in the tarball (under the tightvnc/ directory). Unfortunately, it seems as if this particular version has trouble being built on 64-bit platforms. Luckily, the author included patches for the regular TightVNC tree. Therefore, I downloaded the lastest version of tightvnc and I unpacked overwriting the tightvnc/ directory. Then patched the TightVNC sources using the included patches:

vmgl.hg/tightvnc$ patch -p1 < ../extra/patches/vncviewer.patch vmgl.hg/tightvnc$ patch -p1 < ../extra/patches/Xvnc.patch

Now everything builds great =). I then moved to build VMGL in my 32-bit Ubuntu guest. Everything went great, and now I was ready to do some testing.

WARNING: If your guest is also 64-bit, you have to do more patching. Not using the VNC option requires loading a VMGL X module in the guest, which comes as a 32-bit binary. You will need to download the X sources and patch them. I haven't tried that.

I chose to run using X forwarding. Ubuntu users can enable TCP access to X in the "Login window" settings. If not, you will need to edit /etc/gdm/gdm.conf (or kdm.conf if you are a KDE user, or xdm.conf if you use the plain X Display Manager, any of them of course in a sensible /etc folder) and allow TCP connections.

Now comes the fun part. As I said in the last post, QEMU's default networking uses a usermode network stack. This is great to make VMs have the same network access as the host, without any need for superuser priviliges. However, it sucks for VMGL. We need to use tap based networking. There are great tutorials in the KVM wiki.

Once you've set up the networking, you should be able to run something relatively similar to what I ran:

$ sudo qemu-system-x86_64 stuff/images/ubuntu.img -net nic,model=virtio,macaddr=AA:BB:CC:DD:EE:FF -net tap -m 512

If you're wondering what that virtio stuff is, that's KVM paravirtualized IO infrastructure. It will make a difference for VMGL if you try and run an OpenGL game like Quake 3 in your guest. Yes, you can run Quake 3 in your guest with VMGL and it plays very well. Yes, that's totally cool.

Now that you have networking setup correctly, you can allow connections from your guest into your host X:

$ xhost +[your guest's IP address]

Following the VMGL readme, now we have to start stub-daemon in the host:

$ stub-daemon

We then see the port that we need to connect to from the guest:

$ tail -n 1 .stub-daemon.log

Now in the guest, we first set the port we got from the line above:

$ export GLSTUB=[your host's IP address]:[the port you found above]

Finally, we set the display to the host's X server main display (i.e. your desktop):

$ export GLSTUB=[your host's IP address]:0

*drumroll*

$ glxgears -info


That's really cool.


But Quake 3 Arena is better =).

3 comments:

Anonymous said...

Hi,
I'm trying to port VMGL on current X (7.7)
So I downloaded the X sources and patched them with the xorg patch from the tarball.

I just want getting Xforwarding to work.

So after some little fixed make gets through.

But when I get starting X it crashed with a segmentation fault at address 0x3!
This happens in the function VMGLClipNotify after findWindow() returns a NULL pointer.

Without the extension (remove "LOAD vmglext" in xorg.conf) my X works fine.

Can you get me some help if something changed to current X version?

Josh

Tamsyn said...

I'm not the original developer of VMGL so it's hard to say what's failing. Since the crashing code seem to be in VMGL, it's likely that assumptions in the VMGL code have been broken by X updates. It should be possible to debug the problem and possibly adjust VMGL code to avoid crashing.

Anonymous said...

Got it working on 64bit Rhel Distribution.
Some Modifications needed in code so check my repo on github.
Accountname: L3oV1nc3