feature/softbody-runtime-control
Benjamin Kraft 4 months ago
parent d1c32ce089
commit a3da2f8f3d
  1. 3
      include/application.hpp
  2. 20
      include/simulation.hpp
  3. 2
      include/vulkan/buffer.hpp
  4. 7
      include/vulkan/descriptor_pool.hpp
  5. 35
      shaders/normal.comp
  6. 13
      shaders/pbd.comp
  7. 196
      src/simulation.cpp
  8. 9
      src/vulkan/application.cpp
  9. 55
      src/vulkan/descriptor_pool.cpp

@ -16,6 +16,9 @@
#include <map> #include <map>
#include <glm/vec2.hpp> #include <glm/vec2.hpp>
using std::unique_ptr, std::make_unique;
using std::vector;
class Instance; class Instance;
class Swapchain; class Swapchain;
class GraphicsPipeline; class GraphicsPipeline;

@ -10,16 +10,20 @@ public:
Simulation(); Simulation();
~Simulation(); ~Simulation();
private: private:
Buffer* vertexBuffer; unique_ptr<Buffer> vertexBuffer;
Buffer* edgeBuffer; unique_ptr<Buffer> faceBuffer;
Buffer* triangleBuffer; unique_ptr<Buffer> edgeBuffer;
Buffer* faceBuffer; unique_ptr<Buffer> triangleBuffer;
Buffer* tetrahedronBuffer; unique_ptr<Buffer> tetrahedronBuffer;
void createMeshBuffers();
ComputePipeline* pbdPipeline = nullptr; unique_ptr<Buffer> sizeInformationBuffer;
ComputePipeline* normalPipeline = nullptr;
std::vector<std::unique_ptr<SoftBody>> softBodies; unique_ptr<ComputePipeline> pbdPipeline;
unique_ptr<ComputePipeline> normalPipeline;
void createComputePipelines();
vector<unique_ptr<SoftBody>> softBodies;
void recordDrawCommands() override; void recordDrawCommands() override;
void recordComputeCommands(VkCommandBuffer cmdBuffer) override; void recordComputeCommands(VkCommandBuffer cmdBuffer) override;
}; };

@ -19,6 +19,8 @@ public:
VmaAllocation allocation = VK_NULL_HANDLE; VmaAllocation allocation = VK_NULL_HANDLE;
VmaAllocationInfo allocationInfo {}; VmaAllocationInfo allocationInfo {};
VkDeviceSize size; VkDeviceSize size;
Buffer(const Buffer& other) = delete;
Buffer& operator =(const Buffer& other) = delete;
private: private:
void copyTo(Buffer* dst); void copyTo(Buffer* dst);
}; };

