OpenGL display lists crash iR ?

New Message Reply Date view Thread view Subject view Author view

From: Rajko Schoeffel (rajko.schoeffel++at++artemedia.de)
Date: 09/12/2000 08:52:22


[Sorry but this is not directly related to Performer, but OpenGL on iR]
[Please reply to me direct since I am not a member of this mailing list
yet.]

Hello,

we try to find a bug in our VisSim application, which crashes
sporadically
if it runs on a Onyx/iR or Onyx2/iR2 machine and if it uses many OpenGL
display lists.
The bug is very hard for us to find since no coredump is created,
but the gfx pipe crashes internally or the process is killed.

The application runs fine on other architectures, such as SGI O2 (IRIX),

SGI 540 (NT,W2000) and PC with nVidia GeForce2 (W2000) (always using
OpenGL display lists).

We used Purify / malloc_cv / dmalloc to check our memory, but the app
crashed (reproducable now)
always somewhere at __glXFree().

It seems that something goes wrong with the display list management on
the iR/iR2.
To confirm this theory, I wrote a very simple test app, which creates
many display lists
and sends them again and again to the gfx pipe.

This simple app does not crash :) but if I use malloc_cv or malloc_ss,
it complains about corrupted heap blocks, but only if the size and
number of
the display lists exceed a particular limit. Since the test app doesn't
use malloc(),
the heap blocks must be getting corrupt elsewhere.

I estimate the display list limit to be greater than 57 MByte, before
malloc_cv complains.

Can somebody please explain this behaviour? We are really lost, how can

we find our bug if
our debug tools (malloc_cv/dmalloc) do not work? Is there a workaround
for dmalloc? Or is it
a bug in the OpenGL implementation of iR?

thanks for any help,
Rajko

---------------------------------------------------------------------------

/*
  dltest.c

  This will crash malloc_cv/dmalloc on a Onyx/InfiniteReality.

*/

/*
  ENVIRONMENT:

  dmalloc -i 1000 -l dmalloc.log medium -p allow-free-null
  [ setenv DMALLOC_OPTIONS debug=0x24f41d83,inter=1000,log=dmalloc.log ]

  try: (libGL.so is the only lib with .init code)
  LD_BIND_NOW=1
  setenv _RLD_ARGS "-ignore_unresolved -v"
  setenv _RLDN32_PATH /usr/lib32/rld.debug

  setenv GLKONA_DLIST_USAGE 1
*/

/* compile: cc -n32 -o dltest dltest.c -lGL -lX11 -lmalloc_cv */

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
#include <GL/gl.h>

static int snglBuf[] = {GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
                        GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 12, None};
static int dblBuf[] = {GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
                        GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 12,
GLX_DOUBLEBUFFER, None};

Display *dpy;
Window win;
Bool doubleBuffer = True;
/* Initial 3D box orientation. */
GLfloat xAngle = 42.0, yAngle = 82.0, zAngle = 112.0;

void redraw(void);
void buildDL(void);
void callDL(void);
void warmUpMalloc(void);

void
fatalError(char *message)
{
  fprintf(stderr, "dltest: %s\n", message);
  exit(1);
}

void
main(int argc, char **argv)
{
    XVisualInfo *vi;
    Colormap cmap;
    XSetWindowAttributes swa;
    GLXContext cx;
    XEvent event;
    Bool needRedraw = False, recalcModelView = True;
    int dummy;

    dpy = XOpenDisplay(NULL);
    if (dpy == NULL) fatalError("could not open display");

    if (!glXQueryExtension(dpy, &dummy, &dummy))
        fatalError("X server has no OpenGL GLX extension");

    vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
    if (vi == NULL)
    {
        vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
        if (vi == NULL)
            fatalError("no RGB visual with depth buffer");
        doubleBuffer = False;
    }
    if (vi->class != TrueColor)
        fatalError("TrueColor visual required for this program");

    cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
                           vi->visual, AllocNone);
    swa.colormap = cmap;
    swa.border_pixel = 0;
    swa.event_mask = ExposureMask | ButtonPressMask |
