I have a question regarding PBOs in a CPU -> GPU transfer scenario.
When a PBO is bound, I understand glTexImage2D() returns immediately. What happens with regards to OpenGL rendering while the texture data is being transfered?
What happens if, say, I have a fragment shader attempting to do texture reads on the texture being transfered? Will the values be unpredictable? Or will the texture fragment lookup wait/stall until the texture transfer has completed?
No, it is not unpredicatble. While TexImage in fact returns immediately, the forthcoming rendering commands will actually be executed on the GPU after the image transfer happened.
When you usually issue a draw call that is not executed immediately either. Commands on the server side are always executed in the order you requested so even though TexImage will return immediately on the client side, on the server side it will be executed before any subsequent commands.
// (*) Request new buffer data (third parameter = NULL)
// This call will return immediately. The GPU will complete any transfer in progress with the previous buffer data
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, DATA_SIZE, NULL, GL_STREAM_DRAW_ARB);
// Load up new pixels into the same pbo, but into its new buffer data (requested above), not the previous one
glMapBuffer
updatePixels
glUnmapBuffer
// Issue asynchronous transfer to texture
glTexImage2D(…, 0);
This version is okay. It should be as efficient as two PBOs as you anyway discard the previous buffer and ask for new storage.
In such cases actually the driver will retain the previously allocated storage until the transfer is completed so actually in this case also at least two PBOs are present just the application does not have to worry about it.
Yes.
I am a bit surprised the web page I mentionned above explicitly manages 2 different PBOs, but also still uses the trick here to discard the previous buffer.