normal compute

feature/softbody-runtime-control
Benjamin Kraft 4 months ago
parent 95527a5a55
commit c84fe3e3b9
  1. 2
      include/application.hpp
  2. 2
      include/camera.hpp
  3. 3
      include/simulation.hpp
  4. 4
      include/soft_body.hpp
  5. 4
      include/vulkan/pipeline.hpp
  6. 5
      include/vulkan/vertex.hpp
  7. 3
      shaders/compile.sh
  8. 74
      shaders/normal.comp
  9. 1
      shaders/pbd.comp
  10. 3
      shaders/shader.frag
  11. 3
      shaders/shader.vert
  12. 2
      src/camera.cpp
  13. 46
      src/simulation.cpp
  14. 14
      src/soft_body.cpp
  15. 3
      src/vulkan/application.cpp
  16. 13
      src/vulkan/instance.cpp
  17. 33
      src/vulkan/pipeline.cpp
  18. 11
      src/vulkan/vertex.cpp

@ -37,8 +37,6 @@ protected:
Pipeline* graphicsPipeline = nullptr; Pipeline* graphicsPipeline = nullptr;
Buffer* uniformBuffer = nullptr; Buffer* uniformBuffer = nullptr;
ComputePipeline* computePipeline = nullptr;
void updateUniformBuffer(); void updateUniformBuffer();
void recordGraphicsCommandBuffer(uint32_t imageIndex); void recordGraphicsCommandBuffer(uint32_t imageIndex);

