|
|
|
@ -81,9 +81,11 @@ Application::Application() { |
|
|
|
|
bool grabbing; |
|
|
|
|
} initialGrabInformation {}; |
|
|
|
|
initialGrabInformation.distanceToFace = 1e20; |
|
|
|
|
grabBuffer = make_unique<Buffer>(sizeof(GrabInformation), &initialGrabInformation, sizeof(GrabInformation), |
|
|
|
|
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); |
|
|
|
|
grabBuffer = make_unique<Buffer>(sizeof(GrabInformation), |
|
|
|
|
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, |
|
|
|
|
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); |
|
|
|
|
grabBuffer->setName("Grab"); |
|
|
|
|
grabBuffer->setData(&initialGrabInformation, 0, sizeof(initialGrabInformation)); |
|
|
|
|
grabber = make_unique<Grabber>(); |
|
|
|
|
|
|
|
|
|
sizeInformationBuffer = make_unique<Buffer>( |
|
|
|
@ -93,8 +95,9 @@ Application::Application() { |
|
|
|
|
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); |
|
|
|
|
sizeInformationBuffer->setName("Sizes"); |
|
|
|
|
sizeInformation = &sizeInformationBuffer->access<SizesUniformData>(); |
|
|
|
|
*sizeInformation = {}; |
|
|
|
|
|
|
|
|
|
addSoftBody("models/bunny_medium.ply"); |
|
|
|
|
addSoftBody("models/bunny_medium.ply", 10); |
|
|
|
|
|
|
|
|
|
SimulationUniformData simulationUniformData { |
|
|
|
|
.gravity = {0, -9.81, 0}, |
|
|
|
@ -122,13 +125,6 @@ Application::Application() { |
|
|
|
|
descriptorPool->bindBuffer(*cameraUniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::WORLD, 0); |
|
|
|
|
descriptorPool->bindImage(*firstImage, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, DescriptorSet::WORLD, 2); |
|
|
|
|
|
|
|
|
|
descriptorPool->bindBuffer(*vertexBuffers[1 - currentDrawVertexBuffer], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 0); |
|
|
|
|
descriptorPool->bindBuffer(*faceBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 1); |
|
|
|
|
descriptorPool->bindBuffer(*edgeBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 2); |
|
|
|
|
// descriptorPool->bindBuffer(*triangleBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 3);
|
|
|
|
|
descriptorPool->bindBuffer(*tetrahedronBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 4); |
|
|
|
|
descriptorPool->bindBuffer(*sizeInformationBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::MESH, 5); |
|
|
|
|
|
|
|
|
|
descriptorPool->bindBuffer(*simulationPropertiesBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::SIMULATION, 0); |
|
|
|
|
descriptorPool->bindBuffer(*grabBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::SIMULATION, 1); |
|
|
|
|
|
|
|
|
@ -179,10 +175,12 @@ void Application::createSyncObjects() { |
|
|
|
|
transferSemaphore = make_unique<Semaphore>(); |
|
|
|
|
renderFence = make_unique<Fence>(true); |
|
|
|
|
computeFence = make_unique<Fence>(false); |
|
|
|
|
transferFence = make_unique<Fence>(false); |
|
|
|
|
computeTransferredFence = make_unique<Fence>(false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::addSoftBody(const std::string &modelFile, size_t count) { |
|
|
|
|
bufferWriteMutex.lock(); |
|
|
|
|
|
|
|
|
|
Mesh mesh(modelFile); |
|
|
|
|
|
|
|
|
|
// Do SoftBody calculations once in constructor, will be copied from now on
|
|
|
|
@ -242,25 +240,64 @@ void Application::addSoftBody(const std::string &modelFile, size_t count) { |
|
|
|
|
sizeInformation->vertexCount += newVertices.size(); |
|
|
|
|
sizeInformation->faceCount += newFaces.size(); |
|
|
|
|
|
|
|
|
|
auto commandBuffer = Instance::instance->renderingCommandPool->beginSingleTimeCommandBuffer(); |
|
|
|
|
vertexBuffers[0] = Buffer::Append(*vertexBuffers[0], newVertices.data(), newVertices.size() * sizeof(Vertex), commandBuffer); |
|
|
|
|
vertexBuffers[1] = Buffer::Append(*vertexBuffers[1], newVertices.data(), newVertices.size() * sizeof(Vertex), commandBuffer); |
|
|
|
|
faceBuffer = Buffer::Append(*faceBuffer, newFaces.data(), newFaces.size() * sizeof(Face), commandBuffer); |
|
|
|
|
edgeBuffer = Buffer::Replace(*edgeBuffer, constraintData.edges.data(), constraintData.edges.size() * sizeof(Edge), commandBuffer); |
|
|
|
|
// triangleBuffer = Buffer::Replace(*triangleBuffer, constraintData.triangles.data(), constraintData.triangles.size() * sizeof(Triangle), commandBuffer);
|
|
|
|
|
tetrahedronBuffer = Buffer::Replace(*tetrahedronBuffer, constraintData.tetrahedra.data(), constraintData.tetrahedra.size() * sizeof(Tetrahedron), commandBuffer); |
|
|
|
|
|
|
|
|
|
vertexBuffers[0] = make_unique<SimulationBuffer>(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); |
|
|
|
|
vertexBuffers[1] = make_unique<SimulationBuffer>(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); |
|
|
|
|
faceBuffer = make_unique<SimulationBuffer>(VK_BUFFER_USAGE_INDEX_BUFFER_BIT); |
|
|
|
|
unique_ptr<Buffer> newVertexBuffers[2]; |
|
|
|
|
unique_ptr<Buffer> newFaceBuffer; |
|
|
|
|
unique_ptr<Buffer> newEdgeBuffer; |
|
|
|
|
unique_ptr<Buffer> newTetrahedronBuffer; |
|
|
|
|
|
|
|
|
|
auto commandBuffer = Instance::instance->renderingCommandPool->beginSingleTimeCommandBuffer(); |
|
|
|
|
|
|
|
|
|
vertexBuffers[0]->setName("Vertices 0"); |
|
|
|
|
vertexBuffers[1]->setName("Vertices 1"); |
|
|
|
|
faceBuffer->setName("Faces"); |
|
|
|
|
VkBufferUsageFlags bufferUsageFlags = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT; |
|
|
|
|
VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; |
|
|
|
|
|
|
|
|
|
if (vertexBuffers[0] == nullptr){ |
|
|
|
|
newVertexBuffers[0] = make_unique<Buffer>(newVertices.size() * sizeof(Vertex), |
|
|
|
|
bufferUsageFlags | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, |
|
|
|
|
memoryUsage, 0); |
|
|
|
|
newVertexBuffers[1] = make_unique<Buffer>(newVertices.size() * sizeof(Vertex), |
|
|
|
|
bufferUsageFlags | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, |
|
|
|
|
memoryUsage, 0); |
|
|
|
|
newFaceBuffer = make_unique<Buffer>(newFaces.size() * sizeof(Face), |
|
|
|
|
bufferUsageFlags | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, |
|
|
|
|
memoryUsage, 0); |
|
|
|
|
newEdgeBuffer = make_unique<Buffer>(constraintData.edges.size() * sizeof(Edge), bufferUsageFlags, memoryUsage, 0); |
|
|
|
|
newTetrahedronBuffer = make_unique<Buffer>(constraintData.tetrahedra.size() * sizeof(Tetrahedron), bufferUsageFlags, memoryUsage, 0); |
|
|
|
|
|
|
|
|
|
newVertexBuffers[0]->setName("Vertices 0"); |
|
|
|
|
newVertexBuffers[1]->setName("Vertices 1"); |
|
|
|
|
newFaceBuffer->setName("Faces"); |
|
|
|
|
newEdgeBuffer->setName("Edges"); |
|
|
|
|
newTetrahedronBuffer->setName("Tetrahedra"); |
|
|
|
|
|
|
|
|
|
newVertexBuffers[0]->setData(newVertices.data(), 0, newVertexBuffers[0]->size, commandBuffer); |
|
|
|
|
newVertexBuffers[1]->setData(newVertices.data(), 0, newVertexBuffers[1]->size, commandBuffer); |
|
|
|
|
newFaceBuffer->setData(newFaces.data(), 0, newFaceBuffer->size, commandBuffer); |
|
|
|
|
newEdgeBuffer->setData(constraintData.edges.data(), 0, newEdgeBuffer->size, commandBuffer); |
|
|
|
|
newTetrahedronBuffer->setData(constraintData.tetrahedra.data(), 0, newTetrahedronBuffer->size, commandBuffer); |
|
|
|
|
} else { |
|
|
|
|
newVertexBuffers[0] = vertexBuffers[0]->appended(newVertices.data(), newVertices.size() * sizeof(Vertex), commandBuffer); |
|
|
|
|
newVertexBuffers[1] = vertexBuffers[1]->appended(newVertices.data(), newVertices.size() * sizeof(Vertex), commandBuffer); |
|
|
|
|
newFaceBuffer = faceBuffer->appended(newFaces.data(), newFaces.size() * sizeof(Face), commandBuffer); |
|
|
|
|
newEdgeBuffer = edgeBuffer->replaced(constraintData.edges.data(), constraintData.edges.size() * sizeof(Edge), commandBuffer); |
|
|
|
|
newTetrahedronBuffer = tetrahedronBuffer->replaced(constraintData.tetrahedra.data(), constraintData.tetrahedra.size() * sizeof(Tetrahedron), commandBuffer); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VkQueue queue = Instance::instance->graphicsAndPresentQueue; |
|
|
|
|
Instance::instance->renderingCommandPool->endSingleTimeCommandBuffer(commandBuffer, queue); |
|
|
|
|
|
|
|
|
|
vertexBuffers[0] = std::move(newVertexBuffers[0]); |
|
|
|
|
vertexBuffers[1] = std::move(newVertexBuffers[1]); |
|
|
|
|
faceBuffer = std::move(newFaceBuffer); |
|
|
|
|
edgeBuffer = std::move(newEdgeBuffer); |
|
|
|
|
tetrahedronBuffer = std::move(newTetrahedronBuffer); |
|
|
|
|
|
|
|
|
|
descriptorPool->bindBuffer(*vertexBuffers[1 - currentDrawVertexBuffer], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 0); |
|
|
|
|
descriptorPool->bindBuffer(*faceBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 1); |
|
|
|
|
descriptorPool->bindBuffer(*edgeBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 2); |
|
|
|
|
descriptorPool->bindBuffer(*tetrahedronBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 4); |
|
|
|
|
descriptorPool->bindBuffer(*sizeInformationBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::MESH, 5); |
|
|
|
|
|
|
|
|
|
bufferWriteMutex.unlock(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::removeSoftBody(const unique_ptr<SoftBody> &softBody) { |
|
|
|
@ -275,13 +312,14 @@ void Application::removeSoftBody(const unique_ptr<SoftBody> &softBody) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::updateConstraintBuffers(VkCommandBuffer commandBuffer) { |
|
|
|
|
edgeBuffer = make_unique<SimulationBuffer>(constraintData.edges.size() * sizeof(Edge), constraintData.edges.data()); |
|
|
|
|
// triangleBuffer = make_unique<SimulationBuffer>();
|
|
|
|
|
tetrahedronBuffer = make_unique<SimulationBuffer>(constraintData.tetrahedra.size() * sizeof(Tetrahedron), constraintData.tetrahedra.data()); |
|
|
|
|
/*
|
|
|
|
|
edgeBuffer = make_unique<Buffer>(constraintData.edges.size() * sizeof(Edge), constraintData.edges.data()); |
|
|
|
|
tetrahedronBuffer = make_unique<Buffer>(constraintData.tetrahedra.size() * sizeof(Tetrahedron), constraintData.tetrahedra.data()); |
|
|
|
|
|
|
|
|
|
edgeBuffer.value()->setName("Edges"); |
|
|
|
|
// triangleBuffer->setName("Triangles");
|
|
|
|
|
tetrahedronBuffer.value()->setName("Tetrahedra"); |
|
|
|
|
*/ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::createComputePipelines() { |
|
|
|
@ -365,7 +403,7 @@ void Application::drawFrame(float dt) { |
|
|
|
|
|
|
|
|
|
VkBufferMemoryBarrier vertexBufferBarrier{}; |
|
|
|
|
vertexBufferBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; |
|
|
|
|
vertexBufferBarrier.size = vertexBuffers[currentDrawVertexBuffer]->allocationInfo.size; |
|
|
|
|
vertexBufferBarrier.size = vertexBuffers[currentDrawVertexBuffer]->size; |
|
|
|
|
vertexBufferBarrier.offset = 0; |
|
|
|
|
vertexBufferBarrier.buffer = vertexBuffers[currentDrawVertexBuffer]->handle; |
|
|
|
|
vertexBufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; |
|
|
|
@ -474,6 +512,8 @@ void Application::recordDrawCommands(VkCommandBuffer commandBuffer) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::update() { |
|
|
|
|
bufferWriteMutex.lock(); |
|
|
|
|
|
|
|
|
|
VkCommandBufferBeginInfo beginInfo {}; |
|
|
|
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; |
|
|
|
|
beginInfo.flags = 0; |
|
|
|
@ -507,7 +547,7 @@ void Application::update() { |
|
|
|
|
vkBeginCommandBuffer(cmdBuffer, &beginInfo); |
|
|
|
|
|
|
|
|
|
VkBufferCopy copyRegion {}; |
|
|
|
|
copyRegion.size = vertexBuffers[1 - currentDrawVertexBuffer]->allocationInfo.size; |
|
|
|
|
copyRegion.size = vertexBuffers[1 - currentDrawVertexBuffer]->size; |
|
|
|
|
copyRegion.srcOffset = 0; |
|
|
|
|
copyRegion.dstOffset = 0; |
|
|
|
|
|
|
|
|
@ -526,7 +566,7 @@ void Application::update() { |
|
|
|
|
submit.pWaitDstStageMask = &waitStage; |
|
|
|
|
|
|
|
|
|
submitMutex.lock(); |
|
|
|
|
vkQueueSubmit(Instance::instance->computeAndTransferQueue, 1, &submit, transferFence->handle); |
|
|
|
|
vkQueueSubmit(Instance::instance->computeAndTransferQueue, 1, &submit, computeTransferredFence->handle); |
|
|
|
|
submitMutex.unlock(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -535,11 +575,13 @@ void Application::update() { |
|
|
|
|
|
|
|
|
|
currentDrawVertexBuffer = 1 - currentDrawVertexBuffer; |
|
|
|
|
|
|
|
|
|
vkWaitForFences(Instance::GetDevice(), 1, &transferFence->handle, VK_TRUE, UINT64_MAX); |
|
|
|
|
vkResetFences(Instance::GetDevice(), 1, &transferFence->handle); |
|
|
|
|
vkWaitForFences(Instance::GetDevice(), 1, &computeTransferredFence->handle, VK_TRUE, UINT64_MAX); |
|
|
|
|
vkResetFences(Instance::GetDevice(), 1, &computeTransferredFence->handle); |
|
|
|
|
|
|
|
|
|
currentDrawVertexBuffer = 1 - currentDrawVertexBuffer; |
|
|
|
|
// descriptorPool->bindBuffer(*vertexBuffers[1 - currentDrawVertexBuffer], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 0);
|
|
|
|
|
|
|
|
|
|
bufferWriteMutex.unlock(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint32_t Application::GetGroupCount(uint32_t threads, uint32_t blockSize) { |
|
|
|
@ -670,7 +712,7 @@ void Application::computePipelineBarrier(VkCommandBuffer commandBuffer) { |
|
|
|
|
VkBufferMemoryBarrier bufferMemoryBarrier {}; |
|
|
|
|
bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; |
|
|
|
|
bufferMemoryBarrier.buffer = buffer.handle; |
|
|
|
|
bufferMemoryBarrier.size = buffer.allocationInfo.size; |
|
|
|
|
bufferMemoryBarrier.size = buffer.size; |
|
|
|
|
bufferMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; |
|
|
|
|
bufferMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; |
|
|
|
|
bufferMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; |
|
|
|
|