Stop all work. New Opsiian video jusst dropped

This commit is contained in:
Андреев Григорий 2025-11-12 19:54:26 +03:00
parent 6ba756fe1a
commit f00ea20d4a
4 changed files with 132 additions and 47 deletions

View File

@ -56,8 +56,8 @@ void generate_margaret_eve_for_vulkan_utils() {
.T = cstr("RefMutMargaretBufferOccupationSubBuffer"), .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_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);

View File

@ -14,7 +14,8 @@ void generate_l1_5_template_instantiations_for_margaret(){
.t_primitive = true,
.alternative_less = cstr("MargaretFreeMemSegment_less"),
.alternative_equal = cstr("MargaretFreeMemSegment_equal"),
.alternative_comp_set_name_embed = cstr("Len")
.alternative_comp_set_name_embed = cstr("Len"),
.unconditional_equality = true,
});
generate_rb_tree_Set_templ_inst_eve_header(l, ns, (set_instantiation_op){
.T = cstr("MargaretFreeMemSegment"),
@ -23,7 +24,8 @@ void generate_l1_5_template_instantiations_for_margaret(){
.alternative_less = cstr("MargaretFreeMemSegment_less_resp_align"),
.alternative_equal = cstr("MargaretFreeMemSegment_equal_resp_align"),
.alternative_comp_set_name_embed = cstr("LenRespAlign"),
.guest_data_T = cstr("U8")
.guest_data_T = cstr("U8"),
.unconditional_equality = true,
});
generate_rb_tree_Map_templ_inst_eve_header(l, ns, (map_instantiation_op){
.K = cstr("U64"), .k_integer = true, .V = cstr("MargaretMemoryOccupation"), /* MargaretMemoryOccupation is not primitive */

View File

@ -621,7 +621,6 @@ NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op
op.T, op.T));
}
/* Erasing time!!!! */
codegen_append_rb_tree_map__method_empty_index_erase(&res, set);
codegen_append_rb_tree_map__erase_kind_method(&res, map_op, set, cstr("erase"), vcstr("bool"),
@ -635,11 +634,9 @@ NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op
VecU8_fmt("return None_%s();\n", op.T),
VecU8_fmt("%s saved = self->el.buf[cur - 1];\n", op.T),
VecU8_fmt("return Some_%s(saved);\n", op.T));
}
/* We erased enough */
if (!op.unconditional_equality)
codegen_append_rb_tree_map__method_at(&res, map_op, set, false);
}
VecU8_append_vec(&res, VecU8_fmt(
"const %s* %s_at_iter(const %s* self, U64 it) {\n" /* op.T, set, set */

View File

@ -379,6 +379,7 @@ typedef struct{
typedef struct {
BuffRBTree_MapU64ToMargaretMemoryOccupation occupied_memory;
U64 length;
/* I am 100% sure that this fields is useless rn. You might use it to show cool infographics on F3 screen */
U64 occupation_counter;
VkDeviceMemory mem_hand;
void* mapped_memory;
@ -516,12 +517,6 @@ struct MargaretMemAllocator {
VkPhysicalDevice physical_device;
};
void MargaretMemAllocator_drop(MargaretMemAllocator self){
// todo: first: drop absolutely everything
VecMargaretMemAllocatorOneBlock_drop(self.blocks);
MargaretMemFreeSpaceManager_drop(self.mem_free_space);
}
MargaretMemAllocator MargaretMemAllocator_new(
VkDevice device, VkPhysicalDevice physical_device, SpanMargaretBufferKindDescription buffer_types,
VkMemoryPropertyFlags mem_properties, U8 memory_type_id
@ -552,6 +547,128 @@ MargaretMemAllocator MargaretMemAllocator_new(
return self;
}
void MargaretMemAllocator__erase_free_space_for_subbufers(
BuffRBTreeByLen_SetMargaretFreeMemSegment* free_space_inside_buffers, U64 start, U64 len, U32 dev_mem_block
){
if (len > 0) {
bool eret = BuffRBTreeByLen_SetMargaretFreeMemSegment_erase(free_space_inside_buffers, &(MargaretFreeMemSegment){
.start = start, .len = len, .dev_mem_block = dev_mem_block});
assert(eret);
}
}
/* 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);
U64 occ_it = BuffRBTree_MapU64ToMargaretMemoryOccupation_find_max_less_or_eq(&block->occupied_memory, 2);
U64 occ_start;
MargaretMemoryOccupation* occ_buf;
BuffRBTree_MapU64ToMargaretMemoryOccupation_mat_iter(&block->occupied_memory, occ_it, &occ_start, &occ_buf);
assert(occ_buf->variant == MargaretMemoryOccupation_Buffer);
MargaretMemoryOccupationBuffer* buf = &occ_buf->buf;
assert(occ_start <= start);
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;
BuffRBTree_MapU64ToMargaretBufferOccupationSubBuffer_at_iter(&buf->subbuffers, subbuf_it, &subbuf_start, &subbuf);
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;
U64 left_free_space_start, left_free_space_length;
U64 prev_subbuf_it = BuffRBTree_MapU64ToMargaretBufferOccupationSubBuffer_find_prev(&buf->subbuffers, subbuf_it);
if (prev_subbuf_it != 0) {
U64 prev_subbuf_start;
const MargaretBufferOccupationSubBuffer* prev_subbuf;
BuffRBTree_MapU64ToMargaretBufferOccupationSubBuffer_at_iter(&buf->subbuffers, prev_subbuf_it, &prev_subbuf_start, &prev_subbuf);
assert(prev_subbuf_start + prev_subbuf->length <= subbuf_start);
left_free_space_start = prev_subbuf_start + prev_subbuf->length;
left_free_space_length = subbuf_start - (prev_subbuf_start + prev_subbuf->length);
} else {
left_free_space_start = 0;
left_free_space_length = subbuf_start;
}
U64 right_free_space_start, right_free_space_length;
U64 next_subbuf_it = BuffRBTree_MapU64ToMargaretBufferOccupationSubBuffer_find_next(&buf->subbuffers, subbuf_it);
if (next_subbuf_it != 0) {
U64 next_subbuf_start;
const MargaretBufferOccupationSubBuffer* next_subbuf;
BuffRBTree_MapU64ToMargaretBufferOccupationSubBuffer_at_iter(&buf->subbuffers, next_subbuf_it, &next_subbuf_start, &next_subbuf);
assert(subbuf_start + subbuf->length <= next_subbuf_start);
right_free_space_start = subbuf_start + subbuf->length;
right_free_space_length = next_subbuf_start - (subbuf_start + subbuf->length);
} else {
right_free_space_start = subbuf_start + subbuf->length;
right_free_space_length = buf->capacity - (subbuf_start + subbuf->length);
}
/* 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 */
MargaretMemAllocator__erase_free_space_for_subbufers(&kindred->free_space_inside_buffers,
left_free_space_start, left_free_space_length, mem_block_id);
MargaretMemAllocator__erase_free_space_for_subbufers(&kindred->free_space_inside_buffers,
right_free_space_start, right_free_space_length, 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 */
// todo: уебать буффер
} else {
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});
assert(iret);
}
}
/* 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);
}
}
vkFreeMemory(self->device, block->mem_hand, NULL);
}
void MargaretMemAllocator_drop(MargaretMemAllocator self){
for (size_t blind = 0; blind < self.old_blocks.len; blind++) {
MargaretMemAllocator__clean_handlers_in_block(&self, &self.old_blocks.buf[blind]);
}
for (size_t blind = 0; blind < self.blocks.len; blind++) {
MargaretMemAllocator__clean_handlers_in_block(&self, &self.blocks.buf[blind]);
}
VecMargaretMemAllocatorOneBlock_drop(self.old_blocks);
VecMargaretMemAllocatorOneBlock_drop(self.blocks);
VecMargaretOldBufferResizeRecord_drop(self.old_buff_resize_record);
VecMargaretBufferKindInfo_drop(self.buffer_types);
MargaretMemFreeSpaceManager_drop(self.mem_free_space);
}
MargaretMemAllocatorDemands MargaretMemAllocator_carry_out_request(
MargaretMemAllocator* self, VkCommandBuffer cmd_buff, MargaretMemAllocatorRequest* request
){
@ -561,44 +678,13 @@ MargaretMemAllocatorDemands MargaretMemAllocator_carry_out_request(
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++) {
MargaretMemAllocatorOneBlock* block = &self->old_blocks.buf[blind];
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);
{ /* destroying images and buffers from this block. Binary tree detour takes O(n) time */
U64 set_it = BuffRBTree_MapU64ToMargaretMemoryOccupation_find_min(&block->occupied_memory);
while (set_it > 0) {
assert(set_it < block->occupied_memory.tree.len && set_it > 0);
U64 occ_start;
const MargaretMemoryOccupation* occ;
BuffRBTree_MapU64ToMargaretMemoryOccupation_at_iter(&block->occupied_memory, set_it, &occ_start, &occ);
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);
}
set_it = BuffRBTree_MapU64ToMargaretMemoryOccupation_find_next(&block->occupied_memory, set_it);
}
}
vkFreeMemory(self->device, block->mem_hand, NULL);
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) {
MargaretMemAllocatorOneBlock* block = VecMargaretMemAllocatorOneBlock_mat(&self->blocks, resize->old_mem_block_id);
U64 occ_it = BuffRBTree_MapU64ToMargaretMemoryOccupation_find_max_less_or_eq(&block->occupied_memory, 2);
U64 occ_start;
MargaretMemoryOccupation* occ;
BuffRBTree_MapU64ToMargaretMemoryOccupation_mat_iter(&block->occupied_memory, occ_it, &occ_start, &occ);
// todo: this fucker wants to be deleted. Do it for him. Maybe it will also carry the whole VkBuffer with
// him
// OptionMargaretBufferOccupationSubBuffer delete_me = BuffRBTree_MapU64ToMargaretBufferOccupationSubBuffer_pop(&self->
MargaretMemAllocator__get_rid_of_sub_buffer(self, resize->old_mem_block_id, resize->old_start);
}
}
VecMargaretOldBufferResizeRecord_sink(&self->old_buff_resize_record, 0);