feature/softbody-runtime-control
Benjamin Kraft 4 months ago
parent cb8ee6a962
commit 8be5d3059f
  1. 73
      include/application.hpp
  2. 54
      include/simulation.hpp
  3. 2
      include/vulkan/command_pool.hpp
  4. 4
      include/vulkan/image.hpp
  5. 13
      include/vulkan/instance.hpp
  6. 2
      shaders/shader.frag
  7. 259
      src/application.cpp
  8. 12
      src/main.cpp
  9. 205
      src/vulkan/application.cpp
  10. 10
      src/vulkan/buffer.cpp
  11. 16
      src/vulkan/command_pool.cpp
  12. 12
      src/vulkan/descriptor_pool.cpp
  13. 8
      src/vulkan/image.cpp
  14. 18
      src/vulkan/instance.cpp
  15. 18
      src/vulkan/pipeline.cpp
  16. 28
      src/vulkan/swapchain.cpp
  17. 8
      src/vulkan/synchronization.cpp

@ -15,10 +15,13 @@
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
#include <map> #include <map>
#include <glm/vec2.hpp> #include <glm/vec2.hpp>
#include "constraints.hpp"
#include <glm/vec3.hpp>
using std::unique_ptr, std::make_unique; using std::unique_ptr, std::make_unique;
using std::vector; using std::vector;
class SoftBody;
class Instance; class Instance;
class Swapchain; class Swapchain;
class GraphicsPipeline; class GraphicsPipeline;
@ -36,27 +39,63 @@ public:
explicit Application(); explicit Application();
void mainLoop(); void mainLoop();
~Application(); ~Application();
protected: private:
Swapchain* swapchain = nullptr;
DescriptorPool* descriptorPool = nullptr;
GraphicsPipeline* graphicsPipeline = nullptr;
Buffer* uniformBuffer = nullptr;
void updateUniformBuffer(); void createSyncObjects();
unique_ptr<Semaphore> imageAvailable;
unique_ptr<Semaphore> renderFinished;
unique_ptr<Semaphore> computeFinished;
unique_ptr<Fence> renderInFlight;
unique_ptr<Fence> computeInFlight;
void recordGraphicsCommandBuffer(uint32_t imageIndex); unique_ptr<Swapchain> swapchain;
unique_ptr<DescriptorPool> descriptorPool;
unique_ptr<GraphicsPipeline> graphicsPipeline;
unique_ptr<Buffer> uniformBuffer;
unique_ptr<Camera> camera;
void createMeshBuffers();
unique_ptr<Buffer> vertexBuffer;
unique_ptr<Buffer> faceBuffer;
unique_ptr<Buffer> edgeBuffer;
unique_ptr<Buffer> triangleBuffer;
unique_ptr<Buffer> tetrahedronBuffer;
ConstraintData constraintData {};
vector<unique_ptr<SoftBody>> softBodies;
struct SizeInformation {
uint32_t vertexCount;
uint32_t faceCount;
uint32_t edgeCount;
uint32_t triangleCount;
uint32_t tetrahedronCount;
};
unique_ptr<Buffer> sizeInformationBuffer;
struct Properties {
glm::vec3 gravity;
float dt;
uint32_t k;
};
unique_ptr<Buffer> propertiesBuffer;
Properties properties {};
Semaphore* imageAvailable = nullptr; void createComputePipelines();
Semaphore* renderFinished = nullptr; unique_ptr<ComputePipeline> pbdPipeline;
Semaphore* computeFinished = nullptr; unique_ptr<ComputePipeline> normalPipeline;
Fence* renderInFlight = nullptr;
Fence* computeInFlight = nullptr;
void updateUniformBuffer();
void recordGraphicsCommandBuffer(uint32_t imageIndex);
void recordDrawCommands();
void drawFrame(); void drawFrame();
virtual void recordDrawCommands() {};
virtual void recordComputeCommands(VkCommandBuffer cmdBuffer) {}
void update();
void createSyncObjects();
Camera* camera = nullptr; void recordComputeCommands(VkCommandBuffer cmdBuffer);
struct PBDPushData {
uint32_t state;
ConstraintData::Partition edgePartition;
ConstraintData::Partition tetrahedronPartition;
};
void update();
}; };

@ -1,54 +0,0 @@
#pragma once
#include "application.hpp"
#include "constraints.hpp"
#include <glm/vec3.hpp>
class SoftBody;
class Buffer;
class Simulation : public Application {
public:
Simulation();
~Simulation();
private:
unique_ptr<Buffer> vertexBuffer;
unique_ptr<Buffer> faceBuffer;
unique_ptr<Buffer> edgeBuffer;
unique_ptr<Buffer> triangleBuffer;
unique_ptr<Buffer> tetrahedronBuffer;
void createMeshBuffers();
struct SizeInformation {
uint32_t vertexCount;
uint32_t faceCount;
uint32_t edgeCount;
uint32_t triangleCount;
uint32_t tetrahedronCount;
};
unique_ptr<Buffer> sizeInformationBuffer;
struct Properties {
glm::vec3 gravity;
float dt;
uint32_t k;
};
unique_ptr<Buffer> propertiesBuffer;
Properties properties {};
struct PBDPushData {
uint32_t state;
ConstraintData::Partition edgePartition;
ConstraintData::Partition tetrahedronPartition;
};
ConstraintData constraintData {};
unique_ptr<ComputePipeline> pbdPipeline;
unique_ptr<ComputePipeline> normalPipeline;
void createComputePipelines();
vector<unique_ptr<SoftBody>> softBodies;
void recordDrawCommands() override;
void recordComputeCommands(VkCommandBuffer cmdBuffer) override;
};

