Package: libsdl1.2debian
Version: 1.2.10-3
Severity: normal
Tags: patch

Nexuiz uses SDL's OpenGL stuff, but HW acceleration doesn't work. It
works fine with other games that use OGL directly. Glxinfo also
shows that HW acceleration is activated.

What's happening:
,-----------
| [EMAIL PROTECTED]:/tmp/src$ glxinfo 2>/dev/null | grep renderer
| OpenGL renderer string: Mesa DRI R300 20040924 AGP 8x TCL
| [EMAIL PROTECTED]:/home/greek0$ LIBGL_DEBUG=verbose nexuiz
| ...
| ^7Starting video system
| ^7Video: fullscreen 640x480x32x60hz
| ^7Linked against SDL version 1.2.10
| ^7Using SDL library version 1.2.10
| libGL: XF86DRIGetClientDriverName: 4.0.3 r300 (screen 0)
| libGL: OpenDriver: trying /usr/lib/dri/r300_dri.so
| libGL error: dlopen /usr/lib/dri/r300_dri.so failed 
(/usr/lib/dri/r300_dri.so: undefined symbol: _glapi_Dispatch)
| libGL error: unable to find driver: r300_dri.so
| ^7checking for OpenGL 1.1.0...  enabled
| ^7GL_VENDOR: Mesa project: www.mesa3d.org
| ^7GL_RENDERER: Mesa GLX Indirect
| ^7GL_VERSION: 1.2 (1.5 Mesa 6.4.2)
| ...
`-----------

So it tries to load r300_dri, but it doesn't work, because there are
missing symbols. After a bit of googling I found this:
http://www.mail-archive.com/[email protected]/msg26006.html

The workaround proposed there (preloading libGL.so.1) actually
works.

Looking at the source, SDL really uses dlopen() without RTLD_GLOBAL.
X11_GL_LoadLibrary() calls SDL_LoadObject(), and on Linux the
implementation in src/loadso/dlopen/SDL_sysloadso.c is used. There
we can see:
,-----------
| void *handle = dlopen(sofile, RTLD_NOW);
`-----------

As Drepper writes[1], using RTLD_GLOBAL generally isn't a good idea,
but libGL seems to require it:
http://dri.sourceforge.net/doc/DRIuserguide.html#s11

So the attached patch introduces a new static function
SDL_LoadObject_LibGL() in src/video/x11/SDL_x11gl.c, which does the
same as SDL_LoadObject, but uses RTLD_GLOBAL. If SDL_LOADSO_DLOPEN
is not defined (i.e. not the dlopen SDL_LoadObject implementation is
used, but another one), the patch doesn't touch anything.

It fixes the bug for me and shouldn't cause any other problems
AFAICS.

After writing all this I see that there's a simmilar patch in the
SDL svn repository, cf. commit 2523:
http://www.libsdl.org/cgi/viewvc.cgi/trunk/SDL/src/video/x11/SDL_x11gl.c?view=log

Would be nice if you could apply either one of the patches to fix
this problem, thanks.

Cheers,
Christian Aichinger

[1] <URL:http://people.redhat.com/drepper/dsohowto.pdf>, Page 9

-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 
'experimental')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/dash
Kernel: Linux 2.6.17.2-vs2.1.1-rc23-iphigenie
Locale: LANG=de_AT.UTF-8, LC_CTYPE=de_AT.UTF-8 (charmap=UTF-8)

Versions of packages libsdl1.2debian depends on:
ii  libsdl1.2debian-alsa          1.2.10-3   Simple DirectMedia Layer (with X11

libsdl1.2debian recommends no packages.

-- no debconf information
diff -Nur libsdl1.2-1.2.10.orig/src/video/x11/SDL_x11gl.c 
libsdl1.2-1.2.10/src/video/x11/SDL_x11gl.c
--- libsdl1.2-1.2.10.orig/src/video/x11/SDL_x11gl.c     2006-05-17 
05:16:07.000000000 +0200
+++ libsdl1.2-1.2.10/src/video/x11/SDL_x11gl.c  2006-07-07 23:27:16.000000000 
+0200
@@ -447,6 +447,25 @@
 
 #if SDL_VIDEO_OPENGL_GLX
 
+/* We need this because libGL.so needs RTLD_GLOBAL to work, but SDL_LoadObject
+ * doesn't use it normally (for good reasons) */
+#ifdef SDL_LOADSO_DLOPEN
+#include <stdio.h>
+#include <dlfcn.h>
+
+static void *SDL_LoadObject_LibGL(const char *sofile)
+{
+       void *handle = dlopen(sofile, RTLD_NOW | RTLD_GLOBAL);
+       const char *loaderror = (char *)dlerror();
+       if ( handle == NULL ) {
+               SDL_SetError("Failed loading %s: %s", sofile, loaderror);
+       }
+       return(handle);
+}
+#else
+#define SDL_LoadObject_LibGL(sofile) SDL_LoadObject(sofile)
+#endif
+
 /* Passing a NULL path means load pointers from the application */
 int X11_GL_LoadLibrary(_THIS, const char* path) 
 {
@@ -464,7 +483,7 @@
                }
        }
 
-       handle = SDL_LoadObject(path);
+       handle = SDL_LoadObject_LibGL(path);
        if ( handle == NULL ) {
                /* SDL_LoadObject() will call SDL_SetError() for us. */
                return -1;

Attachment: signature.asc
Description: Digital signature

Reply via email to