summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/base/shaders/sum3.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/base/shaders/sum3.glsl')
-rw-r--r--Build/source/utils/asymptote/base/shaders/sum3.glsl80
1 files changed, 66 insertions, 14 deletions
diff --git a/Build/source/utils/asymptote/base/shaders/sum3.glsl b/Build/source/utils/asymptote/base/shaders/sum3.glsl
index 85f55ff2a6c..4ee5203060b 100644
--- a/Build/source/utils/asymptote/base/shaders/sum3.glsl
+++ b/Build/source/utils/asymptote/base/shaders/sum3.glsl
@@ -1,28 +1,80 @@
-layout(local_size_x=LOCAL_SIZE_X) in;
+layout(local_size_x=LOCALSIZE) in;
-uniform uint offset2;
+const uint groupSize=LOCALSIZE*BLOCKSIZE;
-layout(binding=2, std430) buffer localSumBuffer
+uniform uint final;
+
+layout(binding=0, std430) buffer offsetBuffer
+{
+ uint maxDepth;
+ uint offset[];
+};
+
+layout(binding=2, std430) buffer countBuffer
{
- uint localSum[];
+ uint maxSize;
+ uint count[];
};
-layout(binding=3, std430) buffer globalSumBuffer {
+layout(binding=3, std430) buffer globalSumBuffer
+{
uint globalSum[];
};
-void main(void)
+layout(binding=8, std430) buffer feedbackBuffer
{
- uint id=gl_GlobalInvocationID.x;
+ uint size;
+ uint fragments;
+};
- uint row=offset2+LOCAL_SIZE_X*id;
- uint stop=row+LOCAL_SIZE_X;
+shared uint shuffle[groupSize+LOCALSIZE-1u];
+shared uint groupSum[LOCALSIZE+1u];
+
+void main()
+{
+ uint id=gl_LocalInvocationID.x;
- uint Sum=localSum[row];
- for(uint i=row+1u; i < stop; ++i) {
- Sum += localSum[i];
- localSum[i]=Sum;
+// avoid bank conflicts and coalesce global memory accesses
+ uint dataOffset=gl_WorkGroupID.x*groupSize+id;
+ uint shuffleOffset=id/BLOCKSIZE+id;
+ const uint stride=LOCALSIZE/BLOCKSIZE+LOCALSIZE;
+ for(uint i=0u; i < BLOCKSIZE; i++)
+ shuffle[shuffleOffset+i*stride]=count[dataOffset+i*LOCALSIZE];
+
+ barrier();
+
+ uint Offset=id*BLOCKSIZE+id;
+ uint stop=Offset+BLOCKSIZE;
+
+ uint sum=0u;
+ for(uint i=Offset; i < stop; ++i)
+ shuffle[i]=sum += shuffle[i];
+
+ if(id == 0u)
+ groupSum[0u]=0u;
+ groupSum[id+1u]=sum;
+ barrier();
+
+ // Apply Hillis-Steele algorithm over all sums in workgroup
+ for(uint shift=1u; shift < LOCALSIZE; shift *= 2u) {
+ uint read;
+ if(shift <= id)
+ read=groupSum[id]+groupSum[id-shift];
+ barrier();
+ if(shift <= id)
+ groupSum[id]=read;
+ barrier();
}
- globalSum[id+1u]=Sum;
+ uint groupOffset=globalSum[gl_WorkGroupID.x];
+ for(uint i=0u; i < BLOCKSIZE; ++i)
+ offset[dataOffset+i*LOCALSIZE]=shuffle[shuffleOffset+i*stride]+
+ groupSum[(i*LOCALSIZE+id)/BLOCKSIZE]+groupOffset;
+
+ uint diff=final-dataOffset;
+ if(diff < groupSize && diff % LOCALSIZE == 0) {
+ size=maxDepth;
+ maxDepth=0u;
+ fragments=offset[final+1u]=offset[final];
+ }
}