Saving progress on MargaretMemAllocator. The exam is near, can't do this anymore

This commit is contained in:
Андреев Григорий 2025-11-04 12:24:08 +03:00
parent 497808ddeb
commit 49ee178eb6
11 changed files with 381 additions and 83 deletions

View File

@ -25,6 +25,34 @@ void generate_margaret_eve_for_vulkan_utils() {
.collab_vec_span = true
});
/* For l2/margaret/vulkan_memory_claire.h */
generate_eve_span_company_for_primitive(l, ns, cstr("MargaretBufferKindDescription"), false, true);
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("BuffRBTreeByLenRespAlign_SetMargaretFreeMemSegment")
});
generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorOneBlock"), true, false);
generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorOneMemType"), true, false);
generate_eve_span_company_for_primitive(l, ns, cstr("MargaretBufferKindInfo"), true, false);
generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemoryOccupation"), true, false);
generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){
.T = cstr("MargaretMemoryOccupation"), .t_primitive = true});
generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){
.T = cstr("RefMargaretMemoryOccupation"), .t_primitive = true});
generate_eve_span_company_for_primitive(l, ns, cstr("MargaretBufferOccupationSubBuffer"), 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_primitive = 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("RefMargaretFreeMemSegment"), .t_primitive = true});
generate_eve_span_company_for_primitive(l, ns, cstr("MargaretCommandForImageCopying"), true, true);
generate_eve_span_company_for_primitive(l, ns, cstr("MargaretMemAllocatorRequestAllocBuffer"), true, true);

View File

