为什么使用PBO上传数据要比不使用PBO慢?

时间:2018-10-30 18:23:51

标签: c++ opengl textures shader

在我的程序中,我必须每帧最多上传100个纹理。

我正在使用glTextureSubImage2D上载数据,我试图通过使用持久映射的PBO来提高性能。但是我的fps下降了大约10%。我认为至少性能是相等的,它怎么可能降低?

在填写PBO之后立即调用glTextureSubImage2D是一个坏主意吗?我还能采取其他措施来提高PBO的性能吗?

这是我的代码:

创建pbo:

// Create pbo
glCreateBuffers(1, &pbo);
glNamedBufferStorage(pbo, size, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
pbo_data = glMapNamedBufferRange(pbo, 0, size, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);

将所有数据加载到PBO:

// Load all ktx textures into the PBO
for (size_t i = 0; i < paths.size(); ++i) {
// Read ktx into pbo_data, which is a persistently mapped pointer of pbo
// Return header with ktx info
    auto header = loadKtxToPbo(pbo_data, paths[i]); // This function reads ktx file and loads it directly into the pbo, returns ktx header and offset into the pbo for current ktx
    headers[i] = header;
}

从PBO加载纹理:

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
for (size_t i = 0; i < textures.size(); ++i) {
    auto header = headers[i];
    glCreateTextures(GL_TEXTURE_2D, 1, &textures[i].id);
    glTextureStorage2D(textures[i].id, 1, header.internal_format, header.width, header.height);
    glTextureSubImage2D(textures[i].id, 0, 0, 0, header.width, header.height, header.internalFormat, header.type, header.offset);
}

1 个答案:

答案 0 :(得分:0)

创建和初始化纹理非常昂贵。如果您必须每帧加载大量纹理数据(例如,播放电影,动画精灵等),通常的方法是拥有一组预先分配的超大纹理甚至是纹理图集,您只需将这些更新更新即可次矩形。

尽管我们已经超越了2幂次方维度约束的时代,但此类纹理池的常规合并通常以2幂次方完成。因此,我建议您收集有关到达的纹理尺寸的统计信息,将每个尺寸四舍五入为下一个2的幂,对每个仓中落入多少图像进行计数,然后将该数字四舍五入为下一个2的幂。并使用它作为纹理池的bin大小。

最后,将纹理名称收集到LRU中。