code cleanup

main
Benjamin Kraft 3 months ago
parent 0cfc229226
commit c3ad1f7009
  1. 3
      include/vulkan/buffer.hpp
  2. 2
      lib/imgui
  3. 238
      src/application.cpp
  4. 12
      src/constraints.cpp
  5. 18
      src/input.cpp
  6. 15
      src/soft_body.cpp
  7. 1
      src/stb_image.cpp
  8. 36
      src/vulkan/buffer.cpp
  9. 11
      src/vulkan/descriptor_pool.cpp
  10. 31
      src/vulkan/image.cpp
  11. 7
      src/vulkan/instance.cpp
  12. 21
      src/vulkan/pipeline.cpp
  13. 20
      src/vulkan/swapchain.cpp
  14. 1
      src/vulkan/vma.cpp

@ -18,7 +18,8 @@ class Image;
class Buffer { class Buffer {
public: public:
Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsage, Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsage,
VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags vmaAllocationFlags); VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags vmaAllocationFlags,
const std::string& name="");
unique_ptr<Buffer> appended(void* data, VkDeviceSize appendSize, VkCommandBuffer commandBuffer) const; unique_ptr<Buffer> appended(void* data, VkDeviceSize appendSize, VkCommandBuffer commandBuffer) const;
unique_ptr<Buffer> replaced(void* data, VkDeviceSize replaceSize, VkCommandBuffer commandBuffer) const; unique_ptr<Buffer> replaced(void* data, VkDeviceSize replaceSize, VkCommandBuffer commandBuffer) const;
virtual ~Buffer(); virtual ~Buffer();

@ -1 +1 @@
Subproject commit 4e2126ee44c066c642d89d25320fd32e449e5a9a Subproject commit 646df390032f64eb03f8b5e2e5cbaf0c8e3bb237

