using the same PBO for unpack and pack

I’m wondering if it is possible to use a PBO for unpacking (upload to GPU) and then later bind it as packing (download) and vice versa. An example scenario may be


gen buffer
bind as unpack buffer
allocate space
map buffer for write
set data in sys mem
unmap buffer
TexImage2D

then later...

bind as pack buffer
glReadPixels
map buffer for read
do stuff with data
unmap buffer


My reason for asking is that I want to create a pool of PBOs for upload/download to/from the GPU. If a PBO can be used for both, this is fine otherwise I’ll need a separate pool for upload and download PBOs. In the example above, I omit all the stuff I would be doing whilst waiting for the DMA transfer etc. I have a few other questions too, as I’m not very experienced with PBOs:

  1. Will glMapBuffer block until any current transfer is complete for that PBO ?
  2. I read that calling a NULL glBufferData on a PBO will allocate it new memory and cause glMapBuffer to then not block. Will this cancel a previous transfer in the middle of it’s progress?
  3. My bottom-line question is, “is one certain that PBO transfers will complete?” eg. If a glTexImage2D is reading from a PBO and something then calls glBufferData to re-alloc and then glMapBuffer, can we be certain that glTexImage2D will complete its transfer or will it result in a half-loaded texture. Are there any cases when transfer is not guaranteed?

Thanks very much to anyone can enlighten me :slight_smile:

I’m wondering if it is possible to use a PBO for unpacking (upload to GPU) and then later bind it as packing (download) and vice versa.

I wouldn’t suggest reusing the buffer object for these cases. The buffer object usage hints are READ, DRAW, and COPY. DRAW means “user only writes to it.” READ means “user only reads from it.” And COPY means “user neither reads from nor writes to it.”

Notice that there is no option for “user reads from and writes to it”. That’s generally a hint that you shouldn’t do that.

That being said, you certainly can use a buffer object however you wish. But you’ll be less likely to run into performance problems if your buffer object usage actually conforms to the usage pattern you specified when you created it.

  1. Will glMapBuffer block until any current transfer is complete for that PBO ?

Yes. Unless you’re using glMapBufferRange with the GL_UNSYNCHRONIZED_BIT flag.

  1. I read that calling a NULL glBufferData on a PBO will allocate it new memory and cause glMapBuffer to then not block. Will this cancel a previous transfer in the middle of it’s progress?

This is true of all buffer objects.

However, if you’re in the middle of a read operation (pixel pack), then using glBufferData(NULL) is basically announcing that you no longer care about what you’re getting from that read operation.

  1. My bottom-line question is, “is one certain that PBO transfers will complete?”

As far as your application will see, yes.

Thanks a lot. I’ll go give it all a shot now. :slight_smile: