[wip, win32, canvas] segment setup, non tiled

This commit is contained in:
martinfouilleul 2023-06-29 16:43:38 +02:00
parent f76ff94c28
commit 15c54b9385
3 changed files with 122 additions and 122 deletions

View File

@ -126,7 +126,9 @@ typedef struct mg_gl_canvas_backend
/* /*
GLuint pathSetup; GLuint pathSetup;
*/
GLuint segmentSetup; GLuint segmentSetup;
/*
GLuint backprop; GLuint backprop;
GLuint merge; GLuint merge;
*/ */
@ -253,23 +255,19 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend,
glUniform1f(1, scale); glUniform1f(1, scale);
glDispatchCompute(pathCount, 1, 1); glDispatchCompute(pathCount, 1, 1);
*/
//NOTE: segment setup pass //NOTE: segment setup pass
glUseProgram(backend->segmentSetup); glUseProgram(backend->segmentSetup);
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, backend->elementBuffer, backend->elementBufferOffset, eltCount*sizeof(mg_gl_path_elt)); 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, 1, backend->segmentCountBuffer);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->segmentBuffer); 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(0, scale);
glUniform1f(1, scale);
glDispatchCompute(eltCount, 1, 1); glDispatchCompute(eltCount, 1, 1);
/*
//NOTE: backprop pass //NOTE: backprop pass
glUseProgram(backend->backprop); glUseProgram(backend->backprop);
@ -307,11 +305,11 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend,
glUniform1i(2, backend->msaaCount); glUniform1i(2, backend->msaaCount);
*/ */
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, backend->pathBuffer, backend->pathBufferOffset, pathCount*sizeof(mg_gl_path)); 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); // glUniform1ui(0, tileSize);
glUniform1f(1, scale); // glUniform1f(1, scale);
glUniform1ui(2, eltCount);
int err = glGetError(); int err = glGetError();
if(err) if(err)
@ -745,7 +743,9 @@ mg_canvas_backend* gl_canvas_backend_create(mg_wgl_surface* surface)
int err = 0; int err = 0;
/* /*
err |= mg_gl_canvas_compile_compute_program(glsl_path_setup, &backend->pathSetup); 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_segment_setup, &backend->segmentSetup);
/*
err |= mg_gl_canvas_compile_compute_program(glsl_backprop, &backend->backprop); err |= mg_gl_canvas_compile_compute_program(glsl_backprop, &backend->backprop);
err |= mg_gl_canvas_compile_compute_program(glsl_merge, &backend->merge); err |= mg_gl_canvas_compile_compute_program(glsl_merge, &backend->merge);
*/ */

View File

@ -9,71 +9,21 @@ layout(binding = 0) restrict readonly buffer pathBufferSSBO
mg_gl_path elements[]; mg_gl_path elements[];
} pathBuffer; } pathBuffer;
layout(binding = 1) restrict readonly buffer elementBufferSSBO layout(binding = 1) restrict readonly buffer segmentBufferCountSSBO
{ {
mg_gl_path_elt elements[]; int elements[];
} elementBuffer; } 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 = 0) uniform uint tileSize; // this has to be commented until it's effectively used!!
layout(location = 1) uniform float scale; //layout(location = 0) uniform float scale;
layout(location = 2) uniform uint eltCount;
layout(rgba8, binding = 0) uniform restrict writeonly image2D outTexture; 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) 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)); 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() void main()
{ {
int segCount = segmentCountBuffer.elements[0];
vec2 sampleCoord = vec2(gl_WorkGroupID.xy*uvec2(16, 16) + gl_LocalInvocationID.xy); vec2 sampleCoord = vec2(gl_WorkGroupID.xy*uvec2(16, 16) + gl_LocalInvocationID.xy);
int winding = 0; 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: winding += seg.windingIncrement;
{
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;
} }
/*
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; int pathIndex = 0;
vec4 clip = pathBuffer.elements[pathIndex].clip * scale;
// vec4 clip = pathBuffer.elements[pathIndex].clip * scale;
/* if( sampleCoord.x >= clip.x /* if( sampleCoord.x >= clip.x
&& sampleCoord.x < clip.z && sampleCoord.x < clip.z

View File

@ -19,28 +19,92 @@ layout(binding = 2) restrict writeonly buffer segmentBufferSSBO
mg_gl_segment elements[]; mg_gl_segment elements[];
} segmentBuffer; } segmentBuffer;
layout(binding = 3) restrict readonly buffer pathQueueBufferSSBO layout(location = 0) uniform float scale;
{
mg_gl_path_queue elements[];
} pathQueueBuffer;
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[]; int segIndex = atomicAdd(segmentCountBuffer.elements[0], 1);
} tileOpBuffer;
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[]; int segIndex = push_segment(p, MG_GL_LINE);
} tileOpCountBuffer; segmentBuffer.elements[segIndex].hullVertex = p[0];
//TODO later bin to tiles
}
void main() 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;
}
} }