tetgen start

feature/softbody-runtime-control
Benjamin Kraft 4 months ago
parent 385c608d96
commit dda4ec2fe5
  1. 17
      CMakeLists.txt
  2. 27
      include/constraints.hpp
  3. 14
      include/mesh.hpp
  4. 9
      include/simulation.hpp
  5. 29
      include/soft_body.hpp
  6. 3438
      include/tetgen.h
  7. 6
      include/vulkan/application.hpp
  8. 7
      include/vulkan/pipeline.hpp
  9. 47775
      models/bunny_high.ply
  10. 2195
      models/environment.obj
  11. 1083
      models/sphere_high.ply
  12. 6
      shaders/shader.comp
  13. 1
      src/constraints.cpp
  14. 25
      src/mesh.cpp
  15. 80
      src/simulation.cpp
  16. 70
      src/soft_body.cpp
  17. 73
      src/vulkan/application.cpp
  18. 16
      src/vulkan/pipeline.cpp

@ -11,14 +11,27 @@ find_package(glfw3 REQUIRED)
find_package(glm REQUIRED) find_package(glm REQUIRED)
include(FetchContent) include(FetchContent)
FetchContent_Declare(vma FetchContent_Declare(
vma
GIT_REPOSITORY https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git GIT_REPOSITORY https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
GIT_TAG v3.1.0 GIT_TAG v3.1.0
GIT_PROGRESS ON GIT_PROGRESS ON
FIND_PACKAGE_ARGS 3.1.0) FIND_PACKAGE_ARGS 3.1.0)
FetchContent_MakeAvailable(vma) FetchContent_MakeAvailable(vma)
target_link_libraries(VulkanSimulation glm::glm glfw Vulkan::Vulkan GPUOpen::VulkanMemoryAllocator) FetchContent_Declare(assimp
GIT_REPOSITORY https://github.com/assimp/assimp.git
GIT_TAG v5.4.3
)
FetchContent_MakeAvailable(assimp)
FetchContent_Declare(tetgen
GIT_REPOSITORY https://github.com/ufz/tetgen.git
GIT_TAG 1.5.1
)
FetchContent_MakeAvailable(tetgen)
target_link_libraries(VulkanSimulation glm::glm glfw Vulkan::Vulkan GPUOpen::VulkanMemoryAllocator assimp tet)
target_include_directories(VulkanSimulation PRIVATE include) target_include_directories(VulkanSimulation PRIVATE include)
target_compile_definitions(VulkanSimulation PRIVATE target_compile_definitions(VulkanSimulation PRIVATE
GLM_FORCE_RADIANS GLM_FORCE_RADIANS

@ -0,0 +1,27 @@
#pragma once
#include <cstdint>
struct Edge {
uint32_t a;
uint32_t b;
float length;
};
struct Face {
uint32_t a;
uint32_t b;
uint32_t c;
};
struct Triangle : Face {
float area;
};
struct Tetrahedron {
uint32_t a;
uint32_t b;
uint32_t c;
uint32_t d;
float volume;
};

@ -0,0 +1,14 @@
#pragma once
#include <string>
#include "vulkan/vertex.hpp"
#include <vector>
struct Face;
class Mesh {
public:
explicit Mesh(const std::string &fileName);
std::vector<Vertex> vertices;
std::vector<Face> faces;
};

@ -3,13 +3,20 @@
#include "vulkan/application.hpp" #include "vulkan/application.hpp"
class SoftBody; class SoftBody;
class Buffer;
class Simulation : public Application { class Simulation : public Application {
public: public:
Simulation(); Simulation();
~Simulation(); ~Simulation();
private: private:
Buffer* vertexBuffer;
Buffer* edgeBuffer;
Buffer* triangleBuffer;
Buffer* faceBuffer;
Buffer* tetrahedronBuffer;
std::vector<std::unique_ptr<SoftBody>> softBodies; std::vector<std::unique_ptr<SoftBody>> softBodies;
void recordDrawCommands() override; void recordDrawCommands() override;
void recordComputeCommands() override; void recordComputeCommands(VkCommandBuffer cmdBuffer) override;
}; };

@ -4,20 +4,29 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "vulkan/vertex.hpp"
#include <glm/vec3.hpp>
using std::vector; using std::vector;
struct Face { struct Vertex;
uint32_t a; struct Edge;
uint32_t b; struct Triangle;
uint32_t c; struct Face;
}; struct Tetrahedron;
class Mesh;
class SoftBody { class SoftBody {
public: public:
explicit SoftBody(const std::string& fileName); explicit SoftBody(Mesh* mesh, float compliance);
private:
uint32_t indexCount = 0; uint32_t indexCount = 0;
uint32_t partitionCount = 0;
float compliance;
vector<Vertex> vertices;
vector<Edge> edges;
vector<Triangle> triangles;
vector<Face> faces;
vector<Tetrahedron> tetrahedra;
SoftBody& operator =(const SoftBody& other) = delete;
private:
}; };

File diff suppressed because it is too large Load Diff

@ -33,15 +33,13 @@ public:
protected: protected:
Swapchain* swapchain = nullptr; Swapchain* swapchain = nullptr;
Pipeline* graphicsPipeline = nullptr; Pipeline* graphicsPipeline = nullptr;
Buffer* vertexBuffer = nullptr;
Buffer* indexBuffer = nullptr;
Buffer* uniformBuffer = nullptr; Buffer* uniformBuffer = nullptr;
ComputePipeline* computePipeline = nullptr; ComputePipeline* computePipeline = nullptr;
void updateUniformBuffer(); void updateUniformBuffer();
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex); void recordGraphicsCommandBuffer(uint32_t imageIndex);
Semaphore* imageAvailable = nullptr; Semaphore* imageAvailable = nullptr;
Semaphore* renderFinished = nullptr; Semaphore* renderFinished = nullptr;
@ -51,7 +49,7 @@ protected:
void drawFrame(); void drawFrame();
virtual void recordDrawCommands() {}; virtual void recordDrawCommands() {};
virtual void recordComputeCommands() {} virtual void recordComputeCommands(VkCommandBuffer cmdBuffer) {}
void update(); void update();
void createSyncObjects(); void createSyncObjects();
}; };

