singleton instance

main
Benjamin Kraft 2 weeks ago
parent 9e0b0af5e8
commit 85ebf53ee1
  1. 4
      shaders/shader.vert
  2. 6
      src/glm.h
  3. 56
      src/vulkan/application.cpp
  4. 8
      src/vulkan/application.hpp
  5. 53
      src/vulkan/buffer.cpp
  6. 17
      src/vulkan/buffer.hpp
  7. 12
      src/vulkan/command_pool.cpp
  8. 3
      src/vulkan/command_pool.hpp
  9. 4
      src/vulkan/instance.cpp
  10. 1
      src/vulkan/instance.hpp
  11. 28
      src/vulkan/pipeline.cpp
  12. 5
      src/vulkan/pipeline.hpp
  13. 33
      src/vulkan/swapchain.cpp
  14. 3
      src/vulkan/swapchain.hpp
  15. 5
      src/vulkan/vertex.hpp

@ -1,6 +1,6 @@
#version 450 #version 450
layout (location = 0) in vec2 inPosition; layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec3 inColor; layout (location = 1) in vec3 inColor;
layout (location = 0) out vec3 fragColor; layout (location = 0) out vec3 fragColor;
@ -12,6 +12,6 @@ layout (binding = 0) uniform UniformBufferObject {
} ubo; } ubo;
void main() { void main() {
gl_Position = ubo.projection * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0); gl_Position = ubo.projection * ubo.view * ubo.model * vec4(inPosition, 1.0);
fragColor = inColor; fragColor = inColor;
} }

@ -0,0 +1,6 @@
#pragma once
#define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

