PDA

View Full Version : ATI -ARB_uniform_buffer_object undefined reference



Jotschi
12-02-2009, 12:36 PM
Hello,

I'm trying to use the ARB_uniform_buffer_objects on linux with my ati 4850.

I tried to compile the example program from the specs but i encountered an odd problem. I can't compile it.

This is the reduced code:


#define GL_GLEXT_PROTOTYPES
#include "GL/gl.h"
#include "GL/glext.h"
#include "GL/glu.h"

int main(int argc, const char** argv) {
GLuint prog_id;
glGetUniformBlockIndex(prog_id, "colors0");
}


If i try to compile it i get a linker error:


gcc example.c -lGL
/tmp/ccsSi3Sj.o: In function `main':
example.c:(.text+0x20): undefined reference to `glGetUniformBlockIndex'
/tmp/ccsSi3Sj.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status


A friend which owns an nvidia card and uses nvidia drivers can compile the code without any problems (Debian testing). But me who only a ati 4850 can not.

I'm using Debian testing with fglrx 9-11-2 (newest) and yes the extension is supported:


jotschi@NeXuS:~$ glxinfo | grep uniform_buffer
GL_ARB_uniform_buffer_object, GL_ARB_vertex_array_bgra,




jotschi@NeXuS:~$ ldd /usr/lib/libGL.so.1.2
linux-gate.so.1 => (0xb7f92000)
libpthread.so.0 => /lib/i686/cmov/libpthread.so.0 (0xb7ed1000)
libXext.so.6 => /usr/lib/libXext.so.6 (0xb7ec3000)
libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb7e9c000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7e7f000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7d38000)
libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb7d34000)
/lib/ld-linux.so.2 (0xb7f93000)
libX11.so.6 => /usr/lib/libX11.so.6 (0xb7c18000)
libXau.so.6 => /usr/lib/libXau.so.6 (0xb7c15000)
libxcb.so.1 => /usr/lib/libxcb.so.1 (0xb7bfb000)
libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0xb7bf6000)


The definition of the method is only mentioned within glext.h and a mangle header:


jotschi@NeXuS:/usr/include$ grep -r glGetUniformBlockIndex .
./GL/gl_mangle.h:#define glGetUniformBlockIndex MANGLE(GetUniformBlockIndex)
./GL/glext.h:GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint, const GLchar *);


ATI ships own headers with the driver. I tried to use them but without any success.

Perhaps someone can identify the problem.

Greetings,

Jotschi

kRogue
12-03-2009, 12:27 PM
It might be that the function is not exposed to the linker ld, but available via glXGetProcAddress (or whatever the function call was). All in all, you should load the function pointers yourself at runtime, be it your own code or some extension handler like GLEW or GLEE.

Jotschi
12-03-2009, 02:27 PM
It might be that the function is not exposed to the linker ld, but available via glXGetProcAddress (or whatever the function call was). All in all, you should load the function pointers yourself at runtime, be it your own code or some extension handler like GLEW or GLEE.


Hi,

i tried to use glXGetProcAddress to get the function pointer:


#include <GL/glx.h>

#define GL_GLEXT_PROTOTYPES
#include "GL/gl.h"
#include "GL/glext.h"
#include "GL/glu.h"

#include <stdio.h>
#define glXGetProcAddress(x) (*glXGetProcAddressARB)((const GLubyte*)x)

//GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint, const GLchar *);
//typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName);

int main(int argc, const char** argv) {

__GLXextFuncPtr ptr;
ptr = glXGetProcAddress("glGetUniformBlockIndex");
printf("glXGetProcAddressARB:%016p\n", ptr);

ptr = glXGetProcAddress("glGetUniformBlockIndexARB");
printf("glXGetProcAddressARB:%016p\n", ptr);

GLuint prog_id;
//glGetUniformBlockIndex(prog_id, "colors0");

}


But my output is always:
glXGetProcAddressARB: (nil)
glXGetProcAddressARB: (nil)

For functions i know that they work the addes is != nil.

Is there a way of inspecting the libGL.so to determine which functions are 'exported'?

This drives me crazy :\

kRogue
12-04-2009, 06:55 AM
But my output is always:
glXGetProcAddressARB: (nil)
glXGetProcAddressARB: (nil)

That means that the drivers that you are using from ATI is either bugged or does not support UBO's.

However, the plot thickens:

Firstly what is the string returned by glGetString(GL_VERSION)? Secondly how are you creating your GL context? Thirdly what is the output of glGetString(GL_EXTENSIONS) {if a GL 2.x context} or for GL 3.x, you have to do:

glGetIntegerv(GL_NUM_EXTENSIONS, &amp;numextensions);
for(GLint i=0;i<numextensions;++i)
{
const char *ex;
ex=(const char*)glGetStringi(GL_EXTENSIONS, i);
}

the function glGetUniformBlockIndex will only be present if the GL version is atleast 3.1 and the function glGetUniformBlockIndexARB will only be present if the extension GL_ARB_uniform_buffer_object is present.

Brolingstanz
12-04-2009, 08:42 AM
Yup you really should query the extension string anyways as even a non-NULL pointer returned by glXGetProcAddress is no guarantee of support. See e.g. page 35 of the GLX 1.4 spec.

Jotschi
12-04-2009, 10:23 AM
I created a gl3 context via glglXCreateContextAttribsARB and guess what..

I got my function pointers :)

glXGetProcAddressARB:0x000000b7f9f5d0
glXGetProcAddressARB:0x000000b7fa0620
Version:3.1.9116

Jotschi
12-04-2009, 01:27 PM
Here are some additional information about this issue:

1. How to workaround it:


#define glXGetProcAddress(x) (*glXGetProcAddressARB)((const GLubyte*)x)
PFNGLGETUNIFORMBLOCKINDEXPROC myptr = NULL;

myptr = (PFNGLGETUNIFORMBLOCKINDEXPROC) glXGetProcAddress("glGetUniformBlockIndex");
GLuint prog_id;
(*myptr)(prog_id, "colors0");


This issue is caused because the ati libGL.so does not export all function symbols.

NV (Latest):


objdump -T /usr/lib/libGL.so | grep UniformBlock
000a8f80 g DF .writetext 00000000 Base glGetUniformBlockIndex
000a8fa0 g DF .writetext 00000000 Base glGetActiveUniformBlockiv
000a8fc0 g DF .writetext 00000000 Base glGetActiveUniformBlockName
000a8fe0 g DF .writetext 00000000 Base glUniformBlockBinding


ATI(9-11):


objdump -T /usr/lib/libGL.so | grep UniformBlock


I have one last additional question. How does the glXGetProcAddress method acquire the correct function addresses? Is there a internal register of some kind?

Thanks to everyone who helped to solve this problem.