@ -21,9 +21,10 @@ public:
VkPipeline handle = VK_NULL_HANDLE; VkPipeline handle = VK_NULL_HANDLE;
VkPipelineLayout layout = VK_NULL_HANDLE; VkPipelineLayout layout = VK_NULL_HANDLE;
VkDescriptorSet descriptorSet = VK_NULL_HANDLE; VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
void createDescriptorSet(Buffer* buffer, VkDescriptorType type);
void updateDescriptor(uint32_t binding, Buffer* buffer, VkDescriptorType type);
protected: protected:
VkShaderModule createShaderModule(const std::vector<char> &code); VkShaderModule createShaderModule(const std::vector<char> &code);
VkDescriptorPool descriptorPool = VK_NULL_HANDLE; VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
@ -31,10 +32,12 @@ protected:
void createDescriptorSetLayout(); void createDescriptorSetLayout();
void createDescriptorPool(VkDescriptorType type); void createDescriptorPool(VkDescriptorType type);
void allocateDescriptorSet();
}; };
class ComputePipeline : public Pipeline { class ComputePipeline : public Pipeline {
public: public:
explicit ComputePipeline(Buffer* buffer); explicit ComputePipeline();
void updateDescriptor(uint32_t binding, Buffer* buffer);
}; };

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,16 +1,16 @@
#version 450 #version 450
layout (local_size_x = 1) in; layout (local_size_x = 32) in;
struct Vertex { struct Vertex {
vec3 position; vec3 position;
vec3 color; vec3 color;
}; };
layout (std140, binding = 0) buffer VertexBuffer { layout (std140, set = 0, binding = 0) buffer VertexBuffer {
Vertex vertices[]; Vertex vertices[];
}; };
void main() { void main() {
vertices[0].position.z += 0.001; // vertices[0].position.z += 0.001;
} }

@ -0,0 +1 @@
#include "constraints.hpp"