@ -5,33 +5,37 @@
#include "buffer.hpp" #include "buffer.hpp"
#include "command_pool.hpp" #include "command_pool.hpp"
Application::Application() { Application::Application() {
instance = new Instance; new Instance;
swapchain = new Swapchain(instance); swapchain = new Swapchain();
pipeline = new Pipeline(instance, swapchain->renderPass); pipeline = new Pipeline(swapchain->renderPass);
auto stagedVertexBuffer = Buffer::createStagedVertexBuffer(instance); auto stagedVertexBuffer = Buffer::createStagedVertexBuffer();
vertexBuffer = new Buffer(instance, stagedVertexBuffer->size, vertexBuffer = new Buffer(stagedVertexBuffer->size,
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
auto stagedIndexBuffer = Buffer::createStagedIndexBuffer(instance); auto stagedIndexBuffer = Buffer::createStagedIndexBuffer();
indexBuffer = new Buffer(instance, stagedIndexBuffer->size, indexBuffer = new Buffer(stagedIndexBuffer->size,
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
VkDeviceSize bufferSize = sizeof(UniformBufferObject); VkDeviceSize bufferSize = sizeof(UniformBufferObject);
uniformBuffer = new Buffer(instance, bufferSize, uniformBuffer = new Buffer(bufferSize,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
vkMapMemory(instance->device, uniformBuffer->memory, 0, bufferSize, 0, &uniformBufferMapped); vkMapMemory(Instance::instance->device, uniformBuffer->memory, 0, bufferSize, 0, &uniformBufferMapped);
pipeline->createDescriptorSet(uniformBuffer); pipeline->createDescriptorSet(uniformBuffer);
commandPool = new CommandPool(instance); commandPool = new CommandPool();
stagedVertexBuffer->copyTo(vertexBuffer, commandPool); stagedVertexBuffer->copyTo(vertexBuffer, commandPool);
stagedIndexBuffer->copyTo(indexBuffer, commandPool); stagedIndexBuffer->copyTo(indexBuffer, commandPool);
createDepthResources();
delete stagedVertexBuffer; delete stagedVertexBuffer;
delete stagedIndexBuffer; delete stagedIndexBuffer;
@ -101,16 +105,16 @@ void Application::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t im
} }
void Application::drawFrame() { void Application::drawFrame() {
vkWaitForFences(instance->device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX); vkWaitForFences(Instance::instance->device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
uint32_t imageIndex; uint32_t imageIndex;
VkResult result = vkAcquireNextImageKHR(instance->device, swapchain->handle, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex); VkResult result = vkAcquireNextImageKHR(Instance::instance->device, swapchain->handle, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
if (result == VK_ERROR_OUT_OF_DATE_KHR){ if (result == VK_ERROR_OUT_OF_DATE_KHR){
swapchain->recreateSwapchain(); swapchain->recreateSwapchain();
return; return;
} }
vkResetFences(instance->device, 1, &inFlightFences[currentFrame]); vkResetFences(Instance::instance->device, 1, &inFlightFences[currentFrame]);
vkResetCommandBuffer(commandPool->buffers[currentFrame], 0); vkResetCommandBuffer(commandPool->buffers[currentFrame], 0);
recordCommandBuffer(commandPool->buffers[currentFrame], imageIndex); recordCommandBuffer(commandPool->buffers[currentFrame], imageIndex);
@ -132,7 +136,7 @@ void Application::drawFrame() {
submitInfo.signalSemaphoreCount = 1; submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores; submitInfo.pSignalSemaphores = signalSemaphores;
vkQueueSubmit(instance->graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]); vkQueueSubmit(Instance::instance->graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]);
VkPresentInfoKHR presentInfo {}; VkPresentInfoKHR presentInfo {};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
@ -144,7 +148,7 @@ void Application::drawFrame() {
presentInfo.pSwapchains = swapchains; presentInfo.pSwapchains = swapchains;
presentInfo.pImageIndices = &imageIndex; presentInfo.pImageIndices = &imageIndex;
result = vkQueuePresentKHR(instance->presentQueue, &presentInfo); result = vkQueuePresentKHR(Instance::instance->presentQueue, &presentInfo);
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR){ if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR){
swapchain->recreateSwapchain(); swapchain->recreateSwapchain();
return; return;
@ -166,33 +170,37 @@ void Application::createSyncObjects() {
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++){ for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++){
vkCreateSemaphore(instance->device, &semaphoreInfo, nullptr, &imageAvailableSemaphores[i]); vkCreateSemaphore(Instance::instance->device, &semaphoreInfo, nullptr, &imageAvailableSemaphores[i]);
vkCreateSemaphore(instance->device, &semaphoreInfo, nullptr, &renderFinishedSemaphores[i]); vkCreateSemaphore(Instance::instance->device, &semaphoreInfo, nullptr, &renderFinishedSemaphores[i]);
vkCreateFence(instance->device, &fenceInfo, nullptr, &inFlightFences[i]); vkCreateFence(Instance::instance->device, &fenceInfo, nullptr, &inFlightFences[i]);
} }
} }
void Application::mainLoop() { void Application::mainLoop() {
while (!glfwWindowShouldClose(instance->window)){ while (!glfwWindowShouldClose(Instance::instance->window)){
glfwPollEvents(); glfwPollEvents();
drawFrame(); drawFrame();
} }
vkDeviceWaitIdle(instance->device); vkDeviceWaitIdle(Instance::instance->device);
} }
Application::~Application() { Application::~Application() {
delete swapchain; delete swapchain;
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++){ for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++){
vkDestroySemaphore(instance->device, imageAvailableSemaphores[i], nullptr); vkDestroySemaphore(Instance::instance->device, imageAvailableSemaphores[i], nullptr);
vkDestroySemaphore(instance->device, renderFinishedSemaphores[i], nullptr); vkDestroySemaphore(Instance::instance->device, renderFinishedSemaphores[i], nullptr);
vkDestroyFence(instance->device, inFlightFences[i], nullptr); vkDestroyFence(Instance::instance->device, inFlightFences[i], nullptr);
} }
delete commandPool; delete commandPool;
delete vertexBuffer; delete vertexBuffer;
delete indexBuffer; delete indexBuffer;
delete uniformBuffer; delete uniformBuffer;
delete pipeline; delete pipeline;
delete instance; delete Instance::instance;
}
void Application::createDepthResources() {
} }

@ -2,8 +2,6 @@
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <cstring> #include <cstring>
@ -43,7 +41,6 @@ public:
void mainLoop(); void mainLoop();
~Application(); ~Application();
private: private:
Instance* instance = nullptr;
Swapchain* swapchain = nullptr; Swapchain* swapchain = nullptr;
Pipeline* pipeline = nullptr; Pipeline* pipeline = nullptr;
Buffer* vertexBuffer = nullptr; Buffer* vertexBuffer = nullptr;
@ -53,6 +50,11 @@ private:
void* uniformBufferMapped = nullptr; void* uniformBufferMapped = nullptr;
VkImage depthImage = VK_NULL_HANDLE;
VkDeviceMemory depthImageMemory = VK_NULL_HANDLE;
VkImageView depthImageView = VK_NULL_HANDLE;
void createDepthResources();
void updateUniformBuffer(); void updateUniformBuffer();
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex); void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex);

@ -5,31 +5,31 @@
#include "instance.hpp" #include "instance.hpp"
#include "command_pool.hpp" #include "command_pool.hpp"
Buffer::Buffer(Instance* instance, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties) : instance(instance), size(size){ Buffer::Buffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties) : size(size){
VkBufferCreateInfo bufferInfo{}; VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = size; bufferInfo.size = size;
bufferInfo.usage = usage; bufferInfo.usage = usage;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
vkCreateBuffer(instance->device, &bufferInfo, nullptr, &handle); vkCreateBuffer(Instance::instance->device, &bufferInfo, nullptr, &handle);
VkMemoryRequirements memoryRequirements; VkMemoryRequirements memoryRequirements;
vkGetBufferMemoryRequirements(instance->device, handle, &memoryRequirements); vkGetBufferMemoryRequirements(Instance::instance->device, handle, &memoryRequirements);
VkMemoryAllocateInfo allocateInfo {}; VkMemoryAllocateInfo allocateInfo {};
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocateInfo.allocationSize = memoryRequirements.size; allocateInfo.allocationSize = memoryRequirements.size;
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, properties); allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, properties);
vkAllocateMemory(instance->device, &allocateInfo, nullptr, &memory); vkAllocateMemory(Instance::instance->device, &allocateInfo, nullptr, &memory);
vkBindBufferMemory(instance->device, handle, memory, 0); vkBindBufferMemory(Instance::instance->device, handle, memory, 0);
} }
uint32_t Buffer::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags propertyFlags) { uint32_t Buffer::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags propertyFlags) {
VkPhysicalDeviceMemoryProperties memoryProperties; VkPhysicalDeviceMemoryProperties memoryProperties;
vkGetPhysicalDeviceMemoryProperties(instance->physicalDevice, &memoryProperties); vkGetPhysicalDeviceMemoryProperties(Instance::instance->physicalDevice, &memoryProperties);
for (uint32_t type = 0; type < memoryProperties.memoryTypeCount; type++){ for (uint32_t type = 0; type < memoryProperties.memoryTypeCount; type++){
if ((typeFilter & (1 << type)) && (memoryProperties.memoryTypes[type].propertyFlags & propertyFlags)){ if ((typeFilter & (1 << type)) && (memoryProperties.memoryTypes[type].propertyFlags & propertyFlags)){
@ -41,35 +41,48 @@ uint32_t Buffer::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags prope
} }
Buffer::~Buffer() { Buffer::~Buffer() {
vkFreeMemory(instance->device, memory, nullptr); vkFreeMemory(Instance::instance->device, memory, nullptr);
vkDestroyBuffer(instance->device, handle, nullptr); vkDestroyBuffer(Instance::instance->device, handle, nullptr);
} }
Buffer* Buffer::createStagedVertexBuffer(Instance* instance) { Buffer* Buffer::createStagedVertexBuffer() {
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); VkDeviceSize size = vertices.size() * sizeof(Vertex);
VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
VkMemoryPropertyFlags properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; VkMemoryPropertyFlags properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
auto stagingBuffer = new Buffer(instance, size, usage, properties); auto stagingBuffer = new Buffer(size, usage, properties);
void* data; void* data;
vkMapMemory(instance->device, stagingBuffer->memory, 0, size, 0, &data); vkMapMemory(Instance::instance->device, stagingBuffer->memory, 0, size, 0, &data);
memcpy(data, vertices.data(), size); memcpy(data, vertices.data(), size);
vkUnmapMemory(instance->device, stagingBuffer->memory); vkUnmapMemory(Instance::instance->device, stagingBuffer->memory);
return stagingBuffer; return stagingBuffer;
} }
Buffer *Buffer::createStagedIndexBuffer(Instance *instance) { Buffer *Buffer::createStagedIndexBuffer() {
VkDeviceSize size = indices.size() * sizeof(uint32_t); VkDeviceSize size = indices.size() * sizeof(uint32_t);
VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
VkMemoryPropertyFlags properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; VkMemoryPropertyFlags properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
auto stagingBuffer = new Buffer(instance, size, usage, properties); auto stagingBuffer = new Buffer(size, usage, properties);
uint32_t *data; uint32_t *data;
vkMapMemory(instance->device, stagingBuffer->memory, 0, size, 0, reinterpret_cast<void**>(&data)); vkMapMemory(Instance::instance->device, stagingBuffer->memory, 0, size, 0, reinterpret_cast<void**>(&data));
memcpy(data, indices.data(), sizeof(uint32_t) * indices.size()); memcpy(data, indices.data(), sizeof(uint32_t) * indices.size());
vkUnmapMemory(instance->device, stagingBuffer->memory); vkUnmapMemory(Instance::instance->device, stagingBuffer->memory);
return stagingBuffer; return stagingBuffer;
} }
@ -82,7 +95,7 @@ void Buffer::copyTo(Buffer *dst, CommandPool* commandPool) {
allocateInfo.commandBufferCount = 1; allocateInfo.commandBufferCount = 1;
VkCommandBuffer commandBuffer; VkCommandBuffer commandBuffer;
vkAllocateCommandBuffers(instance->device, &allocateInfo, &commandBuffer); vkAllocateCommandBuffers(Instance::instance->device, &allocateInfo, &commandBuffer);
VkCommandBufferBeginInfo beginInfo {}; VkCommandBufferBeginInfo beginInfo {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
@ -99,8 +112,8 @@ void Buffer::copyTo(Buffer *dst, CommandPool* commandPool) {
submitInfo.commandBufferCount = 1; submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer; submitInfo.pCommandBuffers = &commandBuffer;
vkQueueSubmit(instance->graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE); vkQueueSubmit(Instance::instance->graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
vkDeviceWaitIdle(instance->device); vkDeviceWaitIdle(Instance::instance->device);
vkFreeCommandBuffers(instance->device, commandPool->handle, 1, &commandBuffer); vkFreeCommandBuffers(Instance::instance->device, commandPool->handle, 1, &commandBuffer);
} }

@ -4,15 +4,9 @@
#include <stdexcept> #include <stdexcept>
#include "vertex.hpp" #include "vertex.hpp"
const std::vector<Vertex> vertices = {
{{0.0, -0.5}, {1, 0, 0}},
{{0.5, 0.5}, {0, 1, 0}},
{{-0.5, 0.5}, {0, 0, 1}},
{{0.8, -0.5}, {1, 1, 1}}
};
const std::vector<uint32_t> indices = { const std::vector<uint32_t> indices = {
0, 1, 2, 0, 3, 1 0, 1, 2, 0, 3, 1,
4, 5, 6, 4, 7, 5
}; };
class Instance; class Instance;
@ -20,19 +14,18 @@ class CommandPool;
class Buffer { class Buffer {
public: public:
explicit Buffer(Instance* instance, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties); explicit Buffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties);
~Buffer(); ~Buffer();
VkBuffer handle = VK_NULL_HANDLE; VkBuffer handle = VK_NULL_HANDLE;
VkDeviceMemory memory = VK_NULL_HANDLE; VkDeviceMemory memory = VK_NULL_HANDLE;
VkDeviceSize size; VkDeviceSize size;
static Buffer* createStagedVertexBuffer(Instance* instance); static Buffer* createStagedVertexBuffer();
static Buffer* createStagedIndexBuffer(Instance* instance); static Buffer* createStagedIndexBuffer();
void copyTo(Buffer* dst, CommandPool* commandPool); void copyTo(Buffer* dst, CommandPool* commandPool);
private: private:
Instance* instance = nullptr;
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags propertyFlags); uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags propertyFlags);
}; };

@ -2,15 +2,15 @@
#include "application.hpp" #include "application.hpp"
#include "instance.hpp" #include "instance.hpp"
CommandPool::CommandPool(Instance *instance) : instance(instance) { CommandPool::CommandPool() {
Instance::QueueFamilyIndices indices = Instance::findQueueFamilies(instance->physicalDevice, instance->surface); Instance::QueueFamilyIndices indices = Instance::findQueueFamilies(Instance::instance->physicalDevice, Instance::instance->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.graphicsFamily.value(); poolInfo.queueFamilyIndex = indices.graphicsFamily.value();
vkCreateCommandPool(instance->device, &poolInfo, nullptr, &handle); vkCreateCommandPool(Instance::instance->device, &poolInfo, nullptr, &handle);
createBuffers(); createBuffers();
} }
@ -24,10 +24,10 @@ void CommandPool::createBuffers() {
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocateInfo.commandBufferCount = buffers.size(); allocateInfo.commandBufferCount = buffers.size();
vkAllocateCommandBuffers(instance->device, &allocateInfo, buffers.data()); vkAllocateCommandBuffers(Instance::instance->device, &allocateInfo, buffers.data());
} }
CommandPool::~CommandPool() { CommandPool::~CommandPool() {
vkFreeCommandBuffers(instance->device, handle, buffers.size(), buffers.data()); vkFreeCommandBuffers(Instance::instance->device, handle, buffers.size(), buffers.data());
vkDestroyCommandPool(instance->device, handle, nullptr); vkDestroyCommandPool(Instance::instance->device, handle, nullptr);
} }

@ -7,12 +7,11 @@ class Instance;
class CommandPool { class CommandPool {
public: public:
explicit CommandPool(Instance* instance); explicit CommandPool();
~CommandPool(); ~CommandPool();
std::vector<VkCommandBuffer> buffers; std::vector<VkCommandBuffer> buffers;
VkCommandPool handle = VK_NULL_HANDLE; VkCommandPool handle = VK_NULL_HANDLE;
private: private:
Instance* instance;
void createBuffers(); void createBuffers();
}; };

@ -46,7 +46,11 @@ bool checkValidationLayerSupport(){
} }
#endif #endif
Instance* Instance::instance = nullptr;
Instance::Instance() { Instance::Instance() {
instance = this;
initWindow(); initWindow();
createInstance(); createInstance();

@ -30,6 +30,7 @@ public:
}; };
static QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface); static QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface);
static Instance* instance;
private: private:
VkInstance handle = VK_NULL_HANDLE; VkInstance handle = VK_NULL_HANDLE;