@ -7,7 +7,7 @@ class Instance;
class CommandPool { class CommandPool {
public: public:
explicit CommandPool(); explicit CommandPool(VkSurfaceKHR surface);
~CommandPool(); ~CommandPool();
VkCommandBuffer graphicsBuffer = VK_NULL_HANDLE; VkCommandBuffer graphicsBuffer = VK_NULL_HANDLE;
VkCommandBuffer computeBuffer = VK_NULL_HANDLE; VkCommandBuffer computeBuffer = VK_NULL_HANDLE;

@ -7,7 +7,7 @@ class Instance;
class Image { class Image {
public: public:
explicit Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage); VkImageUsageFlags usage);
~Image(); ~Image();
@ -16,6 +16,6 @@ public:
VkImage handle = VK_NULL_HANDLE; VkImage handle = VK_NULL_HANDLE;
VkImageView view = VK_NULL_HANDLE; VkImageView view = VK_NULL_HANDLE;
private: private:
VmaAllocation allocation = VK_NULL_HANDLE; VmaAllocation allocation = nullptr;
VmaAllocationInfo allocationInfo {}; VmaAllocationInfo allocationInfo {};
}; };

@ -14,10 +14,6 @@ public:
~Instance(); ~Instance();
GLFWwindow *window = nullptr; GLFWwindow *window = nullptr;
VkSurfaceKHR surface = VK_NULL_HANDLE;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
VkDevice device = VK_NULL_HANDLE;
VmaAllocator allocator = VK_NULL_HANDLE;
VkQueue graphicsQueue = VK_NULL_HANDLE; VkQueue graphicsQueue = VK_NULL_HANDLE;
VkQueue presentQueue = VK_NULL_HANDLE; VkQueue presentQueue = VK_NULL_HANDLE;
VkQueue computeQueue = VK_NULL_HANDLE; VkQueue computeQueue = VK_NULL_HANDLE;
@ -49,7 +45,16 @@ public:
static QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface); static QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface);
static Instance* instance; static Instance* instance;
static VkDevice GetDevice();
static VkPhysicalDevice GetPhysicalDevice();
static VmaAllocator GetAllocator();
static VkSurfaceKHR GetSurface();
private: private:
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
VkDevice device = VK_NULL_HANDLE;
VkSurfaceKHR surface = VK_NULL_HANDLE;
VmaAllocator allocator = VK_NULL_HANDLE;
VkInstance handle = VK_NULL_HANDLE; VkInstance handle = VK_NULL_HANDLE;
void initWindow(); void initWindow();

@ -8,5 +8,5 @@ layout (location = 2) in vec3 normal;
void main() { void main() {
outColor = vec4((normal + vec3(1, 1, 1)) / 2, 1.0); outColor = vec4((normal + vec3(1, 1, 1)) / 2, 1.0);
outColor = vec4(uv.x, uv.y, 0.0, 1.0); // outColor = vec4(uv.x, uv.y, 0.0, 1.0);
} }

