From a6767082a78e8b090fcce8c386fcbd359da8ecee Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Wed, 21 Jun 2023 08:56:34 -0700 Subject: Fix bug in Geometry that would over-allocate buffers. --- gfx/src/render/buffer.c | 44 +++++------ gfx/src/render/buffer.h | 3 + gfx/src/render/geometry.c | 183 +++++++++++++++++++++++++--------------------- 3 files changed, 124 insertions(+), 106 deletions(-) diff --git a/gfx/src/render/buffer.c b/gfx/src/render/buffer.c index 3c0c794..55c68cc 100644 --- a/gfx/src/render/buffer.c +++ b/gfx/src/render/buffer.c @@ -8,24 +8,7 @@ static size_t get_buffer_size_bytes( BufferType type, const BufferDataDesc* desc) { - switch (type) { - case BufferUntyped: - return desc->count; - case Buffer2d: - return desc->count * sizeof(vec2); - case Buffer3d: - return desc->count * sizeof(vec3); - case Buffer4d: - return desc->count * sizeof(vec4); - case BufferFloat: - return desc->count * sizeof(float); - case BufferU8: - return desc->count * sizeof(uint8_t); - case BufferU16: - return desc->count * sizeof(uint16_t); - } - assert(false); - return 0; + return desc->count * gfx_get_buffer_type_size_bytes(type); } static GLenum get_buffer_usage(BufferUsage usage) { @@ -39,6 +22,27 @@ static GLenum get_buffer_usage(BufferUsage usage) { return GL_STATIC_DRAW; } +size_t gfx_get_buffer_type_size_bytes(BufferType type) { + switch (type) { + case BufferUntyped: + return 1; + case Buffer2d: + return sizeof(vec2); + case Buffer3d: + return sizeof(vec3); + case Buffer4d: + return sizeof(vec4); + case BufferFloat: + return sizeof(float); + case BufferU8: + return sizeof(uint8_t); + case BufferU16: + return sizeof(uint16_t); + } + assert(false); + return 0; +} + bool gfx_init_buffer(Buffer* buffer, const BufferDesc* desc) { assert(buffer); buffer->type = desc->type; @@ -61,9 +65,7 @@ void gfx_del_buffer(Buffer* buffer) { } } -void gfx_update_buffer( - RenderBackend* render_backend, Buffer* buffer, const BufferDataDesc* desc) { - assert(render_backend); +void gfx_update_buffer(Buffer* buffer, const BufferDataDesc* desc) { assert(buffer); assert(desc); // OpenGL allows updating static buffers, but it is not optimal for diff --git a/gfx/src/render/buffer.h b/gfx/src/render/buffer.h index 0c81e7b..3adfd8e 100644 --- a/gfx/src/render/buffer.h +++ b/gfx/src/render/buffer.h @@ -16,6 +16,9 @@ typedef struct Buffer { size_t size_bytes; } Buffer; +/// Return the buffer type size in bytes. +size_t gfx_get_buffer_type_size_bytes(BufferType); + /// Create a buffer from raw data. bool gfx_init_buffer(Buffer*, const BufferDesc*); diff --git a/gfx/src/render/geometry.c b/gfx/src/render/geometry.c index e9d3ae5..44bfd04 100644 --- a/gfx/src/render/geometry.c +++ b/gfx/src/render/geometry.c @@ -26,21 +26,26 @@ static GLenum primitive_type_to_gl(PrimitiveType type) { } } -/// Create a buffer for the buffer view if the view does not already point to -/// a buffer. -#define INIT_VIEW_BUFFER(render_backend, view, buffer_type, buffer_usage) \ - if (!view.buffer) { \ - view.buffer = (__typeof__(view.buffer))gfx_make_buffer( \ - render_backend, &(BufferDesc){ \ - .usage = buffer_usage, \ - .type = buffer_type, \ - .data.data = view.data, \ - .data.count = view.size_bytes}); \ - } \ - assert(view.size_bytes <= view.buffer->size_bytes); +/// Create a typed buffer for the buffer view if the view does not already point +/// to a buffer. +void init_view_buffer( + RenderBackend* render_backend, BufferView* view, BufferType buffer_type, + BufferUsage buffer_usage) { + if (!view->buffer) { + view->buffer = gfx_make_buffer( + render_backend, + &(BufferDesc){ + .usage = buffer_usage, + .type = buffer_type, + .data.data = view->data, + .data.count = view->size_bytes / + gfx_get_buffer_type_size_bytes(buffer_type)}); + } + assert(view->size_bytes <= view->buffer->size_bytes); +} -/// Create a buffer for the view, then configure it in the VAO. -static bool configure_buffer( +/// Configure the buffer in teh VAO. +static void configure_buffer( RenderBackend* render_backend, const GeometryDesc* desc, BufferView* view, size_t num_components, size_t component_size_bytes, GLenum component_type, GLboolean normalized, GLuint channel) { @@ -70,8 +75,6 @@ static bool configure_buffer( (const void*)view->offset_bytes); } glBindBuffer(GL_ARRAY_BUFFER, 0); - - return true; } static bool configure_vertex_attributes( @@ -80,105 +83,113 @@ static bool configure_vertex_attributes( assert(desc); if (view_is_populated(desc->positions3d)) { - INIT_VIEW_BUFFER( - render_backend, desc->positions3d, Buffer3d, desc->buffer_usage); - if (!desc->positions3d.buffer || - !configure_buffer( - render_backend, desc, (BufferView*)&desc->positions3d, 3, - sizeof(float), GL_FLOAT, GL_FALSE, GFX_POSITION_CHANNEL)) { + init_view_buffer( + render_backend, (BufferView*)&desc->positions3d, Buffer3d, + desc->buffer_usage); + if (!desc->positions3d.buffer) { return false; } + configure_buffer( + render_backend, desc, (BufferView*)&desc->positions3d, 3, sizeof(float), + GL_FLOAT, GL_FALSE, GFX_POSITION_CHANNEL); } else if (view_is_populated(desc->positions2d)) { - INIT_VIEW_BUFFER( - render_backend, desc->positions2d, Buffer2d, desc->buffer_usage); - if (!desc->positions2d.buffer || - !configure_buffer( - render_backend, desc, (BufferView*)&desc->positions2d, 2, - sizeof(float), GL_FLOAT, GL_FALSE, GFX_POSITION_CHANNEL)) { + init_view_buffer( + render_backend, (BufferView*)&desc->positions2d, Buffer2d, + desc->buffer_usage); + if (!desc->positions2d.buffer) { return false; } + configure_buffer( + render_backend, desc, (BufferView*)&desc->positions2d, 2, sizeof(float), + GL_FLOAT, GL_FALSE, GFX_POSITION_CHANNEL); } if (view_is_populated(desc->normals)) { - INIT_VIEW_BUFFER( - render_backend, desc->normals, Buffer3d, desc->buffer_usage); - if (!desc->normals.buffer || - !configure_buffer( - render_backend, desc, (BufferView*)&desc->normals, 3, sizeof(float), - GL_FLOAT, GL_FALSE, GFX_NORMAL_CHANNEL)) { + init_view_buffer( + render_backend, (BufferView*)&desc->normals, Buffer3d, + desc->buffer_usage); + if (!desc->normals.buffer) { return false; } + configure_buffer( + render_backend, desc, (BufferView*)&desc->normals, 3, sizeof(float), + GL_FLOAT, GL_FALSE, GFX_NORMAL_CHANNEL); } if (view_is_populated(desc->tangents)) { - INIT_VIEW_BUFFER( - render_backend, desc->tangents, Buffer4d, desc->buffer_usage); - if (!desc->tangents.buffer || - !configure_buffer( - render_backend, desc, (BufferView*)&desc->tangents, 4, - sizeof(float), GL_FLOAT, GL_FALSE, GFX_TANGENT_CHANNEL)) { + init_view_buffer( + render_backend, (BufferView*)&desc->tangents, Buffer4d, + desc->buffer_usage); + if (!desc->tangents.buffer) { return false; } + configure_buffer( + render_backend, desc, (BufferView*)&desc->tangents, 4, sizeof(float), + GL_FLOAT, GL_FALSE, GFX_TANGENT_CHANNEL); } if (view_is_populated(desc->texcoords)) { - INIT_VIEW_BUFFER( - render_backend, desc->texcoords, Buffer2d, desc->buffer_usage); - if (!desc->texcoords.buffer || - !configure_buffer( - render_backend, desc, (BufferView*)&desc->texcoords, 2, - sizeof(float), GL_FLOAT, GL_FALSE, GFX_TEXCOORDS_CHANNEL)) { + init_view_buffer( + render_backend, (BufferView*)&desc->texcoords, Buffer2d, + desc->buffer_usage); + if (!desc->texcoords.buffer) { return false; } + configure_buffer( + render_backend, desc, (BufferView*)&desc->texcoords, 2, sizeof(float), + GL_FLOAT, GL_FALSE, GFX_TEXCOORDS_CHANNEL); } if (view_is_populated(desc->joints.u8)) { - INIT_VIEW_BUFFER( - render_backend, desc->joints.u8, BufferU8, desc->buffer_usage); - if (!desc->joints.u8.buffer || - !configure_buffer( - render_backend, desc, (BufferView*)&desc->joints.u8, 4, - sizeof(uint8_t), GL_UNSIGNED_BYTE, GL_FALSE, GFX_JOINTS_CHANNEL)) { + init_view_buffer( + render_backend, (BufferView*)&desc->joints.u8, BufferU8, + desc->buffer_usage); + if (!desc->joints.u8.buffer) { return false; } + configure_buffer( + render_backend, desc, (BufferView*)&desc->joints.u8, 4, sizeof(uint8_t), + GL_UNSIGNED_BYTE, GL_FALSE, GFX_JOINTS_CHANNEL); } else if (view_is_populated(desc->joints.u16)) { - INIT_VIEW_BUFFER( - render_backend, desc->joints.u16, BufferU16, desc->buffer_usage); - if (!desc->joints.u16.buffer || - !configure_buffer( - render_backend, desc, (BufferView*)&desc->joints.u16, 4, - sizeof(uint16_t), GL_UNSIGNED_SHORT, GL_FALSE, - GFX_JOINTS_CHANNEL)) { + init_view_buffer( + render_backend, (BufferView*)&desc->joints.u16, BufferU16, + desc->buffer_usage); + if (!desc->joints.u16.buffer) { return false; } + configure_buffer( + render_backend, desc, (BufferView*)&desc->joints.u16, 4, + sizeof(uint16_t), GL_UNSIGNED_SHORT, GL_FALSE, GFX_JOINTS_CHANNEL); } - // If weights are given as unsigned integers, then they are normalized when - // read by the shader. + // If weights are given as unsigned integers, then they are normalized + // when read by the shader. if (view_is_populated(desc->weights.u8)) { - INIT_VIEW_BUFFER( - render_backend, desc->weights.u8, BufferU8, desc->buffer_usage); - if (!desc->weights.u8.buffer || - !configure_buffer( - render_backend, desc, (BufferView*)&desc->weights.u8, 4, - sizeof(uint8_t), GL_UNSIGNED_BYTE, GL_TRUE, GFX_WEIGHTS_CHANNEL)) { + init_view_buffer( + render_backend, (BufferView*)&desc->weights.u8, BufferU8, + desc->buffer_usage); + if (!desc->weights.u8.buffer) { return false; } + configure_buffer( + render_backend, desc, (BufferView*)&desc->weights.u8, 4, + sizeof(uint8_t), GL_UNSIGNED_BYTE, GL_TRUE, GFX_WEIGHTS_CHANNEL); } else if (view_is_populated(desc->weights.u16)) { - INIT_VIEW_BUFFER( - render_backend, desc->weights.u16, BufferU16, desc->buffer_usage); - if (!desc->weights.u16.buffer || - !configure_buffer( - render_backend, desc, (BufferView*)&desc->weights.u16, 4, - sizeof(uint16_t), GL_UNSIGNED_SHORT, GL_TRUE, - GFX_WEIGHTS_CHANNEL)) { + init_view_buffer( + render_backend, (BufferView*)&desc->weights.u16, BufferU16, + desc->buffer_usage); + if (!desc->weights.u16.buffer) { return false; } + configure_buffer( + render_backend, desc, (BufferView*)&desc->weights.u16, 4, + sizeof(uint16_t), GL_UNSIGNED_SHORT, GL_TRUE, GFX_WEIGHTS_CHANNEL); } else if (view_is_populated(desc->weights.floats)) { - INIT_VIEW_BUFFER( - render_backend, desc->weights.floats, BufferFloat, desc->buffer_usage); - if (!desc->weights.floats.buffer || - !configure_buffer( - render_backend, desc, (BufferView*)&desc->weights.floats, 4, - sizeof(float), GL_FLOAT, GL_FALSE, GFX_WEIGHTS_CHANNEL)) { + init_view_buffer( + render_backend, (BufferView*)&desc->weights.floats, BufferFloat, + desc->buffer_usage); + if (!desc->weights.floats.buffer) { return false; } + configure_buffer( + render_backend, desc, (BufferView*)&desc->weights.floats, 4, + sizeof(float), GL_FLOAT, GL_FALSE, GFX_WEIGHTS_CHANNEL); } return true; @@ -193,8 +204,9 @@ static bool configure_indices( assert(desc->num_indices > 0); assert( desc->num_indices <= desc->indices8.size_bytes / sizeof(VertexIndex8)); - INIT_VIEW_BUFFER( - render_backend, desc->indices8, BufferU8, desc->buffer_usage); + init_view_buffer( + render_backend, (BufferView*)&desc->indices8, BufferU8, + desc->buffer_usage); if (!desc->indices8.buffer) { return false; } @@ -203,8 +215,9 @@ static bool configure_indices( assert( desc->num_indices <= desc->indices16.size_bytes / sizeof(VertexIndex16)); - INIT_VIEW_BUFFER( - render_backend, desc->indices16, BufferU16, desc->buffer_usage); + init_view_buffer( + render_backend, (BufferView*)&desc->indices16, BufferU16, + desc->buffer_usage); if (!desc->indices16.buffer) { return false; } @@ -280,7 +293,7 @@ void gfx_update_geometry(Geometry* geometry, const GeometryDesc* desc) { // The geometry must already have an underlying GPU buffer. assert(geometry->desc.positions3d.buffer); gfx_update_buffer( - geometry->render_backend, geometry->desc.positions3d.buffer, + geometry->desc.positions3d.buffer, &(BufferDataDesc){ .vec3s = desc->positions3d.data, .count = desc->positions3d.size_bytes / sizeof(vec3)}); -- cgit v1.2.3