diff --git a/include/application.hpp b/include/application.hpp index 2f017e8..0a7ca54 100644 --- a/include/application.hpp +++ b/include/application.hpp @@ -75,14 +75,7 @@ private: unique_ptr sizeInformationBuffer; - struct SimulationUniformData { - glm::vec3 gravity; - // Delta time in seconds - float dt; - uint32_t k; - }; - unique_ptr propertiesBuffer; - SimulationUniformData simulationUniformData {}; + unique_ptr simulationPropertiesBuffer; void createComputePipelines(); unique_ptr grabPipeline; diff --git a/include/vulkan/buffer.hpp b/include/vulkan/buffer.hpp index 0302960..1112d8c 100644 --- a/include/vulkan/buffer.hpp +++ b/include/vulkan/buffer.hpp @@ -7,16 +7,20 @@ class Buffer { public: - explicit Buffer(VkDeviceSize size, VkBufferUsageFlags bufferUsage, - VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags flags); - explicit Buffer(VkDeviceSize size, void* data, VkDeviceSize dataSize, VkBufferUsageFlags bufferUsage, - VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags flags); + explicit Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsage, + VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags vmaAllocationFlags); + explicit Buffer(VkDeviceSize bufferSize, void* initialData, VkDeviceSize initialDataSize, VkBufferUsageFlags bufferUsage, + VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags vmaAllocationFlags); ~Buffer(); VkBuffer handle = VK_NULL_HANDLE; VmaAllocation allocation = VK_NULL_HANDLE; VmaAllocationInfo allocationInfo {}; VkDeviceSize size; void setName(const std::string& name); + template + T& access(){ + return *reinterpret_cast(allocationInfo.pMappedData); + } Buffer(const Buffer& other) = delete; Buffer& operator =(const Buffer& other) = delete; private: diff --git a/src/application.cpp b/src/application.cpp index 7259c8a..f5bd2b8 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -29,6 +29,12 @@ struct CameraUniformData { glm::vec2 viewport; }; +struct SimulationUniformData { + glm::vec3 gravity; + float dt; + uint32_t k; +}; + struct GrabPushData { uint32_t state; alignas(8) glm::vec2 screenPosition; @@ -49,14 +55,13 @@ Application::Application() { swapchain->renderPass, {descriptorPool->layouts[DescriptorSet::WORLD]})); - VkDeviceSize bufferSize = sizeof(CameraUniformData); - - cameraUniformBuffer = make_unique(bufferSize, + cameraUniformBuffer = make_unique(sizeof(CameraUniformData), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); cameraUniformBuffer->setName("Camera"); camera = make_unique(swapchain->extent); + updateCameraBuffer(); struct GrabInformation { float originalInverseMass; @@ -82,16 +87,19 @@ Application::Application() { VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); sizeInformationBuffer->setName("Sizes"); - simulationUniformData.gravity = {0, -9.81, 0}; - simulationUniformData.k = 10; - simulationUniformData.dt = 1.f / 60.f; + SimulationUniformData simulationUniformData { + .gravity = {0, -9.81, 0}, + .dt = 1.f / 60.f, + .k = 10, + }; - propertiesBuffer = make_unique( - sizeof(SimulationUniformData), &simulationUniformData, sizeof(simulationUniformData), + simulationPropertiesBuffer = make_unique( + sizeof(SimulationUniformData), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); - propertiesBuffer->setName("Simulation properties"); - + VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, + VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); + simulationPropertiesBuffer->setName("Simulation properties"); + simulationPropertiesBuffer->access() = simulationUniformData; descriptorPool->bindBuffer(*cameraUniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::WORLD, 0); @@ -102,7 +110,7 @@ Application::Application() { descriptorPool->bindBuffer(*tetrahedronBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 4); descriptorPool->bindBuffer(*sizeInformationBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::MESH, 5); - descriptorPool->bindBuffer(*propertiesBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::SIMULATION, 0); + descriptorPool->bindBuffer(*simulationPropertiesBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::SIMULATION, 0); descriptorPool->bindBuffer(*grabBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::SIMULATION, 1); createComputePipelines(); @@ -124,16 +132,15 @@ void Application::mainLoop() { auto t2 = system_clock::now(); auto measuredUpdateDuration = duration(t2 - t1); - auto requestedUpdateDuration = duration(simulationUniformData.dt); + auto requestedUpdateDuration = duration(simulationPropertiesBuffer->access().dt); std::this_thread::sleep_for(requestedUpdateDuration - measuredUpdateDuration); } }); - auto t2 = system_clock::now(); auto t1 = system_clock::now(); while (!glfwWindowShouldClose(Instance::instance->window)){ glfwPollEvents(); - t2 = system_clock::now(); + auto t2 = system_clock::now(); float seconds = duration(t2 - t1).count(); t1 = system_clock::now(); drawFrame(seconds); @@ -326,13 +333,11 @@ void Application::createComputePipelines() { } void Application::updateCameraBuffer() { - CameraUniformData ubo {}; - ubo.view = camera->view(); - ubo.projection = camera->projection(); - ubo.projection[1][1] *= -1; - ubo.viewport = camera->viewport(); - - memcpy(cameraUniformBuffer->allocationInfo.pMappedData, &ubo, sizeof(CameraUniformData)); + CameraUniformData& data = cameraUniformBuffer->access(); + data.view = camera->view(); + data.projection = camera->projection(); + data.projection[1][1] *= -1; + data.viewport = camera->viewport(); } void Application::drawFrame(float dt) { @@ -605,7 +610,9 @@ void Application::recordPBDCommands(VkCommandBuffer cmdBuffer) { uint32_t state; - for (size_t i = 0; i < simulationUniformData.k; i++){ + uint32_t k = simulationPropertiesBuffer->access().k; + + for (size_t i = 0; i < k; i++){ state = 0; vkCmdPushConstants(cmdBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state); vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1); diff --git a/src/vulkan/buffer.cpp b/src/vulkan/buffer.cpp index 869ea47..d48661d 100644 --- a/src/vulkan/buffer.cpp +++ b/src/vulkan/buffer.cpp @@ -6,32 +6,32 @@ #include "vk_mem_alloc.h" -Buffer::Buffer(VkDeviceSize size, VkBufferUsageFlags bufferUsage, VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags flags) : size(size) { +Buffer::Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsage, VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags vmaAllocationFlags) : size(bufferSize) { VkBufferCreateInfo bufferCreateInfo {}; bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferCreateInfo.size = size; + bufferCreateInfo.size = bufferSize; bufferCreateInfo.usage = bufferUsage; bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; VmaAllocationCreateInfo allocationCreateInfo {}; allocationCreateInfo.usage = memoryUsage; - allocationCreateInfo.flags = flags; + allocationCreateInfo.flags = vmaAllocationFlags; vmaCreateBuffer(Instance::GetAllocator(), &bufferCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo); } -Buffer::Buffer(VkDeviceSize size, void *data, VkDeviceSize dataSize, VkBufferUsageFlags bufferUsage, - VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags flags) - : Buffer(size, bufferUsage | VK_BUFFER_USAGE_TRANSFER_DST_BIT, memoryUsage, flags){ +Buffer::Buffer(VkDeviceSize bufferSize, void *initialData, VkDeviceSize initialDataSize, VkBufferUsageFlags bufferUsage, + VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags vmaAllocationFlags) + : Buffer(bufferSize, bufferUsage | VK_BUFFER_USAGE_TRANSFER_DST_BIT, memoryUsage, vmaAllocationFlags){ Buffer stagingBuffer( - size, + bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT ); - memcpy(stagingBuffer.allocationInfo.pMappedData, data, dataSize); + memcpy(stagingBuffer.allocationInfo.pMappedData, initialData, initialDataSize); stagingBuffer.copyTo(this); } @@ -43,7 +43,7 @@ void Buffer::copyTo(Buffer *dst) { VkCommandBufferAllocateInfo allocateInfo {}; allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocateInfo.commandPool = Instance::instance->renderingCommandPool->handle; + allocateInfo.commandPool = Instance::instance->computeCommandPool->handle; allocateInfo.commandBufferCount = 1; VkCommandBuffer commandBuffer; @@ -64,10 +64,10 @@ void Buffer::copyTo(Buffer *dst) { submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &commandBuffer; - vkQueueSubmit(Instance::instance->graphicsAndPresentQueue, 1, &submitInfo, VK_NULL_HANDLE); + vkQueueSubmit(Instance::instance->computeAndTransferQueue, 1, &submitInfo, VK_NULL_HANDLE); vkDeviceWaitIdle(Instance::GetDevice()); - vkFreeCommandBuffers(Instance::GetDevice(), Instance::instance->renderingCommandPool->handle, 1, &commandBuffer); + vkFreeCommandBuffers(Instance::GetDevice(), Instance::instance->computeCommandPool->handle, 1, &commandBuffer); } void Buffer::setName(const std::string &name) {