@ -0,0 +1,25 @@
#include "mesh.hpp"
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include "constraints.hpp"
Mesh::Mesh(const std::string &fileName) {
Assimp::Importer importer;
auto scene = importer.ReadFile(fileName, aiProcess_Triangulate);
auto mesh = scene->mMeshes[0];
for (size_t i = 0; i < mesh->mNumVertices; i++){
vertices.push_back({
*reinterpret_cast<glm::vec3*>(&mesh->mVertices[i]),
glm::vec3(1, 0, 0)
});
}
for (size_t i = 0; i < mesh->mNumFaces; i++){
faces.push_back(*reinterpret_cast<Face*>(mesh->mFaces[i].mIndices));
}
}

@ -4,30 +4,88 @@
#include "vulkan/buffer.hpp" #include "vulkan/buffer.hpp"
#include "vulkan/pipeline.hpp" #include "vulkan/pipeline.hpp"
#include "soft_body.hpp" #include "soft_body.hpp"
#include "mesh.hpp"
#include "constraints.hpp"
Simulation::Simulation() { Simulation::Simulation() {
softBodies.push_back(std::make_unique<SoftBody>("")); Mesh mesh("models/sphere_high.ply");
softBodies.push_back(std::make_unique<SoftBody>(&mesh, 0.3f));
vector<Vertex> vertices;
vector<Edge> edges;
vector<Triangle> triangles;
vector<Face> faces;
vector<Tetrahedron> tetrahedra;
for (const std::unique_ptr<SoftBody> &softBody : softBodies){
vertices.insert(vertices.end(), softBody->vertices.begin(), softBody->vertices.end());
edges.insert(edges.end(), softBody->edges.begin(), softBody->edges.end());
triangles.insert(triangles.end(), softBody->triangles.begin(), softBody->triangles.end());
faces.insert(faces.end(), softBody->faces.begin(), softBody->faces.end());
tetrahedra.insert(tetrahedra.end(), softBody->tetrahedra.begin(), softBody->tetrahedra.end());
}
class SimulationBuffer : public Buffer {
public:
SimulationBuffer(void* data, VkDeviceSize size, VkBufferUsageFlags additionalUsageFlags=0)
: Buffer(size, data, size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | additionalUsageFlags, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0) {}
};
vertexBuffer = new SimulationBuffer(vertices.data(), vertices.size() * sizeof(Vertex), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
edgeBuffer = new SimulationBuffer(edges.data(), edges.size() * sizeof(Edge));
triangleBuffer = new SimulationBuffer(triangles.data(), triangles.size() * sizeof(Triangle));
faceBuffer = new SimulationBuffer(faces.data(), faces.size() * sizeof(Face), VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
tetrahedronBuffer = new SimulationBuffer(tetrahedra.data(), tetrahedra.size() * sizeof(Tetrahedron));
computePipeline->updateDescriptor(0, vertexBuffer);
} }
void Simulation::recordDrawCommands() { void Simulation::recordDrawCommands() {
VkCommandBuffer commandBuffer = Instance::instance->commandPool->graphicsBuffer; VkCommandBuffer cmdBuffer = Instance::instance->commandPool->graphicsBuffer;
VkBuffer buffers[] = {vertexBuffer->handle}; VkBuffer buffers[] = {vertexBuffer->handle};
VkDeviceSize offsets[] = {0}; VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, buffers, offsets); vkCmdBindVertexBuffers(cmdBuffer, 0, 1, buffers, offsets);
vkCmdBindIndexBuffer(commandBuffer, indexBuffer->handle, 0, VK_INDEX_TYPE_UINT32); vkCmdBindIndexBuffer(cmdBuffer, faceBuffer->handle, 0, VK_INDEX_TYPE_UINT32);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1, &graphicsPipeline->descriptorSet, 0, nullptr); vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1, &graphicsPipeline->descriptorSet, 0, nullptr);
vkCmdDrawIndexed(commandBuffer, 12, 1, 0, 0, 0); vkCmdDrawIndexed(cmdBuffer, faceBuffer->size / sizeof(Face) * 3, 1, 0, 0, 0);
} }
void Simulation::recordComputeCommands() { void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) {
VkCommandBuffer commandBuffer = Instance::instance->commandPool->computeBuffer; SoftBody& body = *softBodies[0];
VkMemoryBarrier barrier {};
barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline->layout, 0, 1, &computePipeline->descriptorSet, 0, nullptr); vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline->layout, 0, 1, &computePipeline->descriptorSet, 0, nullptr);
vkCmdDispatch(commandBuffer, 1, 1, 1);
size_t subSteps = 1;
for (size_t i = 0; i < subSteps; i++){
uint32_t preSolveInvocations = 1;
vkCmdDispatch(cmdBuffer, preSolveInvocations, 1, 1);
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr);
uint32_t partitionCount = 1;
for (uint32_t partition = 0; partition < partitionCount; partition++){
uint32_t partitionSize = 1;
vkCmdDispatch(cmdBuffer, partitionSize, 1, 1);
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr);
}
uint32_t postSolveInvocations = 1;
vkCmdDispatch(cmdBuffer, postSolveInvocations, 1, 1);
} }
Simulation::~Simulation() { }
Simulation::~Simulation() {
delete vertexBuffer;
delete edgeBuffer;
delete triangleBuffer;
delete faceBuffer;
delete tetrahedronBuffer;
} }

