4 Replies Latest reply on Jan 26, 2012 8:51 AM by xavier_om

    using PBO to upload large image lead to damaged image

    jianliang79

          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.