|
|
@ -7,6 +7,7 @@ |
|
|
|
#include "mesh.hpp" |
|
|
|
#include "mesh.hpp" |
|
|
|
#include "constraints.hpp" |
|
|
|
#include "constraints.hpp" |
|
|
|
#include "vulkan/descriptor_pool.hpp" |
|
|
|
#include "vulkan/descriptor_pool.hpp" |
|
|
|
|
|
|
|
#include "timer.hpp" |
|
|
|
|
|
|
|
|
|
|
|
Simulation::Simulation() { |
|
|
|
Simulation::Simulation() { |
|
|
|
createMeshBuffers(); |
|
|
|
createMeshBuffers(); |
|
|
@ -49,14 +50,17 @@ void Simulation::recordDrawCommands() { |
|
|
|
VkBuffer buffers[] = {vertexBuffer->handle}; |
|
|
|
VkBuffer buffers[] = {vertexBuffer->handle}; |
|
|
|
VkDeviceSize offsets[] = {0}; |
|
|
|
VkDeviceSize offsets[] = {0}; |
|
|
|
vkCmdBindVertexBuffers(cmdBuffer, 0, 1, buffers, offsets); |
|
|
|
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); |
|
|
|
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) { |
|
|
|
void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) { |
|
|
|
#define BlOCK_SIZE 256 |
|
|
|
#define BlOCK_SIZE 16 |
|
|
|
|
|
|
|
|
|
|
|
auto getGroupCount = [](uint32_t threads, uint32_t blockSize){ |
|
|
|
auto getGroupCount = [](uint32_t threads, uint32_t blockSize){ |
|
|
|
return (threads - 1) / blockSize + 1; |
|
|
|
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 vertexGroupCount = getGroupCount(vertexBuffer->size / sizeof(Vertex), BlOCK_SIZE); |
|
|
|
uint32_t faceGroupCount = getGroupCount(faceBuffer->size / sizeof(Face), BlOCK_SIZE); |
|
|
|
uint32_t faceGroupCount = getGroupCount(faceBuffer->size / sizeof(Face), BlOCK_SIZE); |
|
|
|
|
|
|
|
|
|
|
|
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->handle); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkMemoryBarrier barrier {}; |
|
|
|
VkMemoryBarrier barrier {}; |
|
|
|
barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; |
|
|
|
barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; |
|
|
|
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; |
|
|
|
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; |
|
|
|
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | 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); |
|
|
|
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++){ |
|
|
|
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); |
|
|
|
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); |
|
|
|
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; |
|
|
|
uint32_t partitionCount = 1; |
|
|
|
for (uint32_t partition = 0; partition < partitionCount; partition++){ |
|
|
|
for (uint32_t partition = 0; partition < partitionCount; partition++){ |
|
|
|
uint32_t partitionSize = 1; |
|
|
|
uint32_t partitionSize = 1; |
|
|
|
vkCmdDispatch(cmdBuffer, partitionSize, 1, 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); |
|
|
|
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); |
|
|
|
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); |
|
|
|
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); |
|
|
|
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); |
|
|
|
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); |
|
|
|
vkCmdPushConstants(cmdBuffer, normalPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state); |
|
|
|
vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1); |
|
|
|
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); |
|
|
|
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<SoftBody>(&sphere, 0.3f); |
|
|
|
auto body = std::make_unique<SoftBody>(&sphere, 0.3f); |
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 500; i++){ |
|
|
|
for (size_t i = 0; i < 5; i++){ |
|
|
|
auto copy = std::make_unique<SoftBody>(*body.get()); |
|
|
|
auto copy = std::make_unique<SoftBody>(*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<SoftBody>(&bunny, 0.3f); |
|
|
|
|
|
|
|
for (size_t i = 0; i < 5; i++){ |
|
|
|
|
|
|
|
auto copy = std::make_unique<SoftBody>(*body.get()); |
|
|
|
|
|
|
|
copy->applyOffset({i * 2, 2, 0}); |
|
|
|
softBodies.push_back(std::move(copy)); |
|
|
|
softBodies.push_back(std::move(copy)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -168,7 +186,12 @@ void Simulation::createComputePipelines() { |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]); |
|
|
|
layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]); |
|
|
|
pbdPipeline = unique_ptr<ComputePipeline>(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<ComputePipeline>(new ComputePipeline("shaders/pbd.spv", layouts, pushRanges)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
layouts.clear(); |
|
|
|
layouts.clear(); |
|
|
|