From 1cd9343cbfcb9074b5467b946fc526f7dab00a12 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Fri, 10 May 2024 17:16:19 +0530 Subject: [PATCH 1/6] [Follow up Fix] Fixed typo in vulkan_subpass_create_info_builder_get() --- source/renderer/vulkan/vulkan_subpass_create_info_builder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/renderer/vulkan/vulkan_subpass_create_info_builder.c b/source/renderer/vulkan/vulkan_subpass_create_info_builder.c index 21ccb652..f60c2b6d 100644 --- a/source/renderer/vulkan/vulkan_subpass_create_info_builder.c +++ b/source/renderer/vulkan/vulkan_subpass_create_info_builder.c @@ -91,7 +91,7 @@ RENDERER_API vulkan_subpass_create_info_t* vulkan_subpass_create_info_builder_ge else create_info->color_attachments = NULL; /* input attachments */ - create_info->input_attachment_count = buf_get_element_count(&build_info->color_attachments); + create_info->input_attachment_count = buf_get_element_count(&build_info->input_attachments); if(create_info->input_attachment_count > 0) create_info->input_attachments = CAST_TO(VkAttachmentReference*, buf_get_ptr(&build_info->input_attachments)); else From d11a758d64c0d5b9f079c353d294925159f956a2 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Fri, 10 May 2024 19:19:43 +0530 Subject: [PATCH 2/6] [New] added string_builder_newline and string_builder_append_builder - Added string_builder_newline() - Added string_builder_append_builder() - Added string_builder_append_builder_destroy() - Made changes to use memory_allocator_buf_create instead of buf_create in string_builder.c --- include/renderer/string_builder.h | 15 +++++++++++++-- source/renderer/string_builder.c | 11 ++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/include/renderer/string_builder.h b/include/renderer/string_builder.h index 0116e412..0d086b72 100644 --- a/include/renderer/string_builder.h +++ b/include/renderer/string_builder.h @@ -45,19 +45,30 @@ BEGIN_CPP_COMPATIBLE RENDERER_API string_builder_t* string_builder_create(memory_allocator_t* allocator, u32 capacity); RENDERER_API void string_builder_destroy(string_builder_t* builder); +/* returns the internal string buffer */ +RENDERER_API char* string_builder_get_str(string_builder_t* builder); + /* appends the formatted string to the internal character buffer */ RENDERER_API void string_builder_append(string_builder_t* builder, const char* const format, ...); +static CAN_BE_UNUSED_FUNCTION INLINE_IF_RELEASE_MODE void string_builder_append_builder(string_builder_t* builder, string_builder_t* _builder) +{ + string_builder_append(builder, string_builder_get_str(_builder)); +} +static CAN_BE_UNUSED_FUNCTION INLINE_IF_RELEASE_MODE void string_builder_append_builder_destroy(string_builder_t* builder, string_builder_t* _builder) +{ + string_builder_append_builder(builder, _builder); + string_builder_destroy(_builder); +} /* appends null termination character, sometimes we don't need to append that so lets keep it explicit not default */ RENDERER_API void string_builder_append_null(string_builder_t* builder); +RENDERER_API void string_builder_append_newline(string_builder_t* builder); /* increments the indentation for the subsequent calls to string_builder_append() */ RENDERER_API void string_builder_increment_indentation(string_builder_t* builder); /* decrements the indentiation for the subsequent calls to the string_builder_append() */ RENDERER_API void string_builder_decrement_indentation(string_builder_t* builder); -/* returns the internal string buffer */ -RENDERER_API char* string_builder_get_str(string_builder_t* builder); /* clears the string buffer and indentation buffer */ RENDERER_API void string_builder_clear(string_builder_t* builder); diff --git a/source/renderer/string_builder.c b/source/renderer/string_builder.c index ead9ab48..eae61364 100644 --- a/source/renderer/string_builder.c +++ b/source/renderer/string_builder.c @@ -34,8 +34,8 @@ RENDERER_API string_builder_t* string_builder_create(memory_allocator_t* allocat { string_builder_t* builder = (allocator == NULL) ? heap_new(string_builder_t) : memory_allocator_alloc_obj(allocator, MEMORY_ALLOCATION_TYPE_OBJ_STRING_BUILDER, string_builder_t); builder->allocator = allocator; - builder->string_buffer = buf_create(sizeof(char), capacity, 0); - builder->indentation_buffer = buf_create(sizeof(char), 1, 0); + builder->string_buffer = (allocator != NULL) ? memory_allocator_buf_create(allocator, sizeof(char), capacity, 0) : buf_create(sizeof(char), capacity, 0); + builder->indentation_buffer = (allocator != NULL) ? memory_allocator_buf_create(allocator, sizeof(char), 1, 0) : buf_create(sizeof(char), 1, 0); return builder; } @@ -77,7 +77,7 @@ RENDERER_API void string_builder_append(string_builder_t* builder, const char* c /* format the string and put that into the buffer */ va_start(args, format); - CAN_BE_UNUSED_FUNCTION u32 written_size = vsnprintf(CAST_TO(char*, ptr + indentation_level), required_size + 1, format, args); + CAN_BE_UNUSED_VARIABLE u32 written_size = vsnprintf(CAST_TO(char*, ptr + indentation_level), required_size + 1, format, args); _debug_assert__(written_size == required_size); va_end(args); @@ -90,6 +90,11 @@ RENDERER_API void string_builder_append_null(string_builder_t* builder) buf_push_null(&builder->string_buffer); } +RENDERER_API void string_builder_append_newline(string_builder_t* builder) +{ + buf_push_char(&builder->indentation_buffer, '\n'); +} + RENDERER_API void string_builder_increment_indentation(string_builder_t* builder) { buf_push_char(&builder->indentation_buffer, '\t'); From e3b39516a659345f2a3f9913f140d0dbbf63d5e3 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Fri, 10 May 2024 19:22:37 +0530 Subject: [PATCH 3/6] [Memory Leak Fixes] Memory leak fixes and optional allocator support in hash_table - Derived buffer2d_view_t from __OBJECT__ - Added optional allocator parameter in hash_table_create - More changes in vulkan_subpass_create_info_builder.h/.c - More changes in vulkan_render_pass_create_info_builder.h/.c - Eliminated memory leaks at various sites --- include/renderer/buffer2d_view.h | 10 +++++++++- include/renderer/hash_table.h | 5 +++-- .../vulkan_render_pass_create_info_builder.h | 7 +++++-- .../vulkan/vulkan_subpass_create_info_builder.h | 5 +++-- include/renderer/object.h | 1 + source/renderer/buffer2d.c | 12 +++++++----- source/renderer/buffer2d_view.c | 6 ++++-- source/renderer/event.c | 12 ++++++++---- source/renderer/font.c | 2 +- source/renderer/hash_table.c | 4 ++-- .../vulkan/vulkan_bitmap_glyph_atlas_texture.c | 2 +- .../vulkan/vulkan_host_buffered_texture.c | 3 ++- .../vulkan_render_pass_create_info_builder.c | 10 ++++++++-- source/renderer/vulkan/vulkan_render_queue.c | 6 +++++- source/renderer/vulkan/vulkan_render_scene.c | 17 ++++++++--------- source/renderer/vulkan/vulkan_shader.c | 2 +- .../vulkan/vulkan_subpass_create_info_builder.c | 7 +++++-- source/tests/bitmap_text.c | 7 ++++--- 18 files changed, 77 insertions(+), 41 deletions(-) diff --git a/include/renderer/buffer2d_view.h b/include/renderer/buffer2d_view.h index 6b4f23e2..8beaeb57 100644 --- a/include/renderer/buffer2d_view.h +++ b/include/renderer/buffer2d_view.h @@ -28,6 +28,7 @@ #include #include #include // iextent2d_t +#include typedef struct buffer2d_view_create_info_t { @@ -39,6 +40,7 @@ typedef struct buffer2d_view_create_info_t typedef struct buffer2d_view_t { + __OBJECT__; memory_allocator_t* allocator; buffer_t* backed_buffer; iextent2d_t size; @@ -46,7 +48,8 @@ typedef struct buffer2d_view_t typedef buffer2d_view_t* buffer2d_view_ptr_t; -#define BUFFER2D_VIEW(ptr) DYNAMIC_CAST(buffer2d_view_t*, ptr) +#define BUFFER2D_VIEW(ptr) OBJECT_UP_CAST(buffer2d_view_t*, ptr) +#define BUFFER2D_VIEW_CONST(ptr) OBJECT_UP_CAST_CONST(const buffer2d_view_t*, ptr) BEGIN_CPP_COMPATIBLE @@ -55,6 +58,11 @@ BEGIN_CPP_COMPATIBLE RENDERER_API buffer2d_view_t* buffer2d_view_new(memory_allocator_t* allocator); RENDERER_API buffer2d_view_t* buffer2d_view_create(memory_allocator_t* allocator, buffer2d_view_create_info_t* create_info); RENDERER_API void buffer2d_view_create_no_alloc(memory_allocator_t* allocator, buffer2d_view_create_info_t* create_info, buffer2d_view_t OUT view); +static CAN_BE_UNUSED_FUNCTION INLINE_IF_RELEASE_MODE void buffer2d_view_create_no_alloc_ext(memory_allocator_t* allocator, buffer2d_view_create_info_t* create_info, buffer2d_view_t OUT view) +{ + OBJECT_INIT(view, OBJECT_TYPE_BUFFER2D_VIEW, OBJECT_NATIONALITY_EXTERNAL); + buffer2d_view_create_no_alloc(allocator, create_info, view); +} RENDERER_API void buffer2d_view_destroy(buffer2d_view_t* view); RENDERER_API void buffer2d_view_release_resources(buffer2d_view_t* view); diff --git a/include/renderer/hash_table.h b/include/renderer/hash_table.h index 141dfb44..9e0f1bae 100644 --- a/include/renderer/hash_table.h +++ b/include/renderer/hash_table.h @@ -30,6 +30,7 @@ #include // hash_function_t #include // multi_buffer_t +typedef struct memory_allocator_t memory_allocator_t; typedef buffer_t /* sub_buffer_handle_t */ bucket_handle_list_t; typedef struct hash_table_t @@ -55,8 +56,8 @@ typedef hash_table_t* hash_table_ptr_t; BEGIN_CPP_COMPATIBLE /* constructor and destructors */ -#define hash_table_create(Tkey, Tvalue, capacity, key_comparer, key_hash_function) __hash_table_create(sizeof(Tkey), sizeof(Tvalue), capacity, key_comparer, key_hash_function) -RENDERER_API hash_table_t __hash_table_create(u32 key_size, u32 value_size, u32 capacity, comparer_t key_comparer, hash_function_t key_hash_function); +#define hash_table_create(allocator, Tkey, Tvalue, capacity, key_comparer, key_hash_function) __hash_table_create(allocator, sizeof(Tkey), sizeof(Tvalue), capacity, key_comparer, key_hash_function) +RENDERER_API hash_table_t __hash_table_create(memory_allocator_t* allocator, u32 key_size, u32 value_size, u32 capacity, comparer_t key_comparer, hash_function_t key_hash_function); RENDERER_API void hash_table_free(hash_table_t* table); /* clears the hash table and ready to be used again */ diff --git a/include/renderer/internal/vulkan/vulkan_render_pass_create_info_builder.h b/include/renderer/internal/vulkan/vulkan_render_pass_create_info_builder.h index dedeab1e..93b14aac 100644 --- a/include/renderer/internal/vulkan/vulkan_render_pass_create_info_builder.h +++ b/include/renderer/internal/vulkan/vulkan_render_pass_create_info_builder.h @@ -17,10 +17,13 @@ typedef struct vulkan_render_pass_create_info_build_info_t buffer_t attachment_usages; /* non-null if set by vulkan_render_pass_create_info_builder_add_render_set_bindings_builder() */ vulkan_shader_resource_description_builder_t* render_set_bindings_builder; + bool is_destroy_render_set_bindings_builder; /* non-null if allocated by vulkan_render_pass_create_info_builder_set_supplementary_attachment_bucket() */ VkImageView* vo_supplementary_attachments; /* non-null if set by vulkan_render_pass_create_info_builder_set_subpasses_builder*/ vulkan_subpass_create_info_builder_t* subpasses_builder; + bool is_destroy_subpasses_builder; + bool is_use_render_set_bindings_builder; bool is_use_subpasses_builder; bool is_supplementary_attachments_internal; @@ -59,9 +62,9 @@ RENDERER_API void vulkan_render_pass_create_info_builder_add_attachment_descript RENDERER_API void vulkan_render_pass_create_info_builder_add_attachment_usages(vulkan_render_pass_create_info_builder_t* builder, vulkan_attachment_next_pass_usage_t* usages, u32 usage_count); RENDERER_API void vulkan_render_pass_create_info_builder_set_render_set_bindings(vulkan_render_pass_create_info_builder_t* builder, vulkan_shader_resource_description_t* bindings, u32 binding_count); -RENDERER_API void vulkan_render_pass_create_info_builder_set_render_set_bindings_builder(vulkan_render_pass_create_info_builder_t* builder, vulkan_shader_resource_description_builder_t* srd_builder); +RENDERER_API void vulkan_render_pass_create_info_builder_set_render_set_bindings_builder(vulkan_render_pass_create_info_builder_t* builder, vulkan_shader_resource_description_builder_t* srd_builder, bool is_destroy); RENDERER_API void vulkan_render_pass_create_info_builder_set_subpasses(vulkan_render_pass_create_info_builder_t* builder, vulkan_subpass_create_info_t* infos, u32 info_count); -RENDERER_API void vulkan_render_pass_create_info_builder_set_subpasses_builder(vulkan_render_pass_create_info_builder_t* builder, vulkan_subpass_create_info_builder_t* sci_builder); +RENDERER_API void vulkan_render_pass_create_info_builder_set_subpasses_builder(vulkan_render_pass_create_info_builder_t* builder, vulkan_subpass_create_info_builder_t* sci_builder, bool is_destroy); RENDERER_API void vulkan_render_pass_create_info_builder_set_dependencies(vulkan_render_pass_create_info_builder_t* builder, VkSubpassDependency* dependencies, u32 dependency_count); diff --git a/include/renderer/internal/vulkan/vulkan_subpass_create_info_builder.h b/include/renderer/internal/vulkan/vulkan_subpass_create_info_builder.h index ff8c1f74..918fe20a 100644 --- a/include/renderer/internal/vulkan/vulkan_subpass_create_info_builder.h +++ b/include/renderer/internal/vulkan/vulkan_subpass_create_info_builder.h @@ -19,6 +19,7 @@ typedef struct vulkan_subpass_create_info_build_info_t VkAttachmentReference depth_stencil_attachment; /* non-null if set by vulkan_subpass_create_info_builder_set_render_set_bindings_builder() */ vulkan_shader_resource_description_builder_t* render_set_bindings_builder; + bool is_destroy_render_set_bindings_builder; /* sub_render_set_bindings_internal */ bool is_render_set_bindings_internal; bool is_color_attachments_internal; @@ -44,7 +45,7 @@ typedef struct vulkan_subpass_create_info_builder_t BEGIN_CPP_COMPATIBLE RENDERER_API vulkan_subpass_create_info_builder_t* vulkan_subpass_create_info_builder_create(memory_allocator_t* allocator); -RENDERER_API void vulkan_subpass_create_info_destroy(vulkan_subpass_create_info_builder_t* builder); +RENDERER_API void vulkan_subpass_create_info_builder_destroy(vulkan_subpass_create_info_builder_t* builder); RENDERER_API void vulkan_subpass_create_info_builder_add(vulkan_subpass_create_info_builder_t* builder, u32 count); RENDERER_API void vulkan_subpass_create_info_builder_bind(vulkan_subpass_create_info_builder_t* builder, u32 index); @@ -54,7 +55,7 @@ RENDERER_API u32 vulkan_subpass_create_info_builder_get_count(vulkan_subpass_cre RENDERER_API void vulkan_subpass_create_info_builder_set_render_set_bindings(vulkan_subpass_create_info_builder_t* builder, vulkan_shader_resource_description_t* bindings, u32 binding_count); -RENDERER_API void vulkan_subpass_create_info_builder_set_render_set_bindings_builder(vulkan_subpass_create_info_builder_t* builder, vulkan_shader_resource_description_builder_t* srd_builder); +RENDERER_API void vulkan_subpass_create_info_builder_set_render_set_bindings_builder(vulkan_subpass_create_info_builder_t* builder, vulkan_shader_resource_description_builder_t* srd_builder, bool is_destroy); RENDERER_API void vulkan_subpass_create_info_builder_set_bind_point(vulkan_subpass_create_info_builder_t* builder, VkPipelineBindPoint bind_point); RENDERER_API void vulkan_subpass_create_info_builder_add_color_attachments(vulkan_subpass_create_info_builder_t* builder, VkAttachmentReference* attachments, u32 attachment_count); RENDERER_API void vulkan_subpass_create_info_builder_add_input_attachments(vulkan_subpass_create_info_builder_t* builder, VkAttachmentReference* attachments, u32 attachment_count); diff --git a/include/renderer/object.h b/include/renderer/object.h index f07a3b46..cc496da3 100644 --- a/include/renderer/object.h +++ b/include/renderer/object.h @@ -83,6 +83,7 @@ typedef enum object_type_t OBJECT_TYPE_VK_SWAPCHAIN, OBJECT_TYPE_EVENT, + OBJECT_TYPE_BUFFER2D_VIEW, OBJECT_TYPE_MAX, OBJECT_TYPE_VK_AMBIENT_LIGHT = OBJECT_TYPE_VK_LIGHT, diff --git a/source/renderer/buffer2d.c b/source/renderer/buffer2d.c index ebe00ecc..3b0df15c 100644 --- a/source/renderer/buffer2d.c +++ b/source/renderer/buffer2d.c @@ -71,12 +71,12 @@ RENDERER_API void buffer2d_create_no_alloc(memory_allocator_t* allocator, buffer buffer->is_backed_buffer_owner = false, buffer->resize_mode = create_info->resize_mode, - buffer->filled_rects = __hash_table_create(create_info->key_size, + buffer->filled_rects = __hash_table_create(allocator, create_info->key_size, sizeof(filled_rect_info_t), 128, create_info->key_comparer, create_info->key_hash_function), - buffer->vacant_rects = hash_table_create(rect2d_info_key_t, rect2d_info_t, 512, u32_equal_to, u32_hash), + buffer->vacant_rects = hash_table_create(allocator, rect2d_info_key_t, rect2d_info_t, 512, u32_equal_to, u32_hash), buffer->counter = 0; /* create 2d view if not supplied by the user */ @@ -418,7 +418,7 @@ RENDERER_API void buffer2d_resize(buffer2d_t* buffer, u32 num_rows, u32 num_colu .buffer = &old_backed_buffer }; buffer2d_view_t old_view; - buffer2d_view_create_no_alloc(buffer->allocator, &view_create_info, &old_view); + buffer2d_view_create_no_alloc_ext(buffer->allocator, &view_create_info, &old_view); /* resize the backed buffer (it will invalid the exisiting written data and vacant rects ) */ buffer2d_view_resize(view, num_rows, num_columns); @@ -439,6 +439,7 @@ RENDERER_API void buffer2d_resize(buffer2d_t* buffer, u32 num_rows, u32 num_colu /* destroy the old data */ buffer2d_view_destroy(&old_view); + buffer2d_view_release_resources(&old_view); buf_free(&old_backed_buffer); } @@ -500,7 +501,7 @@ RENDERER_API void buffer2d_dump(buffer2d_t* buffer, const char* file_name) AUTO size = buffer->view->size; /* allocate pixel data buffer */ - buffer_t pixel_data = buf_create(sizeof(icolor3_t), IEXTENT2D_AREA(size), 0); + buffer_t pixel_data = memory_allocator_buf_create(buffer->allocator, sizeof(icolor3_t), IEXTENT2D_AREA(size), 0); /* fill the pixel data buffer with WHITE color (as a background color) */ icolor3_t default_color = ICOLOR3_GREY; @@ -518,7 +519,7 @@ RENDERER_API void buffer2d_dump(buffer2d_t* buffer, const char* file_name) .buffer = &pixel_data }; buffer2d_view_t view; - buffer2d_view_create_no_alloc(buffer->allocator, &view_create_info, &view); + buffer2d_view_create_no_alloc_ext(buffer->allocator, &view_create_info, &view); /* write colors to the pixel data buffer */ @@ -533,6 +534,7 @@ RENDERER_API void buffer2d_dump(buffer2d_t* buffer, const char* file_name) /* destroy pixel data */ buffer2d_view_destroy(&view); + buffer2d_view_release_resources(&view); buf_free(&pixel_data); } #endif /* GLOBAL_DEBUG */ diff --git a/source/renderer/buffer2d_view.c b/source/renderer/buffer2d_view.c index 99e0bcdf..e4a04cac 100644 --- a/source/renderer/buffer2d_view.c +++ b/source/renderer/buffer2d_view.c @@ -30,6 +30,7 @@ RENDERER_API buffer2d_view_t* buffer2d_view_new(memory_allocator_t* allocator) { buffer2d_view_t* view = memory_allocator_alloc_obj(allocator, MEMORY_ALLOCATION_TYPE_OBJ_BUFFER2D_VIEW, buffer2d_view_t); memzero(view, buffer2d_view_t); + OBJECT_INIT(view, OBJECT_TYPE_BUFFER2D_VIEW, OBJECT_NATIONALITY_INTERNAL); return view; } @@ -42,7 +43,7 @@ RENDERER_API buffer2d_view_t* buffer2d_view_create(memory_allocator_t* allocator RENDERER_API void buffer2d_view_create_no_alloc(memory_allocator_t* allocator, buffer2d_view_create_info_t* create_info, buffer2d_view_t OUT view) { - memzero(view, buffer2d_view_t); + OBJECT_MEMZERO(view, buffer2d_view_t); view->allocator = allocator; view->size = create_info->size; @@ -57,7 +58,8 @@ RENDERER_API void buffer2d_view_destroy(buffer2d_view_t* view) RENDERER_API void buffer2d_view_release_resources(buffer2d_view_t* view) { - memory_allocator_dealloc(view->allocator, view); + if(OBJECT_IS_INTERNAL(view)) + memory_allocator_dealloc(view->allocator, view); } RENDERER_API void buffer2d_view_set_buffer(buffer2d_view_t* view, buffer_t* buffer) diff --git a/source/renderer/event.c b/source/renderer/event.c index 412dd571..35cadca8 100644 --- a/source/renderer/event.c +++ b/source/renderer/event.c @@ -319,7 +319,7 @@ static const char* signal_to_string(signal_bits_t bit) } } -CAN_BE_UNUSED_FUNCTION static char* signal_bits_to_string(memory_allocator_t* allocator, signal_bits_t bits) +CAN_BE_UNUSED_FUNCTION static string_builder_t* signal_bits_to_string(memory_allocator_t* allocator, signal_bits_t bits) { string_builder_t* builder = string_builder_create(allocator, 128); @@ -332,7 +332,7 @@ CAN_BE_UNUSED_FUNCTION static char* signal_bits_to_string(memory_allocator_t* al string_builder_append(builder, " | "); } } - return string_builder_get_str(builder); + return builder; } static void subscription_dump(memory_allocator_t* allocator, subscription_t* subscription, string_builder_t* builder) @@ -343,8 +343,12 @@ static void subscription_dump(memory_allocator_t* allocator, subscription_t* sub string_builder_append(builder, ".location = { %lu, %s, %s }\n", subscription->debug_info.line, subscription->debug_info.function_str, subscription->debug_info.file_str); string_builder_append(builder, ".handler = %s (%p)\n", subscription->invocation_data.handler.handler_str, subscription->invocation_data.handler.handler); string_builder_append(builder, ".handler_data = %p\n", subscription->invocation_data.handler_data); - string_builder_append(builder, ".wait_bits = %s\n", signal_bits_to_string(allocator, subscription->invocation_data.wait_bits)); - string_builder_append(builder, ".signal_bits = %s\n", signal_bits_to_string(allocator, subscription->invocation_data.signal_bits)); + string_builder_append(builder, ".wait_bits = "); + string_builder_append_builder_destroy(builder, signal_bits_to_string(allocator, subscription->invocation_data.wait_bits)); + string_builder_append_newline(builder); + string_builder_append(builder, ".signal_bits = "); + string_builder_append_builder_destroy(builder, signal_bits_to_string(allocator, subscription->invocation_data.signal_bits)); + string_builder_append_newline(builder); string_builder_append(builder, ".handle = %llu\n", subscription->handle); string_builder_decrement_indentation(builder); string_builder_append(builder, "}\n"); diff --git a/source/renderer/font.c b/source/renderer/font.c index dad4d58c..288be2b2 100644 --- a/source/renderer/font.c +++ b/source/renderer/font.c @@ -92,7 +92,7 @@ RENDERER_API void font_create_no_alloc(renderer_t* renderer, void* bytes, u64 le else font_set_char_size(font, 11); - font->glyph_info_table = hash_table_create(pair_t(utf32_t, u32), font_glyph_info_t, 128, utf32_u32_equal_to, utf32_u32_hash); + font->glyph_info_table = hash_table_create(renderer->allocator, pair_t(utf32_t, u32), font_glyph_info_t, 128, utf32_u32_equal_to, utf32_u32_hash); } RENDERER_API font_t* font_load_and_create(renderer_t* renderer, const char* file_name) diff --git a/source/renderer/hash_table.c b/source/renderer/hash_table.c index 5b970676..6e551895 100644 --- a/source/renderer/hash_table.c +++ b/source/renderer/hash_table.c @@ -26,7 +26,7 @@ #include #include // stack_alloc -RENDERER_API hash_table_t __hash_table_create(u32 key_size, u32 value_size, u32 capacity, comparer_t key_comparer, hash_function_t key_hash_function) +RENDERER_API hash_table_t __hash_table_create(memory_allocator_t* allocator, u32 key_size, u32 value_size, u32 capacity, comparer_t key_comparer, hash_function_t key_hash_function) { hash_table_t table = { @@ -35,7 +35,7 @@ RENDERER_API hash_table_t __hash_table_create(u32 key_size, u32 value_size, u32 .capacity = capacity, .get_hash = key_hash_function, .is_equal = key_comparer, - .bucket_handles = buf_create(sizeof(sub_buffer_handle_t), capacity, 0) + .bucket_handles = (allocator != NULL) ? memory_allocator_buf_create(allocator, sizeof(sub_buffer_handle_t), capacity, 0) : buf_create(sizeof(sub_buffer_handle_t), capacity, 0) }; /* create buffer to store hash table entries */ diff --git a/source/renderer/vulkan/vulkan_bitmap_glyph_atlas_texture.c b/source/renderer/vulkan/vulkan_bitmap_glyph_atlas_texture.c index 2b37a896..c70303c4 100644 --- a/source/renderer/vulkan/vulkan_bitmap_glyph_atlas_texture.c +++ b/source/renderer/vulkan/vulkan_bitmap_glyph_atlas_texture.c @@ -88,7 +88,7 @@ RENDERER_API void vulkan_bitmap_glyph_atlas_texture_destroy(vulkan_bitmap_glyph_ RENDERER_API void vulkan_bitmap_glyph_atlas_texture_release_resources(vulkan_bitmap_glyph_atlas_texture_t* texture) { - event_destroy(texture->on_resize_event); + event_release_resources(texture->on_resize_event); vulkan_host_buffered_texture_release_resources(BASE(texture)); if(VULKAN_OBJECT_IS_INTERNAL(texture)) memory_allocator_dealloc(texture->renderer->allocator, texture); diff --git a/source/renderer/vulkan/vulkan_host_buffered_texture.c b/source/renderer/vulkan/vulkan_host_buffered_texture.c index 2e9ff159..ed72bb58 100644 --- a/source/renderer/vulkan/vulkan_host_buffered_texture.c +++ b/source/renderer/vulkan/vulkan_host_buffered_texture.c @@ -82,7 +82,7 @@ RENDERER_API void vulkan_host_buffered_texture_create_no_alloc(vulkan_renderer_t .size = { create_info->width, create_info->height }, .buffer = vulkan_host_buffered_buffer_get_host_buffer(&texture->buffer), }; - buffer2d_view_create_no_alloc(renderer->allocator, &view_create_info, &texture->view); + buffer2d_view_create_no_alloc_ext(renderer->allocator, &view_create_info, &texture->view); } RENDERER_API void vulkan_host_buffered_texture_destroy(vulkan_host_buffered_texture_t* texture) @@ -94,6 +94,7 @@ RENDERER_API void vulkan_host_buffered_texture_destroy(vulkan_host_buffered_text RENDERER_API void vulkan_host_buffered_texture_release_resources(vulkan_host_buffered_texture_t* texture) { + buffer2d_view_release_resources(&texture->view); vulkan_texture_release_resources(BASE(texture)); if(VULKAN_OBJECT_IS_INTERNAL(texture)) memory_allocator_dealloc(texture->renderer->allocator, texture); diff --git a/source/renderer/vulkan/vulkan_render_pass_create_info_builder.c b/source/renderer/vulkan/vulkan_render_pass_create_info_builder.c index f3966e40..47b47c4b 100644 --- a/source/renderer/vulkan/vulkan_render_pass_create_info_builder.c +++ b/source/renderer/vulkan/vulkan_render_pass_create_info_builder.c @@ -29,6 +29,10 @@ RENDERER_API void vulkan_render_pass_create_info_builder_destroy(vulkan_render_p buf_free(&build_info->attachment_usages); if(build_info->is_supplementary_attachments_internal) memory_allocator_dealloc(builder->allocator, build_info->vo_supplementary_attachments); + if((build_info->render_set_bindings_builder != NULL) && build_info->is_destroy_render_set_bindings_builder) + vulkan_shader_resource_description_builder_destroy(build_info->render_set_bindings_builder); + if((build_info->subpasses_builder != NULL) && build_info->is_destroy_subpasses_builder) + vulkan_subpass_create_info_builder_destroy(build_info->subpasses_builder); } buf_free(&builder->build_info_array); memory_allocator_dealloc(builder->allocator, builder); @@ -180,10 +184,11 @@ RENDERER_API void vulkan_render_pass_create_info_builder_set_render_set_bindings build_info->is_use_render_set_bindings_builder = false; } -RENDERER_API void vulkan_render_pass_create_info_builder_set_render_set_bindings_builder(vulkan_render_pass_create_info_builder_t* builder, vulkan_shader_resource_description_builder_t* srd_builder) +RENDERER_API void vulkan_render_pass_create_info_builder_set_render_set_bindings_builder(vulkan_render_pass_create_info_builder_t* builder, vulkan_shader_resource_description_builder_t* srd_builder, bool is_destroy) { AUTO build_info = get_bound_build_info(builder); build_info->render_set_bindings_builder = srd_builder; + build_info->is_destroy_render_set_bindings_builder = is_destroy; build_info->is_use_render_set_bindings_builder = true; } @@ -196,10 +201,11 @@ RENDERER_API void vulkan_render_pass_create_info_builder_set_subpasses(vulkan_re build_info->is_use_subpasses_builder = false; } -RENDERER_API void vulkan_render_pass_create_info_builder_set_subpasses_builder(vulkan_render_pass_create_info_builder_t* builder, vulkan_subpass_create_info_builder_t* sci_builder) +RENDERER_API void vulkan_render_pass_create_info_builder_set_subpasses_builder(vulkan_render_pass_create_info_builder_t* builder, vulkan_subpass_create_info_builder_t* sci_builder, bool is_destroy) { AUTO build_info = get_bound_build_info(builder); build_info->subpasses_builder = sci_builder; + build_info->is_destroy_subpasses_builder = is_destroy; build_info->is_use_subpasses_builder = true; } diff --git a/source/renderer/vulkan/vulkan_render_queue.c b/source/renderer/vulkan/vulkan_render_queue.c index 0ff85e99..d95742b9 100644 --- a/source/renderer/vulkan/vulkan_render_queue.c +++ b/source/renderer/vulkan/vulkan_render_queue.c @@ -162,7 +162,11 @@ RENDERER_API void vulkan_render_queue_destroy_all_objects(vulkan_render_queue_t* // vulkan_render_object_destroy(DEREF_TO(vulkan_render_object_t*, buf_get_ptr_at(list, k))); for(u32 k = 0; k < count2; k++) - vulkan_render_object_destroy(DEREF_TO(vulkan_render_object_t*, buf_peek_ptr(list))); + { + AUTO obj = DEREF_TO(vulkan_render_object_t*, buf_peek_ptr(list)); + vulkan_render_object_destroy(obj); + vulkan_render_object_release_resources(obj); + } buf_clear(list, NULL); } } diff --git a/source/renderer/vulkan/vulkan_render_scene.c b/source/renderer/vulkan/vulkan_render_scene.c index c3a6a73d..6d6cadce 100644 --- a/source/renderer/vulkan/vulkan_render_scene.c +++ b/source/renderer/vulkan/vulkan_render_scene.c @@ -130,7 +130,7 @@ RENDERER_API void vulkan_render_scene_destroy(vulkan_render_scene_t* scene) u32 count = dictionary_get_count(&scene->queues); for(u32 i = 0; i < count; i++) { - vulkan_render_queue_t* queue = dictionary_get_value_ptr_at(&scene->queues, i); + vulkan_render_queue_t* queue = VULKAN_RENDER_QUEUE(dictionary_get_value_ptr_at(&scene->queues, i)); vulkan_render_queue_destroy_all_objects(queue); vulkan_render_queue_destroy(queue); } @@ -138,10 +138,9 @@ RENDERER_API void vulkan_render_scene_destroy(vulkan_render_scene_t* scene) RENDERER_API void vulkan_render_scene_release_resources(vulkan_render_scene_t* scene) { - // TODO - // u32 count = buf_get_count(&scene->queues); - // for(u32 i = 0; i < count; i++) - // vulkan_render_queue_release_resources(buf_get_ptr_at(&scene->queues, i)); + u32 count = dictionary_get_count(&scene->queues); + for(u32 i = 0; i < count; i++) + vulkan_render_queue_release_resources(VULKAN_RENDER_QUEUE(dictionary_get_value_ptr_at(&scene->queues, i))); dictionary_free(&scene->queues); if(VULKAN_OBJECT_IS_INTERNAL(scene)) memory_allocator_dealloc(scene->renderer->allocator, scene); @@ -195,7 +194,7 @@ RENDERER_API void vulkan_render_scene_render(vulkan_render_scene_t* scene, u64 q { AUTO queue_type = DEREF_TO(vulkan_render_queue_type_t, dictionary_get_key_ptr_at(&scene->queues, i)); if((BIT64(queue_type) & queue_mask) == BIT64(queue_type)) - vulkan_render_queue_dispatch(dictionary_get_value_ptr_at(&scene->queues, i), camera); + vulkan_render_queue_dispatch(VULKAN_RENDER_QUEUE(dictionary_get_value_ptr_at(&scene->queues, i)), camera); } } @@ -215,7 +214,7 @@ RENDERER_API vulkan_render_scene_object_handle_t vulkan_render_scene_create_obje buf_ucount_t queue_index = dictionary_find_index_of(&scene->queues, &REINTERPRET_TO(vulkan_render_queue_type_t, queue_type)); if(queue_index == DICTIONARY_INVALID_INDEX) LOG_FETAL_ERR("render scene doesn't contain the requested queue type %u\n", queue_type); - vulkan_render_queue_t* queue = dictionary_get_value_ptr_at(&scene->queues, queue_index); + vulkan_render_queue_t* queue = VULKAN_RENDER_QUEUE(dictionary_get_value_ptr_at(&scene->queues, queue_index)); _debug_assert__(sizeof(buf_ucount_t) == sizeof(vulkan_render_queue_handle_t)); vulkan_render_object_handle_t handle = vulkan_render_queue_add(queue, object); @@ -231,7 +230,7 @@ RENDERER_API vulkan_render_scene_object_handle_t vulkan_render_scene_create_obje RENDERER_API void vulkan_render_scene_destroy_objectH(vulkan_render_scene_t* scene, vulkan_render_scene_object_handle_t handle) { - vulkan_render_queue_t* queue = dictionary_get_value_ptr_at(&scene->queues, handle.queue_handle); + vulkan_render_queue_t* queue = VULKAN_RENDER_QUEUE(dictionary_get_value_ptr_at(&scene->queues, handle.queue_handle)); vulkan_render_queue_removeH(queue, handle.object_handle); } @@ -241,7 +240,7 @@ RENDERER_API void vulkan_render_scene_build_queues(vulkan_render_scene_t* scene) u32 count = dictionary_get_count(&scene->queues); for(u32 i = 0; i < count; i++) { - AUTO queue = CAST_TO(vulkan_render_queue_t*, dictionary_get_value_ptr_at(&scene->queues, i)); + AUTO queue = VULKAN_RENDER_QUEUE(dictionary_get_value_ptr_at(&scene->queues, i)); debug_log_info("Queue type: %s", vulkan_render_queue_type_str(queue->type)); vulkan_render_queue_build(queue); } diff --git a/source/renderer/vulkan/vulkan_shader.c b/source/renderer/vulkan/vulkan_shader.c index 0643a54c..d592cfc0 100644 --- a/source/renderer/vulkan/vulkan_shader.c +++ b/source/renderer/vulkan/vulkan_shader.c @@ -736,7 +736,7 @@ static vulkan_render_pass_create_info_builder_t* convert_render_pass_description _debug_assert__(pass->subpass_description_count > 0); vulkan_subpass_create_info_builder_t* subpass_builder = vulkan_subpass_create_info_builder_create(renderer->allocator); - vulkan_render_pass_create_info_builder_set_subpasses_builder(builder, subpass_builder); + vulkan_render_pass_create_info_builder_set_subpasses_builder(builder, subpass_builder, true); for(u32 i = 0; i < pass->subpass_count; i++) { vulkan_subpass_create_info_builder_add(subpass_builder, 1); diff --git a/source/renderer/vulkan/vulkan_subpass_create_info_builder.c b/source/renderer/vulkan/vulkan_subpass_create_info_builder.c index f60c2b6d..af98b5a9 100644 --- a/source/renderer/vulkan/vulkan_subpass_create_info_builder.c +++ b/source/renderer/vulkan/vulkan_subpass_create_info_builder.c @@ -14,7 +14,7 @@ RENDERER_API vulkan_subpass_create_info_builder_t* vulkan_subpass_create_info_bu return builder; } -RENDERER_API void vulkan_subpass_create_info_destroy(vulkan_subpass_create_info_builder_t* builder) +RENDERER_API void vulkan_subpass_create_info_builder_destroy(vulkan_subpass_create_info_builder_t* builder) { buf_free(&builder->create_info_array); u32 build_info_count = buf_get_element_count(&builder->build_info_array); @@ -24,6 +24,8 @@ RENDERER_API void vulkan_subpass_create_info_destroy(vulkan_subpass_create_info_ buf_free(&build_info->color_attachments); buf_free(&build_info->input_attachments); buf_free(&build_info->preserve_attachments); + if((build_info->render_set_bindings_builder != NULL) && build_info->is_destroy_render_set_bindings_builder) + vulkan_shader_resource_description_builder_destroy(build_info->render_set_bindings_builder); } buf_free(&builder->build_info_array); memory_allocator_dealloc(builder->allocator, builder); @@ -133,10 +135,11 @@ RENDERER_API void vulkan_subpass_create_info_builder_set_render_set_bindings(vul build_info->is_use_render_set_bindings_builder = false; } -RENDERER_API void vulkan_subpass_create_info_builder_set_render_set_bindings_builder(vulkan_subpass_create_info_builder_t* builder, vulkan_shader_resource_description_builder_t* srd_builder) +RENDERER_API void vulkan_subpass_create_info_builder_set_render_set_bindings_builder(vulkan_subpass_create_info_builder_t* builder, vulkan_shader_resource_description_builder_t* srd_builder, bool is_destroy) { AUTO build_info = get_bound_build_info(builder); build_info->render_set_bindings_builder = srd_builder; + build_info->is_destroy_render_set_bindings_builder = is_destroy; build_info->is_render_set_bindings_internal = false; build_info->is_use_render_set_bindings_builder = true; } diff --git a/source/tests/bitmap_text.c b/source/tests/bitmap_text.c index 0fe5332f..7cec86f8 100644 --- a/source/tests/bitmap_text.c +++ b/source/tests/bitmap_text.c @@ -99,7 +99,7 @@ static void test_hash_table() { /* hash table test */ - hash_table_t _table = hash_table_create(u64, u32, 5, u64_equal_to, u64_hash); + hash_table_t _table = hash_table_create(NULL, u64, u32, 5, u64_equal_to, u64_hash); u64 key = 40; u32 _value = 500; hash_table_add(&_table, &key, &_value); @@ -116,7 +116,7 @@ static void test_hash_table() hash_table_foreach(&_table, print_key_value_pair_i, NULL); hash_table_free(&_table); - hash_table_t table = hash_table_create(const char*, u32, 5, string_equal_to, string_hash); + hash_table_t table = hash_table_create(NULL, const char*, u32, 5, string_equal_to, string_hash); const char* str = "Hello World"; u32 value = 100; hash_table_add(&table, &str, &value); value = 200; @@ -197,7 +197,7 @@ static void test_buffer2d_view(renderer_t* renderer) .buffer = &pixels }; buffer2d_view_t view; - buffer2d_view_create_no_alloc(renderer->allocator, &view_create_info, &view); + buffer2d_view_create_no_alloc_ext(renderer->allocator, &view_create_info, &view); icolor3_t colors[IEXTENT2D_AREA(size)]; for(u32 i = 0; i < IEXTENT2D_AREA(size); i++) @@ -218,6 +218,7 @@ static void test_buffer2d_view(renderer_t* renderer) bmp_write(buf_get_ptr(&pixels), size.x, size.y, 3, "buffer2d_view.bmp"); buffer2d_view_destroy(&view); + buffer2d_view_release_resources(&view); buf_free(&pixels); } From 827c88369fcc6c2e6b852eded6948021fe845d4c Mon Sep 17 00:00:00 2001 From: ravi688 Date: Fri, 10 May 2024 20:24:32 +0530 Subject: [PATCH 4/6] [Memory Leak Fixes] Eliminated more memory leaks - Derived buffer2d_t from __OBJECT__ - Derived bitmap_glyph_pool_t from __OBJECT__ - Use BUFFER2D_VIEW() instead of CAST_TO() in buffer2d.c - Eliminated more memory leaks at various sites --- include/renderer/bitmap_glyph_pool.h | 11 ++++++++ include/renderer/buffer2d.h | 10 +++++++ include/renderer/buffer2d_view.h | 4 +-- include/renderer/object.h | 5 ++++ source/renderer/bitmap_glyph_pool.c | 8 +++--- source/renderer/buffer2d.c | 10 ++++--- .../vulkan_bitmap_glyph_atlas_texture.c | 3 ++- .../renderer/vulkan/vulkan_glyph_mesh_pool.c | 3 +-- source/renderer/vulkan/vulkan_render_queue.c | 27 +++---------------- source/tests/bitmap_text.c | 6 +++-- 10 files changed, 50 insertions(+), 37 deletions(-) diff --git a/include/renderer/bitmap_glyph_pool.h b/include/renderer/bitmap_glyph_pool.h index fa625c2b..21c9c04c 100644 --- a/include/renderer/bitmap_glyph_pool.h +++ b/include/renderer/bitmap_glyph_pool.h @@ -28,6 +28,7 @@ #include #include // font_t, utf32_t #include // buffer2d_t +#include #include /* stores texture coordinates of a glyph */ @@ -57,11 +58,15 @@ typedef struct bitmap_glyph_pool_create_info_t typedef struct bitmap_glyph_pool_t { + __OBJECT__; renderer_t* renderer; font_t* font; buffer2d_t pixels; } bitmap_glyph_pool_t; +#define BITMAP_GLYPH_POOL(ptr) OBJECT_UP_CAST(bitmap_glyph_pool_t*, OBJECT_TYPE_BITMAP_GLYPH_POOL, ptr) +#define BITMAP_GLYPH_POOL_CONST(ptr) OBJECT_UP_CAST_CONST(const bitmap_glyph_pool_t*, OBJECT_TYPE_BITMAP_GLYPH_POOL, ptr) + BEGIN_CPP_COMPATIBLE @@ -69,6 +74,12 @@ BEGIN_CPP_COMPATIBLE RENDERER_API bitmap_glyph_pool_t* bitmap_glyph_pool_new(memory_allocator_t* allocator); RENDERER_API bitmap_glyph_pool_t* bitmap_glyph_pool_create(renderer_t* renderer, bitmap_glyph_pool_create_info_t* create_info); RENDERER_API void bitmap_glyph_pool_create_no_alloc(renderer_t* renderer, bitmap_glyph_pool_create_info_t* create_info, bitmap_glyph_pool_t OUT pool); +static CAN_BE_UNUSED_FUNCTION INLINE_IF_RELEASE_MODE void bitmap_glyph_pool_create_no_alloc_ext(renderer_t* renderer, bitmap_glyph_pool_create_info_t* create_info, bitmap_glyph_pool_t OUT pool) +{ + OBJECT_INIT(pool, OBJECT_TYPE_BITMAP_GLYPH_POOL, OBJECT_NATIONALITY_EXTERNAL); + bitmap_glyph_pool_create_no_alloc(renderer, create_info, pool); +} + RENDERER_API void bitmap_glyph_pool_destroy(bitmap_glyph_pool_t* pool); RENDERER_API void bitmap_glyph_pool_release_resources(bitmap_glyph_pool_t* pool); diff --git a/include/renderer/buffer2d.h b/include/renderer/buffer2d.h index 4e4803b3..3f923773 100644 --- a/include/renderer/buffer2d.h +++ b/include/renderer/buffer2d.h @@ -31,6 +31,7 @@ #include // hash_table_t, comparer_t, hash_function_t #include // buffer2d_view_t, isize2d_t, ioffset2d_t #include // irect2d_t +#include #ifdef GLOBAL_DEBUG # include // color3_t @@ -99,6 +100,7 @@ typedef void (*packed_rect_relocate_callback_t)(const rect2d_info_t* before, con typedef struct buffer2d_t { + __OBJECT__; memory_allocator_t* allocator; #if DBG_ENABLED(BUFFER2D_RESIZE) @@ -128,12 +130,20 @@ typedef struct buffer2d_t typedef buffer2d_t* buffer2d_ptr_t; +#define BUFFER2D(ptr) OBJECT_UP_CAST(buffer2d_t*, OBJECT_TYPE_BUFFER2D, ptr) +#define BUFFER2D_CONST(ptr) OBJECT_UP_CAST_CONST(const buffer2d_t*, OBJECT_TYPE_BUFFER2D, ptr) + BEGIN_CPP_COMPATIBLE /* constructors and destructurs */ RENDERER_API buffer2d_t* buffer2d_new(memory_allocator_t* allocator); RENDERER_API buffer2d_t* buffer2d_create(memory_allocator_t* allocator, buffer2d_create_info_t* create_info); RENDERER_API void buffer2d_create_no_alloc(memory_allocator_t* allocator, buffer2d_create_info_t* create_info, buffer2d_t OUT buffer); +static CAN_BE_UNUSED_FUNCTION INLINE_IF_RELEASE_MODE void buffer2d_create_no_alloc_ext(memory_allocator_t* allocator, buffer2d_create_info_t* create_info, buffer2d_t OUT buffer) +{ + OBJECT_INIT(buffer, OBJECT_TYPE_BUFFER2D, OBJECT_NATIONALITY_EXTERNAL); + buffer2d_create_no_alloc(allocator, create_info, buffer); +} RENDERER_API void buffer2d_destroy(buffer2d_t* buffer); RENDERER_API void buffer2d_release_resources(buffer2d_t* buffer); diff --git a/include/renderer/buffer2d_view.h b/include/renderer/buffer2d_view.h index 8beaeb57..dcbc7416 100644 --- a/include/renderer/buffer2d_view.h +++ b/include/renderer/buffer2d_view.h @@ -48,8 +48,8 @@ typedef struct buffer2d_view_t typedef buffer2d_view_t* buffer2d_view_ptr_t; -#define BUFFER2D_VIEW(ptr) OBJECT_UP_CAST(buffer2d_view_t*, ptr) -#define BUFFER2D_VIEW_CONST(ptr) OBJECT_UP_CAST_CONST(const buffer2d_view_t*, ptr) +#define BUFFER2D_VIEW(ptr) OBJECT_UP_CAST(buffer2d_view_t*, OBJECT_TYPE_BUFFER2D_VIEW, ptr) +#define BUFFER2D_VIEW_CONST(ptr) OBJECT_UP_CAST_CONST(const buffer2d_view_t*, OBJECT_TYPE_BUFFER2D_VIEW, ptr) BEGIN_CPP_COMPATIBLE diff --git a/include/renderer/object.h b/include/renderer/object.h index cc496da3..cd816281 100644 --- a/include/renderer/object.h +++ b/include/renderer/object.h @@ -84,6 +84,8 @@ typedef enum object_type_t OBJECT_TYPE_EVENT, OBJECT_TYPE_BUFFER2D_VIEW, + OBJECT_TYPE_BUFFER2D, + OBJECT_TYPE_BITMAP_GLYPH_POOL, OBJECT_TYPE_MAX, OBJECT_TYPE_VK_AMBIENT_LIGHT = OBJECT_TYPE_VK_LIGHT, @@ -137,6 +139,9 @@ static CAN_BE_UNUSED_FUNCTION const char* object_type_to_string(object_type_t ty RETURN_STR_CASE(OBJECT_TYPE_VK_SHADER_LIBRARY); RETURN_STR_CASE(OBJECT_TYPE_VK_SWAPCHAIN); RETURN_STR_CASE(OBJECT_TYPE_EVENT); + RETURN_STR_CASE(OBJECT_TYPE_BUFFER2D_VIEW); + RETURN_STR_CASE(OBJECT_TYPE_BUFFER2D); + RETURN_STR_CASE(OBJECT_TYPE_BITMAP_GLYPH_POOL); RETURN_STR_CASE(OBJECT_TYPE_MAX); default: return ""; } diff --git a/source/renderer/bitmap_glyph_pool.c b/source/renderer/bitmap_glyph_pool.c index e6468846..b018e73f 100644 --- a/source/renderer/bitmap_glyph_pool.c +++ b/source/renderer/bitmap_glyph_pool.c @@ -32,6 +32,7 @@ RENDERER_API bitmap_glyph_pool_t* bitmap_glyph_pool_new(memory_allocator_t* allo { bitmap_glyph_pool_t* pool = memory_allocator_alloc_obj(allocator, MEMORY_ALLOCATION_TYPE_OBJ_BITMAP_GLYPH_POOL, bitmap_glyph_pool_t); memzero(pool, bitmap_glyph_pool_t); + OBJECT_INIT(pool, OBJECT_TYPE_BITMAP_GLYPH_POOL, OBJECT_NATIONALITY_INTERNAL); return pool; } @@ -44,7 +45,7 @@ RENDERER_API bitmap_glyph_pool_t* bitmap_glyph_pool_create(renderer_t* renderer, RENDERER_API void bitmap_glyph_pool_create_no_alloc(renderer_t* renderer, bitmap_glyph_pool_create_info_t* create_info, bitmap_glyph_pool_t OUT pool) { - memzero(pool, bitmap_glyph_pool_t); + OBJECT_MEMZERO(pool, bitmap_glyph_pool_t); pool->renderer = renderer; pool->font = create_info->font; buffer2d_create_info_t _create_info = @@ -57,7 +58,7 @@ RENDERER_API void bitmap_glyph_pool_create_no_alloc(renderer_t* renderer, bitmap .key_hash_function = utf32_u32_hash, .key_comparer = utf32_u32_equal_to }; - buffer2d_create_no_alloc(renderer->allocator, &_create_info, &pool->pixels); + buffer2d_create_no_alloc_ext(renderer->allocator, &_create_info, &pool->pixels); buffer2d_clear(&pool->pixels, NULL); } @@ -68,7 +69,8 @@ RENDERER_API void bitmap_glyph_pool_destroy(bitmap_glyph_pool_t* pool) RENDERER_API void bitmap_glyph_pool_release_resources(bitmap_glyph_pool_t* pool) { - memory_allocator_dealloc(pool->renderer->allocator, pool); + if(OBJECT_IS_INTERNAL(pool)) + memory_allocator_dealloc(pool->renderer->allocator, pool); } RENDERER_API bool bitmap_glyph_pool_get_texcoord(bitmap_glyph_pool_t* pool, pair_t(utf32_t, u32) unicode, glyph_texcoord_t OUT texcoord, bool OUT is_resized) diff --git a/source/renderer/buffer2d.c b/source/renderer/buffer2d.c index 3b0df15c..355e9a66 100644 --- a/source/renderer/buffer2d.c +++ b/source/renderer/buffer2d.c @@ -51,6 +51,7 @@ RENDERER_API buffer2d_t* buffer2d_new(memory_allocator_t* allocator) { buffer2d_t* buffer = memory_allocator_alloc_obj(allocator, MEMORY_ALLOCATION_TYPE_OBJ_BUFFER2D, buffer2d_t); memzero(buffer, buffer2d_t); + OBJECT_INIT(buffer, OBJECT_TYPE_BUFFER2D, OBJECT_NATIONALITY_INTERNAL); return buffer; } @@ -65,7 +66,7 @@ RENDERER_API void buffer2d_create_no_alloc(memory_allocator_t* allocator, buffer { debug_assert__(create_info->resize_mode == BUFFER2D_RESIZE_MODE_ASPECT_RATIO_STRICT, "For now we will only support BUFFER2D_RESIZE_MODE_ASPECT_RATIO_STRICT"); - memzero(buffer, buffer2d_t); + OBJECT_MEMZERO(buffer, buffer2d_t); buffer->allocator = allocator; @@ -127,7 +128,8 @@ RENDERER_API void buffer2d_release_resources(buffer2d_t* buffer) { if(buffer->is_view_owner) buffer2d_view_release_resources(buffer->view); - memory_allocator_dealloc(buffer->allocator, buffer); + if(OBJECT_IS_INTERNAL(buffer)) + memory_allocator_dealloc(buffer->allocator, buffer); } RENDERER_API buffer_t* buffer2d_get_backed_buffer(buffer2d_t* buffer) @@ -469,7 +471,7 @@ static void dump_filled_rect(void* key, void* value, void* user_data) AUTO _rect = irect2d(ioffset2d(rect->rect_info.rect.offset.x * sizeof(icolor3_t), rect->rect_info.rect.offset.y), iextent2d(rect->rect_info.rect.extent.x * sizeof(icolor3_t), rect->rect_info.rect.extent.y)); - buffer2d_view_broadcast_rect(CAST_TO(buffer2d_view_t*, user_data), _rect, &rect->color, sizeof(icolor3_t)); + buffer2d_view_broadcast_rect(BUFFER2D_VIEW(user_data), _rect, &rect->color, sizeof(icolor3_t)); } static icolor3_t vacant_colors[] = @@ -492,7 +494,7 @@ static void dump_vacant_rect(void* key, void* value, void* user_data) static u32 counter = 0; ++counter; - buffer2d_view_broadcast_rect(CAST_TO(buffer2d_view_t*, user_data), _rect, &vacant_colors[counter % SIZEOF_ARRAY(vacant_colors)], sizeof(icolor3_t)); + buffer2d_view_broadcast_rect(BUFFER2D_VIEW(user_data), _rect, &vacant_colors[counter % SIZEOF_ARRAY(vacant_colors)], sizeof(icolor3_t)); } RENDERER_API void buffer2d_dump(buffer2d_t* buffer, const char* file_name) diff --git a/source/renderer/vulkan/vulkan_bitmap_glyph_atlas_texture.c b/source/renderer/vulkan/vulkan_bitmap_glyph_atlas_texture.c index c70303c4..e725045b 100644 --- a/source/renderer/vulkan/vulkan_bitmap_glyph_atlas_texture.c +++ b/source/renderer/vulkan/vulkan_bitmap_glyph_atlas_texture.c @@ -74,7 +74,7 @@ RENDERER_API void vulkan_bitmap_glyph_atlas_texture_create_no_alloc(vulkan_rende .buffer = vulkan_host_buffered_texture_get_host_buffer(BASE(texture)), .view = vulkan_host_buffered_texture_get_view(BASE(texture)) }; - bitmap_glyph_pool_create_no_alloc(RENDERER(renderer), &bgp_create_info, &texture->pool); + bitmap_glyph_pool_create_no_alloc_ext(RENDERER(renderer), &bgp_create_info, &texture->pool); texture->on_resize_event = event_create(renderer->allocator, texture PARAM_IF_DEBUG("Vulkan-Glyph-Atlas-Texture-Resize")); } @@ -89,6 +89,7 @@ RENDERER_API void vulkan_bitmap_glyph_atlas_texture_destroy(vulkan_bitmap_glyph_ RENDERER_API void vulkan_bitmap_glyph_atlas_texture_release_resources(vulkan_bitmap_glyph_atlas_texture_t* texture) { event_release_resources(texture->on_resize_event); + bitmap_glyph_pool_release_resources(&texture->pool); vulkan_host_buffered_texture_release_resources(BASE(texture)); if(VULKAN_OBJECT_IS_INTERNAL(texture)) memory_allocator_dealloc(texture->renderer->allocator, texture); diff --git a/source/renderer/vulkan/vulkan_glyph_mesh_pool.c b/source/renderer/vulkan/vulkan_glyph_mesh_pool.c index d9387204..36ca8cec 100644 --- a/source/renderer/vulkan/vulkan_glyph_mesh_pool.c +++ b/source/renderer/vulkan/vulkan_glyph_mesh_pool.c @@ -65,7 +65,7 @@ RENDERER_API void vulkan_glyph_mesh_pool_destroy(vulkan_glyph_mesh_pool_t* pool) RENDERER_API void vulkan_glyph_mesh_pool_release_resources(vulkan_glyph_mesh_pool_t* pool) { for(u64 i = 0; i < dictionary_get_count(&pool->glyph_meshes); i++) - vulkan_mesh_release_resources(CAST_TO(vulkan_glyph_mesh_t*, dictionary_get_value_ptr_at(&pool->glyph_meshes, i))->mesh); + vulkan_mesh_release_resources(VULKAN_MESH(CAST_TO(vulkan_glyph_mesh_t*, dictionary_get_value_ptr_at(&pool->glyph_meshes, i))->mesh)); dictionary_clear(&pool->glyph_meshes); if(VULKAN_OBJECT_IS_INTERNAL(pool)) @@ -95,7 +95,6 @@ RENDERER_API vulkan_mesh_t* vulkan_glyph_mesh_pool_get_mesh(vulkan_glyph_mesh_po * So, if the renderer interface chooses an opengl implementation of this function then calling * this function from the vulkan API backend will result in data corruption. * However, to get the intended results one needs to link compatible API backend with the rendering interface. */ - RDR_OBJECT_INIT(mesh, RDR_OBJECT_TYPE_MESH, RDR_OBJECT_NATIONALITY_EXTERNAL); mesh_create_no_alloc(pool->renderer->renderer, mesh3d, MESH(mesh)); diff --git a/source/renderer/vulkan/vulkan_render_queue.c b/source/renderer/vulkan/vulkan_render_queue.c index d95742b9..200e8ef7 100644 --- a/source/renderer/vulkan/vulkan_render_queue.c +++ b/source/renderer/vulkan/vulkan_render_queue.c @@ -83,8 +83,8 @@ RENDERER_API void vulkan_render_queue_destroy(vulkan_render_queue_t* queue) subpass_shader_list_t* lists = DEREF_TO(subpass_shader_list_t*, dictionary_get_value_ptr_at(&queue->render_pass_handles, i)); u32 subpass_count = vulkan_render_pass_pool_getH(queue->renderer->render_pass_pool, DEREF_TO(vulkan_render_pass_handle_t, dictionary_get_key_ptr_at(&queue->render_pass_handles, i)))->subpass_count; for(u32 j = 0; j < subpass_count; j++) - buf_clear(&lists[j], NULL); - // heap_free(list); + buf_free(&lists[i]); + memory_allocator_dealloc(queue->renderer->allocator, lists); } dictionary_clear(&queue->render_pass_handles); @@ -104,9 +104,9 @@ RENDERER_API void vulkan_render_queue_destroy(vulkan_render_queue_t* queue) obj->queue = NULL; obj->handle = VULKAN_RENDER_OBJECT_HANDLE_INVALID; } - buf_clear(list, NULL); + buf_free(list); } - dictionary_clear(map); + dictionary_free(map); } dictionary_clear(&queue->shader_handles); @@ -118,26 +118,7 @@ RENDERER_API void vulkan_render_queue_destroy(vulkan_render_queue_t* queue) RENDERER_API void vulkan_render_queue_release_resources(vulkan_render_queue_t* queue) { - buf_ucount_t count = dictionary_get_count(&queue->render_pass_handles); - for(buf_ucount_t i = 0; i < count; i++) - { - subpass_shader_list_t* list = DEREF_TO(subpass_shader_list_t*, dictionary_get_value_ptr_at(&queue->render_pass_handles, i)); - u32 subpass_count = vulkan_render_pass_pool_getH(queue->renderer->render_pass_pool, DEREF_TO(vulkan_render_pass_handle_t, dictionary_get_key_ptr_at(&queue->render_pass_handles, i)))->subpass_count; - for(u32 j = 0; j < subpass_count; j++) - buf_free(&list[i]); - memory_allocator_dealloc(queue->renderer->allocator, list); - } dictionary_free(&queue->render_pass_handles); - - count = dictionary_get_count(&queue->shader_handles); - for(buf_ucount_t i = 0; i < count; i++) - { - material_and_render_object_list_map_t* map = dictionary_get_value_ptr_at(&queue->shader_handles, i); - buf_ucount_t count1 = dictionary_get_count(map); - for(buf_ucount_t j = 0; j < count1; j++) - buf_free(dictionary_get_value_ptr_at(map, i)); - dictionary_free(map); - } dictionary_free(&queue->shader_handles); vulkan_render_pass_graph_release_resources(&queue->pass_graph); diff --git a/source/tests/bitmap_text.c b/source/tests/bitmap_text.c index 7cec86f8..485c2d48 100644 --- a/source/tests/bitmap_text.c +++ b/source/tests/bitmap_text.c @@ -466,7 +466,7 @@ static void test_buffer2d(renderer_t* renderer) .key_hash_function = u32_hash }; buffer2d_t buffer; - buffer2d_create_no_alloc(renderer->allocator, &create_info, &buffer); + buffer2d_create_no_alloc_ext(renderer->allocator, &create_info, &buffer); u32 input_count = SIZEOF_ARRAY(inputs); for(u32 i = 0; i < input_count; i++) @@ -480,6 +480,7 @@ static void test_buffer2d(renderer_t* renderer) debug_log_info("Packing Efficientcy: %f", buffer2d_get_packing_efficiency(&buffer)); buffer2d_destroy(&buffer); + buffer2d_release_resources(&buffer); } static void test_glyph_rasterization(renderer_t* renderer) @@ -549,7 +550,7 @@ static void test_buffer2d_backed_buffer_dump(renderer_t* renderer) .key_hash_function = u32_hash }; buffer2d_t bitmap; - buffer2d_create_no_alloc(renderer->allocator, &create_info, &bitmap); + buffer2d_create_no_alloc_ext(renderer->allocator, &create_info, &bitmap); u8 default_color = 255; buffer2d_clear(&bitmap, (void*)&default_color); @@ -564,6 +565,7 @@ static void test_buffer2d_backed_buffer_dump(renderer_t* renderer) bmp_write(ptr, bitmap.view->size.x / sizeof(icolor3_t), bitmap.view->size.y, 3, "test_buffer2d_backed_buffer_dump.bmp"); buffer2d_destroy(&bitmap); + buffer2d_release_resources(&bitmap); } static void test_glyph_packing(renderer_t* renderer) From 20d9bcb088a16ff1d0672af345be9d9a17fc34e1 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Fri, 10 May 2024 20:45:37 +0530 Subject: [PATCH 5/6] [Fix] set is_supplementary_attachments_internal to true - set is_supplementary_attachments_internal to true in vulkan_render_pass_create_info_builder_set_supplementary_attachment_bucket --- .../renderer/vulkan/vulkan_render_pass_create_info_builder.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/renderer/vulkan/vulkan_render_pass_create_info_builder.c b/source/renderer/vulkan/vulkan_render_pass_create_info_builder.c index 47b47c4b..de5b3b66 100644 --- a/source/renderer/vulkan/vulkan_render_pass_create_info_builder.c +++ b/source/renderer/vulkan/vulkan_render_pass_create_info_builder.c @@ -150,7 +150,10 @@ RENDERER_API void vulkan_render_pass_create_info_builder_set_supplementary_attac build_info->is_supplementary_attachments_internal = false; } if(create_info->framebuffer_layout_description.supplementary_attachment_count > 0) + { build_info->vo_supplementary_attachments = memory_allocator_alloc_obj_array(builder->allocator, MEMORY_ALLOCATION_TYPE_OBJ_VKAPI_IMAGE_VIEW_ARRAY, VkImageView, create_info->framebuffer_layout_description.supplementary_attachment_count); + build_info->is_supplementary_attachments_internal = true; + } else build_info->vo_supplementary_attachments = NULL; } From f02d5a44db7eaedf1c5a50bad717dfa1a51d2454 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Fri, 10 May 2024 20:46:51 +0530 Subject: [PATCH 6/6] [Memory Leak Fix] Eliminated memory leaks in CUBE, and TID_48_CASE_5 - destory mesh3d_t objects. --- source/tests/TID-48.case5.c | 8 ++++++-- source/tests/cube.c | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/source/tests/TID-48.case5.c b/source/tests/TID-48.case5.c index ef22b97a..58f1567d 100644 --- a/source/tests/TID-48.case5.c +++ b/source/tests/TID-48.case5.c @@ -121,12 +121,16 @@ TEST_ON_INITIALIZE(TID_48_CASE_5) "shaders/builtins/color_present.sb"), "ColorPresentMaterial")); material_set_vec4(this->colorPresentMaterial, "parameters.color", vec4(1.0, 1.0, 1.0, 1.0)); - this->mesh = mesh_create(renderer, mesh3d_cube(renderer->allocator, 1)); + AUTO cube_mesh_3d = mesh3d_cube(renderer->allocator, 1); + this->mesh = mesh_create(renderer, cube_mesh_3d); + mesh3d_destroy(cube_mesh_3d); this->render_object = render_scene_getH(this->scene, render_scene_create_object(this->scene, RENDER_OBJECT_TYPE_MESH, RENDER_QUEUE_TYPE_GEOMETRY)); render_object_set_material(this->render_object, this->material); render_object_attach(this->render_object, this->mesh); - this->quadMesh = mesh_create(renderer, mesh3d_plane(renderer->allocator, 1)); + AUTO plane_mesh_3d = mesh3d_plane(renderer->allocator, 1); + this->quadMesh = mesh_create(renderer, plane_mesh_3d); + mesh3d_destroy(plane_mesh_3d); this->quadObject = render_scene_getH(this->scene, render_scene_create_object(this->scene, RENDER_OBJECT_TYPE_MESH, RENDER_QUEUE_TYPE_GEOMETRY_LAST)); render_object_set_material(this->quadObject, this->depthPresentMaterial); render_object_attach(this->quadObject, this->quadMesh); diff --git a/source/tests/cube.c b/source/tests/cube.c index f87be46c..6663f533 100644 --- a/source/tests/cube.c +++ b/source/tests/cube.c @@ -83,6 +83,7 @@ TEST_ON_INITIALIZE(CUBE) AUTO cubeMeshData = mesh3d_cube(renderer->allocator, 1); this->mesh = mesh_create(renderer, cubeMeshData); + mesh3d_destroy(cubeMeshData); this->render_object = render_scene_getH(this->scene, render_scene_create_object(this->scene, RENDER_OBJECT_TYPE_MESH, RENDER_QUEUE_TYPE_GEOMETRY)); render_object_set_material(this->render_object, this->material); render_object_attach(this->render_object, this->mesh);