@ -1,15 +1,36 @@
#include "simulation.hpp" #include "application.hpp"
#include "vulkan/swapchain.hpp"
#include "vulkan/pipeline.hpp"
#include "vulkan/instance.hpp" #include "vulkan/instance.hpp"
#include "vulkan/command_pool.hpp"
#include "vulkan/buffer.hpp" #include "vulkan/buffer.hpp"
#include "vulkan/pipeline.hpp" #include "vulkan/command_pool.hpp"
#include "vulkan/image.hpp"
#include "vulkan/synchronization.hpp"
#include "vulkan/descriptor_pool.hpp"
#include "camera.hpp"
#include "input.hpp"
#include "soft_body.hpp" #include "soft_body.hpp"
#include "mesh.hpp" #include "mesh.hpp"
#include "constraints.hpp" #include "constraints.hpp"
#include "vulkan/descriptor_pool.hpp"
#include "timer.hpp"
Simulation::Simulation() { Application::Application() {
createSyncObjects();
swapchain = make_unique<Swapchain>();
descriptorPool = make_unique<DescriptorPool>();
graphicsPipeline = unique_ptr<GraphicsPipeline>(new GraphicsPipeline("shaders/vert.spv", "shaders/frag.spv",
swapchain->renderPass,
{descriptorPool->layouts[DescriptorSet::WORLD]}));
VkDeviceSize bufferSize = sizeof(UniformBufferObject);
uniformBuffer = make_unique<Buffer>(bufferSize,
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);
descriptorPool->bindBuffer(*uniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::WORLD, 0);
camera = make_unique<Camera>(swapchain->extent);
createMeshBuffers(); createMeshBuffers();
SizeInformation sizeInformation {}; SizeInformation sizeInformation {};
@ -42,12 +63,33 @@ Simulation::Simulation() {
createComputePipelines(); createComputePipelines();
char* stats; char* stats;
vmaBuildStatsString(Instance::instance->allocator, &stats, VK_TRUE); vmaBuildStatsString(Instance::GetAllocator(), &stats, VK_TRUE);
// printf("%s", stats); // printf("%s", stats);
vmaFreeStatsString(Instance::instance->allocator, stats); vmaFreeStatsString(Instance::GetAllocator(), stats);
} }
void Simulation::createMeshBuffers() { void Application::mainLoop() {
while (!glfwWindowShouldClose(Instance::instance->window)){
glfwPollEvents();
update();
drawFrame();
}
vkDeviceWaitIdle(Instance::GetDevice());
}
Application::~Application() {
}
void Application::createSyncObjects() {
imageAvailable = make_unique<Semaphore>();
renderFinished = make_unique<Semaphore>();
computeFinished = make_unique<Semaphore>();
renderInFlight = make_unique<Fence>(true);
computeInFlight = make_unique<Fence>(true);
}
void Application::createMeshBuffers() {
Mesh sphere("models/icosphere.ply"); Mesh sphere("models/icosphere.ply");
Mesh bunny("models/bunny_medium.ply"); Mesh bunny("models/bunny_medium.ply");
@ -161,9 +203,178 @@ void Simulation::createMeshBuffers() {
tetrahedronBuffer = make_unique<SimulationBuffer>(constraintData.tetrahedra.data(), constraintData.tetrahedra.size() * sizeof(Tetrahedron)); tetrahedronBuffer = make_unique<SimulationBuffer>(constraintData.tetrahedra.data(), constraintData.tetrahedra.size() * sizeof(Tetrahedron));
} }
void Simulation::recordDrawCommands() { void Application::createComputePipelines() {
vector<VkDescriptorSetLayout> layouts;
vector<VkPushConstantRange> pushRanges;
{
layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]);
layouts.push_back(descriptorPool->layouts[DescriptorSet::SIMULATION]);
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));
}
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));
}
}
void Application::updateUniformBuffer() {
static float elapsed = 0;
elapsed += 0.007;
UniformBufferObject ubo {};
ubo.model = glm::mat4(1);
ubo.view = camera->view();
ubo.projection = camera->projection();
ubo.projection[1][1] *= -1;
memcpy(uniformBuffer->allocationInfo.pMappedData, &ubo, sizeof(UniformBufferObject));
}
void Application::recordGraphicsCommandBuffer(uint32_t imageIndex) {
VkCommandBuffer cmdBuffer = Instance::instance->commandPool->graphicsBuffer; VkCommandBuffer cmdBuffer = Instance::instance->commandPool->graphicsBuffer;
VkCommandBufferBeginInfo beginInfo {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
vkBeginCommandBuffer(cmdBuffer, &beginInfo);
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] {};
clearValues[0].color = {{0, 0, 0, 1}};
clearValues[1].depthStencil = {1.0f, 0};
renderPassInfo.clearValueCount = 2;
renderPassInfo.pClearValues = clearValues;
vkCmdBeginRenderPass(cmdBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
VkViewport viewport {};
viewport.x = 0;
viewport.y = 0;
viewport.width = static_cast<float>(swapchain->extent.width);
viewport.height = static_cast<float>(swapchain->extent.height);
viewport.minDepth = 0;
viewport.maxDepth = 1;
vkCmdSetViewport(cmdBuffer, 0, 1, &viewport);
VkRect2D scissor {};
scissor.offset = {0, 0};
scissor.extent = swapchain->extent;
vkCmdSetScissor(cmdBuffer, 0, 1, &scissor);
recordDrawCommands();
vkCmdEndRenderPass(cmdBuffer);
vkEndCommandBuffer(cmdBuffer);
}
void Application::drawFrame() {
vkWaitForFences(Instance::GetDevice(), 1, &renderInFlight->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){
swapchain->recreateSwapchain();
return;
}
vkResetFences(Instance::GetDevice(), 1, &renderInFlight->handle);
vkResetCommandBuffer(Instance::instance->commandPool->graphicsBuffer, 0);
recordGraphicsCommandBuffer(imageIndex);
camera->update(0.017);
updateUniformBuffer();
VkSubmitInfo submitInfo {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
VkSemaphore waitSemaphores[] = {imageAvailable->handle, computeFinished->handle};
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT};
submitInfo.waitSemaphoreCount = 2;
submitInfo.pWaitSemaphores = waitSemaphores;
submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &Instance::instance->commandPool->graphicsBuffer;
VkSemaphore signalSemaphores[] = {renderFinished->handle};
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores;
vkQueueSubmit(Instance::instance->graphicsQueue, 1, &submitInfo, renderInFlight->handle);
VkPresentInfoKHR presentInfo {};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = signalSemaphores;
VkSwapchainKHR swapchains[] = {swapchain->handle};
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = swapchains;
presentInfo.pImageIndices = &imageIndex;
result = vkQueuePresentKHR(Instance::instance->presentQueue, &presentInfo);
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || Instance::instance->windowResized){
Instance::instance->windowResized = false;
swapchain->recreateSwapchain();
}
}
void Application::update() {
vkWaitForFences(Instance::GetDevice(), 1, &computeInFlight->handle, VK_TRUE, UINT64_MAX);
vkResetFences(Instance::GetDevice(), 1, &computeInFlight->handle);
VkCommandBuffer cmdBuffer = Instance::instance->commandPool->computeBuffer;
vkResetCommandBuffer(cmdBuffer, 0);
VkCommandBufferBeginInfo beginInfo {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = 0;
vkBeginCommandBuffer(cmdBuffer, &beginInfo);
recordComputeCommands(cmdBuffer);
vkEndCommandBuffer(cmdBuffer);
VkSubmitInfo submit {};
submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submit.commandBufferCount = 1;
submit.pCommandBuffers = &Instance::instance->commandPool->computeBuffer;
submit.signalSemaphoreCount = 1;
submit.pSignalSemaphores = &computeFinished->handle;
vkQueueSubmit(Instance::instance->computeQueue, 1, &submit, computeInFlight->handle);
}
void Application::recordDrawCommands() {
VkCommandBuffer cmdBuffer = Instance::instance->commandPool->graphicsBuffer;
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->handle);
VkBuffer buffers[] = {vertexBuffer->handle}; VkBuffer buffers[] = {vertexBuffer->handle};
VkDeviceSize offsets[] = {0}; VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(cmdBuffer, 0, 1, buffers, offsets); vkCmdBindVertexBuffers(cmdBuffer, 0, 1, buffers, offsets);
@ -175,7 +386,7 @@ void Simulation::recordDrawCommands() {
} }
} }
void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) { void Application::recordComputeCommands(VkCommandBuffer cmdBuffer) {
#define BlOCK_SIZE 32 #define BlOCK_SIZE 32
auto getGroupCount = [](uint32_t threads, uint32_t blockSize){ auto getGroupCount = [](uint32_t threads, uint32_t blockSize){
@ -250,35 +461,9 @@ void Simulation::recordComputeCommands(VkCommandBuffer cmdBuffer) {
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);
} }
void Simulation::createComputePipelines() {
vector<VkDescriptorSetLayout> layouts;
vector<VkPushConstantRange> pushRanges;
{
layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]);
layouts.push_back(descriptorPool->layouts[DescriptorSet::SIMULATION]);
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));
}
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));
}
}
Simulation::~Simulation() = default;

