diff options
author | Norbert Preining <norbert@preining.info> | 2022-02-06 03:01:17 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2022-02-06 03:01:17 +0000 |
commit | 350b3e35109171f0edd6fe9d697b91d5e76561f9 (patch) | |
tree | c6eac90d0b35dec36fa17ee58b736e55d6e42755 /graphics/asymptote/base/shaders | |
parent | 08ccf305ee79ab8e5ba9d1a8f3d22e74dccedd80 (diff) |
CTAN sync 202202060301
Diffstat (limited to 'graphics/asymptote/base/shaders')
-rw-r--r-- | graphics/asymptote/base/shaders/blend.glsl | 111 | ||||
-rw-r--r-- | graphics/asymptote/base/shaders/fragment.glsl | 48 | ||||
-rw-r--r-- | graphics/asymptote/base/shaders/partialsum.glsl | 15 | ||||
-rw-r--r-- | graphics/asymptote/base/shaders/postsum.glsl | 30 | ||||
-rw-r--r-- | graphics/asymptote/base/shaders/presum.glsl | 8 |
5 files changed, 125 insertions, 87 deletions
diff --git a/graphics/asymptote/base/shaders/blend.glsl b/graphics/asymptote/base/shaders/blend.glsl index f3bd26c393..629cc2dda5 100644 --- a/graphics/asymptote/base/shaders/blend.glsl +++ b/graphics/asymptote/base/shaders/blend.glsl @@ -1,7 +1,5 @@ -struct Fragment -{ - vec4 color; - float depth; +layout(binding=0, std430) buffer sumBuffer { + uint sum[]; }; layout(binding=1, std430) buffer offsetBuffer { @@ -13,12 +11,26 @@ layout(binding=2, std430) buffer countBuffer { }; layout(binding=3, std430) buffer fragmentBuffer { - Fragment fragment[]; + vec4 fragment[]; +}; + +layout(binding=4, std430) buffer depthBuffer { + float depth[]; +}; + +layout(binding=5, std430) buffer opaqueBuffer { + vec4 opaqueColor[]; +}; + +layout(binding=6, std430) buffer opaqueDepthBuffer { + float opaqueDepth[]; }; out vec4 outColor; uniform uint width; +uniform uint M; +uniform uint r; uniform vec4 background; vec4 blend(vec4 outColor, vec4 color) @@ -30,55 +42,90 @@ void main() { uint headIndex=uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x); uint size=count[headIndex]; + float OpaqueDepth=opaqueDepth[headIndex]; if(size == 0u) { #ifdef GPUINDEXING offset[headIndex]=0u; #endif + opaqueDepth[headIndex]=0.0; discard; } - uint listIndex=offset[headIndex]; + + uint listIndex= +#ifdef GPUINDEXING + sum[headIndex < r*(M+1u) ? headIndex/(M+1u) : (headIndex-r)/M]+ +#endif + offset[headIndex]; const uint maxSize=16u; // Sort the fragments with respect to descending depth if(size < maxSize) { - Fragment sortedList[maxSize]; + vec4 sortedColor[maxSize]; + float sortedDepth[maxSize]; - sortedList[0]=fragment[listIndex]; - for(uint i=1u; i < size; i++) { - Fragment temp=fragment[listIndex+i]; - float depth=temp.depth; - uint j=i; - Fragment f; - while(f=sortedList[j-1u], j > 0u && depth > f.depth) { - sortedList[j]=f; - j--; + uint k=0u; + + if(OpaqueDepth != 0.0) + while(k < size && depth[listIndex+k] >= OpaqueDepth) + ++k; + + uint i=0u; + if(k < size) { + sortedColor[0]=fragment[listIndex+k]; + sortedDepth[0]=depth[listIndex+k]; + ++k; + i=1u; + while(true) { + if(OpaqueDepth != 0.0) + while(k < size && depth[listIndex+k] >= OpaqueDepth) + ++k; + if(k == size) break; + float D=depth[listIndex+k]; + uint j=i; + float d; + while(j > 0u && D > sortedDepth[j-1u]) { + sortedColor[j]=sortedColor[j-1u]; + sortedDepth[j]=sortedDepth[j-1u]; + --j; + } + sortedColor[j]=fragment[listIndex+k]; + sortedDepth[j]=D; + ++i; + ++k; } - sortedList[j]=temp; } - - outColor=background; - for(uint i=0u; i < size; i++) - outColor=blend(outColor,sortedList[i].color); + outColor=OpaqueDepth != 0.0 ? opaqueColor[headIndex] : background; + for(uint j=0u; j < i; ++j) + outColor=blend(outColor,sortedColor[j]); } else { - for(uint i=1u; i < size; i++) { - Fragment temp=fragment[listIndex+i]; - float depth=temp.depth; + uint k=0u; + if(OpaqueDepth != 0.0) + while(k < size && depth[listIndex+k] >= OpaqueDepth) + ++k; + for(uint i=k+1u; i < size; i++) { + vec4 temp=fragment[listIndex+i]; + float D=depth[listIndex+i]; uint j=i; - Fragment f; - while(f=fragment[listIndex+j-1u], j > 0u && depth > f.depth) { - fragment[listIndex+j]=f; - j--; + while(j > 0u && D > depth[listIndex+j-1u]) { + fragment[listIndex+j]=fragment[listIndex+j-1u]; + depth[listIndex+j]=depth[listIndex+j-1u]; + --j; } fragment[listIndex+j]=temp; + depth[listIndex+j]=D; } - outColor=background; + outColor=OpaqueDepth != 0.0 ? opaqueColor[headIndex] : background; uint stop=listIndex+size; - for(uint i=listIndex; i < stop; i++) - outColor=blend(outColor,fragment[i].color); + for(uint i=listIndex+k; i < stop; i++) { + if(OpaqueDepth == 0.0 || depth[i] < OpaqueDepth) + outColor=blend(outColor,fragment[i]); + } } + count[headIndex]=0u; + opaqueDepth[headIndex]=0.0; #ifdef GPUINDEXING - offset[headIndex]=0u; + offset[headIndex]=0u; #endif } diff --git a/graphics/asymptote/base/shaders/fragment.glsl b/graphics/asymptote/base/shaders/fragment.glsl index 423ec679b2..5f60a56efd 100644 --- a/graphics/asymptote/base/shaders/fragment.glsl +++ b/graphics/asymptote/base/shaders/fragment.glsl @@ -29,10 +29,9 @@ float Roughness2; // roughness squared, for smoothing float Roughness; #ifdef HAVE_SSBO -struct Fragment -{ - vec4 color; - float depth; + +layout(binding=0, std430) buffer sumBuffer { + uint sum[]; }; layout(binding=1, std430) buffer offsetBuffer { @@ -44,10 +43,24 @@ layout(binding=2, std430) buffer countBuffer { }; layout(binding=3, std430) buffer fragmentBuffer { - Fragment fragment[]; + vec4 fragment[]; +}; + +layout(binding=4, std430) buffer depthBuffer { + float depth[]; +}; + +layout(binding=5, std430) buffer opaqueBuffer { + vec4 opaqueColor[]; +}; + +layout(binding=6, std430) buffer opaqueDepthBuffer { + float opaqueDepth[]; }; uniform uint width; +uniform uint M; +uniform uint r; #endif #ifdef NORMAL @@ -244,15 +257,32 @@ void main() outColor=emissive; #endif +#ifndef WIDTH #ifdef HAVE_SSBO uint headIndex=uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x); - uint listIndex=offset[headIndex]+atomicAdd(count[headIndex],1u); - fragment[listIndex].color=outColor; - fragment[listIndex].depth=gl_FragCoord.z; -#ifdef TRANSPARENT +#if defined(TRANSPARENT) || (!defined(HAVE_INTERLOCK) && !defined(OPAQUE)) + uint listIndex= +#ifdef GPUINDEXING + sum[headIndex < r*(M+1u) ? headIndex/(M+1u) : (headIndex-r)/M]+ +#endif + offset[headIndex]+atomicAdd(count[headIndex],1u); + fragment[listIndex]=outColor; + depth[listIndex]=gl_FragCoord.z; #ifndef WIREFRAME discard; #endif +#else +#ifndef OPAQUE +#ifdef HAVE_INTERLOCK +beginInvocationInterlockARB(); +if(opaqueDepth[headIndex] == 0.0 || gl_FragCoord.z < opaqueDepth[headIndex]) { + opaqueDepth[headIndex]=gl_FragCoord.z; + opaqueColor[headIndex]=outColor; +} +endInvocationInterlockARB(); +#endif +#endif +#endif #endif #endif } diff --git a/graphics/asymptote/base/shaders/partialsum.glsl b/graphics/asymptote/base/shaders/partialsum.glsl index 4b04a01dae..d00195bb3a 100644 --- a/graphics/asymptote/base/shaders/partialsum.glsl +++ b/graphics/asymptote/base/shaders/partialsum.glsl @@ -7,17 +7,12 @@ layout(binding=0, std430) buffer sumBuffer uint sum[]; }; -layout(binding=1, std430) buffer offsetBuffer -{ - uint offset[]; -}; - shared uint sharedData[PROCESSORS]; void main(void) { uint id=gl_LocalInvocationID.x; - sharedData[id]=sum[id]; + sharedData[id]=sum[id+1u]; barrier(); @@ -38,11 +33,5 @@ void main(void) sharedData[windex] += sharedData[index]; barrier(); - uint id1=id+1u; - if(id1 < PROCESSORS) { - uint m=elements/PROCESSORS; - uint row=m*id1+min(id1,elements-m*PROCESSORS); - offset[row] += sharedData[id]; - } else - sum[0]=sharedData[id]; // Store fragment size in sum[0] + sum[id+1u]=sharedData[id]; } diff --git a/graphics/asymptote/base/shaders/postsum.glsl b/graphics/asymptote/base/shaders/postsum.glsl deleted file mode 100644 index 999fe5fdf3..0000000000 --- a/graphics/asymptote/base/shaders/postsum.glsl +++ /dev/null @@ -1,30 +0,0 @@ -layout(local_size_x=1) in; - -uniform uint elements; - -layout(binding=1, std430) buffer offsetBuffer -{ - uint offset[]; -}; - -void main(void) -{ - uint id=gl_GlobalInvocationID.x; - - uint m=elements/gl_NumWorkGroups.x; - uint r=elements-m*gl_NumWorkGroups.x; - uint row,stop; - if(id < r) { - row=m*id+id; - stop=row+m+1; - } else { - row=m*id+r; - stop=row+m; - } - - uint Sum=offset[row]; - for(uint i=row+1u; i < stop; ++i) { - Sum += offset[i]; - offset[i]=Sum; - } -} diff --git a/graphics/asymptote/base/shaders/presum.glsl b/graphics/asymptote/base/shaders/presum.glsl index f2311c6756..5b0a8df89e 100644 --- a/graphics/asymptote/base/shaders/presum.glsl +++ b/graphics/asymptote/base/shaders/presum.glsl @@ -21,15 +21,17 @@ void main(void) uint row,stop; if(id < r) { row=m*id+id; - stop=row+m+1; + stop=row+m+1u; } else { row=m*id+r; stop=row+m; } uint Sum=offset[row]; - for(uint i=row+1u; i < stop; ++i) + for(uint i=row+1u; i < stop; ++i) { Sum += offset[i]; + offset[i]=Sum; + } - sum[id]=Sum; + sum[id+1u]=Sum; } |