我有一个迭代调度的计算着色器,并使用2d纹理临时存储值。每个调用id都访问纹理中的特定行。
问题是,在每个着色器调度之前,必须将此纹理初始化为0。
目前,我在着色器代码的末尾使用了一个循环,该循环使用imageStore()将相应行中的所有像素重置为0。
for (uint i = 0; i < CONSTANT_SIZE; i++)
{
imageStore( myTexture, ivec2( i, global_invocation_id ), vec4( 0, 0, 0, 0) );
}
我想知道是否有更快的方法来实现这一点,一种方法可以通过一次调用设置多个像素(最好是整行)?我已经查看了关于图像操作的GLSL 4.3规范,但我找不到一个不需要特定像素位置的规范。
如果有一种更快的方法在CPU上实现这一点我也会对此开放,我尝试使用glTexImage2D()重新缓冲纹理,但是对于每个使用imageStore并没有任何明显的性能变化个别像素。
答案 0 :(得分:3)
“更快的方法”是从OpenGL清除纹理,而不是在着色器中清除纹理。 4.4提供direct texture clearing function,但即使是通过glTexSubImage2D进行像素传输这样简单(当然在屏障之后)也可能比你正在做的更快。
或者,如果您使用此纹理的所有内容都是用于调用的临时内存...为什么使用纹理?为此使用shared variables会更好。只需创建一个vec4数组数组,每个本地调用访问一个数组数组。访问它们的速度会更快。
给定共享变量的32KB存储空间(允许的最小值),如果每个工作组有8个调用,则每个工作组可以使用4KB。这给了每个256 vec4
s。如果最多移动16个调用,则将其减少到128 vec4
s。