Hi,

While I was studying OpenGL with Mesa, I got a problem concerning
glAreTexturesReside().

First, please skim the following small glut program, whose original
purpose is to illustrate how to do texture prioritization with
OpenGL API, though the prioritization is not the issue of this
note.

#include <GL/glut.h>

GLuint texture;

void init(void)
{
   GLubyte pixel[] = { 0xff, 0xff, 0xff };
   GLclampf priority = 1.0f;

   glGenTextures(1, &texture);
   glBindTexture(GL_TEXTURE_2D, texture);
   glTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0,
        GL_RGB, GL_UNSIGNED_BYTE, pixel);
   glPrioritizeTextures(1, &texture, &priority);

   glEnable(GL_TEXTURE_2D);
}

void display(void)
{
   GLboolean residence = GL_FALSE;

   glAreTexturesResident(1, &texture, &residence);
}

int main(int argc, char *argv[])
{
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_RGBA);
   glutCreateWindow(argv[0]);
   glutDisplayFunc(display);
   init();
   glutMainLoop();
   return 0;
}

Do you see anything wrong with the code above?  Actually,
it compiles. It works fine if direct rendering is enabled.
I found, however, it resulted in segfault when I did
   $ LIBGL_ALWAYS_INDIRECT=1 ./prog

That's the problem I got.

Looking for the cause of the segfalut, I used gdb with
the core dumped. But it didn't give me any useful clue
for the cause because it only suggested that the value of
an internal variable of glut was invalid, which I thought
was irrelevant to the problem.

So, after tweaking the code above, I found:
(1) If the call of glAreTexturesResident() was removed,
   segfault didn't take place.
(2) If either the scope or the storage type of 'residence',
   which is a local variable of the function display(),
   was changed to local static or global, segfalut didn't
   take place. (In this case, the glAreTexturesResident
   code was not removed.)

Since the fact (2) suggested that there was something wrong
with the stack or frame, I suspected it was due to a bug
of the compiler I used. But I soon came to realize that
it was fairly unlikely: the same problem arose even with
the binary compiled with gcc-2.95.3 or gcc-3.4.4, not only
with the latest gcc-4.0.2.

So I concluded, as the fact (1) suggested, that there was
something wrong with glAreTexturesResident(), to be more
specific, __indirect_glAreTexturesResident(), whose
implementation was given src/glx/x11/indirect.c.

At line 4306 of the file, the function

GLboolean
__indirect_glAreTexturesResident(GLsizei n,
                               const GLuint *textures,
                               GLboolean *residences);

is defined. Unless USE_XCB is defined, the function invokes

CARD32
__glXReadDisplay(Display *dpy,
               size_t size,
               void *dest,
               GLboolean reply_is_always_true);

with the parameters size = 1, dest = residences, and
reply_is_always_true = GL_TRUE.

The implementation of __glXReadDisplay() is given at line 66
of the same file. The following is the excerpt of the
implementation:

xGLXSingleReply reply;
_XReply(dpy, &reply, 0, False);
if (size != 0) {
  if ((reply.length > 0) || reply_is_always_true) {
      const GLint bytes = (reply_is_always_array)
        ? (4 * reply.length) : (reply.size * size);
      ...
      _XRead(dpy, dest, bytes);
      ...
  }
...
}

Since size = 1, and reply_is_always_true = GL_TRUE in our
particular case, the value of the local variable 'bytes' is
equal to that of 4 * reply.length if reply.length > 0. This
implies that we let _XRead() write the reply from the server
to the parameter 'dest' as if the storage size 'dest' points
to were at least 4 bytes, which is wrong in our particular
case where 'dest' is actually a pointer to a variable of type
GLboolean.

I think this caused the segfault I mentioned in the middle
of this note.  It also seemingly explains the "undefined
behavior"-like phenomenon, i.e., the fact (2).

It looks to me that the implementation of __glXReadDisplay()
is valid only for the case where the parameter 'size' is set
to 4.  IOW, the case for 'size' = 1, 2 is not appropriately
supported.

Did I miss something?

Thanks,
KK




-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to