diff --git a/.gitignore b/.gitignore index 8e5e5f8..ca37570 100644 --- a/.gitignore +++ b/.gitignore @@ -29,5 +29,3 @@ backup coverage coverage/* .venv -*.glb -imgui.ini diff --git a/Makefile b/Makefile index 7536b9a..73487f8 100644 --- a/Makefile +++ b/Makefile @@ -13,9 +13,6 @@ shaders: glslangValidator -V gradient.comp -o gradient.comp.spv glslangValidator -V sky.comp -o sky.comp.spv glslangValidator -V gradient_color.comp -o gradient_color.comp.spv - glslangValidator -V colored_triangle.frag -o colored_triangle.frag.spv - glslangValidator -V colored_triangle.vert -o colored_triangle.vert.spv - glslangValidator -V colored_triangle_mesh.vert -o colored_triangle_mesh.vert.spv %.cpp : %.rl ragel -I $(ROOT_DIR) -G1 -o $@ $< @@ -26,15 +23,9 @@ shaders: %.png: %.dot dot -Tpng $< -o $@ -%.glb: %.glb.gz - gunzip -k $< - build: meson compile -j 10 -C $(ROOT_DIR)/builddir -meshes: basicmesh.glb - @echo "Meshes made" - release_build: meson --wipe builddir -Db_ndebug=true --buildtype release meson compile -j 10 -C builddir @@ -59,10 +50,9 @@ debug_run: build clean: meson compile --clean -C builddir - rm -f basicmesh.glb debug_test: build gdb --nx -x .gdbinit --ex run --ex bt --ex q --args builddir/runtests -e "[pathing]" money: - scc --exclude-dir subprojects,vendor + scc --exclude-dir subprojects diff --git a/basicmesh.glb.gz b/basicmesh.glb.gz deleted file mode 100644 index 9de0ed5..0000000 Binary files a/basicmesh.glb.gz and /dev/null differ diff --git a/colored_triangle.frag b/colored_triangle.frag deleted file mode 100644 index 2f05038..0000000 --- a/colored_triangle.frag +++ /dev/null @@ -1,13 +0,0 @@ -#version 450 - -//shader input -layout (location = 0) in vec3 inColor; - -//output write -layout (location = 0) out vec4 outFragColor; - -void main() -{ - //return red - outFragColor = vec4(inColor,1.0f); -} diff --git a/colored_triangle.frag.spv b/colored_triangle.frag.spv deleted file mode 100644 index ad41591..0000000 Binary files a/colored_triangle.frag.spv and /dev/null differ diff --git a/colored_triangle.vert b/colored_triangle.vert deleted file mode 100644 index 8b0db4a..0000000 --- a/colored_triangle.vert +++ /dev/null @@ -1,24 +0,0 @@ -#version 450 - -layout (location = 0) out vec3 outColor; - -void main() -{ - //const array of positions for the triangle - const vec3 positions[3] = vec3[3]( - vec3(1.f,1.f, 0.0f), - vec3(-1.f,1.f, 0.0f), - vec3(0.f,-1.f, 0.0f) - ); - - //const array of colors for the triangle - const vec3 colors[3] = vec3[3]( - vec3(1.0f, 0.0f, 0.0f), //red - vec3(0.0f, 1.0f, 0.0f), //green - vec3(00.f, 0.0f, 1.0f) //blue - ); - - //output the position of each vertex - gl_Position = vec4(positions[gl_VertexIndex], 1.0f); - outColor = colors[gl_VertexIndex]; -} diff --git a/colored_triangle.vert.spv b/colored_triangle.vert.spv deleted file mode 100644 index ffd8bf3..0000000 Binary files a/colored_triangle.vert.spv and /dev/null differ diff --git a/colored_triangle_mesh.vert b/colored_triangle_mesh.vert deleted file mode 100644 index fe9bec5..0000000 --- a/colored_triangle_mesh.vert +++ /dev/null @@ -1,37 +0,0 @@ -#version 450 -#extension GL_EXT_buffer_reference : require - -layout (location = 0) out vec3 outColor; -layout (location = 1) out vec2 outUV; - -struct Vertex { - - vec3 position; - float uv_x; - vec3 normal; - float uv_y; - vec4 color; -}; - -layout(buffer_reference, std430) readonly buffer VertexBuffer{ - Vertex vertices[]; -}; - -//push constants block -layout( push_constant ) uniform constants -{ - mat4 render_matrix; - VertexBuffer vertexBuffer; -} PushConstants; - -void main() -{ - //load vertex data from device adress - Vertex v = PushConstants.vertexBuffer.vertices[gl_VertexIndex]; - - //output data - gl_Position = PushConstants.render_matrix *vec4(v.position, 1.0f); - outColor = v.color.xyz; - outUV.x = v.uv_x; - outUV.y = v.uv_y; -} diff --git a/colored_triangle_mesh.vert.spv b/colored_triangle_mesh.vert.spv deleted file mode 100644 index 7461a40..0000000 Binary files a/colored_triangle_mesh.vert.spv and /dev/null differ diff --git a/json_mods.hpp b/json_mods.hpp new file mode 100644 index 0000000..85481af --- /dev/null +++ b/json_mods.hpp @@ -0,0 +1,34 @@ +#pragma once +#include +#include +#include + +#define ENROLL_COMPONENT(COMPONENT, ...) \ + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(COMPONENT, __VA_ARGS__); \ + template <> struct NameOf { \ + static constexpr const char *name = #COMPONENT; \ + }; + +// partial specialization (full specialization works too) +namespace nlohmann { + template + struct adl_serializer> { + static void to_json(json& j, const std::optional& opt) { + if (opt == std::nullopt) { + j = nullptr; + } else { + j = *opt; // this will call adl_serializer::to_json which will + // find the free function to_json in T's namespace! + } + } + + static void from_json(const json& j, std::optional& opt) { + if (j.is_null() || j == false) { + opt = std::nullopt; + } else { + opt = std::make_optional(j.template get()); + // same as above, but with adl_serializer::from_json + } + } + }; +} diff --git a/meson.build b/meson.build index b11ce11..9d89fea 100644 --- a/meson.build +++ b/meson.build @@ -69,6 +69,7 @@ elif build_machine.system() == 'darwin' endif vma = subproject('vulkan-memory-allocator').get_variable('vma_allocator_dep') +# vulkan_headers = subproject('vulkan-headers').get_variable('vulkan_headers_dep') imgui = subproject('imgui', default_options: { @@ -79,13 +80,6 @@ imgui = subproject('imgui', sdl2 = subproject('sdl2').get_variable('sdl2_dep') -fastgltf_opts = cmake.subproject_options() -fastgltf_opts.add_cmake_defines({ - 'FASTGLTF_DOWNLOAD_SIMDJSON': false, -}) - -fastgltf_proj = cmake.subproject('fastgltf', options: fastgltf_opts) -fastgltf = fastgltf_proj.get_variable('fastgltf_dep') glm_opts = cmake.subproject_options() glm_opts.add_cmake_defines({ @@ -94,7 +88,6 @@ glm_opts.add_cmake_defines({ glm_proj = cmake.subproject('glm', options: glm_opts) glm = glm_proj.get_variable('glm_dep') -simdjson = dependency('simdjson') vk_opts = cmake.subproject_options() @@ -111,6 +104,7 @@ else }) endif +json = subproject('nlohmann_json').get_variable('nlohmann_json_dep') vkbootstrap_proj = cmake.subproject('vk-bootstrap', options: vk_opts) vkbootstrap = vkbootstrap_proj.get_variable('vk_bootstrap_dep') @@ -118,10 +112,9 @@ dependencies += [ vma, vkbootstrap, glm, - # imgui, + imgui, sdl2, - fastgltf, - simdjson, + json, ] sources = [ @@ -130,21 +123,15 @@ sources = [ 'vk_images.cpp', 'vk_descriptors.cpp', 'vk_pipelines.cpp', - 'vk_loader.cpp', - 'vk_gui.cpp', 'main.cpp', ] -# have to force this here for...cmake reasons -include_dirs = include_directories('subprojects/fastgltf/include') - tests = [ ] executable('hellovulk', sources, cpp_args: cpp_args, link_args: link_args, - include_directories: include_dirs, win_subsystem: 'windows', override_options: exe_defaults, dependencies: dependencies) diff --git a/vendor/stb_image.h b/stb_image.h similarity index 100% rename from vendor/stb_image.h rename to stb_image.h diff --git a/trash_test.hpp b/trash_test.hpp new file mode 100644 index 0000000..e750836 --- /dev/null +++ b/trash_test.hpp @@ -0,0 +1,8 @@ +#include "vk_types.h" +#include "json_mods.hpp" + +template struct NameOf; + +ENROLL_COMPONENT(VkSemaphoreCreateInfo, sType); +ENROLL_COMPONENT(VkFenceCreateInfo, sType); +ENROLL_COMPONENT(VkImageViewCreateInfo, sType, viewType, subresourceRange.baseMipLevel, subresourceRange.levelCount, subresourceRange.baseArrayLayer, subresourceRange.layerCount); diff --git a/vk_descriptors.cpp b/vk_descriptors.cpp index d8d4f62..bfad725 100644 --- a/vk_descriptors.cpp +++ b/vk_descriptors.cpp @@ -2,11 +2,11 @@ void DescriptorLayoutBuilder::add_binding(uint32_t binding, VkDescriptorType type) { - VkDescriptorSetLayoutBinding newbind{ - .binding = binding, - .descriptorType = type, - .descriptorCount = 1, - }; + + VkDescriptorSetLayoutBinding newbind {}; + newbind.binding = binding; + newbind.descriptorCount = 1; + newbind.descriptorType = type; bindings.push_back(newbind); } @@ -25,16 +25,18 @@ VkDescriptorSetLayout DescriptorLayoutBuilder::build(VkDevice device, b.stageFlags |= shaderStages; } - VkDescriptorSetLayoutCreateInfo info{ - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .pNext = pNext, - .flags = flags, - .bindingCount = (uint32_t)bindings.size(), - .pBindings = bindings.data(), + VkDescriptorSetLayoutCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; + info.pNext = pNext; + + info.pBindings = bindings.data(); + info.bindingCount = (uint32_t)bindings.size(); + info.flags = flags; VkDescriptorSetLayout set; - VK_CHECK(vkCreateDescriptorSetLayout(device, &info, nullptr, &set)); + VK_CHECK(vkCreateDescriptorSetLayout(device, + &info, nullptr, &set)); return set; } @@ -44,19 +46,19 @@ void DescriptorAllocator::init_pool(VkDevice device, uint32_t maxSets, { std::vector poolSizes; for(PoolSizeRatio ratio : poolRatios) { - poolSizes.push_back({ + poolSizes.push_back(VkDescriptorPoolSize{ .type = ratio.type, .descriptorCount = uint32_t(ratio.ratio * maxSets) }); } - VkDescriptorPoolCreateInfo pool_info{ - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .flags = 0, - .maxSets = maxSets, - .poolSizeCount = (uint32_t)poolSizes.size(), - .pPoolSizes = poolSizes.data(), + VkDescriptorPoolCreateInfo pool_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; + pool_info.flags = 0; + pool_info.maxSets = maxSets; + pool_info.poolSizeCount = (uint32_t)poolSizes.size(); + pool_info.pPoolSizes = poolSizes.data(); vkCreateDescriptorPool(device, &pool_info, nullptr, &pool); } @@ -73,13 +75,15 @@ void DescriptorAllocator::destroy_pool(VkDevice device) VkDescriptorSet DescriptorAllocator::allocate(VkDevice device, VkDescriptorSetLayout layout) { - VkDescriptorSetAllocateInfo allocInfo{ - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .descriptorPool = pool, - .descriptorSetCount = 1, - .pSetLayouts = &layout, + VkDescriptorSetAllocateInfo allocInfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO }; + allocInfo.pNext = nullptr; + allocInfo.descriptorPool = pool; + allocInfo.descriptorSetCount = 1; + allocInfo.pSetLayouts = &layout; + VkDescriptorSet ds; VK_CHECK(vkAllocateDescriptorSets(device, &allocInfo, &ds)); diff --git a/vk_engine.cpp b/vk_engine.cpp index 8924d40..7fcec8f 100644 --- a/vk_engine.cpp +++ b/vk_engine.cpp @@ -3,13 +3,18 @@ #include "vk_pipelines.h" #include +#include +#include + #include #include #include "VkBootstrap.h" #include #include -#include +#include "imgui.h" +#include "imgui_impl_sdl2.h" +#include "imgui_impl_vulkan.h" #define VMA_IMPLEMENTATION #include "vk_mem_alloc.h" @@ -27,7 +32,18 @@ void VulkanEngine::init() assert(loadedEngine == nullptr); loadedEngine = this; - _window = _gui.init_window(_windowExtent); + // We initialize SDL and create a window with it. + SDL_Init(SDL_INIT_VIDEO); + + SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN); + + _window = SDL_CreateWindow( + "Vulkan Engine", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + int(_windowExtent.width), + int(_windowExtent.height), + window_flags); init_vulkan(); init_swapchain(); @@ -35,7 +51,7 @@ void VulkanEngine::init() init_sync_structures(); init_descriptors(); init_pipelines(); - init_default_data(); + init_imgui(); //everything went fine _isInitialized = true; @@ -57,11 +73,6 @@ void VulkanEngine::cleanup() _frames[i]._deletionQueue.flush(); } - for (auto& mesh : testMeshes) { - destroy_buffer(mesh->meshBuffers.indexBuffer); - destroy_buffer(mesh->meshBuffers.vertexBuffer); - } - _mainDeletionQueue.flush(); destroy_swapchain(); @@ -70,14 +81,14 @@ void VulkanEngine::cleanup() vkDestroyDevice(_device, nullptr); vkb::destroy_debug_utils_messenger(_instance, _debug_messenger); vkDestroyInstance(_instance, nullptr); - _gui.destroy(_window); + SDL_DestroyWindow(_window); } loadedEngine = nullptr; } -Transaction VulkanEngine::begin_transaction() { - // ZED: begin command transaction +void VulkanEngine::draw() +{ // wait until the gpu has finished rendering the last frame. Timeout of 1 second VK_CHECK(vkWaitForFences(_device, 1, &get_current_frame()._renderFence, true, 1000000000)); get_current_frame()._deletionQueue.flush(); @@ -92,24 +103,44 @@ Transaction VulkanEngine::begin_transaction() { VkCommandBufferBeginInfo cmdBeginInfo = vkinit::command_buffer_begin_info(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + _drawExtent.width = _drawImage.imageExtent.width; + _drawExtent.height = _drawImage.imageExtent.height; + VK_CHECK(vkBeginCommandBuffer(cmd, &cmdBeginInfo)); - return {cmd, swapchainImageIndex}; -} + // transition our main draw image into general layout so we can write into it + // we will overwrite it all so we dont care about what was the older layout -void VulkanEngine::commit_transaction(Transaction& t) { - VK_CHECK(vkEndCommandBuffer(t.cmd)); + vkutil::transition_image(cmd, _drawImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL); + + draw_background(cmd); + + vkutil::transition_image(cmd, _drawImage.image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + + vkutil::transition_image(cmd, _swapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + vkutil::copy_image_to_image(cmd, _drawImage.image, + _swapchainImages[swapchainImageIndex], + _drawExtent, _swapchainExtent); + + vkutil::transition_image(cmd, _swapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + + draw_imgui(cmd, _swapchainImageViews[swapchainImageIndex]); + + vkutil::transition_image(cmd, _swapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); + + VK_CHECK(vkEndCommandBuffer(cmd)); - // ZED: submit command to queue //prepare the submission to the queue. //we want to wait on the _presentSemaphore, as that semaphore is signaled when the swapchain is ready //we will signal the _renderSemaphore, to signal that rendering has finished - VkCommandBufferSubmitInfo cmdinfo = vkinit::command_buffer_submit_info(t.cmd); + + VkCommandBufferSubmitInfo cmdinfo = vkinit::command_buffer_submit_info(cmd); VkSemaphoreSubmitInfo waitInfo = vkinit::semaphore_submit_info(VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR,get_current_frame()._swapchainSemaphore); VkSemaphoreSubmitInfo signalInfo = vkinit::semaphore_submit_info(VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT, get_current_frame()._renderSemaphore); - VkSubmitInfo2 submit = vkinit::submit_info(&cmdinfo, &signalInfo, &waitInfo); + VkSubmitInfo2 submit = vkinit::submit_info(&cmdinfo,&signalInfo,&waitInfo); //submit command buffer to the queue and execute it. // _renderFence will now block until the graphic commands finish execution @@ -119,15 +150,16 @@ void VulkanEngine::commit_transaction(Transaction& t) { // this will put the image we just rendered to into the visible window. // we want to wait on the _renderSemaphore for that, // as its necessary that drawing commands have finished before the image is displayed to the user - VkPresentInfoKHR presentInfo{ - .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, - .pNext = nullptr, - .waitSemaphoreCount = 1, - .pWaitSemaphores = &get_current_frame()._renderSemaphore, - .swapchainCount = 1, - .pSwapchains = &_swapchain, - .pImageIndices = &t.swapchainImageIndex, - }; + VkPresentInfoKHR presentInfo{}; + presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + presentInfo.pNext = nullptr; + presentInfo.pSwapchains = &_swapchain; + presentInfo.swapchainCount = 1; + + presentInfo.pWaitSemaphores = &get_current_frame()._renderSemaphore; + presentInfo.waitSemaphoreCount = 1; + + presentInfo.pImageIndices = &swapchainImageIndex; VK_CHECK(vkQueuePresentKHR(_graphicsQueue, &presentInfo)); @@ -135,131 +167,70 @@ void VulkanEngine::commit_transaction(Transaction& t) { _frameNumber++; } -void VulkanEngine::draw() -{ - auto t = begin_transaction(); - - // ZED: draw the things - _drawExtent.width = _drawImage.imageExtent.width; - _drawExtent.height = _drawImage.imageExtent.height; - - // transition our main draw image into general layout so we can write into it - // we will overwrite it all so we dont care about what was the older layout - vkutil::transition_image(t.cmd, _drawImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL); - - draw_background(t.cmd); - - vkutil::transition_image(t.cmd, _drawImage.image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - - draw_geometry(t.cmd); - - // ZED: ? - vkutil::transition_image(t.cmd, _drawImage.image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - - // ZED: ? - vkutil::transition_image(t.cmd, _swapchainImages[t.swapchainImageIndex], - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - - vkutil::copy_image_to_image(t.cmd, _drawImage.image, - _swapchainImages[t.swapchainImageIndex], - _drawExtent, _swapchainExtent); - - // ZED: ? - vkutil::transition_image(t.cmd, _swapchainImages[t.swapchainImageIndex], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - - // ZED: finalize image and commit command buffer - vkutil::transition_image(t.cmd, _swapchainImages[t.swapchainImageIndex], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); - - commit_transaction(t); -} - -void VulkanEngine::draw_geometry(VkCommandBuffer cmd) -{ - VkRenderingAttachmentInfo colorAttachment = vkinit::attachment_info(_drawImage.imageView, nullptr, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - - VkRenderingInfo renderInfo = vkinit::rendering_info(_drawExtent, &colorAttachment, nullptr); - vkCmdBeginRendering(cmd, &renderInfo); - - vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, _trianglePipeline); - - VkViewport viewport{ - .x = 0, - .y = 0, - .width = (float)_drawExtent.width, - .height = (float)_drawExtent.height, - .minDepth = 0.0f, - .maxDepth = 1.0f, - }; - - vkCmdSetViewport(cmd, 0, 1, &viewport); - - VkRect2D scissor{ - .offset = { .x = 0, .y = 0, }, - .extent = _drawExtent - }; - - vkCmdSetScissor(cmd, 0, 1, &scissor); - - vkCmdDraw(cmd, 3, 1, 0, 0); - - // draw rectangle - vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, _meshPipeline); - - GPUDrawPushConstants push_constants{ - .worldMatrix = glm::mat4{ 1.0f }, - .vertexBuffer = rectangle.vertexBufferAddress, - }; - - vkCmdPushConstants(cmd, _meshPipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(GPUDrawPushConstants), -&push_constants); - vkCmdBindIndexBuffer(cmd, rectangle.indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32); - - vkCmdDrawIndexed(cmd, 6, 1, 0, 0, 0); - - - // draw monkey - size_t model_idx = 2; // 0 cube; 1 sphere; 2 monkey - - push_constants.vertexBuffer = testMeshes[model_idx]->meshBuffers.vertexBufferAddress; - - vkCmdPushConstants(cmd, - _meshPipelineLayout, - VK_SHADER_STAGE_VERTEX_BIT, - 0, - sizeof(GPUDrawPushConstants), - &push_constants); - - vkCmdBindIndexBuffer(cmd, - testMeshes[model_idx]->meshBuffers.indexBuffer.buffer, - 0, - VK_INDEX_TYPE_UINT32); - - vkCmdDrawIndexed(cmd, - testMeshes[model_idx]->surfaces[0].count, - 1, - testMeshes[model_idx]->surfaces[0].startIndex, - 0, 0); - - vkCmdEndRendering(cmd); -} - void VulkanEngine::run() { - //main loop - while(!_gui.should_quit) - { - _gui.poll_event(); + SDL_Event e; + bool bQuit = false; + bool stop_rendering = false; - if(_gui.stop_rendering) { + //main loop + while(!bQuit) + { + //Handle events on queue + while(SDL_PollEvent(&e) != 0) + { + //close the window when user alt-f4s or clicks the X button + if(e.type == SDL_QUIT) { + bQuit = true; + } + + if(e.type == SDL_WINDOWEVENT) { + if(e.window.event == SDL_WINDOWEVENT_MINIMIZED) { + stop_rendering = true; + } + + if(e.window.event == SDL_WINDOWEVENT_RESTORED) { + stop_rendering = false; + } + } + + ImGui_ImplSDL2_ProcessEvent(&e); + } + + if(stop_rendering) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); continue; } + render_imgui(); draw(); } } +void VulkanEngine::render_imgui() { + ImGui_ImplVulkan_NewFrame(); + ImGui_ImplSDL2_NewFrame(); + + ImGui::NewFrame(); + + if (ImGui::Begin("background")) { + + ComputeEffect& selected = backgroundEffects[currentBackgroundEffect]; + + ImGui::Text("Selected effect: %s", selected.name); + + ImGui::SliderInt("Effect Index", ¤tBackgroundEffect,0, backgroundEffects.size() - 1); + + ImGui::InputFloat4("data1",(float*)& selected.data.data1); + ImGui::InputFloat4("data2",(float*)& selected.data.data2); + ImGui::InputFloat4("data3",(float*)& selected.data.data3); + ImGui::InputFloat4("data4",(float*)& selected.data.data4); + } + ImGui::End(); + + ImGui::Render(); +} + void VulkanEngine::init_vulkan() { vkb::InstanceBuilder builder; @@ -280,18 +251,17 @@ void VulkanEngine::init_vulkan() { SDL_Vulkan_CreateSurface(_window, _instance, &_surface); //vulkan 1.3 features - VkPhysicalDeviceVulkan13Features features13{ - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, - .synchronization2 = true, - .dynamicRendering = true, - }; + VkPhysicalDeviceVulkan13Features features13{}; + + features13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; + features13.dynamicRendering = true; + features13.synchronization2 = true; //vulkan 1.2 features - VkPhysicalDeviceVulkan12Features features12{ - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, - .descriptorIndexing = true, - .bufferDeviceAddress = true, - }; + VkPhysicalDeviceVulkan12Features features12{}; + features12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; + features12.bufferDeviceAddress = true; + features12.descriptorIndexing = true; // use vkbootstrap to select a gpu // We want a gpu that can write to the SDL surface @@ -314,13 +284,11 @@ void VulkanEngine::init_vulkan() { _graphicsQueueFamily = vkbDevice.get_queue_index(vkb::QueueType::graphics).value(); // initialize the memory allocator - VmaAllocatorCreateInfo allocatorInfo{ - .flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT, - .physicalDevice = _chosenGPU, - .device = _device, - .instance = _instance, - }; - + VmaAllocatorCreateInfo allocatorInfo{}; + allocatorInfo.physicalDevice = _chosenGPU; + allocatorInfo.device = _device; + allocatorInfo.instance = _instance; + allocatorInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT; vmaCreateAllocator(&allocatorInfo, &_allocator); _mainDeletionQueue.push_function([&]() { @@ -371,18 +339,17 @@ void VulkanEngine::init_swapchain() { _drawImage.imageFormat = VK_FORMAT_R16G16B16A16_SFLOAT; _drawImage.imageExtent = drawImageExtent; - VkImageUsageFlags drawImageUsages = - VK_IMAGE_USAGE_TRANSFER_SRC_BIT - | VK_IMAGE_USAGE_TRANSFER_DST_BIT - | VK_IMAGE_USAGE_STORAGE_BIT - | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + VkImageUsageFlags drawImageUsages{}; + drawImageUsages |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + drawImageUsages |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; + drawImageUsages |= VK_IMAGE_USAGE_STORAGE_BIT; + drawImageUsages |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; VkImageCreateInfo rimg_info = vkinit::image_create_info(_drawImage.imageFormat, drawImageUsages, drawImageExtent); - VmaAllocationCreateInfo rimg_allocinfo{ - .usage = VMA_MEMORY_USAGE_GPU_ONLY, - .requiredFlags = VkMemoryPropertyFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT), - }; + VmaAllocationCreateInfo rimg_allocinfo{}; + rimg_allocinfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; + rimg_allocinfo.requiredFlags = VkMemoryPropertyFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); //allocate and create the image vmaCreateImage(_allocator, &rimg_info, &rimg_allocinfo, &_drawImage.image, &_drawImage.allocation, nullptr); @@ -463,7 +430,7 @@ void VulkanEngine::init_descriptors() { { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1 } }; - _globalDescriptorAllocator.init_pool(_device, 10, sizes); + globalDescriptorAllocator.init_pool(_device, 10, sizes); // make the descriptor set layout for our compute draw { @@ -474,27 +441,27 @@ void VulkanEngine::init_descriptors() { // other code //allocate a descriptor set for our draw image - _drawImageDescriptors = _globalDescriptorAllocator.allocate(_device,_drawImageDescriptorLayout); + _drawImageDescriptors = globalDescriptorAllocator.allocate(_device,_drawImageDescriptorLayout); - VkDescriptorImageInfo imgInfo{ - .imageView = _drawImage.imageView, - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, - }; + VkDescriptorImageInfo imgInfo{}; + imgInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + imgInfo.imageView = _drawImage.imageView; - VkWriteDescriptorSet drawImageWrite{ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = _drawImageDescriptors, - .dstBinding = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - .pImageInfo = &imgInfo, - }; + VkWriteDescriptorSet drawImageWrite = {}; + drawImageWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + drawImageWrite.pNext = nullptr; + + drawImageWrite.dstBinding = 0; + drawImageWrite.dstSet = _drawImageDescriptors; + drawImageWrite.descriptorCount = 1; + drawImageWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + drawImageWrite.pImageInfo = &imgInfo; vkUpdateDescriptorSets(_device, 1, &drawImageWrite, 0, nullptr), //make sure both the descriptor allocator and the new layout get cleaned up properly _mainDeletionQueue.push_function([&]() { - _globalDescriptorAllocator.destroy_pool(_device); + globalDescriptorAllocator.destroy_pool(_device); vkDestroyDescriptorSetLayout(_device, _drawImageDescriptorLayout, nullptr); }); @@ -503,83 +470,77 @@ void VulkanEngine::init_descriptors() { void VulkanEngine::init_pipelines() { init_background_pipelines(); - init_triangle_pipelines(); - init_mesh_pipeline(); - init_shaders(); } -void VulkanEngine::load_shader(const char *file_name, const char *entry_point, ComputeEffect effect) { - VkShaderModule shader; - bool good = vkutil::load_shader_module(file_name, _device, &shader); - assert(good && "failed to load shader"); - - VkPipelineShaderStageCreateInfo stageinfo{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_COMPUTE_BIT, - .module = shader, - .pName = entry_point, - }; - - VkComputePipelineCreateInfo computePipelineCreateInfo{ - .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, - .stage = stageinfo, - .layout = _gradientPipelineLayout, - }; - - effect.layout = _gradientPipelineLayout; - - VK_CHECK(vkCreateComputePipelines(_device, VK_NULL_HANDLE, 1, &computePipelineCreateInfo, nullptr, &effect.pipeline)); - - backgroundEffects.push_back(effect); - - vkDestroyShaderModule(_device, shader, nullptr); - - _mainDeletionQueue.push_function([=,this]() { - vkDestroyPipeline(_device, effect.pipeline, nullptr); - }); -} - - void VulkanEngine::init_background_pipelines() { - VkPushConstantRange pushConstant{ - .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, - .offset = 0, - .size = sizeof(ComputePushConstants), - }; + VkPipelineLayoutCreateInfo computeLayout{}; + computeLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + computeLayout.pNext = nullptr; + computeLayout.pSetLayouts = &_drawImageDescriptorLayout; + computeLayout.setLayoutCount = 1; - VkPipelineLayoutCreateInfo computeLayout{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .setLayoutCount = 1, - .pSetLayouts = &_drawImageDescriptorLayout, - .pushConstantRangeCount = 1, - .pPushConstantRanges = &pushConstant, - }; + VkPushConstantRange pushConstant{}; + pushConstant.offset = 0; + pushConstant.size = sizeof(ComputePushConstants) ; + pushConstant.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + + computeLayout.pPushConstantRanges = &pushConstant; + computeLayout.pushConstantRangeCount = 1; VK_CHECK(vkCreatePipelineLayout(_device, &computeLayout, nullptr, &_gradientPipelineLayout)); - // final cleanup + VkShaderModule gradientShader; + bool good = vkutil::load_shader_module("gradient_color.comp.spv", _device, &gradientShader); + assert(good && "failed to load gradient_color.comp.spv"); + + VkShaderModule skyShader; + good = vkutil::load_shader_module("sky.comp.spv", _device, &skyShader); + + VkPipelineShaderStageCreateInfo stageinfo{}; + stageinfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stageinfo.pNext = nullptr; + stageinfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; + stageinfo.module = gradientShader; + stageinfo.pName = "main"; + + VkComputePipelineCreateInfo computePipelineCreateInfo{}; + computePipelineCreateInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + computePipelineCreateInfo.pNext = nullptr; + computePipelineCreateInfo.layout = _gradientPipelineLayout; + computePipelineCreateInfo.stage = stageinfo; + + ComputeEffect gradient; + gradient.layout = _gradientPipelineLayout; + gradient.name = "gradient"; + gradient.data = {}; + gradient.data.data1 = glm::vec4(1, 0, 0, 1); + gradient.data.data2 = glm::vec4(0, 0, 1, 1); + + VK_CHECK(vkCreateComputePipelines(_device, VK_NULL_HANDLE, 1, &computePipelineCreateInfo, nullptr, &gradient.pipeline)); + + // change the shader module only to create the sky + computePipelineCreateInfo.stage.module = skyShader; + ComputeEffect sky; + sky.layout = _gradientPipelineLayout; + sky.name = "sky"; + sky.data = {}; + // default sky + sky.data.data1 = glm::vec4(0.1, 0.2, 0.4, 0.97); + + VK_CHECK(vkCreateComputePipelines(_device, VK_NULL_HANDLE, 1, &computePipelineCreateInfo, nullptr, &sky.pipeline)); + + + backgroundEffects.push_back(gradient); + backgroundEffects.push_back(sky); + + vkDestroyShaderModule(_device, gradientShader, nullptr); + vkDestroyShaderModule(_device, skyShader, nullptr); + _mainDeletionQueue.push_function([=,this]() { vkDestroyPipelineLayout(_device, _gradientPipelineLayout, nullptr); - }); -} - - -void VulkanEngine::init_shaders() { - /// gradient shader - load_shader("gradient_color.comp.spv", "main", { - .name="gradient", - .data={ - .data1 = glm::vec4(1, 0, 0, 1), - .data2 = glm::vec4(0, 0, 1, 1), - } - }); - - load_shader("sky.comp.spv", "main", { - .name="sky", - .data = { - .data1 = glm::vec4(0.1, 0.2, 0.4, 0.97) - } + vkDestroyPipeline(_device, sky.pipeline, nullptr); + vkDestroyPipeline(_device, sky.pipeline, nullptr); }); } @@ -603,222 +564,76 @@ void VulkanEngine::immediate_submit(std::function&& f VkSubmitInfo2 submit = vkinit::submit_info(&cmdinfo, nullptr, nullptr); VK_CHECK(vkQueueSubmit2(_graphicsQueue, 1, &submit, _immFence)); - VK_CHECK(vkWaitForFences(_device, 1, &_immFence, true,9999999999)); + VK_CHECK(vkWaitForFences(_device, 1, &_immFence, true,9999999999)); + } -void VulkanEngine::init_mesh_pipeline() + +void VulkanEngine::init_imgui() { - VkShaderModule triangleFragShader; - if (!vkutil::load_shader_module("colored_triangle.frag.spv", _device, &triangleFragShader)) { - std::print("Error when building the triangle fragment shader module"); - } - else { - std::print("Triangle fragment shader succesfully loaded"); - } +// 1: create descriptor pool for IMGUI + // the size of the pool is very oversize, but it's copied from imgui demo + // itself. + VkDescriptorPoolSize pool_sizes[] = { { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 }, + { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 } }; + + VkDescriptorPoolCreateInfo pool_info{}; + pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; + pool_info.maxSets = 1000; + pool_info.poolSizeCount = (uint32_t)std::size(pool_sizes); + pool_info.pPoolSizes = pool_sizes; - VkShaderModule triangleVertexShader; - if (!vkutil::load_shader_module("colored_triangle_mesh.vert.spv", _device, &triangleVertexShader)) { - std::print("Error when building the triangle vertex shader module"); - } - else { - std::print("Triangle vertex shader succesfully loaded"); - } + VkDescriptorPool imguiPool; + VK_CHECK(vkCreateDescriptorPool(_device, &pool_info, nullptr, &imguiPool)); - VkPushConstantRange bufferRange{ - .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, - .offset = 0, - .size = sizeof(GPUDrawPushConstants), - }; + // 2: initialize the imgui library + ImGui::CreateContext(); - VkPipelineLayoutCreateInfo pipeline_layout_info = vkinit::pipeline_layout_create_info(); - pipeline_layout_info.pPushConstantRanges = &bufferRange; - pipeline_layout_info.pushConstantRangeCount = 1; + ImGui_ImplSDL2_InitForVulkan(_window); + ImGui_ImplVulkan_InitInfo init_info{}; + init_info.Instance = _instance; + init_info.PhysicalDevice = _chosenGPU; + init_info.Device = _device; + init_info.Queue = _graphicsQueue; + init_info.DescriptorPool = imguiPool; + init_info.MinImageCount = 3; + init_info.ImageCount = 3; + init_info.UseDynamicRendering = true; - VK_CHECK(vkCreatePipelineLayout(_device, &pipeline_layout_info, nullptr, &_meshPipelineLayout)); + init_info.PipelineRenderingCreateInfo = {.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO}; + init_info.PipelineRenderingCreateInfo.colorAttachmentCount = 1; + init_info.PipelineRenderingCreateInfo.pColorAttachmentFormats = &_swapchainImageFormat; + init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT; + ImGui_ImplVulkan_Init(&init_info); + ImGui_ImplVulkan_CreateFontsTexture(); - PipelineBuilder pipelineBuilder; - - pipelineBuilder._pipelineLayout = _meshPipelineLayout; - pipelineBuilder.set_shaders(triangleVertexShader, triangleFragShader); - pipelineBuilder.set_input_topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); - pipelineBuilder.set_polygon_mode(VK_POLYGON_MODE_FILL); - pipelineBuilder.set_cull_mode(VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE); - pipelineBuilder.set_multisampling_none(); - pipelineBuilder.disable_blending(); - pipelineBuilder.disable_depthtest(); - pipelineBuilder.set_color_attachment_format(_drawImage.imageFormat); - pipelineBuilder.set_depth_format(VK_FORMAT_UNDEFINED); - - _meshPipeline = pipelineBuilder.build_pipeline(_device); - vkDestroyShaderModule(_device, triangleFragShader, nullptr); - vkDestroyShaderModule(_device, triangleVertexShader, nullptr); - - _mainDeletionQueue.push_function([&]() { - vkDestroyPipelineLayout(_device, _meshPipelineLayout, nullptr); - vkDestroyPipeline(_device, _meshPipeline, nullptr); + _mainDeletionQueue.push_function([=,this]() { + ImGui_ImplVulkan_Shutdown(); + vkDestroyDescriptorPool(_device, imguiPool, nullptr); }); } -void VulkanEngine::init_triangle_pipelines() +void VulkanEngine::draw_imgui(VkCommandBuffer cmd, VkImageView targetImageView) { - VkShaderModule triangleFragShader; + VkRenderingAttachmentInfo colorAttachment = vkinit::attachment_info(targetImageView, nullptr, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - if(!vkutil::load_shader_module("colored_triangle.frag.spv",_device, &triangleFragShader)) { - std::print("Error when building the triangle fragment shaders module"); - } else { - std::print("Triangle fragment shader successfully loaded"); - } + VkRenderingInfo renderInfo = vkinit::rendering_info(_swapchainExtent, &colorAttachment, nullptr); - VkShaderModule triangleVertexShader; - if(!vkutil::load_shader_module("colored_triangle.vert.spv", _device, &triangleVertexShader)) { - std::println("Error when building the triangle, vertex shader module"); - } else { - std::println("Triangle vertex shader successfully loaded"); - } + vkCmdBeginRendering(cmd, &renderInfo); - VkPipelineLayoutCreateInfo pipeline_layout_info = vkinit::pipeline_layout_create_info(); + ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd); - VK_CHECK(vkCreatePipelineLayout(_device, &pipeline_layout_info, nullptr, &_trianglePipelineLayout)); - - PipelineBuilder pipelineBuilder; - - pipelineBuilder._pipelineLayout = _trianglePipelineLayout; - pipelineBuilder.set_shaders(triangleVertexShader, triangleFragShader); - pipelineBuilder.set_input_topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); - pipelineBuilder.set_polygon_mode(VK_POLYGON_MODE_FILL); - pipelineBuilder.set_cull_mode(VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE); - pipelineBuilder.set_multisampling_none(); - pipelineBuilder.disable_blending(); - pipelineBuilder.disable_depthtest(); - - // connect the image format we will drw into, from draw image - pipelineBuilder.set_color_attachment_format(_drawImage.imageFormat); - pipelineBuilder.set_depth_format(VK_FORMAT_UNDEFINED); - - _trianglePipeline = pipelineBuilder.build_pipeline(_device); - - vkDestroyShaderModule(_device, triangleFragShader, nullptr); - vkDestroyShaderModule(_device, triangleVertexShader, nullptr); - - _mainDeletionQueue.push_function([&]() { - vkDestroyPipelineLayout(_device, _trianglePipelineLayout, nullptr); - vkDestroyPipeline(_device, _trianglePipeline, nullptr); - }); -} - - -AllocatedBuffer VulkanEngine::create_buffer(size_t allocSize, VkBufferUsageFlags usage, VmaMemoryUsage memoryUsage) -{ - VkBufferCreateInfo bufferInfo{ - .sType=VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .size = allocSize, - .usage = usage, - }; - - VmaAllocationCreateInfo vmaallocInfo{ - .flags = VMA_ALLOCATION_CREATE_MAPPED_BIT, - .usage = memoryUsage, - }; - - AllocatedBuffer newBuffer; - - VK_CHECK(vmaCreateBuffer(_allocator, &bufferInfo, - &vmaallocInfo, &newBuffer.buffer, - &newBuffer.allocation, &newBuffer.info)); - - return newBuffer; -} - -void VulkanEngine::destroy_buffer(const AllocatedBuffer& buffer) -{ - vmaDestroyBuffer(_allocator, buffer.buffer, buffer.allocation); -} - -GPUMeshBuffers VulkanEngine::uploadMesh(std::span indices, std::span vertices) -{ - const size_t vertexBufferSize = vertices.size() * sizeof(Vertex); - const size_t indexBufferSize = indices.size() * sizeof(uint32_t); - - GPUMeshBuffers newSurface; - - newSurface.vertexBuffer = create_buffer( - vertexBufferSize, - VK_BUFFER_USAGE_STORAGE_BUFFER_BIT - | VK_BUFFER_USAGE_TRANSFER_DST_BIT - | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, - VMA_MEMORY_USAGE_GPU_ONLY); - - VkBufferDeviceAddressInfo deviceAddressInfo{ - .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, - .buffer = newSurface.vertexBuffer.buffer - }; - - newSurface.vertexBufferAddress = vkGetBufferDeviceAddress(_device, &deviceAddressInfo); - - newSurface.indexBuffer = create_buffer(indexBufferSize, - VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, - VMA_MEMORY_USAGE_GPU_ONLY); - - AllocatedBuffer staging = create_buffer(vertexBufferSize + indexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY); - - void* data = staging.allocation->GetMappedData(); - - memcpy(data, vertices.data(), vertexBufferSize); - memcpy((char *)data + vertexBufferSize, indices.data(), indexBufferSize); - - immediate_submit([&](VkCommandBuffer cmd) { - VkBufferCopy vertexCopy{ - .srcOffset = 0, - .dstOffset = 0, - .size = vertexBufferSize, - }; - - vkCmdCopyBuffer(cmd, staging.buffer, - newSurface.vertexBuffer.buffer, 1, - &vertexCopy); - - VkBufferCopy indexCopy{ - .srcOffset = vertexBufferSize, - .dstOffset = 0, - .size = indexBufferSize, - }; - - vkCmdCopyBuffer(cmd, staging.buffer, - newSurface.indexBuffer.buffer, 1, - &indexCopy); - }); - - destroy_buffer(staging); - - return newSurface; -} - -void VulkanEngine::init_default_data() { - std::array rect_vertices; - - rect_vertices[0].position = {0.5,-0.5,0}; - rect_vertices[1].position = {0.5,0.5,0}; - rect_vertices[2].position = {-0.5,-0.5,0}; - rect_vertices[3].position = {-0.5,0.5,0}; - - rect_vertices[0].color = { 0, 0, 0, 1 }; - rect_vertices[1].color = { 0.5,0.5,0.5,1 }; - rect_vertices[2].color = { 1,0, 0,1 }; - rect_vertices[3].color = { 0,1, 0,1 }; - - std::array rect_indices{0, 1, 2, 2, 1, 3}; - - rectangle = uploadMesh(rect_indices, rect_vertices); - - auto basicmesh = loadGltfMeshes(this, "./basicmesh.glb"); - assert(basicmesh != std::nullopt && "Failed to load basicmesh.glb"); - - testMeshes = *basicmesh; - - _mainDeletionQueue.push_function([&](){ - destroy_buffer(rectangle.indexBuffer); - destroy_buffer(rectangle.vertexBuffer); - }); + vkCmdEndRendering(cmd); } diff --git a/vk_engine.h b/vk_engine.h index 1875146..5a7903b 100644 --- a/vk_engine.h +++ b/vk_engine.h @@ -5,14 +5,23 @@ #include #include -#include "vk_gui.h" -#include "vk_loader.h" -struct Transaction { - VkCommandBuffer cmd; - uint32_t swapchainImageIndex = 0; +struct ComputePushConstants { + glm::vec4 data1; + glm::vec4 data2; + glm::vec4 data3; + glm::vec4 data4; }; +struct ComputeEffect { + const char *name; + VkPipeline pipeline; + VkPipelineLayout layout; + + ComputePushConstants data; +}; + + struct DeletionQueue { std::deque> deletors; @@ -39,6 +48,7 @@ struct FrameData { DeletionQueue _deletionQueue; }; +constexpr unsigned int FRAME_OVERLAP=2; class VulkanEngine { public: @@ -48,7 +58,7 @@ public: VkPipeline _gradientPipeline; VkPipelineLayout _gradientPipelineLayout; - DescriptorAllocator _globalDescriptorAllocator; + DescriptorAllocator globalDescriptorAllocator; VkDescriptorSet _drawImageDescriptors; VkDescriptorSetLayout _drawImageDescriptorLayout; @@ -67,7 +77,6 @@ public: std::vector _swapchainImageViews; VkExtent2D _swapchainExtent; - // VMA stuff VmaAllocator _allocator; @@ -95,16 +104,6 @@ public: // imgui shader stuff std::vector backgroundEffects; int currentBackgroundEffect{0}; - VkPipelineLayout _trianglePipelineLayout; - VkPipeline _trianglePipeline; - VkPipelineLayout _meshPipelineLayout; - VkPipeline _meshPipeline; - - GPUMeshBuffers rectangle; - std::vector> testMeshes; - - // ZED's REFACTOR - VkGUI _gui; static VulkanEngine& Get(); @@ -122,11 +121,6 @@ public: void immediate_submit(std::function&& function); - Transaction begin_transaction(); - void commit_transaction(Transaction& cmd); - - GPUMeshBuffers uploadMesh(std::span indices, std::span vertices); - private: void init_vulkan(); void init_swapchain(); @@ -135,19 +129,11 @@ private: void init_descriptors(); void init_pipelines(); void init_background_pipelines(); - void init_shaders(); - void init_triangle_pipelines(); - void init_mesh_pipeline(); - void init_default_data(); - - void load_shader(const char *file_name, const char *entry_point, ComputeEffect data); + void init_imgui(); void create_swapchain(uint32_t width, uint32_t height); - AllocatedBuffer create_buffer(size_t allocSize, VkBufferUsageFlags usage, VmaMemoryUsage memoryUsage); - void destroy_swapchain(); - void destroy_buffer(const AllocatedBuffer& buffer); void draw_background(VkCommandBuffer cmd); - void draw_geometry(VkCommandBuffer cmd); - + void draw_imgui(VkCommandBuffer cmd, VkImageView targetImageView); + void render_imgui(); }; diff --git a/vk_gui.cpp b/vk_gui.cpp deleted file mode 100644 index 08cd0bb..0000000 --- a/vk_gui.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "vk_gui.h" -#include "vk_initializers.h" -#include -#include -#include "vk_engine.h" - -struct SDL_Window* VkGUI::init_window(VkExtent2D windowExtent) -{ - SDL_Init(SDL_INIT_VIDEO); - - SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN); - - return SDL_CreateWindow( - "Vulkan Engine", - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - int(windowExtent.width), - int(windowExtent.height), - window_flags); -} - - -void VkGUI::destroy(struct SDL_Window* _window) -{ - SDL_DestroyWindow(_window); -} - - -void VkGUI::poll_event() { - SDL_Event event; - - while(SDL_PollEvent(&event) != 0) { - //close the window when user alt-f4s or clicks the X button - if(event.type == SDL_QUIT) { - should_quit = true; - } - - if(event.type == SDL_WINDOWEVENT) { - if(event.window.event == SDL_WINDOWEVENT_MINIMIZED) { - stop_rendering = true; - } - - if(event.window.event == SDL_WINDOWEVENT_RESTORED) { - stop_rendering = false; - } - } - } -} diff --git a/vk_gui.h b/vk_gui.h deleted file mode 100644 index aa25f6c..0000000 --- a/vk_gui.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "vk_types.h" - -class VulkanEngine; - -class VkGUI { - public: - bool should_quit = false; - bool stop_rendering = false; - - struct SDL_Window* init_window(VkExtent2D windowExtent); - void destroy(struct SDL_Window* _window); - - void poll_event(); -}; diff --git a/vk_images.cpp b/vk_images.cpp index c97537e..a457d61 100644 --- a/vk_images.cpp +++ b/vk_images.cpp @@ -3,25 +3,28 @@ void vkutil::transition_image(VkCommandBuffer cmd, VkImage image, VkImageLayout currentLayout, VkImageLayout newLayout) { + VkImageMemoryBarrier2 imageBarrier{}; + imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2; + imageBarrier.pNext = nullptr; + + imageBarrier.srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + imageBarrier.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT; + imageBarrier.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + imageBarrier.dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT | VK_ACCESS_2_MEMORY_READ_BIT; + + + imageBarrier.oldLayout = currentLayout; + imageBarrier.newLayout = newLayout; + VkImageAspectFlags aspectMask = (newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; + imageBarrier.subresourceRange = vkinit::image_subresource_range(aspectMask); + imageBarrier.image = image; - VkImageMemoryBarrier2 imageBarrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, - .srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, - .srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, - .dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, - .dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT | VK_ACCESS_2_MEMORY_READ_BIT, - .oldLayout = currentLayout, - .newLayout = newLayout, - .image = image, - .subresourceRange = vkinit::image_subresource_range(aspectMask), - }; - - VkDependencyInfo depInfo{ - .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, - .imageMemoryBarrierCount = 1, - .pImageMemoryBarriers = &imageBarrier, - }; + VkDependencyInfo depInfo{}; + depInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; + depInfo.pNext = nullptr; + depInfo.imageMemoryBarrierCount = 1; + depInfo.pImageMemoryBarriers = &imageBarrier; vkCmdPipelineBarrier2(cmd, &depInfo); } @@ -30,45 +33,39 @@ void vkutil::copy_image_to_image(VkCommandBuffer cmd, VkImage source, VkImage de { VkImageBlit2 blitRegion{ .sType = VK_STRUCTURE_TYPE_IMAGE_BLIT_2, + .pNext = nullptr }; - blitRegion.srcSubresource = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .mipLevel = 0, - .baseArrayLayer = 0, - .layerCount = 1, - }; + blitRegion.srcOffsets[1].x = srcSize.width; + blitRegion.srcOffsets[1].y = srcSize.height; + blitRegion.srcOffsets[1].z = 1; - blitRegion.dstSubresource = { - .aspectMask=VK_IMAGE_ASPECT_COLOR_BIT, - .mipLevel=0, - .baseArrayLayer=0, - .layerCount=1, - }; + blitRegion.dstOffsets[1].x = dstSize.width; + blitRegion.dstOffsets[1].y = dstSize.height; + blitRegion.dstOffsets[1].z = 1; - blitRegion.srcOffsets[1] = { - .x = int32_t(srcSize.width), - .y = int32_t(srcSize.height), - .z = 1, - }; + blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + blitRegion.srcSubresource.baseArrayLayer = 0; + blitRegion.srcSubresource.layerCount = 1; + blitRegion.srcSubresource.mipLevel = 0; - blitRegion.dstOffsets[1] = { - .x = int32_t(dstSize.width), - .y = int32_t(dstSize.height), - .z = 1, - }; + blitRegion.dstSubresource.aspectMask=VK_IMAGE_ASPECT_COLOR_BIT; + blitRegion.dstSubresource.baseArrayLayer=0; + blitRegion.dstSubresource.layerCount=1; + blitRegion.dstSubresource.mipLevel=0; VkBlitImageInfo2 blitInfo{ - .sType = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2, - .srcImage = source, - .srcImageLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - .dstImage = destination, - .dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - .regionCount = 1, - .pRegions = &blitRegion, - .filter = VK_FILTER_LINEAR, + .sType = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2, .pNext = nullptr }; + blitInfo.dstImage = destination; + blitInfo.dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + blitInfo.srcImage = source; + blitInfo.srcImageLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + blitInfo.filter = VK_FILTER_LINEAR; + blitInfo.regionCount = 1; + blitInfo.pRegions = &blitRegion; + vkCmdBlitImage2(cmd, &blitInfo); } diff --git a/vk_initializers.cpp b/vk_initializers.cpp index b54c78c..c31d17b 100644 --- a/vk_initializers.cpp +++ b/vk_initializers.cpp @@ -1,139 +1,191 @@ #include +#include +#include "trash_test.hpp" + +nlohmann::json DATA = nlohmann::json::parse(R"( + { + "VkSemaphoreCreateInfo": { + "draw": { + "sType": 9 + } + }, + "VkFenceCreateInfo": { + "draw": { + "sType": 8 + } + }, + "VkImageViewCreateInfo": { + "draw": { + "sType": 15, + "viewType": 1, + "subresourceRange.baseMipLevel": 0, + "subresourceRange.levelCount": 1, + "subresourceRange.baseArrayLayer": 0, + "subresourceRange.layerCount": 1 + } + } + } +)"); + +template COMPONENT load(nlohmann::json &data, const std::string& profile) { + COMPONENT result{}; + auto& type_stuff = data[NameOf::name]; + auto& profile_data = type_stuff[profile]; + nlohmann::from_json(profile_data, result); + return result; +} + VkCommandPoolCreateInfo vkinit::command_pool_create_info(uint32_t queueFamilyIndex, VkCommandPoolCreateFlags flags /*= 0*/) { - return { - .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, - .flags = flags, - .queueFamilyIndex = queueFamilyIndex, - }; + VkCommandPoolCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + info.pNext = nullptr; + info.queueFamilyIndex = queueFamilyIndex; + info.flags = flags; + return info; } VkCommandBufferAllocateInfo vkinit::command_buffer_allocate_info( VkCommandPool pool, uint32_t count /*= 1*/) { - return { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, - .commandPool = pool, - .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - .commandBufferCount = count, - }; + VkCommandBufferAllocateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + info.pNext = nullptr; + + info.commandPool = pool; + info.commandBufferCount = count; + info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + return info; } VkFenceCreateInfo vkinit::fence_create_info(VkFenceCreateFlags flags /*=0*/) { - return { - .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, - .flags = flags - }; + auto info = load(DATA, "draw"); + info.flags = flags; + return info; } VkSemaphoreCreateInfo vkinit::semaphore_create_info(VkSemaphoreCreateFlags flags/*=0*/) { - return { - .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, - .flags = flags, - }; + auto info = load(DATA, "draw"); + info.flags = flags; + + return info; } VkCommandBufferBeginInfo vkinit::command_buffer_begin_info(VkCommandBufferUsageFlags flags /*= 0*/) { - return { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - .flags = flags, - .pInheritanceInfo = nullptr, - }; + VkCommandBufferBeginInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + info.pNext = nullptr; + + info.pInheritanceInfo = nullptr; + info.flags = flags; + return info; } VkImageSubresourceRange vkinit::image_subresource_range(VkImageAspectFlags aspectMask) { - return { - .aspectMask = aspectMask, - .baseMipLevel = 0, - .levelCount = VK_REMAINING_MIP_LEVELS, - .baseArrayLayer = 0, - .layerCount = VK_REMAINING_ARRAY_LAYERS, - }; + VkImageSubresourceRange subImage {}; + subImage.aspectMask = aspectMask; + subImage.baseMipLevel = 0; + subImage.levelCount = VK_REMAINING_MIP_LEVELS; + subImage.baseArrayLayer = 0; + subImage.layerCount = VK_REMAINING_ARRAY_LAYERS; + + return subImage; } VkSemaphoreSubmitInfo vkinit::semaphore_submit_info(VkPipelineStageFlags2 stageMask, VkSemaphore semaphore) { - return { - .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO, - .semaphore = semaphore, - .value = 1, - .stageMask = stageMask, - .deviceIndex = 0, - }; + VkSemaphoreSubmitInfo submitInfo{}; + submitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO; + submitInfo.pNext = nullptr; + submitInfo.semaphore = semaphore; + submitInfo.stageMask = stageMask; + submitInfo.deviceIndex = 0; + submitInfo.value = 1; + + return submitInfo; } VkCommandBufferSubmitInfo vkinit::command_buffer_submit_info(VkCommandBuffer cmd) { - return { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO, - .commandBuffer = cmd, - .deviceMask = 0, - }; + VkCommandBufferSubmitInfo info{}; + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO; + info.pNext = nullptr; + info.commandBuffer = cmd; + info.deviceMask = 0; + + return info; } VkSubmitInfo2 vkinit::submit_info(VkCommandBufferSubmitInfo* cmd, VkSemaphoreSubmitInfo* signalSemaphoreInfo, VkSemaphoreSubmitInfo* waitSemaphoreInfo) { - return { - .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2, - .waitSemaphoreInfoCount = (waitSemaphoreInfo == nullptr ? 0u : 1u), - .pWaitSemaphoreInfos = waitSemaphoreInfo, - .commandBufferInfoCount = 1, - .pCommandBufferInfos = cmd, - .signalSemaphoreInfoCount = (signalSemaphoreInfo == nullptr ? 0u : 1u), - .pSignalSemaphoreInfos = signalSemaphoreInfo, - }; + VkSubmitInfo2 info = {}; + info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2; + info.pNext = nullptr; + + info.waitSemaphoreInfoCount = waitSemaphoreInfo == nullptr ? 0 : 1; + info.pWaitSemaphoreInfos = waitSemaphoreInfo; + + info.signalSemaphoreInfoCount = signalSemaphoreInfo == nullptr ? 0 : 1; + info.pSignalSemaphoreInfos = signalSemaphoreInfo; + + info.commandBufferInfoCount = 1; + info.pCommandBufferInfos = cmd; + + return info; } VkImageCreateInfo vkinit::image_create_info(VkFormat format, VkImageUsageFlags usageFlags, VkExtent3D extent) { - return { - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .imageType = VK_IMAGE_TYPE_2D, - .format = format, - .extent = extent, - .mipLevels = 1, - .arrayLayers = 1, - .samples = VK_SAMPLE_COUNT_1_BIT, - .tiling = VK_IMAGE_TILING_OPTIMAL, - .usage = usageFlags, - }; + VkImageCreateInfo info{}; + info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + info.pNext = nullptr; + + info.imageType = VK_IMAGE_TYPE_2D; + + info.format = format; + info.extent = extent; + + info.mipLevels = 1; + info.arrayLayers = 1; + + info.samples = VK_SAMPLE_COUNT_1_BIT; + + info.tiling = VK_IMAGE_TILING_OPTIMAL; + info.usage = usageFlags; + + return info; } VkImageViewCreateInfo vkinit::imageview_create_info(VkFormat format, VkImage image, VkImageAspectFlags aspectFlags) { - return { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .image = image, - .viewType = VK_IMAGE_VIEW_TYPE_2D, - .format = format, - .subresourceRange = { - .aspectMask = aspectFlags, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1, - } - }; + auto info = load(DATA, "draw"); + + info.image = image; + info.format = format; + info.subresourceRange.aspectMask = aspectFlags; + + return info; } VkRenderingAttachmentInfo vkinit::attachment_info( VkImageView view, VkClearValue* clear ,VkImageLayout layout /*= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL*/) { - VkRenderingAttachmentInfo colorAttachment{ - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .imageView = view, - .imageLayout = layout, - .loadOp = clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - }; + VkRenderingAttachmentInfo colorAttachment {}; + colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + colorAttachment.pNext = nullptr; + + colorAttachment.imageView = view; + colorAttachment.imageLayout = layout; + colorAttachment.loadOp = clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD; + colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; if (clear) { colorAttachment.clearValue = *clear; @@ -146,38 +198,16 @@ VkRenderingAttachmentInfo vkinit::attachment_info( VkRenderingInfo vkinit::rendering_info(VkExtent2D renderExtent, VkRenderingAttachmentInfo* colorAttachment, VkRenderingAttachmentInfo* depthAttachment) { - return { - .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, - .renderArea = VkRect2D { VkOffset2D { 0, 0 }, renderExtent }, - .layerCount = 1, - .colorAttachmentCount = 1, - .pColorAttachments = colorAttachment, - .pDepthAttachment = depthAttachment, - .pStencilAttachment = nullptr, - }; + VkRenderingInfo renderInfo {}; + renderInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; + renderInfo.pNext = nullptr; + + renderInfo.renderArea = VkRect2D { VkOffset2D { 0, 0 }, renderExtent }; + renderInfo.layerCount = 1; + renderInfo.colorAttachmentCount = 1; + renderInfo.pColorAttachments = colorAttachment; + renderInfo.pDepthAttachment = depthAttachment; + renderInfo.pStencilAttachment = nullptr; + + return renderInfo; } - - -VkPipelineShaderStageCreateInfo vkinit::pipeline_shader_stage_create_info(VkShaderStageFlagBits stage, VkShaderModule shader, const char* entry) { - return { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = stage, - .module = shader, - .pName = entry, - }; -} - - -VkPipelineLayoutCreateInfo vkinit::pipeline_layout_create_info() -{ - return { - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .setLayoutCount = 0, - .pSetLayouts = nullptr, - .pushConstantRangeCount = 0, - .pPushConstantRanges = nullptr, - }; -} - diff --git a/vk_initializers.h b/vk_initializers.h index 3cec09a..000b378 100644 --- a/vk_initializers.h +++ b/vk_initializers.h @@ -35,9 +35,5 @@ namespace vkinit { VkImageView view, VkClearValue* clear ,VkImageLayout layout=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); VkRenderingInfo rendering_info(VkExtent2D renderExtent, VkRenderingAttachmentInfo* colorAttachment, VkRenderingAttachmentInfo* depthAttachment); - - VkPipelineShaderStageCreateInfo pipeline_shader_stage_create_info(VkShaderStageFlagBits stage, VkShaderModule shader, const char* entry="main"); - - VkPipelineLayoutCreateInfo pipeline_layout_create_info(); } diff --git a/vk_loader.cpp b/vk_loader.cpp deleted file mode 100644 index 8d077d1..0000000 --- a/vk_loader.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include -#include "vendor/stb_image.h" -#include - -#include "vk_engine.h" -#include "vk_initializers.h" -#include "vk_types.h" -#include - -#include -#include -#include - -std::optional>> loadGltfMeshes(VulkanEngine* engine, std::filesystem::path filePath) -{ -//> openmesh - std::cout << "\nLoading GLTF: " << filePath << std::endl; - - fastgltf::GltfDataBuffer data; - data.loadFromFile(filePath); - - constexpr auto gltfOptions = fastgltf::Options::LoadGLBBuffers - | fastgltf::Options::LoadExternalBuffers; - - fastgltf::Asset gltf; - fastgltf::Parser parser {}; - - auto load = parser.loadBinaryGLTF(&data, filePath.parent_path(), gltfOptions); - if (load) { - gltf = std::move(load.get()); - } else { - std::print("Failed to load glTF: {} \n", fastgltf::to_underlying(load.error())); - return {}; - } -//< openmesh -//> loadmesh - std::vector> meshes; - - // use the same vectors for all meshes so that the memory doesnt reallocate as - // often - std::vector indices; - std::vector vertices; - for (fastgltf::Mesh& mesh : gltf.meshes) { - MeshAsset newmesh; - - newmesh.name = mesh.name; - - // clear the mesh arrays each mesh, we dont want to merge them by error - indices.clear(); - vertices.clear(); - - for (auto&& p : mesh.primitives) { - GeoSurface newSurface; - newSurface.startIndex = (uint32_t)indices.size(); - newSurface.count = (uint32_t)gltf.accessors[p.indicesAccessor.value()].count; - - size_t initial_vtx = vertices.size(); - - // load indexes - { - fastgltf::Accessor& indexaccessor = gltf.accessors[p.indicesAccessor.value()]; - indices.reserve(indices.size() + indexaccessor.count); - - fastgltf::iterateAccessor(gltf, indexaccessor, - [&](std::uint32_t idx) { - indices.push_back(idx + initial_vtx); - }); - } - - // load vertex positions - { - fastgltf::Accessor& posAccessor = gltf.accessors[p.findAttribute("POSITION")->second]; - vertices.resize(vertices.size() + posAccessor.count); - - fastgltf::iterateAccessorWithIndex(gltf, posAccessor, - [&](glm::vec3 v, size_t index) { - Vertex newvtx; - newvtx.position = v; - newvtx.normal = { 1, 0, 0 }; - newvtx.color = glm::vec4 { 1.f }; - newvtx.uv_x = 0; - newvtx.uv_y = 0; - vertices[initial_vtx + index] = newvtx; - }); - } - - // load vertex normals - auto normals = p.findAttribute("NORMAL"); - if (normals != p.attributes.end()) { - - fastgltf::iterateAccessorWithIndex(gltf, gltf.accessors[(*normals).second], - [&](glm::vec3 v, size_t index) { - vertices[initial_vtx + index].normal = v; - }); - } - - // load UVs - auto uv = p.findAttribute("TEXCOORD_0"); - if (uv != p.attributes.end()) { - - fastgltf::iterateAccessorWithIndex(gltf, gltf.accessors[(*uv).second], - [&](glm::vec2 v, size_t index) { - vertices[initial_vtx + index].uv_x = v.x; - vertices[initial_vtx + index].uv_y = v.y; - }); - } - - // load vertex colors - auto colors = p.findAttribute("COLOR_0"); - if (colors != p.attributes.end()) { - - fastgltf::iterateAccessorWithIndex(gltf, gltf.accessors[(*colors).second], - [&](glm::vec4 v, size_t index) { - vertices[initial_vtx + index].color = v; - }); - } - newmesh.surfaces.push_back(newSurface); - } - - // display the vertex normals - constexpr bool OverrideColors = true; - if (OverrideColors) { - for (Vertex& vtx : vertices) { - vtx.color = glm::vec4(vtx.normal, 1.f); - } - } - newmesh.meshBuffers = engine->uploadMesh(indices, vertices); - - meshes.emplace_back(std::make_shared(std::move(newmesh))); - } - - return meshes; - -//< loadmesh -} diff --git a/vk_loader.h b/vk_loader.h deleted file mode 100644 index 2750e4f..0000000 --- a/vk_loader.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include -#include - -struct GeoSurface { - uint32_t startIndex; - uint32_t count; -}; - -struct MeshAsset { - std::string name; - - std::vector surfaces; - GPUMeshBuffers meshBuffers; -}; - -class VulkanEngine; - -std::optional>> loadGltfMeshes(VulkanEngine* engine, std::filesystem::path filePath); - - diff --git a/vk_pipelines.cpp b/vk_pipelines.cpp index b7b3c8d..4067f1d 100644 --- a/vk_pipelines.cpp +++ b/vk_pipelines.cpp @@ -23,13 +23,13 @@ bool vkutil::load_shader_module(const char* filePath, file.close(); - VkShaderModuleCreateInfo createInfo = { - .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, - .pNext = nullptr, - // codeSize has to be in bytes - .codeSize = buffer.size() * sizeof(uint32_t), - .pCode = buffer.data(), - }; + VkShaderModuleCreateInfo createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + createInfo.pNext = nullptr; + + // codeSize has to be in bytes + createInfo.codeSize = buffer.size() * sizeof(uint32_t); + createInfo.pCode = buffer.data(); VkShaderModule shaderModule; if(vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) { @@ -40,165 +40,3 @@ bool vkutil::load_shader_module(const char* filePath, *outShaderModule = shaderModule; return true; } - - -void PipelineBuilder::clear() { - // clear all of the structs we need back to 0 with their correct stype - - _inputAssembly = { .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; - - _rasterizer = { .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; - - _colorBlendAttachment = {}; - - _multisampling = { .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; - - _pipelineLayout = {}; - - _depthStencil = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; - - _renderInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO }; - - _shaderStages.clear(); -} - -VkPipeline PipelineBuilder::build_pipeline(VkDevice device) -{ - VkPipelineViewportStateCreateInfo viewportState{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, - .viewportCount = 1, - .scissorCount = 1, - }; - - VkPipelineColorBlendStateCreateInfo colorBlending{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, - .logicOpEnable = VK_FALSE, - .logicOp = VK_LOGIC_OP_COPY, - .attachmentCount = 1, - .pAttachments = &_colorBlendAttachment, - }; - - VkPipelineVertexInputStateCreateInfo _vertexInputInfo{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO - }; - - VkDynamicState state[] = { - VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR - }; - - VkPipelineDynamicStateCreateInfo dynamicInfo{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, - .dynamicStateCount = 2, - // ZED: we don't need to do this? state is also &state[0] - .pDynamicStates = &state[0], - }; - - // build the actual pipeline - VkGraphicsPipelineCreateInfo pipelineInfo = { - .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .pNext = &_renderInfo, - .stageCount = (uint32_t)_shaderStages.size(), - .pStages = _shaderStages.data(), - .pVertexInputState = &_vertexInputInfo, - .pInputAssemblyState = &_inputAssembly, - .pViewportState = &viewportState, - .pRasterizationState = &_rasterizer, - .pMultisampleState = &_multisampling, - .pDepthStencilState = &_depthStencil, - .pColorBlendState = &colorBlending, - .pDynamicState = &dynamicInfo, - .layout = _pipelineLayout, - }; - - // its easy to error out on create graphics pipeline, so we handle it a bit - // better than the common VK_CHECK case - - VkPipeline newPipeline; - auto works = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &newPipeline); - - if(works != VK_SUCCESS) { - std::println("failed to create pipeline"); - return VK_NULL_HANDLE; - } else { - return newPipeline; - } -} - -void PipelineBuilder::set_shaders(VkShaderModule vertexShader, VkShaderModule fragmentShader) -{ - _shaderStages.clear(); - - _shaderStages.push_back( - vkinit::pipeline_shader_stage_create_info( - VK_SHADER_STAGE_VERTEX_BIT, - vertexShader)); - - _shaderStages.push_back( - vkinit::pipeline_shader_stage_create_info( - VK_SHADER_STAGE_FRAGMENT_BIT, - fragmentShader)); -} - -void PipelineBuilder::set_input_topology(VkPrimitiveTopology topology) -{ - _inputAssembly.topology = topology; - _inputAssembly.primitiveRestartEnable = VK_FALSE; -} - -void PipelineBuilder::set_polygon_mode(VkPolygonMode mode) -{ - _rasterizer.polygonMode = mode; - _rasterizer.lineWidth = 1.0f; -} - -void PipelineBuilder::set_cull_mode(VkCullModeFlags cullMode, VkFrontFace frontFace) -{ - _rasterizer.cullMode = cullMode; - _rasterizer.frontFace = frontFace; -} - -void PipelineBuilder::set_multisampling_none() -{ - _multisampling.sampleShadingEnable = VK_FALSE; - _multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - _multisampling.minSampleShading = 1.0f; - _multisampling.pSampleMask = nullptr; - _multisampling.alphaToCoverageEnable = VK_FALSE; - _multisampling.alphaToOneEnable = VK_FALSE; -} - -void PipelineBuilder::disable_blending() -{ - _colorBlendAttachment.colorWriteMask = - VK_COLOR_COMPONENT_R_BIT - | VK_COLOR_COMPONENT_G_BIT - | VK_COLOR_COMPONENT_B_BIT - | VK_COLOR_COMPONENT_A_BIT; - - _colorBlendAttachment.blendEnable = VK_FALSE; -} - -void PipelineBuilder::set_color_attachment_format(VkFormat format) -{ - _colorAttachmentFormat = format; - _renderInfo.colorAttachmentCount = 1; - _renderInfo.pColorAttachmentFormats = &_colorAttachmentFormat; -} - -void PipelineBuilder::set_depth_format(VkFormat format) -{ - _renderInfo.depthAttachmentFormat = format; -} - -void PipelineBuilder::disable_depthtest() -{ - _depthStencil.depthTestEnable = VK_FALSE; - _depthStencil.depthWriteEnable = VK_FALSE; - _depthStencil.depthCompareOp = VK_COMPARE_OP_NEVER; - _depthStencil.depthBoundsTestEnable = VK_FALSE; - _depthStencil.stencilTestEnable = VK_FALSE; - _depthStencil.front = {}; - _depthStencil.back = {}; - _depthStencil.minDepthBounds = 0.0f; - _depthStencil.maxDepthBounds = 1.0f; -} diff --git a/vk_pipelines.h b/vk_pipelines.h index 16b4067..df9c74d 100644 --- a/vk_pipelines.h +++ b/vk_pipelines.h @@ -2,37 +2,6 @@ #include "vk_types.h" -class PipelineBuilder { - public: - std::vector _shaderStages; - - VkPipelineInputAssemblyStateCreateInfo _inputAssembly; - VkPipelineRasterizationStateCreateInfo _rasterizer; - VkPipelineColorBlendAttachmentState _colorBlendAttachment; - VkPipelineMultisampleStateCreateInfo _multisampling; - VkPipelineLayout _pipelineLayout; - VkPipelineDepthStencilStateCreateInfo _depthStencil; - VkPipelineRenderingCreateInfo _renderInfo; - VkFormat _colorAttachmentFormat; - - PipelineBuilder() { - clear(); - } - - void clear(); - - VkPipeline build_pipeline(VkDevice device); - void set_shaders(VkShaderModule vertexShader, VkShaderModule fragmentShader); - void set_input_topology(VkPrimitiveTopology topology); - void set_polygon_mode(VkPolygonMode mode); - void set_cull_mode(VkCullModeFlags cullMode, VkFrontFace frontFace); - void set_multisampling_none(); - void disable_blending(); - void set_color_attachment_format(VkFormat format); - void set_depth_format(VkFormat format); - void disable_depthtest(); -}; - namespace vkutil { bool load_shader_module(const char* filePath, VkDevice device, diff --git a/vk_types.h b/vk_types.h index d491e6f..9b880a6 100644 --- a/vk_types.h +++ b/vk_types.h @@ -18,7 +18,6 @@ #include -#define GLM_ENABLE_EXPERIMENTAL 1 #include #include @@ -31,14 +30,6 @@ } while (0) -constexpr unsigned int FRAME_OVERLAP=2; - -struct AllocatedBuffer { - VkBuffer buffer; - VmaAllocation allocation; - VmaAllocationInfo info; -}; - struct AllocatedImage { VkImage image; VkImageView imageView; @@ -46,38 +37,3 @@ struct AllocatedImage { VkExtent3D imageExtent; VkFormat imageFormat; }; - -struct ComputePushConstants { - glm::vec4 data1; - glm::vec4 data2; - glm::vec4 data3; - glm::vec4 data4; -}; - -struct ComputeEffect { - const char *name; - VkPipeline pipeline; - VkPipelineLayout layout; - - ComputePushConstants data; -}; - -struct Vertex { - glm::vec3 position; - float uv_x; - glm::vec3 normal; - float uv_y; - glm::vec4 color; -}; - -struct GPUMeshBuffers { - AllocatedBuffer indexBuffer; - AllocatedBuffer vertexBuffer; - VkDeviceAddress vertexBufferAddress; -}; - -struct GPUDrawPushConstants { - glm::mat4 worldMatrix; - VkDeviceAddress vertexBuffer; -}; - diff --git a/wraps/fastgltf.wrap b/wraps/fastgltf.wrap deleted file mode 100644 index 06cadec..0000000 --- a/wraps/fastgltf.wrap +++ /dev/null @@ -1,9 +0,0 @@ -[wrap-git] -directory=fastgltf -url=https://github.com/spnda/fastgltf.git -revision=v0.6.1 -depth=1 -method=cmake - -[provide] -fastgltf = fastgltf_dep diff --git a/wraps/nlohmann_json.wrap b/wraps/nlohmann_json.wrap new file mode 100644 index 0000000..8c46676 --- /dev/null +++ b/wraps/nlohmann_json.wrap @@ -0,0 +1,11 @@ +[wrap-file] +directory = nlohmann_json-3.11.3 +lead_directory_missing = true +source_url = https://github.com/nlohmann/json/releases/download/v3.11.3/include.zip +source_filename = nlohmann_json-3.11.3.zip +source_hash = a22461d13119ac5c78f205d3df1db13403e58ce1bb1794edc9313677313f4a9d +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/nlohmann_json_3.11.3-1/nlohmann_json-3.11.3.zip +wrapdb_version = 3.11.3-1 + +[provide] +nlohmann_json = nlohmann_json_dep diff --git a/wraps/simdjson.wrap b/wraps/simdjson.wrap deleted file mode 100644 index a3e383c..0000000 --- a/wraps/simdjson.wrap +++ /dev/null @@ -1,13 +0,0 @@ -[wrap-file] -directory = simdjson-3.3.0 -source_url = https://github.com/simdjson/simdjson/archive/refs/tags/v3.3.0.tar.gz -source_filename = simdjson-3.3.0.tar.gz -source_hash = a8c9feff2f19c3ff281d42f0b6b4b18f02236513b99229756fa9a1b14787a58a -patch_filename = simdjson_3.3.0-2_patch.zip -patch_url = https://wrapdb.mesonbuild.com/v2/simdjson_3.3.0-2/get_patch -patch_hash = 3c39f8a5abac17732b9599a416e6edb09f5f987bcf4e8b46808dbe88040eb40f -source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/simdjson_3.3.0-2/simdjson-3.3.0.tar.gz -wrapdb_version = 3.3.0-2 - -[provide] -simdjson = simdjson_dep