diff --git a/src/l1/anne/margaret/margaret_misc.h b/src/l1/anne/margaret/margaret_misc.h index 5e0b6b2..662a839 100644 --- a/src/l1/anne/margaret/margaret_misc.h +++ b/src/l1/anne/margaret/margaret_misc.h @@ -27,50 +27,53 @@ 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_eve_span_company_for_primitive(l, ns, cstr("MargaretSubBufRelocationRequest"), true, false); - generate_eve_span_company_for_non_primitive_non_clonable(l, ns, cstr("VecMargaretSubBufRelocationRequest"), 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 */ - .T = cstr("BufRBTreeByLenRespAlign_SetMargaretFreeMemSegment") - }); - generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){ - .T = cstr("MargaretMemAllocatorOneBlock"), .vec = true, - }); - generate_eve_span_company_for_non_primitive_non_clonable(l, ns, cstr("MargaretBufferKindInfo"), true, false); + /* It is actually an integer (pointer) */ + generate_eve_span_company_for_non_primitive_non_clonable(l, ns, cstr("MargaretMemAllocatorOneBlock"), true, false); - generate_eve_span_company_for_non_primitive_non_clonable(l, ns, cstr("KVPU64ToMargaretMemoryOccupation"), true, false); - generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){ - .T = cstr("MargaretMemoryOccupation")}); - generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){ - .T = cstr("RefMargaretMemoryOccupation"), .t_ptr = true}); - generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){ - .T = cstr("RefMutMargaretMemoryOccupation"), .t_ptr = true}); - - generate_eve_span_company_for_primitive(l, ns, cstr("KVPU64ToMargaretBufferOccupationSubBuffer"), true, false); - generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){ - .T = cstr("MargaretBufferOccupationSubBuffer"), .t_primitive = true}); - generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){ - .T = cstr("RefMargaretBufferOccupationSubBuffer"), .t_ptr = true}); - generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){ - .T = cstr("RefMutMargaretBufferOccupationSubBuffer"), .t_ptr = true}); + generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorRequestFreeOccupant"), true, false); + generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorRequestResizeBuffer"), true, false); + generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorRequestAllocBuffer"), true, false); + generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorRequestAllocImage"), true, false); generate_eve_span_company_for_primitive(l, ns, cstr("MargaretFreeMemSegment"), true, false); generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){ .T = cstr("MargaretFreeMemSegment"), .t_primitive = true}); - generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorRequestFreeSubBuffer"), true, false); - generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorRequestFreeImage"), true, false); - generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){ - .T = cstr("MargaretMemAllocatorRequestResizeSubBuffer"), .t_primitive = true, .vec_extended = true}); - generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorRequestAllocSubBuffer"), true, false); - generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorRequestAllocImage"), true, false); - generate_eve_span_company_for_non_primitive_non_clonable(l, ns, - cstr("MargaretMemAllocatorRequestsForCertainBufferKindAllocation"), true, false); + generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){ + .T = cstr("BufRBTreeByLenRespAlign_SetMargaretFreeMemSegment")}); + + // generate_eve_span_company_for_primitive(l, ns, cstr("MargaretOldBufferResizeRecord"), true, false); + // generate_eve_span_company_for_primitive(l, ns, cstr("MargaretBufRelocationRequest"), 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 */ + // .T = cstr("BufRBTreeByLenRespAlign_SetMargaretFreeMemSegment") + // }); + // generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){ + // .T = cstr("MargaretMemAllocatorOneBlock"), .vec = true, + // }); + // + // generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){ + // .T = cstr("MargaretMemoryOccupation")}); + // generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){ + // .T = cstr("RefMargaretMemoryOccupation"), .t_ptr = true}); + // generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){ + // .T = cstr("RefMutMargaretMemoryOccupation"), .t_ptr = true}); + // + // generate_eve_span_company_for_primitive(l, ns, cstr("MargaretFreeMemSegment"), true, false); + // generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){ + // .T = cstr("MargaretFreeMemSegment"), .t_primitive = true}); + // + // generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorRequestFreeBuffer"), true, false); + // generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorRequestFreeImage"), true, false); + // generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){ + // .T = cstr("MargaretMemAllocatorRequestResizeBuffer"), .t_primitive = true, .vec_extended = true}); + // generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorRequestAllocBuffer"), true, false); + // generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorRequestAllocImage"), true, false); + // generate_eve_span_company_for_non_primitive_non_clonable(l, ns, + // cstr("MargaretMemAllocatorRequestsForCertainBufferKindAllocation"), true, false); } diff --git a/src/l1_5/anne/margaret.h b/src/l1_5/anne/margaret.h index e3b36ad..fe11dc9 100644 --- a/src/l1_5/anne/margaret.h +++ b/src/l1_5/anne/margaret.h @@ -10,11 +10,6 @@ void generate_l1_5_template_instantiations_for_margaret(){ mkdir_nofail("l1_5/eve/margaret"); /* For MargaretMemAllocator */ - generate_buf_rbtree_Set_templ_inst_eve_header(l, ns, (set_instantiation_op){ - .T = cstr("MargaretFreeMemSegment"), .t_primitive = true, - .alternative_less = cstr("MargaretFreeMemSegment_less"), - .alternative_comp_set_name_embed = cstr("Len"), - }); generate_buf_rbtree_Set_templ_inst_eve_header(l, ns, (set_instantiation_op){ .T = cstr("MargaretFreeMemSegment"), .t_primitive = true, /* comparison takes additional U8 parameter */ @@ -23,12 +18,8 @@ void generate_l1_5_template_instantiations_for_margaret(){ .guest_data_T = cstr("U8"), }); generate_rbtree_Map_templ_inst_eve_header(l, ns, (map_instantiation_op){ - /* MargaretMemoryOccupation is not primitive */ - .K = cstr("U64"), .k_integer = true, .V = cstr("MargaretMemoryOccupation"), + .K = cstr("U64"), .k_integer = true, .V = cstr("MargaretMemoryOccupation"), .v_primitive = true, }, true /* We want RBTreeNode_KVPU64ToMargaretMemoryOccupation to be generated here for us */ ); - generate_rbtree_Map_templ_inst_eve_header(l, ns, (map_instantiation_op){ - .K = cstr("U64"), .k_integer = true, .V = cstr("MargaretBufferOccupationSubBuffer"), .v_primitive = true, - }, true); } #endif \ No newline at end of file diff --git a/src/l1_5/codegen/all_set_map_templ_util_inst.h b/src/l1_5/codegen/all_set_map_templ_util_inst.h index e6d5872..ef296e9 100644 --- a/src/l1_5/codegen/all_set_map_templ_util_inst.h +++ b/src/l1_5/codegen/all_set_map_templ_util_inst.h @@ -43,6 +43,8 @@ typedef struct { SpanU8 alternative_comp_map_name_embed; SpanU8 guest_data_T; + + bool at, mat; } map_instantiation_op; void map_instantiation_op_fix(map_instantiation_op* self){ diff --git a/src/l1_5/codegen/buff_rbtree_set_map_template_inst.h b/src/l1_5/codegen/buff_rbtree_set_map_template_inst.h index c12c916..2ad1069 100644 --- a/src/l1_5/codegen/buff_rbtree_set_map_template_inst.h +++ b/src/l1_5/codegen/buff_rbtree_set_map_template_inst.h @@ -530,8 +530,10 @@ NODISCARD VecU8 generate_buf_rbtree_Map_template_instantiation(map_instantiation // todo: write _pop method - codegen_append_buf_rbtree_map__method_at(&res, op, map, false); - codegen_append_buf_rbtree_map__method_at(&res, op, map, true); + if (op.at) + codegen_append_buf_rbtree_map__method_at(&res, op, map, false); + if (op.mat) + codegen_append_buf_rbtree_map__method_at(&res, op, map, true); /* These functions break my design and return answer through pointers given in arguments. For greater good ofk */ codegen_append_buff_rbtree_map__method_at_iter(&res, op, map, false); diff --git a/src/l1_5/codegen/rbtree_set_map_template_inst.h b/src/l1_5/codegen/rbtree_set_map_template_inst.h index 9041c3a..c404945 100644 --- a/src/l1_5/codegen/rbtree_set_map_template_inst.h +++ b/src/l1_5/codegen/rbtree_set_map_template_inst.h @@ -405,6 +405,8 @@ NODISCARD VecU8 generate_rbtree_Map_template_instantiation(map_instantiation_op op.k_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(v->key);\n", op.K), op.V, op.V)); + // todo: write generator for methods _at and _mat + return res; } diff --git a/src/l2/margaret/vulkan_memory_claire.h b/src/l2/margaret/vulkan_memory_claire.h index 3b31bb1..8436d6d 100644 --- a/src/l2/margaret/vulkan_memory_claire.h +++ b/src/l2/margaret/vulkan_memory_claire.h @@ -174,95 +174,6 @@ #include "../../l1/core/int_primitives.h" -/* MargaretMemAllocator assumes that your application tolerates existence of several - * 'quiet' time phases, when no frames are in flight and all you do is relocate and defragment your memory */ - -/* ======== End of MargaretMemAllocator backend interface ======== */ - -typedef struct { - VkBufferUsageFlags usage_flags; - VkMemoryPropertyFlags memory_properties; - bool preserve_at_quiet; - U64 inner_alignment; -} MargaretBufferKindDescription; - -#include "../../../gen/l1/eve/margaret/SpanMargaretBufferKindDescription.h" - -typedef struct { - VkBuffer buffer; - U64 offset; - /* Fun fact: Muller dictionary recognizes nubble, but not nubbin, while firefox spellchecker and clion - * recognize nubbin, but not nubble. But I prefer nubble more. */ - U64 offset_in_device_memory_nubble; - /* If your buffer kind requested VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, MargaretMemAllocator - * will map all nubbles with it. Use `offset_in_device_memory_nubble` to access this buffer from cpu */ - U32 memory_allocation_id; -} MargaretMemAllocatorSubBufferPosition; - -typedef struct { - VkImage image; - U64 offset_in_device_memory_nubble; - U32 memory_allocation_id; -} MargaretMemAllocatorImagePosition; - -typedef MargaretMemAllocatorSubBufferPosition* MargaretMemAllocatorRequestFreeSubBuffer; -#include "../../../gen/l1/eve/margaret/VecMargaretMemAllocatorRequestFreeSubBuffer.h" - -typedef MargaretMemAllocatorImagePosition* MargaretMemAllocatorRequestFreeImage; -#include "../../../gen/l1/eve/margaret/VecMargaretMemAllocatorRequestFreeImage.h" - -typedef struct { - MargaretMemAllocatorSubBufferPosition* prev_ans; - U64 new_size; -} MargaretMemAllocatorRequestResizeSubBuffer; -#include "../../../gen/l1/eve/margaret/VecMargaretMemAllocatorRequestResizeSubBuffer.h" - -typedef struct { - /* We don't specify the buffer kind, because you should place this request in a vector, - * corresponding to needed buffer kind */ - U64 size; - /* If I were you, I would just store this in heap and did not care */ - MargaretMemAllocatorSubBufferPosition* ans; -} MargaretMemAllocatorRequestAllocSubBuffer; -#include "../../../gen/l1/eve/margaret/VecMargaretMemAllocatorRequestAllocSubBuffer.h" - -typedef struct { - U64 width; - U64 height; - VkFormat format; - VkImageTiling tiling; - VkImageLayout initial_layout; - VkImageUsageFlags usage_flags; - VkMemoryPropertyFlags memory_properties; - bool preserve_at_quiet; - /* If I were you, I would just store this in heap and did not care*/ - MargaretMemAllocatorImagePosition* ans; -} MargaretMemAllocatorRequestAllocImage; -#include "../../../gen/l1/eve/margaret/VecMargaretMemAllocatorRequestAllocImage.h" - -/* It is users job to put resize and alloca requests for sub-buffers of type T to the corresponding request - * vectors for this exact type T */ -typedef struct { - VecMargaretMemAllocatorRequestResizeSubBuffer expand; - VecMargaretMemAllocatorRequestAllocSubBuffer alloc; -} MargaretMemAllocatorRequestsForCertainBufferKindAllocation; -#include "../../../gen/l1/eve/margaret/VecMargaretMemAllocatorRequestsForCertainBufferKindAllocation.h" - -typedef struct { - VecMargaretMemAllocatorRequestFreeSubBuffer free_subbuffer; - VecMargaretMemAllocatorRequestFreeImage free_image; - VecMargaretMemAllocatorRequestResizeSubBuffer shrink_subbuffer; - VecMargaretMemAllocatorRequestsForCertainBufferKindAllocation expand_alloc_buffer; - VecMargaretMemAllocatorRequestAllocImage alloc_image; -} MargaretMemAllocatorRequest; - -/* That is our guy! */ -typedef struct MargaretMemAllocator MargaretMemAllocator; - -MargaretMemAllocator MargaretMemAllocator_new( - VkDevice device, VkPhysicalDevice physical_device, SpanMargaretBufferKindDescription buffer_types, - VkMemoryPropertyFlags mem_properties, U8 memory_type_id); - /* Demands + Warnings */ typedef U8 MargaretMemAllocatorDemands; /* If we do defragmentation, MargaretMemAllocator warns us that for @@ -281,25 +192,15 @@ typedef U8 MargaretMemAllocatorDemands; */ #define MARGARET_MEM_ALLOCATOR_DEMANDS_CMD_BUFFER 2 -/* Appends copying commands into cmd_buff. It may append none. Defragmentation, device memory relocation -* need copying commands, but buffer resize may also require copying */ -MargaretMemAllocatorDemands MargaretMemAllocator_carry_out_request( - MargaretMemAllocator* self, VkCommandBuffer cmd_buff, MargaretMemAllocatorRequest* request); - -void MargaretMemAllocator_wipe_old(MargaretMemAllocator* self); - -char* MargaretMemAllocator_get_host_visible_buffer_ptr( - const MargaretMemAllocator* self, const MargaretMemAllocatorSubBufferPosition* pos); - #define MARGARET_ALLOC_LIMIT_ALIGNMENT_EXP 21 -/* ======= End of MargaretMemAllocator client interface ======== */ - #include "../../l1/core/uint_segments.h" #include "../../l1/core/util.h" #include "../../l1_5/core/buff_rb_tree_node.h" #include "../../l1_5/core/rb_tree_node.h" +typedef struct MargaretMemAllocatorOccupantPosition MargaretMemAllocatorOccupantPosition; + typedef struct { U64 width; U64 height; @@ -309,38 +210,15 @@ typedef struct { VkImageUsageFlags usage_flags; bool preserve_at_quiet; VkImage image; - MargaretMemAllocatorImagePosition* ans; + MargaretMemAllocatorOccupantPosition* ans; } MargaretMemoryOccupationImage; - -/* Stored in MargaretMemoryOccupation::buf */ +/* primitive */ typedef struct { - U64 length; - MargaretMemAllocatorSubBufferPosition* ans; -} MargaretBufferOccupationSubBuffer; - -/* Needed for Map */ -typedef const MargaretBufferOccupationSubBuffer* RefMargaretBufferOccupationSubBuffer; -typedef MargaretBufferOccupationSubBuffer* RefMutMargaretBufferOccupationSubBuffer; - -typedef struct { - U64 key; /* start */ - MargaretBufferOccupationSubBuffer value; -} KVPU64ToMargaretBufferOccupationSubBuffer; - -#include "../../../gen/l1/eve/margaret/VecKVPU64ToMargaretBufferOccupationSubBuffer.h" -#include "../../../gen/l1/eve/margaret/OptionMargaretBufferOccupationSubBuffer.h" -#include "../../../gen/l1/eve/margaret/OptionRefMargaretBufferOccupationSubBuffer.h" -#include "../../../gen/l1/eve/margaret/OptionRefMutMargaretBufferOccupationSubBuffer.h" -#include "../../../gen/l1_5/eve/margaret/RBTree_MapU64ToMargaretBufferOccupationSubBuffer.h" - - -/* Not primitive */ -typedef struct { - U16 kind; + VkBufferUsageFlags usage_flags; + bool preserve_at_quiet; VkBuffer buffer; - U64 capacity; - RBTree_MapU64ToMargaretBufferOccupationSubBuffer subbuffers; + U64 capacity; /* Needed only for debugging purposes */ } MargaretMemoryOccupationBuffer; typedef enum { @@ -350,6 +228,7 @@ typedef enum { typedef struct { U64 taken_size; + MargaretMemAllocatorOccupantPosition* ans; MargaretMemoryOccupation_variant variant; union { MargaretMemoryOccupationImage img; @@ -357,27 +236,9 @@ typedef struct { }; } MargaretMemoryOccupation; -void MargaretMemoryOccupation_drop(MargaretMemoryOccupation self){ - if (self.variant == MargaretMemoryOccupation_Buffer) { - RBTree_MapU64ToMargaretBufferOccupationSubBuffer_drop(self.buf.subbuffers); - } -} - -/* Needed for Map */ -typedef const MargaretMemoryOccupation* RefMargaretMemoryOccupation; -typedef MargaretMemoryOccupation* RefMutMargaretMemoryOccupation; - -typedef struct{ - U64 key; - MargaretMemoryOccupation value; -} KVPU64ToMargaretMemoryOccupation; - -#include "../../../gen/l1/eve/margaret/VecKVPU64ToMargaretMemoryOccupation.h" -#include "../../../gen/l1/eve/margaret/OptionMargaretMemoryOccupation.h" -#include "../../../gen/l1/eve/margaret/OptionRefMargaretMemoryOccupation.h" -#include "../../../gen/l1/eve/margaret/OptionRefMutMargaretMemoryOccupation.h" #include "../../../gen/l1_5/eve/margaret/RBTree_MapU64ToMargaretMemoryOccupation.h" +/* Not primitive */ typedef struct { RBTree_MapU64ToMargaretMemoryOccupation occupied_memory; U64 length; @@ -387,14 +248,58 @@ typedef struct { void* mapped_memory; } MargaretMemAllocatorOneBlock; + void MargaretMemAllocatorOneBlock_drop(MargaretMemAllocatorOneBlock self){ RBTree_MapU64ToMargaretMemoryOccupation_drop(self.occupied_memory); } #include "../../../gen/l1/eve/margaret/VecMargaretMemAllocatorOneBlock.h" -/* Used to enumerate both free memory segments in VkDeviceMemory - * and free memory in buffers of some kind */ +struct MargaretMemAllocatorOccupantPosition{ + U64 device_mem_ind; + RBTreeNode_KVPU64ToMargaretMemoryOccupation* occ_it; +}; + +typedef MargaretMemAllocatorOccupantPosition* MargaretMemAllocatorRequestFreeOccupant; +#include "../../../gen/l1/eve/margaret/VecMargaretMemAllocatorRequestFreeOccupant.h" + +typedef MargaretMemAllocatorRequestFreeOccupant MargaretMemAllocatorRequestFreeBuffer; +typedef MargaretMemAllocatorRequestFreeOccupant MargaretMemAllocatorRequestFreeImage; + +typedef struct{ + U64 new_size; + MargaretMemAllocatorOccupantPosition* ans; +} MargaretMemAllocatorRequestResizeBuffer; +#include "../../../gen/l1/eve/margaret/VecMargaretMemAllocatorRequestResizeBuffer.h" + +typedef struct { + VkBufferUsageFlags usage; + bool preserve_at_quiet; + MargaretMemAllocatorOccupantPosition* ans; +} MargaretMemAllocatorRequestAllocBuffer; +#include "../../../gen/l1/eve/margaret/VecMargaretMemAllocatorRequestAllocBuffer.h" + +typedef struct { + U64 width; + U64 height; + VkFormat format; + VkImageTiling tiling; + VkImageLayout current_layout; + VkImageUsageFlags usage_flags; + bool preserve_at_quiet; + MargaretMemAllocatorOccupantPosition* ans; +} MargaretMemAllocatorRequestAllocImage; +#include "../../../gen/l1/eve/margaret/VecMargaretMemAllocatorRequestAllocImage.h" + +typedef struct { + VecMargaretMemAllocatorRequestFreeOccupant free_buf; + VecMargaretMemAllocatorRequestFreeOccupant free_image; + VecMargaretMemAllocatorRequestResizeBuffer shrink_buf; + VecMargaretMemAllocatorRequestResizeBuffer expand_buf; + VecMargaretMemAllocatorRequestAllocBuffer alloc_buf; + VecMargaretMemAllocatorRequestAllocImage alloc_image; +} MargaretMemAllocatorRequests; + typedef struct { U64 start; U64 len; @@ -430,37 +335,34 @@ bool MargaretFreeMemSegment_less_resp_align( #include "../../../gen/l1/eve/margaret/VecMargaretFreeMemSegment.h" #include "../../../gen/l1/eve/margaret/OptionMargaretFreeMemSegment.h" -#include "../../../gen/l1_5/eve/margaret/BufRBTreeByLen_SetMargaretFreeMemSegment.h" #include "../../../gen/l1_5/eve/margaret/BufRBTreeByLenRespAlign_SetMargaretFreeMemSegment.h" #include "../../../gen/l1/eve/margaret/OptionBufRBTreeByLenRespAlign_SetMargaretFreeMemSegment.h" -typedef struct{ - U32 old_mem_block_id; - U64 old_start; - U64 old_len; - U32 new_mem_block_id; - U64 new_start; - U64 new_len; -} 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" - -/* This is not a request from a user to MMA, this is a request from MMA to MMA-defragmentation subroutine */ -typedef struct{ - U64 old_size; /* in buffer in old VkDeviceMemory */ - U64 new_size; /* in buffer in new VkDeviceMemory */ - MargaretMemAllocatorSubBufferPosition* ans; -} MargaretSubBufRelocationRequest; -#include "../../../gen/l1/eve/margaret/VecMargaretSubBufRelocationRequest.h" - -#include "../../../gen/l1/eve/margaret/VecVecMargaretSubBufRelocationRequest.h" +// typedef struct{ +// U32 old_mem_block_id; +// U64 old_start; +// U64 old_len; +// U32 new_mem_block_id; +// U64 new_start; +// U64 new_len; +// } 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" +// +// /* This is not a request from a user to MMA, this is a request from MMA to MMA-defragmentation subroutine */ +// typedef struct{ +// U64 old_size; /* in buffer in old VkDeviceMemory */ +// U64 new_size; /* in buffer in new VkDeviceMemory */ +// MargaretMemAllocatorSubBufferPosition* ans; +// } MargaretSubBufRelocationRequest; +// #include "../../../gen/l1/eve/margaret/VecMargaretSubBufRelocationRequest.h" #include "../../../gen/l1/VecAndSpan_U8.h" @@ -541,39 +443,8 @@ OptionMargaretFreeMemSegment MargaretMemFreeSpaceManager_search(MargaretMemFreeS &man->free_space_in_memory[alignment_exp].some, sit)); } -typedef struct { - VkBufferUsageFlags usage; - U8 inner_alignment_exp; - bool preserve_at_quiet; - - U64 total_occupation; - BufRBTreeByLen_SetMargaretFreeMemSegment free_space_inside_buffers; -} MargaretBufferKindInfo; - -void MargaretBufferKindInfo_drop(MargaretBufferKindInfo self){ - BufRBTreeByLen_SetMargaretFreeMemSegment_drop(self.free_space_inside_buffers); -} - -void MargaretBufferKindInfo_erase_free_space(MargaretBufferKindInfo* self, U64 start, U64 len, U32 dev_mem_block){ - if (len == 0) - return; - bool eret = BufRBTreeByLen_SetMargaretFreeMemSegment_erase(&self->free_space_inside_buffers, - &(MargaretFreeMemSegment){.start = start, .len = len, .dev_mem_block = dev_mem_block}); - assert(eret); -} - -void MargaretBufferKindInfo_insert_free_space(MargaretBufferKindInfo* self, U64 start, U64 len, U32 dev_mem_block){ - if (len == 0) - return; - bool iret = BufRBTreeByLen_SetMargaretFreeMemSegment_insert(&self->free_space_inside_buffers, - (MargaretFreeMemSegment){start, len, dev_mem_block}); - assert(iret); -} - -#include "../../../gen/l1/eve/margaret/VecMargaretBufferKindInfo.h" - /* VkDevice and VkPhysicalDevice stay remembered here. Don't forget that, please */ -struct MargaretMemAllocator { +typedef struct { VecMargaretMemAllocatorOneBlock blocks; /* old_blocks is usually empty. BUT! When you generated a defragmentation command buffer with * MargaretMemAllocator_carry_out_request, this vector will be filled with old blocks, while @@ -583,28 +454,22 @@ struct MargaretMemAllocator { * that MargaretMemAllocator_carry_out_request generates, you can (and should) wipe out old blocks */ VecMargaretMemAllocatorOneBlock old_blocks; - /* If your previous set of requests did not cause defragmentation, it could cause relocation of some data - * in a subbuffer that you wanted to resize */ - VecMargaretOldBufferResizeRecord old_buff_resize_record; MargaretMemFreeSpaceManager mem_free_space; - VecMargaretBufferKindInfo buffer_types; VkMemoryPropertyFlags mem_properties; U8 memory_type_id; VkDevice device; VkPhysicalDevice physical_device; -}; +} MargaretMemAllocator; MargaretMemAllocator MargaretMemAllocator_new( - VkDevice device, VkPhysicalDevice physical_device, SpanMargaretBufferKindDescription buffer_types, - VkMemoryPropertyFlags mem_properties, U8 memory_type_id + VkDevice device, VkPhysicalDevice physical_device, VkMemoryPropertyFlags mem_properties, U8 memory_type_id ){ MargaretMemAllocator self = { - .buffer_types = VecMargaretBufferKindInfo_new_reserved(buffer_types.len), .blocks = VecMargaretMemAllocatorOneBlock_new(), .old_blocks = VecMargaretMemAllocatorOneBlock_new(), - .old_buff_resize_record = VecMargaretOldBufferResizeRecord_new(), + // .old_buff_resize_record = VecMargaretOldBufferResizeRecord_new(), .mem_free_space = MargaretMemFreeSpaceManager_new(), .memory_type_id = memory_type_id, .mem_properties = mem_properties, @@ -612,25 +477,12 @@ MargaretMemAllocator MargaretMemAllocator_new( .physical_device = physical_device }; - for (size_t i = 0; i < buffer_types.len; i++) { - const MargaretBufferKindDescription* desc = &buffer_types.data[i]; - check(U64_is_2pow(desc->inner_alignment)); - VecMargaretBufferKindInfo_append(&self.buffer_types, (MargaretBufferKindInfo){ - .usage = desc->usage_flags, - .inner_alignment_exp = U64_2pow_log(desc->inner_alignment), - .preserve_at_quiet = desc->preserve_at_quiet, - .total_occupation = 0, - .free_space_inside_buffers = BufRBTreeByLen_SetMargaretFreeMemSegment_new() - }); - } return self; } -void MargaretMemAllocator__sink_memory(MargaretMemAllocator* self){ - for (size_t i = 0; i < self->buffer_types.len; i++) - BufRBTreeByLen_SetMargaretFreeMemSegment_sink(&self->buffer_types.buf[i].free_space_inside_buffers); - MargaretMemFreeSpaceManager_sink(&self->mem_free_space); -} +// void MargaretMemAllocator__sink_memory(MargaretMemAllocator* self){ +// MargaretMemFreeSpaceManager_sink(&self->mem_free_space); +// } U64Segment MargaretMemAllocatorOneBlock_get_left_free_space( const MargaretMemAllocatorOneBlock* self, RBTreeNode_KVPU64ToMargaretMemoryOccupation* occ_it){ @@ -692,104 +544,21 @@ void MargaretMemAllocator__get_rid_of_memory_occupant( right_free_space.start + right_free_space.len - left_free_space.start, mem_block_id); } -/* Given a subbuffer inside given buffer, returns segment of free space on the left */ -U64Segment MargaretMemoryOccupationBuffer_get_left_free_space( - MargaretMemoryOccupationBuffer* buf, RBTreeNode_KVPU64ToMargaretBufferOccupationSubBuffer* subbuf_it){ - U64 subbuf_start = subbuf_it->key; - assert(subbuf_start + subbuf_it->value.length <= buf->capacity); - RBTreeNode_KVPU64ToMargaretBufferOccupationSubBuffer* prev_subbuf_it = - RBTree_MapU64ToMargaretBufferOccupationSubBuffer_find_prev(&buf->subbuffers, subbuf_it); - if (prev_subbuf_it != NULL) { - U64 prev_subbuf_start = prev_subbuf_it->key; - U64 prev_subbuf_length = prev_subbuf_it->value.length; - assert(prev_subbuf_start + prev_subbuf_length <= subbuf_start); - return (U64Segment){.start = prev_subbuf_start + prev_subbuf_length, - .len = subbuf_start - (prev_subbuf_start + prev_subbuf_length)}; - } - return (U64Segment){.start = 0, .len = subbuf_start}; -} - -/* Given a subbuffer inside this buffer, return segment of free space on the right */ -U64Segment MargaretMemoryOccupationBuffer_get_right_free_space( - MargaretMemoryOccupationBuffer* buf, RBTreeNode_KVPU64ToMargaretBufferOccupationSubBuffer* subbuf_it){ - U64 subbuf_start = subbuf_it->key; - U64 subbuf_length = subbuf_it->value.length; - assert(subbuf_start + subbuf_length <= buf->capacity); - - RBTreeNode_KVPU64ToMargaretBufferOccupationSubBuffer* next_subbuf_it = - RBTree_MapU64ToMargaretBufferOccupationSubBuffer_find_next(&buf->subbuffers, subbuf_it); - if (next_subbuf_it != NULL) { - U64 next_subbuf_start = next_subbuf_it->key; - assert(subbuf_start + subbuf_length <= next_subbuf_start); - return (U64Segment){.start = subbuf_start + subbuf_length, - .len = next_subbuf_start - (subbuf_start + subbuf_length)}; - } - return (U64Segment){.start = subbuf_start + subbuf_length, .len = buf->capacity - (subbuf_start + subbuf_length)}; -} - -/* 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, RBTreeNode_KVPU64ToMargaretMemoryOccupation* occ_it, - RBTreeNode_KVPU64ToMargaretBufferOccupationSubBuffer* subbuf_it - ){ - MargaretMemAllocatorOneBlock* block = VecMargaretMemAllocatorOneBlock_mat(&self->blocks, mem_block_id); - U64 occ_start = occ_it->key; - MargaretMemoryOccupation* occ_buf = &occ_it->value; - assert(occ_buf->variant == MargaretMemoryOccupation_Buffer); - MargaretMemoryOccupationBuffer* buf = &occ_buf->buf; - - MargaretBufferKindInfo* kindred = VecMargaretBufferKindInfo_mat(&self->buffer_types, buf->kind); - - U64 subbuf_it = BuffRBTree_MapU64ToMargaretBufferOccupationSubBuffer_find(&buf->subbuffers, start - occ_start); - U64 subbuf_start; - const MargaretBufferOccupationSubBuffer* subbuf; - assert(occ_start <= start); - assert(subbuf_start == start - occ_start); - assert(subbuf_start + subbuf->length <= buf->capacity); - assert(start + subbuf->length <= occ_start + buf->capacity); - kindred->total_occupation -= subbuf->length; // todo: give a thought to memory counting - - - U64Segment left_free_space = MargaretMemoryOccupationBuffer_get_left_free_space(buf, subbuf_it); - U64Segment right_free_space = MargaretMemoryOccupationBuffer_get_right_free_space(buf, subbuf_it); - - /* all these iterators and pointers will get invalidated */ - /* Because MargaretBufferOccupationSubBuffer is primitive, we don't need to drop it before erasing */ - BuffRBTree_MapU64ToMargaretBufferOccupationSubBuffer_empty_index_erase(&buf->subbuffers, subbuf_it); - /* all these iterators and pointers just got invalidated */ - - MargaretBufferKindInfo_erase_free_space(kindred, left_free_space.start, left_free_space.len, mem_block_id); - MargaretBufferKindInfo_erase_free_space(kindred, right_free_space.start, right_free_space.len, mem_block_id); - - 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 */ - MargaretMemAllocator__get_rid_of_memory_occupant(self, mem_block_id, occ_it); - } else { - U64 LEN = right_free_space.start + right_free_space.len - left_free_space.start; - assert(LEN > 0); - MargaretBufferKindInfo_insert_free_space(kindred, left_free_space.start, LEN, mem_block_id); - } -} - -/* This function puts block into invalid state. Which means block should already be in unusable state. - * This structure only wipes out vulkan handlers, destroyes buffers, images, and then destroys memory block - * It won't drop anything, you should do it after you called it. - * It is useful when dropping the whole allocator or when wiping old blocks - */ void MargaretMemAllocator__clean_handlers_in_block(const MargaretMemAllocator* self, const MargaretMemAllocatorOneBlock* block){ assert(((self->mem_properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) == (block->mapped_memory != NULL)); if (block->mapped_memory) vkUnmapMemory(self->device, block->mapped_memory); - for (size_t i = 0; i < block->occupied_memory.el.len; i++) { - const MargaretMemoryOccupation* occ = &block->occupied_memory.el.buf[i].value; - if (occ->variant == MargaretMemoryOccupation_Buffer) { - const MargaretMemoryOccupationBuffer* wb = &occ->buf; - vkDestroyBuffer(self->device, wb->buffer, NULL); - } else if (occ->variant == MargaretMemoryOccupation_Image) { - const MargaretMemoryOccupationImage* wi = &occ->img; - vkDestroyImage(self->device, wi->image, NULL); + for (RBTreeNode_KVPU64ToMargaretMemoryOccupation* i = + RBTree_MapU64ToMargaretMemoryOccupation_find_min(&block->occupied_memory); i; + i = RBTree_MapU64ToMargaretMemoryOccupation_find_next(&block->occupied_memory, i)) + { + if (i->value.variant == MargaretMemoryOccupation_Buffer) { + vkDestroyBuffer(self->device, i->value.buf.buffer, NULL); + } else { + assert(i->value.variant == MargaretMemoryOccupation_Image); + vkDestroyImage(self->device, i->value.img.image, NULL); } } vkFreeMemory(self->device, block->mem_hand, NULL); @@ -804,14 +573,27 @@ void MargaretMemAllocator_drop(MargaretMemAllocator self){ } VecMargaretMemAllocatorOneBlock_drop(self.old_blocks); VecMargaretMemAllocatorOneBlock_drop(self.blocks); - VecMargaretOldBufferResizeRecord_drop(self.old_buff_resize_record); - VecMargaretBufferKindInfo_drop(self.buffer_types); + // VecMargaretOldBufferResizeRecord_drop(self.old_buff_resize_record); MargaretMemFreeSpaceManager_drop(self.mem_free_space); } +void MargaretMemAllocator_wipe_old(MargaretMemAllocator* self){ + assert(!self->old_blocks.len || !self->old_buff_resize_record.len); + for (size_t blind = 0; blind < self->old_blocks.len; blind++) { + MargaretMemAllocator__clean_handlers_in_block(self, &self->old_blocks.buf[blind]); + } + VecMargaretMemAllocatorOneBlock_sink(&self->old_blocks, 0); + for (U64 ri = 0; ri < self->old_buff_resize_record.len; ri++) { + const MargaretOldBufferResizeRecord* resize = &self->old_buff_resize_record.buf[ri]; + if (resize->old_mem_block_id != resize->new_mem_block_id || resize->old_start != resize->new_start) { + MargaretMemAllocator__get_rid_of_sub_buffer(self, resize->old_mem_block_id, resize->old_start); + } + } + VecMargaretOldBufferResizeRecord_sink(&self->old_buff_resize_record, 0); +} MargaretMemAllocatorDemands MargaretMemAllocator_carry_out_request( - MargaretMemAllocator* self, VkCommandBuffer cmd_buff, MargaretMemAllocatorRequest* request + MargaretMemAllocator* self, VkCommandBuffer cmd_buff, MargaretMemAllocatorRequests* requests ){ MargaretMemAllocator_wipe_old(self); assert(request->expand_alloc_buffer.len == self->buffer_types.len); @@ -1003,21 +785,7 @@ MargaretMemAllocatorDemands MargaretMemAllocator_carry_out_request( return 0; } -void MargaretMemAllocator_wipe_old(MargaretMemAllocator* self){ - assert(!self->old_blocks.len || !self->old_buff_resize_record.len); - for (size_t blind = 0; blind < self->old_blocks.len; blind++) { - MargaretMemAllocator__clean_handlers_in_block(self, &self->old_blocks.buf[blind]); - } - VecMargaretMemAllocatorOneBlock_sink(&self->old_blocks, 0); - for (U64 ri = 0; ri < self->old_buff_resize_record.len; ri++) { - const MargaretOldBufferResizeRecord* resize = &self->old_buff_resize_record.buf[ri]; - if (resize->old_mem_block_id != resize->new_mem_block_id || resize->old_start != resize->new_start) { - MargaretMemAllocator__get_rid_of_sub_buffer(self, resize->old_mem_block_id, resize->old_start); - } - } - VecMargaretOldBufferResizeRecord_sink(&self->old_buff_resize_record, 0); -} - +// todo: fix skill issues , lol char* MargaretMemAllocator_get_host_visible_buffer_ptr( const MargaretMemAllocator* self, const MargaretMemAllocatorSubBufferPosition* pos){ check((self->mem_properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));