@ -22,7 +22,7 @@ std::vector<char> readFile(const std::string& fileName){
return buffer; return buffer;
} }
Pipeline::Pipeline(Instance* instance, VkRenderPass renderPass) : instance(instance) { Pipeline::Pipeline(VkRenderPass renderPass) {
createDescriptorSetLayout(); createDescriptorSetLayout();
createDescriptorPool(); createDescriptorPool();
@ -107,7 +107,7 @@ Pipeline::Pipeline(Instance* instance, VkRenderPass renderPass) : instance(insta
pipelineLayoutInfo.setLayoutCount = 1; pipelineLayoutInfo.setLayoutCount = 1;
pipelineLayoutInfo.pSetLayouts = &descriptorSetLayout; pipelineLayoutInfo.pSetLayouts = &descriptorSetLayout;
vkCreatePipelineLayout(instance->device, &pipelineLayoutInfo, nullptr, &layout); vkCreatePipelineLayout(Instance::instance->device, &pipelineLayoutInfo, nullptr, &layout);
VkGraphicsPipelineCreateInfo pipelineInfo {}; VkGraphicsPipelineCreateInfo pipelineInfo {};
{ {
@ -130,10 +130,10 @@ Pipeline::Pipeline(Instance* instance, VkRenderPass renderPass) : instance(insta
pipelineInfo.subpass = 0; pipelineInfo.subpass = 0;
} }
vkCreateGraphicsPipelines(instance->device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &handle); vkCreateGraphicsPipelines(Instance::instance->device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &handle);
vkDestroyShaderModule(instance->device, vertShaderModule, nullptr); vkDestroyShaderModule(Instance::instance->device, vertShaderModule, nullptr);
vkDestroyShaderModule(instance->device, fragShaderModule, nullptr); vkDestroyShaderModule(Instance::instance->device, fragShaderModule, nullptr);
} }
VkShaderModule Pipeline::createShaderModule(const std::vector<char> &code) { VkShaderModule Pipeline::createShaderModule(const std::vector<char> &code) {
@ -143,16 +143,16 @@ 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->device, &createInfo, nullptr, &shaderModule); vkCreateShaderModule(Instance::instance->device, &createInfo, nullptr, &shaderModule);
return shaderModule; return shaderModule;
} }
Pipeline::~Pipeline() { Pipeline::~Pipeline() {
vkDestroyDescriptorPool(instance->device, descriptorPool, nullptr); vkDestroyDescriptorPool(Instance::instance->device, descriptorPool, nullptr);
vkDestroyDescriptorSetLayout(instance->device, descriptorSetLayout, nullptr); vkDestroyDescriptorSetLayout(Instance::instance->device, descriptorSetLayout, nullptr);
vkDestroyPipeline(instance->device, handle, nullptr); vkDestroyPipeline(Instance::instance->device, handle, nullptr);
vkDestroyPipelineLayout(instance->device, layout, nullptr); vkDestroyPipelineLayout(Instance::instance->device, layout, nullptr);
} }
void Pipeline::createDescriptorSetLayout() { void Pipeline::createDescriptorSetLayout() {
@ -167,7 +167,7 @@ void Pipeline::createDescriptorSetLayout() {
layoutCreateInfo.bindingCount = 1; layoutCreateInfo.bindingCount = 1;
layoutCreateInfo.pBindings = &uboLayoutBinding; layoutCreateInfo.pBindings = &uboLayoutBinding;
vkCreateDescriptorSetLayout(instance->device, &layoutCreateInfo, nullptr, &descriptorSetLayout); vkCreateDescriptorSetLayout(Instance::instance->device, &layoutCreateInfo, nullptr, &descriptorSetLayout);
} }
void Pipeline::createDescriptorPool() { void Pipeline::createDescriptorPool() {
@ -181,7 +181,7 @@ void Pipeline::createDescriptorPool() {
poolInfo.poolSizeCount = 1; poolInfo.poolSizeCount = 1;
poolInfo.maxSets = 1; poolInfo.maxSets = 1;
vkCreateDescriptorPool(instance->device, &poolInfo, nullptr, &descriptorPool); vkCreateDescriptorPool(Instance::instance->device, &poolInfo, nullptr, &descriptorPool);
} }
void Pipeline::createDescriptorSet(Buffer *buffer) { void Pipeline::createDescriptorSet(Buffer *buffer) {
@ -191,7 +191,7 @@ void Pipeline::createDescriptorSet(Buffer *buffer) {
allocateInfo.descriptorSetCount = 1; allocateInfo.descriptorSetCount = 1;
allocateInfo.pSetLayouts = &descriptorSetLayout; allocateInfo.pSetLayouts = &descriptorSetLayout;
vkAllocateDescriptorSets(instance->device, &allocateInfo, &descriptorSet); vkAllocateDescriptorSets(Instance::instance->device, &allocateInfo, &descriptorSet);
VkDescriptorBufferInfo bufferInfo {}; VkDescriptorBufferInfo bufferInfo {};
bufferInfo.buffer = buffer->handle; bufferInfo.buffer = buffer->handle;
@ -207,6 +207,6 @@ void Pipeline::createDescriptorSet(Buffer *buffer) {
descriptorWrite.descriptorCount = 1; descriptorWrite.descriptorCount = 1;
descriptorWrite.pBufferInfo = &bufferInfo; descriptorWrite.pBufferInfo = &bufferInfo;
vkUpdateDescriptorSets(instance->device, 1, &descriptorWrite, 0, nullptr); vkUpdateDescriptorSets(Instance::instance->device, 1, &descriptorWrite, 0, nullptr);
} }

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "../glm.h"
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include <glm/gtc/matrix_transform.hpp>
class Instance; class Instance;
class Buffer; class Buffer;
@ -15,7 +15,7 @@ struct UniformBufferObject {
class Pipeline { class Pipeline {
public: public:
explicit Pipeline(Instance* instance, VkRenderPass renderPass); explicit Pipeline(VkRenderPass renderPass);
~Pipeline(); ~Pipeline();
VkPipeline handle = VK_NULL_HANDLE; VkPipeline handle = VK_NULL_HANDLE;
VkPipelineLayout layout = VK_NULL_HANDLE; VkPipelineLayout layout = VK_NULL_HANDLE;
@ -27,7 +27,6 @@ private:
VkDescriptorPool descriptorPool = VK_NULL_HANDLE; VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE; VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE;
Instance* instance = nullptr;
void createDescriptorSetLayout(); void createDescriptorSetLayout();
void createDescriptorPool(); void createDescriptorPool();

@ -25,8 +25,7 @@ SwapchainSupportDetails querySwapchainSupport(VkPhysicalDevice device, VkSurface
return details; return details;
} }
Swapchain::Swapchain(Instance* instance) Swapchain::Swapchain() {
: instance(instance) {
createSwapchain(); createSwapchain();
createImageViews(); createImageViews();
createRenderpass(); createRenderpass();
@ -35,7 +34,7 @@ Swapchain::Swapchain(Instance* instance)
Swapchain::~Swapchain() { Swapchain::~Swapchain() {
cleanupSwapchain(); cleanupSwapchain();
vkDestroyRenderPass(instance->device, renderPass, nullptr); vkDestroyRenderPass(Instance::instance->device, renderPass, nullptr);
} }
VkExtent2D Swapchain::chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilities) { VkExtent2D Swapchain::chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilities) {
@ -43,7 +42,7 @@ VkExtent2D Swapchain::chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilit
return capabilities.currentExtent; return capabilities.currentExtent;
} else { } else {
int width, height; int width, height;
glfwGetFramebufferSize(instance->window, &width, &height); glfwGetFramebufferSize(Instance::instance->window, &width, &height);
VkExtent2D actualExtent = { VkExtent2D actualExtent = {
static_cast<uint32_t>(width), static_cast<uint32_t>(width),
@ -58,7 +57,7 @@ VkExtent2D Swapchain::chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilit
} }
void Swapchain::createSwapchain() { void Swapchain::createSwapchain() {
SwapchainSupportDetails swapchainSupport = querySwapchainSupport(instance->physicalDevice, instance->surface); SwapchainSupportDetails swapchainSupport = querySwapchainSupport(Instance::instance->physicalDevice, Instance::instance->surface);
VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapchainSupport.formats); VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapchainSupport.formats);
VkPresentModeKHR presentMode = chooseSwapPresentMode(swapchainSupport.presentModes); VkPresentModeKHR presentMode = chooseSwapPresentMode(swapchainSupport.presentModes);
@ -71,7 +70,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->surface; createInfo.surface = Instance::instance->surface;
createInfo.minImageCount = imageCount; createInfo.minImageCount = imageCount;
createInfo.imageFormat = surfaceFormat.format; createInfo.imageFormat = surfaceFormat.format;
createInfo.imageColorSpace = surfaceFormat.colorSpace; createInfo.imageColorSpace = surfaceFormat.colorSpace;
@ -79,7 +78,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->physicalDevice, instance->surface); Instance::QueueFamilyIndices indices = Instance::findQueueFamilies(Instance::instance->physicalDevice, Instance::instance->surface);
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){
@ -96,27 +95,27 @@ void Swapchain::createSwapchain() {
createInfo.clipped = VK_TRUE; createInfo.clipped = VK_TRUE;
createInfo.oldSwapchain = VK_NULL_HANDLE; createInfo.oldSwapchain = VK_NULL_HANDLE;
vkCreateSwapchainKHR(instance->device, &createInfo, nullptr, &handle); vkCreateSwapchainKHR(Instance::instance->device, &createInfo, nullptr, &handle);
vkGetSwapchainImagesKHR(instance->device, handle, &imageCount, nullptr); vkGetSwapchainImagesKHR(Instance::instance->device, handle, &imageCount, nullptr);
images.resize(imageCount); images.resize(imageCount);
vkGetSwapchainImagesKHR(instance->device, handle, &imageCount, images.data()); vkGetSwapchainImagesKHR(Instance::instance->device, 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->device, framebuffer, nullptr); vkDestroyFramebuffer(Instance::instance->device, framebuffer, nullptr);
} }
for (auto imageView : imageViews){ for (auto imageView : imageViews){
vkDestroyImageView(instance->device, imageView, nullptr); vkDestroyImageView(Instance::instance->device, imageView, nullptr);
} }
vkDestroySwapchainKHR(instance->device, handle, nullptr); vkDestroySwapchainKHR(Instance::instance->device, handle, nullptr);
} }
void Swapchain::recreateSwapchain() { void Swapchain::recreateSwapchain() {
vkDeviceWaitIdle(instance->device); vkDeviceWaitIdle(Instance::instance->device);
cleanupSwapchain(); cleanupSwapchain();
@ -140,7 +139,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->device, &createInfo, nullptr, &imageViews[i]); vkCreateImageView(Instance::instance->device, &createInfo, nullptr, &imageViews[i]);
} }
} }
@ -158,7 +157,7 @@ void Swapchain::createFramebuffers() {
framebufferInfo.height = extent.height; framebufferInfo.height = extent.height;
framebufferInfo.layers = 1; framebufferInfo.layers = 1;
vkCreateFramebuffer(instance->device, &framebufferInfo, nullptr, &frameBuffers[i]); vkCreateFramebuffer(Instance::instance->device, &framebufferInfo, nullptr, &frameBuffers[i]);
} }
} }
@ -212,5 +211,5 @@ void Swapchain::createRenderpass() {
renderPassInfo.dependencyCount = 1; renderPassInfo.dependencyCount = 1;
renderPassInfo.pDependencies = &dependency; renderPassInfo.pDependencies = &dependency;
vkCreateRenderPass(instance->device, &renderPassInfo, nullptr, &renderPass); vkCreateRenderPass(Instance::instance->device, &renderPassInfo, nullptr, &renderPass);
} }