@ -1,8 +1,10 @@
#include "simulation.hpp" #include "application.hpp"
#include "vulkan/instance.hpp"
#include <thread> #include "input.hpp"
int main() { int main() {
Simulation simulation; Instance instance;
simulation.mainLoop(); Input input(Instance::instance->window);
Application application;
application.mainLoop();
} }

@ -1,205 +0,0 @@
#include "application.hpp"
#include "vulkan/swapchain.hpp"
#include "vulkan/pipeline.hpp"
#include "vulkan/instance.hpp"
#include "vulkan/buffer.hpp"
#include "vulkan/command_pool.hpp"
#include "vulkan/image.hpp"
#include "vulkan/synchronization.hpp"
#include "camera.hpp"
#include "input.hpp"
#include "vulkan/descriptor_pool.hpp"
Application::Application() {
new Instance;
new Input(Instance::instance->window);
createSyncObjects();
swapchain = new Swapchain();
descriptorPool = new DescriptorPool();
graphicsPipeline = new GraphicsPipeline("shaders/vert.spv", "shaders/frag.spv",
swapchain->renderPass,
{descriptorPool->layouts[DescriptorSet::WORLD]});
VkDeviceSize bufferSize = sizeof(UniformBufferObject);
uniformBuffer = new Buffer(bufferSize,
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);
descriptorPool->bindBuffer(*uniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::WORLD, 0);
camera = new Camera(swapchain->extent);
}
void Application::updateUniformBuffer() {
static float elapsed = 0;
elapsed += 0.007;
UniformBufferObject ubo {};
ubo.model = glm::mat4(1);
ubo.view = camera->view();
ubo.projection = camera->projection();
ubo.projection[1][1] *= -1;
memcpy(uniformBuffer->allocationInfo.pMappedData, &ubo, sizeof(UniformBufferObject));
}
void Application::recordGraphicsCommandBuffer(uint32_t imageIndex) {
VkCommandBuffer cmdBuffer = Instance::instance->commandPool->graphicsBuffer;
VkCommandBufferBeginInfo beginInfo {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
vkBeginCommandBuffer(cmdBuffer, &beginInfo);
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] {};
clearValues[0].color = {{0, 0, 0, 1}};
clearValues[1].depthStencil = {1.0f, 0};
renderPassInfo.clearValueCount = 2;
renderPassInfo.pClearValues = clearValues;
vkCmdBeginRenderPass(cmdBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->handle);
VkViewport viewport {};
viewport.x = 0;
viewport.y = 0;
viewport.width = static_cast<float>(swapchain->extent.width);
viewport.height = static_cast<float>(swapchain->extent.height);
viewport.minDepth = 0;
viewport.maxDepth = 1;
vkCmdSetViewport(cmdBuffer, 0, 1, &viewport);
VkRect2D scissor {};
scissor.offset = {0, 0};
scissor.extent = swapchain->extent;
vkCmdSetScissor(cmdBuffer, 0, 1, &scissor);
recordDrawCommands();
vkCmdEndRenderPass(cmdBuffer);
vkEndCommandBuffer(cmdBuffer);
}
void Application::createSyncObjects() {
imageAvailable = new Semaphore;
renderFinished = new Semaphore;
computeFinished = new Semaphore;
renderInFlight = new Fence(true);
computeInFlight = new Fence(true);
}
void Application::mainLoop() {
while (!glfwWindowShouldClose(Instance::instance->window)){
glfwPollEvents();
update();
drawFrame();
}
vkDeviceWaitIdle(Instance::instance->device);
}
void Application::drawFrame() {
vkWaitForFences(Instance::instance->device, 1, &renderInFlight->handle, VK_TRUE, UINT64_MAX);
uint32_t imageIndex;
VkResult result = vkAcquireNextImageKHR(Instance::instance->device, swapchain->handle, UINT64_MAX, imageAvailable->handle, VK_NULL_HANDLE, &imageIndex);
if (result == VK_ERROR_OUT_OF_DATE_KHR){
swapchain->recreateSwapchain();
return;
}
vkResetFences(Instance::instance->device, 1, &renderInFlight->handle);
vkResetCommandBuffer(Instance::instance->commandPool->graphicsBuffer, 0);
recordGraphicsCommandBuffer(imageIndex);
camera->update(0.017);
updateUniformBuffer();
VkSubmitInfo submitInfo {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
VkSemaphore waitSemaphores[] = {imageAvailable->handle, computeFinished->handle};
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT};
submitInfo.waitSemaphoreCount = 2;
submitInfo.pWaitSemaphores = waitSemaphores;
submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &Instance::instance->commandPool->graphicsBuffer;
VkSemaphore signalSemaphores[] = {renderFinished->handle};
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores;
vkQueueSubmit(Instance::instance->graphicsQueue, 1, &submitInfo, renderInFlight->handle);
VkPresentInfoKHR presentInfo {};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = signalSemaphores;
VkSwapchainKHR swapchains[] = {swapchain->handle};
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = swapchains;
presentInfo.pImageIndices = &imageIndex;
result = vkQueuePresentKHR(Instance::instance->presentQueue, &presentInfo);
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || Instance::instance->windowResized){
Instance::instance->windowResized = false;
swapchain->recreateSwapchain();
}
}
void Application::update() {
vkWaitForFences(Instance::instance->device, 1, &computeInFlight->handle, VK_TRUE, UINT64_MAX);
vkResetFences(Instance::instance->device, 1, &computeInFlight->handle);
VkCommandBuffer cmdBuffer = Instance::instance->commandPool->computeBuffer;
vkResetCommandBuffer(cmdBuffer, 0);
VkCommandBufferBeginInfo beginInfo {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = 0;
vkBeginCommandBuffer(cmdBuffer, &beginInfo);
recordComputeCommands(cmdBuffer);
vkEndCommandBuffer(cmdBuffer);
VkSubmitInfo submit {};
submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submit.commandBufferCount = 1;
submit.pCommandBuffers = &Instance::instance->commandPool->computeBuffer;
submit.signalSemaphoreCount = 1;
submit.pSignalSemaphores = &computeFinished->handle;
vkQueueSubmit(Instance::instance->computeQueue, 1, &submit, computeInFlight->handle);
}
Application::~Application() {
delete swapchain;
delete descriptorPool;
delete imageAvailable;
delete renderFinished;
delete computeFinished;
delete renderInFlight;
delete computeInFlight;
delete uniformBuffer;
delete graphicsPipeline;
delete camera;
delete Instance::instance;
}

@ -17,7 +17,7 @@ Buffer::Buffer(VkDeviceSize size, VkBufferUsageFlags bufferUsage, VmaMemoryUsage
allocationCreateInfo.usage = memoryUsage; allocationCreateInfo.usage = memoryUsage;
allocationCreateInfo.flags = flags; allocationCreateInfo.flags = flags;
vmaCreateBuffer(Instance::instance->allocator, &bufferCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo); vmaCreateBuffer(Instance::GetAllocator(), &bufferCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo);
} }
Buffer::Buffer(VkDeviceSize size, void *data, VkDeviceSize dataSize, VkBufferUsageFlags bufferUsage, Buffer::Buffer(VkDeviceSize size, void *data, VkDeviceSize dataSize, VkBufferUsageFlags bufferUsage,
@ -36,7 +36,7 @@ Buffer::Buffer(VkDeviceSize size, void *data, VkDeviceSize dataSize, VkBufferUsa
} }
Buffer::~Buffer() { Buffer::~Buffer() {
vmaDestroyBuffer(Instance::instance->allocator, handle, allocation); vmaDestroyBuffer(Instance::GetAllocator(), handle, allocation);
} }
void Buffer::copyTo(Buffer *dst) { void Buffer::copyTo(Buffer *dst) {
@ -47,7 +47,7 @@ void Buffer::copyTo(Buffer *dst) {
allocateInfo.commandBufferCount = 1; allocateInfo.commandBufferCount = 1;
VkCommandBuffer commandBuffer; VkCommandBuffer commandBuffer;
vkAllocateCommandBuffers(Instance::instance->device, &allocateInfo, &commandBuffer); vkAllocateCommandBuffers(Instance::GetDevice(), &allocateInfo, &commandBuffer);
VkCommandBufferBeginInfo beginInfo {}; VkCommandBufferBeginInfo beginInfo {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
@ -65,7 +65,7 @@ void Buffer::copyTo(Buffer *dst) {
submitInfo.pCommandBuffers = &commandBuffer; submitInfo.pCommandBuffers = &commandBuffer;
vkQueueSubmit(Instance::instance->graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE); vkQueueSubmit(Instance::instance->graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
vkDeviceWaitIdle(Instance::instance->device); vkDeviceWaitIdle(Instance::GetDevice());
vkFreeCommandBuffers(Instance::instance->device, Instance::instance->commandPool->handle, 1, &commandBuffer); vkFreeCommandBuffers(Instance::GetDevice(), Instance::instance->commandPool->handle, 1, &commandBuffer);
} }

@ -2,15 +2,15 @@
#include "application.hpp" #include "application.hpp"
#include "vulkan/instance.hpp" #include "vulkan/instance.hpp"
CommandPool::CommandPool() { CommandPool::CommandPool(VkSurfaceKHR surface) {
Instance::QueueFamilyIndices indices = Instance::findQueueFamilies(Instance::instance->physicalDevice, Instance::instance->surface); Instance::QueueFamilyIndices indices = Instance::findQueueFamilies(Instance::GetPhysicalDevice(), surface);
VkCommandPoolCreateInfo poolInfo {}; VkCommandPoolCreateInfo poolInfo {};
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
poolInfo.queueFamilyIndex = indices.graphicsAndComputeFamily.value(); poolInfo.queueFamilyIndex = indices.graphicsAndComputeFamily.value();
vkCreateCommandPool(Instance::instance->device, &poolInfo, nullptr, &handle); vkCreateCommandPool(Instance::GetDevice(), &poolInfo, nullptr, &handle);
createBuffers(); createBuffers();
} }
@ -22,12 +22,12 @@ void CommandPool::createBuffers() {
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocateInfo.commandBufferCount = 1; allocateInfo.commandBufferCount = 1;
vkAllocateCommandBuffers(Instance::instance->device, &allocateInfo, &graphicsBuffer); vkAllocateCommandBuffers(Instance::GetDevice(), &allocateInfo, &graphicsBuffer);
vkAllocateCommandBuffers(Instance::instance->device, &allocateInfo, &computeBuffer); vkAllocateCommandBuffers(Instance::GetDevice(), &allocateInfo, &computeBuffer);
} }
CommandPool::~CommandPool() { CommandPool::~CommandPool() {
vkFreeCommandBuffers(Instance::instance->device, handle, 1, &graphicsBuffer); vkFreeCommandBuffers(Instance::GetDevice(), handle, 1, &graphicsBuffer);
vkFreeCommandBuffers(Instance::instance->device, handle, 1, &computeBuffer); vkFreeCommandBuffers(Instance::GetDevice(), handle, 1, &computeBuffer);
vkDestroyCommandPool(Instance::instance->device, handle, nullptr); vkDestroyCommandPool(Instance::GetDevice(), handle, nullptr);
} }

@ -15,7 +15,7 @@ DescriptorPool::DescriptorPool() {
poolInfo.poolSizeCount = sizeof(poolSizes) / sizeof(VkDescriptorPoolSize); poolInfo.poolSizeCount = sizeof(poolSizes) / sizeof(VkDescriptorPoolSize);
poolInfo.maxSets = 10; poolInfo.maxSets = 10;
vkCreateDescriptorPool(Instance::instance->device, &poolInfo, nullptr, &handle); vkCreateDescriptorPool(Instance::GetDevice(), &poolInfo, nullptr, &handle);
std::map<DescriptorSet, std::vector<VkDescriptorSetLayoutBinding>> setBindings; std::map<DescriptorSet, std::vector<VkDescriptorSetLayoutBinding>> setBindings;
auto addBinding = [&setBindings](DescriptorSet set, VkDescriptorType type, VkShaderStageFlags stageFlags){ auto addBinding = [&setBindings](DescriptorSet set, VkDescriptorType type, VkShaderStageFlags stageFlags){
@ -62,14 +62,14 @@ DescriptorPool::DescriptorPool() {
allocateInfo.descriptorSetCount = 1; allocateInfo.descriptorSetCount = 1;
allocateInfo.pSetLayouts = &layout; allocateInfo.pSetLayouts = &layout;
vkAllocateDescriptorSets(Instance::instance->device, &allocateInfo, &sets[set]); vkAllocateDescriptorSets(Instance::GetDevice(), &allocateInfo, &sets[set]);
} }
} }
DescriptorPool::~DescriptorPool() { DescriptorPool::~DescriptorPool() {
vkDestroyDescriptorPool(Instance::instance->device, handle, nullptr); vkDestroyDescriptorPool(Instance::GetDevice(), handle, nullptr);
for (const auto &[type, layout] : layouts) for (const auto &[type, layout] : layouts)
vkDestroyDescriptorSetLayout(Instance::instance->device, layout, nullptr); 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) {
@ -87,7 +87,7 @@ void DescriptorPool::bindBuffer(const Buffer& buffer, VkDescriptorType type, Des
descriptorWrite.descriptorCount = 1; descriptorWrite.descriptorCount = 1;
descriptorWrite.pBufferInfo = &bufferInfo; descriptorWrite.pBufferInfo = &bufferInfo;
vkUpdateDescriptorSets(Instance::instance->device, 1, &descriptorWrite, 0, nullptr); vkUpdateDescriptorSets(Instance::GetDevice(), 1, &descriptorWrite, 0, nullptr);
} }
void DescriptorPool::createLayout(DescriptorSet set, const std::vector<VkDescriptorSetLayoutBinding> &bindings) { void DescriptorPool::createLayout(DescriptorSet set, const std::vector<VkDescriptorSetLayoutBinding> &bindings) {
@ -96,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, &layouts[set]); vkCreateDescriptorSetLayout(Instance::GetDevice(), &layoutCreateInfo, nullptr, &layouts[set]);
} }

@ -24,13 +24,13 @@ Image::Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling til
allocationCreateInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; allocationCreateInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
allocationCreateInfo.flags = 0; allocationCreateInfo.flags = 0;
vmaCreateImage(Instance::instance->allocator, &imageCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo); vmaCreateImage(Instance::GetAllocator(), &imageCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo);
} }
Image::~Image() { Image::~Image() {
if (view) if (view)
vkDestroyImageView(Instance::instance->device, view, nullptr); vkDestroyImageView(Instance::GetDevice(), view, nullptr);
vmaDestroyImage(Instance::instance->allocator, handle, allocation); vmaDestroyImage(Instance::GetAllocator(), handle, allocation);
} }
VkImageView Image::createView(VkFormat format, VkImageAspectFlags aspectFlags) { VkImageView Image::createView(VkFormat format, VkImageAspectFlags aspectFlags) {
@ -48,7 +48,7 @@ VkImageView Image::createView(VkFormat format, VkImageAspectFlags aspectFlags) {
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
createInfo.subresourceRange = subresourceRange; createInfo.subresourceRange = subresourceRange;
vkCreateImageView(Instance::instance->device, &createInfo, nullptr, &view); vkCreateImageView(Instance::GetDevice(), &createInfo, nullptr, &view);
return view; return view;
} }

@ -59,7 +59,7 @@ Instance::Instance() {
pickPhysicalDevice(); pickPhysicalDevice();
createLogicalDevice(); createLogicalDevice();
createAllocator(); createAllocator();
commandPool = new CommandPool; commandPool = new CommandPool(surface);
} }
void Instance::initWindow() { void Instance::initWindow() {
@ -254,6 +254,22 @@ bool Instance::checkDeviceExtensionSupport(VkPhysicalDevice device) {
return required.empty(); return required.empty();
} }
VkDevice Instance::GetDevice() {
return instance->device;
}
VkPhysicalDevice Instance::GetPhysicalDevice() {
return instance->physicalDevice;
}
VmaAllocator Instance::GetAllocator() {
return instance->allocator;
}
VkSurfaceKHR Instance::GetSurface() {
return instance->surface;
}
Instance::~Instance() { Instance::~Instance() {
delete commandPool; delete commandPool;
vmaDestroyAllocator(allocator); vmaDestroyAllocator(allocator);

@ -28,7 +28,7 @@ VkShaderModule Pipeline::createShaderModule(const std::vector<char> &code) {
createInfo.pCode = reinterpret_cast<const uint32_t *>(code.data()); createInfo.pCode = reinterpret_cast<const uint32_t *>(code.data());
VkShaderModule shaderModule; VkShaderModule shaderModule;
vkCreateShaderModule(Instance::instance->device, &createInfo, nullptr, &shaderModule); vkCreateShaderModule(Instance::GetDevice(), &createInfo, nullptr, &shaderModule);
return shaderModule; return shaderModule;
} }
@ -42,12 +42,12 @@ Pipeline::Pipeline(const std::vector<VkDescriptorSetLayout> &descriptorSetLayout
pipelineLayoutInfo.pushConstantRangeCount = pushConstantRanges.size(); pipelineLayoutInfo.pushConstantRangeCount = pushConstantRanges.size();
pipelineLayoutInfo.pPushConstantRanges = pushConstantRanges.data(); pipelineLayoutInfo.pPushConstantRanges = pushConstantRanges.data();
vkCreatePipelineLayout(Instance::instance->device, &pipelineLayoutInfo, nullptr, &layout); vkCreatePipelineLayout(Instance::GetDevice(), &pipelineLayoutInfo, nullptr, &layout);
} }
Pipeline::~Pipeline() { Pipeline::~Pipeline() {
vkDestroyPipelineLayout(Instance::instance->device, layout, nullptr); vkDestroyPipelineLayout(Instance::GetDevice(), layout, nullptr);
vkDestroyPipeline(Instance::instance->device, handle, nullptr); vkDestroyPipeline(Instance::GetDevice(), handle, nullptr);
} }
@ -160,10 +160,10 @@ GraphicsPipeline::GraphicsPipeline(const std::string& vertexShaderPath, const st
pipelineInfo.subpass = 0; pipelineInfo.subpass = 0;
} }
vkCreateGraphicsPipelines(Instance::instance->device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &handle); vkCreateGraphicsPipelines(Instance::GetDevice(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &handle);
vkDestroyShaderModule(Instance::instance->device, vertShaderModule, nullptr); vkDestroyShaderModule(Instance::GetDevice(), vertShaderModule, nullptr);
vkDestroyShaderModule(Instance::instance->device, fragShaderModule, nullptr); vkDestroyShaderModule(Instance::GetDevice(), fragShaderModule, nullptr);
} }
ComputePipeline::ComputePipeline(const std::string& shaderFile, ComputePipeline::ComputePipeline(const std::string& shaderFile,
@ -182,9 +182,9 @@ ComputePipeline::ComputePipeline(const std::string& shaderFile,
pipelineInfo.layout = layout; pipelineInfo.layout = layout;
pipelineInfo.stage = stageInfo; pipelineInfo.stage = stageInfo;
vkCreateComputePipelines(Instance::instance->device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &handle); vkCreateComputePipelines(Instance::GetDevice(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &handle);
vkDestroyShaderModule(Instance::instance->device, module, nullptr); vkDestroyShaderModule(Instance::GetDevice(), module, nullptr);
} }

@ -36,7 +36,7 @@ Swapchain::Swapchain() {
Swapchain::~Swapchain() { Swapchain::~Swapchain() {
cleanupSwapchain(); cleanupSwapchain();
vkDestroyRenderPass(Instance::instance->device, renderPass, nullptr); vkDestroyRenderPass(Instance::GetDevice(), renderPass, nullptr);
} }
VkExtent2D Swapchain::chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilities) { VkExtent2D Swapchain::chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilities) {
@ -59,7 +59,7 @@ VkExtent2D Swapchain::chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilit
} }
void Swapchain::createSwapchain() { void Swapchain::createSwapchain() {
SwapchainSupportDetails swapchainSupport = querySwapchainSupport(Instance::instance->physicalDevice, Instance::instance->surface); SwapchainSupportDetails swapchainSupport = querySwapchainSupport(Instance::GetPhysicalDevice(), Instance::GetSurface());
VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapchainSupport.formats); VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapchainSupport.formats);
VkPresentModeKHR presentMode = chooseSwapPresentMode(swapchainSupport.presentModes); VkPresentModeKHR presentMode = chooseSwapPresentMode(swapchainSupport.presentModes);
@ -72,7 +72,7 @@ void Swapchain::createSwapchain() {
VkSwapchainCreateInfoKHR createInfo {}; VkSwapchainCreateInfoKHR createInfo {};
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
createInfo.surface = Instance::instance->surface; createInfo.surface = Instance::GetSurface();
createInfo.minImageCount = imageCount; createInfo.minImageCount = imageCount;
createInfo.imageFormat = surfaceFormat.format; createInfo.imageFormat = surfaceFormat.format;
createInfo.imageColorSpace = surfaceFormat.colorSpace; createInfo.imageColorSpace = surfaceFormat.colorSpace;
@ -80,7 +80,7 @@ void Swapchain::createSwapchain() {
createInfo.imageArrayLayers = 1; createInfo.imageArrayLayers = 1;
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
Instance::QueueFamilyIndices indices = Instance::findQueueFamilies(Instance::instance->physicalDevice, Instance::instance->surface); Instance::QueueFamilyIndices indices = Instance::findQueueFamilies(Instance::GetPhysicalDevice(), Instance::GetSurface());
uint32_t queueFamilyIndices[] = {indices.graphicsFamily.value(), indices.presentFamily.value()}; uint32_t queueFamilyIndices[] = {indices.graphicsFamily.value(), indices.presentFamily.value()};
if (indices.graphicsFamily != indices.presentFamily){ if (indices.graphicsFamily != indices.presentFamily){
@ -97,28 +97,28 @@ void Swapchain::createSwapchain() {
createInfo.clipped = VK_TRUE; createInfo.clipped = VK_TRUE;
createInfo.oldSwapchain = VK_NULL_HANDLE; createInfo.oldSwapchain = VK_NULL_HANDLE;
vkCreateSwapchainKHR(Instance::instance->device, &createInfo, nullptr, &handle); vkCreateSwapchainKHR(Instance::GetDevice(), &createInfo, nullptr, &handle);
vkGetSwapchainImagesKHR(Instance::instance->device, handle, &imageCount, nullptr); vkGetSwapchainImagesKHR(Instance::GetDevice(), handle, &imageCount, nullptr);
images.resize(imageCount); images.resize(imageCount);
vkGetSwapchainImagesKHR(Instance::instance->device, handle, &imageCount, images.data()); vkGetSwapchainImagesKHR(Instance::GetDevice(), handle, &imageCount, images.data());
imageFormat = surfaceFormat.format; imageFormat = surfaceFormat.format;
} }
void Swapchain::cleanupSwapchain() { void Swapchain::cleanupSwapchain() {
for (auto framebuffer : frameBuffers){ for (auto framebuffer : frameBuffers){
vkDestroyFramebuffer(Instance::instance->device, framebuffer, nullptr); vkDestroyFramebuffer(Instance::GetDevice(), framebuffer, nullptr);
} }
for (auto imageView : imageViews){ for (auto imageView : imageViews){
vkDestroyImageView(Instance::instance->device, imageView, nullptr); vkDestroyImageView(Instance::GetDevice(), imageView, nullptr);
} }
delete depthImage; delete depthImage;
vkDestroySwapchainKHR(Instance::instance->device, handle, nullptr); vkDestroySwapchainKHR(Instance::GetDevice(), handle, nullptr);
} }
void Swapchain::recreateSwapchain() { void Swapchain::recreateSwapchain() {
vkDeviceWaitIdle(Instance::instance->device); vkDeviceWaitIdle(Instance::GetDevice());
cleanupSwapchain(); cleanupSwapchain();
@ -143,7 +143,7 @@ void Swapchain::createImageViews() {
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
}; };
createInfo.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; createInfo.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
vkCreateImageView(Instance::instance->device, &createInfo, nullptr, &imageViews[i]); vkCreateImageView(Instance::GetDevice(), &createInfo, nullptr, &imageViews[i]);
} }
} }
@ -201,7 +201,7 @@ void Swapchain::createRenderpass() {
renderPassInfo.dependencyCount = 1; renderPassInfo.dependencyCount = 1;
renderPassInfo.pDependencies = &dependency; renderPassInfo.pDependencies = &dependency;
vkCreateRenderPass(Instance::instance->device, &renderPassInfo, nullptr, &renderPass); vkCreateRenderPass(Instance::GetDevice(), &renderPassInfo, nullptr, &renderPass);
} }
void Swapchain::createDepthResources() { void Swapchain::createDepthResources() {
@ -232,7 +232,7 @@ void Swapchain::createFramebuffers() {
framebufferInfo.height = extent.height; framebufferInfo.height = extent.height;
framebufferInfo.layers = 1; framebufferInfo.layers = 1;
vkCreateFramebuffer(Instance::instance->device, &framebufferInfo, nullptr, &frameBuffers[i]); vkCreateFramebuffer(Instance::GetDevice(), &framebufferInfo, nullptr, &frameBuffers[i]);
} }
} }