@ -62,15 +62,21 @@ Application::Application() {
swapchain = make_unique<Swapchain>(); swapchain = make_unique<Swapchain>();
Instance::instance->initImGui(*swapchain); Instance::instance->initImGui(*swapchain);
descriptorPool = make_unique<DescriptorPool>(); descriptorPool = make_unique<DescriptorPool>();
graphicsPipeline = unique_ptr<GraphicsPipeline>(new GraphicsPipeline("shaders/vert.spv", "shaders/frag.spv", graphicsPipeline = unique_ptr<GraphicsPipeline>(
new GraphicsPipeline(
"shaders/vert.spv", "shaders/frag.spv",
swapchain->renderPass, swapchain->renderPass,
{descriptorPool->layouts[DescriptorSet::WORLD]})); {descriptorPool->layouts[DescriptorSet::WORLD]}
)
);
cameraUniformBuffer = make_unique<Buffer>(sizeof(CameraUniformData), cameraUniformBuffer = make_unique<Buffer>(
sizeof(CameraUniformData),
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
cameraUniformBuffer->setName("Camera"); "Camera"
);
camera = make_unique<Camera>(swapchain->extent); camera = make_unique<Camera>(swapchain->extent);
updateCameraBuffer(); updateCameraBuffer();
@ -81,10 +87,11 @@ Application::Application() {
bool grabbing; bool grabbing;
} initialGrabInformation {}; } initialGrabInformation {};
initialGrabInformation.distanceToFace = 1e20; initialGrabInformation.distanceToFace = 1e20;
grabBuffer = make_unique<Buffer>(sizeof(GrabInformation), grabBuffer = make_unique<Buffer>(
sizeof(GrabInformation),
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0, "Grab"
grabBuffer->setName("Grab"); );
grabBuffer->setData(&initialGrabInformation, 0, sizeof(initialGrabInformation)); grabBuffer->setData(&initialGrabInformation, 0, sizeof(initialGrabInformation));
grabber = make_unique<Grabber>(); grabber = make_unique<Grabber>();
@ -92,8 +99,9 @@ Application::Application() {
sizeof(SizesUniformData), sizeof(SizesUniformData),
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
sizeInformationBuffer->setName("Sizes"); "Sizes"
);
sizeInformation = &sizeInformationBuffer->access<SizesUniformData>(); sizeInformation = &sizeInformationBuffer->access<SizesUniformData>();
*sizeInformation = {}; *sizeInformation = {};
@ -109,15 +117,19 @@ Application::Application() {
sizeof(SimulationUniformData), sizeof(SimulationUniformData),
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
simulationPropertiesBuffer->setName("Simulation properties"); "Simulation properties"
);
simulationPropertiesBuffer->access<SimulationUniformData>() = simulationUniformData; simulationPropertiesBuffer->access<SimulationUniformData>() = simulationUniformData;
{ {
int w, h; int w, h;
stbi_uc *data = stbi_load("textures/rocky_diff.jpg", &w, &h, nullptr, STBI_rgb_alpha); stbi_uc *data = stbi_load("textures/rocky_diff.jpg", &w, &h, nullptr, STBI_rgb_alpha);
VkDeviceSize imageSize = w * h * 4; VkDeviceSize imageSize = w * h * 4;
firstImage = make_unique<Image>(data, imageSize, w, h, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); firstImage = make_unique<Image>(
data, imageSize, w, h, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
);
firstImage->createView(VK_IMAGE_ASPECT_COLOR_BIT); firstImage->createView(VK_IMAGE_ASPECT_COLOR_BIT);
firstImage->createSampler(); firstImage->createSampler();
} }
@ -125,7 +137,9 @@ Application::Application() {
descriptorPool->bindBuffer(*cameraUniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::WORLD, 0); descriptorPool->bindBuffer(*cameraUniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::WORLD, 0);
descriptorPool->bindImage(*firstImage, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, DescriptorSet::WORLD, 2); descriptorPool->bindImage(*firstImage, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, DescriptorSet::WORLD, 2);
descriptorPool->bindBuffer(*simulationPropertiesBuffer, 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); descriptorPool->bindBuffer(*grabBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::SIMULATION, 1);
createComputePipelines(); createComputePipelines();
@ -135,7 +149,8 @@ Application::Application() {
void Application::mainLoop() { void Application::mainLoop() {
vkDeviceWaitIdle(Instance::GetDevice()); vkDeviceWaitIdle(Instance::GetDevice());
std::future compute = std::async(std::launch::async, [this](){ std::future compute = std::async(
std::launch::async, [this]() {
while (!glfwWindowShouldClose(Instance::instance->window)) { while (!glfwWindowShouldClose(Instance::instance->window)) {
auto t1 = system_clock::now(); auto t1 = system_clock::now();
update(); update();
@ -143,13 +158,16 @@ void Application::mainLoop() {
auto measuredUpdateDuration = duration<float>(t2 - t1); auto measuredUpdateDuration = duration<float>(t2 - t1);
auto requestedUpdateDuration = duration<float>( auto requestedUpdateDuration = duration<float>(
simulationPropertiesBuffer->access<SimulationUniformData>().dt); simulationPropertiesBuffer->access<SimulationUniformData>().dt
);
std::this_thread::sleep_for(requestedUpdateDuration - measuredUpdateDuration); std::this_thread::sleep_for(requestedUpdateDuration - measuredUpdateDuration);
performanceInformation.updateDuration = measuredUpdateDuration.count(); performanceInformation.updateDuration = measuredUpdateDuration.count();
performanceInformation.recentTotalUpdateDurations.push(std::max(requestedUpdateDuration, measuredUpdateDuration).count()); performanceInformation.recentTotalUpdateDurations.push(
std::max(requestedUpdateDuration, measuredUpdateDuration).count());
} }
}); }
);
auto t1 = system_clock::now(); auto t1 = system_clock::now();
while (!glfwWindowShouldClose(Instance::instance->window)) { while (!glfwWindowShouldClose(Instance::instance->window)) {
@ -247,27 +265,37 @@ void Application::addSoftBody(const std::string &modelFile, size_t count) {
auto commandBuffer = Instance::instance->renderingCommandPool->beginSingleTimeCommandBuffer(); auto commandBuffer = Instance::instance->renderingCommandPool->beginSingleTimeCommandBuffer();
VkBufferUsageFlags bufferUsageFlags = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 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; VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
if (vertexBuffers[0] == nullptr) { if (vertexBuffers[0] == nullptr) {
newVertexBuffers[0] = make_unique<Buffer>(newVertices.size() * sizeof(Vertex), newVertexBuffers[0] = make_unique<Buffer>(
newVertices.size() * sizeof(Vertex),
bufferUsageFlags | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, bufferUsageFlags | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
memoryUsage, 0); memoryUsage, 0, "Vertices 0"
newVertexBuffers[1] = make_unique<Buffer>(newVertices.size() * sizeof(Vertex), );
newVertexBuffers[1] = make_unique<Buffer>(
newVertices.size() * sizeof(Vertex),
bufferUsageFlags | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, bufferUsageFlags | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
memoryUsage, 0); memoryUsage, 0, "Vertices 1"
newFaceBuffer = make_unique<Buffer>(newFaces.size() * sizeof(Face), );
newFaceBuffer = make_unique<Buffer>(
newFaces.size() * sizeof(Face),
bufferUsageFlags | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, bufferUsageFlags | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
memoryUsage, 0); memoryUsage, 0, "Faces"
newEdgeBuffer = make_unique<Buffer>(constraintData.edges.size() * sizeof(Edge), bufferUsageFlags, memoryUsage, 0); );
newTetrahedronBuffer = make_unique<Buffer>(constraintData.tetrahedra.size() * sizeof(Tetrahedron), bufferUsageFlags, memoryUsage, 0); newEdgeBuffer = make_unique<Buffer>(
constraintData.edges.size() * sizeof(Edge),
newVertexBuffers[0]->setName("Vertices 0"); bufferUsageFlags,
newVertexBuffers[1]->setName("Vertices 1"); memoryUsage,
newFaceBuffer->setName("Faces"); 0,
newEdgeBuffer->setName("Edges"); "Edges"
newTetrahedronBuffer->setName("Tetrahedra"); );
newTetrahedronBuffer = make_unique<Buffer>(
constraintData.tetrahedra.size() * sizeof(Tetrahedron), bufferUsageFlags, memoryUsage, 0,
"Tetrahedra"
);
newVertexBuffers[0]->setData(newVertices.data(), 0, newVertexBuffers[0]->size, commandBuffer); newVertexBuffers[0]->setData(newVertices.data(), 0, newVertexBuffers[0]->size, commandBuffer);
newVertexBuffers[1]->setData(newVertices.data(), 0, newVertexBuffers[1]->size, commandBuffer); newVertexBuffers[1]->setData(newVertices.data(), 0, newVertexBuffers[1]->size, commandBuffer);
@ -275,11 +303,19 @@ void Application::addSoftBody(const std::string &modelFile, size_t count) {
newEdgeBuffer->setData(constraintData.edges.data(), 0, newEdgeBuffer->size, commandBuffer); newEdgeBuffer->setData(constraintData.edges.data(), 0, newEdgeBuffer->size, commandBuffer);
newTetrahedronBuffer->setData(constraintData.tetrahedra.data(), 0, newTetrahedronBuffer->size, commandBuffer); newTetrahedronBuffer->setData(constraintData.tetrahedra.data(), 0, newTetrahedronBuffer->size, commandBuffer);
} else { } else {
newVertexBuffers[0] = vertexBuffers[0]->appended(newVertices.data(), newVertices.size() * sizeof(Vertex), commandBuffer); newVertexBuffers[0] = vertexBuffers[0]->appended(
newVertexBuffers[1] = vertexBuffers[1]->appended(newVertices.data(), newVertices.size() * sizeof(Vertex), commandBuffer); 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); newFaceBuffer = faceBuffer->appended(newFaces.data(), newFaces.size() * sizeof(Face), commandBuffer);
newEdgeBuffer = edgeBuffer->replaced(constraintData.edges.data(), constraintData.edges.size() * sizeof(Edge), commandBuffer); newEdgeBuffer = edgeBuffer->replaced(
newTetrahedronBuffer = tetrahedronBuffer->replaced(constraintData.tetrahedra.data(), constraintData.tetrahedra.size() * sizeof(Tetrahedron), commandBuffer); 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; VkQueue queue = Instance::instance->graphicsAndPresentQueue;
@ -291,7 +327,9 @@ void Application::addSoftBody(const std::string &modelFile, size_t count) {
edgeBuffer = std::move(newEdgeBuffer); edgeBuffer = std::move(newEdgeBuffer);
tetrahedronBuffer = std::move(newTetrahedronBuffer); tetrahedronBuffer = std::move(newTetrahedronBuffer);
descriptorPool->bindBuffer(*vertexBuffers[1 - currentDrawVertexBuffer], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 0); 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(*faceBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 1);
descriptorPool->bindBuffer(*edgeBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 2); descriptorPool->bindBuffer(*edgeBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 2);
descriptorPool->bindBuffer(*tetrahedronBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 4); descriptorPool->bindBuffer(*tetrahedronBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 4);
@ -330,11 +368,13 @@ void Application::createComputePipelines() {
layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]); layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]);
layouts.push_back(descriptorPool->layouts[DescriptorSet::WORLD]); layouts.push_back(descriptorPool->layouts[DescriptorSet::WORLD]);
layouts.push_back(descriptorPool->layouts[DescriptorSet::SIMULATION]); layouts.push_back(descriptorPool->layouts[DescriptorSet::SIMULATION]);
pushRanges.push_back({ pushRanges.push_back(
{
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
.offset = 0, .offset = 0,
.size = sizeof(GrabPushData) .size = sizeof(GrabPushData)
}); }
);
grabPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/grab.spv", layouts, pushRanges)); grabPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/grab.spv", layouts, pushRanges));
} }
@ -344,11 +384,13 @@ void Application::createComputePipelines() {
{ {
layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]); layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]);
layouts.push_back(descriptorPool->layouts[DescriptorSet::SIMULATION]); layouts.push_back(descriptorPool->layouts[DescriptorSet::SIMULATION]);
pushRanges.push_back({ pushRanges.push_back(
{
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
.offset = 0, .offset = 0,
.size = sizeof(PBDPushData) .size = sizeof(PBDPushData)
}); }
);
pbdPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/pbd.spv", layouts, pushRanges)); pbdPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/pbd.spv", layouts, pushRanges));
} }
@ -357,11 +399,13 @@ void Application::createComputePipelines() {
{ {
layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]); layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]);
pushRanges.push_back({ pushRanges.push_back(
{
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
.offset = 0, .offset = 0,
.size = sizeof(uint32_t) .size = sizeof(uint32_t)
}); }
);
normalPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/normal.spv", layouts, pushRanges)); normalPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/normal.spv", layouts, pushRanges));
} }
@ -379,7 +423,9 @@ void Application::drawFrame(float dt) {
vkWaitForFences(Instance::GetDevice(), 1, &renderFence->handle, VK_TRUE, UINT64_MAX); vkWaitForFences(Instance::GetDevice(), 1, &renderFence->handle, VK_TRUE, UINT64_MAX);
uint32_t imageIndex; uint32_t imageIndex;
VkResult result = vkAcquireNextImageKHR(Instance::GetDevice(), swapchain->handle, UINT64_MAX, imageAvailable->handle, VK_NULL_HANDLE, &imageIndex); VkResult result = vkAcquireNextImageKHR(
Instance::GetDevice(), swapchain->handle, UINT64_MAX, imageAvailable->handle, VK_NULL_HANDLE, &imageIndex
);
if (result == VK_ERROR_OUT_OF_DATE_KHR) { if (result == VK_ERROR_OUT_OF_DATE_KHR) {
submitMutex.lock(); submitMutex.lock();
swapchain->recreateSwapchain(); swapchain->recreateSwapchain();
@ -414,8 +460,10 @@ void Application::drawFrame(float dt) {
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; barrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 1, vkCmdPipelineBarrier(
&barrier, 1, &vertexBufferBarrier, 0, nullptr); cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 1,
&barrier, 1, &vertexBufferBarrier, 0, nullptr
);
VkRenderPassBeginInfo renderPassInfo {}; VkRenderPassBeginInfo renderPassInfo {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
@ -504,7 +552,10 @@ void Application::recordDrawCommands(VkCommandBuffer commandBuffer) {
VkDeviceSize offsets[] = {0}; VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, buffers, offsets); vkCmdBindVertexBuffers(commandBuffer, 0, 1, buffers, offsets);
vkCmdBindIndexBuffer(commandBuffer, faceBuffer->handle, 0, VK_INDEX_TYPE_UINT32); vkCmdBindIndexBuffer(commandBuffer, faceBuffer->handle, 0, VK_INDEX_TYPE_UINT32);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr); vkCmdBindDescriptorSets(
commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1,
&descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr
);
for (const auto &softBody: softBodies) { for (const auto &softBody: softBodies) {
vkCmdDrawIndexed(commandBuffer, softBody->faces.size() * 3, 1, softBody->firstIndex, 0, 0); vkCmdDrawIndexed(commandBuffer, softBody->faces.size() * 3, 1, softBody->firstIndex, 0, 0);
@ -551,7 +602,10 @@ void Application::update() {
copyRegion.srcOffset = 0; copyRegion.srcOffset = 0;
copyRegion.dstOffset = 0; copyRegion.dstOffset = 0;
vkCmdCopyBuffer(cmdBuffer, vertexBuffers[1 - currentDrawVertexBuffer]->handle, vertexBuffers[currentDrawVertexBuffer]->handle, 1, &copyRegion); vkCmdCopyBuffer(
cmdBuffer, vertexBuffers[1 - currentDrawVertexBuffer]->handle,
vertexBuffers[currentDrawVertexBuffer]->handle, 1, &copyRegion
);
vkEndCommandBuffer(cmdBuffer); vkEndCommandBuffer(cmdBuffer);
@ -592,16 +646,28 @@ void Application::recordGrabCommands(VkCommandBuffer commandBuffer) {
// TODO maybe add buffermemorybarrier for camera uniform, because it can be changed from main drawing thread // TODO maybe add buffermemorybarrier for camera uniform, because it can be changed from main drawing thread
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->handle); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->handle);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr); vkCmdBindDescriptorSets(
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 1, 1, &descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr); commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 0, 1,
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 2, 1, &descriptorPool->sets[DescriptorSet::SIMULATION], 0, nullptr); &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr
);
vkCmdBindDescriptorSets(
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 1, 1,
&descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr
);
vkCmdBindDescriptorSets(
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 2, 1,
&descriptorPool->sets[DescriptorSet::SIMULATION], 0, nullptr
);
GrabPushData pushConstants {}; GrabPushData pushConstants {};
if (grabber->started()) { if (grabber->started()) {
pushConstants.state = 0; pushConstants.state = 0;
pushConstants.screenPosition = grabber->previousCursorPosition; pushConstants.screenPosition = grabber->previousCursorPosition;
vkCmdPushConstants(commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData), &pushConstants); vkCmdPushConstants(
commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData),
&pushConstants
);
uint32_t faceInvocations = GetGroupCount(sizeInformation->faceCount, BLOCK_SIZE_GRAB); uint32_t faceInvocations = GetGroupCount(sizeInformation->faceCount, BLOCK_SIZE_GRAB);
@ -609,7 +675,10 @@ void Application::recordGrabCommands(VkCommandBuffer commandBuffer) {
computePipelineBarrier(commandBuffer); computePipelineBarrier(commandBuffer);
pushConstants.state = 1; pushConstants.state = 1;
vkCmdPushConstants(commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData), &pushConstants); vkCmdPushConstants(
commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData),
&pushConstants
);
vkCmdDispatch(commandBuffer, 1, 1, 1); vkCmdDispatch(commandBuffer, 1, 1, 1);
} }
@ -619,7 +688,10 @@ void Application::recordGrabCommands(VkCommandBuffer commandBuffer) {
if (grabber->moved(screenDelta)) { if (grabber->moved(screenDelta)) {
pushConstants.state = 2; pushConstants.state = 2;
pushConstants.screenDelta = screenDelta; pushConstants.screenDelta = screenDelta;
vkCmdPushConstants(commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData), &pushConstants); vkCmdPushConstants(
commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData),
&pushConstants
);
vkCmdDispatch(commandBuffer, 1, 1, 1); vkCmdDispatch(commandBuffer, 1, 1, 1);
} }
@ -627,7 +699,10 @@ void Application::recordGrabCommands(VkCommandBuffer commandBuffer) {
if (grabber->stopped()) { if (grabber->stopped()) {
pushConstants.state = 3; pushConstants.state = 3;
vkCmdPushConstants(commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData), &pushConstants); vkCmdPushConstants(
commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData),
&pushConstants
);
vkCmdDispatch(commandBuffer, 1, 1, 1); vkCmdDispatch(commandBuffer, 1, 1, 1);
} }
@ -638,8 +713,14 @@ void Application::recordPBDCommands(VkCommandBuffer commandBuffer) {
uint32_t vertexGroupCount = GetGroupCount(sizeInformation->vertexCount, BLOCK_SIZE_PBD); uint32_t vertexGroupCount = GetGroupCount(sizeInformation->vertexCount, BLOCK_SIZE_PBD);
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->handle); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->handle);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr); vkCmdBindDescriptorSets(
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->layout, 1, 1, &descriptorPool->sets[DescriptorSet::SIMULATION], 0, nullptr); commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->layout, 0, 1,
&descriptorPool->sets[DescriptorSet::MESH], 0, nullptr
);
vkCmdBindDescriptorSets(
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->layout, 1, 1,
&descriptorPool->sets[DescriptorSet::SIMULATION], 0, nullptr
);
uint32_t state; uint32_t state;
@ -647,12 +728,16 @@ void Application::recordPBDCommands(VkCommandBuffer commandBuffer) {
for (size_t i = 0; i < k; i++) { for (size_t i = 0; i < k; i++) {
state = 0; state = 0;
vkCmdPushConstants(commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state); vkCmdPushConstants(
commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state
);
vkCmdDispatch(commandBuffer, vertexGroupCount, 1, 1); vkCmdDispatch(commandBuffer, vertexGroupCount, 1, 1);
computePipelineBarrier(commandBuffer); computePipelineBarrier(commandBuffer);
state = 1; state = 1;
vkCmdPushConstants(commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state); vkCmdPushConstants(
commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state
);
for (uint32_t partition = 0; partition < constraintData.partitionCount; partition++) { for (uint32_t partition = 0; partition < constraintData.partitionCount; partition++) {
auto edgePartition = constraintData.edgePartitions[partition]; auto edgePartition = constraintData.edgePartitions[partition];
@ -663,9 +748,11 @@ void Application::recordPBDCommands(VkCommandBuffer commandBuffer) {
ConstraintData::Partition partitions[2] = {edgePartition, tetrahedronPartition}; ConstraintData::Partition partitions[2] = {edgePartition, tetrahedronPartition};
vkCmdPushConstants(commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, vkCmdPushConstants(
commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT,
offsetof(PBDPushData, edgePartition), offsetof(PBDPushData, edgePartition),
sizeof(partitions), partitions); sizeof(partitions), partitions
);
uint32_t invocations = GetGroupCount(edgePartition.size + tetrahedronPartition.size, BLOCK_SIZE_PBD); uint32_t invocations = GetGroupCount(edgePartition.size + tetrahedronPartition.size, BLOCK_SIZE_PBD);
vkCmdDispatch(commandBuffer, invocations, 1, 1); vkCmdDispatch(commandBuffer, invocations, 1, 1);
@ -673,7 +760,9 @@ void Application::recordPBDCommands(VkCommandBuffer commandBuffer) {
} }
state = 2; state = 2;
vkCmdPushConstants(commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state); vkCmdPushConstants(
commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state
);
vkCmdDispatch(commandBuffer, vertexGroupCount, 1, 1); vkCmdDispatch(commandBuffer, vertexGroupCount, 1, 1);
computePipelineBarrier(commandBuffer); computePipelineBarrier(commandBuffer);
} }
@ -684,7 +773,10 @@ void Application::recordNormalCommands(VkCommandBuffer commandBuffer) {
uint32_t faceGroupCount = GetGroupCount(sizeInformation->faceCount, BLOCK_SIZE_NORMAL); uint32_t faceGroupCount = GetGroupCount(sizeInformation->faceCount, BLOCK_SIZE_NORMAL);
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->handle); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->handle);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr); vkCmdBindDescriptorSets(
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->layout, 0, 1,
&descriptorPool->sets[DescriptorSet::MESH], 0, nullptr
);
uint32_t state = 0; uint32_t state = 0;
vkCmdPushConstants(commandBuffer, normalPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state); vkCmdPushConstants(commandBuffer, normalPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state);
@ -718,12 +810,14 @@ void Application::computePipelineBarrier(VkCommandBuffer commandBuffer) {
bufferMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; bufferMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufferMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; bufferMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vkCmdPipelineBarrier(commandBuffer, vkCmdPipelineBarrier(
commandBuffer,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
0, 0,
1, &memoryBarrier, 1, &memoryBarrier,
1, &bufferMemoryBarrier, 1, &bufferMemoryBarrier,
0, nullptr); 0, nullptr
);
} }
void Application::imGuiWindows() { void Application::imGuiWindows() {
@ -731,7 +825,8 @@ void Application::imGuiWindows() {
ImGui_ImplGlfw_NewFrame(); ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
ImGui::Begin("Performance"); { ImGui::Begin("Performance");
{
float updateMS = performanceInformation.updateDuration * 1000.f; float updateMS = performanceInformation.updateDuration * 1000.f;
float updateHZ = 1 / performanceInformation.recentTotalUpdateDurations.average(); float updateHZ = 1 / performanceInformation.recentTotalUpdateDurations.average();
ImGui::Text("Updates: %2.0fms | %.1fHz", updateMS, updateHZ); ImGui::Text("Updates: %2.0fms | %.1fHz", updateMS, updateHZ);
@ -739,14 +834,17 @@ void Application::imGuiWindows() {
float frameMS = performanceInformation.recentFrameDurations.average() * 1000.f; float frameMS = performanceInformation.recentFrameDurations.average() * 1000.f;
float frameHZ = 1 / performanceInformation.recentFrameDurations.average(); float frameHZ = 1 / performanceInformation.recentFrameDurations.average();
ImGui::Text("Frames: %.2fms | %.1fHz", frameMS, frameHZ); ImGui::Text("Frames: %.2fms | %.1fHz", frameMS, frameHZ);
} ImGui::End(); }
ImGui::End();
ImGui::Begin("Scene"); { ImGui::Begin("Scene");
{
if (ImGui::Button("Add")) { if (ImGui::Button("Add")) {
addSoftBody("models/bunny_medium.ply"); addSoftBody("models/bunny_medium.ply");
} }
for (const auto &softBody: softBodies) { for (const auto &softBody: softBodies) {
ImGui::Text("Some softbody"); ImGui::Text("Some softbody");
} }
} ImGui::End(); }
ImGui::End();
} }

@ -23,12 +23,16 @@ void ConstraintData::insert(const ConstraintData &other) {
tetrahedronPartitions[i].offset += other.tetrahedronPartitions[i].offset; tetrahedronPartitions[i].offset += other.tetrahedronPartitions[i].offset;
auto baseEdgeInsert = other.edges.begin() + other.edgePartitions[i].offset; auto baseEdgeInsert = other.edges.begin() + other.edgePartitions[i].offset;
edges.insert(edges.begin() + edgePartitions[i].offset + edgePartitions[i].size, edges.insert(
baseEdgeInsert, baseEdgeInsert + other.edgePartitions[i].size); edges.begin() + edgePartitions[i].offset + edgePartitions[i].size,
baseEdgeInsert, baseEdgeInsert + other.edgePartitions[i].size
);
auto baseTetrahedronInsert = other.tetrahedra.begin() + other.tetrahedronPartitions[i].offset; auto baseTetrahedronInsert = other.tetrahedra.begin() + other.tetrahedronPartitions[i].offset;
tetrahedra.insert(tetrahedra.begin() + tetrahedronPartitions[i].offset + tetrahedronPartitions[i].size, tetrahedra.insert(
baseTetrahedronInsert, baseTetrahedronInsert + other.tetrahedronPartitions[i].size); tetrahedra.begin() + tetrahedronPartitions[i].offset + tetrahedronPartitions[i].size,
baseTetrahedronInsert, baseTetrahedronInsert + other.tetrahedronPartitions[i].size
);
edgePartitions[i].size += other.edgePartitions[i].size; edgePartitions[i].size += other.edgePartitions[i].size;
tetrahedronPartitions[i].size += other.tetrahedronPartitions[i].size; tetrahedronPartitions[i].size += other.tetrahedronPartitions[i].size;

@ -9,30 +9,36 @@ Input::Input(GLFWwindow *window) : window(window) {
instance = this; instance = this;
glfwSetWindowUserPointer(window, this); glfwSetWindowUserPointer(window, this);
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods){ glfwSetKeyCallback(
window, [](GLFWwindow *window, int key, int scancode, int action, int mods) {
auto inputManager = static_cast<Input *>(glfwGetWindowUserPointer(window)); auto inputManager = static_cast<Input *>(glfwGetWindowUserPointer(window));
if (action == GLFW_PRESS) if (action == GLFW_PRESS)
inputManager->keyPressed(key); inputManager->keyPressed(key);
if (action == GLFW_RELEASE) if (action == GLFW_RELEASE)
inputManager->keyReleased(key); inputManager->keyReleased(key);
}); }
);
glfwSetCursorPosCallback(window, [](GLFWwindow* window, double xpos, double ypos){ glfwSetCursorPosCallback(
window, [](GLFWwindow *window, double xpos, double ypos) {
auto inputManager = static_cast<Input *>(glfwGetWindowUserPointer(window)); auto inputManager = static_cast<Input *>(glfwGetWindowUserPointer(window));
glm::vec2 newPosition = {static_cast<float>(xpos), static_cast<float>(ypos)}; glm::vec2 newPosition = {static_cast<float>(xpos), static_cast<float>(ypos)};
inputManager->mouseMoved(newPosition); inputManager->mouseMoved(newPosition);
}); }
);
double x = 0, y = 0; double x = 0, y = 0;
glfwGetCursorPos(window, &x, &y); glfwGetCursorPos(window, &x, &y);
currentCursorPosition = glm::vec2(static_cast<float>(x), static_cast<float>(y)); currentCursorPosition = glm::vec2(static_cast<float>(x), static_cast<float>(y));
glfwSetMouseButtonCallback(window, [](GLFWwindow* window, int button, int action, int mods){ glfwSetMouseButtonCallback(
window, [](GLFWwindow *window, int button, int action, int mods) {
auto inputManager = static_cast<Input *>(glfwGetWindowUserPointer(window)); auto inputManager = static_cast<Input *>(glfwGetWindowUserPointer(window));
if (action == GLFW_PRESS) if (action == GLFW_PRESS)
inputManager->mouseButtonPressed(button); inputManager->mouseButtonPressed(button);
if (action == GLFW_RELEASE) if (action == GLFW_RELEASE)
inputManager->mouseButtonReleased(button); inputManager->mouseButtonReleased(button);
}); }
);
} }
void Input::keyPressed(int key) { void Input::keyPressed(int key) {

@ -118,7 +118,8 @@ void SoftBody::applyVertexWorldOffset(const glm::vec3 &offset) {
} }
} }
vector<unordered_set<const Constraint *>> createPartitions(const Graph &graph, const vector<const Constraint *> &ordering){ vector<unordered_set<const Constraint *>>
createPartitions(const Graph &graph, const vector<const Constraint *> &ordering) {
unordered_map<const Constraint *, uint32_t> constraintToColor; unordered_map<const Constraint *, uint32_t> constraintToColor;
vector<unordered_set<const Constraint *>> colorToConstraintList; vector<unordered_set<const Constraint *>> colorToConstraintList;
@ -227,20 +228,24 @@ void SoftBody::splitConstraints() {
#pragma omp parallel for default(none) shared(findAdjacent, distanceConstraints) #pragma omp parallel for default(none) shared(findAdjacent, distanceConstraints)
for (const DistanceConstraint &distanceConstraint: distanceConstraints) { for (const DistanceConstraint &distanceConstraint: distanceConstraints) {
findAdjacent(&distanceConstraint, { findAdjacent(
&distanceConstraint, {
distanceConstraint.a, distanceConstraint.a,
distanceConstraint.b distanceConstraint.b
}); }
);
} }
#pragma omp parallel for default(none) shared(findAdjacent, volumeConstraints) #pragma omp parallel for default(none) shared(findAdjacent, volumeConstraints)
for (const VolumeConstraint &volumeConstraint: volumeConstraints) { for (const VolumeConstraint &volumeConstraint: volumeConstraints) {
findAdjacent(&volumeConstraint, { findAdjacent(
&volumeConstraint, {
volumeConstraint.a, volumeConstraint.a,
volumeConstraint.b, volumeConstraint.b,
volumeConstraint.c, volumeConstraint.c,
volumeConstraint.d, volumeConstraint.d,
}); }
);
} }
auto ordering = smallestLastOrdering(graph); auto ordering = smallestLastOrdering(graph);

@ -1,2 +1,3 @@
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" #include "stb_image.h"

@ -6,8 +6,12 @@
#include "vulkan/image.hpp" #include "vulkan/image.hpp"
#include "vk_mem_alloc.h" #include "vk_mem_alloc.h"
Buffer::Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsageFlags, VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags allocationFlags) Buffer::Buffer(
: size(bufferSize), bufferUsageFlags(bufferUsageFlags), memoryUsage(memoryUsage), allocationCreateFlags(allocationFlags) { VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsageFlags,
VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags allocationFlags, const std::string &name
)
: size(bufferSize), bufferUsageFlags(bufferUsageFlags), memoryUsage(memoryUsage),
allocationCreateFlags(allocationFlags) {
VkBufferCreateInfo bufferCreateInfo {}; VkBufferCreateInfo bufferCreateInfo {};
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@ -19,7 +23,11 @@ Buffer::Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsageFlags, Vma
allocationCreateInfo.usage = memoryUsage; allocationCreateInfo.usage = memoryUsage;
allocationCreateInfo.flags = allocationFlags; allocationCreateInfo.flags = allocationFlags;
vmaCreateBuffer(Instance::GetAllocator(), &bufferCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo); vmaCreateBuffer(
Instance::GetAllocator(), &bufferCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo
);
setName(name);
} }
Buffer::~Buffer() { Buffer::~Buffer() {
@ -96,7 +104,8 @@ void Buffer::setData(void *data, VkDeviceSize offset, VkDeviceSize dataSize, VkC
0, 0,
0, nullptr, 0, nullptr,
1, &bufferMemoryBarrier, 1, &bufferMemoryBarrier,
0, nullptr); 0, nullptr
);
VkBufferCopy region {}; VkBufferCopy region {};
region.srcOffset = offset; region.srcOffset = offset;
@ -106,7 +115,9 @@ void Buffer::setData(void *data, VkDeviceSize offset, VkDeviceSize dataSize, VkC
vkCmdCopyBuffer(commandBuffer, stagingBuffer->handle, handle, 1, &region); vkCmdCopyBuffer(commandBuffer, stagingBuffer->handle, handle, 1, &region);
if (singleShot) if (singleShot)
Instance::instance->renderingCommandPool->endSingleTimeCommandBuffer(commandBuffer, Instance::instance->graphicsAndPresentQueue); Instance::instance->renderingCommandPool->endSingleTimeCommandBuffer(
commandBuffer, Instance::instance->graphicsAndPresentQueue
);
} }
} }
@ -116,10 +127,12 @@ void Buffer::setName(const std::string &newName) {
} }
unique_ptr<Buffer> Buffer::appended(void *data, VkDeviceSize appendSize, VkCommandBuffer commandBuffer) const { unique_ptr<Buffer> Buffer::appended(void *data, VkDeviceSize appendSize, VkCommandBuffer commandBuffer) const {
auto buffer = make_unique<Buffer>(size + appendSize, auto buffer = make_unique<Buffer>(
size + appendSize,
bufferUsageFlags, bufferUsageFlags,
memoryUsage, memoryUsage,
allocationCreateFlags); allocationCreateFlags
);
buffer->setName(name); buffer->setName(name);
VkBufferCopy copyRegion {}; VkBufferCopy copyRegion {};
@ -134,10 +147,12 @@ unique_ptr<Buffer> Buffer::appended(void *data, VkDeviceSize appendSize, VkComma
} }
unique_ptr<Buffer> Buffer::replaced(void *data, VkDeviceSize replaceSize, VkCommandBuffer commandBuffer) const { unique_ptr<Buffer> Buffer::replaced(void *data, VkDeviceSize replaceSize, VkCommandBuffer commandBuffer) const {
auto buffer = make_unique<Buffer>(replaceSize, auto buffer = make_unique<Buffer>(
replaceSize,
bufferUsageFlags, bufferUsageFlags,
memoryUsage, memoryUsage,
allocationCreateFlags); allocationCreateFlags
);
buffer->setName(name); buffer->setName(name);
buffer->setData(data, 0, replaceSize, commandBuffer); buffer->setData(data, 0, replaceSize, commandBuffer);
@ -153,7 +168,8 @@ shared_ptr<Buffer> Buffer::getStagingBuffer() {
size, size,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VMA_MEMORY_USAGE_AUTO, VMA_MEMORY_USAGE_AUTO,
VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
);
stagingBufferOptional.value()->setName(name + " staging"); stagingBufferOptional.value()->setName(name + " staging");

@ -22,16 +22,21 @@ DescriptorPool::DescriptorPool() {
std::map<DescriptorSet, std::vector<VkDescriptorSetLayoutBinding>> setBindings; std::map<DescriptorSet, std::vector<VkDescriptorSetLayoutBinding>> setBindings;
auto addBinding = [&setBindings](DescriptorSet set, VkDescriptorType type, VkShaderStageFlags stageFlags) { auto addBinding = [&setBindings](DescriptorSet set, VkDescriptorType type, VkShaderStageFlags stageFlags) {
uint32_t binding = setBindings[set].size(); uint32_t binding = setBindings[set].size();
setBindings[set].push_back({ setBindings[set].push_back(
{
.binding = binding, .binding = binding,
.descriptorType = type, .descriptorType = type,
.descriptorCount = 1, .descriptorCount = 1,
.stageFlags = stageFlags .stageFlags = stageFlags
}); }
);
}; };
// camera // camera
addBinding(DescriptorSet::WORLD, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT); addBinding(
DescriptorSet::WORLD, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT
);
// lights // lights
addBinding(DescriptorSet::WORLD, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT); addBinding(DescriptorSet::WORLD, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
// texture // texture

@ -3,8 +3,10 @@
#include "vulkan/buffer.hpp" #include "vulkan/buffer.hpp"
#include "vulkan/command_pool.hpp" #include "vulkan/command_pool.hpp"
Image::Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, Image::Image(
VkImageUsageFlags usage) : format(format), width(width), height(height) { uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage
) : format(format), width(width), height(height) {
VkImageCreateInfo imageCreateInfo {}; VkImageCreateInfo imageCreateInfo {};
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
@ -25,14 +27,20 @@ Image::Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling til
allocationCreateInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; allocationCreateInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
allocationCreateInfo.flags = 0; allocationCreateInfo.flags = 0;
vmaCreateImage(Instance::GetAllocator(), &imageCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo); vmaCreateImage(
Instance::GetAllocator(), &imageCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo
);
} }
Image::Image(void *initialData, VkDeviceSize size, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, Image::Image(
VkImageUsageFlags usage) : Image(width, height, format, tiling, usage){ void *initialData, VkDeviceSize size, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage
) : Image(width, height, format, tiling, usage) {
Buffer stagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, Buffer stagingBuffer(
VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
);
stagingBuffer.setData(initialData, 0, size); stagingBuffer.setData(initialData, 0, size);
transitionLayout(VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); transitionLayout(VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
@ -122,7 +130,8 @@ void Image::transitionLayout(VkImageLayout oldLayout, VkImageLayout newLayout) {
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT; destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL){ } else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
@ -130,12 +139,14 @@ void Image::transitionLayout(VkImageLayout oldLayout, VkImageLayout newLayout) {
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
} }
vkCmdPipelineBarrier(commandBuffer, vkCmdPipelineBarrier(
commandBuffer,
sourceStage, destinationStage, sourceStage, destinationStage,
0, 0,
0, nullptr, 0, nullptr,
0, nullptr, 0, nullptr,
1, &barrier); 1, &barrier
);
commandPool->endSingleTimeCommandBuffer(commandBuffer, Instance::instance->graphicsAndPresentQueue); commandPool->endSingleTimeCommandBuffer(commandBuffer, Instance::instance->graphicsAndPresentQueue);
} }

@ -86,9 +86,11 @@ void Instance::initWindow() {
glfwGetMonitorPos(monitor, &x, &y); glfwGetMonitorPos(monitor, &x, &y);
window = glfwCreateWindow(800, 600, "Vulkan Simulation", nullptr, nullptr); window = glfwCreateWindow(800, 600, "Vulkan Simulation", nullptr, nullptr);
glfwSetWindowPos(window, x, y); glfwSetWindowPos(window, x, y);
glfwSetFramebufferSizeCallback(window, [](GLFWwindow* window, int width, int height) { glfwSetFramebufferSizeCallback(
window, [](GLFWwindow *window, int width, int height) {
instance->windowResized = true; instance->windowResized = true;
}); }
);
} }
void Instance::createInstance() { void Instance::createInstance() {
@ -193,6 +195,7 @@ void Instance::createLogicalDevice() {
} }
#include <fstream> #include <fstream>
void printVmaStats() { void printVmaStats() {
char *stats; char *stats;
vmaBuildStatsString(Instance::GetAllocator(), &stats, VK_TRUE); vmaBuildStatsString(Instance::GetAllocator(), &stats, VK_TRUE);

@ -33,8 +33,10 @@ VkShaderModule Pipeline::createShaderModule(const std::vector<char> &code) {
return shaderModule; return shaderModule;
} }
Pipeline::Pipeline(const std::vector<VkDescriptorSetLayout> &descriptorSetLayouts, Pipeline::Pipeline(
const std::vector<VkPushConstantRange> &pushConstantRanges) { const std::vector<VkDescriptorSetLayout> &descriptorSetLayouts,
const std::vector<VkPushConstantRange> &pushConstantRanges
) {
VkPipelineLayoutCreateInfo pipelineLayoutInfo {}; VkPipelineLayoutCreateInfo pipelineLayoutInfo {};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = descriptorSetLayouts.size(); pipelineLayoutInfo.setLayoutCount = descriptorSetLayouts.size();
@ -51,10 +53,12 @@ Pipeline::~Pipeline() {
} }
GraphicsPipeline::GraphicsPipeline(const std::string& vertexShaderPath, const std::string& fragmentShaderPath, GraphicsPipeline::GraphicsPipeline(
const std::string &vertexShaderPath, const std::string &fragmentShaderPath,
VkRenderPass renderPass, VkRenderPass renderPass,
const std::vector<VkDescriptorSetLayout> &descriptorSetLayouts, const std::vector<VkDescriptorSetLayout> &descriptorSetLayouts,
const std::vector<VkPushConstantRange> &pushConstantRanges) : Pipeline(descriptorSetLayouts, pushConstantRanges) { const std::vector<VkPushConstantRange> &pushConstantRanges
) : Pipeline(descriptorSetLayouts, pushConstantRanges) {
auto vertShaderCode = readFile(vertexShaderPath); auto vertShaderCode = readFile(vertexShaderPath);
auto fragShaderCode = readFile(fragmentShaderPath); auto fragShaderCode = readFile(fragmentShaderPath);
@ -122,7 +126,8 @@ GraphicsPipeline::GraphicsPipeline(const std::string& vertexShaderPath, const st
multisample.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; multisample.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
VkPipelineColorBlendAttachmentState colorBlendAttachment {}; VkPipelineColorBlendAttachmentState colorBlendAttachment {};
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; colorBlendAttachment.colorWriteMask =
VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
colorBlendAttachment.blendEnable = VK_FALSE; colorBlendAttachment.blendEnable = VK_FALSE;
VkPipelineColorBlendStateCreateInfo colorBlending {}; VkPipelineColorBlendStateCreateInfo colorBlending {};
@ -166,9 +171,11 @@ GraphicsPipeline::GraphicsPipeline(const std::string& vertexShaderPath, const st
vkDestroyShaderModule(Instance::GetDevice(), fragShaderModule, nullptr); vkDestroyShaderModule(Instance::GetDevice(), fragShaderModule, nullptr);
} }
ComputePipeline::ComputePipeline(const std::string& shaderFile, ComputePipeline::ComputePipeline(
const std::string &shaderFile,
const std::vector<VkDescriptorSetLayout> &descriptorSetLayouts, const std::vector<VkDescriptorSetLayout> &descriptorSetLayouts,
const std::vector<VkPushConstantRange> &pushConstantRanges) : Pipeline(descriptorSetLayouts, pushConstantRanges) { const std::vector<VkPushConstantRange> &pushConstantRanges
) : Pipeline(descriptorSetLayouts, pushConstantRanges) {
VkShaderModule module = createShaderModule(readFile(shaderFile)); VkShaderModule module = createShaderModule(readFile(shaderFile));
VkPipelineShaderStageCreateInfo stageInfo {}; VkPipelineShaderStageCreateInfo stageInfo {};

@ -51,15 +51,20 @@ VkExtent2D Swapchain::chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilit
static_cast<uint32_t>(height) static_cast<uint32_t>(height)
}; };
actualExtent.width = std::clamp(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width); actualExtent.width = std::clamp(
actualExtent.height = std::clamp(actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height); actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width
);
actualExtent.height = std::clamp(
actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height
);
return actualExtent; return actualExtent;
} }
} }
void Swapchain::createSwapchain() { void Swapchain::createSwapchain() {
SwapchainSupportDetails swapchainSupport = querySwapchainSupport(Instance::GetPhysicalDevice(), Instance::GetSurface()); SwapchainSupportDetails swapchainSupport = querySwapchainSupport(
Instance::GetPhysicalDevice(), Instance::GetSurface());
VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapchainSupport.formats); VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapchainSupport.formats);
VkPresentModeKHR presentMode = chooseSwapPresentMode(swapchainSupport.presentModes); VkPresentModeKHR presentMode = chooseSwapPresentMode(swapchainSupport.presentModes);
@ -178,9 +183,11 @@ void Swapchain::createRenderpass() {
VkSubpassDependency dependency {}; VkSubpassDependency dependency {};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0; dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; dependency.srcStageMask =
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.srcAccessMask = 0; dependency.srcAccessMask = 0;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; dependency.dstStageMask =
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
VkRenderPassCreateInfo renderPassInfo {}; VkRenderPassCreateInfo renderPassInfo {};
@ -229,7 +236,8 @@ void Swapchain::createFramebuffers() {
VkSurfaceFormatKHR Swapchain::chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR> &availableFormats) { VkSurfaceFormatKHR Swapchain::chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR> &availableFormats) {
for (const auto &availableFormat: availableFormats) { for (const auto &availableFormat: availableFormats) {
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR){ if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB &&
availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
return availableFormat; return availableFormat;
} }
} }

@ -1,2 +1,3 @@
#define VMA_IMPLEMENTATION #define VMA_IMPLEMENTATION
#include "vk_mem_alloc.h" #include "vk_mem_alloc.h"
Loading…
Cancel
Save