From 385c608d96df607634e459814af075d28c1430cb Mon Sep 17 00:00:00 2001 From: Benjamin Kraft Date: Thu, 19 Sep 2024 21:45:33 +0200 Subject: [PATCH] start abstraction --- include/simulation.hpp | 15 +++++ include/soft_body.hpp | 23 ++++++++ include/timer.hpp | 13 +++++ include/vulkan/application.hpp | 31 ++++------- include/vulkan/synchronization.hpp | 17 ++++++ include/vulkan/utils.h | 3 - shaders/shader.comp | 2 +- src/main.cpp | 6 +- src/simulation.cpp | 33 +++++++++++ src/soft_body.cpp | 5 ++ src/timer.cpp | 11 ++++ src/vulkan/application.cpp | 88 +++++++++++++----------------- src/vulkan/buffer.cpp | 1 - src/vulkan/image.cpp | 1 - src/vulkan/synchronization.cpp | 25 +++++++++ src/vulkan/utils.cpp | 17 ------ 16 files changed, 194 insertions(+), 97 deletions(-) create mode 100644 include/simulation.hpp create mode 100644 include/soft_body.hpp create mode 100644 include/timer.hpp create mode 100644 include/vulkan/synchronization.hpp delete mode 100644 include/vulkan/utils.h create mode 100644 src/simulation.cpp create mode 100644 src/soft_body.cpp create mode 100644 src/timer.cpp create mode 100644 src/vulkan/synchronization.cpp delete mode 100644 src/vulkan/utils.cpp diff --git a/include/simulation.hpp b/include/simulation.hpp new file mode 100644 index 0000000..f70ded3 --- /dev/null +++ b/include/simulation.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "vulkan/application.hpp" + +class SoftBody; + +class Simulation : public Application { +public: + Simulation(); + ~Simulation(); +private: + std::vector> softBodies; + void recordDrawCommands() override; + void recordComputeCommands() override; +}; \ No newline at end of file diff --git a/include/soft_body.hpp b/include/soft_body.hpp new file mode 100644 index 0000000..36e2ac0 --- /dev/null +++ b/include/soft_body.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include + +#include "vulkan/vertex.hpp" +#include + +using std::vector; + +struct Face { + uint32_t a; + uint32_t b; + uint32_t c; +}; + +class SoftBody { +public: + explicit SoftBody(const std::string& fileName); +private: + uint32_t indexCount = 0; +}; \ No newline at end of file diff --git a/include/timer.hpp b/include/timer.hpp new file mode 100644 index 0000000..6bb3753 --- /dev/null +++ b/include/timer.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include + +using namespace std::chrono; + +class Timer { +public: + explicit Timer(); + ~Timer(); +private: + time_point start; +}; \ No newline at end of file diff --git a/include/vulkan/application.hpp b/include/vulkan/application.hpp index 30c3fa5..a4d4f09 100644 --- a/include/vulkan/application.hpp +++ b/include/vulkan/application.hpp @@ -21,26 +21,16 @@ class Buffer; class CommandPool; class Image; class ComputePipeline; - -class Timer { -public: - explicit Timer(){ - start = std::chrono::system_clock::now(); - } - ~Timer(){ - size_t nanoseconds = (std::chrono::system_clock::now() - start).count(); - printf("Timer: %zu mus\n", nanoseconds / 1000); - } -private: - std::chrono::time_point start; -}; +class Fence; +class Semaphore; class Application { public: explicit Application(); void mainLoop(); ~Application(); -private: + +protected: Swapchain* swapchain = nullptr; Pipeline* graphicsPipeline = nullptr; Buffer* vertexBuffer = nullptr; @@ -52,15 +42,16 @@ private: void updateUniformBuffer(); void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex); - void recordComputeCommandBuffer(); - VkSemaphore imageAvailableSemaphore = VK_NULL_HANDLE; - VkSemaphore renderFinishedSemaphore = VK_NULL_HANDLE; - VkSemaphore computeFinishedSemaphore = VK_NULL_HANDLE; - VkFence renderInFlightFence = VK_NULL_HANDLE; - VkFence computeInFlightFence = VK_NULL_HANDLE; + Semaphore* imageAvailable = nullptr; + Semaphore* renderFinished = nullptr; + Semaphore* computeFinished = nullptr; + Fence* renderInFlight = nullptr; + Fence* computeInFlight = nullptr; void drawFrame(); + virtual void recordDrawCommands() {}; + virtual void recordComputeCommands() {} void update(); void createSyncObjects(); }; diff --git a/include/vulkan/synchronization.hpp b/include/vulkan/synchronization.hpp new file mode 100644 index 0000000..13de6c9 --- /dev/null +++ b/include/vulkan/synchronization.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include + +class Semaphore { +public: + explicit Semaphore(); + ~Semaphore(); + VkSemaphore handle = VK_NULL_HANDLE; +}; + +class Fence { +public: + explicit Fence(bool signaled); + ~Fence(); + VkFence handle = VK_NULL_HANDLE; +}; \ No newline at end of file diff --git a/include/vulkan/utils.h b/include/vulkan/utils.h deleted file mode 100644 index 97a3834..0000000 --- a/include/vulkan/utils.h +++ /dev/null @@ -1,3 +0,0 @@ -#include - -uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags propertyFlags); \ No newline at end of file diff --git a/shaders/shader.comp b/shaders/shader.comp index a72a073..fc29d48 100644 --- a/shaders/shader.comp +++ b/shaders/shader.comp @@ -12,5 +12,5 @@ layout (std140, binding = 0) buffer VertexBuffer { }; void main() { - vertices[4].position.z += 0.001; + vertices[0].position.z += 0.001; } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 598e934..3900f57 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,8 @@ -#include "vulkan/application.hpp" +#include "simulation.hpp" #include int main() { - Application application; - application.mainLoop(); + Simulation simulation; + simulation.mainLoop(); } diff --git a/src/simulation.cpp b/src/simulation.cpp new file mode 100644 index 0000000..a655949 --- /dev/null +++ b/src/simulation.cpp @@ -0,0 +1,33 @@ +#include "simulation.hpp" +#include "vulkan/instance.hpp" +#include "vulkan/command_pool.hpp" +#include "vulkan/buffer.hpp" +#include "vulkan/pipeline.hpp" +#include "soft_body.hpp" + +Simulation::Simulation() { + softBodies.push_back(std::make_unique("")); +} + +void Simulation::recordDrawCommands() { + VkCommandBuffer commandBuffer = Instance::instance->commandPool->graphicsBuffer; + + VkBuffer buffers[] = {vertexBuffer->handle}; + VkDeviceSize offsets[] = {0}; + vkCmdBindVertexBuffers(commandBuffer, 0, 1, buffers, offsets); + vkCmdBindIndexBuffer(commandBuffer, indexBuffer->handle, 0, VK_INDEX_TYPE_UINT32); + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1, &graphicsPipeline->descriptorSet, 0, nullptr); + + vkCmdDrawIndexed(commandBuffer, 12, 1, 0, 0, 0); +} + +void Simulation::recordComputeCommands() { + VkCommandBuffer commandBuffer = Instance::instance->commandPool->computeBuffer; + + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline->layout, 0, 1, &computePipeline->descriptorSet, 0, nullptr); + vkCmdDispatch(commandBuffer, 1, 1, 1); +} + +Simulation::~Simulation() { + +} diff --git a/src/soft_body.cpp b/src/soft_body.cpp new file mode 100644 index 0000000..e3a0493 --- /dev/null +++ b/src/soft_body.cpp @@ -0,0 +1,5 @@ +#include "soft_body.hpp" + +SoftBody::SoftBody(const std::string &fileName) { + +} diff --git a/src/timer.cpp b/src/timer.cpp new file mode 100644 index 0000000..732d0d7 --- /dev/null +++ b/src/timer.cpp @@ -0,0 +1,11 @@ +#include +#include "timer.hpp" + +Timer::Timer() { + start = system_clock::now(); +} + +Timer::~Timer() { + size_t nanoseconds = (system_clock::now() - start).count(); + printf("Timer: %zu mus\n", nanoseconds / 1000); +} diff --git a/src/vulkan/application.cpp b/src/vulkan/application.cpp index ca8d315..b872f1d 100644 --- a/src/vulkan/application.cpp +++ b/src/vulkan/application.cpp @@ -5,6 +5,7 @@ #include "vulkan/buffer.hpp" #include "vulkan/command_pool.hpp" #include "vulkan/image.hpp" +#include "vulkan/synchronization.hpp" #include @@ -53,17 +54,16 @@ Application::Application() { createSyncObjects(); - recordComputeCommandBuffer(); - char* stats; vmaBuildStatsString(Instance::instance->allocator, &stats, VK_TRUE); // printf("%s", stats); + vmaFreeStatsString(Instance::instance->allocator, stats); } void Application::updateUniformBuffer() { static float elapsed = 0; - elapsed += 0.007; + // elapsed += 0.007; UniformBufferObject ubo {}; ubo.model = glm::rotate(glm::mat4(1), elapsed * glm::radians(90.f), glm::vec3(0, 0, 1)); @@ -113,31 +113,18 @@ void Application::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t im scissor.extent = swapchain->extent; vkCmdSetScissor(commandBuffer, 0, 1, &scissor); - VkBuffer buffers[] = {vertexBuffer->handle}; - VkDeviceSize offsets[] = {0}; - vkCmdBindVertexBuffers(commandBuffer, 0, 1, buffers, offsets); - vkCmdBindIndexBuffer(commandBuffer, indexBuffer->handle, 0, VK_INDEX_TYPE_UINT32); - vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1, &graphicsPipeline->descriptorSet, 0, nullptr); - - vkCmdDrawIndexed(commandBuffer, 12, 1, 0, 0, 0); + recordDrawCommands(); vkCmdEndRenderPass(commandBuffer); vkEndCommandBuffer(commandBuffer); } void Application::createSyncObjects() { - VkSemaphoreCreateInfo semaphoreInfo {}; - semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - - VkFenceCreateInfo fenceInfo {}; - fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; - - vkCreateSemaphore(Instance::instance->device, &semaphoreInfo, nullptr, &imageAvailableSemaphore); - vkCreateSemaphore(Instance::instance->device, &semaphoreInfo, nullptr, &renderFinishedSemaphore); - vkCreateSemaphore(Instance::instance->device, &semaphoreInfo, nullptr, &computeFinishedSemaphore); - vkCreateFence(Instance::instance->device, &fenceInfo, nullptr, &renderInFlightFence); - vkCreateFence(Instance::instance->device, &fenceInfo, nullptr, &computeInFlightFence); + imageAvailable = new Semaphore; + renderFinished = new Semaphore; + computeFinished = new Semaphore; + renderInFlight = new Fence(true); + computeInFlight = new Fence(true); } void Application::mainLoop() { @@ -150,16 +137,16 @@ void Application::mainLoop() { } void Application::drawFrame() { - vkWaitForFences(Instance::instance->device, 1, &renderInFlightFence, VK_TRUE, UINT64_MAX); + vkWaitForFences(Instance::instance->device, 1, &renderInFlight->handle, VK_TRUE, UINT64_MAX); uint32_t imageIndex; - VkResult result = vkAcquireNextImageKHR(Instance::instance->device, swapchain->handle, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex); + VkResult result = vkAcquireNextImageKHR(Instance::instance->device, swapchain->handle, UINT64_MAX, imageAvailable->handle, VK_NULL_HANDLE, &imageIndex); if (result == VK_ERROR_OUT_OF_DATE_KHR){ swapchain->recreateSwapchain(); return; } - vkResetFences(Instance::instance->device, 1, &renderInFlightFence); + vkResetFences(Instance::instance->device, 1, &renderInFlight->handle); vkResetCommandBuffer(Instance::instance->commandPool->graphicsBuffer, 0); recordCommandBuffer(Instance::instance->commandPool->graphicsBuffer, imageIndex); @@ -169,7 +156,7 @@ void Application::drawFrame() { VkSubmitInfo submitInfo {}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - VkSemaphore waitSemaphores[] = {imageAvailableSemaphore, computeFinishedSemaphore}; + VkSemaphore waitSemaphores[] = {imageAvailable->handle, computeFinished->handle}; VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT}; submitInfo.waitSemaphoreCount = 2; submitInfo.pWaitSemaphores = waitSemaphores; @@ -177,11 +164,11 @@ void Application::drawFrame() { submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &Instance::instance->commandPool->graphicsBuffer; - VkSemaphore signalSemaphores[] = {renderFinishedSemaphore}; + VkSemaphore signalSemaphores[] = {renderFinished->handle}; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; - vkQueueSubmit(Instance::instance->graphicsQueue, 1, &submitInfo, renderInFlightFence); + vkQueueSubmit(Instance::instance->graphicsQueue, 1, &submitInfo, renderInFlight->handle); VkPresentInfoKHR presentInfo {}; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; @@ -201,41 +188,40 @@ void Application::drawFrame() { } void Application::update() { - vkWaitForFences(Instance::instance->device, 1, &computeInFlightFence, VK_TRUE, UINT64_MAX); - vkResetFences(Instance::instance->device, 1, &computeInFlightFence); - - VkSubmitInfo submit {}; - submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit.commandBufferCount = 1; - submit.pCommandBuffers = &Instance::instance->commandPool->computeBuffer; - submit.signalSemaphoreCount = 1; - submit.pSignalSemaphores = &computeFinishedSemaphore; + vkWaitForFences(Instance::instance->device, 1, &computeInFlight->handle, VK_TRUE, UINT64_MAX); + vkResetFences(Instance::instance->device, 1, &computeInFlight->handle); - vkQueueSubmit(Instance::instance->computeQueue, 1, &submit, computeInFlightFence); -} -void Application::recordComputeCommandBuffer() { - VkCommandBuffer buffer = Instance::instance->commandPool->computeBuffer; + VkCommandBuffer commandBuffer = Instance::instance->commandPool->computeBuffer; + vkResetCommandBuffer(commandBuffer, 0); VkCommandBufferBeginInfo beginInfo {}; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + beginInfo.flags = 0; + - vkBeginCommandBuffer(buffer, &beginInfo); + vkBeginCommandBuffer(commandBuffer, &beginInfo); + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline->handle); + recordComputeCommands(); + vkEndCommandBuffer(commandBuffer); - vkCmdBindPipeline(buffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline->handle); - vkCmdBindDescriptorSets(buffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline->layout,0, 1, &computePipeline->descriptorSet, 0, nullptr); - vkCmdDispatch(buffer, 1, 1, 1); + VkSubmitInfo submit {}; + submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit.commandBufferCount = 1; + submit.pCommandBuffers = &Instance::instance->commandPool->computeBuffer; + submit.signalSemaphoreCount = 1; + submit.pSignalSemaphores = &computeFinished->handle; - vkEndCommandBuffer(buffer); + vkQueueSubmit(Instance::instance->computeQueue, 1, &submit, computeInFlight->handle); } Application::~Application() { delete swapchain; - vkDestroySemaphore(Instance::instance->device, imageAvailableSemaphore, nullptr); - vkDestroySemaphore(Instance::instance->device, renderFinishedSemaphore, nullptr); - vkDestroySemaphore(Instance::instance->device, computeFinishedSemaphore, nullptr); - vkDestroyFence(Instance::instance->device, renderInFlightFence, nullptr); - vkDestroyFence(Instance::instance->device, computeInFlightFence, nullptr); + delete imageAvailable; + delete renderFinished; + delete computeFinished; + delete renderInFlight; + delete computeInFlight; delete vertexBuffer; delete indexBuffer; delete uniformBuffer; diff --git a/src/vulkan/buffer.cpp b/src/vulkan/buffer.cpp index 2d02f00..649907e 100644 --- a/src/vulkan/buffer.cpp +++ b/src/vulkan/buffer.cpp @@ -3,7 +3,6 @@ #include "vulkan/buffer.hpp" #include "vulkan/instance.hpp" #include "vulkan/command_pool.hpp" -#include "vulkan/utils.h" #include "vk_mem_alloc.h" diff --git a/src/vulkan/image.cpp b/src/vulkan/image.cpp index 5b9486f..f902bc8 100644 --- a/src/vulkan/image.cpp +++ b/src/vulkan/image.cpp @@ -1,7 +1,6 @@ #include #include "vulkan/image.hpp" #include "vulkan/instance.hpp" -#include "vulkan/utils.h" Image::Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, diff --git a/src/vulkan/synchronization.cpp b/src/vulkan/synchronization.cpp new file mode 100644 index 0000000..6bf4fee --- /dev/null +++ b/src/vulkan/synchronization.cpp @@ -0,0 +1,25 @@ +#include "vulkan/synchronization.hpp" +#include "vulkan/instance.hpp" + +Semaphore::Semaphore() { + VkSemaphoreCreateInfo semaphoreInfo {}; + semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + + vkCreateSemaphore(Instance::instance->device, &semaphoreInfo, nullptr, &handle); +} + +Semaphore::~Semaphore() { + vkDestroySemaphore(Instance::instance->device, handle, nullptr); +} + +Fence::Fence(bool signaled) { + VkFenceCreateInfo fenceInfo {}; + fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceInfo.flags = signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0; + + vkCreateFence(Instance::instance->device, &fenceInfo, nullptr, &handle); +} + +Fence::~Fence() { + vkDestroyFence(Instance::instance->device, handle, nullptr); +} diff --git a/src/vulkan/utils.cpp b/src/vulkan/utils.cpp deleted file mode 100644 index f93f594..0000000 --- a/src/vulkan/utils.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include "vulkan/utils.h" - -#include "vulkan/instance.hpp" - -uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags propertyFlags) { - VkPhysicalDeviceMemoryProperties memoryProperties; - vkGetPhysicalDeviceMemoryProperties(Instance::instance->physicalDevice, &memoryProperties); - - for (uint32_t type = 0; type < memoryProperties.memoryTypeCount; type++){ - if ((typeFilter & (1 << type)) && (memoryProperties.memoryTypes[type].propertyFlags & propertyFlags)){ - return type; - } - } - - throw std::runtime_error("failed to find suitable memory type!"); -} \ No newline at end of file