@ -1,5 +1,73 @@
#include "soft_body.hpp" #include "soft_body.hpp"
#include "mesh.hpp"
#include "constraints.hpp"
#include "tetgen.h"
SoftBody::SoftBody(const std::string &fileName) { SoftBody::SoftBody(Mesh* mesh, float compliance) : compliance(compliance) {
edges.push_back(Edge(0, 1, 10));
triangles.push_back(Triangle(Face(0, 1, 2), 40));
tetrahedra.push_back(Tetrahedron(0, 1, 2, 3, 50));
tetgenbehavior behavior;
behavior.parse_commandline(std::string("pYa0.01Qfez").data());
tetgenio in;
in.numberofpoints = static_cast<int>(mesh->vertices.size());
in.pointlist = new REAL[mesh->vertices.size() * 3];
in.numberoffacets = static_cast<int>(mesh->faces.size());
in.facetlist = new tetgenio::facet[mesh->faces.size()];
in.numberofpointattributes = 3;
in.pointattributelist = new REAL[mesh->vertices.size() * 3];
for (size_t i = 0; i < mesh->vertices.size(); i++){
in.pointlist[i * 3 + 0] = mesh->vertices[i].pos.x;
in.pointlist[i * 3 + 1] = mesh->vertices[i].pos.y;
in.pointlist[i * 3 + 2] = mesh->vertices[i].pos.z;
in.pointattributelist[i * 3 + 0] = (mesh->vertices[i].pos.x + 1) / 2;
in.pointattributelist[i * 3 + 1] = (mesh->vertices[i].pos.y + 1) / 2;
in.pointattributelist[i * 3 + 2] = (mesh->vertices[i].pos.z + 1) / 2;
}
for (size_t i = 0; i < mesh->faces.size(); i++){
tetgenio::facet &f = in.facetlist[i];
tetgenio::polygon p;
p.numberofvertices = 3;
p.vertexlist = new int[3];
p.vertexlist[0] = static_cast<int>(mesh->faces[i].a);
p.vertexlist[1] = static_cast<int>(mesh->faces[i].b);
p.vertexlist[2] = static_cast<int>(mesh->faces[i].c);
f.numberofholes = 0;
f.holelist = nullptr;
f.numberofpolygons = 1;
f.polygonlist = new tetgenio::polygon[1];
f.polygonlist[0] = p;
}
tetgenio out;
tetrahedralize(&behavior, &in, &out);
vertices.reserve(out.numberofpoints / 3);
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]);
float r = static_cast<float>(out.pointattributelist[i * 3 + 0]);
float g = static_cast<float>(out.pointattributelist[i * 3 + 1]);
float b = static_cast<float>(out.pointattributelist[i * 3 + 2]);
vertices.emplace_back(Vertex({x, y, z}, {r, g, b}));
}
faces.reserve(out.numberoftrifaces);
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];
if (out.trifacemarkerlist[i] != 0)
faces.emplace_back(Face(a, b, c));
}
faces.shrink_to_fit();
} }