@ -14,7 +14,7 @@ SwapchainSupportDetails querySwapchainSupport(VkPhysicalDevice device, VkSurface
class Swapchain { class Swapchain {
public: public:
explicit Swapchain(Instance* instance); explicit Swapchain();
~Swapchain(); ~Swapchain();
void recreateSwapchain(); void recreateSwapchain();
@ -25,7 +25,6 @@ public:
std::vector<VkFramebuffer> frameBuffers; std::vector<VkFramebuffer> frameBuffers;
VkSwapchainKHR handle = VK_NULL_HANDLE; VkSwapchainKHR handle = VK_NULL_HANDLE;
private: private:
Instance* instance = nullptr;
std::vector<VkImage> images; std::vector<VkImage> images;
VkFormat imageFormat {}; VkFormat imageFormat {};

@ -1,12 +1,11 @@
#pragma once #pragma once
#define GLM_FORCE_RADIANS #include "../glm.h"
#include <glm/glm.hpp>
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include <array> #include <array>
struct Vertex { struct Vertex {
glm::vec2 pos; glm::vec3 pos;
glm::vec3 color; glm::vec3 color;
static VkVertexInputBindingDescription getBindingDescription(); static VkVertexInputBindingDescription getBindingDescription();

Loading…
Cancel
Save