@ -8,7 +8,8 @@ class Buffer;
enum class DescriptorSet { enum class DescriptorSet {
WORLD = 0, WORLD = 0,
MESH = 1 MESH = 1,
SIMULATION = 2
}; };
class DescriptorPool { class DescriptorPool {
@ -16,9 +17,9 @@ public:
DescriptorPool(); DescriptorPool();
~DescriptorPool(); ~DescriptorPool();
void bindBuffer(Buffer* buffer, VkDescriptorType type, DescriptorSet set, uint32_t binding); void bindBuffer(const Buffer& buffer, VkDescriptorType type, DescriptorSet set, uint32_t binding);
std::map<DescriptorSet, VkDescriptorSet> sets; std::map<DescriptorSet, VkDescriptorSet> sets;
std::map<DescriptorSet, VkDescriptorSetLayout> setLayouts; std::map<DescriptorSet, VkDescriptorSetLayout> layouts;
private: private:
VkDescriptorPool handle = VK_NULL_HANDLE; VkDescriptorPool handle = VK_NULL_HANDLE;

@ -20,10 +20,15 @@ struct Face {
layout (std430, set = 0, binding = 0) buffer VertexBuffer { layout (std430, set = 0, binding = 0) buffer VertexBuffer {
Vertex vertices[]; Vertex vertices[];
}; };
layout (std430, set = 0, binding = 3) buffer FaceBuffer { layout (std430, set = 0, binding = 1) buffer FaceBuffer {
Face faces[]; Face faces[];
}; };
layout (std140, set = 0, binding = 5) uniform Sizes {
uint vertexCount;
uint faceCount;
};
layout (push_constant) uniform PushConstants { layout (push_constant) uniform PushConstants {
uint state; uint state;
@ -42,13 +47,11 @@ void atomicAddVec3(uint vID, vec3 add){
} }
} }
void reset(){ void reset(uint vID){
uint vID = gl_GlobalInvocationID.x;
vertices[vID].normal = floatBitsToUint(vec3(0, 0, 0)); vertices[vID].normal = floatBitsToUint(vec3(0, 0, 0));
} }
void accumulate(){ void accumulate(uint fID){
uint fID = gl_GlobalInvocationID.x;
Face f = faces[fID]; Face f = faces[fID];
Vertex v1 = vertices[f.a]; Vertex v1 = vertices[f.a];
@ -61,15 +64,27 @@ void accumulate(){
atomicAddVec3(f.c, weightedNormal); atomicAddVec3(f.c, weightedNormal);
} }
void norm(){ void norm(uint vID){
uint vID = gl_GlobalInvocationID.x;
vertices[vID].normal = floatBitsToUint(normalize(uintBitsToFloat(vertices[vID].normal))); vertices[vID].normal = floatBitsToUint(normalize(uintBitsToFloat(vertices[vID].normal)));
} }
void main() { void main() {
uint id = gl_GlobalInvocationID.x;
switch (state){ switch (state){
case 0: reset(); break; case 0:
case 1: accumulate(); break; if (id < vertexCount){
case 2: norm(); break; reset(id);
}
break;
case 1:
if (id < faceCount){
accumulate(id);
}
break;
case 2:
if (id < vertexCount){
norm(id);
}
break;
} }
} }

@ -1,6 +1,6 @@
#version 450 #version 450
layout (local_size_x = 32) in; layout (local_size_x = 256) in;
struct Vertex { struct Vertex {
vec3 position; vec3 position;
@ -8,10 +8,19 @@ struct Vertex {
vec3 normal; vec3 normal;
}; };
layout (std140, set = 0, binding = 0) buffer VertexBuffer { layout (std430, set = 0, binding = 0) buffer VertexBuffer {
Vertex vertices[]; Vertex vertices[];
}; };
layout (std140, set = 1, binding = 0) uniform UBO {
float dt;
vec3 gravity;
};
layout (push_constant) uniform PushConstants {
uint state;
};
void main() { void main() {
} }

@ -9,70 +9,38 @@
#include "vulkan/descriptor_pool.hpp" #include "vulkan/descriptor_pool.hpp"
Simulation::Simulation() { Simulation::Simulation() {
Mesh sphere("models/sphere_high.ply"); createMeshBuffers();
Mesh bunny("models/bunny_high.ply");
auto body = std::make_unique<SoftBody>(&sphere, 0.3f);
for (size_t i = 0; i < 500; i++){ struct SizeInformation {
auto copy = std::make_unique<SoftBody>(*body.get()); uint32_t vertexCount;
copy->applyOffset({i / 2.f, 0, 0}); uint32_t faceCount;
softBodies.push_back(std::move(copy));
}
vector<Vertex> vertices;
vector<Edge> edges;
vector<Triangle> triangles;
vector<Face> faces;
vector<Tetrahedron> tetrahedra;
for (const std::unique_ptr<SoftBody> &softBody : softBodies){
softBody->firstIndex = faces.size() * 3;
softBody->vertexOffset = static_cast<int32_t>(vertices.size());
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());
for (auto iter = faces.begin() + softBody->firstIndex / 3; iter != faces.end(); iter++){ uint32_t edgeCount;
iter->a += softBody->vertexOffset; uint32_t triangleCount;
iter->b += softBody->vertexOffset; uint32_t tetrahedronCount;
iter->c += softBody->vertexOffset;
}
}
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) {}
}; };
SizeInformation sizeInformation {};
vertexBuffer = new SimulationBuffer(vertices.data(), vertices.size() * sizeof(Vertex), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); sizeInformation.vertexCount = vertexBuffer->size / sizeof(Vertex);
edgeBuffer = new SimulationBuffer(edges.data(), edges.size() * sizeof(Edge)); sizeInformation.faceCount = faceBuffer->size / sizeof(Face);
triangleBuffer = new SimulationBuffer(triangles.data(), triangles.size() * sizeof(Triangle));
faceBuffer = new SimulationBuffer(faces.data(), faces.size() * sizeof(Face), VK_BUFFER_USAGE_INDEX_BUFFER_BIT); sizeInformationBuffer = make_unique<Buffer>(
tetrahedronBuffer = new SimulationBuffer(tetrahedra.data(), tetrahedra.size() * sizeof(Tetrahedron)); sizeof(SizeInformation), &sizeInformation, sizeof(sizeInformation),
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
descriptorPool->bindBuffer(vertexBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 0); VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0);
descriptorPool->bindBuffer(edgeBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 1);
descriptorPool->bindBuffer(triangleBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 2); descriptorPool->bindBuffer(*vertexBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 0);
descriptorPool->bindBuffer(faceBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 3); descriptorPool->bindBuffer(*faceBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 1);
descriptorPool->bindBuffer(tetrahedronBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 4); descriptorPool->bindBuffer(*edgeBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 2);
descriptorPool->bindBuffer(*triangleBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 3);
pbdPipeline = new ComputePipeline("shaders/pbd.spv", {descriptorPool->setLayouts[DescriptorSet::MESH]}); descriptorPool->bindBuffer(*tetrahedronBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 4);
descriptorPool->bindBuffer(*sizeInformationBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::MESH, 5);
normalPipeline = new ComputePipeline("shaders/normal.spv", { createComputePipelines();
descriptorPool->setLayouts[DescriptorSet::MESH]
},{ char* stats;
{ vmaBuildStatsString(Instance::instance->allocator, &stats, VK_TRUE);
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, // printf("%s", stats);
.offset = 0, vmaFreeStatsString(Instance::instance->allocator, stats);
.size = sizeof(uint32_t)
}
});
} }
void Simulation::recordDrawCommands() { void Simulation::recordDrawCommands() {
@ -88,6 +56,15 @@ void Simulation::recordDrawCommands() {
} }
void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) { void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) {
#define BlOCK_SIZE 256
auto getGroupCount = [](uint32_t threads, uint32_t blockSize){
return (threads - 1) / blockSize + 1;
};
uint32_t vertexGroupCount = getGroupCount(vertexBuffer->size / sizeof(Vertex), BlOCK_SIZE);
uint32_t faceGroupCount = getGroupCount(faceBuffer->size / sizeof(Face), BlOCK_SIZE);
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->handle); vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->handle);
VkMemoryBarrier barrier {}; VkMemoryBarrier barrier {};
@ -100,8 +77,7 @@ void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) {
size_t subSteps = 1; size_t subSteps = 1;
for (size_t i = 0; i < subSteps; i++){ for (size_t i = 0; i < subSteps; i++){
uint32_t preSolveInvocations = 1; vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 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); vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr);
uint32_t partitionCount = 1; uint32_t partitionCount = 1;
@ -110,22 +86,14 @@ void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) {
vkCmdDispatch(cmdBuffer, partitionSize, 1, 1); vkCmdDispatch(cmdBuffer, partitionSize, 1, 1);
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr); vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr);
} }
uint32_t postSolveInvocations = 1;
vkCmdDispatch(cmdBuffer, postSolveInvocations, 1, 1); vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1);
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr);
} }
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->handle); vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->handle);
vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr); vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr);
#define BlOCK_SIZE 256
auto getGroupCount = [](uint32_t threads, uint32_t blockSize){
return (threads - 1) / blockSize + 1;
};
uint32_t vertexGroupCount = getGroupCount(vertexBuffer->size / sizeof(Vertex), BlOCK_SIZE);
uint32_t faceGroupCount = getGroupCount(faceBuffer->size / sizeof(Face), BlOCK_SIZE);
uint32_t state = 0; uint32_t state = 0;
vkCmdPushConstants(cmdBuffer, normalPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state); vkCmdPushConstants(cmdBuffer, normalPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state);
vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1); vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1);
@ -143,11 +111,77 @@ void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) {
} }
Simulation::~Simulation() { Simulation::~Simulation() {
delete vertexBuffer;
delete edgeBuffer; }
delete triangleBuffer;
delete faceBuffer; void Simulation::createMeshBuffers() {
delete tetrahedronBuffer; Mesh sphere("models/sphere_high.ply");
delete pbdPipeline; Mesh bunny("models/bunny_high.ply");
delete normalPipeline;
auto body = std::make_unique<SoftBody>(&sphere, 0.3f);
for (size_t i = 0; i < 500; i++){
auto copy = std::make_unique<SoftBody>(*body.get());
copy->applyOffset({i / 2.f, 0, 0});
softBodies.push_back(std::move(copy));
}
vector<Vertex> vertices;
vector<Edge> edges;
vector<Triangle> triangles;
vector<Face> faces;
vector<Tetrahedron> tetrahedra;
for (const std::unique_ptr<SoftBody> &softBody : softBodies){
softBody->firstIndex = faces.size() * 3;
softBody->vertexOffset = static_cast<int32_t>(vertices.size());
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());
for (auto face = faces.begin() + softBody->firstIndex / 3; face != faces.end(); face++){
face->a += softBody->vertexOffset;
face->b += softBody->vertexOffset;
face->c += softBody->vertexOffset;
}
}
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 = make_unique<SimulationBuffer>(vertices.data(), vertices.size() * sizeof(Vertex), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
faceBuffer = make_unique<SimulationBuffer>(faces.data(), faces.size() * sizeof(Face), VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
edgeBuffer = make_unique<SimulationBuffer>(edges.data(), edges.size() * sizeof(Edge));
triangleBuffer = make_unique<SimulationBuffer>(triangles.data(), triangles.size() * sizeof(Triangle));
tetrahedronBuffer = make_unique<SimulationBuffer>(tetrahedra.data(), tetrahedra.size() * sizeof(Tetrahedron));
}
void Simulation::createComputePipelines() {
vector<VkDescriptorSetLayout> layouts;
vector<VkPushConstantRange> pushRanges;
{
layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]);
pbdPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/pbd.spv", layouts));
}
layouts.clear();
pushRanges.clear();
{
layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]);
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));
}
} }