@ -12,35 +12,9 @@
Application::Application() { Application::Application() {
new Instance; new Instance;
createSyncObjects();
swapchain = new Swapchain(); swapchain = new Swapchain();
graphicsPipeline = new Pipeline(swapchain->renderPass); graphicsPipeline = new Pipeline(swapchain->renderPass);
std::vector<Vertex> vertices = {
{{0.0, -0.5, 0}, {1, 0, 0}},
{{0.5, 0.5, 0}, {0, 1, 0}},
{{-0.5, 0.5, 0}, {0, 0, 1}},
{{0.8, -0.5, 0}, {1, 1, 1}}
};
vertices.insert(vertices.end(), vertices.begin(), vertices.end());
for (size_t i = 4; i < vertices.size(); i++){
vertices[i].pos.z -= 0.5f;
}
VkDeviceSize size = vertices.size() * sizeof(Vertex);
vertexBuffer = new Buffer(size, vertices.data(), size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0);
std::vector<uint32_t> indices = {
0, 1, 2, 0, 3, 1,
4, 5, 6, 4, 7, 5
};
size = indices.size() * sizeof(uint32_t);
indexBuffer = new Buffer(size, indices.data(), size,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0);
VkDeviceSize bufferSize = sizeof(UniformBufferObject); VkDeviceSize bufferSize = sizeof(UniformBufferObject);
@ -49,10 +23,8 @@ Application::Application() {
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);
graphicsPipeline->createDescriptorSet(uniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); graphicsPipeline->updateDescriptor(0, uniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
computePipeline = new ComputePipeline(vertexBuffer); computePipeline = new ComputePipeline();
createSyncObjects();
char* stats; char* stats;
vmaBuildStatsString(Instance::instance->allocator, &stats, VK_TRUE); vmaBuildStatsString(Instance::instance->allocator, &stats, VK_TRUE);
@ -63,11 +35,11 @@ Application::Application() {
void Application::updateUniformBuffer() { void Application::updateUniformBuffer() {
static float elapsed = 0; static float elapsed = 0;
// elapsed += 0.007; elapsed += 0.007;
UniformBufferObject ubo {}; UniformBufferObject ubo {};
ubo.model = glm::rotate(glm::mat4(1), elapsed * glm::radians(90.f), glm::vec3(0, 0, 1)); ubo.model = glm::rotate(glm::mat4(1), elapsed * glm::radians(90.f), glm::vec3(0, 0, 1));
ubo.view = glm::lookAt(glm::vec3(2), glm::vec3(0), glm::vec3(0, 0, 1)); ubo.view = glm::lookAt(glm::vec3(5), glm::vec3(0), glm::vec3(0, 0, 1));
ubo.projection = glm::perspective(glm::radians(45.f), ubo.projection = glm::perspective(glm::radians(45.f),
static_cast<float>(swapchain->extent.width) / static_cast<float>(swapchain->extent.height), static_cast<float>(swapchain->extent.width) / static_cast<float>(swapchain->extent.height),
0.1f, 10.f); 0.1f, 10.f);
@ -76,11 +48,13 @@ void Application::updateUniformBuffer() {
memcpy(uniformBuffer->allocationInfo.pMappedData, &ubo, sizeof(UniformBufferObject)); memcpy(uniformBuffer->allocationInfo.pMappedData, &ubo, sizeof(UniformBufferObject));
} }
void Application::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) { void Application::recordGraphicsCommandBuffer(uint32_t imageIndex) {
VkCommandBuffer cmdBuffer = Instance::instance->commandPool->graphicsBuffer;
VkCommandBufferBeginInfo beginInfo {}; VkCommandBufferBeginInfo beginInfo {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
vkBeginCommandBuffer(commandBuffer, &beginInfo); vkBeginCommandBuffer(cmdBuffer, &beginInfo);
VkRenderPassBeginInfo renderPassInfo {}; VkRenderPassBeginInfo renderPassInfo {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
@ -96,8 +70,8 @@ void Application::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t im
renderPassInfo.clearValueCount = 2; renderPassInfo.clearValueCount = 2;
renderPassInfo.pClearValues = clearValues; renderPassInfo.pClearValues = clearValues;
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(cmdBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->handle); vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->handle);
VkViewport viewport {}; VkViewport viewport {};
viewport.x = 0; viewport.x = 0;
@ -106,17 +80,17 @@ void Application::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t im
viewport.height = static_cast<float>(swapchain->extent.height); viewport.height = static_cast<float>(swapchain->extent.height);
viewport.minDepth = 0; viewport.minDepth = 0;
viewport.maxDepth = 1; viewport.maxDepth = 1;
vkCmdSetViewport(commandBuffer, 0, 1, &viewport); vkCmdSetViewport(cmdBuffer, 0, 1, &viewport);
VkRect2D scissor {}; VkRect2D scissor {};
scissor.offset = {0, 0}; scissor.offset = {0, 0};
scissor.extent = swapchain->extent; scissor.extent = swapchain->extent;
vkCmdSetScissor(commandBuffer, 0, 1, &scissor); vkCmdSetScissor(cmdBuffer, 0, 1, &scissor);
recordDrawCommands(); recordDrawCommands();
vkCmdEndRenderPass(commandBuffer); vkCmdEndRenderPass(cmdBuffer);
vkEndCommandBuffer(commandBuffer); vkEndCommandBuffer(cmdBuffer);
} }
void Application::createSyncObjects() { void Application::createSyncObjects() {
@ -149,7 +123,7 @@ void Application::drawFrame() {
vkResetFences(Instance::instance->device, 1, &renderInFlight->handle); vkResetFences(Instance::instance->device, 1, &renderInFlight->handle);
vkResetCommandBuffer(Instance::instance->commandPool->graphicsBuffer, 0); vkResetCommandBuffer(Instance::instance->commandPool->graphicsBuffer, 0);
recordCommandBuffer(Instance::instance->commandPool->graphicsBuffer, imageIndex); recordGraphicsCommandBuffer(imageIndex);
updateUniformBuffer(); updateUniformBuffer();
@ -192,18 +166,17 @@ void Application::update() {
vkResetFences(Instance::instance->device, 1, &computeInFlight->handle); vkResetFences(Instance::instance->device, 1, &computeInFlight->handle);
VkCommandBuffer commandBuffer = Instance::instance->commandPool->computeBuffer; VkCommandBuffer cmdBuffer = Instance::instance->commandPool->computeBuffer;
vkResetCommandBuffer(commandBuffer, 0); vkResetCommandBuffer(cmdBuffer, 0);
VkCommandBufferBeginInfo beginInfo {}; VkCommandBufferBeginInfo beginInfo {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = 0; beginInfo.flags = 0;
vkBeginCommandBuffer(cmdBuffer, &beginInfo);
vkBeginCommandBuffer(commandBuffer, &beginInfo); vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline->handle);
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline->handle); recordComputeCommands(cmdBuffer);
recordComputeCommands(); vkEndCommandBuffer(cmdBuffer);
vkEndCommandBuffer(commandBuffer);
VkSubmitInfo submit {}; VkSubmitInfo submit {};
submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
@ -222,8 +195,6 @@ Application::~Application() {
delete computeFinished; delete computeFinished;
delete renderInFlight; delete renderInFlight;
delete computeInFlight; delete computeInFlight;
delete vertexBuffer;
delete indexBuffer;
delete uniformBuffer; delete uniformBuffer;
delete graphicsPipeline; delete graphicsPipeline;
delete computePipeline; delete computePipeline;

@ -29,6 +29,7 @@ Pipeline::Pipeline() {
Pipeline::Pipeline(VkRenderPass renderPass) { Pipeline::Pipeline(VkRenderPass renderPass) {
createDescriptorSetLayout(); createDescriptorSetLayout();
createDescriptorPool(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); createDescriptorPool(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
allocateDescriptorSet();
auto vertShaderCode = readFile("shaders/vert.spv"); auto vertShaderCode = readFile("shaders/vert.spv");
auto fragShaderCode = readFile("shaders/frag.spv"); auto fragShaderCode = readFile("shaders/frag.spv");
@ -196,7 +197,7 @@ void Pipeline::createDescriptorPool(VkDescriptorType type) {
vkCreateDescriptorPool(Instance::instance->device, &poolInfo, nullptr, &descriptorPool); vkCreateDescriptorPool(Instance::instance->device, &poolInfo, nullptr, &descriptorPool);
} }
void Pipeline::createDescriptorSet(Buffer *buffer, VkDescriptorType type) { void Pipeline::allocateDescriptorSet() {
VkDescriptorSetAllocateInfo allocateInfo {}; VkDescriptorSetAllocateInfo allocateInfo {};
allocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; allocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocateInfo.descriptorPool = descriptorPool; allocateInfo.descriptorPool = descriptorPool;
@ -204,7 +205,9 @@ void Pipeline::createDescriptorSet(Buffer *buffer, VkDescriptorType type) {
allocateInfo.pSetLayouts = &descriptorSetLayout; allocateInfo.pSetLayouts = &descriptorSetLayout;
vkAllocateDescriptorSets(Instance::instance->device, &allocateInfo, &descriptorSet); vkAllocateDescriptorSets(Instance::instance->device, &allocateInfo, &descriptorSet);
}
void Pipeline::updateDescriptor(uint32_t binding, Buffer *buffer, VkDescriptorType type) {
VkDescriptorBufferInfo bufferInfo {}; VkDescriptorBufferInfo bufferInfo {};
bufferInfo.buffer = buffer->handle; bufferInfo.buffer = buffer->handle;
bufferInfo.offset = 0; bufferInfo.offset = 0;
@ -213,7 +216,7 @@ void Pipeline::createDescriptorSet(Buffer *buffer, VkDescriptorType type) {
VkWriteDescriptorSet descriptorWrite {}; VkWriteDescriptorSet descriptorWrite {};
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrite.dstSet = descriptorSet; descriptorWrite.dstSet = descriptorSet;
descriptorWrite.dstBinding = 0; descriptorWrite.dstBinding = binding;
descriptorWrite.dstArrayElement = 0; descriptorWrite.dstArrayElement = 0;
descriptorWrite.descriptorType = type; descriptorWrite.descriptorType = type;
descriptorWrite.descriptorCount = 1; descriptorWrite.descriptorCount = 1;
@ -222,8 +225,9 @@ void Pipeline::createDescriptorSet(Buffer *buffer, VkDescriptorType type) {
vkUpdateDescriptorSets(Instance::instance->device, 1, &descriptorWrite, 0, nullptr); vkUpdateDescriptorSets(Instance::instance->device, 1, &descriptorWrite, 0, nullptr);
} }
ComputePipeline::ComputePipeline(Buffer* buffer) { ComputePipeline::ComputePipeline() {
{ {
// Vertex buffer
VkDescriptorSetLayoutBinding layoutBinding {}; VkDescriptorSetLayoutBinding layoutBinding {};
layoutBinding.binding = 0; layoutBinding.binding = 0;
layoutBinding.descriptorCount = 1; layoutBinding.descriptorCount = 1;
@ -238,7 +242,7 @@ ComputePipeline::ComputePipeline(Buffer* buffer) {
vkCreateDescriptorSetLayout(Instance::instance->device, &descriptorSetLayoutInfo, nullptr, &descriptorSetLayout); vkCreateDescriptorSetLayout(Instance::instance->device, &descriptorSetLayoutInfo, nullptr, &descriptorSetLayout);
createDescriptorPool(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); createDescriptorPool(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
createDescriptorSet(buffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); allocateDescriptorSet();
} }
VkShaderModule module = createShaderModule(readFile("shaders/comp.spv")); VkShaderModule module = createShaderModule(readFile("shaders/comp.spv"));
@ -265,3 +269,7 @@ ComputePipeline::ComputePipeline(Buffer* buffer) {
vkDestroyShaderModule(Instance::instance->device, module, nullptr); vkDestroyShaderModule(Instance::instance->device, module, nullptr);
} }
void ComputePipeline::updateDescriptor(uint32_t binding, Buffer *buffer) {
Pipeline::updateDescriptor(binding, buffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
}

Loading…
Cancel
Save