diff --git a/.gitignore b/.gitignore index 9837024..45eca80 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,4 @@ GRAPH*.gv GRAPH*.png SICK_JOKE* *.hi -*_stub.h \ No newline at end of file +*_stub.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c7df01f..6d005b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,5 +60,5 @@ add_executable(codegen_l1_5 src/l1_5/anne/codegen.c) add_executable(l2_tex_gen src/l2/anne/codegen.c) target_link_libraries(l2_tex_gen -lm -lpng) -add_executable(l2_allie_in_r4 src/l2/allie/allie.c gen/l_wl_protocols/xdg-shell-private.c) -target_link_libraries(l2_allie_in_r4 -lvulkan -lwayland-client -lm -lxkbcommon -lpng -lfreetype) +add_executable(l2_r4 src/l3/r4/r4.c gen/l_wl_protocols/xdg-shell-private.c) +target_link_libraries(l2_r4 -lvulkan -lwayland-client -lm -lxkbcommon -lpng -lfreetype) diff --git a/src/l1/anne/alice.h b/src/l1/anne/alice.h index 9ab1bf3..dceb898 100644 --- a/src/l1/anne/alice.h +++ b/src/l1/anne/alice.h @@ -9,17 +9,17 @@ void generate_code_for_alice_on_l1(){ SpanU8 l = cstr("l1"), ns = cstr("alice"); /* Assets: model topology */ generate_eve_span_company_for_primitive(l, ns, cstr("GenericMeshVertexInc"), true, true); - generate_eve_span_company_for_non_primitive_clonable(l, ns, cstr("GenericMeshInSceneTemplate"), true, false); generate_eve_span_company_for_primitive(l, ns, cstr("ShinyMeshVertexInc"), true, true); - generate_eve_span_company_for_non_primitive_clonable(l, ns, cstr("ShinyMeshTopology"), true, false); /* Engine stuff */ - generate_eve_span_company_for_primitive(l, ns, cstr("GenericModelOnSceneMem"), true, false); - generate_eve_span_company_for_primitive(l, ns, cstr("ShinyModelOnSceneMem"), true, false); - generate_eve_span_company_for_primitive(l, ns, cstr("GenericModelTexVulkPointers"), true, false); + // 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){ + .T = cstr("AliceGenericMeshHand"), .t_primitive = true}, true); + generate_List_templ_inst_eve_header(l, ns, (list_instantiation_op){ + .T = cstr("AliceShinyMeshHand"), .t_primitive = true}, true); - - generate_eve_span_company_for_primitive(l, ns, cstr("ObjectInfo"), true, false); // todo: delete this crap + generate_eve_span_company_for_primitive(l, ns, cstr("RefListNodeAliceGenericMeshHand"), true, false); + generate_eve_span_company_for_primitive(l, ns, cstr("RefListNodeAliceShinyMeshHand"), true, false); } #endif \ No newline at end of file diff --git a/src/l2/alice/assets.h b/src/l2/alice/assets.h index dc85846..6fc14ff 100644 --- a/src/l2/alice/assets.h +++ b/src/l2/alice/assets.h @@ -38,24 +38,15 @@ typedef struct { VecU8 diffuse_texture_path; VecU8 normal_texture_path; VecU8 specular_texture_path; -} GenericMeshInSceneTemplate; +} GenericMeshAndTextureFilePath; -void GenericMeshInSceneTemplate_drop(GenericMeshInSceneTemplate self) { +void GenericMeshInSceneTemplate_drop(GenericMeshAndTextureFilePath self) { GenericMeshTopology_drop(self.topology); VecU8_drop(self.diffuse_texture_path); VecU8_drop(self.normal_texture_path); VecU8_drop(self.specular_texture_path); } -GenericMeshInSceneTemplate GenericMeshInSceneTemplate_clone(const GenericMeshInSceneTemplate* self) { - return (GenericMeshInSceneTemplate){.topology = GenericMeshTopology_clone(&self->topology), - .diffuse_texture_path = VecU8_clone(&self->diffuse_texture_path), - .normal_texture_path = VecU8_clone(&self->normal_texture_path), - .specular_texture_path = VecU8_clone(&self->specular_texture_path)}; -} - -#include "../../../gen/l1/eve/alice/VecGenericMeshInSceneTemplate.h" - typedef struct { mat4 model_t; } GenericMeshInstanceInc; @@ -91,7 +82,6 @@ ShinyMeshTopology ShinyMeshTopology_clone(const ShinyMeshTopology* self) { VecU32_clone(&self->indexes)}; } -#include "../../../gen/l1/eve/alice/VecShinyMeshTopology.h" typedef struct{ mat4 model_t; @@ -133,15 +123,6 @@ typedef struct { char _padding_1[4]; } Pipeline0PointLight; -typedef struct { - VecGenericMeshInSceneTemplate generic_models; - VecShinyMeshTopology shiny_models; -} SceneTemplate; - -void SceneTemplate_drop(SceneTemplate self) { - VecGenericMeshInSceneTemplate_drop(self.generic_models); -} - #define pipeline_0_ubo_point_light_max_count 120 #define pipeline_0_ubo_spotlight_max_count 20 diff --git a/src/l2/allie/allie.c b/src/l2/allie/allie.c index c64f7f4..996d4d9 100644 --- a/src/l2/allie/allie.c +++ b/src/l2/allie/allie.c @@ -6,24 +6,25 @@ typedef struct { U64 count; - MargaretSubbuf staging_busy; - MargaretSubbuf staging_updatable; + MargaretSubbuf staging; MargaretSubbuf device_local; - U64 cap; - // todo: delete this crap. This crap turned out to be completely useless. It is another one of my very very dumb ideas - // todo: remove updatable buffer, fill staging buffer in main thread } PatriciaBuf; -void PatriciaBuf_swap_staging(PatriciaBuf* self){ - MargaretSubbuf t = self->staging_updatable; - self->staging_updatable = self->staging_busy; - self->staging_busy = t; -} +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 */ + VkDescriptorSet p_0a_set_0; +} AliceGenericMeshMemDependantVkObj; typedef struct { size_t indexes; - + // Option MargaretSubbuf staging_vbo; + // Option MargaretSubbuf staging_ebo; // todo: replace TextureDataXXX with MargaretPngPromises @@ -39,24 +40,16 @@ typedef struct { MargaretSubbuf ebo; PatriciaBuf instance_attr; - // todo: store dimensions of these images MargaretImg diffuse_texture; MargaretImg normal_texture; MargaretImg specular_texture; -} GenericModelOnSceneMem; -#include "../../../gen/l1/eve/alice/VecGenericModelOnSceneMem.h" + AliceGenericMeshMemDependantVkObj mem_dependant_vk_obj; -void GenericModelOnSceneMem_set(GenericModelOnSceneMem* self, size_t instance, GenericMeshInstanceInc uncomp){ - assert(instance < self->instance_attr.count); - GenericMeshInstance* staging = (GenericMeshInstance*)MargaretSubbuf_get_mapped(&self->instance_attr.staging_updatable); - staging[instance].base = uncomp; - mat4 tr_inv = mat4_transpose(mat4_inverse(uncomp.model_t)); - staging[instance].normal_t = mat3_new( - tr_inv.x.x, tr_inv.y.x, tr_inv.z.x, - tr_inv.x.y, tr_inv.y.y, tr_inv.z.y, - tr_inv.x.z, tr_inv.y.z, tr_inv.z.z ); -} + bool scheduled_for_deletion; +} AliceGenericMeshHand; + +#include "../../../gen/l1/eve/alice/ListAliceGenericMeshHand.h" typedef struct { size_t indexes; @@ -67,260 +60,57 @@ typedef struct { MargaretSubbuf vbo; MargaretSubbuf ebo; PatriciaBuf instance_attr; -} ShinyModelOnSceneMem; -#include "../../../gen/l1/eve/alice/VecShinyModelOnSceneMem.h" + bool scheduled_for_deletion; +} AliceShinyMeshHand; -void ShinyModelOnSceneMem_set(ShinyModelOnSceneMem* self, size_t instance, ShinyMeshInstanceInc uncomp){ - assert(instance < self->instance_attr.count); - ShinyMeshInstance* staging = (ShinyMeshInstance*)MargaretSubbuf_get_mapped(&self->instance_attr.staging_updatable); - staging[instance].base = uncomp; - mat4 tr_inv = mat4_transpose(mat4_inverse(uncomp.model_t)); - staging[instance].normal_t = mat3_new( - tr_inv.x.x, tr_inv.y.x, tr_inv.z.x, - tr_inv.x.y, tr_inv.y.y, tr_inv.z.y, - tr_inv.x.z, tr_inv.y.z, tr_inv.z.z ); -} +#include "../../../gen/l1/eve/alice/ListAliceShinyMeshHand.h" typedef struct { float fov; mat3 cam_basis; vec3 pos; +} AliceCam; - float speed; +typedef struct{ + AliceCam cam; float sensitivity; float pitch_cap; -} CamControlInfo; +} AliceCamVerticalControl; -void CamControlInfo_forward(CamControlInfo* self, float fl) { - self->pos = vec3_add_vec3(self->pos, vec3_mul_scal(self->cam_basis.z, -self->speed * fl)); -} - -void CamControlInfo_backward(CamControlInfo* self, float fl) { - self->pos = vec3_add_vec3(self->pos, vec3_mul_scal(self->cam_basis.z, self->speed * fl)); -} - -void CamControlInfo_left(CamControlInfo* self, float fl) { - self->pos = vec3_add_vec3(self->pos, vec3_mul_scal(self->cam_basis.x, -self->speed * fl)); -} - -void CamControlInfo_right(CamControlInfo* self, float fl) { - self->pos = vec3_add_vec3(self->pos, vec3_mul_scal(self->cam_basis.x, self->speed * fl)); -} - -void CamControlInfo_down(CamControlInfo* self, float fl) { - self->pos = vec3_add_vec3(self->pos, vec3_mul_scal((vec3){0, -1, 0}, self->speed * fl)); -} - -void CamControlInfo_up(CamControlInfo* self, float fl) { - self->pos = vec3_add_vec3(self->pos, vec3_mul_scal((vec3){0, 1, 0}, self->speed * fl)); -} - -CamControlInfo CamControlInfo_new() { - return (CamControlInfo){ - .fov = 1.5f, .cam_basis = marie_simple_camera_rot_m_basis_in_cols(0, 0, 0), .pos = {0, 0, 0}, - .speed = 6.7f, .sensitivity = 0.5f * M_PIf / 180, .pitch_cap = M_PIf * 0.49f +AliceCamVerticalControl AliceCamVerticalControl_new() { + return (AliceCamVerticalControl){ + .cam.fov = 1.5f, .cam.cam_basis = marie_simple_camera_rot_m_basis_in_cols(0, 0, 0), .cam.pos = {0, 0, 0}, + .sensitivity = 0.5f * M_PIf / 180, .pitch_cap = M_PIf * 0.49f }; } -void CamControlInfo_update_direction(CamControlInfo* self, int win_width, int win_height, int pointer_x, int pointer_y) { - float yaw = ((float)win_width / 2 - (float)pointer_x) * self->sensitivity; +void AliceCamVerticalControl_update_direction( + AliceCamVerticalControl* self, int win_width, int win_height, float pointer_x, float pointer_y) { + float yaw = ((float)win_width / 2 - pointer_x) * self->sensitivity; float pitch = marie_clamp_float( - ((float)win_height / 2 - (float)pointer_y) * self->sensitivity, + ((float)win_height / 2 - pointer_y) * self->sensitivity, -self->pitch_cap, self->pitch_cap ); - self->cam_basis = marie_simple_camera_rot_m_basis_in_cols(yaw, pitch, 0); + self->cam.cam_basis = marie_simple_camera_rot_m_basis_in_cols(yaw, pitch, 0); } typedef struct { - MargaretSubbuf staging_busy; - MargaretSubbuf staging_updatable; + MargaretSubbuf staging; MargaretSubbuf device_local; -} Pipeline0Transfer; +} AlicePipeline0UBO; -// Just for a test in alice -typedef struct { - mat3 rotation; - vec3 pos; - float scale; - vec3 color_on; -} ObjectInfo; - -#include "../../../gen/l1/eve/alice/VecObjectInfo.h" - -/* Non copyable */ -typedef struct { - VecGenericModelOnSceneMem generic_models; - VecShinyModelOnSceneMem shiny_models; - - VkClearColorValue color; +typedef struct{ + vec4 clear_color; float gamma_correction_factor; float hdr_factor; float lsd_factor; - float anim_time; // A timer, passed to functions that push push constants +} AliceRenderConfig; - /* point_light_vec_len and spotlight_vec_len are stored in staging (and also device local) buffers */ - Pipeline0Transfer pipeline0_ubo; - - CamControlInfo cam; - - VecObjectInfo smeshnyavka_1; - VecObjectInfo smeshnyavka_3; - - VecU8 text_on_screen; -} Scene; - -ShinyMeshInstanceInc ShinyMeshInstanceInc_from_ObjectInfo(const ObjectInfo* oi){ - return (ShinyMeshInstanceInc){ - .model_t = mat4_mul_mat4(marie_translation_mat4(oi->pos), - mat4_mul_mat4(marie_3d_scal_mat4(oi->scale), marie_mat3_to_mat4(oi->rotation))), - .color_on = oi->color_on, .color_off = {1, 0.4f, 0.5f} - }; -} - -// todo: remove this shit -void Scene_add_smeshnyavka_3(Scene* self, ObjectInfo oi){ - ShinyModelOnSceneMem* model_sh = VecShinyModelOnSceneMem_mat(&self->shiny_models, 0); - size_t ni = self->smeshnyavka_3.len; - assert(ni < model_sh->instance_attr.cap); - VecObjectInfo_append(&self->smeshnyavka_3, oi); - model_sh->instance_attr.count = ni + 1; - ShinyModelOnSceneMem_set(model_sh, ni, ShinyMeshInstanceInc_from_ObjectInfo(&oi)); -} - -// todo: remove this shit (and rewrite everything in haskell) -void Scene_update_smeshnyavka_3(Scene* self, size_t sh_id){ - assert(sh_id < self->smeshnyavka_3.len); - const ObjectInfo* oi = VecObjectInfo_at(&self->smeshnyavka_3, sh_id); - ShinyModelOnSceneMem* model_sh = VecShinyModelOnSceneMem_mat(&self->shiny_models, 0); - ShinyModelOnSceneMem_set(model_sh, sh_id, ShinyMeshInstanceInc_from_ObjectInfo(oi)); -} - -GenericMeshInstanceInc GenericMeshInstanceInc_from_ObjectInfo(const ObjectInfo* oi){ - return (GenericMeshInstanceInc){ - .model_t = mat4_mul_mat4(marie_translation_mat4(oi->pos), - mat4_mul_mat4(marie_3d_scal_mat4(oi->scale), marie_mat3_to_mat4(oi->rotation))), - }; -} - -// todo: remove this shit -void Scene_add_smeshnyavka_1(Scene* self, ObjectInfo oi){ - GenericModelOnSceneMem* model = VecGenericModelOnSceneMem_mat(&self->generic_models, 0); - size_t ni = self->smeshnyavka_1.len; - assert(ni < model->instance_attr.cap); - VecObjectInfo_append(&self->smeshnyavka_1, oi); - model->instance_attr.count = ni + 1; - GenericModelOnSceneMem_set(model, ni, GenericMeshInstanceInc_from_ObjectInfo(&oi)); -} - -// todo: remove this shit -void Scene_update_smeshnyavka_1(Scene* self, size_t sh_id){ - assert(sh_id < self->smeshnyavka_1.len); - const ObjectInfo* oi = VecObjectInfo_at(&self->smeshnyavka_1, sh_id); - GenericModelOnSceneMem* model = VecGenericModelOnSceneMem_mat(&self->generic_models, 0); - GenericModelOnSceneMem_set(model, sh_id, GenericMeshInstanceInc_from_ObjectInfo(oi)); -} - - - -Scene Scene_new(VecGenericModelOnSceneMem generic_models, VecShinyModelOnSceneMem shiny_models, - Pipeline0Transfer pipeline0_ubo) { - return (Scene){.generic_models = generic_models, .shiny_models = shiny_models, - .color = {.float32 = {0, 0, 0, 1}}, - .gamma_correction_factor = 2.2f, .hdr_factor = 1, .lsd_factor = 0, .anim_time = 0, - .pipeline0_ubo = pipeline0_ubo, .cam = CamControlInfo_new(), - .smeshnyavka_1 = VecObjectInfo_new(), - .smeshnyavka_3 = VecObjectInfo_new(), // todo: remove this shit and rewrite everything in haskell - .text_on_screen = VecU8_new(), - }; -} - -void Scene_drop(Scene self) { - VecGenericModelOnSceneMem_drop(self.generic_models); - VecShinyModelOnSceneMem_drop(self.shiny_models); -} - -/* No buffer rerecording, no buffer beginning, no buffer ending */ -void SceneTemplate_copy_initial_model_topology_cmd_buf_recording( - const SceneTemplate* scene_template, const Scene* scene, VkCommandBuffer command_buffer) { - assert(scene_template->generic_models.len == scene->generic_models.len); - assert(scene_template->shiny_models.len == scene->shiny_models.len); - assert(scene_template->generic_models.len == scene->generic_models.len); - - for (size_t mi = 0; mi < scene_template->generic_models.len; mi++) { - const GenericMeshInSceneTemplate* mt = VecGenericMeshInSceneTemplate_at(&scene_template->generic_models, mi); - const GenericModelOnSceneMem *mm = VecGenericModelOnSceneMem_at(&scene->generic_models, mi); - - assert(mm->staging_vbo.len >= mt->topology.vertices.len * sizeof(GenericMeshVertex)); - assert(mm->vbo.len >= mt->topology.vertices.len * sizeof(GenericMeshVertex)); - GenericMeshVertex* staging_vbo = (GenericMeshVertex*)MargaretSubbuf_get_mapped(&mm->staging_vbo); - for (U64 i = 0; i < mt->topology.vertices.len; i++) { - staging_vbo[i].base = mt->topology.vertices.buf[i]; - } - assert(mt->topology.indexes.len % 3 == 0); - for (size_t ti = 0; ti * 3 < mt->topology.indexes.len; ti++) { - U32 v0 = mt->topology.indexes.buf[ti * 3 + 0]; - U32 v1 = mt->topology.indexes.buf[ti * 3 + 1]; - U32 v2 = mt->topology.indexes.buf[ti * 3 + 2]; - const GenericMeshVertexInc* A0 = VecGenericMeshVertexInc_at(&mt->topology.vertices, v0); - const GenericMeshVertexInc* A1 = VecGenericMeshVertexInc_at(&mt->topology.vertices, v1); - const GenericMeshVertexInc* A2 = VecGenericMeshVertexInc_at(&mt->topology.vertices, v2); - vec3 dp1 = vec3_minus_vec3(A1->pos, A0->pos); - vec3 dp2 = vec3_minus_vec3(A2->pos, A0->pos); - float du1 = A1->tex.x - A0->tex.x; - float dv1 = A1->tex.y - A0->tex.y; - float du2 = A2->tex.x - A0->tex.x; - float dv2 = A2->tex.y - A0->tex.y; - vec3 norm = vec3_normalize(vec3_cross(dp1, dp2)); - mat2x3 tang_U_V = mat3x2_transpose(mat2_mul_mat3x2( - mat2_inverse(mat2_new(du1, dv1, du2, dv2)), - mat2x3_transpose((mat2x3){.x = dp1, .y = dp2}) - )); - staging_vbo[v0].norm = staging_vbo[v1].norm = staging_vbo[v2].norm = norm; - staging_vbo[v0].tang_U = staging_vbo[v1].tang_U = staging_vbo[v2].tang_U = tang_U_V.x; - staging_vbo[v0].tang_V = staging_vbo[v1].tang_V = staging_vbo[v2].tang_V = tang_U_V.y; - } - margaret_rec_cmd_copy_buffer_one_to_one(command_buffer, &mm->staging_vbo, &mm->vbo); - - assert(mt->topology.indexes.len == mm->indexes); - size_t ebo_len = mt->topology.indexes.len * sizeof(U32); - assert(mm->ebo.len >= ebo_len); - U32* staging_ebo = (U32*)MargaretSubbuf_get_mapped(&mm->staging_ebo); - memcpy(staging_ebo, mt->topology.indexes.buf, ebo_len); - margaret_rec_cmd_copy_buffer_one_to_one(command_buffer, &mm->staging_ebo, &mm->ebo); - } - - for (size_t mi = 0; mi < scene_template->shiny_models.len; mi++) { - const ShinyMeshTopology* mt = VecShinyMeshTopology_at(&scene_template->shiny_models, mi); - const ShinyModelOnSceneMem *mm = VecShinyModelOnSceneMem_at(&scene->shiny_models, mi); - - assert(mm->staging_vbo.len >= mt->vertices.len * sizeof(ShinyMeshVertex)); - assert(mm->vbo.len >= mt->vertices.len * sizeof(ShinyMeshVertex)); - ShinyMeshVertex* staging_vbo = (ShinyMeshVertex*)MargaretSubbuf_get_mapped(&mm->staging_vbo); - for (U64 i = 0; i < mt->vertices.len; i++) { - staging_vbo[i].base = mt->vertices.buf[i]; - } - assert(mt->indexes.len % 3 == 0); - for (size_t ti = 0; ti * 3 < mt->indexes.len; ti++) { - U32 v0 = mt->indexes.buf[ti * 3 + 0]; - U32 v1 = mt->indexes.buf[ti * 3 + 1]; - U32 v2 = mt->indexes.buf[ti * 3 + 2]; - vec3 p0 = VecShinyMeshVertexInc_at(&mt->vertices, v0)->pos; - vec3 p1 = VecShinyMeshVertexInc_at(&mt->vertices, v1)->pos; - vec3 p2 = VecShinyMeshVertexInc_at(&mt->vertices, v2)->pos; - 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; - } - - margaret_rec_cmd_copy_buffer_one_to_one(command_buffer, &mm->staging_vbo, &mm->vbo); - - assert(mt->indexes.len == mm->indexes); - size_t ebo_len = mt->indexes.len * sizeof(U32); - assert(mm->ebo.len >= ebo_len); - U32* staging_ebo = (U32*)MargaretSubbuf_get_mapped(&mm->staging_ebo); - memcpy(staging_ebo, mt->indexes.buf, ebo_len); - margaret_rec_cmd_copy_buffer_one_to_one(command_buffer, &mm->staging_ebo, &mm->ebo); - } +AliceRenderConfig AliceRenderConfig_new(){ + return (AliceRenderConfig){ + .clear_color = {0, 0.5f, 0.9f, 1}, + .gamma_correction_factor = 2.2f, .hdr_factor = 1, .lsd_factor = 0}; } /* Here ends the old r0_scene.h file @@ -336,19 +126,6 @@ void SceneTemplate_copy_initial_model_topology_cmd_buf_recording( #include "../../../gen/l_wl_protocols/xdg-shell-client.h" -typedef struct { - VkPipelineLayout pipeline_layout; - VkPipeline pipeline; - VkDescriptorSetLayout descriptor_set_layout; -} PipelineHands; - - -void destroy_graphics_pipeline_hands(VkDevice device, PipelineHands hands) { - vkDestroyPipeline(device, hands.pipeline, NULL); - vkDestroyPipelineLayout(device, hands.pipeline_layout, NULL); - vkDestroyDescriptorSetLayout(device, hands.descriptor_set_layout, NULL); -} - VkRenderPass create_render_pass_0(VkDevice logical_device, VkFormat colorbuffer_format, VkFormat zbuffer_format) { VkAttachmentDescription all_attachments[2] = { { @@ -418,7 +195,19 @@ VkRenderPass create_render_pass_0(VkDevice logical_device, VkFormat colorbuffer_ return render_pass; } -PipelineHands create_graphics_pipeline_0( +typedef struct { + VkPipelineLayout pipeline_layout; + VkPipeline pipeline; + VkDescriptorSetLayout descriptor_set_layout; +} AlicePipeline0a; + +void AlicePipeline0a_destroy(VkDevice device, AlicePipeline0a hands) { + vkDestroyPipeline(device, hands.pipeline, NULL); + vkDestroyPipelineLayout(device, hands.pipeline_layout, NULL); + vkDestroyDescriptorSetLayout(device, hands.descriptor_set_layout, NULL); +} + +AlicePipeline0a create_graphics_pipeline_0( VkDevice device, SpanU8 root_dir, VkRenderPass render_pass, uint32_t subpass ) { VkDescriptorSetLayoutBinding bindings_for_my_descr_set_layout[] = { @@ -569,10 +358,22 @@ PipelineHands create_graphics_pipeline_0( .vertexAttributeDescriptionCount = ARRAY_SIZE(vertex_attributes), vertex_attributes, .depthTestEnable = true, .depthWriteEnable = true, .blendEnable = false }); - return (PipelineHands){.pipeline_layout = pipeline_layout, .pipeline = pipeline, .descriptor_set_layout = my_descriptor_set_layout}; + return (AlicePipeline0a){.pipeline_layout = pipeline_layout, .pipeline = pipeline, .descriptor_set_layout = my_descriptor_set_layout}; } -PipelineHands create_graphics_pipeline_0_b( +typedef struct { + VkPipelineLayout pipeline_layout; + VkPipeline pipeline; + VkDescriptorSetLayout descriptor_set_layout; +} AlicePipeline0b; + +void AlicePipeline0b_destroy(VkDevice device, AlicePipeline0b hands) { + vkDestroyPipeline(device, hands.pipeline, NULL); + vkDestroyPipelineLayout(device, hands.pipeline_layout, NULL); + vkDestroyDescriptorSetLayout(device, hands.descriptor_set_layout, NULL); +} + +AlicePipeline0b create_graphics_pipeline_0_b( VkDevice device, SpanU8 root_dir, VkRenderPass render_pass, uint32_t subpass ) { VkDescriptorSetLayout my_descriptor_set_layout; @@ -691,10 +492,9 @@ PipelineHands create_graphics_pipeline_0_b( .depthTestEnable = true, .depthWriteEnable = true, .blendEnable = false }); - return (PipelineHands){.pipeline_layout = pipeline_layout, .pipeline = pipeline, .descriptor_set_layout = my_descriptor_set_layout}; + return (AlicePipeline0b){.pipeline_layout = pipeline_layout, .pipeline = pipeline, .descriptor_set_layout = my_descriptor_set_layout}; } - VkRenderPass create_render_pass_1(VkDevice logical_device, VkFormat image_format) { // Color attachments array for our render pass VkAttachmentDescription all_attachments[1] = { (VkAttachmentDescription){ @@ -746,8 +546,19 @@ VkRenderPass create_render_pass_1(VkDevice logical_device, VkFormat image_format return render_pass; } +typedef struct { + VkPipelineLayout pipeline_layout; + VkPipeline pipeline; + VkDescriptorSetLayout descriptor_set_layout; +} AlicePipeline1; -PipelineHands create_graphics_pipeline_1( +void AlicePipeline1_destroy(VkDevice device, AlicePipeline1 hands) { + vkDestroyPipeline(device, hands.pipeline, NULL); + vkDestroyPipelineLayout(device, hands.pipeline_layout, NULL); + vkDestroyDescriptorSetLayout(device, hands.descriptor_set_layout, NULL); +} + +AlicePipeline1 create_graphics_pipeline_1( VkDevice device, SpanU8 root_dir, VkRenderPass render_pass, uint32_t subpass ) { @@ -793,7 +604,7 @@ PipelineHands create_graphics_pipeline_1( .vertexBindingDescriptionCount = 0, .pVertexBindingDescriptions = NULL, .vertexAttributeDescriptionCount = 0, .pVertexAttributeDescriptions = NULL, }); - return (PipelineHands){.pipeline_layout = pipeline_layout, .pipeline = pipeline, .descriptor_set_layout = my_descriptor_set_layout}; + return (AlicePipeline1){.pipeline_layout = pipeline_layout, .pipeline = pipeline, .descriptor_set_layout = my_descriptor_set_layout}; } VkFramebuffer create_IT1_framebuffer(VkDevice device, VkImageView IT1_view, VkImageView zbuffer_view, VkRenderPass render_pass_0, @@ -856,186 +667,6 @@ typedef struct { VkQueue presentation_queue; } UsedVulkanQueues; -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 */ - VkDescriptorSet p_0a_set_0; -} GenericModelTexVulkPointers; -#include "../../../gen/l1/eve/alice/VecGenericModelTexVulkPointers.h" - -void reset_and_record_command_buffer_0( - VkCommandBuffer command_buffer, VkRenderPass render_pass_0, - const PipelineHands* pipeline_and_layout_0a, const PipelineHands* pipeline_and_layout_0b, - VkFramebuffer result_framebuffer, VkExtent2D image_extent, - const Scene* scene, - /* We need descriptor sets for generic meshes from here */ - const VecGenericModelTexVulkPointers* generic_models, - VkDescriptorSet descriptor_set_for_pipeline_0b, - mat4 proj_cam_t, vec3 camera_pos - ) { - margaret_reset_and_begin_command_buffer(command_buffer); - - vkCmdBeginRenderPass(command_buffer, &(VkRenderPassBeginInfo){ - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = render_pass_0, - .framebuffer = result_framebuffer, - .renderArea.offset = (VkOffset2D){0, 0}, - .renderArea.extent = image_extent, - .clearValueCount = 2, - .pClearValues = (VkClearValue[]){{.color = scene->color}, {.depthStencil = {.depth = 1, .stencil = 0}}}, - }, VK_SUBPASS_CONTENTS_INLINE); - - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout_0a->pipeline); - record_cmd_set_viewport_and_scissors(command_buffer, image_extent); - vkCmdPushConstants(command_buffer, pipeline_and_layout_0a->pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, - 0, sizeof(mat4), &proj_cam_t); - vkCmdPushConstants(command_buffer, pipeline_and_layout_0a->pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, - sizeof(mat4), sizeof(vec3), &camera_pos); - for (size_t i = 0; i < scene->generic_models.len; i++) { - const GenericModelOnSceneMem *model = VecGenericModelOnSceneMem_at(&scene->generic_models, i); - VkDescriptorSet model_indiv_descriptor_set_0 = VecGenericModelTexVulkPointers_at(generic_models, i)->p_0a_set_0; - - const MargaretSubbuf* dev_local_vbo = &model->vbo; - const MargaretSubbuf* dev_local_inst_attr = &model->instance_attr.device_local; - const MargaretSubbuf* dev_local_ebo = &model->ebo; - // const - vkCmdBindVertexBuffers(command_buffer, 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 }); - vkCmdBindIndexBuffer(command_buffer, MargaretSubbuf_get_buffer(dev_local_ebo), dev_local_ebo->start, - VK_INDEX_TYPE_UINT32); - vkCmdBindDescriptorSets( - command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout_0a->pipeline_layout, 0, - 1, &model_indiv_descriptor_set_0, 0, NULL); - vkCmdDrawIndexed(command_buffer, model->indexes, model->instance_attr.count, 0, 0, 0); - } - - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout_0b->pipeline); - record_cmd_set_viewport_and_scissors(command_buffer, image_extent); - vkCmdPushConstants(command_buffer, pipeline_and_layout_0b->pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, - 0, sizeof(mat4), &proj_cam_t); - vkCmdPushConstants(command_buffer, pipeline_and_layout_0b->pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, - sizeof(mat4), sizeof(vec3), &camera_pos); - vkCmdBindDescriptorSets( - command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout_0b->pipeline_layout, 0, - 1, &descriptor_set_for_pipeline_0b, 0, NULL); - for (size_t i = 0; i < scene->shiny_models.len; i++) { - const ShinyModelOnSceneMem* model = VecShinyModelOnSceneMem_at(&scene->shiny_models, i); - const MargaretSubbuf* dev_local_vbo = &model->vbo; - const MargaretSubbuf* dev_local_inst_attr = &model->instance_attr.device_local; - const MargaretSubbuf* dev_local_ebo = &model->ebo; - vkCmdBindVertexBuffers(command_buffer, 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 }); - vkCmdBindIndexBuffer(command_buffer, MargaretSubbuf_get_buffer(dev_local_ebo), dev_local_ebo->start, - VK_INDEX_TYPE_UINT32); - vkCmdDrawIndexed(command_buffer, model->indexes, model->instance_attr.count, 0, 0, 0); - } - - vkCmdEndRenderPass(command_buffer); - margaret_end_command_buffer(command_buffer); -} - -void reset_and_record_command_buffer_1( - VkCommandBuffer command_buffer, VkRenderPass render_pass_1, - const PipelineHands* pipeline_and_layout_1, - VkFramebuffer swapchain_image_framebuffer, VkExtent2D image_extent, - VkExtent2D max_win_size, const Scene* scene, - VkDescriptorSet descriptor_set_for_pipeline_1, LucyRenderer* lucy_renderer - ) { - margaret_reset_and_begin_command_buffer(command_buffer); - - vkCmdBeginRenderPass(command_buffer, &(VkRenderPassBeginInfo){ - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = render_pass_1, - .framebuffer = swapchain_image_framebuffer, - .renderArea.offset = (VkOffset2D){0, 0}, - .renderArea.extent = image_extent, - }, VK_SUBPASS_CONTENTS_INLINE); - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout_1->pipeline); - - record_cmd_set_viewport_and_scissors(command_buffer, image_extent); - vkCmdBindDescriptorSets( - command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout_1->pipeline_layout, 0, - 1, &descriptor_set_for_pipeline_1, 0, NULL); - - Pipeline1PushRangeVertex reg_and_params_vertex = {.win_scale = { - (float)image_extent.width / (float)max_win_size.width, - (float)image_extent.height / (float)max_win_size.height}, - }; - Pipeline1PushRangeFragment reg_and_params_fragment = { - .gamma_correction_factor = scene->gamma_correction_factor, - .hdr_factor = scene->hdr_factor, - .lsd_factor = scene->lsd_factor, - .anim_time = scene->anim_time - }; - vkCmdPushConstants(command_buffer, pipeline_and_layout_1->pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, - 0, sizeof(Pipeline1PushRangeVertex), ®_and_params_vertex); - vkCmdPushConstants(command_buffer, pipeline_and_layout_1->pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, - sizeof(Pipeline1PushRangeVertex), sizeof(Pipeline1PushRangeFragment), ®_and_params_fragment); - vkCmdDraw(command_buffer, 3, 1, 0, 0); - - LucyRenderer_another_frame_rec_drawing(lucy_renderer, command_buffer, image_extent); - - vkCmdEndRenderPass(command_buffer); - margaret_end_command_buffer(command_buffer); -} - -/* This function records a command buffer that copies EVERYTHING. You won't normally need to copy every single thing, - * but here you have the most bold solution. Does not 'begin', does not 'end' comamnd buffer - * */ -void record_copying_entire_scene_from_staging_to_device_local(VkCommandBuffer command_buffer, const Scene* scene) { - for (size_t mi = 0; mi < scene->generic_models.len; mi++) { - const GenericModelOnSceneMem* model = VecGenericModelOnSceneMem_at(&scene->generic_models, mi); - assert(model->instance_attr.count * sizeof(GenericMeshInstance) <= model->instance_attr.staging_busy.len); - assert(model->instance_attr.count * sizeof(GenericMeshInstance) <= model->instance_attr.device_local.len); - if (model->instance_attr.count) { - margaret_rec_cmd_copy_buffer(command_buffer, - &model->instance_attr.staging_busy, 0, &model->instance_attr.device_local, 0, - model->instance_attr.count * sizeof(GenericMeshInstance)); - } - } - for (size_t mi = 0; mi < scene->shiny_models.len; mi++) { - const ShinyModelOnSceneMem* model = VecShinyModelOnSceneMem_at(&scene->shiny_models, mi); - assert(model->instance_attr.count * sizeof(ShinyMeshInstance) <= model->instance_attr.staging_busy.len); - assert(model->instance_attr.count * sizeof(ShinyMeshInstance) <= model->instance_attr.device_local.len); - if (model->instance_attr.count) { - margaret_rec_cmd_copy_buffer(command_buffer, - &model->instance_attr.staging_busy, 0, &model->instance_attr.device_local, 0, - model->instance_attr.count * sizeof(ShinyMeshInstance)); - } - } - { /* Pipeline0 UBO */ - Pipeline0UBO* mem = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&scene->pipeline0_ubo.staging_busy); - assert(mem->point_light_count <= pipeline_0_ubo_point_light_max_count); - assert(mem->spotlight_count <= pipeline_0_ubo_spotlight_max_count); - - // todo: I will probably replace pipeline0ubo with ubo for length + two readonly storage buffers for light sources - // all of this is basically useless - - const MargaretSubbuf* ubo_staging = &scene->pipeline0_ubo.staging_busy; - const MargaretSubbuf* ubo_device_local = &scene->pipeline0_ubo.device_local; - - margaret_rec_cmd_copy_buffer_one_to_one_part(command_buffer, ubo_staging, ubo_device_local, - offsetof(Pipeline0UBO, point_light_count), sizeof(int)); - margaret_rec_cmd_copy_buffer_one_to_one_part(command_buffer, ubo_staging, ubo_device_local, - offsetof(Pipeline0UBO, spotlight_count), sizeof(int)); - if (mem->point_light_count) { - margaret_rec_cmd_copy_buffer_one_to_one_part(command_buffer, ubo_staging, ubo_device_local, - offsetof(Pipeline0UBO, point_light_arr), sizeof(Pipeline0PointLight) * mem->point_light_count); - } - if (mem->spotlight_count) { - margaret_rec_cmd_copy_buffer_one_to_one_part(command_buffer, ubo_staging, ubo_device_local, - offsetof(Pipeline0UBO, spotlight_arr), sizeof(Pipeline0Spotlight) * mem->spotlight_count); - } - } -} void alice_default_callback_on_wl_keyboard_key(){} @@ -1076,6 +707,7 @@ typedef struct { struct xkb_keymap* xkb_keymap; /* app state */ uint32_t last_frame_time; + uint32_t cur_frame_time; int32_t width_heard; int32_t height_heard; int32_t width_confirmed; @@ -1087,6 +719,54 @@ typedef struct { margaret_ns_time prev_key_frame_time; } AliceWaylandApp; +float AliceWaylandApp_get_elapsed_time(const AliceWaylandApp* self){ + return (float)(self->cur_frame_time - self->last_frame_time) / 1000; +} + +/* They are actually MutRef, but who cares lol, we won't have such distinction here anytime soon, so we shorten + * it to Ref (whil keeping in kind that it is actually MutRef) + */ +typedef struct ListNodeAliceGenericMeshHand* RefListNodeAliceGenericMeshHand; +#include "../../../gen/l1/eve/alice/VecRefListNodeAliceGenericMeshHand.h" + +typedef struct { + ListAliceGenericMeshHand hands; + /* Familiar pattern. Todo: move familiar pattern to l1 codegen. 3 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(), + }; +} + +typedef struct ListNodeAliceShinyMeshHand* RefListNodeAliceShinyMeshHand; +#include "../../../gen/l1/eve/alice/VecRefListNodeAliceShinyMeshHand.h" + +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(), + }; +} + + struct Alice { AliceCallbacks callbacks; AliceWaylandApp wl; @@ -1100,10 +780,10 @@ struct Alice { VkFormat zbuffer_format; VkFormat IT1_format; VkRenderPass render_pass_0; - PipelineHands pipeline_hands_0a; - PipelineHands pipeline_hands_0b; + AlicePipeline0a pipeline_hands_0a; + AlicePipeline0b pipeline_hands_0b; VkRenderPass render_pass_1; - PipelineHands pipeline_hands_1; + AlicePipeline1 pipeline_hands_1; VkSampler linear_sampler; VkSampler nearest_sampler; VkCommandPool command_pool; @@ -1111,9 +791,6 @@ struct Alice { VkCommandBuffer rendering_command_buf_1; VkCommandBuffer transfer_command_buf; VkCommandBuffer device_local_mem_mv_command_buf; - // todo: use MargaretBufAllocator for staging buffers. - // todo: but first, write the damn thing - VkCommandBuffer host_visible_mem_mv_command_buf; /* This is just pure blasphemy: todo: remove it nahyu */ VkDescriptorPool descriptor_pool; // todo: write dynamic allocator wrapper for descriptor pools MargaretImgAllocator dev_local_images; @@ -1123,27 +800,580 @@ struct Alice { Jane_alice jane; // todo: figure out my own design MargaretSwapchainBundle swfb; - SceneTemplate scene_template; + AlicePipeline0UBO pipeline0_ubo; + AliceAllMeshesGeneric generic_models; + AliceAllMeshesShiny shiny_models; + AliceCamVerticalControl cam_info; + /* stuff like background color, hdr factor and + * postprocessing kernel. Mostly related to renderpass 1 */ + AliceRenderConfig rendering_config; - Scene scene; MargaretImg IT1_image; MargaretImg zbuffer_image; FT_Library ft_library; LucyGlyphCache lucy_cache; - LucyFace font_face; - RBTreeNodeLucyFaceFixedSize* font_face_of_size_40; LucyRenderer lucy_renderer; - // todo: move it to AliceGenericModelHand - VecGenericModelTexVulkPointers generic_model_tex_vulk_pointers; VkImageView zbuffer_view; VkImageView IT1_view; VkFramebuffer IT1_framebuffer; VkDescriptorSet descriptor_set_for_pipeline_0b; VkDescriptorSet descriptor_set_for_pipeline_1; + + /* todo: it is not actually a part of engine code, it is an app code. I will delete it */ + LucyFace font_face; + RBTreeNodeLucyFaceFixedSize* font_face_of_size_40; + + ListNodeAliceGenericMeshHand* model_gen; + ListNodeAliceShinyMeshHand* model_sh; }; +ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, GenericMeshAndTextureFilePath mt){ + ListNodeAliceGenericMeshHand* mm_node = safe_calloc(1, sizeof(ListNodeAliceGenericMeshHand)); + AliceGenericMeshHand* mm = &mm_node->el; + mm->indexes = mt.topology.indexes.len; + mm->instance_attr.count = 0; + mm->instance_attr.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, 69); + mm->instance_attr.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, 69); + + mm->staging_vbo = MargaretBufAllocator_alloc(&alice->staging_buffers, + mt.topology.vertices.len * sizeof(GenericMeshVertex)); + mm->staging_ebo = MargaretBufAllocator_alloc(&alice->staging_buffers, + mt.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(&mt.diffuse_texture_path)); + mm->pixels_normal = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&mt.normal_texture_path)); + mm->pixels_specular = TextureDataR8_read_from_png_nofail(VecU8_to_span(&mt.specular_texture_path)); + VecU8_drop(mt.diffuse_texture_path); + VecU8_drop(mt.normal_texture_path); + VecU8_drop(mt.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 = MargaretBufAllocator_alloc(&alice->dev_local_buffers, + mt.topology.vertices.len * sizeof(GenericMeshVertex)); + mm->ebo = MargaretBufAllocator_alloc(&alice->dev_local_buffers, + mt.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->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 >= mt.topology.vertices.len * sizeof(GenericMeshVertex)); + assert(mm->vbo.len >= mt.topology.vertices.len * sizeof(GenericMeshVertex)); + GenericMeshVertex* staging_vbo = (GenericMeshVertex*)MargaretSubbuf_get_mapped(&mm->staging_vbo); + for (U64 i = 0; i < mt.topology.vertices.len; i++) { + staging_vbo[i].base = mt.topology.vertices.buf[i]; + } + assert(mt.topology.indexes.len % 3 == 0); + for (size_t ti = 0; ti * 3 < mt.topology.indexes.len; ti++) { + U32 v0 = mt.topology.indexes.buf[ti * 3 + 0]; + U32 v1 = mt.topology.indexes.buf[ti * 3 + 1]; + U32 v2 = mt.topology.indexes.buf[ti * 3 + 2]; + const GenericMeshVertexInc* A0 = VecGenericMeshVertexInc_at(&mt.topology.vertices, v0); + const GenericMeshVertexInc* A1 = VecGenericMeshVertexInc_at(&mt.topology.vertices, v1); + const GenericMeshVertexInc* A2 = VecGenericMeshVertexInc_at(&mt.topology.vertices, v2); + vec3 dp1 = vec3_minus_vec3(A1->pos, A0->pos); + vec3 dp2 = vec3_minus_vec3(A2->pos, A0->pos); + float du1 = A1->tex.x - A0->tex.x; + float dv1 = A1->tex.y - A0->tex.y; + float du2 = A2->tex.x - A0->tex.x; + float dv2 = A2->tex.y - A0->tex.y; + vec3 norm = vec3_normalize(vec3_cross(dp1, dp2)); + mat2x3 tang_U_V = mat3x2_transpose(mat2_mul_mat3x2( + mat2_inverse(mat2_new(du1, dv1, du2, dv2)), + mat2x3_transpose((mat2x3){.x = dp1, .y = dp2}) + )); + staging_vbo[v0].norm = staging_vbo[v1].norm = staging_vbo[v2].norm = norm; + staging_vbo[v0].tang_U = staging_vbo[v1].tang_U = staging_vbo[v2].tang_U = tang_U_V.x; + staging_vbo[v0].tang_V = staging_vbo[v1].tang_V = staging_vbo[v2].tang_V = tang_U_V.y; + } + /* Filling EBO is easy */ + assert(mt.topology.indexes.len == mm->indexes); + size_t ebo_len = mt.topology.indexes.len * sizeof(U32); + assert(mm->ebo.len >= ebo_len); + U32* staging_ebo = (U32*)MargaretSubbuf_get_mapped(&mm->staging_ebo); + memcpy(staging_ebo, mt.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, + TextureDataR8G8B8A8_get_size_in_bytes(&mm->pixels_diffuse)); + memcpy(MargaretSubbuf_get_mapped(&mm->staging_normal_tex_buf), 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, + 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; + + 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, + .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, + .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, + .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, + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .pBufferInfo = &buffer_info_for_descriptor_0_in_set_0a, + }, + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = P.p_0a_set_0, + .dstBinding = 1, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .pImageInfo = &image_info_for_descriptor_1_in_set_0a, + }, + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = P.p_0a_set_0, + .dstBinding = 2, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .pImageInfo = &image_info_for_descriptor_2_in_set_0a, + }, + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = P.p_0a_set_0, + .dstBinding = 3, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .pImageInfo = &image_info_for_descriptor_3_in_set_0a, + }, + }; + 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, ShinyMeshTopology topology){ + ListNodeAliceShinyMeshHand* mm_node = safe_calloc(1, sizeof(ListNodeAliceShinyMeshHand)); + AliceShinyMeshHand* mm = &mm_node->el; + + mm->indexes = topology.indexes.len; + + mm->instance_attr.count = 0; + 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)); + + ListAliceShinyMeshHand_insert_node(&alice->shiny_models.hands, mm_node); + VecRefListNodeAliceShinyMeshHand_append(&alice->shiny_models.to_be_copied_to_device_next_cycle, mm_node); + /* 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); + for (U64 i = 0; i < topology.vertices.len; i++) { + staging_vbo[i].base = topology.vertices.buf[i]; + } + assert(topology.indexes.len % 3 == 0); + for (size_t ti = 0; ti * 3 < topology.indexes.len; ti++) { + U32 v0 = topology.indexes.buf[ti * 3 + 0]; + U32 v1 = topology.indexes.buf[ti * 3 + 1]; + U32 v2 = topology.indexes.buf[ti * 3 + 2]; + vec3 p0 = VecShinyMeshVertexInc_at(&topology.vertices, v0)->pos; + vec3 p1 = VecShinyMeshVertexInc_at(&topology.vertices, v1)->pos; + vec3 p2 = VecShinyMeshVertexInc_at(&topology.vertices, v2)->pos; + 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 */ + + 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); + memcpy(staging_ebo, topology.indexes.buf, ebo_len); + return mm_node; +} + +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); + MargaretBufAllocator_expand_or_move_old_host_visible( + &alice->staging_buffers, &self->instance_attr.staging, needed_length); + } + self->instance_attr.count = new_count; +} + +void AliceShinyMeshHand_resize_instance_arr(Alice* alice, AliceShinyMeshHand* self, U64 new_count){ + U64 needed_length = new_count * sizeof(ShinyMeshInstance); + if (self->instance_attr.staging.len < needed_length) { + MargaretBufAllocator_expand_or_move_old_host_visible( + &alice->staging_buffers, &self->instance_attr.staging, needed_length); + } + self->instance_attr.count = new_count; +} + +void AliceGenericMeshHand_set(AliceGenericMeshHand* self, size_t instance, GenericMeshInstanceInc uncomp){ + assert(instance < self->instance_attr.count); + GenericMeshInstance* staging = (GenericMeshInstance*)MargaretSubbuf_get_mapped(&self->instance_attr.staging); + staging[instance].base = uncomp; + mat4 tr_inv = mat4_transpose(mat4_inverse(uncomp.model_t)); + staging[instance].normal_t = mat3_new( + tr_inv.x.x, tr_inv.y.x, tr_inv.z.x, + tr_inv.x.y, tr_inv.y.y, tr_inv.z.y, + tr_inv.x.z, tr_inv.y.z, tr_inv.z.z ); +} + +void AliceShinyMeshHand_set(AliceShinyMeshHand* self, size_t instance, ShinyMeshInstanceInc uncomp){ + assert(instance < self->instance_attr.count); + ShinyMeshInstance* staging = (ShinyMeshInstance*)MargaretSubbuf_get_mapped(&self->instance_attr.staging); + staging[instance].base = uncomp; + mat4 tr_inv = mat4_transpose(mat4_inverse(uncomp.model_t)); + staging[instance].normal_t = mat3_new( + tr_inv.x.x, tr_inv.y.x, tr_inv.z.x, + tr_inv.x.y, tr_inv.y.y, tr_inv.z.y, + 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); + } + 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); + + // 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); + } + 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); + + 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; +} + +/* No buffer rerecording, no buffer beginning, no buffer ending, + * 1) It copies initial generic model and shiny model topology. Textures of generic models included + * 2) For all models and for all light sources it copies EVERYTHING. + * You won't normally need to copy every single thing, but here you have the most bold solution. + * 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); + + for (ListNodeAliceGenericMeshHand* mm_node = alice->generic_models.hands.first; mm_node; mm_node = mm_node->next) { + AliceGenericMeshHand* mm = &mm_node->el; + assert(mm->instance_attr.count * sizeof(GenericMeshInstance) <= mm->instance_attr.staging.len); + if (mm->instance_attr.count * sizeof(GenericMeshInstance) > mm->instance_attr.device_local.len) { + MargaretBufAllocator_expand_or_free_old(&alice->dev_local_buffers, &mm->instance_attr.device_local, + mm->instance_attr.count * sizeof(GenericMeshInstance)); + } + assert(mm->instance_attr.count * sizeof(GenericMeshInstance) <= mm->instance_attr.device_local.len); + if (mm->instance_attr.count) { + margaret_rec_cmd_copy_buffer_one_to_one_part(alice->transfer_command_buf, + &mm->instance_attr.staging, &mm->instance_attr.device_local, 0, + mm->instance_attr.count * sizeof(GenericMeshInstance)); + } + } + for (ListNodeAliceShinyMeshHand* mm_node = alice->shiny_models.hands.first; mm_node; mm_node = mm_node->next) { + AliceShinyMeshHand* mm = &mm_node->el; + assert(mm->instance_attr.count * sizeof(ShinyMeshInstance) <= mm->instance_attr.staging.len); + if (mm->instance_attr.count * sizeof(ShinyMeshInstance) > mm->instance_attr.device_local.len) { + MargaretBufAllocator_expand_or_free_old(&alice->dev_local_buffers, &mm->instance_attr.device_local, + mm->instance_attr.count * sizeof(ShinyMeshInstance)); + } + assert(mm->instance_attr.count * sizeof(ShinyMeshInstance) <= mm->instance_attr.device_local.len); + if (mm->instance_attr.count) { + margaret_rec_cmd_copy_buffer_one_to_one_part(alice->transfer_command_buf, + &mm->instance_attr.staging, &mm->instance_attr.device_local, 0, + mm->instance_attr.count * sizeof(ShinyMeshInstance)); + } + } + Pipeline0UBO* mem = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_ubo.staging); + assert(mem->point_light_count <= pipeline_0_ubo_point_light_max_count); + assert(mem->spotlight_count <= pipeline_0_ubo_spotlight_max_count); + + // todo: I will probably replace pipeline0ubo with ubo for length + two readonly storage buffers for light sources + // all of this is basically useless + + const MargaretSubbuf* ubo_staging = &alice->pipeline0_ubo.staging; + const MargaretSubbuf* ubo_device_local = &alice->pipeline0_ubo.device_local; + + margaret_rec_cmd_copy_buffer_one_to_one_part(alice->transfer_command_buf, ubo_staging, ubo_device_local, + offsetof(Pipeline0UBO, point_light_count), sizeof(int)); + margaret_rec_cmd_copy_buffer_one_to_one_part(alice->transfer_command_buf, ubo_staging, ubo_device_local, + offsetof(Pipeline0UBO, spotlight_count), sizeof(int)); + if (mem->point_light_count) { + margaret_rec_cmd_copy_buffer_one_to_one_part(alice->transfer_command_buf, ubo_staging, ubo_device_local, + offsetof(Pipeline0UBO, point_light_arr), sizeof(Pipeline0PointLight) * mem->point_light_count); + } + if (mem->spotlight_count) { + margaret_rec_cmd_copy_buffer_one_to_one_part(alice->transfer_command_buf, ubo_staging, ubo_device_local, + offsetof(Pipeline0UBO, spotlight_arr), sizeof(Pipeline0Spotlight) * mem->spotlight_count); + } +} + + +void alice_reset_and_record_command_buffer_0(Alice* alice, mat4 proj_cam_t) { + margaret_reset_and_begin_command_buffer(alice->rendering_command_buf_0); + + vec4 clear_color = alice->rendering_config.clear_color; + VkExtent2D image_extent = alice->swfb.extent; + vkCmdBeginRenderPass(alice->rendering_command_buf_0, &(VkRenderPassBeginInfo){ + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .renderPass = alice->render_pass_0, + .framebuffer = alice->IT1_framebuffer, + .renderArea.offset = (VkOffset2D){0, 0}, + .renderArea.extent = image_extent, + .clearValueCount = 2, + .pClearValues = (VkClearValue[]){ + {.color.float32 = {clear_color.x, clear_color.y, clear_color.z, clear_color.w}}, + {.depthStencil = {.depth = 1, .stencil = 0}} + }, + }, VK_SUBPASS_CONTENTS_INLINE); + + vkCmdBindPipeline(alice->rendering_command_buf_0, VK_PIPELINE_BIND_POINT_GRAPHICS, alice->pipeline_hands_0a.pipeline); + record_cmd_set_viewport_and_scissors(alice->rendering_command_buf_0, image_extent); + vkCmdPushConstants(alice->rendering_command_buf_0, alice->pipeline_hands_0a.pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, + 0, sizeof(mat4), &proj_cam_t); + vkCmdPushConstants(alice->rendering_command_buf_0, alice->pipeline_hands_0a.pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, + sizeof(mat4), sizeof(vec3), &alice->cam_info.cam.pos); + + for (ListNodeAliceGenericMeshHand* mm_node = alice->generic_models.hands.first; mm_node; mm_node = mm_node->next) { + 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_inst_attr = &model->instance_attr.device_local; + const MargaretSubbuf* dev_local_ebo = &model->ebo; + // const + 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 }); + vkCmdBindIndexBuffer(alice->rendering_command_buf_0, MargaretSubbuf_get_buffer(dev_local_ebo), dev_local_ebo->start, + VK_INDEX_TYPE_UINT32); + vkCmdBindDescriptorSets( + alice->rendering_command_buf_0, VK_PIPELINE_BIND_POINT_GRAPHICS, alice->pipeline_hands_0a.pipeline_layout, 0, + 1, &model_indiv_descriptor_set_0, 0, NULL); + vkCmdDrawIndexed(alice->rendering_command_buf_0, model->indexes, model->instance_attr.count, 0, 0, 0); + } + + vkCmdBindPipeline(alice->rendering_command_buf_0, VK_PIPELINE_BIND_POINT_GRAPHICS, alice->pipeline_hands_0b.pipeline); + record_cmd_set_viewport_and_scissors(alice->rendering_command_buf_0, image_extent); + vkCmdPushConstants(alice->rendering_command_buf_0, alice->pipeline_hands_0b.pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, + 0, sizeof(mat4), &proj_cam_t); + vkCmdPushConstants(alice->rendering_command_buf_0, alice->pipeline_hands_0b.pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, + sizeof(mat4), sizeof(vec3), &alice->cam_info.cam.pos); + vkCmdBindDescriptorSets( + alice->rendering_command_buf_0, VK_PIPELINE_BIND_POINT_GRAPHICS, alice->pipeline_hands_0b.pipeline_layout, 0, + 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_inst_attr = &model->instance_attr.device_local; + const MargaretSubbuf* dev_local_ebo = &model->ebo; + 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 }); + vkCmdBindIndexBuffer(alice->rendering_command_buf_0, MargaretSubbuf_get_buffer(dev_local_ebo), dev_local_ebo->start, + VK_INDEX_TYPE_UINT32); + vkCmdDrawIndexed(alice->rendering_command_buf_0, model->indexes, model->instance_attr.count, 0, 0, 0); + } + + vkCmdEndRenderPass(alice->rendering_command_buf_0); + margaret_end_command_buffer(alice->rendering_command_buf_0); +} + +void alice_reset_and_record_command_buffer_1( + Alice* alice, VkFramebuffer swapchain_image_framebuffer + ) { + margaret_reset_and_begin_command_buffer(alice->rendering_command_buf_1); + + VkExtent2D image_extent = alice->swfb.extent; + vkCmdBeginRenderPass(alice->rendering_command_buf_1, &(VkRenderPassBeginInfo){ + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .renderPass = alice->render_pass_1, + .framebuffer = swapchain_image_framebuffer, + .renderArea.offset = (VkOffset2D){0, 0}, + .renderArea.extent = image_extent, + }, VK_SUBPASS_CONTENTS_INLINE); + vkCmdBindPipeline(alice->rendering_command_buf_1, VK_PIPELINE_BIND_POINT_GRAPHICS, alice->pipeline_hands_1.pipeline); + + record_cmd_set_viewport_and_scissors(alice->rendering_command_buf_1, image_extent); + vkCmdBindDescriptorSets( + alice->rendering_command_buf_1, VK_PIPELINE_BIND_POINT_GRAPHICS, alice->pipeline_hands_1.pipeline_layout, 0, + 1, &alice->descriptor_set_for_pipeline_1, 0, NULL); + + Pipeline1PushRangeVertex reg_and_params_vertex = {.win_scale = { + (float)image_extent.width / (float)alice->wl.sane_image_extent_limit.width, + (float)image_extent.height / (float)alice->wl.sane_image_extent_limit.height}, + }; + Pipeline1PushRangeFragment reg_and_params_fragment = { + .gamma_correction_factor = alice->rendering_config.gamma_correction_factor, + .hdr_factor = alice->rendering_config.hdr_factor, + .lsd_factor = alice->rendering_config.lsd_factor, + .anim_time = 0 /* Not used */ + }; + vkCmdPushConstants(alice->rendering_command_buf_1, alice->pipeline_hands_1.pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, + 0, sizeof(Pipeline1PushRangeVertex), ®_and_params_vertex); + vkCmdPushConstants(alice->rendering_command_buf_1, alice->pipeline_hands_1.pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, + sizeof(Pipeline1PushRangeVertex), sizeof(Pipeline1PushRangeFragment), ®_and_params_fragment); + vkCmdDraw(alice->rendering_command_buf_1, 3, 1, 0, 0); + + LucyRenderer_another_frame_rec_drawing(&alice->lucy_renderer, alice->rendering_command_buf_1, image_extent); + + vkCmdEndRenderPass(alice->rendering_command_buf_1); + margaret_end_command_buffer(alice->rendering_command_buf_1); +} + void recreate_swapchain(Alice *alice) { // We are stopping program and rebuilding our sem+sem+fence synchronization mechanism vkDeviceWaitIdle(alice->device); // todo: AAAAAAAAAAAAAAA this is all so so wrong AAAAAAAA @@ -1167,84 +1397,86 @@ void recreate_swapchain(Alice *alice) { alice->swfb = new_swfb; } -void update_state(Alice* alice, uint32_t dur) { - float fl = (float)dur / 1000; - - alice->scene.anim_time += fl; - if (alice->wl.first_0x80_keys[XKB_KEY_w]) - CamControlInfo_forward(&alice->scene.cam, fl); - if (alice->wl.first_0x80_keys[XKB_KEY_s]) - CamControlInfo_backward(&alice->scene.cam, fl); - if (alice->wl.first_0x80_keys[XKB_KEY_a]) - CamControlInfo_left(&alice->scene.cam, fl); - if (alice->wl.first_0x80_keys[XKB_KEY_d]) - CamControlInfo_right(&alice->scene.cam, fl); - if (alice->wl.first_0x80_keys[XKB_KEY_q]) - CamControlInfo_down(&alice->scene.cam, fl); - if (alice->wl.first_0x80_keys[XKB_KEY_e]) - CamControlInfo_up(&alice->scene.cam, fl); - - if (alice->wl.first_0x80_keys[XKB_KEY_bracketright]) { - for (size_t i = 0; i < alice->scene.smeshnyavka_3.len; i++) { - ObjectInfo* oi = &alice->scene.smeshnyavka_3.buf[i]; - vec3 p1 = alice->scene.cam.pos; - vec3 r = vec3_normalize(vec3_minus_vec3(p1, oi->pos)); - oi->rotation = mat3_mul_mat3(marie_3d_rot_mat3(r, fl * 0.7f), oi->rotation); - Scene_update_smeshnyavka_3(&alice->scene, i); - } - } - if (alice->wl.first_0x80_keys[XKB_KEY_bracketleft]) { - for (size_t i = 0; i < alice->scene.smeshnyavka_1.len; i++) { - ObjectInfo* oi = &alice->scene.smeshnyavka_1.buf[i]; - oi->rotation = mat3_mul_mat3(marie_3d_rot_mat3((vec3){0, 0, 1}, fl * 0.4f), oi->rotation); - Scene_update_smeshnyavka_1(&alice->scene, i); - } - } - if (alice->wl.first_0x80_keys[XKB_KEY_minus]) { - for (size_t i = 0; i < alice->scene.smeshnyavka_3.len; i++) { - ObjectInfo* oi = &alice->scene.smeshnyavka_3.buf[i]; - vec3 p1 = alice->scene.cam.pos; - float dist = vec3_length(vec3_minus_vec3(p1, oi->pos)); - float fac = 80/dist; - oi->scale *= (1 - 0.01f * fl * fac); - Scene_update_smeshnyavka_3(&alice->scene, i); - } - } - if (alice->wl.first_0x80_keys[XKB_KEY_equal]) { - for (size_t i = 0; i < alice->scene.smeshnyavka_3.len; i++) { - ObjectInfo* oi = &alice->scene.smeshnyavka_3.buf[i]; - vec3 p1 = alice->scene.cam.pos; - float dist = vec3_length(vec3_minus_vec3(p1, oi->pos)); - float fac = 80/dist; - oi->scale *= (1 + 0.01f * fl * fac); - Scene_update_smeshnyavka_3(&alice->scene, i); - } - } - - { - GenericModelOnSceneMem* model = VecGenericModelOnSceneMem_mat(&alice->scene.generic_models, 0); - assert(model->instance_attr.count >= 1); - if (alice->wl.first_0x80_keys[XKB_KEY_j]) { - alice->scene.smeshnyavka_1.buf[0].pos.x -= fl; - Scene_update_smeshnyavka_1(&alice->scene, 0); - } - if (alice->wl.first_0x80_keys[XKB_KEY_k]) { - alice->scene.smeshnyavka_1.buf[0].pos.z -= fl; - Scene_update_smeshnyavka_1(&alice->scene, 0); - } - if (alice->wl.first_0x80_keys[XKB_KEY_l]) { - alice->scene.smeshnyavka_1.buf[0].pos.z += fl; - Scene_update_smeshnyavka_1(&alice->scene, 0); - } - if (alice->wl.first_0x80_keys[XKB_KEY_semicolon]) { - alice->scene.smeshnyavka_1.buf[0].pos.x += fl; - Scene_update_smeshnyavka_1(&alice->scene, 0); - } - } +// todo: delete it +/* It is just a stupid example */ +void update_state(Alice* alice) { + float fl = AliceWaylandApp_get_elapsed_time(&alice->wl); + // todo: ok, maybe I don't want an example. I am good enough + // if (alice->wl.first_0x80_keys[XKB_KEY_w]) + // CamControlInfo_forward(&alice->scene.cam, fl); + // if (alice->wl.first_0x80_keys[XKB_KEY_s]) + // CamControlInfo_backward(&alice->scene.cam, fl); + // if (alice->wl.first_0x80_keys[XKB_KEY_a]) + // CamControlInfo_left(&alice->scene.cam, fl); + // if (alice->wl.first_0x80_keys[XKB_KEY_d]) + // CamControlInfo_right(&alice->scene.cam, fl); + // if (alice->wl.first_0x80_keys[XKB_KEY_q]) + // CamControlInfo_down(&alice->scene.cam, fl); + // if (alice->wl.first_0x80_keys[XKB_KEY_e]) + // CamControlInfo_up(&alice->scene.cam, fl); + // + // if (alice->wl.first_0x80_keys[XKB_KEY_bracketright]) { + // for (size_t i = 0; i < alice->scene.smeshnyavka_3.len; i++) { + // ObjectInfo* oi = &alice->scene.smeshnyavka_3.buf[i]; + // vec3 p1 = alice->scene.cam.pos; + // vec3 r = vec3_normalize(vec3_minus_vec3(p1, oi->pos)); + // oi->rotation = mat3_mul_mat3(marie_3d_rot_mat3(r, fl * 0.7f), oi->rotation); + // Scene_update_smeshnyavka_3(&alice->scene, i); + // } + // } + // if (alice->wl.first_0x80_keys[XKB_KEY_bracketleft]) { + // for (size_t i = 0; i < alice->scene.smeshnyavka_1.len; i++) { + // ObjectInfo* oi = &alice->scene.smeshnyavka_1.buf[i]; + // oi->rotation = mat3_mul_mat3(marie_3d_rot_mat3((vec3){0, 0, 1}, fl * 0.4f), oi->rotation); + // Scene_update_smeshnyavka_1(&alice->scene, i); + // } + // } + // if (alice->wl.first_0x80_keys[XKB_KEY_minus]) { + // for (size_t i = 0; i < alice->scene.smeshnyavka_3.len; i++) { + // ObjectInfo* oi = &alice->scene.smeshnyavka_3.buf[i]; + // vec3 p1 = alice->scene.cam.pos; + // float dist = vec3_length(vec3_minus_vec3(p1, oi->pos)); + // float fac = 80/dist; + // oi->scale *= (1 - 0.01f * fl * fac); + // Scene_update_smeshnyavka_3(&alice->scene, i); + // } + // } + // if (alice->wl.first_0x80_keys[XKB_KEY_equal]) { + // for (size_t i = 0; i < alice->scene.smeshnyavka_3.len; i++) { + // ObjectInfo* oi = &alice->scene.smeshnyavka_3.buf[i]; + // vec3 p1 = alice->scene.cam.pos; + // float dist = vec3_length(vec3_minus_vec3(p1, oi->pos)); + // float fac = 80/dist; + // oi->scale *= (1 + 0.01f * fl * fac); + // Scene_update_smeshnyavka_3(&alice->scene, i); + // } + // } + // + // { + // GenericModelOnSceneMem* model = VecGenericModelOnSceneMem_mat(&alice->scene.generic_models, 0); + // assert(model->instance_attr.count >= 1); + // if (alice->wl.first_0x80_keys[XKB_KEY_j]) { + // alice->scene.smeshnyavka_1.buf[0].pos.x -= fl; + // Scene_update_smeshnyavka_1(&alice->scene, 0); + // } + // if (alice->wl.first_0x80_keys[XKB_KEY_k]) { + // alice->scene.smeshnyavka_1.buf[0].pos.z -= fl; + // Scene_update_smeshnyavka_1(&alice->scene, 0); + // } + // if (alice->wl.first_0x80_keys[XKB_KEY_l]) { + // alice->scene.smeshnyavka_1.buf[0].pos.z += fl; + // Scene_update_smeshnyavka_1(&alice->scene, 0); + // } + // if (alice->wl.first_0x80_keys[XKB_KEY_semicolon]) { + // alice->scene.smeshnyavka_1.buf[0].pos.x += fl; + // Scene_update_smeshnyavka_1(&alice->scene, 0); + // } + // } } -/* It recreates image views, descriptor sets, framebuffers. */ -void recreate_vulkan_references_objects(Alice* alice){ +/* It creates image views, descriptor sets, framebuffers. But not for generic models. + * If we ever gonna do defragmentation, this step would have to be repeated */ +void alice_create_mem_dependant_vk_obj(Alice* alice){ alice->zbuffer_view = margaret_create_view_for_image(alice->device, alice->zbuffer_image.a.image, alice->zbuffer_format, VK_IMAGE_ASPECT_DEPTH_BIT); alice->IT1_view = margaret_create_view_for_image(alice->device, alice->IT1_image.a.image, @@ -1253,91 +1485,15 @@ void recreate_vulkan_references_objects(Alice* alice){ alice->IT1_view, alice->zbuffer_view, alice->render_pass_0, alice->wl.sane_image_extent_limit.width, alice->wl.sane_image_extent_limit.height); - /* Busy creating views for all my textures */ - alice->generic_model_tex_vulk_pointers = VecGenericModelTexVulkPointers_new_reserved(alice->scene.generic_models.len); - for (size_t i = 0; i < alice->scene.generic_models.len; i++) { - GenericModelOnSceneMem* model = &alice->scene.generic_models.buf[i]; - GenericModelTexVulkPointers P = (GenericModelTexVulkPointers){ - .diffuse_view = margaret_create_view_for_image(alice->device, model->diffuse_texture.a.image, - VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT), - .normal_view = margaret_create_view_for_image(alice->device, model->normal_texture.a.image, - VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT), - .specular_view = margaret_create_view_for_image(alice->device, model->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), - }; - VecGenericModelTexVulkPointers_append(&alice->generic_model_tex_vulk_pointers, P); - // Configuring my descriptor sets, that I just allocated - // todo: create a separate function for that shit - VkDescriptorBufferInfo buffer_info_for_descriptor_0_in_set_0a = { - .buffer = MargaretSubbuf_get_buffer(&alice->scene.pipeline0_ubo.device_local), - .offset = alice->scene.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, - .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, - .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, - .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, - .dstBinding = 0, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .pBufferInfo = &buffer_info_for_descriptor_0_in_set_0a, - }, - { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = P.p_0a_set_0, - .dstBinding = 1, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .pImageInfo = &image_info_for_descriptor_1_in_set_0a, - }, - { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = P.p_0a_set_0, - .dstBinding = 2, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .pImageInfo = &image_info_for_descriptor_2_in_set_0a, - }, - { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = P.p_0a_set_0, - .dstBinding = 3, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .pImageInfo = &image_info_for_descriptor_3_in_set_0a, - }, - }; - vkUpdateDescriptorSets(alice->device, ARRAY_SIZE(writes_in_descriptor_set), writes_in_descriptor_set, 0, NULL); - - } - alice->descriptor_set_for_pipeline_0b = margaret_allocate_descriptor_set( alice->device, alice->descriptor_pool, alice->pipeline_hands_0b.descriptor_set_layout); alice->descriptor_set_for_pipeline_1 = margaret_allocate_descriptor_set( alice->device, alice->descriptor_pool, alice->pipeline_hands_1.descriptor_set_layout); - // todo: update the others + ACTUALLY CARRY OUT DEVIEL LOCAL ALLOCATION MARAGERReeuqs request // todo: separate set0 and set 1 VkDescriptorBufferInfo buffer_info_for_descriptor_0_in_set_0b = { - .buffer = MargaretSubbuf_get_buffer(&alice->scene.pipeline0_ubo.device_local), - .offset = alice->scene.pipeline0_ubo.device_local.start, .range = sizeof(Pipeline0UBO), + .buffer = MargaretSubbuf_get_buffer(&alice->pipeline0_ubo.device_local), + .offset = alice->pipeline0_ubo.device_local.start, .range = sizeof(Pipeline0UBO), }; VkDescriptorImageInfo image_info_for_descriptor_0_in_set_1 = { .sampler = alice->nearest_sampler, .imageView = alice->IT1_view, @@ -1369,50 +1525,11 @@ void recreate_vulkan_references_objects(Alice* alice){ /* Needed for defragmentation of memory */ void destroy_vulkan_reference_objects(Alice* alice){ - + abortf("Please don't\n"); // todo: vkdestro all the views all the framebuffers // todo: drop everything, } -/* another frame. busy staging buffer is not longer busy. And the updatable staging buffer contains updates. - * We copy updates to the one that once was hella busy, but not anymore, and the updatable buffer swaps places with - * busy buffer. This happens in generic model instances, shiny model instances, pipeline0 ubo - */ -void Scene_swap_talking_buffers(Scene* scene){ - for (size_t mi = 0; mi < scene->generic_models.len; mi++) { - PatriciaBuf* inst = &scene->generic_models.buf[mi].instance_attr; - assert(inst->count <= inst->cap); - assert(inst->cap * sizeof(GenericMeshInstance) <= inst->staging_updatable.len); - assert(inst->staging_updatable.len == inst->staging_busy.len); - memcpy(MargaretSubbuf_get_mapped(&inst->staging_busy), MargaretSubbuf_get_mapped(&inst->staging_updatable), - inst->count * sizeof(GenericMeshInstance)); - PatriciaBuf_swap_staging(inst); - } - for (size_t mi = 0; mi < scene->shiny_models.len; mi++) { - PatriciaBuf* inst = &scene->shiny_models.buf[mi].instance_attr; - assert(inst->count <= inst->cap); - assert(inst->cap * sizeof(ShinyMeshInstance) <= inst->staging_updatable.len); - assert(inst->staging_updatable.len == inst->staging_busy.len); - memcpy(MargaretSubbuf_get_mapped(&inst->staging_busy), MargaretSubbuf_get_mapped(&inst->staging_updatable), - inst->count * sizeof(ShinyMeshInstance)); - PatriciaBuf_swap_staging(inst); - } - { - Pipeline0Transfer* ubo = &scene->pipeline0_ubo; - Pipeline0UBO* updated = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&ubo->staging_updatable); - Pipeline0UBO* outdated = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&ubo->staging_busy); - outdated->point_light_count = updated->point_light_count; - outdated->spotlight_count = updated->spotlight_count; - memcpy(outdated->point_light_arr, updated->point_light_arr, - sizeof(Pipeline0PointLight) * updated->point_light_count); - memcpy(outdated->spotlight_arr, updated->spotlight_arr, - sizeof(Pipeline0Spotlight) * updated->spotlight_count); - MargaretSubbuf t = ubo->staging_updatable; - ubo->staging_updatable = ubo->staging_busy; - ubo->staging_busy = t; - } -} - void alice_frame_drawing(Alice* alice) { check(vkWaitForFences(alice->device, 1, &alice->jane.in_flight_fence, VK_TRUE, UINT64_MAX) == VK_SUCCESS); check(vkResetFences(alice->device, 1, &alice->jane.in_flight_fence) == VK_SUCCESS); @@ -1431,22 +1548,18 @@ void alice_frame_drawing(Alice* alice) { abortf("vkAcquireNextImageKHR"); } - Scene_swap_talking_buffers(&alice->scene); - - alice->scene.color = (VkClearColorValue){{0, 0.5f, 0.9f, 1}}; mat4 projection_matrix = marie_perspective_projection_fov_mat4( (float)alice->wl.width_confirmed, (float)alice->wl.height_confirmed, - alice->scene.cam.fov, 0.01f, 1000); - mat4 camera_rotation_matrix = marie_mat3_to_mat4_transposed(alice->scene.cam.cam_basis); - mat4 camera_translation_matrix = marie_translation_mat4(vec3_minus(alice->scene.cam.pos)); + alice->cam_info.cam.fov, 0.01f, 1000); + mat4 camera_rotation_matrix = marie_mat3_to_mat4_transposed(alice->cam_info.cam.cam_basis); + mat4 camera_translation_matrix = marie_translation_mat4(vec3_minus(alice->cam_info.cam.pos)); mat4 t_mat = mat4_mul_mat4(projection_matrix, mat4_mul_mat4(camera_rotation_matrix, camera_translation_matrix)); alice->callbacks.on_another_frame(alice); margaret_reset_and_begin_command_buffer(alice->transfer_command_buf); - // todo: replace vector with a list and start supporting handlers - record_copying_entire_scene_from_staging_to_device_local(alice->transfer_command_buf, &alice->scene); + AliceScene__another_frame(alice); LucyGlyphCache_another_frame(&alice->lucy_cache); // LucyRenderer_clear(&alice->lucy_renderer); @@ -1455,21 +1568,9 @@ void alice_frame_drawing(Alice* alice) { LucyRenderer_another_frame(&alice->lucy_renderer); margaret_end_command_buffer(alice->transfer_command_buf); - reset_and_record_command_buffer_0( - alice->rendering_command_buf_0, alice->render_pass_0, - &alice->pipeline_hands_0a, &alice->pipeline_hands_0b, - alice->IT1_framebuffer, alice->swfb.extent, - &alice->scene, - &alice->generic_model_tex_vulk_pointers, /* Needed just to get descriptor sets for generic models */ - alice->descriptor_set_for_pipeline_0b, - t_mat, alice->scene.cam.pos); + alice_reset_and_record_command_buffer_0(alice, t_mat); - reset_and_record_command_buffer_1(alice->rendering_command_buf_1, alice->render_pass_1, - &alice->pipeline_hands_1, - *VecVkFramebuffer_at(&alice->swfb.framebuffers, ij), - alice->swfb.extent, - alice->wl.sane_image_extent_limit, &alice->scene, alice->descriptor_set_for_pipeline_1, - &alice->lucy_renderer); + alice_reset_and_record_command_buffer_1(alice, *VecVkFramebuffer_at(&alice->swfb.framebuffers, ij)); check(vkQueueSubmit(alice->queues.graphics_queue, 1, &(VkSubmitInfo){ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, @@ -1588,8 +1689,6 @@ static const struct xdg_wm_base_listener main_h_xdg_wm_base_listener = { .ping = main_h_xdg_wm_base_ping, }; - - static void main_h_wl_keyboard_keymap( void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int32_t fd, uint32_t size ) { @@ -1647,28 +1746,24 @@ static void main_h_wl_keyboard_key( alice->callbacks.on_wl_keyboard_key(alice); if (key_action == WL_KEYBOARD_KEY_STATE_RELEASED) { if (keysym == XKB_KEY_1) { - vec3 p = alice->scene.cam.pos; - p.y += 1.5f; - ShinyModelOnSceneMem* model = VecShinyModelOnSceneMem_mat(&alice->scene.shiny_models, 0); - assert(model->instance_attr.count >= 1); - VecObjectInfo_mat(&alice->scene.smeshnyavka_3, 0)->pos = p; - Scene_update_smeshnyavka_3(&alice->scene, 0); - - Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->scene.pipeline0_ubo.staging_updatable); - assert(ubo->point_light_count >= 1); - ubo->point_light_arr[0].pos = p; - - printf("Point light source pos set to %f %f %f\n", p.x, p.y, p.z); + // vec3 p = alice->cam_info.pos; + // p.y += 1.5f; + // ShinyModelOnSceneMem* model = VecShinyModelOnSceneMem_mat(&alice->scene.shiny_models, 0); + // assert(model->instance_attr.count >= 1); + // VecObjectInfo_mat(&alice->scene.smeshnyavka_3, 0)->pos = p; + // Scene_update_smeshnyavka_3(&alice->scene, 0); + // + // Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->scene.pipeline0_ubo.staging_updatable); + // assert(ubo->point_light_count >= 1); + // ubo->point_light_arr[0].pos = p; + // + // printf("Point light source pos set to %f %f %f\n", p.x, p.y, p.z); } else if (keysym == XKB_KEY_2) { - alice->scene.hdr_factor /= 1.05f; - printf("hdr factor decreased to %f\n", alice->scene.hdr_factor); + alice->rendering_config.hdr_factor /= 1.05f; + printf("hdr factor decreased to %f\n", alice->rendering_config.hdr_factor); } else if (keysym == XKB_KEY_3) { - alice->scene.hdr_factor *= 1.05f; - printf("hdr factor increased to %f\n", alice->scene.hdr_factor); - } else if (keysym == XKB_KEY_7) { - VecU8_append(&alice->scene.text_on_screen, '7'); - } else if (keysym == XKB_KEY_Return) { - VecU8_append(&alice->scene.text_on_screen, '\n'); + alice->rendering_config.hdr_factor *= 1.05f; + printf("hdr factor increased to %f\n", alice->rendering_config.hdr_factor); } } } @@ -1710,7 +1805,7 @@ static void main_h_wl_pointer_motion( void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y ) { Alice* alice = data; - CamControlInfo_update_direction(&alice->scene.cam, + AliceCamVerticalControl_update_direction(&alice->cam_info, alice->wl.width_confirmed, alice->wl.height_confirmed, (float)surface_x / 256.f, (float)surface_y / 256.f); } @@ -1809,9 +1904,6 @@ static void main_h_wl_surface_frame_done(void *data, struct wl_callback *cb, uin abortf("wl_surface_frame\n"); wl_callback_add_listener(alice->wl.wl_callback, &main_h_wl_surface_frame_listener, alice); - if (alice->wl.last_frame_time != 0) { - update_state(alice, time - alice->wl.last_frame_time); - } alice_frame_drawing(alice); alice->wl.last_frame_time = time; } @@ -1867,6 +1959,7 @@ Alice* Alice_new(){ if (!alice->wl.wl_callback) abortf("wl_surface_frame\n"); wl_callback_add_listener(alice->wl.wl_callback, &main_h_wl_surface_frame_listener, alice); + alice->wl.cur_frame_time = alice->wl.last_frame_time = 0; alice->instance_and_debug = MargaretInstanceAndItsDebug_new(ENABLE_VALIDATION_LAYERS); VkInstance instance = alice->instance_and_debug.instance; @@ -1918,10 +2011,8 @@ Alice* Alice_new(){ alice->rendering_command_buf_1 = margaret_allocate_command_buffer(alice->device, alice->command_pool); alice->transfer_command_buf = margaret_allocate_command_buffer(alice->device, alice->command_pool); alice->device_local_mem_mv_command_buf = margaret_allocate_command_buffer(alice->device, alice->command_pool); - // todo: git rid of this line. Rn it won't even be used, like, at all... I won't actually use it in my test, yes, I am not a psyco - alice->host_visible_mem_mv_command_buf = margaret_allocate_command_buffer(alice->device, alice->command_pool); - // todo: write a descriptor set allocator (in Margaret) that manages synamic descript or pool allocatrinonsasdasdasd + // todo: write a descriptor set allocator (in Margaret) that manages dynamic descript or pool allocatrinonsasdasdasd alice->descriptor_pool = margaret_create_descriptor_set_pool(alice->device, 100, 100, 100); /* Here we search physical device memory types for the one with host-visible flag and the other with device-local flag */ @@ -1971,104 +2062,14 @@ Alice* Alice_new(){ alice->device, alice->queue_fam, swapchain_details_res.ok, alice->surface, alice->render_pass_1, NULL); - alice->scene_template = (SceneTemplate){ - .generic_models = VecGenericMeshInSceneTemplate_new(), - .shiny_models = VecShinyMeshTopology_new() - }; + alice->generic_models = AliceAllMeshesGeneric_new(); + alice->shiny_models = AliceAllMeshesShiny_new(); + alice->pipeline0_ubo.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, sizeof(Pipeline0UBO)); + alice->pipeline0_ubo.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, sizeof(Pipeline0UBO)); - VecGenericMeshInSceneTemplate_append(&alice->scene_template.generic_models, - GenericMeshInSceneTemplate_for_log(root_dir, 10, 2, 6)); - VecShinyMeshTopology_append(&alice->scene_template.shiny_models, generate_shiny_cube(0.3f)); + alice->cam_info = AliceCamVerticalControl_new(); + alice->rendering_config = AliceRenderConfig_new(); - VecGenericModelOnSceneMem generic_model_mem = VecGenericModelOnSceneMem_new(); - VecShinyModelOnSceneMem shiny_model_mem = VecShinyModelOnSceneMem_new(); - - for (size_t i = 0; i < alice->scene_template.generic_models.len; i++) { - const GenericMeshInSceneTemplate* template = &alice->scene_template.generic_models.buf[i]; - GenericModelOnSceneMem mem; - mem.indexes = template->topology.indexes.len; - - mem.instance_attr.cap = 100; - // todo: patricia method should manage this, not me - mem.instance_attr.staging_busy = MargaretBufAllocator_alloc(&alice->staging_buffers, - mem.instance_attr.cap * sizeof(GenericMeshInstance)); - mem.instance_attr.staging_updatable = MargaretBufAllocator_alloc(&alice->staging_buffers, - mem.instance_attr.cap * sizeof(GenericMeshInstance)); - mem.instance_attr.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, - mem.instance_attr.cap * sizeof(GenericMeshInstance)); - mem.instance_attr.count = 0; - - mem.staging_vbo = MargaretBufAllocator_alloc(&alice->staging_buffers, - template->topology.vertices.len * sizeof(GenericMeshVertex)); - mem.staging_ebo = MargaretBufAllocator_alloc(&alice->staging_buffers, - template->topology.indexes.len * sizeof(U32)); - - mem.pixels_diffuse = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&template->diffuse_texture_path)), - mem.pixels_normal = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&template->normal_texture_path)), - mem.pixels_specular = TextureDataR8_read_from_png_nofail(VecU8_to_span(&template->specular_texture_path)), - - mem.staging_diffuse_tex_buf = MargaretBufAllocator_alloc(&alice->staging_buffers, - mem.pixels_diffuse.pixels.len * sizeof(cvec4)); - mem.staging_normal_tex_buf = MargaretBufAllocator_alloc(&alice->staging_buffers, - mem.pixels_normal.pixels.len * sizeof(cvec4)); - mem.staging_specular_tex_buf = MargaretBufAllocator_alloc(&alice->staging_buffers, - mem.pixels_specular.pixels.len * sizeof(U8)); - - mem.vbo = MargaretBufAllocator_alloc(&alice->dev_local_buffers, - template->topology.vertices.len * sizeof(GenericMeshVertex)); - mem.ebo = MargaretBufAllocator_alloc(&alice->dev_local_buffers, - template->topology.indexes.len * sizeof(U32)); - - mem.diffuse_texture = MargaretImgAllocator_alloc(&alice->dev_local_images, - mem.pixels_diffuse.width, mem.pixels_diffuse.height, - VK_FORMAT_R8G8B8A8_SRGB, - VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); - mem.normal_texture = MargaretImgAllocator_alloc(&alice->dev_local_images, - mem.pixels_normal.width, mem.pixels_normal.height, - VK_FORMAT_R8G8B8A8_UNORM, - VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); - mem.specular_texture = MargaretImgAllocator_alloc(&alice->dev_local_images, - mem.pixels_specular.width, mem.pixels_specular.height, - VK_FORMAT_R8_UNORM, - VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); - VecGenericModelOnSceneMem_append(&generic_model_mem, mem); - } - - for (size_t i = 0; i < alice->scene_template.shiny_models.len; i++) { - const ShinyMeshTopology* temp_topology = &alice->scene_template.shiny_models.buf[i]; - ShinyModelOnSceneMem mem; - mem.indexes = temp_topology->indexes.len; - - mem.instance_attr.cap = 100; - // todo: patricia method should manage this, not me - mem.instance_attr.staging_busy = MargaretBufAllocator_alloc(&alice->staging_buffers, - mem.instance_attr.cap * sizeof(ShinyMeshInstance)); - mem.instance_attr.staging_updatable = MargaretBufAllocator_alloc(&alice->staging_buffers, - mem.instance_attr.cap * sizeof(ShinyMeshInstance)); - mem.instance_attr.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, - mem.instance_attr.cap * sizeof(ShinyMeshInstance)); - mem.instance_attr.count = 0; - - mem.staging_vbo = MargaretBufAllocator_alloc(&alice->staging_buffers, - temp_topology->vertices.len * sizeof(ShinyMeshVertex)); - mem.staging_ebo = MargaretBufAllocator_alloc(&alice->staging_buffers, - temp_topology->indexes.len * sizeof(U32)); - - mem.vbo = MargaretBufAllocator_alloc(&alice->dev_local_buffers, - temp_topology->vertices.len * sizeof(ShinyMeshVertex)); - mem.ebo = MargaretBufAllocator_alloc(&alice->dev_local_buffers, - temp_topology->indexes.len * sizeof(U32)); - - VecShinyModelOnSceneMem_append(&shiny_model_mem, mem); - } - - Pipeline0Transfer pipeline0_ubo = (Pipeline0Transfer){ - .staging_busy = MargaretBufAllocator_alloc(&alice->staging_buffers, sizeof(Pipeline0UBO)), - .staging_updatable = MargaretBufAllocator_alloc(&alice->staging_buffers, sizeof(Pipeline0UBO)), - .device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, sizeof(Pipeline0UBO)), - }; - - alice->scene = Scene_new(generic_model_mem, shiny_model_mem, pipeline0_ubo); alice->IT1_image = MargaretImgAllocator_alloc(&alice->dev_local_images, MAX_WIN_WIDTH, MAX_WIN_HEIGHT, alice->IT1_format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); alice->zbuffer_image = MargaretImgAllocator_alloc(&alice->dev_local_images, @@ -2086,6 +2087,17 @@ Alice* Alice_new(){ abortf("Can't init free type library\n"); alice->lucy_cache = LucyGlyphCache_new(engine_reference); + + alice->lucy_renderer = LucyRenderer_new(engine_reference, &alice->lucy_cache, root_dir, alice->render_pass_1, 0); + + // Creating framebuffer for IT1, image views for IT1 and zbuffer + // Creating descriptor set for pipeline 0b and for pipeline 1 (containing IT1 sampler) + alice_create_mem_dependant_vk_obj(alice); + + alice->wl.prev_key_frame_time = margaret_clock_gettime_monotonic_raw(); + alice->wl.frame_count_since_key = 0; + /* Alice initialization complete */ + /* todo: delete exaple data initialization. Yes, this is not part of an engine. It is an example I need to delete this */ alice->font_face = LucyFace_new(alice->ft_library, &alice->lucy_cache, VecU8_fmt("%s/src/l3/fonts/DMSerifText-Regular.ttf", root_dir)); alice->font_face_of_size_40 = LucyFace_of_size(&alice->font_face, 40); @@ -2098,35 +2110,38 @@ Alice* Alice_new(){ }); LucyGlyphCache_add_glyphs(lucy_requests); } - VecU8_append_span(&alice->scene.text_on_screen, cstr("I am late :(\nExam is in 25 hours...")); - alice->lucy_renderer = LucyRenderer_new(engine_reference, &alice->lucy_cache, root_dir, alice->render_pass_1, 0); - { - GenericModelOnSceneMem *model_g = VecGenericModelOnSceneMem_mat(&alice->scene.generic_models, 0); - assert(model_g->instance_attr.cap >= 100); - for (int X = 0; X < 10; X++) { - for (int Z = 0; Z < 10; Z++) { - Scene_add_smeshnyavka_1(&alice->scene, (ObjectInfo){ - .pos = (vec3){11.f * (float)X, -6, 4.f * (float)Z}, - .scale = 1, .rotation = mat3_E}); - } - } + alice->model_gen = Alice_add_generic_mesh(alice, GenericMeshAndTextureFilePath_for_log(root_dir, 10, 2, 6)); + AliceGenericMeshHand_resize_instance_arr(alice, &alice->model_gen->el, 100); for (int X = 0; X < 10; X++) { for (int Z = 0; Z < 10; Z++) { - Scene_add_smeshnyavka_3(&alice->scene, (ObjectInfo){.rotation = mat3_E, - .pos = (vec3){11.f * (float)X - 20, 10, 4.f * (float)Z - 10}, .scale = 1, .color_on = {0, 1, 0}}); + AliceGenericMeshHand_set(&alice->model_gen->el, X * 10 + Z, (GenericMeshInstanceInc){ + .model_t = marie_translation_mat4((vec3){11.f * (float)X, -6, 4.f * (float)Z}), + }); } } - Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->scene.pipeline0_ubo.staging_updatable); + alice->model_sh = Alice_add_shiny_mesh(alice, generate_shiny_cube(0.3f)); + AliceShinyMeshHand_resize_instance_arr(alice, &alice->model_sh->el, 100); + + for (int X = 0; X < 10; X++) { + for (int Z = 0; Z < 10; Z++) { + AliceShinyMeshHand_set(&alice->model_sh->el, X * 10 + Z, (ShinyMeshInstanceInc){ + .color_on = {0, 1, 0}, .color_off = {0.3f, 0.6f, 0.3f}, + .model_t = marie_translation_mat4((vec3){11.f * (float)X - 20, 10, 4.f * (float)Z - 10}), + }); + } + } + + Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_ubo.staging); assert(pipeline_0_ubo_point_light_max_count >= 100); ubo->point_light_count = 100; ubo->spotlight_count = 0; for (int X = 0; X < 10; X++) { for (int Z = 0; Z < 10; Z++) { ubo->point_light_arr[X * 10 + Z] = (Pipeline0PointLight){ - .pos = (vec3){11.f * (float)X, 10, 4.f * (float)Z}, + .pos = (vec3){11.f * (float)X - 20, 10, 4.f * (float)Z - 10}, .color = {5, 5, 5} }; } @@ -2134,40 +2149,9 @@ Alice* Alice_new(){ ubo->point_light_arr[0].color = (vec3){100, 100, 100}; } - /* Here we both copy from topology + textures to staging buffers and record commands that will copy staging data - * to device local memory */ - margaret_reset_and_begin_command_buffer(alice->transfer_command_buf); - SceneTemplate_copy_initial_model_topology_cmd_buf_recording( - &alice->scene_template, &alice->scene, alice->transfer_command_buf); - for (U64 i = 0; i < alice->scene.generic_models.len; i++) { - GenericModelOnSceneMem* model = &alice->scene.generic_models.buf[i]; - memcpy(MargaretSubbuf_get_mapped(&model->staging_diffuse_tex_buf), model->pixels_diffuse.pixels.buf, - TextureDataR8G8B8A8_get_size_in_bytes(&model->pixels_diffuse)); - memcpy(MargaretSubbuf_get_mapped(&model->staging_normal_tex_buf), model->pixels_normal.pixels.buf, - TextureDataR8G8B8A8_get_size_in_bytes(&model->pixels_normal)); - memcpy(MargaretSubbuf_get_mapped(&model->staging_specular_tex_buf), model->pixels_specular.pixels.buf, - TextureDataR8_get_size_in_bytes(&model->pixels_specular)); + LucyRenderer_add_text(&alice->lucy_renderer, alice->font_face_of_size_40, (vec4){1, 0, 0, 1}, 0, + cstr("Bebra budet\notnyahana"), (ivec2){10, 10}); - margaret_rec_cmd_copy_buffer_to_image_one_to_one_color_aspect(alice->transfer_command_buf, - &model->staging_diffuse_tex_buf, &model->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, - &model->staging_normal_tex_buf, &model->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, - &model->staging_specular_tex_buf, &model->specular_texture, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT); - } - margaret_end_command_buffer(alice->transfer_command_buf); - check(vkQueueSubmit(alice->queues.graphics_queue, 1, &(VkSubmitInfo){ - .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .commandBufferCount = 1, .pCommandBuffers = &alice->transfer_command_buf, - }, alice->jane.roxy) == VK_SUCCESS); - check(vkWaitForFences(alice->device, 1, &alice->jane.roxy, VK_TRUE, UINT64_MAX) == VK_SUCCESS); - - recreate_vulkan_references_objects(alice); - - alice->wl.prev_key_frame_time = margaret_clock_gettime_monotonic_raw(); - alice->wl.frame_count_since_key = 0; return alice; } diff --git a/src/l2/anne/r4_models.h b/src/l2/anne/r4_models.h index ae3f945..eec0cad 100644 --- a/src/l2/anne/r4_models.h +++ b/src/l2/anne/r4_models.h @@ -141,8 +141,8 @@ CubeVertOfFace CubeVertOfFace_next(CubeVertOfFace vert) { } // todo: yes, it is AGAINST THE RULES to take from l3 when being on l2, but we fjsdafklj lI WILL REMOVE THIS OK, MAN CALM DOWN -GenericMeshInSceneTemplate GenericMeshInSceneTemplate_for_log(SpanU8 root_dir, U64 w, U64 r, U64 k) { - return (GenericMeshInSceneTemplate){.topology = generate_one_fourth_of_a_cylinder((float)w, (float)r, k), +GenericMeshAndTextureFilePath GenericMeshAndTextureFilePath_for_log(SpanU8 root_dir, U64 w, U64 r, U64 k) { + return (GenericMeshAndTextureFilePath){.topology = generate_one_fourth_of_a_cylinder((float)w, (float)r, k), .diffuse_texture_path = VecU8_fmt("%s/src/l3/textures/log_%u_%u_%u_diffuse.png", root_dir, w, r, k), .normal_texture_path = VecU8_fmt("%s/gen/l2/textures/r4/log_%u_%u_%u_NORMAL.png", root_dir, w, r, k), .specular_texture_path = VecU8_fmt("%s/src/l3/textures/log_%u_%u_%u_specular.png", root_dir, w, r, k), diff --git a/src/l2/margaret/vulkan_buffer_claire.h b/src/l2/margaret/vulkan_buffer_claire.h index c7b0f4f..b01c6fc 100644 --- a/src/l2/margaret/vulkan_buffer_claire.h +++ b/src/l2/margaret/vulkan_buffer_claire.h @@ -202,6 +202,9 @@ void MargaretBufAllocator_free(MargaretBufAllocator* self, MargaretSubbuf alloca MargaretBufAllocator__insert_gap(self, allocation.block, left_free_space.start, right_free_space.start + right_free_space.len - left_free_space.start); + + bool eret = BufRBTree_MapU64ToU64_erase(&allocation.block->occupants, allocation.start); + assert(eret); } /* Idk how to hide this monster */ diff --git a/src/l2/margaret/vulkan_images_claire.h b/src/l2/margaret/vulkan_images_claire.h index 342f016..05c6048 100644 --- a/src/l2/margaret/vulkan_images_claire.h +++ b/src/l2/margaret/vulkan_images_claire.h @@ -442,6 +442,10 @@ void MargaretImgAllocator_free(MargaretImgAllocator* self, MargaretImgAllocation MargaretImgAllocator__insert_gap(self, allocation.block, left_free_space.start, right_free_space.start + right_free_space.len - left_free_space.start); + + MargaretImgAllocatorOneBlock* block = VecMargaretImgAllocatorOneBlock_mat(&self->blocks, allocation.block); + bool eret = BufRBTree_MapU64ToU64_erase(&block->images, allocation.start); + assert(eret); } NODISCARD MargaretImgAllocation MargaretImgAllocator__alloc( diff --git a/src/l3/r4/r4.c b/src/l3/r4/r4.c new file mode 100644 index 0000000..1ad2117 --- /dev/null +++ b/src/l3/r4/r4.c @@ -0,0 +1,18 @@ +#include "../../l2/allie/allie.c" + +void main_h_on_wayland_keyboard_key(Alice* alice){ + +} + +void main_h_on_another_frame(Alice* alice){ + +} + +int main(){ + Alice* alice = Alice_new(); + Alice_mainloop(alice, &(AliceCallbacks){ + .on_wl_keyboard_key = main_h_on_wayland_keyboard_key, + .on_another_frame = main_h_on_another_frame, + }); + return 0; +} \ No newline at end of file