diff --git a/shaders/normal.comp b/shaders/normal.comp index bc28a3d..c235082 100644 --- a/shaders/normal.comp +++ b/shaders/normal.comp @@ -1,9 +1,6 @@ #version 450 -#extension GL_EXT_shader_atomic_float : enable - - -layout (local_size_x = 256) in; +layout (local_size_x = 16) in; struct Vertex { vec3 position; diff --git a/shaders/pbd.comp b/shaders/pbd.comp index d9e342c..245b205 100644 --- a/shaders/pbd.comp +++ b/shaders/pbd.comp @@ -1,6 +1,6 @@ #version 450 -layout (local_size_x = 256) in; +layout (local_size_x = 16) in; struct Vertex { vec3 position; @@ -12,6 +12,11 @@ layout (std430, set = 0, binding = 0) buffer VertexBuffer { Vertex vertices[]; }; +layout (std140, set = 0, binding = 5) uniform Sizes { + uint vertexCount; + uint faceCount; +}; + layout (std140, set = 1, binding = 0) uniform UBO { float dt; vec3 gravity; @@ -19,8 +24,29 @@ layout (std140, set = 1, binding = 0) uniform UBO { layout (push_constant) uniform PushConstants { uint state; + int vertexOffset; }; -void main() { +void preSolve(uint vID){ + vertices[vID].position += vec3(0.0001, 0, 0); +} +void postSolve(uint vID){ + vertices[vID].position += vec3(0, 0.0001, 0); +} + +void main() { + uint id = gl_GlobalInvocationID.x; + switch (state){ + case 0: + if (id < vertexCount){ + preSolve(id); + } + break; + case 2: + if (id < vertexCount){ + postSolve(id); + } + break; + } } \ No newline at end of file diff --git a/src/input.cpp b/src/input.cpp index d729724..b99bd9e 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -10,7 +10,7 @@ Input::Input(GLFWwindow *window) : window(window) { glfwSetWindowUserPointer(window, this); glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods){ - auto inputManager = reinterpret_cast(glfwGetWindowUserPointer(window)); + auto inputManager = static_cast(glfwGetWindowUserPointer(window)); if (action == GLFW_PRESS) inputManager->keyPressed(key); if (action == GLFW_RELEASE) @@ -18,13 +18,13 @@ Input::Input(GLFWwindow *window) : window(window) { }); glfwSetCursorPosCallback(window, [](GLFWwindow* window, double xpos, double ypos){ - auto inputManager = reinterpret_cast(glfwGetWindowUserPointer(window)); + auto inputManager = static_cast(glfwGetWindowUserPointer(window)); inputManager->mouseMoved(xpos, ypos); }); glfwGetCursorPos(window, &oldX, &oldY); glfwSetMouseButtonCallback(window, [](GLFWwindow* window, int button, int action, int mods){ - auto inputManager = reinterpret_cast(glfwGetWindowUserPointer(window)); + auto inputManager = static_cast(glfwGetWindowUserPointer(window)); if (action == GLFW_PRESS) inputManager->mouseButtonPressed(button); if (action == GLFW_RELEASE) diff --git a/src/simulation.cpp b/src/simulation.cpp index 21e565d..4f55697 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -7,6 +7,7 @@ #include "mesh.hpp" #include "constraints.hpp" #include "vulkan/descriptor_pool.hpp" +#include "timer.hpp" Simulation::Simulation() { createMeshBuffers(); @@ -49,14 +50,17 @@ void Simulation::recordDrawCommands() { VkBuffer buffers[] = {vertexBuffer->handle}; VkDeviceSize offsets[] = {0}; vkCmdBindVertexBuffers(cmdBuffer, 0, 1, buffers, offsets); - vkCmdBindIndexBuffer(cmdBuffer, faceBuffer->handle, 0, VK_INDEX_TYPE_UINT32); vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr); - vkCmdDrawIndexed(cmdBuffer, faceBuffer->size / sizeof(Face) * 3, 1, 0, 0, 0); + for (const auto &softBody : softBodies){ + vkCmdBindIndexBuffer(cmdBuffer, faceBuffer->handle, sizeof(uint32_t) * softBody->firstIndex, VK_INDEX_TYPE_UINT32); + vkCmdDrawIndexed(cmdBuffer, softBody->faces.size() * 3, 1, 0, 0, 0); + } + // vkCmdDrawIndexed(cmdBuffer, faceBuffer->size / sizeof(Face) * 3, 1, 0, 0, 0); } void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) { -#define BlOCK_SIZE 256 +#define BlOCK_SIZE 16 auto getGroupCount = [](uint32_t threads, uint32_t blockSize){ return (threads - 1) / blockSize + 1; @@ -65,28 +69,34 @@ void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) { uint32_t vertexGroupCount = getGroupCount(vertexBuffer->size / sizeof(Vertex), BlOCK_SIZE); uint32_t faceGroupCount = getGroupCount(faceBuffer->size / sizeof(Face), BlOCK_SIZE); - vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->handle); - VkMemoryBarrier barrier {}; barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->handle); vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr); - size_t subSteps = 1; + uint32_t state; + + size_t subSteps = 10; for (size_t i = 0; i < subSteps; i++){ + state = 0; + vkCmdPushConstants(cmdBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state); vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1); vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr); + /* uint32_t partitionCount = 1; for (uint32_t partition = 0; partition < partitionCount; partition++){ uint32_t partitionSize = 1; vkCmdDispatch(cmdBuffer, partitionSize, 1, 1); vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr); } - + */ + state = 2; + vkCmdPushConstants(cmdBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state); vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1); vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr); } @@ -94,7 +104,8 @@ void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) { vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->handle); vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr); - uint32_t state = 0; + + state = 0; vkCmdPushConstants(cmdBuffer, normalPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state); vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1); vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr); @@ -120,9 +131,16 @@ void Simulation::createMeshBuffers() { auto body = std::make_unique(&sphere, 0.3f); - for (size_t i = 0; i < 500; i++){ + for (size_t i = 0; i < 5; i++){ auto copy = std::make_unique(*body.get()); - copy->applyOffset({i / 2.f, 0, 0}); + copy->applyOffset({i * 2, 0, 0}); + softBodies.push_back(std::move(copy)); + } + + body = std::make_unique(&bunny, 0.3f); + for (size_t i = 0; i < 5; i++){ + auto copy = std::make_unique(*body.get()); + copy->applyOffset({i * 2, 2, 0}); softBodies.push_back(std::move(copy)); } @@ -168,7 +186,12 @@ void Simulation::createComputePipelines() { { layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]); - pbdPipeline = unique_ptr(new ComputePipeline("shaders/pbd.spv", layouts)); + pushRanges.push_back({ + .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, + .offset = 0, + .size = 2 * sizeof(uint32_t) + }); + pbdPipeline = unique_ptr(new ComputePipeline("shaders/pbd.spv", layouts, pushRanges)); } layouts.clear(); diff --git a/src/timer.cpp b/src/timer.cpp index 732d0d7..84c7e03 100644 --- a/src/timer.cpp +++ b/src/timer.cpp @@ -7,5 +7,5 @@ Timer::Timer() { Timer::~Timer() { size_t nanoseconds = (system_clock::now() - start).count(); - printf("Timer: %zu mus\n", nanoseconds / 1000); + printf("Timer: %zu μs\n", nanoseconds / 1000); }