diff options
Diffstat (limited to 'graphics/asymptote/base/shaders/partialsum.glsl')
-rw-r--r-- | graphics/asymptote/base/shaders/partialsum.glsl | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/graphics/asymptote/base/shaders/partialsum.glsl b/graphics/asymptote/base/shaders/partialsum.glsl new file mode 100644 index 0000000000..0506965c23 --- /dev/null +++ b/graphics/asymptote/base/shaders/partialsum.glsl @@ -0,0 +1,54 @@ +layout(local_size_x=PROCESSORS) in; + +uniform uint elements; +uniform uint steps; + +layout(binding=0, std430) buffer sumBuffer +{ + uint sum[]; +}; + +layout(binding=1, std430) buffer offsetBuffer +{ + uint offset[]; +}; + +shared uint sharedData[PROCESSORS]; + +uint ceilquotient(uint a, uint b) +{ + return (a+b-1u)/b; +} + +void main(void) +{ + uint id=gl_LocalInvocationID.x; + sharedData[id]=sum[id]; + + barrier(); + + uint index=id << 1u; + sharedData[index+1u] += sharedData[index]; + barrier(); + uint step; + for(step=1u; step < steps-1u; step++) { + uint mask=(1u << step)-1u; + uint index=((id >> step) << (step+1u))+mask; + uint windex=index+(id&mask)+1u; + sharedData[windex] += sharedData[index]; + barrier(); + } + uint mask=(1u << step)-1u; + index=((id >> step) << steps)+mask; + uint windex=index+(id&mask)+1u; + if(windex < PROCESSORS) + sharedData[windex] += sharedData[index]; + barrier(); + + uint m=ceilquotient(elements,PROCESSORS); + + if(id+1u < PROCESSORS) + offset[m*(id+1u)] += sharedData[id]; + else + sum[0]=sharedData[id]; // Store fragment size in sum[0] +} |