@ -5,11 +5,11 @@ Semaphore::Semaphore() {
VkSemaphoreCreateInfo semaphoreInfo {}; VkSemaphoreCreateInfo semaphoreInfo {};
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
vkCreateSemaphore(Instance::instance->device, &semaphoreInfo, nullptr, &handle); vkCreateSemaphore(Instance::GetDevice(), &semaphoreInfo, nullptr, &handle);
} }
Semaphore::~Semaphore() { Semaphore::~Semaphore() {
vkDestroySemaphore(Instance::instance->device, handle, nullptr); vkDestroySemaphore(Instance::GetDevice(), handle, nullptr);
} }
Fence::Fence(bool signaled) { Fence::Fence(bool signaled) {
@ -17,9 +17,9 @@ Fence::Fence(bool signaled) {
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceInfo.flags = signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0; fenceInfo.flags = signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0;
vkCreateFence(Instance::instance->device, &fenceInfo, nullptr, &handle); vkCreateFence(Instance::GetDevice(), &fenceInfo, nullptr, &handle);
} }
Fence::~Fence() { Fence::~Fence() {
vkDestroyFence(Instance::instance->device, handle, nullptr); vkDestroyFence(Instance::GetDevice(), handle, nullptr);
} }

Loading…
Cancel
Save