diff options
author | Norbert Preining <norbert@preining.info> | 2022-04-07 03:01:53 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2022-04-07 03:01:53 +0000 |
commit | 4ab0687cfdd546779ccb6d8589a671441bf5865f (patch) | |
tree | 77554e11f1829a925194242636c38c7306fa43a8 /graphics/asymptote/base | |
parent | 333540a9182285f9d72d7d39be3fa730c135d664 (diff) |
CTAN sync 202204070301
Diffstat (limited to 'graphics/asymptote/base')
-rw-r--r-- | graphics/asymptote/base/shaders/blend.glsl | 136 | ||||
-rw-r--r-- | graphics/asymptote/base/shaders/compress.glsl | 30 | ||||
-rw-r--r-- | graphics/asymptote/base/shaders/count.glsl | 17 | ||||
-rw-r--r-- | graphics/asymptote/base/shaders/fragment.glsl | 59 | ||||
-rw-r--r-- | graphics/asymptote/base/shaders/sum1.glsl | 6 | ||||
-rw-r--r-- | graphics/asymptote/base/shaders/sum2.glsl | 6 | ||||
-rw-r--r-- | graphics/asymptote/base/shaders/sum3.glsl | 25 | ||||
-rw-r--r-- | graphics/asymptote/base/shaders/zero.glsl | 3 | ||||
-rw-r--r-- | graphics/asymptote/base/stats.asy | 27 | ||||
-rw-r--r-- | graphics/asymptote/base/v3dheadertypes.asy | 2 | ||||
-rw-r--r-- | graphics/asymptote/base/v3dtypes.asy | 2 |
11 files changed, 215 insertions, 98 deletions
diff --git a/graphics/asymptote/base/shaders/blend.glsl b/graphics/asymptote/base/shaders/blend.glsl index 76dfe94ad3..8a656e06c9 100644 --- a/graphics/asymptote/base/shaders/blend.glsl +++ b/graphics/asymptote/base/shaders/blend.glsl @@ -1,34 +1,39 @@ -layout(binding=0, std430) buffer offsetBuffer { +layout(binding=0, std430) buffer offsetBuffer +{ uint offset[]; }; -layout(binding=1, std430) buffer maxBuffer { - uint maxSize; -}; - #ifdef GPUINDEXING +uniform uint elements; uniform uint offset2; uniform uint m1; +uniform uint m2; uniform uint r; -layout(binding=2, std430) buffer localSumBuffer { +layout(binding=2, std430) buffer localSumBuffer +{ uint localSum[]; }; -layout(binding=3, std430) buffer globalSumBuffer { +layout(binding=3, std430) buffer globalSumBuffer +{ uint globalSum[]; }; +#define count offset #else -layout(binding=2, std430) buffer countBuffer { +layout(binding=2, std430) buffer countBuffer +{ uint count[]; }; #endif -layout(binding=4, std430) buffer fragmentBuffer { +layout(binding=4, std430) buffer fragmentBuffer +{ vec4 fragment[]; }; -layout(binding=5, std430) buffer depthBuffer { +layout(binding=5, std430) buffer depthBuffer +{ float depth[]; }; @@ -37,13 +42,25 @@ layout(binding=6, std430) buffer opaqueBuffer { }; layout(binding=7, std430) buffer opaqueDepthBuffer { + uint maxSize; float opaqueDepth[]; }; +#ifdef GPUCOMPRESS +layout(binding=1, std430) buffer indexBuffer +{ + uint index[]; +}; +#define INDEX(pixel) index[pixel] +#define COUNT(pixel) index[pixel] +#else +#define INDEX(pixel) pixel +#define COUNT(pixel) count[pixel] +#endif + out vec4 outColor; uniform uint width; -uniform uint pixels; uniform vec4 background; vec4 blend(vec4 outColor, vec4 color) @@ -53,29 +70,36 @@ vec4 blend(vec4 outColor, vec4 color) void main() { - uint headIndex=uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x); -#ifdef GPUINDEXING - uint size=offset[headIndex]; -#else - uint size=count[headIndex]; + uint pixel=uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x); + float OpaqueDepth=opaqueDepth[pixel]; + uint element=INDEX(pixel); + +#ifdef GPUCOMPRESS + if(element == 0u) { + if(OpaqueDepth != 0.0) + opaqueDepth[pixel]=0.0; + discard; + } #endif - float OpaqueDepth=opaqueDepth[headIndex]; + + uint size=count[element]; + +#ifndef GPUCOMPRESS if(size == 0u) { -#ifdef GPUINDEXING - offset[pixels+headIndex]=0u; -#endif - opaqueDepth[headIndex]=0.0; + if(OpaqueDepth != 0.0) + opaqueDepth[pixel]=0.0; discard; } +#endif - outColor=OpaqueDepth != 0.0 ? opaqueColor[headIndex] : background; + outColor=OpaqueDepth != 0.0 ? opaqueColor[pixel] : background; #ifdef GPUINDEXING - uint p=headIndex < r*(m1+1u) ? headIndex/(m1+1u) : (headIndex-r)/m1; + uint p=element < r*(m1+1u) ? element/(m1+1u) : (element-r)/m1; uint listIndex=localSum[p]+localSum[offset2+p/m2]+globalSum[p/(m2*m2)]+ - offset[pixels+headIndex]; + offset[elements+element]; #else - uint listIndex=offset[headIndex]-size; + uint listIndex=offset[element]-size; #endif uint k=0u; @@ -83,36 +107,49 @@ void main() while(k < size && depth[listIndex+k] >= OpaqueDepth) ++k; + uint n=size-k; + // Sort the fragments with respect to descending depth - if(size-k <= ARRAYSIZE) { - if(k < size) { - uint Index[ARRAYSIZE]; - float Depth[ARRAYSIZE]; - Index[0]=k; - Depth[0]=depth[listIndex+k]; - ++k; + if(n <= ARRAYSIZE) { + if(n == 1) + outColor=blend(outColor,fragment[listIndex+k]); + else if(n > 0) { + struct element { + uint index; + float depth; + }; + + element E[ARRAYSIZE]; + E[0]=element(k,depth[listIndex+k]); uint i=1u; - while(true) { - if(OpaqueDepth != 0.0) - while(k < size && depth[listIndex+k] >= OpaqueDepth) - ++k; - if(k == size) break; + while(++k < size) { float d=depth[listIndex+k]; + if(OpaqueDepth != 0.0) { + while(k < size && d >= OpaqueDepth) { + ++k; + d=depth[listIndex+k]; + } + if(k == size) break; + } uint j=i; - while(j > 0u && d > Depth[j-1u]) { - Index[j]=Index[j-1u]; - Depth[j]=Depth[j-1u]; + while(j > 0u && d > E[j-1u].depth) { + E[j]=E[j-1u]; --j; } - Index[j]=k++; - Depth[j]=d; + E[j]=element(k,d); ++i; } for(uint j=0u; j < i; ++j) - outColor=blend(outColor,fragment[listIndex+Index[j]]); + outColor=blend(outColor,fragment[listIndex+E[j].index]); } + + if(OpaqueDepth != 0.0) + opaqueDepth[pixel]=0.0; } else { atomicMax(maxSize,size); +#ifndef GPUINDEXING + count[0]=maxSize; +#endif for(uint i=k+1u; i < size; i++) { vec4 temp=fragment[listIndex+i]; float d=depth[listIndex+i]; @@ -130,19 +167,14 @@ void main() if(OpaqueDepth == 0.0) for(uint i=listIndex+k; i < stop; i++) outColor=blend(outColor,fragment[i]); - else + else { for(uint i=listIndex+k; i < stop; i++) { if(depth[i] < OpaqueDepth) outColor=blend(outColor,fragment[i]); } + opaqueDepth[pixel]=0.0; + } } - - opaqueDepth[headIndex]=0.0; -#ifdef GPUINDEXING - offset[headIndex]=0u; - offset[pixels+headIndex]=0u; -#else - count[headIndex]=0u; -#endif + COUNT(pixel)=0u; } diff --git a/graphics/asymptote/base/shaders/compress.glsl b/graphics/asymptote/base/shaders/compress.glsl new file mode 100644 index 0000000000..2f64d24c88 --- /dev/null +++ b/graphics/asymptote/base/shaders/compress.glsl @@ -0,0 +1,30 @@ +#ifdef GPUINDEXING +layout(binding=0, std430) buffer offsetBuffer +{ + uint offset[]; +}; +#define count offset +#else +layout(binding=2, std430) buffer countBuffer +{ + uint count[]; +}; +#endif + +layout(binding=0) uniform atomic_uint elements; + +layout(binding=1, std430) buffer indexBuffer +{ + uint index[]; +}; + +uniform uint width; + +void main() +{ + uint pixel=uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x); + uint Count=index[pixel]; + if(Count > 0u) + count[(index[pixel]=atomicCounterIncrement(elements))]=Count; + discard; +} diff --git a/graphics/asymptote/base/shaders/count.glsl b/graphics/asymptote/base/shaders/count.glsl index c942771498..bd06331d77 100644 --- a/graphics/asymptote/base/shaders/count.glsl +++ b/graphics/asymptote/base/shaders/count.glsl @@ -1,17 +1,20 @@ +#ifdef GPUCOMPRESS +layout(binding=1, std430) buffer indexBuffer +#else #ifdef GPUINDEXING -layout(binding=0, std430) buffer offsetBuffer { - uint count[]; -}; +layout(binding=0, std430) buffer offsetBuffer #else -layout(binding=2, std430) buffer countBuffer { - uint count[]; -}; +layout(binding=2, std430) buffer countBuffer #endif +#endif +{ + uint index[]; +}; uniform uint width; void main() { - atomicAdd(count[uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x)],1u); + atomicAdd(index[uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x)],1u); discard; } diff --git a/graphics/asymptote/base/shaders/fragment.glsl b/graphics/asymptote/base/shaders/fragment.glsl index e8d4be86cf..79f2573402 100644 --- a/graphics/asymptote/base/shaders/fragment.glsl +++ b/graphics/asymptote/base/shaders/fragment.glsl @@ -30,49 +30,67 @@ float Roughness; #ifdef HAVE_SSBO -layout(binding=0, std430) buffer offsetBuffer { +layout(binding=0, std430) buffer offsetBuffer +{ uint offset[]; }; #ifdef GPUINDEXING - #if defined(TRANSPARENT) || (!defined(HAVE_INTERLOCK) && !defined(OPAQUE)) +uniform uint elements; uniform uint offset2; uniform uint m1; +uniform uint m2; uniform uint r; #endif - -layout(binding=2, std430) buffer localSumBuffer { +layout(binding=2, std430) buffer localSumBuffer +{ uint localSum[]; }; -layout(binding=3, std430) buffer globalSumBuffer { +layout(binding=3, std430) buffer globalSumBuffer +{ uint globalSum[]; }; #else -layout(binding=2, std430) buffer countBuffer { +layout(binding=2, std430) buffer countBuffer +{ uint count[]; }; #endif -layout(binding=4, std430) buffer fragmentBuffer { +layout(binding=4, std430) buffer fragmentBuffer +{ vec4 fragment[]; }; -layout(binding=5, std430) buffer depthBuffer { +layout(binding=5, std430) buffer depthBuffer +{ float depth[]; }; -layout(binding=6, std430) buffer opaqueBuffer { +layout(binding=6, std430) buffer opaqueBuffer +{ vec4 opaqueColor[]; }; -layout(binding=7, std430) buffer opaqueDepthBuffer { +layout(binding=7, std430) buffer opaqueDepthBuffer +{ + uint maxSize; float opaqueDepth[]; }; +#ifdef GPUCOMPRESS +layout(binding=1, std430) buffer indexBuffer +{ + uint index[]; +}; +#define INDEX(pixel) index[pixel] +#else +#define INDEX(pixel) pixel +#endif + uniform uint width; -uniform uint pixels; #endif @@ -272,14 +290,15 @@ void main() #ifndef WIDTH #ifdef HAVE_SSBO - uint headIndex=uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x); + uint pixel=uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x); #if defined(TRANSPARENT) || (!defined(HAVE_INTERLOCK) && !defined(OPAQUE)) + uint element=INDEX(pixel); #ifdef GPUINDEXING - uint p=headIndex < r*(m1+1u) ? headIndex/(m1+1u) : (headIndex-r)/m1; + uint p=element < r*(m1+1u) ? element/(m1+1u) : (element-r)/m1; uint listIndex=localSum[p]+localSum[offset2+p/m2]+globalSum[p/(m2*m2)]+ - atomicAdd(offset[pixels+headIndex],-1u)-1u; + atomicAdd(offset[elements+element],-1u)-1u; #else - uint listIndex=offset[headIndex]-atomicAdd(count[headIndex],1u)-1u; + uint listIndex=offset[element]-atomicAdd(count[element],1u)-1u; #endif fragment[listIndex]=outColor; depth[listIndex]=gl_FragCoord.z; @@ -287,18 +306,16 @@ void main() discard; #endif #else -#ifndef OPAQUE -#ifdef HAVE_INTERLOCK +#if defined(HAVE_INTERLOCK) && !defined(OPAQUE) beginInvocationInterlockARB(); - if(opaqueDepth[headIndex] == 0.0 || gl_FragCoord.z < opaqueDepth[headIndex]) + if(opaqueDepth[pixel] == 0.0 || gl_FragCoord.z < opaqueDepth[pixel]) { - opaqueDepth[headIndex]=gl_FragCoord.z; - opaqueColor[headIndex]=outColor; + opaqueDepth[pixel]=gl_FragCoord.z; + opaqueColor[pixel]=outColor; } endInvocationInterlockARB(); #endif #endif #endif #endif -#endif } diff --git a/graphics/asymptote/base/shaders/sum1.glsl b/graphics/asymptote/base/shaders/sum1.glsl index 2cb9ed23aa..f1fa8454b0 100644 --- a/graphics/asymptote/base/shaders/sum1.glsl +++ b/graphics/asymptote/base/shaders/sum1.glsl @@ -29,10 +29,8 @@ void main(void) uint Sum=offset[row]; offset[elements+row]=Sum; - for(uint i=row+1u; i < stop; ++i) { - Sum += offset[i]; - offset[elements+i]=Sum; - } + for(uint i=row+1u; i < stop; ++i) + offset[elements+i]=Sum += offset[i]; localSum[id+1u]=Sum; } diff --git a/graphics/asymptote/base/shaders/sum2.glsl b/graphics/asymptote/base/shaders/sum2.glsl index 1ab03513eb..11bf0064eb 100644 --- a/graphics/asymptote/base/shaders/sum2.glsl +++ b/graphics/asymptote/base/shaders/sum2.glsl @@ -15,10 +15,8 @@ void main(void) uint stop=row+LOCAL_SIZE_X; uint Sum=localSum[row]; - for(uint i=row+1u; i < stop; ++i) { - Sum += localSum[i]; - localSum[i]=Sum; - } + for(uint i=row+1u; i < stop; ++i) + localSum[i]=Sum += localSum[i]; localSum[offset2+id+1u]=Sum; } diff --git a/graphics/asymptote/base/shaders/sum3.glsl b/graphics/asymptote/base/shaders/sum3.glsl index 85f55ff2a6..8e6e94bf45 100644 --- a/graphics/asymptote/base/shaders/sum3.glsl +++ b/graphics/asymptote/base/shaders/sum3.glsl @@ -1,28 +1,39 @@ layout(local_size_x=LOCAL_SIZE_X) in; uniform uint offset2; +uniform uint final; layout(binding=2, std430) buffer localSumBuffer { uint localSum[]; }; -layout(binding=3, std430) buffer globalSumBuffer { +layout(binding=3, std430) buffer globalSumBuffer +{ uint globalSum[]; }; +layout(binding=7, std430) buffer opaqueDepthBuffer +{ + uint maxSize; + float opaqueDepth[]; +}; + void main(void) { uint id=gl_GlobalInvocationID.x; - uint row=offset2+LOCAL_SIZE_X*id; uint stop=row+LOCAL_SIZE_X; uint Sum=localSum[row]; - for(uint i=row+1u; i < stop; ++i) { - Sum += localSum[i]; - localSum[i]=Sum; - } + for(uint i=row+1u; i < stop; ++i) + localSum[i]=Sum += localSum[i]; - globalSum[id+1u]=Sum; + uint id1=id+1u; + if(id1 < gl_WorkGroupSize.x*gl_NumWorkGroups.x) + globalSum[id1]=Sum; + else { + globalSum[0]=maxSize; + globalSum[id1]=Sum+localSum[offset2-1u]+localSum[final]; + } } diff --git a/graphics/asymptote/base/shaders/zero.glsl b/graphics/asymptote/base/shaders/zero.glsl index 9bcb6d222e..747f44b3bc 100644 --- a/graphics/asymptote/base/shaders/zero.glsl +++ b/graphics/asymptote/base/shaders/zero.glsl @@ -1,4 +1,5 @@ -layout(binding=2, std430) buffer countBuffer { +layout(binding=2, std430) buffer countBuffer +{ uint count[]; }; diff --git a/graphics/asymptote/base/stats.asy b/graphics/asymptote/base/stats.asy index 6183fc18df..3143a39003 100644 --- a/graphics/asymptote/base/stats.asy +++ b/graphics/asymptote/base/stats.asy @@ -290,3 +290,30 @@ linefit leastsquares(real[] x, real[] y) } return L; } + +// Do a least-squares fit of data in real arrays x and y weighted by w +// to the line y=m*x+b, by minimizing sum(w*(y-m*x-b)^2). +linefit leastsquares(real[] x, real[] y, real[] w) +{ + linefit L; + int n=x.length; + if(n == 1) abort("Least squares fit requires at least 2 data points"); + real sx=sum(w*x); + real sy=sum(w*y); + real W=sum(w); + real sxx=W*sum(w*x^2)-sx^2; + real sxy=W*sum(w*x*y)-sx*sy; + L.m=sxy/sxx; + L.b=(sy-L.m*sx)/W; + if(n > 2) { + real syy=W*sum(w*y^2)-sy^2; + if(sxx == 0 || syy == 0) return L; + L.r=sxy/sqrt(sxx*syy); + real arg=syy-sxy^2/sxx; + if(arg <= 0) return L; + real s=sqrt(arg/(n-2)); + L.dm=s*sqrt(1/sxx); + L.db=s*sqrt(1+sx^2/sxx)/W; + } + return L; +} diff --git a/graphics/asymptote/base/v3dheadertypes.asy b/graphics/asymptote/base/v3dheadertypes.asy index dba3c18d0b..96da507ec8 100644 --- a/graphics/asymptote/base/v3dheadertypes.asy +++ b/graphics/asymptote/base/v3dheadertypes.asy @@ -1,6 +1,6 @@ // Enum class for v3dheadertypes // AUTO-GENERATED from v3dheadertypes.csv -// Generated at 2022-03-07 12:05:14.285216 +// Generated at 2022-04-05 20:52:21.949166 struct v3dheadertypes { diff --git a/graphics/asymptote/base/v3dtypes.asy b/graphics/asymptote/base/v3dtypes.asy index 6de6b31c5c..b3d11e2e68 100644 --- a/graphics/asymptote/base/v3dtypes.asy +++ b/graphics/asymptote/base/v3dtypes.asy @@ -1,6 +1,6 @@ // Enum class for v3dtypes // AUTO-GENERATED from v3dtypes.csv -// Generated at 2022-03-07 12:05:14.274334 +// Generated at 2022-04-05 20:52:21.903691 struct v3dtypes { |