Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ngscopeclient/scopehal-apps
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 22f1355b4767
Choose a base ref
...
head repository: ngscopeclient/scopehal-apps
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: e82984c9deea
Choose a head ref
  • 8 commits
  • 1 file changed
  • 1 contributor

Commits on May 13, 2021

  1. Copy the full SHA
    9086353 View commit details
  2. Copy the full SHA
    9e6b6d3 View commit details
  3. Copy the full SHA
    863cf13 View commit details
  4. Copy the full SHA
    dcea83e View commit details
  5. Copy the full SHA
    9fd9806 View commit details
  6. Copy the full SHA
    b0dfef5 View commit details
  7. Copy the full SHA
    806c2cd View commit details
  8. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    e82984c View commit details
Showing with 105 additions and 134 deletions.
  1. +105 −134 src/glscopeclient/shaders/waveform-compute-core.glsl
239 changes: 105 additions & 134 deletions src/glscopeclient/shaders/waveform-compute-core.glsl
Original file line number Diff line number Diff line change
@@ -2,9 +2,8 @@
//This is enough for a nearly fullscreen 4K window so should be plenty.
#define MAX_HEIGHT 2048

//Number of columns of pixels per thread block
#define COLS_PER_BLOCK 1
#define ROWS_PER_BLOCK 32
//Number of threads per column of pixels
#define ROWS_PER_BLOCK 64

//The output texture (for now, only alpha channel is used)
layout(binding=0, rgba32f) uniform image2D outputTex;
@@ -15,16 +14,16 @@ layout(std430, binding=3) buffer index
uint xind[];
};

//Shared buffer for the local working buffer
shared float g_workingBuffer[COLS_PER_BLOCK][MAX_HEIGHT];
//Shared buffer for the local working buffer (8 kB)
shared float g_workingBuffer[MAX_HEIGHT];

//Min/max for the current sample
shared int g_blockmin[COLS_PER_BLOCK];
shared int g_blockmax[COLS_PER_BLOCK];
shared bool g_done[COLS_PER_BLOCK];
shared bool g_updating[COLS_PER_BLOCK];
shared int g_blockmin[ROWS_PER_BLOCK];
shared int g_blockmax[ROWS_PER_BLOCK];
shared bool g_done;
shared bool g_updating[ROWS_PER_BLOCK];

layout(local_size_x=COLS_PER_BLOCK, local_size_y=ROWS_PER_BLOCK, local_size_z=1) in;
layout(local_size_x=1, local_size_y=ROWS_PER_BLOCK, local_size_z=1) in;

//Interpolate a Y coordinate
float InterpolateY(vec2 left, vec2 right, float slope, float x)
@@ -34,11 +33,6 @@ float InterpolateY(vec2 left, vec2 right, float slope, float x)

