From 1a45c2295259706ffb09e3f2b20701424e000f30 Mon Sep 17 00:00:00 2001 From: Andreew Gregory Date: Thu, 13 Nov 2025 18:24:44 +0300 Subject: [PATCH] saving progress. Wrote __get_rid_of_memory_occupant method --- src/l1/anne/margaret/margaret_misc.h | 1 + src/l2/margaret/vulkan_memory_claire.h | 134 ++++++++++++++++++++++++- 2 files changed, 130 insertions(+), 5 deletions(-) diff --git a/src/l1/anne/margaret/margaret_misc.h b/src/l1/anne/margaret/margaret_misc.h index 90dec03..8a686a3 100644 --- a/src/l1/anne/margaret/margaret_misc.h +++ b/src/l1/anne/margaret/margaret_misc.h @@ -29,6 +29,7 @@ void generate_margaret_eve_for_vulkan_utils() { /* For l2/margaret/vulkan_memory_claire.h */ generate_eve_span_company_for_primitive(l, ns, cstr("MargaretBufferKindDescription"), false, true); generate_eve_span_company_for_primitive(l, ns, cstr("MargaretOldBufferResizeRecord"), true, false); + generate_eve_span_company_for_primitive(l, ns, cstr("MargaretResizeToNascentRecord"), true, false); generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){ /* We won't need to clone this type, like, at all... It is actually clonable, but we just made * it non-clonable */ diff --git a/src/l2/margaret/vulkan_memory_claire.h b/src/l2/margaret/vulkan_memory_claire.h index f6074c6..7655b28 100644 --- a/src/l2/margaret/vulkan_memory_claire.h +++ b/src/l2/margaret/vulkan_memory_claire.h @@ -202,7 +202,7 @@ typedef struct { typedef struct { VkImage image; U64 offset_in_device_memory_nubble; - U16 memory_allocation_id; + U32 memory_allocation_id; } MargaretMemAllocatorImagePosition; typedef MargaretMemAllocatorSubBufferPosition* MargaretMemAllocatorRequestFreeSubBuffer; @@ -457,6 +457,16 @@ typedef struct{ } MargaretOldBufferResizeRecord; #include "../../../gen/l1/eve/margaret/VecMargaretOldBufferResizeRecord.h" + +typedef struct { + U32 old_mem_block_id; + U64 old_start; + U64 old_len; + U64 offset_in_nascent_buffer; +} MargaretResizeToNascentRecord; +#include "../../../gen/l1/eve/margaret/VecMargaretResizeToNascentRecord.h" + + #include "../../../gen/l1/VecAndSpan_U8.h" /* Superstructure for managing free segments of memory of some type in ALL BLOCKS */ @@ -557,6 +567,103 @@ void MargaretMemAllocator__erase_free_space_for_subbufers( } } +/* Not in a dedicated buffer, just in general memory */ +void MargaretMemAllocator__erase_free_space_in_memory( + MargaretMemAllocator* self, U64 start, U64 len, U32 dev_mem_block){ + if (len == 0) + return; + MargaretMemFreeSpaceManager* man = &self->mem_free_space; + assert(man->set_present.len > 0); + for (size_t aj = 0; aj < man->set_present.len; aj++) { + U8 alignment = man->set_present.buf[aj]; + assert(alignment < MARGARET_ALLOC_LIMIT_ALIGNMENT_EXP); + assert(man->free_space_in_memory[alignment].variant == Option_Some); + bool eret = BuffRBTreeByLenRespAlign_SetMargaretFreeMemSegment_erase(& + man->free_space_in_memory[alignment].some, &(MargaretFreeMemSegment){start, len, dev_mem_block}); + assert(eret); + } +} + +void MargaretMemAllocator__insert_free_space_in_memory( + MargaretMemAllocator* self, U64 start, U64 len, U32 dev_mem_block){ + assert(len > 0); + MargaretMemFreeSpaceManager* man = &self->mem_free_space; + assert(man->set_present.len > 0); /* MargaretMemFreeSpaceManager will do that for us with 2^3 */ + for (size_t aj = 0; aj < man->set_present.len; aj++) { + U8 alignment = man->set_present.buf[aj]; + assert(alignment < MARGARET_ALLOC_LIMIT_ALIGNMENT_EXP); + assert(man->free_space_in_memory[alignment].variant == Option_Some); + bool iret = BuffRBTreeByLenRespAlign_SetMargaretFreeMemSegment_insert(& + man->free_space_in_memory[alignment].some, (MargaretFreeMemSegment){start, len, dev_mem_block}); + assert(iret); + } +} + +// void MargaretFreeMemSegment + +/* If mem occupant in question is VkBuffer, it won't delete anything from the set of available free mem segments + * for that buffer kindred. It is your job to remove free buffer subsegments from this set*/ +void MargaretMemAllocator__get_rid_of_memory_occupant( + MargaretMemAllocator* self, U32 mem_block_id, U64 occ_it){ + MargaretMemAllocatorOneBlock* block = VecMargaretMemAllocatorOneBlock_mat(&self->blocks, mem_block_id); + assert(0 < occ_it && occ_it < block->occupied_memory.tree.len); + + U64 occ_start = block->occupied_memory.el.buf[occ_it - 1].key; + /* We are doing silent pop. But right now we only copied buf occ, we will pop it silently at the end */ + MargaretMemoryOccupation occ = block->occupied_memory.el.buf[occ_it - 1].value; + + /* Updating block usage counter */ + block->occupation_counter -= occ.taken_size; + + U64 left_free_space_start, left_free_space_length; + + U64 prev_occ_it = BuffRBTree_MapU64ToMargaretMemoryOccupation_find_prev(&block->occupied_memory, occ_it); + if (prev_occ_it != 0) { + U64 prev_occ_start; + const MargaretMemoryOccupation* prev_occ; + BuffRBTree_MapU64ToMargaretMemoryOccupation_at_iter(&block->occupied_memory, prev_occ_it, &prev_occ_start, &prev_occ); + assert(prev_occ_start + prev_occ->taken_size <= occ_start); + left_free_space_start = prev_occ_start + prev_occ->taken_size; + left_free_space_length = occ_start - (prev_occ_start + prev_occ->taken_size); + } else { + left_free_space_start = 0; + left_free_space_length = occ_start; + } + + U64 right_free_space_start, right_free_space_length; + + U64 next_occ_it = BuffRBTree_MapU64ToMargaretMemoryOccupation_find_next(&block->occupied_memory, occ_it); + if (next_occ_it != 0) { + U64 next_occ_start; + const MargaretMemoryOccupation* next_occ; + BuffRBTree_MapU64ToMargaretMemoryOccupation_at_iter(&block->occupied_memory, next_occ_it, &next_occ_start, &next_occ); + assert(occ_start + occ.taken_size <= next_occ_start); + right_free_space_start = occ_start + occ.taken_size; + right_free_space_length = next_occ_start - (occ_start + occ.taken_size); + } else { + right_free_space_start = occ_start + occ.taken_size; + right_free_space_length = block->length - (occ_start + occ.taken_size); + } + + /* All these iterators and pointers will get invalidated */ + BuffRBTree_MapU64ToMargaretMemoryOccupation_empty_index_erase(&block->occupied_memory, occ_it); + /* All these iterators and pointers just got invalidated */ + if (occ.variant == MargaretMemoryOccupation_Buffer) { + vkDestroyBuffer(self->device, occ.buf.buffer, NULL); + } else { + vkDestroyImage(self->device, occ.img.image, NULL); + } + MargaretMemoryOccupation_drop(occ); + /* Occ is out of the game. And invalidated */ + + + MargaretMemAllocator__erase_free_space_in_memory(self, left_free_space_start, left_free_space_length, mem_block_id); + MargaretMemAllocator__erase_free_space_in_memory(self, right_free_space_start, right_free_space_length, mem_block_id); + + U64 LEN = right_free_space_start + right_free_space_length - left_free_space_start; + MargaretMemAllocator__insert_free_space_in_memory(self, left_free_space_start, LEN, mem_block_id); +} + /* Don't forget that all the iterators for MMA maps for buffers and sets for free space just got invalidated */ void MargaretMemAllocator__get_rid_of_sub_buffer(MargaretMemAllocator* self, U32 mem_block_id, U64 start){ MargaretMemAllocatorOneBlock* block = VecMargaretMemAllocatorOneBlock_mat(&self->blocks, mem_block_id); @@ -621,12 +728,12 @@ void MargaretMemAllocator__get_rid_of_sub_buffer(MargaretMemAllocator* self, U32 if (buf->subbuffers.el.len == 0) { /* We don't actually need to add the BIG free memory segment because we are already deleting the whole buffer */ - // todo: уебать буффер + MargaretMemAllocator__get_rid_of_memory_occupant(self, mem_block_id, occ_it); } else { + U64 LEN = right_free_space_start + right_free_space_length - left_free_space_start; + assert(LEN > 0); bool iret = BuffRBTreeByLen_SetMargaretFreeMemSegment_insert(&kindred->free_space_inside_buffers, - (MargaretFreeMemSegment){.start = left_free_space_start, - .len = right_free_space_start + right_free_space_length - left_free_space_start, - .dev_mem_block = mem_block_id}); + (MargaretFreeMemSegment){.start = left_free_space_start, .len = LEN, .dev_mem_block = mem_block_id}); assert(iret); } } @@ -672,6 +779,23 @@ void MargaretMemAllocator_drop(MargaretMemAllocator self){ MargaretMemAllocatorDemands MargaretMemAllocator_carry_out_request( MargaretMemAllocator* self, VkCommandBuffer cmd_buff, MargaretMemAllocatorRequest* request ){ + MargaretMemAllocator_wipe_old(self); + for (size_t i = 0; i < request->free_subbuffer.len; i++) { + MargaretMemAllocatorSubBufferPosition* req = request->free_subbuffer.buf[i]; + MargaretMemAllocator__get_rid_of_sub_buffer(self, req->memory_allocation_id, req->offset_in_device_memory_nubble); + } + for (size_t i = 0; i < request->free_image.len; i++) { + MargaretMemAllocatorImagePosition* req = request->free_image.buf[i]; + MargaretMemAllocatorOneBlock* block = VecMargaretMemAllocatorOneBlock_mat(&self->blocks, req->memory_allocation_id); + U64 occ_it = BuffRBTree_MapU64ToMargaretMemoryOccupation_find(&block->occupied_memory, req->offset_in_device_memory_nubble); + MargaretMemAllocator__get_rid_of_memory_occupant(self, req->memory_allocation_id, occ_it); + } + /* We iterate even over those buffer kinds, that we don't use. It is okay, there won't be alot of buffer kinds + * ,and we tend to use all of them */ + for (U16 bk = 0; bk < (U16)self->buffer_types.len; bk++) { + MargaretBufferKindInfo* kindred = &self->buffer_types.buf[bk]; + + } return 0; }