我正在尝试为Forward + Shading创建一个全局链表,但是有一些
实施过程中的困难。
对于计算着色器中的每个组,它有一个共享变量:一个本地索引数组,并且此数组具有可变长度(容量是常量,但内容不是)。这是一个例子:
shared int array [1024]; // GLSL中的声明
shared int length; //它也是工作组中的共享变量。
组0:长度= 4,数组= 3,5,7,1,-1,-1,-1,-1 ....( - 1 =无效)
组1:长度= 2,数组= 1,6,-1,-1,-1 ....
组2:长度= 1,数组= 8,-1,-1,-1,-1 ....
现在我想将这些索引合并到一个全局索引数组中。即着色器存储缓冲区对象。订单基于组索引:
全局索引数组:3,5,7,1,1,6,8,-1,-1,-1 ......
困难在于,我不知道如何在不同的群体之间进行同步。由于OpenGL中的barrier()仅保证同一组中的同步。
我发现其他帖子中说OpenGL不支持不同组之间的同步。
OpenGL Compute shader sync different work groups
所以,我的问题是。无论如何要实现我的目标吗?
例如,我可以声明一些Shader存储缓冲区对象,例如已完成更新的最新组ID和全局索引数组的偏移量吗?
示例:
unit latestGroupIDUpdated = -1; // a SSBO
unit globalIdxOffset = 0; // a SSBO
in each group:
while( myGroupId - 1 != latestGroupIDUpdated )
{ //keep waiting }
// my previous group has updated the global list
globalIdxOffset+= myArrayLength;
latestGroupIDUpdated = myGroupId;
//now start appending the local index array into global index array
这种尝试会起作用吗?或者它会失败,为什么?
如果失败,建议采用何种方法?
答案 0 :(得分:0)
看起来,看起来你在1D中组织了你的LOCAL GROUP:
layout(local_size_x = X, local_size_y = 1, local_size_z = 1) in;
如果您致电glDispatch(n * X, 1, 1)
,您将有n个小组。
n组之间的处理也是并行执行的,因此您不会知道每个groupID
的更新顺序。使用“latestGroupIDUpdated
”无效。
这是我的方法,您应该使用内置变量
gl_GlobalInvocationID (gl_GlobalInvocationID.x in our case)
gl_GlobalInvocationID.x = gl_WorkGroupID.x * gl_WorkGroupSize.x + gl_LocalInvocationID.x;
---//gl_WorkGroupID.x; [0, n) - 'n' : num groups you dispatched
---//gl_WorkGroupSize.x; X - size (3 in your example)
---//gl_LocalInvocationID.x; [0, gl_WorkGroupSize.x) - or [0, X)
您可以使用gl_GlobalInvocationID.x
索引“global
'SSBO列表以存储”length
“。类似的东西:
GlobalLengthList[gl_GlobalInvocationID.x] = length;
所有这些只是为了在'length
'SSBO列表中以组顺序存储动态值'global
'。在C / C ++应用程序中调用length
后,所有这些“glMemoryBarrier()
”都会更新。
之后,您将不得不修改此数组,以便它存储“长度”数组的“前缀和”(包括)。此过程高度并行化。如果您正在尝试节省时间,可以在单独的计算着色器中执行此操作。 (如果你的长度数组很长,我建议你这样做。)您也可以在CPU上执行此操作。
在你拥有包含前缀和长度数组(让我们称之为PrefixSumLengthArray)之后,你需要再次调用glDispatch()
来发送与总'长度'值一样多的着色器调用 - 你的{的最后一个值{1}}。然后,您将使用PrefixSumLengthArray
索引到新的gl_GlobalInvocationID
列表以存储阵列。类似的东西:
SSBO
这将在不同的群体之间进行同步!