void main()
{
uint i;
uint istart;
vec2 left;
vec2 right;

//Abort if window height is too big, or if we're off the end of the window
if(windowHeight > MAX_HEIGHT)
return;
@@ -51,171 +45,148 @@ void main()
for(uint y=gl_LocalInvocationID.y; y < windowHeight; y += ROWS_PER_BLOCK)
{
if(persistScale == 0)
g_workingBuffer[gl_LocalInvocationID.x][y] = 0;
g_workingBuffer[y] = 0;
else
{
vec4 rgba = imageLoad(outputTex, ivec2(gl_GlobalInvocationID.x, y));
g_workingBuffer[gl_LocalInvocationID.x][y] = rgba.a * persistScale;
g_workingBuffer[y] = rgba.a * persistScale;
}
}

//Setup for main loop
if(gl_LocalInvocationID.y == 0)
{
//Clear loop variables
g_done[gl_LocalInvocationID.x] = false;
g_updating[gl_LocalInvocationID.x] = false;

#ifdef DENSE_PACK
istart = uint(floor(gl_GlobalInvocationID.x / xscale)) + offset_samples;
#else
istart = xind[gl_GlobalInvocationID.x];
#endif


i = istart;

#ifdef ANALOG_PATH
left = vec2(FetchX(istart) * xscale + xoff, (voltage[istart] + yoff)*yscale + ybase);
#endif
g_done = false;

#ifdef DIGITAL_PATH
left = vec2(FetchX(istart) * xscale + xoff, GetBoolean(istart)*yscale + ybase);
#endif
}

barrier();
memoryBarrierShared();
#ifdef DENSE_PACK
uint istart = uint(floor(gl_GlobalInvocationID.x / xscale)) + offset_samples;
#else
uint istart = xind[gl_GlobalInvocationID.x];
#endif
uint i = istart + gl_GlobalInvocationID.y;

//Main loop
while(true)
{
//Main thread
if(gl_LocalInvocationID.y == 0)
if(i < (memDepth-2) )
{
if(i < (memDepth-2) )
{
//If the next point is right of us, stop
if(left.x > gl_GlobalInvocationID.x + 1)
g_done[gl_LocalInvocationID.x] = true;

//Nope, all good
else
{
//Fetch coordinates of the current and upcoming sample

#ifdef ANALOG_PATH
right = vec2(FetchX(i+1) * xscale + xoff, (voltage[i+1] + yoff)*yscale + ybase);
#endif
//Fetch coordinates
#ifdef ANALOG_PATH
vec2 left = vec2(FetchX(i) * xscale + xoff, (voltage[i] + yoff)*yscale + ybase);
vec2 right = vec2(FetchX(i+1) * xscale + xoff, (voltage[i+1] + yoff)*yscale + ybase);
#endif

#ifdef DIGITAL_PATH
right = vec2(FetchX(i+1)*xscale + xoff, GetBoolean(i+1)*yscale + ybase);
#endif
#ifdef DIGITAL_PATH
vec2 left = vec2(FetchX(i) * xscale + xoff, GetBoolean(i)*yscale + ybase);
vec2 right = vec2(FetchX(i+1)*xscale + xoff, GetBoolean(i+1)*yscale + ybase);
#endif

//If the upcoming point is still left of us, we're not there yet
if(right.x < gl_GlobalInvocationID.x)
left = right;
//Skip offscreen samples
if( (right.x >= gl_GlobalInvocationID.x) && (left.x <= gl_GlobalInvocationID.x + 1) )
{
g_updating[gl_LocalInvocationID.y] = true;

else
{
g_updating[gl_LocalInvocationID.x] = true;
//To start, assume we're drawing the entire segment
float starty = left.y;
float endy = right.y;

//To start, assume we're drawing the entire segment
float starty = left.y;
float endy = right.y;
#ifdef ANALOG_PATH

#ifdef ANALOG_PATH
#ifndef NO_INTERPOLATION

#ifndef NO_INTERPOLATION
//Interpolate analog signals if either end is outside our column
float slope = (right.y - left.y) / (right.x - left.x);
if(left.x < gl_GlobalInvocationID.x)
starty = InterpolateY(left, right, slope, gl_GlobalInvocationID.x);
if(right.x > gl_GlobalInvocationID.x + 1)
endy = InterpolateY(left, right, slope, gl_GlobalInvocationID.x + 1);

//Interpolate analog signals if either end is outside our column
float slope = (right.y - left.y) / (right.x - left.x);
if(left.x < gl_GlobalInvocationID.x)
starty = InterpolateY(left, right, slope, gl_GlobalInvocationID.x);
if(right.x > gl_GlobalInvocationID.x + 1)
endy = InterpolateY(left, right, slope, gl_GlobalInvocationID.x + 1);
#endif
#endif

#endif
#endif

#ifdef DIGITAL_PATH
#ifdef DIGITAL_PATH

//If we are very near the right edge, draw vertical line
if(abs(right.x - gl_GlobalInvocationID.x) <= 1)
{
starty = left.y;
endy = right.y;
}
//If we are very near the right edge, draw vertical line
if(abs(right.x - gl_GlobalInvocationID.x) <= 1)
{
starty = left.y;
endy = right.y;
}

//otherwise draw a single pixel
else
{
starty = left.y;
endy = left.y;
}
//otherwise draw a single pixel
else
{
starty = left.y;
endy = left.y;
}

#endif
#endif

#ifdef HISTOGRAM_PATH
starty = 0;
endy = left.y;
#endif
#ifdef HISTOGRAM_PATH
starty = 0;
endy = left.y;
#endif

//Clip to window size
starty = min(starty, MAX_HEIGHT);
endy = min(endy, MAX_HEIGHT);
//Clip to window size
starty = min(starty, MAX_HEIGHT);
endy = min(endy, MAX_HEIGHT);

//Sort Y coordinates from min to max
g_blockmin[gl_LocalInvocationID.x] = int(min(starty, endy));
g_blockmax[gl_LocalInvocationID.x] = int(max(starty, endy));
//Sort Y coordinates from min to max
g_blockmin[gl_LocalInvocationID.y] = int(min(starty, endy));
g_blockmax[gl_LocalInvocationID.y] = int(max(starty, endy));

//Push current point down the pipeline
left = right;
}
}
//Check if we're at the end of the pixel
if(right.x > gl_GlobalInvocationID.x + 1)
g_done = true;
}

else
g_done[gl_LocalInvocationID.x] = true;
g_updating[gl_LocalInvocationID.y] = false;
}

i++;
else
{
g_done = true;
g_updating[gl_LocalInvocationID.y] = false;
}

barrier();
memoryBarrierShared();
i += ROWS_PER_BLOCK;

//Only update if we need to
if(g_done[gl_LocalInvocationID.x])
break;
if(!g_updating[gl_LocalInvocationID.x])
continue;

//Parallel fill
int ymin = g_blockmin[gl_LocalInvocationID.x];
int ymax = g_blockmax[gl_LocalInvocationID.x];
int len = ymax - ymin;
for(uint y=gl_LocalInvocationID.y; y <= len; y += ROWS_PER_BLOCK)
for(int y = 0; y<ROWS_PER_BLOCK; y++)
{
#ifdef HISTOGRAM_PATH
g_workingBuffer[gl_LocalInvocationID.x][ymin + y] = alpha;
#else
g_workingBuffer[gl_LocalInvocationID.x][ymin + y] += alpha;
#endif
barrier();
memoryBarrierShared();

if(g_updating[y])
{
//Parallel fill
int ymin = g_blockmin[y];
int len = g_blockmax[y] - ymin;
for(uint y=gl_LocalInvocationID.y; y <= len; y += ROWS_PER_BLOCK)
{
#ifdef HISTOGRAM_PATH
g_workingBuffer[ymin + y] = alpha;
#else
g_workingBuffer[ymin + y] += alpha;
#endif
}
}
}

if(g_done)
break;
}

barrier();
memoryBarrierShared();

//Copy working buffer to RGB output
if(gl_LocalInvocationID.y == 0)
for(uint y=gl_LocalInvocationID.y; y<windowHeight; y+= ROWS_PER_BLOCK)
{
for(uint y=0; y<windowHeight; y++)
{
imageStore(
outputTex,
ivec2(gl_GlobalInvocationID.x, y),
vec4(0, 0, 0, g_workingBuffer[gl_LocalInvocationID.x][y]));
}
imageStore(
outputTex,
ivec2(gl_GlobalInvocationID.x, y),
vec4(0, 0, 0, g_workingBuffer[y]));
}
}