1

我正在开发一个使用 PBO 在 cpu 和 gpu 之间传输数据的 GPGPU 应用程序。我的应用程序中的一项要求是 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);
}
4

2 回答 2

3

我会说最大的延迟将出现在对 copy() 和/或 glUnmapBuffer() 的调用中,但这取决于很多事情(主要是您的硬件),您最好的选择是在开始时进行一次传输程序并测量它们。对于计时,您应该使用带有高分辨率计时器(例如 QuerPerformanceCounter)的 glFinish() 函数。

于 2011-07-31T19:11:49.820 回答
1

由于这是结构化的,它可能会阻塞glTexSubImage(尽管它最终取决于实现,理论上实现可以推迟这个)。如果您先上传几个缓冲区,然后glTexSubImage按照定义/上传的顺序调用每个缓冲区,您的停顿可能会少很多。

do_other_cpu_stuff调用可能不会有太大帮助,因为它已经更早地阻塞了。

如果您有可用的 ARB_copy_buffer 功能,您可以通过首先在临时缓冲区中定义一些缓冲区数据,然后告诉 OpenGL 在 GPU 上进行缓冲区到缓冲区的复制来进一步避免停滞。
直观地说,这应该不会更快(相当慢),但由于某种我无法理解的原因,它实际上更快

于 2011-07-31T21:55:50.197 回答