[wip, win32, canvas] segment setup, non tiled
This commit is contained in:
parent
f76ff94c28
commit
15c54b9385
|
@ -126,7 +126,9 @@ typedef struct mg_gl_canvas_backend
|
|||
|
||||
/*
|
||||
GLuint pathSetup;
|
||||
*/
|
||||
GLuint segmentSetup;
|
||||
/*
|
||||
GLuint backprop;
|
||||
GLuint merge;
|
||||
*/
|
||||
|
@ -253,23 +255,19 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend,
|
|||
glUniform1f(1, scale);
|
||||
|
||||
glDispatchCompute(pathCount, 1, 1);
|
||||
|
||||
*/
|
||||
//NOTE: segment setup pass
|
||||
glUseProgram(backend->segmentSetup);
|
||||
|
||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, backend->elementBuffer, backend->elementBufferOffset, eltCount*sizeof(mg_gl_path_elt));
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->segmentCountBuffer);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->segmentBuffer);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, backend->pathQueueBuffer);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, backend->tileQueueBuffer);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, backend->tileOpBuffer);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, backend->tileOpCountBuffer);
|
||||
|
||||
glUniform1i(0, tileSize);
|
||||
glUniform1f(1, scale);
|
||||
glUniform1f(0, scale);
|
||||
|
||||
glDispatchCompute(eltCount, 1, 1);
|
||||
|
||||
/*
|
||||
//NOTE: backprop pass
|
||||
glUseProgram(backend->backprop);
|
||||
|
||||
|
@ -307,11 +305,11 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend,
|
|||
glUniform1i(2, backend->msaaCount);
|
||||
*/
|
||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, backend->pathBuffer, backend->pathBufferOffset, pathCount*sizeof(mg_gl_path));
|
||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, backend->elementBuffer, backend->elementBufferOffset, eltCount*sizeof(mg_gl_path_elt));
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->segmentCountBuffer);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->segmentBuffer);
|
||||
|
||||
// glUniform1ui(0, tileSize);
|
||||
glUniform1f(1, scale);
|
||||
glUniform1ui(2, eltCount);
|
||||
// glUniform1f(1, scale);
|
||||
|
||||
int err = glGetError();
|
||||
if(err)
|
||||
|
@ -745,7 +743,9 @@ mg_canvas_backend* gl_canvas_backend_create(mg_wgl_surface* surface)
|
|||
int err = 0;
|
||||
/*
|
||||
err |= mg_gl_canvas_compile_compute_program(glsl_path_setup, &backend->pathSetup);
|
||||
*/
|
||||
err |= mg_gl_canvas_compile_compute_program(glsl_segment_setup, &backend->segmentSetup);
|
||||
/*
|
||||
err |= mg_gl_canvas_compile_compute_program(glsl_backprop, &backend->backprop);
|
||||
err |= mg_gl_canvas_compile_compute_program(glsl_merge, &backend->merge);
|
||||
*/
|
||||
|
|
|
@ -9,71 +9,21 @@ layout(binding = 0) restrict readonly buffer pathBufferSSBO
|
|||
mg_gl_path elements[];
|
||||
} pathBuffer;
|
||||
|
||||
layout(binding = 1) restrict readonly buffer elementBufferSSBO
|
||||
layout(binding = 1) restrict readonly buffer segmentBufferCountSSBO
|
||||
{
|
||||
mg_gl_path_elt elements[];
|
||||
} elementBuffer;
|
||||
int elements[];
|
||||
} segmentCountBuffer;
|
||||
|
||||
layout(binding = 2) restrict readonly buffer segmentBufferSSBO
|
||||
{
|
||||
mg_gl_segment elements[];
|
||||
} segmentBuffer;
|
||||
|
||||
//layout(location = 0) uniform uint tileSize; // this has to be commented until it's effectively used!!
|
||||
layout(location = 1) uniform float scale;
|
||||
layout(location = 2) uniform uint eltCount;
|
||||
//layout(location = 0) uniform float scale;
|
||||
|
||||
layout(rgba8, binding = 0) uniform restrict writeonly image2D outTexture;
|
||||
|
||||
void init_segment(in vec2 p[4], int kind, out mg_gl_segment seg)
|
||||
{
|
||||
vec2 s = p[0];
|
||||
vec2 c = p[0];
|
||||
vec2 e = p[1];
|
||||
|
||||
bool goingUp = e.y >= s.y;
|
||||
bool goingRight = e.x >= s.x;
|
||||
|
||||
seg.kind = kind;
|
||||
seg.pathIndex = 0; ///
|
||||
seg.windingIncrement = goingUp ? 1 : -1;
|
||||
seg.box = vec4(min(s.x, e.x),
|
||||
min(s.y, e.y),
|
||||
max(s.x, e.x),
|
||||
max(s.y, e.y));
|
||||
|
||||
float dx = c.x - seg.box.x;
|
||||
float dy = c.y - seg.box.y;
|
||||
float alpha = (seg.box.w - seg.box.y)/(seg.box.z - seg.box.x);
|
||||
float ofs = seg.box.w - seg.box.y;
|
||||
|
||||
if(goingUp == goingRight)
|
||||
{
|
||||
if(seg.kind == MG_GL_LINE)
|
||||
{
|
||||
seg.config = MG_GL_BR;
|
||||
}
|
||||
else if(dy > alpha*dx)
|
||||
{
|
||||
seg.config = MG_GL_TL;
|
||||
}
|
||||
else
|
||||
{
|
||||
seg.config = MG_GL_BR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(seg.kind == MG_GL_LINE)
|
||||
{
|
||||
seg.config = MG_GL_TR;
|
||||
}
|
||||
else if(dy < ofs - alpha*dx)
|
||||
{
|
||||
seg.config = MG_GL_BL;
|
||||
}
|
||||
else
|
||||
{
|
||||
seg.config = MG_GL_TR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float ccw(vec2 a, vec2 b, vec2 c)
|
||||
{
|
||||
return((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x));
|
||||
|
@ -171,56 +121,42 @@ int side_of_segment(vec2 p, mg_gl_segment seg)
|
|||
|
||||
void main()
|
||||
{
|
||||
int segCount = segmentCountBuffer.elements[0];
|
||||
vec2 sampleCoord = vec2(gl_WorkGroupID.xy*uvec2(16, 16) + gl_LocalInvocationID.xy);
|
||||
|
||||
int winding = 0;
|
||||
|
||||
for(int i=0; i<eltCount; i++)
|
||||
for(int segIndex=0; segIndex<segCount; segIndex++)
|
||||
{
|
||||
mg_gl_path_elt elt = elementBuffer.elements[i];
|
||||
mg_gl_segment seg = segmentBuffer.elements[segIndex];
|
||||
|
||||
switch(elt.kind)
|
||||
if( (sampleCoord.y > seg.box.y)
|
||||
&&(sampleCoord.y <= seg.box.w)
|
||||
&&(side_of_segment(sampleCoord, seg) < 0))
|
||||
{
|
||||
case MG_GL_LINE:
|
||||
{
|
||||
vec2 p[4] = {elt.p[0]*scale, elt.p[1]*scale, vec2(0), vec2(0)};
|
||||
mg_gl_segment seg;
|
||||
init_segment(p, MG_GL_LINE, seg);
|
||||
seg.hullVertex = p[0];
|
||||
|
||||
if( (sampleCoord.y > seg.box.y)
|
||||
&&(sampleCoord.y <= seg.box.w)
|
||||
&&(side_of_segment(sampleCoord, seg) < 0))
|
||||
{
|
||||
winding += seg.windingIncrement;
|
||||
}
|
||||
|
||||
/*
|
||||
if(op->crossRight)
|
||||
{
|
||||
if( (seg.config == MG_GL_BR || seg.config == MG_GL_TL)
|
||||
&&(sampleCoord.y > seg.box.w))
|
||||
{
|
||||
winding += seg.windingIncrement;
|
||||
}
|
||||
else if( (seg.config == MG_GL_BL || seg.config == MG_GL_TR)
|
||||
&&(sampleCoord.y > seg.box.y))
|
||||
{
|
||||
winding -= seg.windingIncrement;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
} break;
|
||||
|
||||
case MG_GL_QUADRATIC:
|
||||
case MG_GL_CUBIC:
|
||||
break;
|
||||
winding += seg.windingIncrement;
|
||||
}
|
||||
|
||||
/*
|
||||
if(op->crossRight)
|
||||
{
|
||||
if( (seg.config == MG_GL_BR || seg.config == MG_GL_TL)
|
||||
&&(sampleCoord.y > seg.box.w))
|
||||
{
|
||||
winding += seg.windingIncrement;
|
||||
}
|
||||
else if( (seg.config == MG_GL_BL || seg.config == MG_GL_TR)
|
||||
&&(sampleCoord.y > seg.box.y))
|
||||
{
|
||||
winding -= seg.windingIncrement;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
int pathIndex = 0;
|
||||
vec4 clip = pathBuffer.elements[pathIndex].clip * scale;
|
||||
|
||||
// vec4 clip = pathBuffer.elements[pathIndex].clip * scale;
|
||||
|
||||
/* if( sampleCoord.x >= clip.x
|
||||
&& sampleCoord.x < clip.z
|
||||
|
|
|
@ -19,28 +19,92 @@ layout(binding = 2) restrict writeonly buffer segmentBufferSSBO
|
|||
mg_gl_segment elements[];
|
||||
} segmentBuffer;
|
||||
|
||||
layout(binding = 3) restrict readonly buffer pathQueueBufferSSBO
|
||||
{
|
||||
mg_gl_path_queue elements[];
|
||||
} pathQueueBuffer;
|
||||
layout(location = 0) uniform float scale;
|
||||
|
||||
layout(binding = 4) restrict readonly buffer tileQueueBufferSSBO
|
||||
{
|
||||
mg_gl_tile_queue elements[];
|
||||
} tileQueueBuffer;
|
||||
|
||||
layout(binding = 5) restrict readonly buffer tileOpBufferSSBO
|
||||
int push_segment(in vec2 p[4], int kind)
|
||||
{
|
||||
mg_gl_tile_op elements[];
|
||||
} tileOpBuffer;
|
||||
int segIndex = atomicAdd(segmentCountBuffer.elements[0], 1);
|
||||
|
||||
layout(binding = 6) restrict readonly buffer tileOpCountBufferSSBO
|
||||
vec2 s = p[0];
|
||||
vec2 c = p[0];
|
||||
vec2 e = p[1];
|
||||
|
||||
bool goingUp = e.y >= s.y;
|
||||
bool goingRight = e.x >= s.x;
|
||||
|
||||
vec4 box = vec4(min(s.x, e.x),
|
||||
min(s.y, e.y),
|
||||
max(s.x, e.x),
|
||||
max(s.y, e.y));
|
||||
|
||||
segmentBuffer.elements[segIndex].kind = kind;
|
||||
segmentBuffer.elements[segIndex].pathIndex = 0; ///
|
||||
segmentBuffer.elements[segIndex].windingIncrement = goingUp ? 1 : -1;
|
||||
segmentBuffer.elements[segIndex].box = box;
|
||||
|
||||
float dx = c.x - box.x;
|
||||
float dy = c.y - box.y;
|
||||
float alpha = (box.w - box.y)/(box.z - box.x);
|
||||
float ofs = box.w - box.y;
|
||||
|
||||
if(goingUp == goingRight)
|
||||
{
|
||||
if(kind == MG_GL_LINE)
|
||||
{
|
||||
segmentBuffer.elements[segIndex].config = MG_GL_BR;
|
||||
}
|
||||
else if(dy > alpha*dx)
|
||||
{
|
||||
segmentBuffer.elements[segIndex].config = MG_GL_TL;
|
||||
}
|
||||
else
|
||||
{
|
||||
segmentBuffer.elements[segIndex].config = MG_GL_BR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(kind == MG_GL_LINE)
|
||||
{
|
||||
segmentBuffer.elements[segIndex].config = MG_GL_TR;
|
||||
}
|
||||
else if(dy < ofs - alpha*dx)
|
||||
{
|
||||
segmentBuffer.elements[segIndex].config = MG_GL_BL;
|
||||
}
|
||||
else
|
||||
{
|
||||
segmentBuffer.elements[segIndex].config = MG_GL_TR;
|
||||
}
|
||||
}
|
||||
|
||||
return(segIndex);
|
||||
}
|
||||
|
||||
void line_setup(vec2 p[4])
|
||||
{
|
||||
int elements[];
|
||||
} tileOpCountBuffer;
|
||||
int segIndex = push_segment(p, MG_GL_LINE);
|
||||
segmentBuffer.elements[segIndex].hullVertex = p[0];
|
||||
|
||||
//TODO later bin to tiles
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int eltIndex = int(gl_WorkGroupID.x);
|
||||
|
||||
mg_gl_path_elt elt = elementBuffer.elements[eltIndex];
|
||||
|
||||
switch(elt.kind)
|
||||
{
|
||||
case MG_GL_LINE:
|
||||
{
|
||||
vec2 p[4] = {elt.p[0]*scale, elt.p[1]*scale, vec2(0), vec2(0)};
|
||||
line_setup(p);
|
||||
} break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue