summaryrefslogtreecommitdiff
path: root/graphics/asymptote/base
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-04-07 03:01:53 +0000
committerNorbert Preining <norbert@preining.info>2022-04-07 03:01:53 +0000
commit4ab0687cfdd546779ccb6d8589a671441bf5865f (patch)
tree77554e11f1829a925194242636c38c7306fa43a8 /graphics/asymptote/base
parent333540a9182285f9d72d7d39be3fa730c135d664 (diff)
CTAN sync 202204070301
Diffstat (limited to 'graphics/asymptote/base')
-rw-r--r--graphics/asymptote/base/shaders/blend.glsl136
-rw-r--r--graphics/asymptote/base/shaders/compress.glsl30
-rw-r--r--graphics/asymptote/base/shaders/count.glsl17
-rw-r--r--graphics/asymptote/base/shaders/fragment.glsl59
-rw-r--r--graphics/asymptote/base/shaders/sum1.glsl6
-rw-r--r--graphics/asymptote/base/shaders/sum2.glsl6
-rw-r--r--graphics/asymptote/base/shaders/sum3.glsl25
-rw-r--r--graphics/asymptote/base/shaders/zero.glsl3
-rw-r--r--graphics/asymptote/base/stats.asy27
-rw-r--r--graphics/asymptote/base/v3dheadertypes.asy2
-rw-r--r--graphics/asymptote/base/v3dtypes.asy2
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
{