@ -19,7 +19,7 @@ Application::Application() {
descriptorPool = new DescriptorPool(); descriptorPool = new DescriptorPool();
graphicsPipeline = new GraphicsPipeline("shaders/vert.spv", "shaders/frag.spv", graphicsPipeline = new GraphicsPipeline("shaders/vert.spv", "shaders/frag.spv",
swapchain->renderPass, swapchain->renderPass,
{descriptorPool->setLayouts[DescriptorSet::WORLD]}); {descriptorPool->layouts[DescriptorSet::WORLD]});
VkDeviceSize bufferSize = sizeof(UniformBufferObject); VkDeviceSize bufferSize = sizeof(UniformBufferObject);
@ -28,13 +28,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);
descriptorPool->bindBuffer(uniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::WORLD, 0); descriptorPool->bindBuffer(*uniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::WORLD, 0);
camera = new Camera(swapchain->extent); camera = new Camera(swapchain->extent);
char* stats;
vmaBuildStatsString(Instance::instance->allocator, &stats, VK_TRUE);
// printf("%s", stats);
vmaFreeStatsString(Instance::instance->allocator, stats);
} }
void Application::updateUniformBuffer() { void Application::updateUniformBuffer() {

@ -18,25 +18,44 @@ DescriptorPool::DescriptorPool() {
vkCreateDescriptorPool(Instance::instance->device, &poolInfo, nullptr, &handle); vkCreateDescriptorPool(Instance::instance->device, &poolInfo, nullptr, &handle);
std::map<DescriptorSet, std::vector<VkDescriptorSetLayoutBinding>> setBindings; std::map<DescriptorSet, std::vector<VkDescriptorSetLayoutBinding>> setBindings;
setBindings[DescriptorSet::WORLD].push_back({ auto addBinding = [&setBindings](DescriptorSet set, VkDescriptorType type, VkShaderStageFlags stageFlags){
.binding = 0, uint32_t binding = setBindings[set].size();
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, setBindings[set].push_back({
.descriptorCount = 1, .binding = binding,
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT .descriptorType = type,
});
for (uint32_t i = 0; i < 5; i++){
setBindings[DescriptorSet::MESH].push_back({
.binding = i,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.descriptorCount = 1, .descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT .stageFlags = stageFlags
}); });
} };
// camera
addBinding(DescriptorSet::WORLD, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT);
// vertices
addBinding(DescriptorSet::MESH, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
// faces
addBinding(DescriptorSet::MESH, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
// edges
addBinding(DescriptorSet::MESH, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
// triangles
addBinding(DescriptorSet::MESH, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
// tetrahedra
addBinding(DescriptorSet::MESH, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
// sizes
addBinding(DescriptorSet::MESH, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
// dt
addBinding(DescriptorSet::SIMULATION, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
for (const auto &[set, bindings] : setBindings) for (const auto &[set, bindings] : setBindings)
createLayout(set, bindings); createLayout(set, bindings);
for (const auto &[set, layout] : setLayouts){ for (const auto &[set, layout] : layouts){
VkDescriptorSetAllocateInfo allocateInfo {}; VkDescriptorSetAllocateInfo allocateInfo {};
allocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; allocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocateInfo.descriptorPool = handle; allocateInfo.descriptorPool = handle;
@ -49,15 +68,15 @@ DescriptorPool::DescriptorPool() {
DescriptorPool::~DescriptorPool() { DescriptorPool::~DescriptorPool() {
vkDestroyDescriptorPool(Instance::instance->device, handle, nullptr); vkDestroyDescriptorPool(Instance::instance->device, handle, nullptr);
for (const auto &[type, layout] : setLayouts) for (const auto &[type, layout] : layouts)
vkDestroyDescriptorSetLayout(Instance::instance->device, layout, nullptr); vkDestroyDescriptorSetLayout(Instance::instance->device, layout, nullptr);
} }
void DescriptorPool::bindBuffer(Buffer *buffer, VkDescriptorType type, DescriptorSet set, uint32_t binding) { void DescriptorPool::bindBuffer(const Buffer& buffer, VkDescriptorType type, DescriptorSet set, uint32_t binding) {
VkDescriptorBufferInfo bufferInfo {}; VkDescriptorBufferInfo bufferInfo {};
bufferInfo.buffer = buffer->handle; bufferInfo.buffer = buffer.handle;
bufferInfo.offset = 0; bufferInfo.offset = 0;
bufferInfo.range = buffer->size; bufferInfo.range = buffer.size;
VkWriteDescriptorSet descriptorWrite {}; VkWriteDescriptorSet descriptorWrite {};
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
@ -77,5 +96,5 @@ void DescriptorPool::createLayout(DescriptorSet set, const std::vector<VkDescrip
layoutCreateInfo.bindingCount = bindings.size(); layoutCreateInfo.bindingCount = bindings.size();
layoutCreateInfo.pBindings = bindings.data(); layoutCreateInfo.pBindings = bindings.data();
vkCreateDescriptorSetLayout(Instance::instance->device, &layoutCreateInfo, nullptr, &setLayouts[set]); vkCreateDescriptorSetLayout(Instance::instance->device, &layoutCreateInfo, nullptr, &layouts[set]);
} }

Loading…
Cancel
Save