glReadPixels crashing - Linux

This is a discussion on glReadPixels crashing - Linux ; Cross posted comp.graphics.api.opengl , comp.os.linux.development.apps I am trying to debug the following program. I can easily make it crash on my computer by moving windows around / changing the stacking order. The program creates 4 x (Display / Window / ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: glReadPixels crashing

  1. glReadPixels crashing

    Cross posted comp.graphics.api.opengl , comp.os.linux.development.apps


    I am trying to debug the following program.
    I can easily make it crash on my computer by
    moving windows around / changing the stacking order.

    The program creates 4 x
    (Display / Window / GLXContext / thread ),
    and makes each thread issue sequences of
    glReadPixels / glDrawPixels calls.

    Are these OpenGL calls valid ?
    I know there are several calls missing, but I
    don't think they are required (setting up the
    matrixes / viewport for instance).


    As for the crash, the system is:
    X Window System Version 6.8.2
    Release Date: 9 February 2005
    X Protocol Version 11, Revision 0, Release 6.8.2
    Build Operating System: Linux 2.6.16-gentoo-r9 x86_64 [ELF]
    Current Operating System: Linux jenny 2.6.16-gentoo-r9 #6 SMP Wed Oct
    25 11:26:46 CEST 2006 x86_64

    nvidia driver 1.0-9625
    NVIDIA GPU GeForce 6800 GT at PCI:3:0:0 (GPU-0)
    screen size 1920x1200
    PCIE - 16X

    I have also started a thread for this on www.nvnews.net,
    but so far the problem is not reproducible.
    (http://www.nvnews.net/vbulletin/show....php?p=1042975)


    The purpose of this message is to find out if the bug is with
    the program / the nvidia driver / the system



    Best regards,


    Even Andersen


    -------------------- ------------------------
    /*
    * Compile with:
    * g++ -g -D_REENTRANT -pthread -o bug main.C -lpthread -lGL -lX11
    *
    */

    #include
    #include
    #include

    #include
    #include

    #include
    #include
    #include
    #include

    static XVisualInfo *nn_findVisual(
    Display *display,
    int screen,
    bool doStereo,
    bool doAlpha,
    int numMultiSamples)
    {
    const struct
    {
    bool valid;
    int alphaSize;
    bool stereo;
    int samples;
    int stencil;
    }
    visuals[] = {
    { true, 8, doStereo, 8, 1 },
    { true, 8, doStereo, 4, 1 },
    { true, 8, doStereo, 2, 1 },
    { true, 8, doStereo, 1, 1 },

    { true, 4, doStereo, 8, 1 },
    { true, 4, doStereo, 4, 1 },
    { true, 4, doStereo, 2, 1 },
    { true, 4, doStereo, 1, 1 },

    { true, 2, doStereo, 8, 1 },
    { true, 2, doStereo, 4, 1 },
    { true, 2, doStereo, 2, 1 },
    { true, 2, doStereo, 1, 1 },

    { true, 1, doStereo, 8, 1 },
    { true, 1, doStereo, 4, 1 },
    { true, 1, doStereo, 2, 1 },
    { true, 1, doStereo, 1, 1 },

    { true, 8, doStereo, 0, 1 },
    { true, 4, doStereo, 0, 1 },
    { true, 2, doStereo, 0, 1 },
    { true, 1, doStereo, 0, 1 },

    { true, 0, doStereo, 0, 1 },

    { true, 8, doStereo, 8, 0 },
    { true, 8, doStereo, 4, 0 },
    { true, 8, doStereo, 2, 0 },
    { true, 8, doStereo, 1, 0 },

    { true, 4, doStereo, 8, 0 },
    { true, 4, doStereo, 4, 0 },
    { true, 4, doStereo, 2, 0 },
    { true, 4, doStereo, 1, 0 },

    { true, 2, doStereo, 8, 0 },
    { true, 2, doStereo, 4, 0 },
    { true, 2, doStereo, 2, 0 },
    { true, 2, doStereo, 1, 0 },

    { true, 1, doStereo, 8, 0 },
    { true, 1, doStereo, 4, 0 },
    { true, 1, doStereo, 2, 0 },
    { true, 1, doStereo, 1, 0 },

    { true, 8, doStereo, 0, 0 },
    { true, 4, doStereo, 0, 0 },
    { true, 2, doStereo, 0, 0 },
    { true, 1, doStereo, 0, 0 },

    { true, 0, doStereo, 0, 0 },

    { false, 0, false, 0, 0 }
    };

    for(size_t i = 0; visuals[i].valid; i++)
    {
    int valphaSize = visuals[i].alphaSize;
    bool vstereo = visuals[i].stereo;
    int vsamples = visuals[i].samples;
    int vstencil = visuals[i].stencil;

    if (!doAlpha)
    valphaSize = 0;

    if (!doStereo)
    vstereo = false;

    if (numMultiSamples >= 0) vsamples = numMultiSamples;

    int attributes[32] = { None };
    int numAttributes = 0;

    // attributes[numAttributes++] = GLX_LEVEL;
    // attributes[numAttributes++] = 0;
    attributes[numAttributes++] = GLX_DOUBLEBUFFER;
    attributes[numAttributes++] = GLX_RGBA;
    attributes[numAttributes++] = GLX_RED_SIZE;
    attributes[numAttributes++] = 1;
    attributes[numAttributes++] = GLX_GREEN_SIZE;
    attributes[numAttributes++] = 1;
    attributes[numAttributes++] = GLX_BLUE_SIZE;
    attributes[numAttributes++] = 1;
    attributes[numAttributes++] = GLX_DEPTH_SIZE;
    attributes[numAttributes++] = 1;

    if (valphaSize > 0)
    {
    attributes[numAttributes++] = GLX_ALPHA_SIZE;
    attributes[numAttributes++] = valphaSize;
    }
    if (vstencil > 0)
    {
    attributes[numAttributes++] = GLX_STENCIL_SIZE;
    attributes[numAttributes++] = vstencil;
    }

    if (vstereo)
    {
    attributes[numAttributes++] = GLX_STEREO;
    }

    if (vsamples > 0)
    {
    #ifdef GLX_SAMPLE_BUFFERS_ARB
    attributes[numAttributes++] = GLX_SAMPLE_BUFFERS_ARB;
    attributes[numAttributes++] = 1;
    attributes[numAttributes++] = GLX_SAMPLES_ARB;
    attributes[numAttributes++] = vsamples;
    #else
    # ifdef GLX_SAMPLE_BUFFERS_SGIS
    attributes[numAttributes++] = GLX_SAMPLE_BUFFERS_SGIS;
    attributes[numAttributes++] = 1;
    attributes[numAttributes++] = GLX_SAMPLES_SGIS;
    attributes[numAttributes++] = vsamples;
    # endif /* GLX_SAMPLE_BUFFERS_SGIS */
    #endif
    }


    attributes[numAttributes++] = GLX_ACCUM_RED_SIZE;
    attributes[numAttributes++] = 0;
    attributes[numAttributes++] = GLX_ACCUM_GREEN_SIZE;
    attributes[numAttributes++] = 0;
    attributes[numAttributes++] = GLX_ACCUM_BLUE_SIZE;
    attributes[numAttributes++] = 0;
    attributes[numAttributes++] = GLX_ACCUM_ALPHA_SIZE;
    attributes[numAttributes++] = 0;

    attributes[numAttributes++] = None;

    XVisualInfo *visual = glXChooseVisual(display, screen,
    attributes);
    if (visual)
    {
    return visual;
    }
    } /* end for */

    return NULL;
    }

    static void nn_log(const char *message)
    {
    write(fileno(stderr), message, strlen(message));
    }

    unsigned char buffers[4][768*480*4] = { 0 };

    struct Position
    {
    int x;
    int y;
    int width;
    int height;
    float colorR;
    float colorG;
    float colorB;
    unsigned char *readBuffer;
    const unsigned char *writeBuffer;
    } positions[] =
    {
    { 0, 0, 768, 480, 1, 0, 0, buffers[0], buffers[1] },
    { 110, 0, 768, 480, 1, 1, 0, buffers[1], buffers[2] },
    { 0, 110, 768, 480, 0, 1, 0, buffers[2], buffers[3] },
    { 110, 110, 768, 480, 0, 0, 1, buffers[3], buffers[0] }
    };

    static void nn_readBuffer(const Position *pos)
    {
    glReadPixels(
    0,
    0,
    pos->width,
    pos->height,
    GL_RGBA,
    GL_UNSIGNED_BYTE,
    pos->readBuffer);
    }

    static void nn_drawBuffer(const Position *pos)
    {
    glRasterPos2i(0, 0);
    glDrawPixels(
    pos->width,
    pos->height,
    GL_RGBA,
    GL_UNSIGNED_BYTE,
    pos->writeBuffer);
    }

    void *runThread(void *vpos)
    {
    const struct Position *pos = (const struct Position *)vpos;

    Display *display = XOpenDisplay(":0.0");
    if (!display)
    {
    nn_log(" Can't open display\n");
    return 0;
    }
    else
    {
    nn_log(" Opened display\n");
    }
    Drawable parent = RootWindow(display, 0);

    XVisualInfo *visual =
    nn_findVisual(
    display,
    0,
    false,
    true,
    -1);
    if (!visual)
    {
    nn_log("No visual\n");
    return 0;
    }

    GLXContext context =
    glXCreateContext(
    display,
    visual,
    None,
    GL_TRUE);

    XSetWindowAttributes wa = { 0 };

    wa.colormap =
    XCreateColormap(display, parent, visual->visual, AllocNone );
    wa.background_pixmap = None;
    wa.border_pixel = 0;
    wa.event_mask =
    StructureNotifyMask |
    ExposureMask |
    KeyPressMask |
    KeyReleaseMask |
    EnterWindowMask |
    LeaveWindowMask |
    FocusChangeMask |
    ButtonMotionMask |
    PointerMotionMask |
    ButtonPressMask |
    ButtonReleaseMask;


    Drawable drawable = XCreateWindow(
    display,
    parent,
    pos->x,
    pos->y,
    pos->width,
    pos->height,
    0,
    visual->depth,
    InputOutput,
    visual->visual,
    CWBackPixmap|CWBorderPixel|CWEventMask|CWColormap,
    &wa );

    XMapWindow(display, drawable);
    XFlush(display);

    if (!glXMakeCurrent(display, drawable, context ))
    {
    nn_log("glXMakeCurrent failed\n");
    return 0;
    }

    /*
    * Run event loop
    *
    */
    {
    XEvent event;
    for(;
    {
    XNextEvent(display, &event);

    switch (event.type)
    {
    //default:
    case Expose:
    {
    glXMakeCurrent(display, drawable, context );
    glClearColor(
    pos->colorR,
    pos->colorG,
    pos->colorB,
    0);
    glClear(GL_COLOR_BUFFER_BIT);

    nn_readBuffer(pos);
    nn_drawBuffer(pos);
    glXSwapBuffers(display, drawable);
    break;
    }

    default:
    ;
    } /* end-switch */
    }
    }

    return NULL;
    }

    int main()
    {
    pthread_t id[4];

    pthread_create(id + 0, NULL, runThread, positions + 0);
    pthread_create(id + 1, NULL, runThread, positions + 1);
    pthread_create(id + 2, NULL, runThread, positions + 2);
    pthread_create(id + 3, NULL, runThread, positions + 3);

    pthread_join(id[0], NULL);
    pthread_join(id[1], NULL);
    pthread_join(id[2], NULL);
    pthread_join(id[3], NULL);
    }

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

  2. Re: glReadPixels crashing

    Even O. Andersen wrote:
    > The program creates 4 x
    > (Display / Window / GLXContext / thread ),
    > and makes each thread issue sequences of
    > glReadPixels / glDrawPixels calls.
    >


    From watching this newsgroup over the last few
    years it seems the multithreaded OpenGL apps
    are good at crashing drivers and don't gain any
    speed.

    Best to do all your OpenGL in a single thread.

    --
    <\___/>
    / O O \
    \_____/ FTB. For email, remove my socks.

    In science it often happens that scientists say, 'You know
    that's a really good argument; my position is mistaken,'
    and then they actually change their minds and you never
    hear that old view from them again. They really do it.
    It doesn't happen as often as it should, because scientists
    are human and change is sometimes painful. But it happens
    every day. I cannot recall the last time something like
    that happened in politics or religion.

    - Carl Sagan, 1987 CSICOP keynote address


+ Reply to Thread