Async glTexSubImage2D and OGL thread blocking
I'm working on a GPGPU application that transfers data between the cpu and gpu using PBOs. One requirement in my application is that the OpenGL rendering thread should be blocking as little as possible and the processing should have as low latency as possible.
My question is whether I have to add latency between the call to glTexSubImage2D (which starts the transform from host to device) and actually using/rendering with the texture? How large should such a latency be for a texture with e.g. size 1024x1024?
for(auto texture: textures)
{
glBindTexture(GL_TEXTURE_2D, texture.id());
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, ...);
glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, ..., NULL, GL_STREAM_DRAW);
void* mem = glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);
copy(mem, data);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, ..., NULL);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
glBind开发者_如何学GoTexture(GL_TEXTURE_2D, 0);
}
do_other_cpu_stuff_while_data_is_transferring(); // Is this needed to avoid blocking calls while rendering? If so, what strategy can I use to estimate the minimum amount of time needed to transfer the data.
for(auto texture: textures)
{
render(texture);
}
I would say that the most latency will be in the call to copy() and/or glUnmapBuffer(), but it will depend on so many things (your hardware, mainly) that your best bet is to do one transfer at the beginning of the program and measure them. For the timing you should use the glFinish() function with a high resolution timer (such as QuerPerformanceCounter).
As this is structured, it will likely block in glTexSubImage
(though it finally depends on the implementation, in theory an implementation could defer this). You would likely have a lot fewer stalls if you uploaded a couple of buffers first and then called glTexSubImage
on each one in the order they were defined/uploaded.
The do_other_cpu_stuff
call will likely not help a lot because it already blocks earlier.
If you have ARB_copy_buffer functionality available, you can further avoid stalling by first defining some buffer data in a temp buffer and then telling OpenGL to do a buffer-to-buffer copy on the GPU.
Intuitively, this should be none faster (rather slower) but for some reason that's beyond me, it is actually faster.
精彩评论