我试图找出最好的方法是使用计算着色器生成OpenGL纹理。到目前为止,我已经了解到像素缓冲区对象非常适合无阻塞的CPU-> GPU传输,并且计算着色器能够读写缓冲区,而不管绑定方式如何。理想情况下,我希望避免复制过多。换句话说,我想在GPU上分配一个缓冲区,向其写入压缩的纹理数据,然后将该缓冲区用作着色器中的纹理对象。

当前,我的代码看起来有些类似像这样:

GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
glBufferStorage(GL_SHADER_STORAGE_BUFFER, tex_size_in_bytes, 0, 0);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

// Bind buffer to resource in compute shader
// execute compute shader

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
glCompressedTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, tex_size_in_bytes, 0);


这是正确的吗?我也读过有关保证同步的内容。我需要添加什么以确保我的计算着色器在从缓冲区对象进行复制之前完成执行?

评论

您想指定您喜欢的纹理压缩格式吗?我正在猜测,但是您的答案可能涉及计算模式纹理压缩例程。

#1 楼

在研究了一段时间之后,我发现了几件事:


您无法避免memcpy:您不能仅使用OpenGL API直接写入分配给压缩纹理的纹理存储中电话。这意味着您无法避免使用绑定的PBO来调用glCompressedTexImage2D。话虽如此,您也许可以在计算着色器中使用16位RGBA纹理和GLSL图像类型。
您确实需要同步内存:为了确保您的计算着色器完成向您的写入存储缓冲区,必须确保对它的所有读取和写入完成。这是通过用glMemoryBarrier调用GL_SHADER_STORAGE_BARRIER_BIT来完成的。

写入缓冲区以用作压缩纹理的内容的完整代码如下所示: >

评论


$ \ begingroup $
“您也许可以使用16位RGBA纹理和一个”,还有什么? :)
$ \ endgroup $
–内森·里德(Nathan Reed)
2015年9月19日,1:12

$ \ begingroup $
哈哈,这是您将选项卡打开以待稍后完成时发生的情况。编辑。
$ \ endgroup $
– Mokosha
2015年9月19日,1:13

$ \ begingroup $
GL_SHADER_STORAGE_BARRIER_BIT错误的障碍。您提供的障碍说明了如何使用内存。并不是着色器如何写入的。您正在执行像素转移,因此需要使用GL_TEXTURE_UPDATE_BARRIER_BIT
$ \ endgroup $
–尼科尔·波拉斯(Nicol Bolas)
16-11-5在17:57

$ \ begingroup $
确定吗?根据文档,GL_TEXTURE_UPDATE_BARRIER_BIT在同步对glTexImage的调用时使用,与存储缓冲区中使用的内存无关。我认为您的意思是GL_PIXEL_BUFFER_BARRIER_BIT?
$ \ endgroup $
– Mokosha
2016年12月9日4:00