2

我有一个迭代调度的计算着色器,并使用 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 并没有任何明显的性能变化。

4

1 回答 1

3

“更快的方法”是从 OpenGL 中清除纹理,而不是在着色器中。4.4 提供了直接的纹理清除功能,但即使是通过 glTexSubImage2D (当然是在屏障之后)进行像素传输这样简单的事情也可能比您正在做的更快。

或者,如果您使用此纹理的只是用于调用的暂存内存……您为什么要使用纹理?最好使用共享变量。只需创建一个 vec4 数组数组,其中每个本地调用访问一个数组数组。访问这些将更快地加载。

给定 32KB 的共享变量存储空间(允许的最低限度),如果每个工作组有 8 次调用,那么每个工作组有 4KB 的空间可供使用。这给了每个人 256vec4秒的时间来玩。如果最多移动 16 次调用,则将其减少到 128vec4秒。

于 2013-08-21T23:26:40.890 回答