code cleanup

main
Benjamin Kraft 3 months ago
parent 0cfc229226
commit c3ad1f7009
  1. 3
      include/vulkan/buffer.hpp
  2. 2
      lib/imgui
  3. 292
      src/application.cpp
  4. 4
      src/camera.cpp
  5. 18
      src/constraints.cpp
  6. 4
      src/grabber.cpp
  7. 40
      src/input.cpp
  8. 12
      src/mesh.cpp
  9. 69
      src/soft_body.cpp
  10. 1
      src/stb_image.cpp
  11. 46
      src/vulkan/buffer.cpp
  12. 21
      src/vulkan/descriptor_pool.cpp
  13. 33
      src/vulkan/image.cpp
  14. 45
      src/vulkan/instance.cpp
  15. 25
      src/vulkan/pipeline.cpp
  16. 40
      src/vulkan/swapchain.cpp
  17. 1
      src/vulkan/vma.cpp

@ -18,7 +18,8 @@ class Image;
class Buffer {
public:
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> replaced(void* data, VkDeviceSize replaceSize, VkCommandBuffer commandBuffer) const;
virtual ~Buffer();

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

@ -62,15 +62,21 @@ Application::Application() {
swapchain = make_unique<Swapchain>();
Instance::instance->initImGui(*swapchain);
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,
{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,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT);
cameraUniformBuffer->setName("Camera");
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
"Camera"
);
camera = make_unique<Camera>(swapchain->extent);
updateCameraBuffer();
@ -81,10 +87,11 @@ Application::Application() {
bool grabbing;
} initialGrabInformation {};
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,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0);
grabBuffer->setName("Grab");
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0, "Grab"
);
grabBuffer->setData(&initialGrabInformation, 0, sizeof(initialGrabInformation));
grabber = make_unique<Grabber>();
@ -92,8 +99,9 @@ Application::Application() {
sizeof(SizesUniformData),
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);
sizeInformationBuffer->setName("Sizes");
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
"Sizes"
);
sizeInformation = &sizeInformationBuffer->access<SizesUniformData>();
*sizeInformation = {};
@ -109,15 +117,19 @@ Application::Application() {
sizeof(SimulationUniformData),
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);
simulationPropertiesBuffer->setName("Simulation properties");
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
"Simulation properties"
);
simulationPropertiesBuffer->access<SimulationUniformData>() = simulationUniformData;
{
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;
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->createSampler();
}
@ -125,7 +137,9 @@ 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(*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);
createComputePipelines();
@ -135,24 +149,28 @@ Application::Application() {
void Application::mainLoop() {
vkDeviceWaitIdle(Instance::GetDevice());
std::future compute = std::async(std::launch::async, [this](){
while (!glfwWindowShouldClose(Instance::instance->window)){
std::future compute = std::async(
std::launch::async, [this]() {
while (!glfwWindowShouldClose(Instance::instance->window)) {
auto t1 = system_clock::now();
update();
auto t2 = system_clock::now();
auto measuredUpdateDuration = duration<float>(t2 - t1);
auto requestedUpdateDuration = duration<float>(
simulationPropertiesBuffer->access<SimulationUniformData>().dt);
simulationPropertiesBuffer->access<SimulationUniformData>().dt
);
std::this_thread::sleep_for(requestedUpdateDuration - measuredUpdateDuration);
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();
while (!glfwWindowShouldClose(Instance::instance->window)){
while (!glfwWindowShouldClose(Instance::instance->window)) {
glfwPollEvents();
imGuiWindows();
@ -189,7 +207,7 @@ void Application::addSoftBody(const std::string &modelFile, size_t count) {
vector<Vertex> newVertices;
vector<Face> newFaces;
for (size_t i = 0; i < count; i++){
for (size_t i = 0; i < count; i++) {
// Local copy
auto softBody = std::make_unique<SoftBody>(*original.get());
@ -205,21 +223,21 @@ void Application::addSoftBody(const std::string &modelFile, size_t count) {
// Vertex offset added manually for easy access in Compute Shaders
{
auto vertexOffset = softBody->vertexOffset;
for (auto &face : softBody->faces){
for (auto &face: softBody->faces) {
face.a += vertexOffset;
face.b += vertexOffset;
face.c += vertexOffset;
}
for (auto &edge : softBody->constraintData.edges){
for (auto &edge: softBody->constraintData.edges) {
edge.a += vertexOffset;
edge.b += vertexOffset;
}
for (auto &triangle : softBody->constraintData.triangles){
for (auto &triangle: softBody->constraintData.triangles) {
triangle.a += vertexOffset;
triangle.b += vertexOffset;
triangle.c += vertexOffset;
}
for (auto &tetrahedron : softBody->constraintData.tetrahedra){
for (auto &tetrahedron: softBody->constraintData.tetrahedra) {
tetrahedron.a += vertexOffset;
tetrahedron.b += vertexOffset;
tetrahedron.c += vertexOffset;
@ -247,27 +265,37 @@ void Application::addSoftBody(const std::string &modelFile, size_t count) {
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;
if (vertexBuffers[0] == nullptr){
newVertexBuffers[0] = make_unique<Buffer>(newVertices.size() * sizeof(Vertex),
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),
memoryUsage, 0, "Vertices 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),
memoryUsage, 0, "Vertices 1"
);
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");
memoryUsage, 0, "Faces"
);
newEdgeBuffer = make_unique<Buffer>(
constraintData.edges.size() * sizeof(Edge),
bufferUsageFlags,
memoryUsage,
0,
"Edges"
);
newTetrahedronBuffer = make_unique<Buffer>(
constraintData.tetrahedra.size() * sizeof(Tetrahedron), bufferUsageFlags, memoryUsage, 0,
"Tetrahedra"
);
newVertexBuffers[0]->setData(newVertices.data(), 0, newVertexBuffers[0]->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);
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);
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);
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;
@ -291,7 +327,9 @@ void Application::addSoftBody(const std::string &modelFile, size_t count) {
edgeBuffer = std::move(newEdgeBuffer);
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(*edgeBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 2);
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::WORLD]);
layouts.push_back(descriptorPool->layouts[DescriptorSet::SIMULATION]);
pushRanges.push_back({
pushRanges.push_back(
{
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
.offset = 0,
.size = sizeof(GrabPushData)
});
}
);
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::SIMULATION]);
pushRanges.push_back({
pushRanges.push_back(
{
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
.offset = 0,
.size = sizeof(PBDPushData)
});
}
);
pbdPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/pbd.spv", layouts, pushRanges));
}
@ -357,18 +399,20 @@ void Application::createComputePipelines() {
{
layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]);
pushRanges.push_back({
pushRanges.push_back(
{
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
.offset = 0,
.size = sizeof(uint32_t)
});
}
);
normalPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/normal.spv", layouts, pushRanges));
}
}
void Application::updateCameraBuffer() {
CameraUniformData& data = cameraUniformBuffer->access<CameraUniformData>();
CameraUniformData &data = cameraUniformBuffer->access<CameraUniformData>();
data.view = camera->view();
data.projection = camera->projection();
data.projection[1][1] *= -1;
@ -379,8 +423,10 @@ void Application::drawFrame(float dt) {
vkWaitForFences(Instance::GetDevice(), 1, &renderFence->handle, VK_TRUE, UINT64_MAX);
uint32_t imageIndex;
VkResult result = vkAcquireNextImageKHR(Instance::GetDevice(), swapchain->handle, UINT64_MAX, imageAvailable->handle, VK_NULL_HANDLE, &imageIndex);
if (result == VK_ERROR_OUT_OF_DATE_KHR){
VkResult result = vkAcquireNextImageKHR(
Instance::GetDevice(), swapchain->handle, UINT64_MAX, imageAvailable->handle, VK_NULL_HANDLE, &imageIndex
);
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
submitMutex.lock();
swapchain->recreateSwapchain();
submitMutex.unlock();
@ -396,12 +442,12 @@ void Application::drawFrame(float dt) {
{
vkResetCommandBuffer(cmdBuffer, 0);
VkCommandBufferBeginInfo beginInfo{};
VkCommandBufferBeginInfo beginInfo {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
vkBeginCommandBuffer(cmdBuffer, &beginInfo);
VkBufferMemoryBarrier vertexBufferBarrier{};
VkBufferMemoryBarrier vertexBufferBarrier {};
vertexBufferBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
vertexBufferBarrier.size = vertexBuffers[currentDrawVertexBuffer]->size;
vertexBufferBarrier.offset = 0;
@ -414,17 +460,19 @@ void Application::drawFrame(float dt) {
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_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,
&barrier, 1, &vertexBufferBarrier, 0, nullptr);
vkCmdPipelineBarrier(
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.renderPass = swapchain->renderPass;
renderPassInfo.framebuffer = swapchain->frameBuffers[imageIndex];
renderPassInfo.renderArea.offset = {0, 0};
renderPassInfo.renderArea.extent = swapchain->extent;
VkClearValue clearValues[2]{};
VkClearValue clearValues[2] {};
clearValues[0].color = {{0, 0, 0, 1}};
clearValues[1].depthStencil = {1.0f, 0};
@ -433,7 +481,7 @@ void Application::drawFrame(float dt) {
vkCmdBeginRenderPass(cmdBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
VkViewport viewport{};
VkViewport viewport {};
viewport.x = 0;
viewport.y = 0;
viewport.width = static_cast<float>(swapchain->extent.width);
@ -442,7 +490,7 @@ void Application::drawFrame(float dt) {
viewport.maxDepth = 1;
vkCmdSetViewport(cmdBuffer, 0, 1, &viewport);
VkRect2D scissor{};
VkRect2D scissor {};
scissor.offset = {0, 0};
scissor.extent = swapchain->extent;
vkCmdSetScissor(cmdBuffer, 0, 1, &scissor);
@ -489,7 +537,7 @@ void Application::drawFrame(float dt) {
result = vkQueuePresentKHR(Instance::instance->graphicsAndPresentQueue, &presentInfo);
submitMutex.unlock();
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || Instance::instance->windowResized){
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || Instance::instance->windowResized) {
Instance::instance->windowResized = false;
submitMutex.lock();
swapchain->recreateSwapchain();
@ -504,9 +552,12 @@ void Application::recordDrawCommands(VkCommandBuffer commandBuffer) {
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, buffers, offsets);
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);
}
}
@ -551,7 +602,10 @@ void Application::update() {
copyRegion.srcOffset = 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);
@ -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
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(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);
vkCmdBindDescriptorSets(
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 0, 1,
&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 {};
if (grabber->started()){
if (grabber->started()) {
pushConstants.state = 0;
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);
@ -609,25 +675,34 @@ void Application::recordGrabCommands(VkCommandBuffer commandBuffer) {
computePipelineBarrier(commandBuffer);
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);
}
computePipelineBarrier(commandBuffer);
glm::vec2 screenDelta;
if (grabber->moved(screenDelta)){
if (grabber->moved(screenDelta)) {
pushConstants.state = 2;
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);
}
computePipelineBarrier(commandBuffer);
if (grabber->stopped()){
if (grabber->stopped()) {
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);
}
@ -638,23 +713,33 @@ void Application::recordPBDCommands(VkCommandBuffer commandBuffer) {
uint32_t vertexGroupCount = GetGroupCount(sizeInformation->vertexCount, BLOCK_SIZE_PBD);
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(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->layout, 1, 1, &descriptorPool->sets[DescriptorSet::SIMULATION], 0, nullptr);
vkCmdBindDescriptorSets(
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 k = simulationPropertiesBuffer->access<SimulationUniformData>().k;
for (size_t i = 0; i < k; i++){
for (size_t i = 0; i < k; i++) {
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);
computePipelineBarrier(commandBuffer);
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 tetrahedronPartition = constraintData.tetrahedronPartitions[partition];
@ -663,9 +748,11 @@ void Application::recordPBDCommands(VkCommandBuffer commandBuffer) {
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),
sizeof(partitions), partitions);
sizeof(partitions), partitions
);
uint32_t invocations = GetGroupCount(edgePartition.size + tetrahedronPartition.size, BLOCK_SIZE_PBD);
vkCmdDispatch(commandBuffer, invocations, 1, 1);
@ -673,7 +760,9 @@ void Application::recordPBDCommands(VkCommandBuffer commandBuffer) {
}
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);
computePipelineBarrier(commandBuffer);
}
@ -684,7 +773,10 @@ void Application::recordNormalCommands(VkCommandBuffer commandBuffer) {
uint32_t faceGroupCount = GetGroupCount(sizeInformation->faceCount, BLOCK_SIZE_NORMAL);
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;
vkCmdPushConstants(commandBuffer, normalPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state);
@ -708,7 +800,7 @@ void Application::computePipelineBarrier(VkCommandBuffer commandBuffer) {
memoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
const Buffer& buffer = *vertexBuffers[1 - currentDrawVertexBuffer];
const Buffer &buffer = *vertexBuffers[1 - currentDrawVertexBuffer];
VkBufferMemoryBarrier bufferMemoryBarrier {};
bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
bufferMemoryBarrier.buffer = buffer.handle;
@ -718,12 +810,14 @@ void Application::computePipelineBarrier(VkCommandBuffer commandBuffer) {
bufferMemoryBarrier.srcQueueFamilyIndex = 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,
0,
1, &memoryBarrier,
1, &bufferMemoryBarrier,
0, nullptr);
0, nullptr
);
}
void Application::imGuiWindows() {
@ -731,7 +825,8 @@ void Application::imGuiWindows() {
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::Begin("Performance"); {
ImGui::Begin("Performance");
{
float updateMS = performanceInformation.updateDuration * 1000.f;
float updateHZ = 1 / performanceInformation.recentTotalUpdateDurations.average();
ImGui::Text("Updates: %2.0fms | %.1fHz", updateMS, updateHZ);
@ -739,14 +834,17 @@ void Application::imGuiWindows() {
float frameMS = performanceInformation.recentFrameDurations.average() * 1000.f;
float frameHZ = 1 / performanceInformation.recentFrameDurations.average();
ImGui::Text("Frames: %.2fms | %.1fHz", frameMS, frameHZ);
} ImGui::End();
}
ImGui::End();
ImGui::Begin("Scene"); {
if (ImGui::Button("Add")){
ImGui::Begin("Scene");
{
if (ImGui::Button("Add")) {
addSoftBody("models/bunny_medium.ply");
}
for (const auto &softBody: softBodies){
for (const auto &softBody: softBodies) {
ImGui::Text("Some softbody");
}
} ImGui::End();
}
ImGui::End();
}

@ -16,7 +16,7 @@ const std::map<int, glm::vec3> moveDirections {
void Camera::update(float dt) {
glm::vec3 velocity {};
for (const auto &[key, dir] : moveDirections)
for (const auto &[key, dir]: moveDirections)
if (Input::KeyIsDown[key])
velocity += dir;
@ -50,7 +50,7 @@ glm::vec2 Camera::viewport() const {
return glm::vec2(static_cast<float>(extent.width), static_cast<float>(extent.height));
}
glm::vec3 Camera::localToWorld(const glm::vec3& direction) const {
glm::vec3 Camera::localToWorld(const glm::vec3 &direction) const {
float x = glm::sin(phi) * glm::cos(theta);
float y = glm::sin(theta);
float z = -glm::cos(phi) * glm::cos(theta);

@ -11,31 +11,35 @@ void ConstraintData::writePartitionInformation() {
}
void ConstraintData::insert(const ConstraintData &other) {
if (other.partitionCount > partitionCount){
if (other.partitionCount > partitionCount) {
edgePartitions.resize(other.partitionCount);
tetrahedronPartitions.resize(other.partitionCount);
}
// insert constraints, increase partition offsets and sizes
for (size_t i = 0; i < other.partitionCount; i++){
for (size_t i = 0; i < other.partitionCount; i++) {
edgePartitions[i].offset += other.edgePartitions[i].offset;
tetrahedronPartitions[i].offset += other.tetrahedronPartitions[i].offset;
auto baseEdgeInsert = other.edges.begin() + other.edgePartitions[i].offset;
edges.insert(edges.begin() + edgePartitions[i].offset + edgePartitions[i].size,
baseEdgeInsert, baseEdgeInsert + other.edgePartitions[i].size);
edges.insert(
edges.begin() + edgePartitions[i].offset + edgePartitions[i].size,
baseEdgeInsert, baseEdgeInsert + other.edgePartitions[i].size
);
auto baseTetrahedronInsert = other.tetrahedra.begin() + other.tetrahedronPartitions[i].offset;
tetrahedra.insert(tetrahedra.begin() + tetrahedronPartitions[i].offset + tetrahedronPartitions[i].size,
baseTetrahedronInsert, baseTetrahedronInsert + other.tetrahedronPartitions[i].size);
tetrahedra.insert(
tetrahedra.begin() + tetrahedronPartitions[i].offset + tetrahedronPartitions[i].size,
baseTetrahedronInsert, baseTetrahedronInsert + other.tetrahedronPartitions[i].size
);
edgePartitions[i].size += other.edgePartitions[i].size;
tetrahedronPartitions[i].size += other.tetrahedronPartitions[i].size;
}
// increase offsets for remaining partitions
for (size_t i = other.partitionCount; i < partitionCount; i++){
for (size_t i = other.partitionCount; i < partitionCount; i++) {
edgePartitions[i].offset += other.edgePartitions[other.partitionCount - 1].offset;
tetrahedronPartitions[i].offset += other.tetrahedronPartitions[other.partitionCount - 1].offset;
}

@ -16,7 +16,7 @@ void Grabber::mouseButtonReleased(int button) {
}
bool Grabber::started() {
if (start){
if (start) {
start = false;
return true;
}
@ -24,7 +24,7 @@ bool Grabber::started() {
}
bool Grabber::stopped() {
if (stop){
if (stop) {
stop = false;
return true;
}

@ -3,36 +3,42 @@
std::map<int, bool> Input::KeyIsDown;
std::map<int, bool> Input::MouseButtonIsDown;
Input* Input::instance;
Input *Input::instance;
Input::Input(GLFWwindow *window) : window(window) {
instance = this;
glfwSetWindowUserPointer(window, this);
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods){
auto inputManager = static_cast<Input*>(glfwGetWindowUserPointer(window));
glfwSetKeyCallback(
window, [](GLFWwindow *window, int key, int scancode, int action, int mods) {
auto inputManager = static_cast<Input *>(glfwGetWindowUserPointer(window));
if (action == GLFW_PRESS)
inputManager->keyPressed(key);
if (action == GLFW_RELEASE)
inputManager->keyReleased(key);
});
}
);
glfwSetCursorPosCallback(window, [](GLFWwindow* window, double xpos, double ypos){
auto inputManager = static_cast<Input*>(glfwGetWindowUserPointer(window));
glfwSetCursorPosCallback(
window, [](GLFWwindow *window, double xpos, double ypos) {
auto inputManager = static_cast<Input *>(glfwGetWindowUserPointer(window));
glm::vec2 newPosition = {static_cast<float>(xpos), static_cast<float>(ypos)};
inputManager->mouseMoved(newPosition);
});
}
);
double x = 0, y = 0;
glfwGetCursorPos(window, &x, &y);
currentCursorPosition = glm::vec2(static_cast<float>(x), static_cast<float>(y));
glfwSetMouseButtonCallback(window, [](GLFWwindow* window, int button, int action, int mods){
auto inputManager = static_cast<Input*>(glfwGetWindowUserPointer(window));
glfwSetMouseButtonCallback(
window, [](GLFWwindow *window, int button, int action, int mods) {
auto inputManager = static_cast<Input *>(glfwGetWindowUserPointer(window));
if (action == GLFW_PRESS)
inputManager->mouseButtonPressed(button);
if (action == GLFW_RELEASE)
inputManager->mouseButtonReleased(button);
});
}
);
}
void Input::keyPressed(int key) {
@ -47,8 +53,8 @@ void Input::mouseButtonPressed(int button) {
Input::MouseButtonIsDown[button] = true;
if (button == GLFW_MOUSE_BUTTON_RIGHT)
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
for (auto listener : listeners)
if (auto mouseListener = dynamic_cast<MouseListener*>(listener))
for (auto listener: listeners)
if (auto mouseListener = dynamic_cast<MouseListener *>(listener))
mouseListener->mouseButtonPressed(button);
}
@ -56,15 +62,15 @@ void Input::mouseButtonReleased(int button) {
Input::MouseButtonIsDown[button] = false;
if (button == GLFW_MOUSE_BUTTON_RIGHT)
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
for (auto listener : listeners)
if (auto mouseListener = dynamic_cast<MouseListener*>(listener))
for (auto listener: listeners)
if (auto mouseListener = dynamic_cast<MouseListener *>(listener))
mouseListener->mouseButtonReleased(button);
}
void Input::mouseMoved(const glm::vec2& newCursorPosition) {
void Input::mouseMoved(const glm::vec2 &newCursorPosition) {
glm::vec2 delta = newCursorPosition - currentCursorPosition;
for (auto listener : listeners)
if (auto mouseListener = dynamic_cast<MouseListener*>(listener))
for (auto listener: listeners)
if (auto mouseListener = dynamic_cast<MouseListener *>(listener))
mouseListener->mouseMoved(delta);
currentCursorPosition = newCursorPosition;
}

@ -11,19 +11,19 @@ Mesh::Mesh(const std::string &fileName) {
auto mesh = scene->mMeshes[0];
for (size_t i = 0; i < mesh->mNumVertices; i++){
glm::vec3 pos = *reinterpret_cast<glm::vec3*>(&mesh->mVertices[i]);
for (size_t i = 0; i < mesh->mNumVertices; i++) {
glm::vec3 pos = *reinterpret_cast<glm::vec3 *>(&mesh->mVertices[i]);
glm::vec2 uv = {0, 0};
if (mesh->mNumUVComponents[0] == 2)
uv = *reinterpret_cast<glm::vec2*>(&mesh->mTextureCoords[0][i]);
uv = *reinterpret_cast<glm::vec2 *>(&mesh->mTextureCoords[0][i]);
glm::vec3 normal = {0, 0, 0};
if (mesh->mNormals != nullptr)
normal = *reinterpret_cast<glm::vec3*>(&mesh->mNormals[i]);
normal = *reinterpret_cast<glm::vec3 *>(&mesh->mNormals[i]);
vertices.push_back({pos, uv, normal});
}
for (size_t i = 0; i < mesh->mNumFaces; i++){
faces.push_back(*reinterpret_cast<Face*>(mesh->mFaces[i].mIndices));
for (size_t i = 0; i < mesh->mNumFaces; i++) {
faces.push_back(*reinterpret_cast<Face *>(mesh->mFaces[i].mIndices));
}
}

@ -7,7 +7,7 @@
#include <omp.h>
#include <iostream>
SoftBody::SoftBody(Mesh* mesh, float edgeCompliance, float triangleCompliance, float tetrahedronCompliance) {
SoftBody::SoftBody(Mesh *mesh, float edgeCompliance, float triangleCompliance, float tetrahedronCompliance) {
tetgenbehavior behavior;
behavior.parse_commandline(std::string("pYQfeza1").data());
@ -19,7 +19,7 @@ SoftBody::SoftBody(Mesh* mesh, float edgeCompliance, float triangleCompliance, f
in.numberofpointattributes = 2; // uv
in.pointattributelist = new REAL[mesh->vertices.size() * 2];
for (size_t i = 0; i < mesh->vertices.size(); i++){
for (size_t i = 0; i < mesh->vertices.size(); i++) {
in.pointlist[i * 3 + 0] = mesh->vertices[i].position.x;
in.pointlist[i * 3 + 1] = mesh->vertices[i].position.y;
in.pointlist[i * 3 + 2] = mesh->vertices[i].position.z;
@ -27,7 +27,7 @@ SoftBody::SoftBody(Mesh* mesh, float edgeCompliance, float triangleCompliance, f
in.pointattributelist[i * 2 + 1] = mesh->vertices[i].uv.t;
}
for (size_t i = 0; i < mesh->faces.size(); i++){
for (size_t i = 0; i < mesh->faces.size(); i++) {
tetgenio::facet &f = in.facetlist[i];
tetgenio::polygon p;
@ -48,7 +48,7 @@ SoftBody::SoftBody(Mesh* mesh, float edgeCompliance, float triangleCompliance, f
tetrahedralize(&behavior, &in, &out);
vertices.reserve(out.numberofpoints);
for (size_t i = 0; i < out.numberofpoints; i++){
for (size_t i = 0; i < out.numberofpoints; i++) {
float x = static_cast<float>(out.pointlist[i * 3 + 0]);
float y = static_cast<float>(out.pointlist[i * 3 + 1]);
float z = static_cast<float>(out.pointlist[i * 3 + 2]);
@ -59,7 +59,7 @@ SoftBody::SoftBody(Mesh* mesh, float edgeCompliance, float triangleCompliance, f
faces.reserve(out.numberoftrifaces);
constraintData.triangles.reserve(out.numberoftrifaces);
for (size_t i = 0; i < out.numberoftrifaces; i++){
for (size_t i = 0; i < out.numberoftrifaces; i++) {
uint32_t a = out.trifacelist[i * 3 + 0];
uint32_t b = out.trifacelist[i * 3 + 1];
uint32_t c = out.trifacelist[i * 3 + 2];
@ -81,7 +81,7 @@ SoftBody::SoftBody(Mesh* mesh, float edgeCompliance, float triangleCompliance, f
vector<float> masses(vertices.size());
constraintData.tetrahedra.reserve(out.numberoftetrahedra);
for (size_t i = 0; i < out.numberoftetrahedra; i++){
for (size_t i = 0; i < out.numberoftetrahedra; i++) {
uint32_t a = out.tetrahedronlist[i * 4 + 0];
uint32_t b = out.tetrahedronlist[i * 4 + 1];
uint32_t c = out.tetrahedronlist[i * 4 + 2];
@ -105,7 +105,7 @@ SoftBody::SoftBody(Mesh* mesh, float edgeCompliance, float triangleCompliance, f
constraintData.tetrahedra.emplace_back(Tetrahedron(a, b, c, d, volume, tetrahedronCompliance));
}
for (size_t i = 0; i < masses.size(); i++){
for (size_t i = 0; i < masses.size(); i++) {
vertices[i].inverseMass = 1.0f / masses[i];
}
@ -113,19 +113,20 @@ SoftBody::SoftBody(Mesh* mesh, float edgeCompliance, float triangleCompliance, f
}
void SoftBody::applyVertexWorldOffset(const glm::vec3 &offset) {
for (Vertex& vertex : vertices){
for (Vertex &vertex: vertices) {
vertex.position += 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;
vector<unordered_set<const Constraint *>> colorToConstraintList;
for (const Constraint * constraint : ordering){
for (const Constraint *constraint: ordering) {
unordered_set<uint32_t> forbiddenColors;
for (auto adjacent : graph.at(constraint))
for (auto adjacent: graph.at(constraint))
if (constraintToColor.contains(adjacent))
forbiddenColors.insert(constraintToColor.at(adjacent));
@ -136,8 +137,8 @@ vector<unordered_set<const Constraint *>> createPartitions(const Graph &graph, c
} else {
uint32_t minColor;
uint32_t minColorUseCount = UINT32_MAX;
for (uint32_t color = 0; color < colorToConstraintList.size(); color++){
if (colorToConstraintList[color].size() < minColorUseCount && !forbiddenColors.contains(color)){
for (uint32_t color = 0; color < colorToConstraintList.size(); color++) {
if (colorToConstraintList[color].size() < minColorUseCount && !forbiddenColors.contains(color)) {
minColorUseCount = colorToConstraintList[color].size();
minColor = color;
}
@ -157,7 +158,7 @@ vector<const Constraint *> smallestLastOrdering(const Graph &graph) {
unordered_map<size_t, unordered_set<const Constraint *>> degreesToConstraints;
unordered_map<const Constraint *, size_t> constraintsToDegrees;
for (const auto &[constraint, adjacent] : graph) {
for (const auto &[constraint, adjacent]: graph) {
degreesToConstraints[adjacent.size()].insert(constraint);
constraintsToDegrees[constraint] = adjacent.size();
}
@ -167,7 +168,7 @@ vector<const Constraint *> smallestLastOrdering(const Graph &graph) {
size_t minDegree = 0;
while (degreesToConstraints[minDegree].empty())
minDegree++;
const Constraint * minConstraint = *degreesToConstraints[minDegree].begin();
const Constraint *minConstraint = *degreesToConstraints[minDegree].begin();
degreesToConstraints[minDegree].erase(minConstraint);
constraintsToDegrees.erase(minConstraint);
@ -197,17 +198,17 @@ void SoftBody::splitConstraints() {
distanceConstraints.reserve(constraintData.edges.size());
volumeConstraints.reserve(constraintData.tetrahedra.size());
for (const Edge &edge : constraintData.edges)
for (const Edge &edge: constraintData.edges)
distanceConstraints.push_back(DistanceConstraint(edge));
for (const Tetrahedron &tetrahedron : constraintData.tetrahedra)
for (const Tetrahedron &tetrahedron: constraintData.tetrahedra)
volumeConstraints.push_back(VolumeConstraint(tetrahedron));
for (const DistanceConstraint &distanceConstraint : distanceConstraints){
for (const DistanceConstraint &distanceConstraint: distanceConstraints) {
pointToConstraints[distanceConstraint.a].push_back(&distanceConstraint);
pointToConstraints[distanceConstraint.b].push_back(&distanceConstraint);
}
for (const VolumeConstraint &volumeConstraint : volumeConstraints){
for (const VolumeConstraint &volumeConstraint: volumeConstraints) {
pointToConstraints[volumeConstraint.a].push_back(&volumeConstraint);
pointToConstraints[volumeConstraint.b].push_back(&volumeConstraint);
pointToConstraints[volumeConstraint.c].push_back(&volumeConstraint);
@ -216,31 +217,35 @@ void SoftBody::splitConstraints() {
Graph graph;
auto findAdjacent = [&pointToConstraints, &graph](const Constraint * constraint, const vector<uint32_t> &vIDs){
auto findAdjacent = [&pointToConstraints, &graph](const Constraint *constraint, const vector<uint32_t> &vIDs) {
unordered_set<const Constraint *> neighbors;
for (uint32_t vID : vIDs)
for (uint32_t vID: vIDs)
neighbors.insert(pointToConstraints[vID].begin(), pointToConstraints[vID].end());
neighbors.erase(constraint);
#pragma omp critical
#pragma omp critical
graph[constraint].assign(neighbors.begin(), neighbors.end());
};
#pragma omp parallel for default(none) shared(findAdjacent, distanceConstraints)
for (const DistanceConstraint &distanceConstraint : distanceConstraints){
findAdjacent(&distanceConstraint, {
#pragma omp parallel for default(none) shared(findAdjacent, distanceConstraints)
for (const DistanceConstraint &distanceConstraint: distanceConstraints) {
findAdjacent(
&distanceConstraint, {
distanceConstraint.a,
distanceConstraint.b
});
}
);
}
#pragma omp parallel for default(none) shared(findAdjacent, volumeConstraints)
for (const VolumeConstraint &volumeConstraint : volumeConstraints){
findAdjacent(&volumeConstraint, {
#pragma omp parallel for default(none) shared(findAdjacent, volumeConstraints)
for (const VolumeConstraint &volumeConstraint: volumeConstraints) {
findAdjacent(
&volumeConstraint, {
volumeConstraint.a,
volumeConstraint.b,
volumeConstraint.c,
volumeConstraint.d,
});
}
);
}
auto ordering = smallestLastOrdering(graph);
@ -253,9 +258,9 @@ void SoftBody::splitConstraints() {
void SoftBody::reorderConstraintIndices(const vector<unordered_set<const Constraint *>> &partitions) {
ConstraintData reordered;
for (uint32_t partition = 0; partition < partitions.size(); partition++){
for (uint32_t partition = 0; partition < partitions.size(); partition++) {
reordered.recordNewPartition();
for (const Constraint * constraint : partitions[partition])
for (const Constraint *constraint: partitions[partition])
constraint->writeData(reordered);
reordered.writePartitionInformation();
}

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

@ -6,8 +6,12 @@
#include "vulkan/image.hpp"
#include "vk_mem_alloc.h"
Buffer::Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsageFlags, VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags allocationFlags)
: size(bufferSize), bufferUsageFlags(bufferUsageFlags), memoryUsage(memoryUsage), allocationCreateFlags(allocationFlags) {
Buffer::Buffer(
VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsageFlags,
VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags allocationFlags, const std::string &name
)
: size(bufferSize), bufferUsageFlags(bufferUsageFlags), memoryUsage(memoryUsage),
allocationCreateFlags(allocationFlags) {
VkBufferCreateInfo bufferCreateInfo {};
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@ -19,7 +23,11 @@ Buffer::Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsageFlags, Vma
allocationCreateInfo.usage = memoryUsage;
allocationCreateInfo.flags = allocationFlags;
vmaCreateBuffer(Instance::GetAllocator(), &bufferCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo);
vmaCreateBuffer(
Instance::GetAllocator(), &bufferCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo
);
setName(name);
}
Buffer::~Buffer() {
@ -28,7 +36,7 @@ Buffer::~Buffer() {
void Buffer::copyTo(Buffer *buffer) const {
VkQueue queue = Instance::instance->graphicsAndPresentQueue;
CommandPool* commandPool = Instance::instance->renderingCommandPool;
CommandPool *commandPool = Instance::instance->renderingCommandPool;
VkCommandBuffer commandBuffer = commandPool->beginSingleTimeCommandBuffer();
@ -41,7 +49,7 @@ void Buffer::copyTo(Buffer *buffer) const {
void Buffer::copyTo(Image *image) const {
VkQueue queue = Instance::instance->graphicsAndPresentQueue;
CommandPool* commandPool = Instance::instance->renderingCommandPool;
CommandPool *commandPool = Instance::instance->renderingCommandPool;
VkCommandBuffer commandBuffer = commandPool->beginSingleTimeCommandBuffer();
@ -62,15 +70,15 @@ void Buffer::copyTo(Image *image) const {
}
void Buffer::setData(void *data, VkDeviceSize offset, VkDeviceSize dataSize, VkCommandBuffer commandBuffer) {
if (allocationInfo.pMappedData){
memcpy(reinterpret_cast<u_char*>(allocationInfo.pMappedData) + offset, data, dataSize);
if (allocationInfo.pMappedData) {
memcpy(reinterpret_cast<u_char *>(allocationInfo.pMappedData) + offset, data, dataSize);
VkMemoryPropertyFlags flags;
vmaGetAllocationMemoryProperties(Instance::GetAllocator(), allocation, &flags);
assert(flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
} else {
bool singleShot = false;
if (!commandBuffer){
if (!commandBuffer) {
commandBuffer = Instance::instance->renderingCommandPool->beginSingleTimeCommandBuffer();
singleShot = true;
}
@ -96,7 +104,8 @@ void Buffer::setData(void *data, VkDeviceSize offset, VkDeviceSize dataSize, VkC
0,
0, nullptr,
1, &bufferMemoryBarrier,
0, nullptr);
0, nullptr
);
VkBufferCopy region {};
region.srcOffset = offset;
@ -106,7 +115,9 @@ void Buffer::setData(void *data, VkDeviceSize offset, VkDeviceSize dataSize, VkC
vkCmdCopyBuffer(commandBuffer, stagingBuffer->handle, handle, 1, &region);
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 {
auto buffer = make_unique<Buffer>(size + appendSize,
auto buffer = make_unique<Buffer>(
size + appendSize,
bufferUsageFlags,
memoryUsage,
allocationCreateFlags);
allocationCreateFlags
);
buffer->setName(name);
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 {
auto buffer = make_unique<Buffer>(replaceSize,
auto buffer = make_unique<Buffer>(
replaceSize,
bufferUsageFlags,
memoryUsage,
allocationCreateFlags);
allocationCreateFlags
);
buffer->setName(name);
buffer->setData(data, 0, replaceSize, commandBuffer);
@ -153,7 +168,8 @@ shared_ptr<Buffer> Buffer::getStagingBuffer() {
size,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
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");

@ -20,18 +20,23 @@ DescriptorPool::DescriptorPool() {
vkCreateDescriptorPool(Instance::GetDevice(), &poolInfo, nullptr, &handle);
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();
setBindings[set].push_back({
setBindings[set].push_back(
{
.binding = binding,
.descriptorType = type,
.descriptorCount = 1,
.stageFlags = stageFlags
});
}
);
};
// 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
addBinding(DescriptorSet::WORLD, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
// texture
@ -55,10 +60,10 @@ DescriptorPool::DescriptorPool() {
// grab information
addBinding(DescriptorSet::SIMULATION, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
for (const auto &[set, bindings] : setBindings)
for (const auto &[set, bindings]: setBindings)
createLayout(set, bindings);
for (const auto &[set, layout] : layouts){
for (const auto &[set, layout]: layouts) {
VkDescriptorSetAllocateInfo allocateInfo {};
allocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocateInfo.descriptorPool = handle;
@ -71,11 +76,11 @@ DescriptorPool::DescriptorPool() {
DescriptorPool::~DescriptorPool() {
vkDestroyDescriptorPool(Instance::GetDevice(), handle, nullptr);
for (const auto &[type, layout] : layouts)
for (const auto &[type, layout]: layouts)
vkDestroyDescriptorSetLayout(Instance::GetDevice(), layout, nullptr);
}
void DescriptorPool::bindBuffer(const Buffer& buffer, VkDescriptorType type, DescriptorSet set, uint32_t binding) {
void DescriptorPool::bindBuffer(const Buffer &buffer, VkDescriptorType type, DescriptorSet set, uint32_t binding) {
VkDescriptorBufferInfo bufferInfo {};
bufferInfo.buffer = buffer.handle;
bufferInfo.offset = 0;

@ -3,8 +3,10 @@
#include "vulkan/buffer.hpp"
#include "vulkan/command_pool.hpp"
Image::Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage) : format(format), width(width), height(height) {
Image::Image(
uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage
) : format(format), width(width), height(height) {
VkImageCreateInfo imageCreateInfo {};
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.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,
VkImageUsageFlags usage) : Image(width, height, format, tiling, usage){
Image::Image(
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,
VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
Buffer stagingBuffer(
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);
transitionLayout(VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
@ -116,13 +124,14 @@ void Image::transitionLayout(VkImageLayout oldLayout, VkImageLayout newLayout) {
VkPipelineStageFlags sourceStage = 0;
VkPipelineStageFlags destinationStage = 0;
if ((oldLayout == VK_IMAGE_LAYOUT_UNDEFINED) && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL){
if ((oldLayout == VK_IMAGE_LAYOUT_UNDEFINED) && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_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.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
@ -130,12 +139,14 @@ void Image::transitionLayout(VkImageLayout oldLayout, VkImageLayout newLayout) {
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
}
vkCmdPipelineBarrier(commandBuffer,
vkCmdPipelineBarrier(
commandBuffer,
sourceStage, destinationStage,
0,
0, nullptr,
0, nullptr,
1, &barrier);
1, &barrier
);
commandPool->endSingleTimeCommandBuffer(commandBuffer, Instance::instance->graphicsAndPresentQueue);
}

@ -6,7 +6,7 @@
#include "vk_mem_alloc.h"
#include <cstring>
const std::vector<const char*> deviceExtensions = {
const std::vector<const char *> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME
};
@ -49,7 +49,7 @@ bool checkValidationLayerSupport(){
}
#endif
Instance* Instance::instance = nullptr;
Instance *Instance::instance = nullptr;
Instance::Instance() {
instance = this;
@ -72,12 +72,12 @@ void Instance::initWindow() {
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
int monitorCount;
GLFWmonitor** monitors = glfwGetMonitors(&monitorCount);
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
for (int i = 1; i < monitorCount; i++){
for (int i = 1; i < monitorCount; i++) {
int w, h;
glfwGetMonitorPhysicalSize(monitors[i], &w, &h);
if (w > h){
if (w > h) {
monitor = monitors[i];
break;
}
@ -86,9 +86,11 @@ void Instance::initWindow() {
glfwGetMonitorPos(monitor, &x, &y);
window = glfwCreateWindow(800, 600, "Vulkan Simulation", nullptr, nullptr);
glfwSetWindowPos(window, x, y);
glfwSetFramebufferSizeCallback(window, [](GLFWwindow* window, int width, int height) {
glfwSetFramebufferSizeCallback(
window, [](GLFWwindow *window, int width, int height) {
instance->windowResized = true;
});
}
);
}
void Instance::createInstance() {
@ -107,7 +109,7 @@ void Instance::createInstance() {
applicationInfo.apiVersion = VK_API_VERSION_1_1;
uint32_t glfwExtensionCount = 0;
const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
VkInstanceCreateInfo instanceCreateInfo {};
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
@ -131,21 +133,21 @@ void Instance::createSurface() {
void Instance::pickPhysicalDevice() {
uint32_t deviceCount = 0;
vkEnumeratePhysicalDevices(handle, &deviceCount, nullptr);
if (deviceCount == 0){
if (deviceCount == 0) {
throw std::runtime_error("failed to find GPUs with Vulkan support!");
}
std::vector<VkPhysicalDevice> devices(deviceCount);
vkEnumeratePhysicalDevices(handle, &deviceCount, devices.data());
for (const VkPhysicalDevice &potentialPhysicalDevice : devices){
if (isDeviceSuitable(potentialPhysicalDevice)){
for (const VkPhysicalDevice &potentialPhysicalDevice: devices) {
if (isDeviceSuitable(potentialPhysicalDevice)) {
physicalDevice = potentialPhysicalDevice;
indices = findQueueFamilies(physicalDevice, surface);
break;
}
}
if (physicalDevice == VK_NULL_HANDLE){
if (physicalDevice == VK_NULL_HANDLE) {
throw std::runtime_error("failed to find a suitable GPU!");
}
@ -158,7 +160,7 @@ void Instance::createLogicalDevice() {
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
float queuePriority = 1.0f;
for (uint32_t queueFamily : indices.uniqueQueueFamilies()){
for (uint32_t queueFamily: indices.uniqueQueueFamilies()) {
VkDeviceQueueCreateInfo queueCreateInfo {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = queueFamily;
@ -193,8 +195,9 @@ void Instance::createLogicalDevice() {
}
#include <fstream>
void printVmaStats(){
char* stats;
void printVmaStats() {
char *stats;
vmaBuildStatsString(Instance::GetAllocator(), &stats, VK_TRUE);
std::ofstream stream("stats.json");
stream << stats;
@ -225,7 +228,7 @@ Instance::QueueFamilyIndices Instance::findQueueFamilies(VkPhysicalDevice device
QueueFamilyIndices indices {};
uint32_t i = 0;
for (const VkQueueFamilyProperties& queueFamilyProperties : queueFamilies){
for (const VkQueueFamilyProperties &queueFamilyProperties: queueFamilies) {
VkBool32 present = false;
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &present);
@ -255,7 +258,7 @@ bool Instance::isDeviceSuitable(VkPhysicalDevice potentialPhysicalDevice) {
bool extensionsSupported = checkDeviceExtensionSupport(potentialPhysicalDevice);
bool swapChainAdequate = false;
if (extensionsSupported){
if (extensionsSupported) {
SwapchainSupportDetails details = querySwapchainSupport(potentialPhysicalDevice, surface);
swapChainAdequate = !details.formats.empty() && !details.presentModes.empty();
}
@ -272,7 +275,7 @@ bool Instance::checkDeviceExtensionSupport(VkPhysicalDevice device) {
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
for (const VkExtensionProperties& extension : availableExtensions){
for (const VkExtensionProperties &extension: availableExtensions) {
required.erase(extension.extensionName);
}
@ -313,10 +316,10 @@ Instance::~Instance() {
glfwTerminate();
}
void Instance::initImGui(const Swapchain& swapchain) {
void Instance::initImGui(const Swapchain &swapchain) {
ImGui::CreateContext();
ImGui::StyleColorsDark();
ImGuiIO& io = ImGui::GetIO();
ImGuiIO &io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
ImGui_ImplGlfw_InitForVulkan(window, true);
@ -330,7 +333,7 @@ void Instance::initImGui(const Swapchain& swapchain) {
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
pool_info.maxSets = 1;
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
pool_info.poolSizeCount = (uint32_t) IM_ARRAYSIZE(pool_sizes);
pool_info.pPoolSizes = pool_sizes;
vkCreateDescriptorPool(Instance::GetDevice(), &pool_info, nullptr, &imGuiDescriptorPool);

@ -4,10 +4,10 @@
#include "vulkan/vertex.hpp"
#include "vulkan/instance.hpp"
std::vector<char> readFile(const std::string& fileName){
std::vector<char> readFile(const std::string &fileName) {
std::ifstream file(fileName, std::ios::ate | std::ios::binary);
if (!file.is_open()){
if (!file.is_open()) {
throw std::runtime_error("failed to open file!");
}
@ -33,8 +33,10 @@ VkShaderModule Pipeline::createShaderModule(const std::vector<char> &code) {
return shaderModule;
}
Pipeline::Pipeline(const std::vector<VkDescriptorSetLayout> &descriptorSetLayouts,
const std::vector<VkPushConstantRange> &pushConstantRanges) {
Pipeline::Pipeline(
const std::vector<VkDescriptorSetLayout> &descriptorSetLayouts,
const std::vector<VkPushConstantRange> &pushConstantRanges
) {
VkPipelineLayoutCreateInfo pipelineLayoutInfo {};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
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,
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 fragShaderCode = readFile(fragmentShaderPath);
@ -122,7 +126,8 @@ GraphicsPipeline::GraphicsPipeline(const std::string& vertexShaderPath, const st
multisample.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
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;
VkPipelineColorBlendStateCreateInfo colorBlending {};
@ -166,9 +171,11 @@ GraphicsPipeline::GraphicsPipeline(const std::string& vertexShaderPath, const st
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<VkPushConstantRange> &pushConstantRanges) : Pipeline(descriptorSetLayouts, pushConstantRanges) {
const std::vector<VkPushConstantRange> &pushConstantRanges
) : Pipeline(descriptorSetLayouts, pushConstantRanges) {
VkShaderModule module = createShaderModule(readFile(shaderFile));
VkPipelineShaderStageCreateInfo stageInfo {};

@ -4,21 +4,21 @@
#include "vulkan/instance.hpp"
#include "vulkan/image.hpp"
SwapchainSupportDetails querySwapchainSupport(VkPhysicalDevice device, VkSurfaceKHR surface){
SwapchainSupportDetails querySwapchainSupport(VkPhysicalDevice device, VkSurfaceKHR surface) {
SwapchainSupportDetails details;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities);
uint32_t formatCount;
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
if (formatCount != 0){
if (formatCount != 0) {
details.formats.resize(formatCount);
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, details.formats.data());
}
uint32_t presentModeCount;
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr);
if (presentModeCount != 0){
if (presentModeCount != 0) {
details.presentModes.resize(presentModeCount);
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, details.presentModes.data());
}
@ -40,7 +40,7 @@ Swapchain::~Swapchain() {
}
VkExtent2D Swapchain::chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilities) {
if (capabilities.currentExtent.width != std::numeric_limits<uint32_t>::max()){
if (capabilities.currentExtent.width != std::numeric_limits<uint32_t>::max()) {
return capabilities.currentExtent;
} else {
int width, height;
@ -51,22 +51,27 @@ VkExtent2D Swapchain::chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilit
static_cast<uint32_t>(height)
};
actualExtent.width = std::clamp(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
actualExtent.height = std::clamp(actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
actualExtent.width = std::clamp(
actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width
);
actualExtent.height = std::clamp(
actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height
);
return actualExtent;
}
}
void Swapchain::createSwapchain() {
SwapchainSupportDetails swapchainSupport = querySwapchainSupport(Instance::GetPhysicalDevice(), Instance::GetSurface());
SwapchainSupportDetails swapchainSupport = querySwapchainSupport(
Instance::GetPhysicalDevice(), Instance::GetSurface());
VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapchainSupport.formats);
VkPresentModeKHR presentMode = chooseSwapPresentMode(swapchainSupport.presentModes);
extent = chooseSwapExtent(swapchainSupport.capabilities);
uint32_t imageCount = swapchainSupport.capabilities.minImageCount + 1;
if (swapchainSupport.capabilities.maxImageCount > 0 && imageCount > swapchainSupport.capabilities.maxImageCount){
if (swapchainSupport.capabilities.maxImageCount > 0 && imageCount > swapchainSupport.capabilities.maxImageCount) {
imageCount = swapchainSupport.capabilities.maxImageCount;
}
@ -98,10 +103,10 @@ void Swapchain::createSwapchain() {
}
void Swapchain::cleanupSwapchain() {
for (auto framebuffer : frameBuffers){
for (auto framebuffer: frameBuffers) {
vkDestroyFramebuffer(Instance::GetDevice(), framebuffer, nullptr);
}
for (auto imageView : imageViews){
for (auto imageView: imageViews) {
vkDestroyImageView(Instance::GetDevice(), imageView, nullptr);
}
delete depthImage;
@ -121,7 +126,7 @@ void Swapchain::recreateSwapchain() {
void Swapchain::createImageViews() {
imageViews.resize(images.size());
for (size_t i = 0; i < images.size(); i++){
for (size_t i = 0; i < images.size(); i++) {
VkImageViewCreateInfo createInfo {};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
createInfo.format = imageFormat;
@ -178,9 +183,11 @@ void Swapchain::createRenderpass() {
VkSubpassDependency dependency {};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
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.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;
VkRenderPassCreateInfo renderPassInfo {};
@ -208,7 +215,7 @@ void Swapchain::createDepthResources() {
void Swapchain::createFramebuffers() {
frameBuffers.resize(imageViews.size());
for (size_t i = 0; i < imageViews.size(); i++){
for (size_t i = 0; i < imageViews.size(); i++) {
VkImageView attachments[] = {
imageViews[i],
depthImage->view
@ -228,8 +235,9 @@ void Swapchain::createFramebuffers() {
}
VkSurfaceFormatKHR Swapchain::chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR> &availableFormats) {
for (const auto& availableFormat : availableFormats){
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR){
for (const auto &availableFormat: availableFormats) {
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB &&
availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
return availableFormat;
}
}

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