StructureNotifyMask;
    win = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
                        0, 0, 300, 300, 0, vi->depth,
                        InputOutput, vi->visual,
                        CWBorderPixel | CWColormap | CWEventMask, &swa);

    XSetStandardProperties(dpy, win, "dltest", "dltest",
                           None, argv, argc, NULL);

    cx = glXCreateContext(dpy, vi,
                          /* No sharing of display lists */ None,
                          /* Direct rendering if possible */ True);
    if (cx == NULL)
        fatalError("could not create rendering context");

    glXMakeCurrent(dpy, win, cx);

    XMapWindow(dpy, win);

    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10.0);

    while (1) {
        while(XPending(dpy))
        {
            XNextEvent(dpy, &event);
            switch (event.type)
            {
                case ButtonPress:
                    switch (event.xbutton.button) {
                        case 1: xAngle += 10.0; break;
                        case 2: yAngle += 10.0; break;
                        case 3: zAngle += 10.0; break;
                    }
                    break;
                case ConfigureNotify:
                    glViewport(0, 0, event.xconfigure.width,
                               event.xconfigure.height);
                    break;
            }
        }

        xAngle += 1.0;
        if( xAngle >= 360.0 ) xAngle = 0.0;

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(0.0, 0.0, -3.0);
        glRotatef(xAngle, 0.1, 0.0, 0.0);
        glRotatef(yAngle, 0.0, 0.1, 0.0);
        glRotatef(zAngle, 0.0, 0.0, 1.0);

        redraw();
    }
}

void
redraw(void)
{
  static Bool displayListInited = False;

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  if (displayListInited)
  {
    glCallList(1);
    callDL();
  }
  else
  {
    /* Otherwise compile and execute to create the display
       list. */
      buildDL();
      glNewList(1, GL_COMPILE_AND_EXECUTE);
      glBegin(GL_QUADS);
        /* Front face */
        glColor3f(0.0, 0.7, 0.1); /* Green */
        glVertex3f(-1.0, 1.0, 1.0);
        glVertex3f(1.0, 1.0, 1.0);
        glVertex3f(1.0, -1.0, 1.0);
        glVertex3f(-1.0, -1.0, 1.0);
        /* Back face */
        glColor3f(0.9, 1.0, 0.0); /* Yellow */
        glVertex3f(-1.0, 1.0, -1.0);
        glVertex3f(1.0, 1.0, -1.0);
        glVertex3f(1.0, -1.0, -1.0);
        glVertex3f(-1.0, -1.0, -1.0);
        /* Top side face */
        glColor3f(0.2, 0.2, 1.0); /* Blue */
        glVertex3f(-1.0, 1.0, 1.0);
        glVertex3f(1.0, 1.0, 1.0);
        glVertex3f(1.0, 1.0, -1.0);
        glVertex3f(-1.0, 1.0, -1.0);
        /* Bottom side face */
        glColor3f(0.7, 0.0, 0.1); /* Red */
        glVertex3f(-1.0, -1.0, 1.0);
        glVertex3f(1.0, -1.0, 1.0);
        glVertex3f(1.0, -1.0, -1.0);
        glVertex3f(-1.0, -1.0, -1.0);
      glEnd();
      glEndList();
      displayListInited = True;
  }

  if (doubleBuffer)
      /* Buffer swap does implicit glFlush. */
      glXSwapBuffers(dpy, win);
  else
      /* Explicit flush for single buffered case. */
      glFlush();
}

/*const int nlists = 0x7fff;*/ /* 20000 */

/*const int nlists = 15600; */ /* 2800 */
/*const int nvtx = 99; */ /* 99 */

const int nlists = 2;
const int nvtx = 900000; /* 800000 * 2 no_crash */

int listBase = 1;
GLfloat unitVector3F[] = {1.0, 1.0, 1.0};
GLfloat unitVector2F[] = {1.0, 1.0};

void buildDL(void)
{
    int i,j;
    srand( 93847 );
    printf("building display lists...\n");
    listBase = glGenLists(nlists);
    if( listBase == 0 )
        fatalError("could not generate display lists");

    for(i=0; i<nlists; ++i)
    {
        glNewList(i+listBase, GL_COMPILE);
        glBegin( GL_TRIANGLES );
        for( j=0; j<nvtx; ++j ) /* 100 */
        {
            glTexCoord2fv( unitVector2F );
            glNormal3fv ( unitVector3F );
            glVertex3fv ( unitVector3F);
        }
        glEnd();
        glEndList();
        if( glGetError() != GL_NO_ERROR )
        {
            fatalError("OpenGL error (buildDL)");
        }
        printf("%d\r",i);
    }
    printf("done \n");
}

void callDL(void)
{
    static int callCount = 0;
    int i;
    ++callCount;
    printf("calling display lists... (%d)\n", callCount);
    for(i=0; i<nlists; ++i)
    {
        /* glCallList( (rand() & nlists) + listBase ); */
        glCallList( i + listBase );
        if( glGetError() != GL_NO_ERROR )
        {
            fatalError("OpenGL error (callDL)");
        }
    }
    printf("done\n");
}

----------------------------------------------------------------------------------

--
rajko schoeffel,                       software engineer
mailto:rajko.schoeffel++at++artemedia.de    http://www.artemedia.de
fon:  +49 [0]331-7062-266,             fax: +49 [0]331-7062-300
artemedia ag berlin_babelsberg,
fx.center, august-bebel-strasse 26-53, 14482 potsdam


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2b29 : Tue Sep 12 2000 - 08:53:30 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.