Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 16

Thread: PBO + glReadPixels not so fast?

Hybrid View

  1. #1
    Intern Contributor
    Join Date
    Dec 2004
    Posts
    71

    PBO + glReadPixels not so fast?

    Hi,

    I'm trying to speed up some code that pulls that from the framebuffer using glReadPixels.

    I've created two PBO with usage set to GL_STREAM_READ_ARB. My rendering code then alternate between the two PBO and do the following:

    glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, current);
    glReadPixels(..., 0);
    glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)

    I was under the impression that glReadPixel would return immediately, but these three lines takes about 6 ms for a 1024 x 1024 framebuffer.

    Currently the code isn't doing any map/unmap so the data should never leave the GPU.

    I'm using a Quadro FX 3500 with the latest drivers (169.96).

    Am I doing something wrong or is this to be expected?

    /A.B.

  2. #2
    Advanced Member Frequent Contributor
    Join Date
    Feb 2006
    Location
    Sweden
    Posts
    748

    Re: PBO + glReadPixels not so fast?

    glReadPixels has to wait until the rendering is done until it can start reading, so yes it's as expected.

  3. #3
    Advanced Member Frequent Contributor yooyo's Avatar
    Join Date
    Apr 2003
    Location
    Belgrade, Serbia
    Posts
    883

    Re: PBO + glReadPixels not so fast?

    Use two PBO's. Bind 1st, read pixels, bind 2nd, map and copy data to sysmem, unmap, unbind all PBO's, then swap PBO names. Repeat this every frame.
    One more thing. Use GL_BGR or GL_BGRA pixel format.

  4. #4
    Member Regular Contributor Jackis's Avatar
    Join Date
    Sep 2005
    Location
    Saint-Petersburg, Russia
    Posts
    279

    Re: PBO + glReadPixels not so fast?

    Good reading on PBO upload/readback - http://www.songho.ca/opengl/gl_pbo.html

    PS: Yooyo seems to be little bit tired by answering the same question several times a month

  5. #5
    Intern Contributor
    Join Date
    Dec 2004
    Posts
    71

    Re: PBO + glReadPixels not so fast?

    Quote Originally Posted by yooyo
    Use two PBO's. Bind 1st, read pixels, bind 2nd, map and copy data to sysmem, unmap, unbind all PBO's, then swap PBO names. Repeat this every frame.
    One more thing. Use GL_BGR or GL_BGRA pixel format.
    Exactly what I'm doing. But as I said, it's not as fast as I expected. I don't see much improvement over just doing an ordinary glReadPixels.

    /A.B.

  6. #6
    Advanced Member Frequent Contributor yooyo's Avatar
    Join Date
    Apr 2003
    Location
    Belgrade, Serbia
    Posts
    883

    Re: PBO + glReadPixels not so fast?

    Then you are doing something wrong...
    1. Render frame
    2. bind pbo1
    3. readback
    4. bind pbo2
    5. copy previous frame from pbo to sysmem... map buffer, copy data to sysmem (use some fast memcpy code)
    6. unmap buffer
    7. unbind pbos
    8. swap pbo1 and pbo2

    So.. frame will be in sysmem with one frame delay. With PBO readback call is nonblocking call. But map buggers can be blocking call if there is pending operation related to currently binded. So... if you call map buffer too soon it will be blocking call. If there is no pending operations mapbuffers returns very quickly.

  7. #7
    Intern Contributor
    Join Date
    Dec 2004
    Posts
    71

    Re: PBO + glReadPixels not so fast?

    Ok, so the question is what am I doing wrong?

    The intitation code looks roughly like this:

    Code :
    SomeClass::initPBO() {
      glGenBuffersARB(2, m_ids);
      for (int i = 0; i < 2; ++i) {
        glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, m_ids[i]);
        glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, m_width * m_height * 4, 0, GL_STREAM_READ_ARB);
      }
      glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
      m_active = 0;
    }

    and the capture code looks like this:

    Code :
    SomeClass::capture() {
      glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, m_ids[m_active]);
      glReadPixels(0, 0, m_width, m_height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
      glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
      m_active = 1 - m_active;
    }

    As you can see, right now I'm not even mapping the buffers (eventually I will of course, otherwise this whole excersize would be kind of pointless), and the code in capture still takes about 6 ms. This could still stall I guess if one were rendering at a high enough framerate? However, my rendering is capped at 15 fps so this shouldn't be an issue.

    The values for m_width and m_height has not changed since I created the buffers so their sizes are still valid.

    /A.B

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •