From cc319190c6f4226e044563809234576bd98f3fe3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 11 May 2025 15:26:05 -0700 Subject: [PATCH] render/opengl: flushed instance buffers --- src/render/opengl/render_opengl.c | 40 +++++++++++++++++++++++++++---- src/render/opengl/render_opengl.h | 14 ++++++++++- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/render/opengl/render_opengl.c b/src/render/opengl/render_opengl.c index eb8240ed..e23df2ac 100644 --- a/src/render/opengl/render_opengl.c +++ b/src/render/opengl/render_opengl.c @@ -65,6 +65,29 @@ r_ogl_format_info_from_tex2dformat(R_Tex2DFormat fmt) return result; } +internal GLuint +r_ogl_instance_buffer_from_size(U64 size) +{ + GLuint buffer = r_ogl_state->scratch_buffer_64kb; + if(size > KB(64)) + { + // rjf: build buffer + U64 flushed_buffer_size = size; + flushed_buffer_size += MB(1)-1; + flushed_buffer_size -= flushed_buffer_size%MB(1); + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, flushed_buffer_size, 0, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + // rjf: push buffer to flush list + R_OGL_FlushBuffer *n = push_array(r_ogl_state->buffer_flush_arena, R_OGL_FlushBuffer, 1); + n->id = buffer; + SLLQueuePush(r_ogl_state->first_buffer_to_flush, r_ogl_state->last_buffer_to_flush, n); + } + return buffer; +} + internal void r_ogl_debug_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) { @@ -150,9 +173,9 @@ r_init(CmdLine *cmdln) //- rjf: set up built-in resources glGenVertexArrays(1, &r_ogl_state->all_purpose_vao); - glGenBuffers(1, &r_ogl_state->scratch_buffer_2mb); - glBindBuffer(GL_ARRAY_BUFFER, r_ogl_state->scratch_buffer_2mb); - glBufferData(GL_ARRAY_BUFFER, MB(2), 0, GL_DYNAMIC_DRAW); + glGenBuffers(1, &r_ogl_state->scratch_buffer_64kb); + glBindBuffer(GL_ARRAY_BUFFER, r_ogl_state->scratch_buffer_64kb); + glBufferData(GL_ARRAY_BUFFER, KB(64), 0, GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenTextures(1, &r_ogl_state->white_texture); glBindTexture(GL_TEXTURE_2D, r_ogl_state->white_texture); @@ -160,6 +183,9 @@ r_init(CmdLine *cmdln) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &white_pixel); glEnable(GL_FRAMEBUFFER_SRGB); + //- rjf: set up buffer flush state + r_ogl_state->buffer_flush_arena = arena_alloc(); + //- rjf: set up debug callback B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); #if BUILD_DEBUG @@ -334,6 +360,12 @@ r_window_begin_frame(OS_Handle os, R_Handle r) r_hook void r_window_end_frame(OS_Handle os, R_Handle r) { + for(R_OGL_FlushBuffer *flush_buffer = r_ogl_state->first_buffer_to_flush; flush_buffer != 0; flush_buffer = flush_buffer->next) + { + glDeleteBuffers(1, &flush_buffer->id); + } + arena_clear(r_ogl_state->buffer_flush_arena); + r_ogl_state->first_buffer_to_flush = r_ogl_state->last_buffer_to_flush = 0; r_ogl_os_window_swap(os, r); } @@ -382,7 +414,7 @@ r_window_submit(OS_Handle window, R_Handle window_equip, R_PassList *passes) } //- rjf: get & fill buffer - GLuint buffer = r_ogl_state->scratch_buffer_2mb; // TODO(rjf): r_ogl_instance_buffer_from_size(batches->byte_count); + GLuint buffer = r_ogl_instance_buffer_from_size(batches->byte_count); { glBindBuffer(GL_ARRAY_BUFFER, buffer); U64 off = 0; diff --git a/src/render/opengl/render_opengl.h b/src/render/opengl/render_opengl.h index dde24165..e8c56ccb 100644 --- a/src/render/opengl/render_opengl.h +++ b/src/render/opengl/render_opengl.h @@ -113,6 +113,7 @@ struct R_OGL_AttributeArray #define R_OGL_ProcedureXList \ X(glGenBuffers, void, (GLsizei n, GLuint *buffers))\ X(glBindBuffer, void, (GLenum target, GLuint buffer))\ +X(glDeleteBuffers, void, (GLsizei n, GLuint *buffers))\ X(glGenVertexArrays, void, (GLsizei n, GLuint *arrays))\ X(glBindVertexArray, void, (GLuint array))\ X(glCreateProgram, GLuint, (void))\ @@ -179,6 +180,13 @@ struct R_OGL_Tex2D Vec2S32 size; }; +typedef struct R_OGL_FlushBuffer R_OGL_FlushBuffer; +struct R_OGL_FlushBuffer +{ + R_OGL_FlushBuffer *next; + GLuint id; +}; + typedef struct R_OGL_State R_OGL_State; struct R_OGL_State { @@ -186,8 +194,11 @@ struct R_OGL_State R_OGL_Tex2D *free_tex2d; GLuint shaders[R_OGL_ShaderKind_COUNT]; GLuint all_purpose_vao; - GLuint scratch_buffer_2mb; + GLuint scratch_buffer_64kb; GLuint white_texture; + Arena *buffer_flush_arena; + R_OGL_FlushBuffer *first_buffer_to_flush; + R_OGL_FlushBuffer *last_buffer_to_flush; }; //////////////////////////////// @@ -201,6 +212,7 @@ global R_OGL_State *r_ogl_state = 0; internal R_Handle r_ogl_handle_from_tex2d(R_OGL_Tex2D *t); internal R_OGL_Tex2D *r_ogl_tex2d_from_handle(R_Handle h); internal R_OGL_FormatInfo r_ogl_format_info_from_tex2dformat(R_Tex2DFormat fmt); +internal GLuint r_ogl_instance_buffer_from_size(U64 size); internal void r_ogl_debug_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam); #define glUseProgramScope(...) DeferLoop(glUseProgram(__VA_ARGS__), glUseProgram(0))