diff options
Diffstat (limited to 'Build/source/utils/asymptote/base/shaders/sum3.glsl')
-rw-r--r-- | Build/source/utils/asymptote/base/shaders/sum3.glsl | 80 |
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]; + } } |