diff --git a/src/gl_canvas.c b/src/gl_canvas.c index 2869683..417d9d3 100644 --- a/src/gl_canvas.c +++ b/src/gl_canvas.c @@ -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); */ diff --git a/src/glsl_shaders/raster.glsl b/src/glsl_shaders/raster.glsl index c5c96ca..26c9458 100644 --- a/src/glsl_shaders/raster.glsl +++ b/src/glsl_shaders/raster.glsl @@ -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 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 diff --git a/src/glsl_shaders/segment_setup.glsl b/src/glsl_shaders/segment_setup.glsl index cade1a3..0a3b080 100644 --- a/src/glsl_shaders/segment_setup.glsl +++ b/src/glsl_shaders/segment_setup.glsl @@ -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; + } }