diff --git a/src/l2/alice/engine.h b/src/l2/alice/engine.h index ba91438..617eaf8 100644 --- a/src/l2/alice/engine.h +++ b/src/l2/alice/engine.h @@ -226,10 +226,7 @@ AlicePipeline0a create_graphics_pipeline_0a( .offset = 0, .size = sizeof(mat4) }, { .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - .offset = sizeof(mat4), .size = sizeof(vec3) - }, { - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - .offset = sizeof(mat4) + sizeof(vec3), .size = sizeof(U32) * 3 + .offset = sizeof(mat4), .size = sizeof(vec3) + sizeof(U32) * 3, } }; @@ -586,6 +583,7 @@ void record_cmd_set_viewport_and_scissors(VkCommandBuffer command_buffer, VkExte typedef struct { VkSemaphore in_frame_transfer_complete; + VkSemaphore in_frame_compute_complete; VkSemaphore image_available_semaphore; VkSemaphore rendered_to_IT1_semaphore; VkFence in_flight_fence; @@ -596,6 +594,7 @@ typedef struct { NODISCARD Jane_alice Jane_alice_create(VkDevice device) { return (Jane_alice){ .in_frame_transfer_complete = margaret_create_semaphore(device), + .in_frame_compute_complete = margaret_create_semaphore(device), .image_available_semaphore = margaret_create_semaphore(device), .rendered_to_IT1_semaphore = margaret_create_semaphore(device), .in_flight_fence = margaret_create_fence(device, true), @@ -718,7 +717,7 @@ struct Alice { VkCommandBuffer rendering_command_buf_0; VkCommandBuffer rendering_command_buf_1; VkCommandBuffer transfer_command_buf; - VkCommandBuffer device_local_mem_mv_command_buf; + VkCommandBuffer compute_command_buf; VkDescriptorPool descriptor_pool; // todo: write dynamic allocator wrapper for descriptor pools MargaretImgAllocator* dev_local_images; @@ -1074,12 +1073,14 @@ void alice_frame_drawing(Alice* alice) { } else { alice->transfer_command_buf_already_reset = false; } + margaret_reset_and_begin_command_buffer(alice->compute_command_buf); alice->callbacks.on_another_frame(alice->guest, (float)(alice->wl.cur_frame_time - alice->wl.last_frame_time) / 1000); AliceScene__another_frame(alice); // LucyGlyphCache_another_frame(&alice->lucy_cache); lucy cache has no business here LucyRenderer_another_frame(&alice->lucy_renderer); margaret_end_command_buffer(alice->transfer_command_buf); + margaret_end_command_buffer(alice->compute_command_buf); alice_reset_and_record_command_buffer_0(alice, t_mat); alice_reset_and_record_command_buffer_1(alice, *VecVkFramebuffer_at(&alice->swfb.framebuffers, ij)); @@ -1092,11 +1093,22 @@ void alice_frame_drawing(Alice* alice) { .pSignalSemaphores = (VkSemaphore[]){ alice->jane.in_frame_transfer_complete }, }, NULL) == VK_SUCCESS); + check(vkQueueSubmit(alice->queues.compute, 1, &(VkSubmitInfo){ + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .waitSemaphoreCount = 1, + .pWaitSemaphores = (VkSemaphore[]){alice->jane.in_frame_transfer_complete}, + .pWaitDstStageMask = (VkPipelineStageFlags[]){ VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT }, + .commandBufferCount = 1, + .pCommandBuffers = (VkCommandBuffer[]){ alice->compute_command_buf }, + .signalSemaphoreCount = 1, + .pSignalSemaphores = (VkSemaphore[]){ alice->jane.in_frame_compute_complete }, + }, NULL) == VK_SUCCESS); + check(vkQueueSubmit(alice->queues.graphics, 1, &(VkSubmitInfo){ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .waitSemaphoreCount = 1, - .pWaitSemaphores = (VkSemaphore[]){alice->jane.in_frame_transfer_complete}, + .pWaitSemaphores = (VkSemaphore[]){alice->jane.in_frame_compute_complete}, .pWaitDstStageMask = (VkPipelineStageFlags[]){ VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT }, @@ -1516,10 +1528,10 @@ Alice* Alice_new(){ alice->rendering_command_buf_0 = margaret_allocate_command_buffer(alice->device, alice->command_pool); 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); + alice->compute_command_buf = margaret_allocate_command_buffer(alice->device, alice->command_pool); // 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, 100); + alice->descriptor_pool = margaret_create_descriptor_set_pool(alice->device, 100, 700, 100, 100); /* Here we search physical device memory types for the one with host-visible flag and the other with device-local flag */ VkPhysicalDeviceMemoryProperties mem_properties; diff --git a/src/l2/margaret/vulkan_utils.h b/src/l2/margaret/vulkan_utils.h index 06895d6..7f78428 100644 --- a/src/l2/margaret/vulkan_utils.h +++ b/src/l2/margaret/vulkan_utils.h @@ -876,22 +876,6 @@ void MargaretSwapchainBundle_drop_with_device(VkDevice device, MargaretSwapchain // Now swapchain bundle is 100% dropped } -VkShaderModule margaret_VkShaderModule_new(VkDevice device, VecU8 code) { - if (code.len < 4) - abortf("Kill yourself, please\n"); - VkShaderModule shad_module; - check(vkCreateShaderModule(device, &(VkShaderModuleCreateInfo){ - .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, - .codeSize = code.len, - // Now this is funny, we can't put arbitrary byte-string here, it should be 4-byte aligned - // Thanks goodness all the strings in VecU8 are allocated with calloc, which gives high alignment to - // virtually everything - .pCode = (const uint32_t*)code.buf - }, NULL, &shad_module) == VK_SUCCESS); - VecU8_drop(code); - return shad_module; -} - VkCommandPool margaret_create_resettable_command_pool(VkDevice device, uint32_t wanted_queue_family) { VkCommandPoolCreateInfo crinfo = { .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, @@ -1064,6 +1048,31 @@ void margaret_end_command_buffer(VkCommandBuffer command_buffer){ check(vkEndCommandBuffer(command_buffer) == VK_SUCCESS); } +VkShaderModule margaret_VkShaderModule_new(VkDevice device, VecU8 code) { + if (code.len < 4) + abortf("Kill yourself, please\n"); + VkShaderModule shad_module; + check(vkCreateShaderModule(device, &(VkShaderModuleCreateInfo){ + .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .codeSize = code.len, + // Now this is funny, we can't put arbitrary byte-string here, it should be 4-byte aligned + // Thanks goodness all the strings in VecU8 are allocated with calloc, which gives high alignment to + // virtually everything + .pCode = (const uint32_t*)code.buf + }, NULL, &shad_module) == VK_SUCCESS); + VecU8_drop(code); + return shad_module; +} + +VkPipelineShaderStageCreateInfo margaret_VkPipelineShaderStageCreateInfo_init( + VkShaderStageFlags stage, VkShaderModule module + ) { + return (VkPipelineShaderStageCreateInfo){ + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .module = module, .stage = stage, .pName = "main", + }; +} + typedef struct { VkPipelineLayout pipeline_layout; VecU8 vertex_shader_code; @@ -1083,24 +1092,15 @@ VkPipeline margaret_create_triangle_pipeline_one_attachment( MargaretMostImportantPipelineOptions op ){ VkPipelineShaderStageCreateInfo shader_modules[3] = { - (VkPipelineShaderStageCreateInfo){ - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .module = margaret_VkShaderModule_new(device, op.vertex_shader_code), - .stage = VK_SHADER_STAGE_VERTEX_BIT, .pName = "main", - }, - (VkPipelineShaderStageCreateInfo){ - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .module = margaret_VkShaderModule_new(device, op.fragment_shader_code), - .stage = VK_SHADER_STAGE_FRAGMENT_BIT, .pName = "main", - }, + margaret_VkPipelineShaderStageCreateInfo_init(VK_SHADER_STAGE_VERTEX_BIT, + margaret_VkShaderModule_new(device, op.vertex_shader_code)), + margaret_VkPipelineShaderStageCreateInfo_init(VK_SHADER_STAGE_FRAGMENT_BIT, + margaret_VkShaderModule_new(device, op.fragment_shader_code)), }; U32 shader_modules_c = 2; if (op.geometry_shader_code.len > 0) { - shader_modules[shader_modules_c] = (VkPipelineShaderStageCreateInfo){ - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .module = margaret_VkShaderModule_new(device, op.geometry_shader_code), - .stage = VK_SHADER_STAGE_GEOMETRY_BIT, .pName = "main", - }; + shader_modules[shader_modules_c] = margaret_VkPipelineShaderStageCreateInfo_init( + VK_SHADER_STAGE_GEOMETRY_BIT, margaret_VkShaderModule_new(device, op.geometry_shader_code)), shader_modules_c++; } @@ -1192,9 +1192,21 @@ VkPipeline margaret_create_triangle_pipeline_one_attachment( return pipeline; } -#include "vulkan_memory.h" +VkPipeline margaret_create_compute_pipeline(VkDevice device, VkPipelineLayout layout, VecU8 code) { + VkPipeline pipeline; + VkShaderModule comp_module = margaret_VkShaderModule_new(device, code); + vkCreateComputePipelines(device, VK_NULL_HANDLE, 1, &(VkComputePipelineCreateInfo){ + .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, + .flags = 0, + .layout = layout, + .stage = margaret_VkPipelineShaderStageCreateInfo_init(VK_SHADER_STAGE_COMPUTE_BIT, + margaret_VkShaderModule_new(device, code)), + }, NULL, &pipeline); + vkDestroyShaderModule(device, comp_module, NULL); + return pipeline; +} -// todo: move image copying function here +#include "vulkan_memory.h" typedef struct { VkDevice device; diff --git a/src/l3/r4/r4.c b/src/l3/r4/r4.c index ce44e8e..0035f33 100644 --- a/src/l3/r4/r4.c +++ b/src/l3/r4/r4.c @@ -102,6 +102,10 @@ typedef struct{ Vecvec3 bullets_stuck_on_ROA; MargaretSubbuf sb; + + size_t ROA_count; + VkPipeline physics_compute_pipe; + } R4BetaState; /* We are surrounded by a giant cubic mesh of light sources */ diff --git a/src/l_adele/physics/r4_rigid.comp b/src/l_adele/physics/r4_rigid.comp new file mode 100644 index 0000000..8c3cd65 --- /dev/null +++ b/src/l_adele/physics/r4_rigid.comp @@ -0,0 +1,14 @@ +#version 450 + + +layout(push_constant, std430) uniform pc { + float dt; +}; + +struct ROA_Config { + float mass; + inertia_moment; + vec3 mass_center +}; + +struct \ No newline at end of file