我正在开发一个GPGPU应用程序,它使用PBO在cpu和gpu之间传输数据。我的应用程序中的一个要求是OpenGL渲染线程应该尽可能少地阻塞,并且处理应该具有尽可能低的延迟。
我的问题是我是否必须在调用glTexSubImage2D(从主机到设备开始转换)和实际使用/渲染纹理之间添加延迟?对于具有例如纹理的纹理,这种延迟应该有多大尺寸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);
glBindTexture(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);
}
答案 0 :(得分:3)
我会说最大延迟将在调用copy()和/或glUnmapBuffer(),但它将取决于很多东西(主要是你的硬件),你最好的选择是在程序的开始和测量它们。 对于时间,你应该使用glFinish()函数和高分辨率计时器(例如QuerPerformanceCounter)。
答案 1 :(得分:1)
由于这是结构化的,它可能会阻塞glTexSubImage
(尽管它最终取决于实现,理论上实现可能推迟这个)。如果你先上传了几个缓冲区然后按照它们被定义/上传的顺序在每个缓冲区上调用glTexSubImage
,你可能会有更少的停顿。
do_other_cpu_stuff
调用可能没有多大帮助,因为它已经提前阻止了。
如果您有ARB_copy_buffer功能可用,您可以先在临时缓冲区中定义一些缓冲区数据然后告诉OpenGL在GPU上执行缓冲区到缓冲区的复制,从而进一步避免停顿。 直观地说,这应该没有更快(相当慢)但由于某些原因超出我的范围,实际上更快。