From d00024b5155293da953799e577d7d038fffdc275 Mon Sep 17 00:00:00 2001 From: martinfouilleul Date: Mon, 3 Jul 2023 15:00:40 +0200 Subject: [PATCH] [wip, win32, canvas] added MSAA to new canvas renderer --- src/gl_canvas.c | 10 +-- src/glsl_shaders/common.glsl | 3 + src/glsl_shaders/raster.glsl | 142 +++++++++++++++++++++++------------ 3 files changed, 98 insertions(+), 57 deletions(-) diff --git a/src/gl_canvas.c b/src/gl_canvas.c index f47cd60..c792647 100644 --- a/src/gl_canvas.c +++ b/src/gl_canvas.c @@ -300,16 +300,7 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend, //NOTE: raster pass glUseProgram(backend->raster); -/* - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, backend->screenTilesBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->tileOpBuffer); - glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 2, backend->pathBuffer, backend->pathBufferOffset, pathCount*sizeof(mg_gl_path)); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, backend->segmentBuffer); - glUniform1i(0, tileSize); - glUniform1f(1, scale); - glUniform1i(2, backend->msaaCount); -*/ glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, backend->pathBuffer, backend->pathBufferOffset, pathCount*sizeof(mg_gl_path)); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->segmentCountBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->segmentBuffer); @@ -317,6 +308,7 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend, glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, backend->screenTilesBuffer); glUniform1f(0, scale); + glUniform1i(1, backend->msaaCount); int err = glGetError(); if(err) diff --git a/src/glsl_shaders/common.glsl b/src/glsl_shaders/common.glsl index 914d894..b30adce 100644 --- a/src/glsl_shaders/common.glsl +++ b/src/glsl_shaders/common.glsl @@ -20,6 +20,9 @@ layout(std430) buffer; #define MG_GL_OP_START 0 #define MG_GL_OP_SEGMENT 1 +// MSAA +#define MG_GL_MAX_SAMPLE_COUNT 8 + struct mg_gl_path { mat3 uvTransform; diff --git a/src/glsl_shaders/raster.glsl b/src/glsl_shaders/raster.glsl index 95930ce..8344821 100644 --- a/src/glsl_shaders/raster.glsl +++ b/src/glsl_shaders/raster.glsl @@ -30,9 +30,11 @@ layout(binding = 4) restrict readonly buffer screenTilesBufferSSBO } screenTilesBuffer; layout(location = 0) uniform float scale; +layout(location = 1) uniform int msaaSampleCount; layout(rgba8, binding = 0) uniform restrict writeonly image2D outTexture; + void main() { uvec2 nTiles = gl_NumWorkGroups.xy; @@ -40,18 +42,45 @@ void main() uint tileIndex = tileCoord.y * nTiles.x + tileCoord.x; ivec2 pixelCoord = ivec2(gl_WorkGroupID.xy*uvec2(16, 16) + gl_LocalInvocationID.xy); - vec2 sampleCoord = vec2(pixelCoord); + vec2 centerCoord = vec2(pixelCoord) + vec2(0.5, 0.5); + + /* + if((pixelCoord.x % 16) == 0 || (pixelCoord.y % 16) == 0) + { + imageStore(outTexture, pixelCoord, vec4(0, 0, 0, 1)); + return; + } + */ + + vec2 sampleCoords[MG_GL_MAX_SAMPLE_COUNT] = { + centerCoord + vec2(1, 3)/16, + centerCoord + vec2(-1, -3)/16, + centerCoord + vec2(5, -1)/16, + centerCoord + vec2(-3, 5)/16, + centerCoord + vec2(-5, -5)/16, + centerCoord + vec2(-7, 1)/16, + centerCoord + vec2(3, -7)/16, + centerCoord + vec2(7, 7)/16 + }; + + int sampleCount = msaaSampleCount; + if(sampleCount != 8) + { + sampleCount = 1; + sampleCoords[0] = centerCoord; + } + + vec4 color[MG_GL_MAX_SAMPLE_COUNT]; + int winding[MG_GL_MAX_SAMPLE_COUNT]; + + for(int i=0; i= 0) { @@ -60,24 +89,28 @@ void main() if(op.kind == MG_GL_OP_START) { + vec4 clip = pathBuffer.elements[pathIndex].clip * scale; vec4 pathColor = pathBuffer.elements[pathIndex].color; pathColor.rgb *= pathColor.a; - vec4 clip = pathBuffer.elements[pathIndex].clip * scale; - - if( sampleCoord.x >= clip.x - && sampleCoord.x < clip.z - && sampleCoord.y >= clip.y - && sampleCoord.y < clip.w) + for(int sampleIndex = 0; sampleIndex= clip.x + && sampleCoord.x < clip.z + && sampleCoord.y >= clip.y + && sampleCoord.y < clip.w) { - vec4 nextColor = pathColor; - color = color*(1-nextColor.a) + nextColor; + bool filled = (pathBuffer.elements[pathIndex].cmd == MG_GL_FILL && ((winding[sampleIndex] & 1) != 0)) + ||(pathBuffer.elements[pathIndex].cmd == MG_GL_STROKE && (winding[sampleIndex] != 0)); + if(filled) + { + vec4 nextColor = pathColor; + color[sampleIndex] = color[sampleIndex]*(1-nextColor.a) + nextColor; + } } - winding = op.windingOffset; + winding[sampleIndex] = op.windingOffset; } pathIndex = op.index; } @@ -86,47 +119,60 @@ void main() int segIndex = op.index; mg_gl_segment seg = segmentBuffer.elements[segIndex]; - if( (sampleCoord.y > seg.box.y) - &&(sampleCoord.y <= seg.box.w) - &&(side_of_segment(sampleCoord, seg) < 0)) + for(int sampleIndex=0; sampleIndex seg.box.w)) + if( (sampleCoord.y > seg.box.y) + &&(sampleCoord.y <= seg.box.w) + &&(side_of_segment(sampleCoord, seg) < 0)) { - winding += seg.windingIncrement; + winding[sampleIndex] += seg.windingIncrement; } - else if( (seg.config == MG_GL_BL || seg.config == MG_GL_TR) - &&(sampleCoord.y > seg.box.y)) + + if(op.crossRight) { - winding -= seg.windingIncrement; + if( (seg.config == MG_GL_BR || seg.config == MG_GL_TL) + &&(sampleCoord.y > seg.box.w)) + { + winding[sampleIndex] += seg.windingIncrement; + } + else if( (seg.config == MG_GL_BL || seg.config == MG_GL_TR) + &&(sampleCoord.y > seg.box.y)) + { + winding[sampleIndex] -= seg.windingIncrement; + } } } } } - vec4 pathColor = pathBuffer.elements[pathIndex].color; - pathColor.rgb *= pathColor.a; - vec4 clip = pathBuffer.elements[pathIndex].clip * scale; - if( sampleCoord.x >= clip.x - && sampleCoord.x < clip.z - && sampleCoord.y >= clip.y - && sampleCoord.y < clip.w) + vec4 pixelColor = vec4(0); + vec4 pathColor = pathBuffer.elements[pathIndex].color; + pathColor.rgb *= pathColor.a; + + for(int sampleIndex=0; sampleIndex= clip.x + && sampleCoord.x < clip.z + && sampleCoord.y >= clip.y + && sampleCoord.y < clip.w) { - vec4 nextColor = pathColor; - color = color*(1-nextColor.a) + nextColor; + bool filled = (pathBuffer.elements[pathIndex].cmd == MG_GL_FILL && ((winding[sampleIndex] & 1) != 0)) + ||(pathBuffer.elements[pathIndex].cmd == MG_GL_STROKE && (winding[sampleIndex] != 0)); + if(filled) + { + vec4 nextColor = pathColor; + color[sampleIndex] = color[sampleIndex]*(1-nextColor.a) + nextColor; + } } + pixelColor += color[sampleIndex]; } - // write to texture - imageStore(outTexture, ivec2(sampleCoord), color); + pixelColor /= sampleCount; + + imageStore(outTexture, pixelCoord, pixelColor); }