From f24ad6d0004ac447738fb19ddf56c283f95d02d7 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Wed, 5 Nov 2025 22:57:21 +0300 Subject: [PATCH] Fixed disappearing objects when using Shared Storage/Uniform Buffer --- src/CRE/render_context.cpp | 42 +++++++++++++++++++++++--------------- src/CRE/render_context.hpp | 10 +++++---- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index 0717c8fe..86b5edb7 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -915,20 +915,22 @@ void render_data_context::set_skinning_data(p_gl_rend_state& p_gl_rend_st, const data.set_skinning_data(p_gl_rend_st, mats, count); } -bool render_context::shared_storage_buffer::can_fill_data(size_t size) { - return (size + align_val(offset, sv_min_storage_buffer_alignment)) <= this->size; +bool render_context::shared_storage_buffer::can_fill_data(size_t buffer_size) { + return (buffer_size + align_val(offset, sv_min_storage_buffer_alignment)) <= this->size; } void render_context::shared_storage_buffer::create(size_t size) { if (buffer) return; + size = min_def(size, sv_max_storage_buffer_size); size = size / sv_min_storage_buffer_alignment * sv_min_storage_buffer_alignment; buffer.Create(gl_state, size); data = force_malloc(size); memset(data, 0, size); offset = 0; + end = 0; this->size = size; } @@ -937,29 +939,32 @@ void render_context::shared_storage_buffer::destroy() { free_def(data); } -size_t render_context::shared_storage_buffer::fill_data(const void* data, size_t size) { +size_t render_context::shared_storage_buffer::fill_data(const void* data, size_t size, size_t buffer_size) { size_t offset = align_val(this->offset, sv_min_storage_buffer_alignment); if (offset != this->offset) memset((void*)((size_t)this->data + this->offset), 0, offset - this->offset); memcpy((void*)((size_t)this->data + offset), data, size); this->offset = offset + size; + end = max_def(end, offset + buffer_size); return offset; } -bool render_context::shared_uniform_buffer::can_fill_data(size_t size) { - return (size + align_val(offset, sv_min_uniform_buffer_alignment)) <= this->size; +bool render_context::shared_uniform_buffer::can_fill_data(size_t buffer_size) { + return (buffer_size + align_val(offset, sv_min_uniform_buffer_alignment)) <= this->size; } void render_context::shared_uniform_buffer::create(size_t size) { if (buffer) return; + size = min_def(size, sv_max_uniform_buffer_size); size = size / sv_min_uniform_buffer_alignment * sv_min_uniform_buffer_alignment; buffer.Create(gl_state, size); data = force_malloc(size); memset(data, 0, size); offset = 0; + end = 0; this->size = size; } @@ -968,12 +973,13 @@ void render_context::shared_uniform_buffer::destroy() { free_def(data); } -size_t render_context::shared_uniform_buffer::fill_data(const void* data, size_t size) { +size_t render_context::shared_uniform_buffer::fill_data(const void* data, size_t size, size_t buffer_size) { size_t offset = align_val(this->offset, sv_min_uniform_buffer_alignment); if (offset != this->offset) memset((void*)((size_t)this->data + this->offset), 0, offset - this->offset); memcpy((void*)((size_t)this->data + offset), data, size); this->offset = offset + size; + end = max_def(end, offset + buffer_size); return offset; } @@ -1406,7 +1412,7 @@ void render_context::add_shared_storage_uniform_buffer_data(size_t index, buffer->create(max_storage_block_size); } - size_t offset = buffer->fill_data(data, size); + size_t offset = buffer->fill_data(data, size, buffer_size); shared_storage_buffer_entries.insert({ index, { buffer->buffer, offset, buffer_size } }); } else { @@ -1423,7 +1429,7 @@ void render_context::add_shared_storage_uniform_buffer_data(size_t index, buffer->create(max_uniform_block_size); } - size_t offset = buffer->fill_data(data, size); + size_t offset = buffer->fill_data(data, size, buffer_size); shared_uniform_buffer_entries.insert({ index, { buffer->buffer, offset, buffer_size } }); } } @@ -1459,13 +1465,13 @@ void render_context::pre_proc() { return; if (GLAD_GL_VERSION_4_3) { - if (rctx->shared_storage_buffer_entries.find((size_t)args->mats) - != rctx->shared_storage_buffer_entries.end()) + auto elem = rctx->shared_storage_buffer_entries.find((size_t)args->mats); + if (elem != rctx->shared_storage_buffer_entries.end()) return; } else { - if (rctx->shared_uniform_buffer_entries.find((size_t)args->mats) - != rctx->shared_uniform_buffer_entries.end()) + auto elem = rctx->shared_uniform_buffer_entries.find((size_t)args->mats); + if (elem != rctx->shared_uniform_buffer_entries.end()) return; } @@ -1529,7 +1535,7 @@ void render_context::pre_proc() { if (!i.offset) continue; - const size_t size = align_val(i.offset, sv_min_uniform_buffer_alignment); + const size_t size = align_val(i.end, sv_min_storage_buffer_alignment); const size_t align = size - i.offset; if (align) memset((void*)((size_t)i.data + i.offset), 0, align); @@ -1540,7 +1546,7 @@ void render_context::pre_proc() { if (!i.offset) continue; - const size_t size = align_val(i.offset, sv_min_uniform_buffer_alignment); + const size_t size = align_val(i.end, sv_min_uniform_buffer_alignment); const size_t align = size - i.offset; if (align) memset((void*)((size_t)i.data + i.offset), 0, align); @@ -1552,14 +1558,18 @@ void render_context::pre_proc() { void render_context::post_proc() { if (sv_shared_storage_uniform_buffer) { if (GLAD_GL_VERSION_4_3) { - for (render_context::shared_storage_buffer& i : shared_storage_buffers) + for (render_context::shared_storage_buffer& i : shared_storage_buffers) { i.offset = 0; + i.end = 0; + } shared_storage_buffer_entries.clear(); } - for (render_context::shared_uniform_buffer& i : shared_uniform_buffers) + for (render_context::shared_uniform_buffer& i : shared_uniform_buffers) { i.offset = 0; + i.end = 0; + } shared_uniform_buffer_entries.clear(); } diff --git a/src/CRE/render_context.hpp b/src/CRE/render_context.hpp index ab1d25e0..c1fa4a7f 100644 --- a/src/CRE/render_context.hpp +++ b/src/CRE/render_context.hpp @@ -501,25 +501,27 @@ struct render_context { struct shared_storage_buffer { void* data; size_t offset; + size_t end; size_t size; GL::ShaderStorageBuffer buffer; - bool can_fill_data(size_t size); + bool can_fill_data(size_t buffer_size); void create(size_t size); void destroy(); - size_t fill_data(const void* data, size_t size); + size_t fill_data(const void* data, size_t size, size_t buffer_size); }; struct shared_uniform_buffer { void* data; size_t offset; + size_t end; size_t size; GL::UniformBuffer buffer; - bool can_fill_data(size_t size); + bool can_fill_data(size_t buffer_size); void create(size_t size); void destroy(); - size_t fill_data(const void* data, size_t size); + size_t fill_data(const void* data, size_t size, size_t buffer_size); }; struct shared_buffer_entry {