Subject: [Nel] Issue to run snowballs2

From: David Mentre <[email-masked]>
Date: 08 Jan 2002 19:34:46 +0100

Hello all,

I'm trying to run snowballs2. However, it failed while trying to load
libnel_drv_opengl.so with an undefined symbol glSetFenceNV.

I commented out all gl*Fence*NV symbols and now I have the following
error:

david@oops:~/pub/NeL/code/snowballs2/client$ /usr/local/Installed/NeL/bin/snowballs 
INF 2967 client.cpp 145 : Starting Snowballs !
WRN 2967 path.cpp 440 : CPath::addSearchPath(data/pacs/, 0, 1): 'data/pacs/' is not found, skip it
WRN 2967 path.cpp 440 : CPath::addSearchPath(data/anims/, 0, 1): 'data/anims/' is not found, skip it
WRN 2967 dru.cpp 95 : when loading dynamic library 'libnel_drv_opengl.so': /usr/local/Installed/NeL/lib/libnel_drv_opengl.so: undefined symbol: glBindProgramNV
WRN 2967 common.cpp 390 : Exception will be launched: libnel_drv_opengl.so not found
Aborted

Like glSetFenceNV, glBindProgramNV symbol is not available in
/usr/lib/*GL* libraries neither in /usr/include/GL/*.h.

Notice also that those symbols are not defined in SGI latest glext.h
(http://oss.sgi.com/projects/ogl-sample/ABI/glext.h).

Notice also that Alexandre Courbot had the same problem as me
(/pipermail/nel/2001-October/000650.html). Apparently,
this has not been fixed.

Are those symbols standard OpenGL or Windows specific? I have missed
something?

Versions:
OpenGL implementation: Mesa 3 provided with XFree86 4.1.0.1
Linux 2.4.17, XFree 4.1.0.1,
OpenGL renderer string: Mesa DRI Rage128 20010405 AGP 1x x86/MMX
OpenGL version string: 1.2 Mesa 3.4.2

Thanks in advance for any help,
Best regards,
d.
-- 
 [email-masked]

---

From: David Mentre <[email-masked]>
Date: 08 Jan 2002 21:39:28 +0100

David Mentre <[email-masked]> writes:

> Are those symbols standard OpenGL or Windows specific? 

After further investigation, I would say that those symbols (and thus
library functions) are NVidia specific:

http://oss.sgi.com/projects/ogl-sample/registry/NV/fence.txt

As far as I have understood, the NeL library should have queried the
OpenGL library to find if those extensions are available and if not use
a workaround. Am I right?

However, there is some code to test those functions availability:
driver_opengl_extension.cpp:333:
	if( strstr(glext, "GL_NV_fence")==NULL )
		return false;

Maybe some cleanup would be needed in driver_opengl_extension_def.h?

I would so much play with snowballs! :)

I hope it helps in some way,
Best regards,
d.
-- 
 [email-masked]

---

From: "Lionel Berenguier" <[email-masked]>
Date: Wed, 9 Jan 2002 11:21:47 +0100

Okay, sorry for late answer but this an issue I have not yet fixed, and I
apologize, but I still don't know how to (the fact is that here at nevrax we
develop under windows, still trying to support linux, except network guys
which really tests both versions).

David, you're right, glSetFenceNV, glBinProgramNV etc.... are part of NVidia
OpenGL extension, but they are dynamically checked (like all other
extensions) in driver_opengl_extension.cpp.

The difference with other extensions is that they are too recent and don't
exist in GLext.h, so they are defined
in   "driver_opengl_extension_def.h".

I tried to follow same syntax as in GLext.h to define thoses extensions (use
of GL_GLEXT_PROTOTYPES, use of APIENTRY) but it seems that it works under
windows (even with drviers/cards that don't support thoses extensions) but
not under linux. I'm not very aware of dynamci libs (.so) under linux but I
think the problem is that all thoses functions are not "export"-ed and so
the dynamic library loader think the function is in libnel_drv_opengl.so.
And of course it is not.

The test in driver_open_extension.cpp:333  ensure that code that use
glSetFenceNV won't be executed, but it's still compiled and linked.
Therefore it crahses when the libnel_drv_opengl.so  is loaded.

If someone could explains me where I am wrong in
driver_opengl_extension_def.h, it would be cool.

Also, can anybody explains me why under linux/unix we don't have to
dynamically import functions (ie with such call like wglGetProcAdress(), or
window's GetProcAdress()) ??? In other terms, What system underlie the
dynamic library loader (I suppose there is system which fill a table of jump
or something like this but I don't really knows).

thanks

Lionel, Nevrax.

----- Original Message -----
From: "David Mentre" <[email-masked]>
To: <[email-masked]>
Sent: Tuesday, January 08, 2002 9:39 PM
Subject: Re: [Nel] Issue to run snowballs2

> _______________________________________________
> Nel mailing list
> [email-masked]
> /mailman/listinfo.cgi/nel
>

---

From: David Mentre <[email-masked]>
Date: 09 Jan 2002 19:15:40 +0100

Hello Lionel,

"Lionel Berenguier" <[email-masked]> writes:

> Okay, sorry for late answer but this an issue I have not yet fixed,

Thank you. I don't mind a late reply if I get a reply at all (especially
when it is detailed like yours :)

> Therefore it crahses when the libnel_drv_opengl.so  is loaded.

One quick workaround would be to put an appropriate test in the
configure. This test would try run a small program testing the GL
extension and thus #define its availability.

But for a long term fix, it would be better to allow the dynamic lookup
of those extensions. It would allow Nevrax to release one binary
supporting all hardware at full speed.

Sorry, I have no fix for that yet.

Anyway, thank you for your reply,
Best regards,
d.
-- 
 [email-masked]

---

From: David Mentre <[email-masked]>
Date: 09 Jan 2002 23:28:29 +0100

> or something like this but I don't really knows).

Ok. Looking at nm(1):
       For each symbol, nm shows:
[...]
           "U" The symbol is undefined.
[...]
           "W" The symbol is a weak  symbol  that  has  not  been
               specifically tagged as a weak object symbol.  When
               a weak defined symbol  is  linked  with  a  normal
               defined  symbol, the normal defined symbol is used
               with no error.  When a weak  undefined  symbol  is
               linked and the symbol is not defined, the value of
               the weak symbol becomes zero with no error.

[...]

So I think we would like those "weak objects" for all GL extensions.

Looking at the generated library, we find:
david@oops:~/pub/NeL/code/nel/src/3d/driver/opengl/.libs$ nm libnel_drv_opengl.so|grep Fence  
0001a58c T finishFence__Q24NL3D19CVertexBufferHardGL
         U glDeleteFencesNV
         U glFinishFenceNV
         U glGenFencesNV
         U glSetFenceNV
000213e0 W isFenceSet__CQ24NL3D19CVertexBufferHardGL
0001a554 T setFence__Q24NL3D19CVertexBufferHardGL

So glSetFenceNV is an undefined symbol that will trigger the dlopen
error.

I've not found a way to change that however. :(

Hope it helps a little,
Best regards,
d.
-- 
 [email-masked]

---

From: Vincent Caron <[email-masked]>
Date: 10 Jan 2002 00:04:16 +0100

> or something like this but I don't really knows).

OpenGL under Unix was used for a long time on a limited set of video
hardware (on SGI/Irix, HP/UX and a few), and there were little migration
of software across these different setups. Thus, the extensions were
simply compiled in libGL.so together with the standard API, and you had
only two solution : 1) choose extension usage at compile time or 2)
dynamically load different versions of your engine (if the DLL wouldn't
load, it meant a required extension was not present).

But of course it was quickly a pb. An extension has been proposed as the
counterpart of wglGetProcAddress (
http://oss.sgi.com/projects/ogl-sample/registry/ARB/get_proc_address.txt
). Since you have the pb of the chicken and the egg (how do you get the
glXGetProcAddressARB function address without itself ? :)), the author
asked driver implementors to _always_ compile this one in their libGL.so
(even if it always return NULL : no extension!). Conclusion: you can
reuse the code currently embraced by #ifdef NL_OS_WINDOWS/#endif for
Linux, replacing wglGetProcAddress by glXGetProcAddressARB (may I
suggest a macro ? :)).

Now you would say : ok, but the gl* extensions are defined twice ! Once
as function pointers in my code, once as functions in libGL.so ! The
fact is that dlopen'ing("/usr/lib/libGL.so") does not import libGL
symbols in your process space. You have to import them with dlsym(), or
in our precise case, with glXGetProcAddressARB(). You get the Windows
behaviour. But Linux users keep a slight advantage : they can code
nVidia specific stuff without those boring function pointer mess, they
just link against libGL.so.

--
There is something worth mentioning : glXGetProcAddressARB is
context-independent while wglGetProcAddress is ! This is spurious,
because wgl* functions are on the windowing system side, and should not
be context-dependent until one of their parameter is a context. If a
Windows host has several drivers (often the case : one software, and one
HW, maybe more with multi-head), context is critical since you can deal
with several driver interfaces. At least it is clearly mentioned in the
first line of the MSDN doc...

--
Add-on: to list symbols of a DLL, use 'nm -D <stuff>.so|less'. Symbols
with a leading 'U' are undefined (meaning their implementation reside in
another lib), those with a 'T' are implemented here (in the 'text
section' = code segment). Very useful if you want to understand the
strategy of the runtime loader.

---

From: "Lionel Berenguier" <[email-masked]>
Date: Tue, 22 Jan 2002 10:04:44 +0100

Thank you Vincent for this great clarification. In your own experience, is
glXGetProcAddressARB widely supported ???

If yes, what I have to do is undef GL_EXT_PROTOTYPES, and use same scheme as
windows, isn't it ??

Lionel.

---

From: Vincent Caron <[email-masked]>
Date: 22 Jan 2002 16:55:37 +0100

> glXGetProcAddressARB widely supported ???

If you want accelerated 3D support under Linux, you either get the old
Mesa way (3DFX), utah-glx under XFree 3.3.x which is Mesa-based, DRI
under XFree 4.x which is Mesa-based and finaly Nvidia proprietary
drivers. They all support glXGetProcAddressARB to my knowledge. I
checked for Mesa : it appeared on the 3.3 branch on 1999/12/11 (
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/mesa3d/Mesa/include/GL/glx.h?rev=1.10&content-type=text/vnd.viewcvs-markup - see end of file). Nvidia had it since its early driver releases (0.9-767 of 2001/02/13).

So I would say, yes, it _is_ supported :)

> If yes, what I have to do is undef GL_EXT_PROTOTYPES, and use same scheme as

Yes.

But I just re-read this thread and realized my last mail contained a big
mistake : I was talking about dlopen'ing libGL.so, which you're not
doing. I was actually thinking with the quake model : Carmack dlopen
libGL.so or opengl32.DLL, and then import every symbol one by one. It
had some advantage at the time of mini-GL and QuakeGL, where you had no
means to choose your driver interface at run-time, but loading the right
DLL. And ID has its own GL tracer/debugger which wraps all GL calls
(they code the engine with a 'qgl*' API).

Now, I think you're right and ID is wrong. ID bypass the standard loader
link stage by dlopen'ing libGL.so, while you do the right thing by
linking nel_drv_opengl.so with libGL at compile time, letting the
runtime loader do its job (it will actually load the right libGL.so for
you when you dlopen nel_drv_opengl.so, thus relying on the user/distro
to have a proper GL setup, and not trying to workaround).

The point I wanted to make (finaly, sorry for being so verbose :)), is
that in this case you'll end with two definitions of a GL extension
symbol under Linux :

a) PFNGLSETFENCENVPROC  glSetFenceNV; // =
glXGetProcAddressARB("glSetFenceNV");

b) nm -D /usr/lib/libGL.so|grep glSetFenceNV
0001b368 T glSetFenceNV

The linker will complain (it says 'type of symbol `glSetFenceNV' changed
from 2 to 1', ahem!), but it seems that our redefinition here gets the
precedence over the libGL.so symbol. I'm not very confident with this
link stuff, but I'm eager to learn more, that's why I'm taking some time
to tackle this issue with you.

I tried to test it on nel GL driver directly, but there are some issues
to clean up first :

- ARB_multitexture is not a GL extension since OpenGL 1.2.1. Since you
should expect 1.3 compliant drivers till Ryzom is ready, I guess there
is no need to import these symbols for pre-1.2.1 drivers ? Currently,
the protos from driver_opengl_extension.h conflicts with plain
definitions of my GL/gl.h :

  // in driver_opengl_extension.h :
  extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;

  // in GL/gl.h : (not enclosed by #ifdef's)
  GLAPI void GLAPIENTRY glActiveTextureARB(GLenum texture);

- Get rid of some wgl dependencies : replace

  extern PFNWGLALLOCATEMEMORYNVPROC wglAllocateMemoryNV;
  extern PFNWGLFREEMEMORYNVPROC  wglFreeMemoryNV;

with something like :

  #ifdef NL_OS_WINDOWS
  typedef PFNWGLALLOCATEMEMORYNVPROC PFNGLEXTALLOCATEMEMORYNVPROC;
  typedef PFNWGLFREEMEMORYNVPROC PFNGLEXTFREEMEMORYNVPROC;
  #endif
  #ifdef NL_OS_UNIX
  typedef void *(*PFNGLEXTALLOCATEMEMORYNVPROC)(GLsizei, GLfloat,
GLfloat, GLfloat);
  typedef void (*PFNGLEXTFREEMEMORYNVPROC)(GLvoid *);
  #endif
  extern PFNGLEXTALLOCATEMEMORYNVPROC glextAllocateMemoryNV;
  extern PFNGLEXTFREEMEMORYNVPROC glextFreeMemoryNV;

 (and update the code in .cpp to fetch the right function name, "wgl*"
or "glX*")

- The same with the pbuffer extension which as its glX counterpart

- and so on ... I won't have much time this week, but I would gladly
have tweaked this myself. Good luck :)

---

From: David MENTRE <[email-masked]>
Date: 24 Jan 2002 20:29:57 +0100

> - The same with the pbuffer extension which as its glX counterpart

Lionel, as of today, the code compiles but does not run[1]. If you try
to fix this bug, let me know and I'll try to recompile snowballs2 on my
machine.

[ BTW, I know there is a special french touch for video games, but I
  didn't know that it consists in putting french words like "Abandon" in
  error messages. :) ]

Until then, I'm stuck. Yes, I know I should fix this myself but I prefer
let you do it your own way. However, if you do not indend to fix this
bug, let me know and I'll try to follow Vincent suggestions.

Best regards,
david

[1]
david@oops:~/pub/NeL/code/snowballs2/client$ /usr/local/Installed/NeL/bin/snowballs 
INF24568 client.cpp 145 : Starting Snowballs !
WRN24568 dru.cpp 95 : when loading dynamic library 'libnel_drv_opengl.so': /usr/local/Installed/NeL/lib/libnel_drv_opengl.so: undefined symbol: glSetFenceNV
WRN24568 common.cpp 390 : Exception will be launched: libnel_drv_opengl.so not found
Abandon

All libs are correctly initialized:
david@oops:~/pub/NeL/code/snowballs2/client$ ldd /usr/local/Installed/NeL/bin/snowballs 
	libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x4001d000)
	libnelmisc.so.0 => /usr/local/Installed/NeL/lib/libnelmisc.so.0 (0x40056000)
	libnelnet.so.0 => /usr/local/Installed/NeL/lib/libnelnet.so.0 (0x401db000)
	libnel3d.so.0 => /usr/local/Installed/NeL/lib/libnel3d.so.0 (0x403c0000)
	libnelpacs.so.0 => /usr/local/Installed/NeL/lib/libnelpacs.so.0 (0x409b8000)
	libnelsnd.so.0 => /usr/local/Installed/NeL/lib/libnelsnd.so.0 (0x40a7a000)
	libstlport_gcc.so => /usr/local/Installed/STLport4.5/lib/libstlport_gcc.so (0x40ab4000)
	libstdc++-libc6.2-2.so.3 => /usr/lib/libstdc++-libc6.2-2.so.3 (0x40bbe000)
	libm.so.6 => /lib/libm.so.6 (0x40c08000)
	libc.so.6 => /lib/libc.so.6 (0x40c2a000)
	libpthread.so.0 => /lib/libpthread.so.0 (0x40d4e000)
	libxml2.so.2 => /usr/lib/libxml2.so.2 (0x40d64000)
	libdl.so.2 => /lib/libdl.so.2 (0x40dfd000)
	/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
	libz.so.1 => /usr/lib/libz.so.1 (0x40e01000)

-- 
 [email-masked]

---

From: "Vianney Lecroart" <[email-masked]>
Date: Mon, 28 Jan 2002 10:36:05 +0100

Hi Vincent,

>   didn't know that it consists in putting french words like "Abandon" in

I search the word Abandon in all the NeL directory sources/includes and look
the result:

Searching for 'Abandon'...
Cannot find the string 'Abandon'.

So think that the real french touch is to install french linux distribution
on your computer!!!

Vianney Lecroart
---
lead network programmer / nevrax.com
icq#: 6870415
homepage: http://ace.planet-d.net
www.geekcode.com: GCS/E d- s+++: a-- C+++$ UL++ P- L+++>+$ E+>- W++ N+ o? K-
w++$ O- M- V- PS- PE? Y PGP t 5? X+ R- tv++ b- DI D+ G e++ h+ r-- y?

---

From: Vincent Caron <[email-masked]>
Date: 28 Jan 2002 16:06:47 +0100

>   didn't know that it consists in putting french words like "Abandon" in

Hi Vianney,

This is actually a David Mentre's quote, and your assumption about him
running a french locale seems right to me :)

---

From: David MENTRE <[email-masked]>
Date: 28 Jan 2002 21:48:17 +0100

> running a french locale seems right to me :)

Oops, shame on me. 

d.
-- 
 [email-masked]