From f0bc88c4fb3f4454206836b686eebddafabab8b5 Mon Sep 17 00:00:00 2001 From: martinfouilleul Date: Tue, 7 Feb 2023 17:00:59 +0100 Subject: [PATCH] gl canvas renderer with buffer re-specification --- build.bat | 2 +- examples/perf_text/build.bat | 2 +- src/gl_canvas.c | 9 +++++---- src/win32_gl_loader.h | 4 ++++ todo.txt | 14 +++++++++++--- vector_renderer_notes.txt | 12 ++++++++++++ 6 files changed, 34 insertions(+), 9 deletions(-) diff --git a/build.bat b/build.bat index 48f703a..131f00f 100644 --- a/build.bat +++ b/build.bat @@ -4,6 +4,6 @@ if not exist bin mkdir bin set gles_shaders=src\gles_canvas_shaders\gles_canvas_blit_vertex.glsl src\gles_canvas_shaders\gles_canvas_blit_fragment.glsl src\gles_canvas_shaders\gles_canvas_clear_counters.glsl src\gles_canvas_shaders\gles_canvas_tile.glsl src\gles_canvas_shaders\gles_canvas_sort.glsl src\gles_canvas_shaders\gles_canvas_draw.glsl call python scripts\embed_text.py %gles_shaders% --output src\gles_canvas_shaders.h -set INCLUDES=/I src /I src/util /I src/platform /I ext /I ext/angle_headers +set INCLUDES=/I src /I src/util /I src/platform /I ext cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GL /std:c11 %INCLUDES% /c /Fo:bin/milepost.obj src/milepost.c lib bin/milepost.obj /OUT:bin/milepost.lib diff --git a/examples/perf_text/build.bat b/examples/perf_text/build.bat index beebece..372691f 100644 --- a/examples/perf_text/build.bat +++ b/examples/perf_text/build.bat @@ -1,4 +1,4 @@ -set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers +set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GL /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib /out:../../bin/perf_text.exe diff --git a/src/gl_canvas.c b/src/gl_canvas.c index da18816..44c1c5e 100644 --- a/src/gl_canvas.c +++ b/src/gl_canvas.c @@ -114,11 +114,12 @@ void mg_gl_canvas_update_vertex_layout(mg_gl_canvas_backend* backend) void mg_gl_send_buffers(mg_gl_canvas_backend* backend, int vertexCount, int indexCount) { glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->vertexBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, LAYOUT_VERTEX_SIZE*vertexCount, backend->vertexMapping, GL_DYNAMIC_DRAW); + glBufferData(GL_SHADER_STORAGE_BUFFER, LAYOUT_VERTEX_SIZE*vertexCount, backend->vertexMapping, GL_STREAM_DRAW); glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->indexBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, LAYOUT_INT_SIZE*indexCount, backend->indexMapping, GL_DYNAMIC_DRAW); + glBufferData(GL_SHADER_STORAGE_BUFFER, LAYOUT_INT_SIZE*indexCount, backend->indexMapping, GL_STREAM_DRAW); } + void mg_gl_canvas_begin(mg_canvas_backend* interface) { mg_gl_canvas_backend* backend = (mg_gl_canvas_backend*)interface; @@ -306,11 +307,11 @@ mg_canvas_backend* mg_gl_canvas_create(mg_surface surface) glGenBuffers(1, &backend->vertexBuffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->vertexBuffer); -// glBufferData(GL_SHADER_STORAGE_BUFFER, MG_GL_CANVAS_VERTEX_BUFFER_SIZE, 0, GL_DYNAMIC_DRAW); + glBufferData(GL_SHADER_STORAGE_BUFFER, MG_GL_CANVAS_VERTEX_BUFFER_SIZE, 0, GL_STREAM_DRAW); glGenBuffers(1, &backend->indexBuffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->indexBuffer); -// glBufferData(GL_SHADER_STORAGE_BUFFER, MG_GL_CANVAS_INDEX_BUFFER_SIZE, 0, GL_DYNAMIC_DRAW); + glBufferData(GL_SHADER_STORAGE_BUFFER, MG_GL_CANVAS_INDEX_BUFFER_SIZE, 0, GL_STREAM_DRAW); glGenBuffers(1, &backend->tileCounterBuffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->tileCounterBuffer); diff --git a/src/win32_gl_loader.h b/src/win32_gl_loader.h index 769a924..9b90d91 100644 --- a/src/win32_gl_loader.h +++ b/src/win32_gl_loader.h @@ -36,6 +36,7 @@ GL_PROC(GLGENBUFFERS, glGenBuffers) \ GL_PROC(GLBINDBUFFER, glBindBuffer) \ GL_PROC(GLBUFFERDATA, glBufferData) \ + GL_PROC(GLBUFFERSUBDATA, glBufferSubData) \ GL_PROC(GLUNIFORMMATRIX4FV, glUniformMatrix4fv) \ GL_PROC(GLVERTEXATTRIBPOINTER, glVertexAttribPointer) \ GL_PROC(GLENABLEVERTEXATTRIBARRAY, glEnableVertexAttribArray) \ @@ -47,6 +48,9 @@ GL_PROC(GLACTIVETEXTURE, glActiveTexture) \ GL_PROC(GLUNIFORM1I, glUniform1i) \ GL_PROC(GLTEXSTORAGE2D, glTexStorage2D) \ + GL_PROC(GLMAPBUFFERRANGE, glMapBufferRange) \ + GL_PROC(GLUNMAPBUFFER, glUnmapBuffer) + #ifdef WIN32_GL_LOADER_API //NOTE: pointer declarations diff --git a/todo.txt b/todo.txt index ac46c91..54ffa98 100644 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,10 @@ +WIP +--- +[ ] Split vertex data into per-vertex and per-shape data. Keep only pos, cubics, and shapeID in vertex data +[?] use half-floats or short fixed-point for pos and uv, packing them in two ints + +----------- [.] Check changes in macos version [x] Restructure macos version to use mp_app_internal.h/mp_app.c [x] test new run loop structure on macos @@ -41,9 +47,11 @@ [ ] Text rendering test app [?] Little test drawing app? - [>] Assess perf - [ ] Tiling - [ ] Precomputing triangle edges/biases? + [.] Assess perf + [x] Tiling + [>] Reduce size of data sent to GPU + [ ] experiment with persistently mapped buffer? + [?] Precomputing triangle edges/biases? [ ] Implement surfaces with child windows on win32 [/] Maybe implement compositing directly in d3d and opengl compat extension... diff --git a/vector_renderer_notes.txt b/vector_renderer_notes.txt index d3a79e5..3c5b021 100644 --- a/vector_renderer_notes.txt +++ b/vector_renderer_notes.txt @@ -80,3 +80,15 @@ Ideally, we would do the vertex computation on the GPU (opportunity to paralleli -> Problem profiling canvas renderer with angle (not really well supported in renderdoc) -> Maybe use an OpenGL backend instead? + +Quick measurement on perf_text.exe +---------------------------------- +* Re-allocate and copy each time with glBufferData --> ~23ms +* Allocate big buffer and update with glBufferSubData --> ~23ms +* Map whole buffer --> ~44ms +* Map whole buffer with GL_MAP_INVALIDATE_BUFFER_BIT --> ~19ms (but with some startup hiccups...) +* Map whole buffer with GL_MAP_INVALIDATE_RANGE_BIT --> ~44ms + + +-> Stutter is with GL_MAP_INVALIDATE_BUFFER_BIT isn't reassuring. Stick to glBufferData for now. +-> May be worth it to try persistently mapped buffers later.