Saving progress on MargaretMemAllocator. The exam is near, can't do this anymore
This commit is contained in:
parent
497808ddeb
commit
49ee178eb6
@ -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);
|
||||
|
||||
@ -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(""),
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
36
src/l1_5/anne/margaret.h
Normal 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
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
// ...
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user