From 71f73964cf9a76c30fb5fce2ec344e8fb41dd2f9 Mon Sep 17 00:00:00 2001 From: Andreew Gregory Date: Thu, 12 Feb 2026 17:54:11 +0300 Subject: [PATCH] Stashing progress... Don't take this commit seriously --- src/l1/anne/alice.h | 5 + src/l2/alice/engine.h | 315 +++++++++++----------------- src/l2/alice/transfer_in_mainloop.h | 186 ++++++++++++++++ src/l2/lucy/glyph_cache.h | 2 - src/l2/margaret/vulkan_utils.h | 32 +++ src/l3/r4/r4.c | 2 + 6 files changed, 343 insertions(+), 199 deletions(-) create mode 100644 src/l2/alice/transfer_in_mainloop.h diff --git a/src/l1/anne/alice.h b/src/l1/anne/alice.h index 76016fe..474344f 100644 --- a/src/l1/anne/alice.h +++ b/src/l1/anne/alice.h @@ -10,6 +10,11 @@ void generate_code_for_alice_on_l1(){ generate_eve_span_company_for_primitive(l, ns, cstr("GenericMeshVertexInc"), true, true); generate_eve_span_company_for_primitive(l, ns, cstr("ShinyMeshVertexInc"), true, true); + /* Helpful utils for sticking your butt into rendering mainloop (transferring stuff to device local + * memory at the right time) */ + generate_eve_span_company_for_primitive(l, ns, cstr("RefAliceBufferUplOnce"), true, false); + generate_eve_span_company_for_primitive(l, ns, cstr("RefAliceTextureUplOnce"), true, false); + /* Engine stuff */ // todo: yes, maybe right now it is not primitive but I surely will make it primitive someday. Right now I don't care generate_List_templ_inst_eve_header(l, ns, (list_instantiation_op){ diff --git a/src/l2/alice/engine.h b/src/l2/alice/engine.h index 78a468f..0432d5b 100644 --- a/src/l2/alice/engine.h +++ b/src/l2/alice/engine.h @@ -3,6 +3,7 @@ #include "model_file.h" #include "../../l1/marie/geom_alg_utils.h" #include "../margaret/vulkan_utils.h" +#include "transfer_in_mainloop.h" #include "../lucy/glyph_render.h" typedef struct { @@ -12,9 +13,6 @@ typedef struct { } PatriciaBuf; typedef struct { - VkImageView diffuse_view; - VkImageView normal_view; - VkImageView specular_view; /* Each generic model has its own descriptor set * It's because it has its own textures. But it also has copies of references to light UBO * Because I am to lazy to create two set layouts for generic model pipeline */ @@ -23,28 +21,21 @@ typedef struct { typedef struct { size_t indexes; - // Option - MargaretSubbuf staging_vbo; - // Option - MargaretSubbuf staging_ebo; // todo: replace TextureDataXXX with MargaretPngPromises TextureDataR8G8B8A8 pixels_diffuse; TextureDataR8G8B8A8 pixels_normal; TextureDataR8 pixels_specular; - MargaretSubbuf staging_diffuse_tex_buf; - MargaretSubbuf staging_normal_tex_buf; - MargaretSubbuf staging_specular_tex_buf; + AliceBufferUplOnce* vbo; + AliceBufferUplOnce* ebo; + + AliceTextureUplOnce* diffuse_texture; + AliceTextureUplOnce* normal_texture; + AliceTextureUplOnce* specular_texture; - MargaretSubbuf vbo; - MargaretSubbuf ebo; PatriciaBuf instance_attr; - MargaretImg diffuse_texture; - MargaretImg normal_texture; - MargaretImg specular_texture; - AliceGenericMeshMemDependantVkObj mem_dependant_vk_obj; bool scheduled_for_deletion; @@ -55,11 +46,8 @@ typedef struct { typedef struct { size_t indexes; - MargaretSubbuf staging_vbo; - MargaretSubbuf staging_ebo; - - MargaretSubbuf vbo; - MargaretSubbuf ebo; + AliceBufferUplOnce* vbo; + AliceBufferUplOnce* ebo; PatriciaBuf instance_attr; bool scheduled_for_deletion; @@ -736,17 +724,12 @@ typedef struct ListNodeAliceGenericMeshHand* RefListNodeAliceGenericMeshHand; typedef struct { ListAliceGenericMeshHand hands; - /* Familiar pattern. Todo: move familiar pattern to l1 codegen. 2 matches so far */ - VecRefListNodeAliceGenericMeshHand to_be_freed_of_old_staging_next_cycle; - VecRefListNodeAliceGenericMeshHand to_be_copied_to_device_next_cycle; VecRefListNodeAliceGenericMeshHand to_be_deleted; } AliceAllMeshesGeneric; AliceAllMeshesGeneric AliceAllMeshesGeneric_new(){ return (AliceAllMeshesGeneric){ .hands = ListAliceGenericMeshHand_new(), - .to_be_freed_of_old_staging_next_cycle = VecRefListNodeAliceGenericMeshHand_new(), - .to_be_copied_to_device_next_cycle = VecRefListNodeAliceGenericMeshHand_new(), .to_be_deleted = VecRefListNodeAliceGenericMeshHand_new(), }; } @@ -757,16 +740,12 @@ typedef struct ListNodeAliceShinyMeshHand* RefListNodeAliceShinyMeshHand; typedef struct { ListAliceShinyMeshHand hands; /* Ah */ - VecRefListNodeAliceShinyMeshHand to_be_freed_of_old_staging_next_cycle; - VecRefListNodeAliceShinyMeshHand to_be_copied_to_device_next_cycle; VecRefListNodeAliceShinyMeshHand to_be_deleted; } AliceAllMeshesShiny; AliceAllMeshesShiny AliceAllMeshesShiny_new(){ return (AliceAllMeshesShiny){ .hands = ListAliceShinyMeshHand_new(), - .to_be_freed_of_old_staging_next_cycle = VecRefListNodeAliceShinyMeshHand_new(), - .to_be_copied_to_device_next_cycle = VecRefListNodeAliceShinyMeshHand_new(), .to_be_deleted = VecRefListNodeAliceShinyMeshHand_new(), }; } @@ -806,6 +785,9 @@ struct Alice { Jane_alice jane; // todo: figure out my own design MargaretSwapchainBundle swfb; + AliceAllSingleUploadBuffers single_upload_buffers; + AliceAllSingleUploadTextures single_upload_textures; + AlicePipeline0UBO pipeline0_ubo; AliceAllMeshesGeneric generic_models; AliceAllMeshesShiny shiny_models; @@ -829,7 +811,8 @@ struct Alice { }; ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const GenericMeshTopology* topology, - AliceGenericMeshTexturePaths t_paths){ + AliceGenericMeshTexturePaths t_paths + ){ ListNodeAliceGenericMeshHand* mm_node = safe_calloc(1, sizeof(ListNodeAliceGenericMeshHand)); AliceGenericMeshHand* mm = &mm_node->el; @@ -838,11 +821,6 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic mm->instance_attr.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, 200); mm->instance_attr.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, 200); - mm->staging_vbo = MargaretBufAllocator_alloc(&alice->staging_buffers, - topology->vertices.len * sizeof(GenericMeshVertex)); - mm->staging_ebo = MargaretBufAllocator_alloc(&alice->staging_buffers, - topology->indexes.len * sizeof(U32)); - // todo: change this, I don't like this at all :( mm->pixels_diffuse = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&t_paths.diffuse_texture_path)); mm->pixels_normal = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&t_paths.normal_texture_path)); @@ -851,38 +829,36 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic VecU8_drop(t_paths.normal_texture_path); VecU8_drop(t_paths.specular_texture_path); - mm->staging_diffuse_tex_buf = MargaretBufAllocator_alloc(&alice->staging_buffers, - mm->pixels_diffuse.pixels.len * sizeof(cvec4)); - mm->staging_normal_tex_buf = MargaretBufAllocator_alloc(&alice->staging_buffers, - mm->pixels_normal.pixels.len * sizeof(cvec4)); - mm->staging_specular_tex_buf = MargaretBufAllocator_alloc(&alice->staging_buffers, - mm->pixels_specular.pixels.len * sizeof(U8)); + mm->vbo = AliceBufferUplOnce_new(topology->vertices.len * sizeof(GenericMeshVertex), + &alice->staging_buffers, &alice->dev_local_buffers); + mm->ebo = AliceBufferUplOnce_new(topology->indexes.len * sizeof(U32), + &alice->staging_buffers, &alice->dev_local_buffers); - mm->vbo = MargaretBufAllocator_alloc(&alice->dev_local_buffers, - topology->vertices.len * sizeof(GenericMeshVertex)); - mm->ebo = MargaretBufAllocator_alloc(&alice->dev_local_buffers, - topology->indexes.len * sizeof(U32)); - - mm->diffuse_texture = MargaretImgAllocator_alloc(&alice->dev_local_images, - mm->pixels_diffuse.width, mm->pixels_diffuse.height, - VK_FORMAT_R8G8B8A8_SRGB, - VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); - mm->normal_texture = MargaretImgAllocator_alloc(&alice->dev_local_images, - mm->pixels_normal.width, mm->pixels_normal.height, - VK_FORMAT_R8G8B8A8_UNORM, - VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); - mm->specular_texture = MargaretImgAllocator_alloc(&alice->dev_local_images, - mm->pixels_specular.width, mm->pixels_specular.height, - VK_FORMAT_R8_UNORM, - VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); + mm->diffuse_texture = AliceTextureUplOnce_new(mm->pixels_diffuse.width, mm->pixels_diffuse.height, + VK_FORMAT_R8G8B8A8_SRGB, sizeof(cvec4), + VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + &alice->staging_buffers, &alice->dev_local_images); + mm->normal_texture = AliceTextureUplOnce_new(mm->pixels_normal.width, mm->pixels_normal.height, + VK_FORMAT_R8G8B8A8_SRGB, sizeof(cvec4), + VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + &alice->staging_buffers, &alice->dev_local_images); + mm->specular_texture = AliceTextureUplOnce_new(mm->pixels_specular.width, mm->pixels_specular.height, + VK_FORMAT_R8_SRGB, sizeof(U8), + VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + &alice->staging_buffers, &alice->dev_local_images); + AliceAllSingleUploadBuffers_register(&alice->single_upload_buffers, mm->vbo); + AliceAllSingleUploadBuffers_register(&alice->single_upload_buffers, mm->ebo); + AliceAllSingleUploadTextures_register(&alice->single_upload_textures, mm->diffuse_texture); + AliceAllSingleUploadTextures_register(&alice->single_upload_textures, mm->normal_texture); + AliceAllSingleUploadTextures_register(&alice->single_upload_textures, mm->specular_texture); mm->scheduled_for_deletion = false; /* We allocated enough memory, but now it's time to actually fill staging buffers */ - /* Filleing staging VBO */ - assert(mm->staging_vbo.len >= topology->vertices.len * sizeof(GenericMeshVertex)); - assert(mm->vbo.len >= topology->vertices.len * sizeof(GenericMeshVertex)); - GenericMeshVertex* staging_vbo = (GenericMeshVertex*)MargaretSubbuf_get_mapped(&mm->staging_vbo); + /* Filling staging VBO */ + assert(mm->vbo->staging.len >= topology->vertices.len * sizeof(GenericMeshVertex)); + assert(mm->vbo->device_buf.len >= topology->vertices.len * sizeof(GenericMeshVertex)); + GenericMeshVertex* staging_vbo = (GenericMeshVertex*)AliceBufferUplOnce_get_mapped_staging(mm->vbo); for (U64 i = 0; i < topology->vertices.len; i++) { staging_vbo[i].base = topology->vertices.buf[i]; } @@ -912,53 +888,47 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic /* Filling EBO is easy */ assert(topology->indexes.len == mm->indexes); size_t ebo_len = topology->indexes.len * sizeof(U32); - assert(mm->ebo.len >= ebo_len); - U32* staging_ebo = (U32*)MargaretSubbuf_get_mapped(&mm->staging_ebo); + assert(mm->ebo->staging.len >= ebo_len); + U32* staging_ebo = (U32*)AliceBufferUplOnce_get_mapped_staging(mm->ebo); memcpy(staging_ebo, topology->indexes.buf, ebo_len); /* Filling staging textures from memory pixel data */ /* todo: do it immediately ON THE READ */ - memcpy(MargaretSubbuf_get_mapped(&mm->staging_diffuse_tex_buf), mm->pixels_diffuse.pixels.buf, + memcpy(AliceTextureUplOnce_get_mapped_staging(mm->diffuse_texture), mm->pixels_diffuse.pixels.buf, TextureDataR8G8B8A8_get_size_in_bytes(&mm->pixels_diffuse)); - memcpy(MargaretSubbuf_get_mapped(&mm->staging_normal_tex_buf), mm->pixels_normal.pixels.buf, + memcpy(AliceTextureUplOnce_get_mapped_staging(mm->normal_texture), mm->pixels_normal.pixels.buf, TextureDataR8G8B8A8_get_size_in_bytes(&mm->pixels_normal)); - memcpy(MargaretSubbuf_get_mapped(&mm->staging_specular_tex_buf), mm->pixels_specular.pixels.buf, + memcpy(AliceTextureUplOnce_get_mapped_staging(mm->specular_texture), mm->pixels_specular.pixels.buf, TextureDataR8_get_size_in_bytes(&mm->pixels_specular)); // todo: that is about time when we can delete mm->pixels_* buffers. They are still wasting space out there // todo: BUt I won't do it, because I chose inplace texture reading (from png) + /* But now we are filling AliceGenericMeshMemDependantVkObj. If we ever gonna do defragmentation, * this step would have to be repeated */ - AliceGenericMeshMemDependantVkObj P = (AliceGenericMeshMemDependantVkObj){ - .diffuse_view = margaret_create_view_for_image(alice->device, mm->diffuse_texture.a.image, - VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT), - .normal_view = margaret_create_view_for_image(alice->device, mm->normal_texture.a.image, - VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT), - .specular_view = margaret_create_view_for_image(alice->device, mm->specular_texture.a.image, - VK_FORMAT_R8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT), - .p_0a_set_0 = margaret_allocate_descriptor_set(alice->device, - alice->descriptor_pool, alice->pipeline_hands_0a.descriptor_set_layout), - }; - mm->mem_dependant_vk_obj = P; + + VkDescriptorSet P = margaret_allocate_descriptor_set(alice->device, + alice->descriptor_pool, alice->pipeline_hands_0a.descriptor_set_layout); + mm->mem_dependant_vk_obj.p_0a_set_0 = P; VkDescriptorBufferInfo buffer_info_for_descriptor_0_in_set_0a = { .buffer = MargaretSubbuf_get_buffer(&alice->pipeline0_ubo.device_local), .offset = alice->pipeline0_ubo.device_local.start, .range = sizeof(Pipeline0UBO), }; VkDescriptorImageInfo image_info_for_descriptor_1_in_set_0a = { - .sampler = alice->linear_sampler, .imageView = P.diffuse_view, + .sampler = alice->linear_sampler, .imageView = mm->diffuse_texture->view, .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, }; VkDescriptorImageInfo image_info_for_descriptor_2_in_set_0a = { - .sampler = alice->nearest_sampler, .imageView = P.normal_view, + .sampler = alice->nearest_sampler, .imageView = mm->normal_texture->view, .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, }; VkDescriptorImageInfo image_info_for_descriptor_3_in_set_0a = { - .sampler = alice->nearest_sampler, .imageView = P.specular_view, + .sampler = alice->nearest_sampler, .imageView = mm->specular_texture->view, .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, }; VkWriteDescriptorSet writes_in_descriptor_set[] = { { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = P.p_0a_set_0, + .dstSet = P, .dstBinding = 0, .dstArrayElement = 0, .descriptorCount = 1, @@ -967,7 +937,7 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic }, { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = P.p_0a_set_0, + .dstSet = P, .dstBinding = 1, .dstArrayElement = 0, .descriptorCount = 1, @@ -976,7 +946,7 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic }, { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = P.p_0a_set_0, + .dstSet = P, .dstBinding = 2, .dstArrayElement = 0, .descriptorCount = 1, @@ -985,7 +955,7 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic }, { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = P.p_0a_set_0, + .dstSet = P, .dstBinding = 3, .dstArrayElement = 0, .descriptorCount = 1, @@ -996,12 +966,10 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const Generic vkUpdateDescriptorSets(alice->device, ARRAY_SIZE(writes_in_descriptor_set), writes_in_descriptor_set, 0, NULL); ListAliceGenericMeshHand_insert_node(&alice->generic_models.hands, mm_node); - VecRefListNodeAliceGenericMeshHand_append(&alice->generic_models.to_be_copied_to_device_next_cycle, mm_node); return mm_node; } ListNodeAliceShinyMeshHand* Alice_add_shiny_mesh(Alice* alice, const ShinyMeshTopology* topology){ - ListNodeAliceShinyMeshHand* mm_node = safe_calloc(1, sizeof(ListNodeAliceShinyMeshHand)); AliceShinyMeshHand* mm = &mm_node->el; @@ -1011,23 +979,20 @@ ListNodeAliceShinyMeshHand* Alice_add_shiny_mesh(Alice* alice, const ShinyMeshTo mm->instance_attr.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, 128); mm->instance_attr.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, 128); - mm->staging_vbo = MargaretBufAllocator_alloc(&alice->staging_buffers, - topology->vertices.len * sizeof(ShinyMeshVertex)); - mm->staging_ebo = MargaretBufAllocator_alloc(&alice->staging_buffers, - topology->indexes.len * sizeof(U32)); - - mm->vbo = MargaretBufAllocator_alloc(&alice->dev_local_buffers, - topology->vertices.len * sizeof(ShinyMeshVertex)); - mm->ebo = MargaretBufAllocator_alloc(&alice->dev_local_buffers, - topology->indexes.len * sizeof(U32)); + mm->vbo = AliceBufferUplOnce_new(topology->vertices.len * sizeof(ShinyMeshVertex), + &alice->staging_buffers, &alice->dev_local_buffers); + mm->ebo = AliceBufferUplOnce_new(topology->indexes.len * sizeof(U32), + &alice->staging_buffers, &alice->dev_local_buffers); ListAliceShinyMeshHand_insert_node(&alice->shiny_models.hands, mm_node); - VecRefListNodeAliceShinyMeshHand_append(&alice->shiny_models.to_be_copied_to_device_next_cycle, mm_node); + AliceAllSingleUploadBuffers_register(&alice->single_upload_buffers, mm->vbo); + AliceAllSingleUploadBuffers_register(&alice->single_upload_buffers, mm->ebo); + /* We allocated enough memory, now it's time to actually fill staging buffers */ /* And we start by filling staging VBO */ - assert(mm->staging_vbo.len >= topology->vertices.len * sizeof(ShinyMeshVertex)); - assert(mm->vbo.len >= topology->vertices.len * sizeof(ShinyMeshVertex)); - ShinyMeshVertex* staging_vbo = (ShinyMeshVertex*)MargaretSubbuf_get_mapped(&mm->staging_vbo); + assert(mm->vbo->staging.len >= topology->vertices.len * sizeof(ShinyMeshVertex)); + assert(mm->vbo->device_buf.len >= topology->vertices.len * sizeof(ShinyMeshVertex)); + ShinyMeshVertex* staging_vbo = (ShinyMeshVertex*)AliceBufferUplOnce_get_mapped_staging(mm->vbo); for (U64 i = 0; i < topology->vertices.len; i++) { staging_vbo[i].base = topology->vertices.buf[i]; } @@ -1042,21 +1007,41 @@ ListNodeAliceShinyMeshHand* Alice_add_shiny_mesh(Alice* alice, const ShinyMeshTo vec3 norm = vec3_normalize(vec3_cross(vec3_minus_vec3(p1, p0), vec3_minus_vec3(p2, p0))); staging_vbo[v0].normal = staging_vbo[v1].normal = staging_vbo[v2].normal = norm; } - /* Filling staging EBO is super-duper easy */ + /* Filling staging EBO is super-duper easy */ assert(topology->indexes.len == mm->indexes); size_t ebo_len = topology->indexes.len * sizeof(U32); - assert(mm->ebo.len >= ebo_len); - U32* staging_ebo = (U32*)MargaretSubbuf_get_mapped(&mm->staging_ebo); + assert(mm->ebo->staging.len >= ebo_len); + U32* staging_ebo = (U32*)AliceBufferUplOnce_get_mapped_staging(mm->ebo); memcpy(staging_ebo, topology->indexes.buf, ebo_len); return mm_node; } + +void Alice_delete_generic_mesh(Alice* alice, ListNodeAliceGenericMeshHand* hand) { + AliceAllSingleUploadBuffers_delete(&alice->single_upload_buffers, hand->el.vbo); + AliceAllSingleUploadBuffers_delete(&alice->single_upload_buffers, hand->el.ebo); + AliceAllSingleUploadTextures_delete(&alice->single_upload_textures, hand->el.diffuse_texture); + AliceAllSingleUploadTextures_delete(&alice->single_upload_textures, hand->el.normal_texture); + AliceAllSingleUploadTextures_delete(&alice->single_upload_textures, hand->el.specular_texture); + hand->el.normal_texture = hand->el.normal_texture = hand->el.specular_texture = NULL; + hand->el.vbo = hand->el.ebo = NULL; + VecRefListNodeAliceGenericMeshHand_append(&alice->generic_models.to_be_deleted, hand); +} + +void Alice_delete_shiny_mesh(Alice* alice, ListNodeAliceShinyMeshHand* hand) { + AliceAllSingleUploadBuffers_delete(&alice->single_upload_buffers, hand->el.vbo); + AliceAllSingleUploadBuffers_delete(&alice->single_upload_buffers, hand->el.ebo); + hand->el.vbo = hand->el.ebo = NULL; + VecRefListNodeAliceShinyMeshHand_append(&alice->shiny_models.to_be_deleted, hand); +} + + void AliceGenericMeshHand_resize_instance_arr(Alice* alice, AliceGenericMeshHand* self, U64 new_count){ U64 needed_length = new_count * sizeof(GenericMeshInstance); if (self->instance_attr.staging.len < needed_length) { printf("Alice generic model instance staging Buffer: Gotta replace %lu with %lu\n", - self->staging_vbo.len, needed_length); + self->instance_attr.staging.len, needed_length); MargaretBufAllocator_expand_or_move_old_host_visible( &alice->staging_buffers, &self->instance_attr.staging, needed_length); } @@ -1094,108 +1079,34 @@ void AliceShinyMeshHand_set_inst(AliceShinyMeshHand* self, size_t instance, Shin tr_inv.x.z, tr_inv.y.z, tr_inv.z.z ); } -void AliceAllMeshesGeneric__resolve_mesh_creation(Alice* alice, AliceAllMeshesGeneric* self){ - for (size_t i = 0; i < self->to_be_freed_of_old_staging_next_cycle.len; i++) { - AliceGenericMeshHand* mm = &self->to_be_freed_of_old_staging_next_cycle.buf[i]->el; - assert(mm->staging_vbo.len != 0); - assert(mm->staging_ebo.len != 0); - MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_vbo); - MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_ebo); - mm->staging_vbo.len = 0; - mm->staging_ebo.len = 0; - } - - for (size_t i = 0; i < self->to_be_copied_to_device_next_cycle.len; i++) { - ListNodeAliceGenericMeshHand* mm_node = self->to_be_copied_to_device_next_cycle.buf[i]; - AliceGenericMeshHand* mm = &mm_node->el; - assert(mm->staging_vbo.len != 0); - assert(mm->staging_ebo.len != 0); - if (mm->scheduled_for_deletion) - continue; - margaret_rec_cmd_copy_buffer_one_to_one(alice->transfer_command_buf, &mm->staging_vbo, &mm->vbo); - margaret_rec_cmd_copy_buffer_one_to_one(alice->transfer_command_buf, &mm->staging_ebo, &mm->ebo); - margaret_rec_cmd_copy_buffer_to_image_one_to_one_color_aspect(alice->transfer_command_buf, - &mm->staging_diffuse_tex_buf, &mm->diffuse_texture, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT); - margaret_rec_cmd_copy_buffer_to_image_one_to_one_color_aspect(alice->transfer_command_buf, - &mm->staging_normal_tex_buf, &mm->normal_texture, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT); - margaret_rec_cmd_copy_buffer_to_image_one_to_one_color_aspect(alice->transfer_command_buf, - &mm->staging_specular_tex_buf, &mm->specular_texture, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT); - VecRefListNodeAliceGenericMeshHand_append(&self->to_be_freed_of_old_staging_next_cycle, mm_node); - } +void AliceAllMeshesGeneric__resolve_on_another_frame(Alice* alice, AliceAllMeshesGeneric* self){ for (size_t i = 0; i < self->to_be_deleted.len; i++) { ListNodeAliceGenericMeshHand* mm_node = self->to_be_deleted.buf[i]; AliceGenericMeshHand* mm = &mm_node->el; assert(mm->scheduled_for_deletion); - if (mm->staging_vbo.len != 0) - MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_vbo); - if (mm->staging_ebo.len != 0) - MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_ebo); - if (mm->staging_diffuse_tex_buf.len != 0) - MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_diffuse_tex_buf); - if (mm->staging_normal_tex_buf.len != 0) - MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_normal_tex_buf); - if (mm->staging_specular_tex_buf.len != 0) - MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_specular_tex_buf); - - MargaretBufAllocator_free(&alice->dev_local_buffers, mm->vbo); - MargaretBufAllocator_free(&alice->dev_local_buffers, mm->ebo); - MargaretImgAllocator_free(&alice->dev_local_images, mm->diffuse_texture.a); - MargaretImgAllocator_free(&alice->dev_local_images, mm->normal_texture.a); - MargaretImgAllocator_free(&alice->dev_local_images, mm->specular_texture.a); - + assert(mm->vbo == NULL); + assert(mm->ebo == NULL); + MargaretBufAllocator_free(&alice->staging_buffers, mm->instance_attr.staging); + MargaretBufAllocator_free(&alice->dev_local_buffers, mm->instance_attr.device_local); // todo: the problem is, here we don't free some memory stored in AliceGenericMeshHand to store texture. // todo: but the truth is: I am gonna get rid of pixels_{,,} fields very soon, so AliceGenericMeshHand would // todo: be primitive again, without stupid crap ListAliceGenericMeshHand_erase_by_it(&self->hands, mm_node); } - - self->to_be_freed_of_old_staging_next_cycle.len = 0; - self->to_be_copied_to_device_next_cycle.len = 0; self->to_be_deleted.len = 0; } -void AliceAllMeshesShiny__resolve_mesh_creation(Alice* alice, AliceAllMeshesShiny* self){ - for (size_t i = 0; i < self->to_be_freed_of_old_staging_next_cycle.len; i++) { - AliceShinyMeshHand* mm = &self->to_be_freed_of_old_staging_next_cycle.buf[i]->el; - assert(mm->staging_vbo.len != 0); - assert(mm->staging_ebo.len != 0); - MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_vbo); - MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_ebo); - mm->staging_vbo.len = 0; - mm->staging_ebo.len = 0; - } - - for (size_t i = 0; i < self->to_be_copied_to_device_next_cycle.len; i++) { - ListNodeAliceShinyMeshHand* mm_node = self->to_be_copied_to_device_next_cycle.buf[i]; - AliceShinyMeshHand* mm = &mm_node->el; - assert(mm->staging_vbo.len != 0); - assert(mm->staging_ebo.len != 0); - if (mm->scheduled_for_deletion) - continue; - margaret_rec_cmd_copy_buffer_one_to_one(alice->transfer_command_buf, &mm->staging_vbo, &mm->vbo); - margaret_rec_cmd_copy_buffer_one_to_one(alice->transfer_command_buf, &mm->staging_ebo, &mm->ebo); - VecRefListNodeAliceShinyMeshHand_append(&self->to_be_freed_of_old_staging_next_cycle, mm_node); - } +void AliceAllMeshesShiny__resolve_on_another_frame(Alice* alice, AliceAllMeshesShiny* self){ for (size_t i = 0; i < self->to_be_deleted.len; i++) { ListNodeAliceShinyMeshHand* mm_node = self->to_be_deleted.buf[i]; AliceShinyMeshHand* mm = &mm_node->el; assert(mm->scheduled_for_deletion); - if (mm->staging_vbo.len != 0) - MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_vbo); - if (mm->staging_ebo.len != 0) - MargaretBufAllocator_free(&alice->staging_buffers, mm->staging_ebo); - - MargaretBufAllocator_free(&alice->dev_local_buffers, mm->vbo); - MargaretBufAllocator_free(&alice->dev_local_buffers, mm->ebo); - + assert(mm->vbo == NULL); + assert(mm->ebo == NULL); + MargaretBufAllocator_free(&alice->staging_buffers, mm->instance_attr.staging); + MargaretBufAllocator_free(&alice->dev_local_buffers, mm->instance_attr.device_local); ListAliceShinyMeshHand_erase_by_it(&self->hands, mm_node); } - - self->to_be_freed_of_old_staging_next_cycle.len = 0; - self->to_be_copied_to_device_next_cycle.len = 0; self->to_be_deleted.len = 0; } @@ -1206,8 +1117,8 @@ void AliceAllMeshesShiny__resolve_mesh_creation(Alice* alice, AliceAllMeshesShin * 3) As mentioned before, Pipeline0UBO also gets copied */ void AliceScene__another_frame(Alice* alice) { - AliceAllMeshesGeneric__resolve_mesh_creation(alice, &alice->generic_models); - AliceAllMeshesShiny__resolve_mesh_creation(alice, &alice->shiny_models); + AliceAllMeshesGeneric__resolve_on_another_frame(alice, &alice->generic_models); + AliceAllMeshesShiny__resolve_on_another_frame(alice, &alice->shiny_models); for (ListNodeAliceGenericMeshHand* mm_node = alice->generic_models.hands.first; mm_node; mm_node = mm_node->next) { AliceGenericMeshHand* mm = &mm_node->el; @@ -1291,9 +1202,9 @@ void alice_reset_and_record_command_buffer_0(Alice* alice, mat4 proj_cam_t) { AliceGenericMeshHand* model = &mm_node->el; VkDescriptorSet model_indiv_descriptor_set_0 = model->mem_dependant_vk_obj.p_0a_set_0; - const MargaretSubbuf* dev_local_vbo = &model->vbo; + const MargaretSubbuf* dev_local_vbo = &model->vbo->device_buf; const MargaretSubbuf* dev_local_inst_attr = &model->instance_attr.device_local; - const MargaretSubbuf* dev_local_ebo = &model->ebo; + const MargaretSubbuf* dev_local_ebo = &model->ebo->device_buf; // const vkCmdBindVertexBuffers(alice->rendering_command_buf_0, 0, 2, (VkBuffer[]){ @@ -1319,9 +1230,9 @@ void alice_reset_and_record_command_buffer_0(Alice* alice, mat4 proj_cam_t) { 1, &alice->descriptor_set_for_pipeline_0b, 0, NULL); for (ListNodeAliceShinyMeshHand* mm_node = alice->shiny_models.hands.first; mm_node; mm_node = mm_node->next) { const AliceShinyMeshHand* model = &mm_node->el; - const MargaretSubbuf* dev_local_vbo = &model->vbo; + const MargaretSubbuf* dev_local_vbo = &model->vbo->device_buf; const MargaretSubbuf* dev_local_inst_attr = &model->instance_attr.device_local; - const MargaretSubbuf* dev_local_ebo = &model->ebo; + const MargaretSubbuf* dev_local_ebo = &model->ebo->device_buf; vkCmdBindVertexBuffers(alice->rendering_command_buf_0, 0, 2, (VkBuffer[]){ MargaretSubbuf_get_buffer(dev_local_vbo), MargaretSubbuf_get_buffer(dev_local_inst_attr) }, (VkDeviceSize[]){ dev_local_vbo->start, dev_local_inst_attr->start }); @@ -1483,6 +1394,13 @@ void alice_frame_drawing(Alice* alice) { alice->callbacks.on_another_frame(alice->guest, (float)(alice->wl.cur_frame_time - alice->wl.last_frame_time) / 1000); margaret_reset_and_begin_command_buffer(alice->transfer_command_buf); + + /* Literally everything, including lucy cache, depends on these two steps */ + AliceAllSingleUploadBuffers__resolve_on_another_frame(&alice->single_upload_buffers, + &alice->staging_buffers, &alice->dev_local_buffers, alice->transfer_command_buf); + AliceAllSingleUploadTextures__resolve_on_another_frame(&alice->single_upload_textures, + &alice->staging_buffers, &alice->dev_local_images, alice->transfer_command_buf); + AliceScene__another_frame(alice); LucyGlyphCache_another_frame(&alice->lucy_cache); LucyRenderer_another_frame(&alice->lucy_renderer); @@ -1961,8 +1879,8 @@ Alice* Alice_new(){ // todo: inquire about the uniform buffer alignment and storage buffer alignment alice->dev_local_buffers = MargaretBufAllocator_new(alice->device, alice->physical_device, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT - /* | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT */, + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT , mem_type_id_device_local, 6, false, 10000); alice->dev_local_images = MargaretImgAllocator_new(alice->device, alice->physical_device, @@ -1974,6 +1892,9 @@ Alice* Alice_new(){ alice->device, alice->queue_fam, swapchain_details_res.ok, alice->surface, alice->render_pass_1, NULL); + alice->single_upload_buffers = AliceAllSingleUploadBuffers_new(); + alice->single_upload_textures = AliceAllSingleUploadTextures_new(); + alice->generic_models = AliceAllMeshesGeneric_new(); alice->shiny_models = AliceAllMeshesShiny_new(); alice->pipeline0_ubo.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, sizeof(Pipeline0UBO)); diff --git a/src/l2/alice/transfer_in_mainloop.h b/src/l2/alice/transfer_in_mainloop.h new file mode 100644 index 0000000..fac1fc6 --- /dev/null +++ b/src/l2/alice/transfer_in_mainloop.h @@ -0,0 +1,186 @@ +#pragma once + +#include "../margaret/vulkan_utils.h" + +/* Handler of a read-only buffer that can be uploaded and deleted at any time with it's staging buffer automatically + * deleted (Similar to what AliceTextureUploadedOnce does to textures) */ +typedef struct { + MargaretSubbuf staging; + MargaretSubbuf device_buf; + bool scheduled_for_deletion; +} AliceBufferUplOnce; + +typedef AliceBufferUplOnce* RefAliceBufferUplOnce; + +#include "../../../gen/l1/eve/alice/VecRefAliceBufferUplOnce.h" + +/* Handler of a texture that can be uploaded and deleted at any time with it's staging buffer automatically deleted. + * Stores VkImageView as a bonus */ +typedef struct { + MargaretSubbuf staging; + MargaretImg img; + VkImageView view; + bool scheduled_for_deletion; +} AliceTextureUplOnce; + +typedef AliceTextureUplOnce* RefAliceTextureUplOnce; + +#include "../../../gen/l1/eve/alice/VecRefAliceTextureUplOnce.h" + +typedef struct { + VecRefAliceBufferUplOnce to_be_freed_of_old_staging_next_cycle; + VecRefAliceBufferUplOnce to_be_copied_to_device_next_cycle; + VecRefAliceBufferUplOnce to_be_deleted; +} AliceAllSingleUploadBuffers; + +AliceAllSingleUploadBuffers AliceAllSingleUploadBuffers_new() { + return (AliceAllSingleUploadBuffers){ + .to_be_freed_of_old_staging_next_cycle = VecRefAliceBufferUplOnce_new(), + .to_be_copied_to_device_next_cycle = VecRefAliceBufferUplOnce_new(), + .to_be_deleted = VecRefAliceBufferUplOnce_new(), + }; +} + +typedef struct { + VecRefAliceTextureUplOnce to_be_freed_of_old_staging_next_cycle; + VecRefAliceTextureUplOnce to_be_copied_to_device_next_cycle; + VecRefAliceTextureUplOnce to_be_deleted; +} AliceAllSingleUploadTextures; + +AliceAllSingleUploadTextures AliceAllSingleUploadTextures_new(){ + return (AliceAllSingleUploadTextures){ + .to_be_freed_of_old_staging_next_cycle = VecRefAliceTextureUplOnce_new(), + .to_be_copied_to_device_next_cycle = VecRefAliceTextureUplOnce_new(), + .to_be_deleted = VecRefAliceTextureUplOnce_new(), + }; +} + +void AliceAllSingleUploadBuffers__resolve_on_another_frame(AliceAllSingleUploadBuffers* self, + MargaretBufAllocator* staging_buffers, MargaretBufAllocator* dev_local_buffers, VkCommandBuffer transfer_cmd_buffer + ) { + for (size_t i = 0; i < self->to_be_freed_of_old_staging_next_cycle.len; i++) { + AliceBufferUplOnce* mm = self->to_be_freed_of_old_staging_next_cycle.buf[i]; + assert(mm->staging.len != 0); + MargaretBufAllocator_free(staging_buffers, mm->staging); + mm->staging.len = 0; + } + + for (size_t i = 0; i < self->to_be_copied_to_device_next_cycle.len; i++) { + AliceBufferUplOnce* mm = self->to_be_copied_to_device_next_cycle.buf[i]; + assert(mm->staging.len != 0); + if (mm->scheduled_for_deletion) + continue; + margaret_rec_cmd_copy_buffer_one_to_one(transfer_cmd_buffer, &mm->staging, &mm->device_buf); + VecRefAliceBufferUplOnce_append(&self->to_be_freed_of_old_staging_next_cycle, mm); + } + for (size_t i = 0; i < self->to_be_deleted.len; i++) { + AliceBufferUplOnce* mm = self->to_be_deleted.buf[i]; + assert(mm->scheduled_for_deletion); + if (mm->staging.len != 0) + MargaretBufAllocator_free(staging_buffers, mm->staging); + MargaretBufAllocator_free(dev_local_buffers, mm->device_buf); + free(mm); + } + + self->to_be_freed_of_old_staging_next_cycle.len = 0; + self->to_be_copied_to_device_next_cycle.len = 0; + self->to_be_deleted.len = 0; +} + +void AliceAllSingleUploadTextures__resolve_on_another_frame(AliceAllSingleUploadTextures* self, + MargaretBufAllocator* staging_buffers, MargaretImgAllocator* dev_local_images, VkCommandBuffer transfer_cmd_buffer + ) { + for (size_t i = 0; i < self->to_be_freed_of_old_staging_next_cycle.len; i++) { + AliceTextureUplOnce* mm = self->to_be_freed_of_old_staging_next_cycle.buf[i]; + assert(mm->staging.len != 0); + MargaretBufAllocator_free(staging_buffers, mm->staging); + mm->staging.len = 0; + } + + for (size_t i = 0; i < self->to_be_copied_to_device_next_cycle.len; i++) { + AliceTextureUplOnce* mm = self->to_be_copied_to_device_next_cycle.buf[i]; + assert(mm->staging.len != 0); + if (mm->scheduled_for_deletion) + continue; + margaret_rec_cmd_copy_buffer_to_image_one_to_one_color_aspect(transfer_cmd_buffer, + &mm->staging, &mm->img, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT); + VecRefAliceTextureUplOnce_append(&self->to_be_freed_of_old_staging_next_cycle, mm); + } + for (size_t i = 0; i < self->to_be_deleted.len; i++) { + AliceTextureUplOnce* mm = self->to_be_deleted.buf[i]; + assert(mm->scheduled_for_deletion); + if (mm->staging.len != 0) + MargaretBufAllocator_free(staging_buffers, mm->staging); + + MargaretImgAllocator_free(dev_local_images, mm->img.a); + vkDestroyImageView(dev_local_images->device, mm->view, NULL); + free(mm); + } + + self->to_be_freed_of_old_staging_next_cycle.len = 0; + self->to_be_copied_to_device_next_cycle.len = 0; + self->to_be_deleted.len = 0; +} + + + +/* Doesn't get automatically added to `to_be_copied_to_device_next_cycle` */ +AliceBufferUplOnce* AliceBufferUplOnce_new(size_t len, + MargaretBufAllocator* staging_buffers, MargaretBufAllocator* dev_local_buffers + ) { + AliceBufferUplOnce* res = (AliceBufferUplOnce*)safe_malloc(sizeof(AliceBufferUplOnce)); + res->staging = MargaretBufAllocator_alloc(staging_buffers, len); + res->device_buf = MargaretBufAllocator_alloc(dev_local_buffers, len); + res->scheduled_for_deletion = false; + return res; +} + +void* AliceBufferUplOnce_get_mapped_staging(AliceBufferUplOnce* self) { + return MargaretSubbuf_get_mapped(&self->staging); +} + +void AliceAllSingleUploadBuffers_register(AliceAllSingleUploadBuffers* self, AliceBufferUplOnce* obj) { + assert(obj->staging.len > 0); + assert(!obj->scheduled_for_deletion); + VecRefAliceBufferUplOnce_append(&self->to_be_copied_to_device_next_cycle, obj); +} + +void AliceAllSingleUploadBuffers_delete(AliceAllSingleUploadBuffers* self, AliceBufferUplOnce* obj) { + assert(obj); + obj->scheduled_for_deletion = true; + VecRefAliceBufferUplOnce_append(&self->to_be_deleted, obj); +} + + + +/* Doesn't get automatically added to `to_be_copied_to_device_next_cycle` + * Only works for VK_IMAGE_ASPECT_COLOR_BIT images */ +AliceTextureUplOnce* AliceTextureUplOnce_new(U64 width, U64 height, U64 pixel_sz, VkFormat format, + VkImageUsageFlags usage, MargaretBufAllocator* staging_buffers, MargaretImgAllocator* dev_local_images + ) { + assert(pixel_sz == margaret_singleplane_format_to_sizeof_type(format)); + AliceTextureUplOnce* res = (AliceTextureUplOnce*)safe_malloc(sizeof(AliceTextureUplOnce)); + res->staging = MargaretBufAllocator_alloc(staging_buffers, width * height * pixel_sz); + res->img = MargaretImgAllocator_alloc(dev_local_images, width, height, format, usage); + res->view = margaret_create_view_for_image(dev_local_images->device, res->img.a.image, + format, VK_IMAGE_ASPECT_COLOR_BIT); + res->scheduled_for_deletion = false; + return res; +} + +void* AliceTextureUplOnce_get_mapped_staging(AliceTextureUplOnce* self) { + return MargaretSubbuf_get_mapped(&self->staging); +} + +void AliceAllSingleUploadTextures_register(AliceAllSingleUploadTextures* self, AliceTextureUplOnce* obj) { + assert(obj->staging.len > 0); + assert(!obj->scheduled_for_deletion); + VecRefAliceTextureUplOnce_append(&self->to_be_copied_to_device_next_cycle, obj); +} + +void AliceAllSingleUploadTextures_delete(AliceAllSingleUploadTextures* self, AliceTextureUplOnce* obj) { + assert(obj); + obj->scheduled_for_deletion = true; + VecRefAliceTextureUplOnce_append(&self->to_be_deleted, obj); +} diff --git a/src/l2/lucy/glyph_cache.h b/src/l2/lucy/glyph_cache.h index 2f21242..fdb1570 100644 --- a/src/l2/lucy/glyph_cache.h +++ b/src/l2/lucy/glyph_cache.h @@ -13,8 +13,6 @@ #define LUCY_MAX_DESCRIPTOR_COUNT 100 -typedef U32 lucy_image_index_t; - typedef struct { /* This value is actually Option. If staging_buffer is already deleted (after it is no longer used), * staging_buffer.len will be 0 */ diff --git a/src/l2/margaret/vulkan_utils.h b/src/l2/margaret/vulkan_utils.h index 72b26d4..63f9a43 100644 --- a/src/l2/margaret/vulkan_utils.h +++ b/src/l2/margaret/vulkan_utils.h @@ -1246,3 +1246,35 @@ void margaret_rec_cmd_copy_buffer_to_image_one_to_one_color_aspect( }); dst->current_layout = dst_new_layout; } + +U64 margaret_singleplane_format_to_sizeof_type(VkFormat type){ + switch (type) { + case VK_FORMAT_R32G32B32A32_SFLOAT: return 16; + case VK_FORMAT_R32G32B32_SFLOAT: return 12; + case VK_FORMAT_R32G32_SFLOAT: return 8; + case VK_FORMAT_R32_SFLOAT: return 4; + case VK_FORMAT_R16_SFLOAT: return 2; + case VK_FORMAT_R16G16_SFLOAT: return 4; + case VK_FORMAT_R16G16B16_SFLOAT: return 6; + case VK_FORMAT_R16G16B16A16_SFLOAT: return 8; + + case VK_FORMAT_R16_UNORM: return 2; + case VK_FORMAT_R16G16_UNORM: return 4; + case VK_FORMAT_R16G16B16_UNORM: return 6; + case VK_FORMAT_R16G16B16A16_UNORM: return 8; + case VK_FORMAT_R8G8B8A8_UNORM: return 4; + case VK_FORMAT_R8G8B8_UNORM: return 3; + case VK_FORMAT_R8G8_UNORM: return 2; + case VK_FORMAT_R8_UNORM: return 1; + + + case VK_FORMAT_R32_UINT: return 4; + case VK_FORMAT_R32G32_UINT: return 8; + case VK_FORMAT_R32G32B32_UINT: return 12; + case VK_FORMAT_R32G32B32A32_UINT: return 16; + + case VK_FORMAT_R8G8B8A8_SRGB: return 4; + default: + abortf("Jokes on you\n"); + } +} diff --git a/src/l3/r4/r4.c b/src/l3/r4/r4.c index cd49d1f..52bf030 100644 --- a/src/l3/r4/r4.c +++ b/src/l3/r4/r4.c @@ -96,6 +96,8 @@ typedef struct{ U64 misses_count; U64 hits_count; Vecvec3 bullets_stuck_on_ROA; + + MargaretSubbuf sb; } R4BetaState; /* We are surrounded by a giant cubic mesh of light sources */