@ -51,14 +51,6 @@ void generate_util_temp_very_base_headers() {
generate_guarded_span_company_for_primitive(cstr("l1"), cstr(""),
cstr("CSTR"), cstr(""), true, false);
generate_util_templ_inst_guarded_header(l, ns, cstr("#include \"../../src/l1/core/uint_segments.h\""),
(util_templates_instantiation_options){.T = cstr("U64Segment"), .t_primitive = true, .vec_extended = true});
generate_Option_templ_inst_guarded_header(l, ns, cstr("#include \"../../src/l1/core/uint_segments.h\""),
(option_template_instantiation_op){.T = cstr("U64Segment"), .t_primitive = true});
/* Required by BuffRBTree_Set */
generate_Option_templ_inst_guarded_header(l, ns, cstr("#include \"../../src/l1/core/uint_segments.h\""),
(option_template_instantiation_op){.T = cstr("RefU64Segment"), .t_primitive = true});
generate_guarded_header_of_result_type_instantiation(cstr("l1"), cstr(""),
cstr(""), cstr("VecU8"), cstr("#include \"VecAndSpan_U8.h\""), true, false);
generate_guarded_header_of_result_type_instantiation(cstr("l1"), cstr(""),

View File

@ -712,7 +712,7 @@ void generate_Option_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, option
VecU8 text = VecU8_from_cstr("/* Automatically generated file. Do not edit it.\n"
" * Do not include it in more than one place */\n\n");
VecU8_append_vec(&text, generate_OptionT_struct_and_methods(op));
VecU8 nt_path = VecU8_fmt("%s/eve/%s/Option%s%c", layer, bonus_ns, op.T, 0);
VecU8 nt_path = VecU8_fmt("%s/eve/%s/Option%s.h%c", layer, bonus_ns, op.T, 0);
write_whole_file_or_abort((const char*)nt_path.buf, VecU8_to_span(&text));
VecU8_drop(nt_path);
VecU8_drop(text);

View File

@ -8,47 +8,44 @@ typedef struct {
U64 len;
} U64Segment;
bool U64Segment_equal_by_start(const U64Segment* A, const U64Segment* B) {
return A->start == B->start;
}
// bool U64Segment_equal_by_start(const U64Segment* A, const U64Segment* B) {
// return A->start == B->start;
// }
bool U64Segment_less_by_start(const U64Segment* A, const U64Segment* B) {
return A->start < B->start;
}
// bool U64Segment_less_by_start(const U64Segment* A, const U64Segment* B) {
// return A->start < B->start;
// }
bool U64Segment_equal_U64Segment(const U64Segment* A, const U64Segment* B) {
return A->start == B->start && A->len == B->len;
}
// bool U64Segment_equal_U64Segment(const U64Segment* A, const U64Segment* B) {
// return A->start == B->start && A->len == B->len;
// }
bool U64Segment_less_by_len_and_start(const U64Segment* A, const U64Segment* B) {
if (A->len == B->len)
return A->start < B->start;
return A->len < B->len;
}
// bool U64Segment_less_by_len_and_start(const U64Segment* A, const U64Segment* B) {
// if (A->len == B->len)
// return A->start < B->start;
// return A->len < B->len;
// }
U64 U64Segment_get_length_resp_alignment(const U64Segment* self, U8 alignment_exp) {
if (self->start & ((1ull << alignment_exp) - 1)) {
U64 pad_left = (1ull << alignment_exp) - (self->start & ((1ull << alignment_exp) - 1));
return self->len >= pad_left ? self->len - pad_left : 0;
U64 U64Segment_get_length_resp_alignment(U64Segment self, U8 alignment_exp) {
if (self.start & ((1ull << alignment_exp) - 1)) {
U64 pad_left = (1ull << alignment_exp) - (self.start & ((1ull << alignment_exp) - 1));
return self.len >= pad_left ? self.len - pad_left : 0;
}
return self->len;
return self.len;
}
bool U64Segment_equal_U64Segment_resp_align(const U64Segment* A, const U64Segment* B, U8 alignment_exp) {
U64 len_A = U64Segment_get_length_resp_alignment(A, alignment_exp);
U64 len_B = U64Segment_get_length_resp_alignment(B, alignment_exp);
return len_A == len_B && A->start == B->start;
}
// bool U64Segment_equal_U64Segment_resp_align(const U64Segment* A, const U64Segment* B, U8 alignment_exp) {
// U64 len_A = U64Segment_get_length_resp_alignment(A, alignment_exp);
// U64 len_B = U64Segment_get_length_resp_alignment(B, alignment_exp);
// return len_A == len_B && A->start == B->start;
// }
bool U64Segment_less_by_len_and_start_resp_align(const U64Segment* A, const U64Segment* B, U8 alignment_exp) {
U64 len_A = U64Segment_get_length_resp_alignment(A, alignment_exp);
U64 len_B = U64Segment_get_length_resp_alignment(B, alignment_exp);
if (len_A == len_B)
return A->start < B->start;
return len_A < len_B;
}
/* Required by BuffRBTree_Set. That was a really tough decision */
typedef const U64Segment* RefU64Segment;
// bool U64Segment_less_by_len_and_start_resp_align(const U64Segment* A, const U64Segment* B, U8 alignment_exp) {
// U64 len_A = U64Segment_get_length_resp_alignment(A, alignment_exp);
// U64 len_B = U64Segment_get_length_resp_alignment(B, alignment_exp);
// if (len_A == len_B)
// return A->start < B->start;
// return len_A < len_B;
// }
#endif

View File

@ -69,6 +69,19 @@ float pow2f(float x) {
return x * x;
}
bool U64_is_2pow(U64 n){
return n > 0 && (n & (n - 1) == 0);
}
U8 U64_2pow_log(U64 n){
U8 log = 0;
while (n > 1){
n >>= 1;
log++;
}
return log;
}
typedef struct {
U32 width;
U32 height;

View File

@ -3,6 +3,7 @@
#include "marie/clipping.h"
#include "liza.h"
#include "l1_5_templ_very_base.h"
#include "margaret.h"
int main() {
mkdir_nofail("l1_5");
@ -10,6 +11,7 @@ int main() {
generate_marie_clipping_header();
generate_l1_5_liza_headers();
generate_l1_5_template_instantiation_for_base_types();
generate_l1_5_template_instantiations_for_margaret();
finish_layer(cstr("l1_5"));
return 0;
}

View File

@ -9,35 +9,6 @@ void generate_l1_5_template_instantiation_for_base_types(){
(set_instantiation_op){.T = cstr("U64"), .t_integer = true});
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, cstr("#include \"../l1/VecAndSpan_S64.h\""),
(set_instantiation_op){.T = cstr("S64"), .t_integer = true});
SpanU8 u64seg_dep = cstr("#include \"../l1/VecU64Segment.h\"\n"
"#include \"../l1/OptionU64Segment.h\"\n"
"#include \"../l1/OptionRefU64Segment.h\"");
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, u64seg_dep,
(set_instantiation_op){
.T = cstr("U64Segment"),
.t_primitive = true,
.alternative_equal = cstr("U64Segment_equal_by_start"),
.alternative_less = cstr("U64Segment_less_by_start"),
.alternative_comp_set_name_embed = cstr("Start")
});
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, u64seg_dep,
(set_instantiation_op){
.T = cstr("U64Segment"),
.t_primitive = true,
.alternative_less = cstr("U64Segment_less_by_len_and_start"),
.alternative_comp_set_name_embed = cstr("Len")
});
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, u64seg_dep,
(set_instantiation_op){
.T = cstr("U64Segment"),
.t_primitive = true,
/* comparison takes additional U8 parameter */
.alternative_less = cstr("U64Segment_less_by_len_and_start_resp_align"),
.alternative_equal = cstr("U64Segment_equal_U64Segment_resp_align"),
.alternative_comp_set_name_embed = cstr("LenRespAlign"),
.guest_data_T = cstr("U8")
});
}
#endif

36
src/l1_5/anne/margaret.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef prototype1_src_l1_5_anne_margaret_h
#define prototype1_src_l1_5_anne_margaret_h
#include "../codegen/rb_tree_set_map_template_inst.h"
void generate_l1_5_template_instantiations_for_margaret(){
SpanU8 l = cstr("l1_5"), ns = cstr("margaret");
mkdir_nofail("l1_5/eve");
mkdir_nofail("l1_5/eve/margaret");
/* For MargaretMemAllocator */
generate_rb_tree_Set_templ_inst_eve_header(l, ns, (set_instantiation_op){
.T = cstr("MargaretFreeMemSegment"),
.t_primitive = true,
.alternative_less = cstr("MargaretFreeMemSegment_less"),
.alternative_equal = cstr("MargaretFreeMemSegment_equal"),
.alternative_comp_set_name_embed = cstr("Len")
});
generate_rb_tree_Set_templ_inst_eve_header(l, ns, (set_instantiation_op){
.T = cstr("MargaretFreeMemSegment"),
.t_primitive = true,
/* comparison takes additional U8 parameter */
.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")
});
generate_rb_tree_Set_templ_inst_eve_header(l, ns, (set_instantiation_op){
.T = cstr("MargaretMemoryOccupation"), .t_primitive = true,
});
generate_rb_tree_Set_templ_inst_eve_header(l, ns, (set_instantiation_op){
.T = cstr("MargaretBufferOccupationSubBuffer"), .t_primitive = true,
});
}
#endif

View File

@ -583,7 +583,7 @@ void generate_rb_tree_Set_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, s
VecU8 text = VecU8_from_cstr("/* Automatically generated file. Do not edit it.\n"
" * Do not include it in more than one place */\n\n");
VecU8_append_vec(&text, generate_rb_tree_Set_template_instantiation(op));
VecU8 nt_path = VecU8_fmt("%s/eve/%s/%s.h%c", layer, bonus_ns, op.T, get_name_of_rb_tree_set_structure(op));
VecU8 nt_path = VecU8_fmt("%s/eve/%s/%v.h%c", layer, bonus_ns, get_name_of_rb_tree_set_structure(op), 0);
write_whole_file_or_abort((const char*)nt_path.buf, VecU8_to_span(&text));
VecU8_drop(nt_path);
VecU8_drop(text);

View File

@ -172,7 +172,7 @@
* const VkAllocationCallbacks* pAllocator)
*/
#include "../../../l1/core/int_primitives.h"
#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 */
@ -184,7 +184,9 @@ typedef struct {
VkMemoryPropertyFlags memory_properties;
bool preserve_at_quiet;
U64 inner_alignment;
} MargaretMemAllocatorBufferKindInfo;
} MargaretBufferKindDescription;
#include "../../../gen/l1/eve/margaret/SpanMargaretBufferKindDescription.h"
typedef struct {
VkBuffer buffer;
@ -195,7 +197,7 @@ typedef struct {
/* 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 */
U8 memory_type_id;
U16 memory_allocation_id;
U32 memory_allocation_id;
} MargaretMemAllocatorBufferPosition;
typedef struct {
@ -251,6 +253,9 @@ typedef struct {
/* That is our guy! */
typedef struct MargaretMemAllocator MargaretMemAllocator;
MargaretMemAllocator MargaretMemAllocator_new(
VkDevice device, VkPhysicalDevice physical_device, SpanMargaretBufferKindDescription buffer_types, double alpha);
/* Vibe check */
bool MargaretMemAllocator_request_needs_silence(MargaretMemAllocator* self, MargaretMemAllocatorRequest req);
@ -263,35 +268,286 @@ bool MargaretMemAllocator_request_needs_silence(MargaretMemAllocator* self, Marg
* actions with memory managed by Self would make any sense */
bool MargaretMemAllocator_carry_out_request(MargaretMemAllocator* self, VkCommandBuffer cmd_buff, bool silence);
// todo: add same shit for images in host visible buffer
void MargaretMemAllocator_wipe_old(MargaretMemAllocator* self);
char* MargaretMemAllocator_get_host_visible_buffer_ptr(
const MargaretMemAllocator* self, const MargaretMemAllocatorBufferPosition* pos);
// todo: add same shit for images in host visible buffer
#define MARGARET_ALLOC_LIMIT_ALIGNMENT_EXP 28
/* ======= End of MargaretMemAllocator client interface ======== */
#define MARGARET_ALLOC_LIMIT_ALIGNMENT_EXP 30
#include "../../l1/core/uint_segments.h"
#include "../../l1/core/util.h"
#include "../../l1_5/core/rb_tree_node.h"
typedef struct {
U64 width;
U64 height;
VkFormat format;
VkImageTiling tiling;
VkImageLayout current_layout;
VkImageUsageFlags usage_flags;
bool preserve_at_quiet;
VkImage image;
MargaretMemAllocatorImagePosition* ans;
} MargaretMemoryOccupationImage;
typedef struct {
U16 kind;
VkBuffer buffer;
U64 occupied_by_sub_buffers;
U64 capacity;
} MargaretMemoryOccupationBuffer;
typedef enum {
MargaretMemoryOccupation_Image,
MargaretMemoryOccupation_Buffer,
} MargaretMemoryOccupation_variant;
typedef struct {
MargaretMemoryOccupation_variant variant;
U64 start;
U64 taken_size;
union {
MargaretMemoryOccupationImage img;
MargaretMemoryOccupationBuffer buf;
};
} MargaretMemoryOccupation;
bool MargaretMemoryOccupation_equal_MargaretMemoryOccupation(
const MargaretMemoryOccupation* A, const MargaretMemoryOccupation* B
){
return A->start == B->start;
}
bool MargaretMemoryOccupation_less_MargaretMemoryOccupation(
const MargaretMemoryOccupation* A, const MargaretMemoryOccupation* B
){
return A->start < B->start;
}
/* Needed for Set<MargaretMemoryOccupation> */
typedef const MargaretMemoryOccupation* RefMargaretMemoryOccupation;
#include "../../../gen/l1/eve/margaret/VecMargaretMemoryOccupation.h"
#include "../../../gen/l1/eve/margaret/OptionMargaretMemoryOccupation.h"
#include "../../../gen/l1/eve/margaret/OptionRefMargaretMemoryOccupation.h"
#include "../../../gen/l1_5/eve/margaret/BuffRBTree_SetMargaretMemoryOccupation.h"
typedef struct {
U64 start;
U64 length;
MargaretMemAllocatorBufferPosition* ans;
} MargaretBufferOccupationSubBuffer;
bool MargaretBufferOccupationSubBuffer_equal_MargaretBufferOccupationSubBuffer(
const MargaretBufferOccupationSubBuffer* A, const MargaretBufferOccupationSubBuffer* B
){
return A->start == B->start;
}
bool MargaretBufferOccupationSubBuffer_less_MargaretBufferOccupationSubBuffer(
const MargaretBufferOccupationSubBuffer* A, const MargaretBufferOccupationSubBuffer* B
){
return A->start < B->start;
}
/* Needed for Set<MargaretBufferOccupationSubBuffer> */
typedef const MargaretBufferOccupationSubBuffer* RefMargaretBufferOccupationSubBuffer;
#include "../../../gen/l1/eve/margaret/VecMargaretBufferOccupationSubBuffer.h"
#include "../../../gen/l1/eve/margaret/OptionMargaretBufferOccupationSubBuffer.h"
#include "../../../gen/l1/eve/margaret/OptionRefMargaretBufferOccupationSubBuffer.h"
#include "../../../gen/l1_5/eve/margaret/BuffRBTree_SetMargaretBufferOccupationSubBuffer.h"
typedef struct {
BuffRBTree_SetMargaretMemoryOccupation occupied_memory;
BuffRBTree_SetMargaretBufferOccupationSubBuffer occupied_buffers;
U64 length;
U64 occupation_counter;
VkDeviceMemory mem_hand;
void* mapped_memory;
} MargaretMemAllocatorOneBlock;
#include "../../../gen/l1/eve/margaret/VecMargaretMemAllocatorOneBlock.h"
/* Used to enumerate both free memory segments in VkDeviceMemory
* and free memory in buffers of some kind */
typedef struct {
U64 start;
U64 len;
/* If this value somehow got higher than zero, your life fucking sucks */
U8 dev_mem_block;
} MargaretFreeMemSegment;
} MargaretMemAllocatorOneType;
bool MargaretFreeMemSegment_equal(
const MargaretFreeMemSegment* A, const MargaretFreeMemSegment* B
){
return A->len == B->len && A->dev_mem_block == B->dev_mem_block && A->start == B->start;
}
bool MargaretFreeMemSegment_less(
const MargaretFreeMemSegment* A, const MargaretFreeMemSegment* B
){
if (A->len == B->len) {
if (A->dev_mem_block == B->dev_mem_block) {
return A->start < B->start;
}
return A->dev_mem_block < B->dev_mem_block;
}
return A->len < B->len;
}
bool MargaretFreeMemSegment_equal_resp_align(
const MargaretFreeMemSegment* A, const MargaretFreeMemSegment* B, U8 alignment_exp
){
U64 A_len = U64Segment_get_length_resp_alignment((U64Segment){A->start, A->len}, alignment_exp);
U64 B_len = U64Segment_get_length_resp_alignment((U64Segment){B->start, B->len}, alignment_exp);
return A_len == B_len && A->dev_mem_block == B->dev_mem_block && A->start == B->start;
}
bool MargaretFreeMemSegment_less_resp_align(
const MargaretFreeMemSegment* A, const MargaretFreeMemSegment* B, U8 alignment_exp
){
U64 A_len = U64Segment_get_length_resp_alignment((U64Segment){A->start, A->len}, alignment_exp);
U64 B_len = U64Segment_get_length_resp_alignment((U64Segment){B->start, B->len}, alignment_exp);
if (A_len == B_len) {
if (A->dev_mem_block == B->dev_mem_block) {
return A->start < B->start;
}
return A->dev_mem_block < B->dev_mem_block;
}
return A_len < B_len;
}
typedef const MargaretFreeMemSegment* RefMargaretFreeMemSegment;
#include "../../../gen/l1/eve/margaret/VecMargaretFreeMemSegment.h"
#include "../../../gen/l1/eve/margaret/OptionMargaretFreeMemSegment.h"
#include "../../../gen/l1/eve/margaret/OptionRefMargaretFreeMemSegment.h"
#include "../../../gen/l1_5/eve/margaret/BuffRBTreeByLen_SetMargaretFreeMemSegment.h"
#include "../../../gen/l1_5/eve/margaret/BuffRBTreeByLenRespAlign_SetMargaretFreeMemSegment.h"
#include "../../../gen/l1/eve/margaret/OptionBuffRBTreeByLenRespAlign_SetMargaretFreeMemSegment.h"
typedef struct {
VecMargaretMemAllocatorOneBlock blocks;
OptionBuffRBTreeByLenRespAlign_SetMargaretFreeMemSegment free_space_in_memory[MARGARET_ALLOC_LIMIT_ALIGNMENT_EXP];
VkMemoryPropertyFlags mem_properties;
} MargaretMemAllocatorOneMemType;
#include "../../../gen/l1/eve/margaret/VecMargaretMemAllocatorOneMemType.h"
/* My template instantiator requires the drop method */
void MargaretMemAllocatorOneMemType_drop(MargaretMemAllocatorOneMemType self){
VecMargaretMemAllocatorOneBlock_drop(self.blocks);
// VecBuffRBTreeByLen_SetMargaretFreeMemSegment_drop(self.free_space_inside_buffers);
for (U8 alignment_exp = 0; alignment_exp < MARGARET_ALLOC_LIMIT_ALIGNMENT_EXP; alignment_exp++)
OptionBuffRBTreeByLenRespAlign_SetMargaretFreeMemSegment_drop(self.free_space_in_memory[alignment_exp]);
}
typedef struct {
VkMemoryPropertyFlags mem_properties;
VkBufferUsageFlags usage;
U8 chosen_memory_type;
U8 inner_alignment_exp;
U64 total_occupation;
BuffRBTreeByLen_SetMargaretFreeMemSegment free_space_inside_buffers;
} MargaretBufferKindInfo;
#include "../../../gen/l1/eve/margaret/VecMargaretBufferKindInfo.h"
/* VkDevice and VkPhysicalDevice stay remembered here. Don't forget that, please */
struct MargaretMemAllocator {
VecMargaretMemAllocatorOneMemType mem_types;
VecMargaretBufferKindInfo buffer_types;
double alpha;
VkDevice device;
VkPhysicalDevice physical_device;
};
MargaretMemAllocator MargaretMemAllocator_new(
VkDevice device, VkPhysicalDevice physical_device, SpanMargaretBufferKindDescription buffer_types, double alpha
){
VkPhysicalDeviceMemoryProperties phd_props;
vkGetPhysicalDeviceMemoryProperties(physical_device, &phd_props);
assert(phd_props.memoryTypeCount < VK_MAX_MEMORY_TYPES);
MargaretMemAllocator self = {.buffer_types = VecMargaretBufferKindInfo_new_zeroinit(buffer_types.len),
.alpha = alpha, .device = device, .physical_device = physical_device,
.mem_types = VecMargaretMemAllocatorOneMemType_new_zeroinit(phd_props.memoryTypeCount)};
for (size_t i = 0; i < buffer_types.len; i++) {
const MargaretBufferKindDescription* desc = &buffer_types.data[i];
check(U64_is_2pow(desc->inner_alignment));
/* We create a test buffer to check which memory types will support it. We decide the link between
* buffer kind and memory type PERMANENTLY. Yes, I don't care what the specification says, if your
* buffer memory type support changes with size, EAT A DICK, fuck you, get the segfault you deserve
*/
VkBufferCreateInfo crinfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = desc->inner_alignment, /* Why not */
.usage = desc->usage_flags,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VkBuffer test_buffer;
if (vkCreateBuffer(device, &crinfo, NULL, &test_buffer) != VK_SUCCESS)
abortf("Kill yourself!\n");
VkMemoryRequirements mem_requirements;
vkGetBufferMemoryRequirements(device, test_buffer, &mem_requirements);
U8 first_good_memory_type;
for (U8 mt = 0; mt < (U8)phd_props.memoryTypeCount; mt++) {
if ((mem_requirements.memoryTypeBits & (1u << mt)) != 0 &&
(phd_props.memoryTypes[mt].propertyFlags & desc->memory_properties) == desc->memory_properties) {
first_good_memory_type = mt;
goto found_good_memory_type;
}
}
abortf("No good memory type for %" PRIu64 " buffer kind\n", i);
found_good_memory_type:
vkDestroyBuffer(device, test_buffer, NULL);
self.buffer_types.buf[i] = (MargaretBufferKindInfo){
.mem_properties = desc->memory_properties, .usage = desc->usage_flags,
.chosen_memory_type = first_good_memory_type, .inner_alignment_exp = U64_2pow_log(desc->inner_alignment),
.total_occupation = 0, .free_space_inside_buffers = BuffRBTreeByLen_SetMargaretFreeMemSegment_new()
};
}
assert(self.mem_types.len == phd_props.memoryTypeCount);
for (U32 i = 0; i < phd_props.memoryTypeCount; i++) {
self.mem_types.buf[i].blocks = VecMargaretMemAllocatorOneBlock_new();
for (U8 ae = 0; ae < MARGARET_ALLOC_LIMIT_ALIGNMENT_EXP; ae++) {
self.mem_types.buf[i].free_space_in_memory[ae] = None_BuffRBTreeByLenRespAlign_SetMargaretFreeMemSegment();
}
self.mem_types.buf[i].mem_properties = phd_props.memoryTypes[i].propertyFlags;
}
return self;
}
bool MargaretMemAllocator_request_needs_silence(MargaretMemAllocator* self, MargaretMemAllocatorRequest req){
return false;
// todo
}
bool MargaretMemAllocator_carry_out_request(MargaretMemAllocator* self, VkCommandBuffer cmd_buff, bool silence){
return false;
// todo: add OLD flag to mem allocator and like uh, fuck this shit man bruh lol deng
// todo:
}
void MargaretMemAllocator_wipe_old(MargaretMemAllocator* self){
// todo
}
char* MargaretMemAllocator_get_host_visible_buffer_ptr(
const MargaretMemAllocator* self, const MargaretMemAllocatorBufferPosition* pos){
return NULL;
check(pos->memory_type_id < VK_MAX_MEMORY_TYPES);
const MargaretMemAllocatorOneMemType* memtype = &self->mem_types.buf[pos->memory_type_id];
check((memtype->mem_properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
check(pos->memory_allocation_id < memtype->blocks.len);
const MargaretMemAllocatorOneBlock* bl = &memtype->blocks.buf[pos->memory_allocation_id];
assert(bl->mapped_memory);
/* We could check correctness of this position, but who cares, lol */
return (char*)bl->mapped_memory + pos->offset_in_device_memory_nubble;
}

View File

@ -1,4 +1,6 @@
#include <stdint.h>
#include "../../../l1/core/util.h"
typedef U64 VkDeviceSize;
typedef int VkResult;
@ -12,7 +14,6 @@ const VkStructureType VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 200;
const VkStructureType VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 3000;
typedef int VkBufferCreateFlags;
typedef int VkDeviceSize;
typedef int VkBufferUsageFlags;
typedef int VkSharingMode;
@ -39,6 +40,8 @@ typedef struct {
typedef int VkMemoryPropertyFlags;
const VkMemoryPropertyFlags VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 184;
typedef struct {
VkMemoryPropertyFlags propertyFlags;
// ...