@ -7,7 +7,7 @@
class Camera : private MouseListener { class Camera : private MouseListener {
private: private:
glm::vec3 position {0, 0, 0}; glm::vec3 position {0, 0, 5};
float phi = 0; float phi = 0;
float theta = 0; float theta = 0;

@ -16,6 +16,9 @@ private:
Buffer* faceBuffer; Buffer* faceBuffer;
Buffer* tetrahedronBuffer; Buffer* tetrahedronBuffer;
ComputePipeline* pbdPipeline = nullptr;
ComputePipeline* normalPipeline = nullptr;
std::vector<std::unique_ptr<SoftBody>> softBodies; std::vector<std::unique_ptr<SoftBody>> softBodies;
void recordDrawCommands() override; void recordDrawCommands() override;
void recordComputeCommands(VkCommandBuffer cmdBuffer) override; void recordComputeCommands(VkCommandBuffer cmdBuffer) override;

@ -17,7 +17,9 @@ class Mesh;
class SoftBody { class SoftBody {
public: public:
explicit SoftBody(Mesh* mesh, float compliance); explicit SoftBody(Mesh* mesh, float compliance);
uint32_t indexCount = 0; uint32_t firstIndex = 0;
int32_t vertexOffset = 0;
uint32_t partitionCount = 0; uint32_t partitionCount = 0;
float compliance; float compliance;

@ -31,13 +31,13 @@ protected:
VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE; VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE;
void createDescriptorSetLayout(); void createDescriptorSetLayout();
void createDescriptorPool(VkDescriptorType type); void createDescriptorPool(VkDescriptorType type, uint32_t descriptorCount);
void allocateDescriptorSet(); void allocateDescriptorSet();
}; };
class ComputePipeline : public Pipeline { class ComputePipeline : public Pipeline {
public: public:
explicit ComputePipeline(); explicit ComputePipeline(const std::string& shaderFile, uint32_t bindings);
void updateDescriptor(uint32_t binding, Buffer* buffer); void updateDescriptor(uint32_t binding, Buffer* buffer);
}; };

@ -5,10 +5,11 @@
#include <array> #include <array>
struct Vertex { struct Vertex {
alignas(16) glm::vec3 pos; alignas(16) glm::vec3 position;
alignas(16) glm::vec3 color; alignas(16) glm::vec3 color;
alignas(16) glm::vec3 normal;
static VkVertexInputBindingDescription getBindingDescription(); static VkVertexInputBindingDescription getBindingDescription();
static std::array<VkVertexInputAttributeDescription, 2> getAttributeDescriptions(); static std::array<VkVertexInputAttributeDescription, 3> getAttributeDescriptions();
}; };

@ -1,4 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
glslc shader.vert -o vert.spv glslc shader.vert -o vert.spv
glslc shader.frag -o frag.spv glslc shader.frag -o frag.spv
glslc shader.comp -o comp.spv glslc pbd.comp -o pbd.spv
glslc --target-env=vulkan1.3 normal.comp -o normal.spv

@ -0,0 +1,74 @@
#version 450
#extension GL_EXT_shader_atomic_float : enable
layout (local_size_x = 1) in;
struct Vertex {
vec3 position;
vec3 color;
uvec3 normal;
};
struct Face {
uint a;
uint b;
uint c;
};
layout (std430, set = 0, binding = 0) buffer VertexBuffer {
Vertex vertices[];
};
layout (std430, set = 0, binding = 1) buffer FaceBuffer {
Face faces[];
};
layout (push_constant) uniform StateConstant {
uint state;
};
void atomicAddVec3(uint vID, vec3 add){
for (int i = 0; i < 3; i++) {
uint expected_memory = vertices[vID].normal[i];
float floatInput = uintBitsToFloat(vertices[vID].normal[i]) + add[i];
uint actual_content = atomicCompSwap(vertices[vID].normal[i], expected_memory, floatBitsToUint(floatInput));
while (actual_content != expected_memory) {
expected_memory = actual_content;
floatInput = uintBitsToFloat(expected_memory) + add[i];
actual_content = atomicCompSwap(vertices[vID].normal[i], expected_memory, floatBitsToUint(floatInput));
}
}
}
void reset(){
uint vID = gl_GlobalInvocationID.x;
vertices[vID].normal = floatBitsToUint(vec3(0, 0, 0));
}
void accumulate(){
uint fID = gl_GlobalInvocationID.x;
Face f = faces[fID];
Vertex v1 = vertices[f.a];
Vertex v2 = vertices[f.b];
Vertex v3 = vertices[f.c];
vec3 weightedNormal = cross(v3.position - v1.position, v2.position - v1.position);
atomicAddVec3(f.a, weightedNormal);
atomicAddVec3(f.b, weightedNormal);
atomicAddVec3(f.c, weightedNormal);
}
void norm(){
uint vID = gl_GlobalInvocationID.x;
vertices[vID].normal = floatBitsToUint(normalize(uintBitsToFloat(vertices[vID].normal)));
}
void main() {
switch (state){
case 0: reset(); break;
case 1: accumulate(); break;
case 2: norm(); break;
}
}

@ -5,6 +5,7 @@ layout (local_size_x = 32) in;
struct Vertex { struct Vertex {
vec3 position; vec3 position;
vec3 color; vec3 color;
vec3 normal;
}; };
layout (std140, set = 0, binding = 0) buffer VertexBuffer { layout (std140, set = 0, binding = 0) buffer VertexBuffer {

@ -2,7 +2,8 @@
layout (location = 0) out vec4 outColor; layout (location = 0) out vec4 outColor;
layout (location = 0) in vec3 fragColor; layout (location = 0) in vec3 fragColor;
layout (location = 1) in vec3 normal;
void main() { void main() {
outColor = vec4(fragColor, 1.0); outColor = vec4((normal + vec3(1, 1, 1)) / 2, 1.0);
} }

@ -2,8 +2,10 @@
layout (location = 0) in vec3 inPosition; layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec3 inColor; layout (location = 1) in vec3 inColor;
layout (location = 2) in vec3 inNormal;
layout (location = 0) out vec3 fragColor; layout (location = 0) out vec3 fragColor;
layout (location = 1) out vec3 normal;
layout (binding = 0) uniform UniformBufferObject { layout (binding = 0) uniform UniformBufferObject {
mat4 model; mat4 model;
@ -14,4 +16,5 @@ layout (binding = 0) uniform UniformBufferObject {
void main() { void main() {
gl_Position = ubo.projection * ubo.view * ubo.model * vec4(inPosition, 1.0); gl_Position = ubo.projection * ubo.view * ubo.model * vec4(inPosition, 1.0);
fragColor = inColor; fragColor = inColor;
normal = inNormal;
} }

@ -55,6 +55,6 @@ void Camera::mouseMoved(float deltaX, float deltaY) {
phi += deltaX / div; phi += deltaX / div;
theta += -deltaY / div; theta += -deltaY / div;
float margin = 0.1; float margin = 0.01;
theta = glm::clamp(theta, -glm::half_pi<float>() + margin, glm::half_pi<float>() - margin); theta = glm::clamp(theta, -glm::half_pi<float>() + margin, glm::half_pi<float>() - margin);
} }

@ -8,9 +8,11 @@
#include "constraints.hpp" #include "constraints.hpp"
Simulation::Simulation() { Simulation::Simulation() {
Mesh mesh("models/sphere_high.ply"); Mesh sphere("models/sphere_high.ply");
Mesh bunny("models/bunny_high.ply");
softBodies.push_back(std::make_unique<SoftBody>(&mesh, 0.3f)); softBodies.push_back(std::make_unique<SoftBody>(&sphere, 0.3f));
// softBodies.push_back(std::make_unique<SoftBody>(&bunny, 0.3f));
vector<Vertex> vertices; vector<Vertex> vertices;
vector<Edge> edges; vector<Edge> edges;
@ -19,6 +21,9 @@ Simulation::Simulation() {
vector<Tetrahedron> tetrahedra; vector<Tetrahedron> tetrahedra;
for (const std::unique_ptr<SoftBody> &softBody : softBodies){ 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()); vertices.insert(vertices.end(), softBody->vertices.begin(), softBody->vertices.end());
edges.insert(edges.end(), softBody->edges.begin(), softBody->edges.end()); edges.insert(edges.end(), softBody->edges.begin(), softBody->edges.end());
triangles.insert(triangles.end(), softBody->triangles.begin(), softBody->triangles.end()); triangles.insert(triangles.end(), softBody->triangles.begin(), softBody->triangles.end());
@ -38,7 +43,12 @@ Simulation::Simulation() {
faceBuffer = new SimulationBuffer(faces.data(), faces.size() * sizeof(Face), VK_BUFFER_USAGE_INDEX_BUFFER_BIT); faceBuffer = new SimulationBuffer(faces.data(), faces.size() * sizeof(Face), VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
tetrahedronBuffer = new SimulationBuffer(tetrahedra.data(), tetrahedra.size() * sizeof(Tetrahedron)); tetrahedronBuffer = new SimulationBuffer(tetrahedra.data(), tetrahedra.size() * sizeof(Tetrahedron));
computePipeline->updateDescriptor(0, vertexBuffer); pbdPipeline = new ComputePipeline("shaders/pbd.spv", 1);
pbdPipeline->updateDescriptor(0, vertexBuffer);
normalPipeline = new ComputePipeline("shaders/normal.spv", 2);
normalPipeline->updateDescriptor(0, vertexBuffer);
normalPipeline->updateDescriptor(1, faceBuffer);
} }
void Simulation::recordDrawCommands() { void Simulation::recordDrawCommands() {
@ -50,10 +60,14 @@ void Simulation::recordDrawCommands() {
vkCmdBindIndexBuffer(cmdBuffer, faceBuffer->handle, 0, VK_INDEX_TYPE_UINT32); vkCmdBindIndexBuffer(cmdBuffer, faceBuffer->handle, 0, VK_INDEX_TYPE_UINT32);
vkCmdBindDescriptorSets(cmdBuffer, 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(cmdBuffer, faceBuffer->size / sizeof(Face) * 3, 1, 0, 0, 0); for (const auto& softBody : softBodies){
vkCmdDrawIndexed(cmdBuffer, softBody->faces.size() * 3, 1, softBody->firstIndex, softBody->vertexOffset, 0);
}
} }
void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) { void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) {
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->handle);
SoftBody& body = *softBodies[0]; SoftBody& body = *softBodies[0];
VkMemoryBarrier barrier {}; VkMemoryBarrier barrier {};
@ -61,7 +75,7 @@ void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) {
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline->layout, 0, 1, &computePipeline->descriptorSet, 0, nullptr); vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->layout, 0, 1, &pbdPipeline->descriptorSet, 0, nullptr);
size_t subSteps = 1; size_t subSteps = 1;
@ -80,6 +94,26 @@ void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) {
vkCmdDispatch(cmdBuffer, postSolveInvocations, 1, 1); vkCmdDispatch(cmdBuffer, postSolveInvocations, 1, 1);
} }
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->handle);
vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->layout, 0, 1, &normalPipeline->descriptorSet, 0, nullptr);
uint32_t vertexGroupCount = vertexBuffer->size / sizeof(Vertex);
uint32_t faceGroupCount = faceBuffer->size / sizeof(Face);
uint32_t state = 0;
vkCmdPushConstants(cmdBuffer, normalPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state);
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);
state = 1;
vkCmdPushConstants(cmdBuffer, normalPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state);
vkCmdDispatch(cmdBuffer, faceGroupCount, 1, 1);
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &barrier, 0, nullptr, 0, nullptr);
state = 2;
vkCmdPushConstants(cmdBuffer, normalPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state);
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);
} }
Simulation::~Simulation() { Simulation::~Simulation() {
@ -88,4 +122,6 @@ Simulation::~Simulation() {
delete triangleBuffer; delete triangleBuffer;
delete faceBuffer; delete faceBuffer;
delete tetrahedronBuffer; delete tetrahedronBuffer;
delete pbdPipeline;
delete normalPipeline;
} }

@ -21,12 +21,12 @@ SoftBody::SoftBody(Mesh* mesh, float compliance) : compliance(compliance) {
in.pointattributelist = new REAL[mesh->vertices.size() * 3]; in.pointattributelist = new REAL[mesh->vertices.size() * 3];
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].pos.x; in.pointlist[i * 3 + 0] = mesh->vertices[i].position.x;
in.pointlist[i * 3 + 1] = mesh->vertices[i].pos.y; in.pointlist[i * 3 + 1] = mesh->vertices[i].position.y;
in.pointlist[i * 3 + 2] = mesh->vertices[i].pos.z; in.pointlist[i * 3 + 2] = mesh->vertices[i].position.z;
in.pointattributelist[i * 3 + 0] = (mesh->vertices[i].pos.x + 1) / 2; in.pointattributelist[i * 3 + 0] = (mesh->vertices[i].position.x + 1) / 2;
in.pointattributelist[i * 3 + 1] = (mesh->vertices[i].pos.y + 1) / 2; in.pointattributelist[i * 3 + 1] = (mesh->vertices[i].position.y + 1) / 2;
in.pointattributelist[i * 3 + 2] = (mesh->vertices[i].pos.z + 1) / 2; in.pointattributelist[i * 3 + 2] = (mesh->vertices[i].position.z + 1) / 2;
} }
for (size_t i = 0; i < mesh->faces.size(); i++){ for (size_t i = 0; i < mesh->faces.size(); i++){
@ -65,7 +65,7 @@ SoftBody::SoftBody(Mesh* mesh, float compliance) : compliance(compliance) {
uint32_t a = out.trifacelist[i * 3 + 0]; uint32_t a = out.trifacelist[i * 3 + 0];
uint32_t b = out.trifacelist[i * 3 + 1]; uint32_t b = out.trifacelist[i * 3 + 1];
uint32_t c = out.trifacelist[i * 3 + 2]; uint32_t c = out.trifacelist[i * 3 + 2];
if (out.trifacemarkerlist[i] != 1) if (out.trifacemarkerlist[i] != 0)
faces.emplace_back(Face(a, b, c)); faces.emplace_back(Face(a, b, c));
} }
faces.shrink_to_fit(); faces.shrink_to_fit();

@ -25,7 +25,6 @@ Application::Application() {
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->updateDescriptor(0, uniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); graphicsPipeline->updateDescriptor(0, uniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
computePipeline = new ComputePipeline();
camera = new Camera(swapchain->extent); camera = new Camera(swapchain->extent);
char* stats; char* stats;
@ -175,7 +174,6 @@ void Application::update() {
beginInfo.flags = 0; beginInfo.flags = 0;
vkBeginCommandBuffer(cmdBuffer, &beginInfo); vkBeginCommandBuffer(cmdBuffer, &beginInfo);
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline->handle);
recordComputeCommands(cmdBuffer); recordComputeCommands(cmdBuffer);
vkEndCommandBuffer(cmdBuffer); vkEndCommandBuffer(cmdBuffer);
@ -198,7 +196,6 @@ Application::~Application() {
delete computeInFlight; delete computeInFlight;
delete uniformBuffer; delete uniformBuffer;
delete graphicsPipeline; delete graphicsPipeline;
delete computePipeline;
delete camera; delete camera;
delete Instance::instance; delete Instance::instance;
} }

@ -7,7 +7,8 @@
#include <cstring> #include <cstring>
const std::vector<const char*> deviceExtensions = { const std::vector<const char*> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME,
}; };
#ifndef NDEBUG #ifndef NDEBUG
@ -82,7 +83,7 @@ void Instance::createInstance() {
applicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); applicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
applicationInfo.pEngineName = "No Engine"; applicationInfo.pEngineName = "No Engine";
applicationInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); applicationInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
applicationInfo.apiVersion = VK_API_VERSION_1_2; applicationInfo.apiVersion = VK_API_VERSION_1_3;
uint32_t glfwExtensionCount = 0; uint32_t glfwExtensionCount = 0;
const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
@ -146,13 +147,17 @@ void Instance::createLogicalDevice() {
queueCreateInfos.push_back(queueCreateInfo); queueCreateInfos.push_back(queueCreateInfo);
} }
VkPhysicalDeviceFeatures deviceFeatures {}; VkPhysicalDeviceFeatures deviceFeaturesCore {};
VkPhysicalDeviceShaderAtomicFloatFeaturesEXT atomicFeatures {};
atomicFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT;
atomicFeatures.shaderBufferFloat32Atomics = VK_TRUE;
VkDeviceCreateInfo createInfo {}; VkDeviceCreateInfo createInfo {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.pQueueCreateInfos = queueCreateInfos.data(); createInfo.pQueueCreateInfos = queueCreateInfos.data();
createInfo.queueCreateInfoCount = queueCreateInfos.size(); createInfo.queueCreateInfoCount = queueCreateInfos.size();
createInfo.pEnabledFeatures = &deviceFeatures; createInfo.pEnabledFeatures = &deviceFeaturesCore;
createInfo.pNext = &atomicFeatures;
createInfo.enabledExtensionCount = deviceExtensions.size(); createInfo.enabledExtensionCount = deviceExtensions.size();
createInfo.ppEnabledExtensionNames = deviceExtensions.data(); createInfo.ppEnabledExtensionNames = deviceExtensions.data();
#ifdef ENABLE_VALIDATION_LAYERS #ifdef ENABLE_VALIDATION_LAYERS

@ -28,7 +28,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, 1);
allocateDescriptorSet(); allocateDescriptorSet();
auto vertShaderCode = readFile("shaders/vert.spv"); auto vertShaderCode = readFile("shaders/vert.spv");
@ -89,7 +89,7 @@ Pipeline::Pipeline(VkRenderPass renderPass) {
rasterizer.polygonMode = VK_POLYGON_MODE_FILL; rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
rasterizer.lineWidth = 1; rasterizer.lineWidth = 1;
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
rasterizer.depthBiasClamp = VK_FALSE; rasterizer.depthBiasClamp = VK_FALSE;
VkPipelineMultisampleStateCreateInfo multisample {}; VkPipelineMultisampleStateCreateInfo multisample {};
@ -183,9 +183,9 @@ void Pipeline::createDescriptorSetLayout() {
vkCreateDescriptorSetLayout(Instance::instance->device, &layoutCreateInfo, nullptr, &descriptorSetLayout); vkCreateDescriptorSetLayout(Instance::instance->device, &layoutCreateInfo, nullptr, &descriptorSetLayout);
} }
void Pipeline::createDescriptorPool(VkDescriptorType type) { void Pipeline::createDescriptorPool(VkDescriptorType type, uint32_t descriptorCount) {
VkDescriptorPoolSize poolSize {}; VkDescriptorPoolSize poolSize {};
poolSize.descriptorCount = 1; poolSize.descriptorCount = descriptorCount;
poolSize.type = type; poolSize.type = type;
VkDescriptorPoolCreateInfo poolInfo {}; VkDescriptorPoolCreateInfo poolInfo {};
@ -225,27 +225,29 @@ void Pipeline::updateDescriptor(uint32_t binding, Buffer *buffer, VkDescriptorTy
vkUpdateDescriptorSets(Instance::instance->device, 1, &descriptorWrite, 0, nullptr); vkUpdateDescriptorSets(Instance::instance->device, 1, &descriptorWrite, 0, nullptr);
} }
ComputePipeline::ComputePipeline() { ComputePipeline::ComputePipeline(const std::string& shaderFile, uint32_t bindings) {
{ {
// Vertex buffer std::vector<VkDescriptorSetLayoutBinding> layoutBindings(bindings, VkDescriptorSetLayoutBinding());
VkDescriptorSetLayoutBinding layoutBinding {}; for (uint32_t binding = 0; binding < bindings; binding++){
layoutBinding.binding = 0; VkDescriptorSetLayoutBinding& layoutBinding = layoutBindings[binding];
layoutBinding.binding = binding;
layoutBinding.descriptorCount = 1; layoutBinding.descriptorCount = 1;
layoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; layoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
layoutBinding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; layoutBinding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
}
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo {}; VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo {};
descriptorSetLayoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; descriptorSetLayoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
descriptorSetLayoutInfo.bindingCount = 1; descriptorSetLayoutInfo.bindingCount = bindings;
descriptorSetLayoutInfo.pBindings = &layoutBinding; descriptorSetLayoutInfo.pBindings = layoutBindings.data();
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, bindings);
allocateDescriptorSet(); allocateDescriptorSet();
} }
VkShaderModule module = createShaderModule(readFile("shaders/comp.spv")); VkShaderModule module = createShaderModule(readFile(shaderFile));
VkPipelineShaderStageCreateInfo stageInfo {}; VkPipelineShaderStageCreateInfo stageInfo {};
stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@ -253,10 +255,17 @@ ComputePipeline::ComputePipeline() {
stageInfo.pName = "main"; stageInfo.pName = "main";
stageInfo.module = module; stageInfo.module = module;
VkPushConstantRange pushConstantRange {};
pushConstantRange.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
pushConstantRange.offset = 0;
pushConstantRange.size = sizeof(uint32_t);
VkPipelineLayoutCreateInfo layoutInfo {}; VkPipelineLayoutCreateInfo layoutInfo {};
layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
layoutInfo.setLayoutCount = 1; layoutInfo.setLayoutCount = 1;
layoutInfo.pSetLayouts = &descriptorSetLayout; layoutInfo.pSetLayouts = &descriptorSetLayout;
layoutInfo.pushConstantRangeCount = 1;
layoutInfo.pPushConstantRanges = &pushConstantRange;
vkCreatePipelineLayout(Instance::instance->device, &layoutInfo, nullptr, &layout); vkCreatePipelineLayout(Instance::instance->device, &layoutInfo, nullptr, &layout);

@ -8,18 +8,23 @@ VkVertexInputBindingDescription Vertex::getBindingDescription() {
return bindingDescription; return bindingDescription;
} }
std::array<VkVertexInputAttributeDescription, 2> Vertex::getAttributeDescriptions() { std::array<VkVertexInputAttributeDescription, 3> Vertex::getAttributeDescriptions() {
std::array<VkVertexInputAttributeDescription, 2> attributeDescriptions {}; std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions {};
attributeDescriptions[0].binding = 0; attributeDescriptions[0].binding = 0;
attributeDescriptions[0].location = 0; attributeDescriptions[0].location = 0;
attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT; attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[0].offset = offsetof(Vertex, pos); attributeDescriptions[0].offset = offsetof(Vertex, position);
attributeDescriptions[1].binding = 0; attributeDescriptions[1].binding = 0;
attributeDescriptions[1].location = 1; attributeDescriptions[1].location = 1;
attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT; attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[1].offset = offsetof(Vertex, color); attributeDescriptions[1].offset = offsetof(Vertex, color);
attributeDescriptions[2].binding = 0;
attributeDescriptions[2].location = 2;
attributeDescriptions[2].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[2].offset = offsetof(Vertex, normal);
return attributeDescriptions; return attributeDescriptions;
} }

Loading…
Cancel
Save