jianliang79

using PBO to upload large image lead to damaged image

Discussion created by jianliang79 on Sep 6, 2011
Latest reply on Jan 26, 2012 by xavier_om

    I use PBO to upload an large image(3072 x 2048) to an 2D texture, it seems that the image has been damaged during loading(there is no problem if the image is not big enough). My computer is a windows 7 x64 and I have install the catalyst 11.8 driver, my video card is radeon HD 5770. The following code snippet can produce this problem:

    ...

    QImage img("d:/big_image.png");
    const unsigned int imageWidth = img.width();
    const unsigned int imageHeight = img.height();

    // create texture
    GLuint tex = 0;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imageWidth, imageHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);

    // create PBO
    GLuint pbo = 0;
    glGenBuffers(1, &pbo);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);

    // allocate storage for PBO
    glBufferData(GL_PIXEL_UNPACK_BUFFER, imageWidth * 4 * imageHeight, 0, GL_DYNAMIC_DRAW);

    // map PBO
    void *pboBuffer = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, imageWidth * imageHeight * 4, GL_MAP_WRITE_BIT);
    if (pboBuffer) {
        unsigned char *pixel = (unsigned char *)pboBuffer;
        for (int i = 0; i < imageHeight; i++) {
            memcpy(pixel, img.scanLine(i), img.bytesPerLine());
            pixel += img.bytesPerLine();
        }

        glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
    }

    // copy PBO to texture
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, imageWidth, imageHeight, GL_BGRA, GL_UNSIGNED_BYTE, 0);

    // download texture image
    glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, img.bits());

    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
    glDeleteBuffers(1, &pbo);
    glDeleteTextures(1, &tex);

    img.save("d:/output.bmp");

    ...

 

    The idea of code is to load an big image (for example, 3072 x 2048, and this image should be a 32bit ARGB image), create a PBO and a texture to load this image to the texture(through the PBO), and then download this texture back to host memory and save it to a image file. The newly saved image file should have the same content of the original image file, but according to my test, when the image is big enough the output image is damaged. Is this my code's bug or a driver bug?

    To run this code, you have to install Qt library, but if don't have Qt, you can use whatever toolkit you like to load and store image and replace the Qt code. Both a GL2 or GL3 context can produce this problem.

Outcomes