Added resizing

main
Benjamin Kraft 3 weeks ago
parent 35f9b7be48
commit 3e43d096fc
  1. 1
      CMakeLists.txt
  2. 105
      main.cpp

@ -6,5 +6,6 @@ set(CMAKE_CXX_STANDARD 20)
add_executable(VulkanSimulation main.cpp) add_executable(VulkanSimulation main.cpp)
find_package(Vulkan REQUIRED) find_package(Vulkan REQUIRED)
find_package(glfw3 REQUIRED)
target_link_libraries(VulkanSimulation glfw Vulkan::Vulkan) target_link_libraries(VulkanSimulation glfw Vulkan::Vulkan)

@ -12,6 +12,7 @@
#include <optional> #include <optional>
#include <set> #include <set>
#include <fstream> #include <fstream>
#include <numeric>
const std::vector<const char*> deviceExtensions = { const std::vector<const char*> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME VK_KHR_SWAPCHAIN_EXTENSION_NAME
@ -52,6 +53,7 @@ bool checkValidationLayerSupport(){
} }
#endif #endif
constexpr int MAX_FRAMES_IN_FLIGHT = 2;
std::vector<char> readFile(const std::string& fileName){ std::vector<char> readFile(const std::string& fileName){
std::ifstream file(fileName, std::ios::ate | std::ios::binary); std::ifstream file(fileName, std::ios::ate | std::ios::binary);
@ -87,7 +89,7 @@ private:
void initWindow(){ void initWindow(){
glfwInit(); glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
window = glfwCreateWindow((int)WIDTH, (int)HEIGHT, "Vulkan Simulation", nullptr, nullptr); window = glfwCreateWindow((int)WIDTH, (int)HEIGHT, "Vulkan Simulation", nullptr, nullptr);
} }
void initVulkan(){ void initVulkan(){
@ -101,7 +103,7 @@ private:
createGraphicsPipeline(); createGraphicsPipeline();
createFramebuffers(); createFramebuffers();
createCommandPool(); createCommandPool();
createCommandBuffer(); createCommandBuffers();
createSyncObjects(); createSyncObjects();
} }
@ -403,6 +405,26 @@ private:
swapchainExtent = extent; swapchainExtent = extent;
} }
void cleanupSwapchain(){
for (auto framebuffer : swapchainFramebuffers){
vkDestroyFramebuffer(device, framebuffer, nullptr);
}
for (auto imageView : swapchainImageViews){
vkDestroyImageView(device, imageView, nullptr);
}
vkDestroySwapchainKHR(device, swapchain, nullptr);
}
void recreateSwapchain(){
vkDeviceWaitIdle(device);
cleanupSwapchain();
createSwapchain();
createImageViews();
createFramebuffers();
}
VkSwapchainKHR swapchain = VK_NULL_HANDLE; VkSwapchainKHR swapchain = VK_NULL_HANDLE;
std::vector<VkImage> swapchainImages; std::vector<VkImage> swapchainImages;
VkFormat swapchainImageFormat {}; VkFormat swapchainImageFormat {};
@ -615,7 +637,8 @@ private:
} }
VkCommandPool commandPool = VK_NULL_HANDLE; VkCommandPool commandPool = VK_NULL_HANDLE;
VkCommandBuffer commandBuffer = VK_NULL_HANDLE;
std::vector<VkCommandBuffer> commandBuffers;
void createCommandPool(){ void createCommandPool(){
QueueFamilyIndices indices = findQueueFamilies(physicalDevice); QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
@ -628,14 +651,16 @@ private:
vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool); vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool);
} }
void createCommandBuffer(){ void createCommandBuffers(){
commandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
VkCommandBufferAllocateInfo allocateInfo {}; VkCommandBufferAllocateInfo allocateInfo {};
allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocateInfo.commandPool = commandPool; allocateInfo.commandPool = commandPool;
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocateInfo.commandBufferCount = 1; allocateInfo.commandBufferCount = commandBuffers.size();
vkAllocateCommandBuffers(device, &allocateInfo, &commandBuffer); vkAllocateCommandBuffers(device, &allocateInfo, commandBuffers.data());
} }
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex){ void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex){
@ -678,11 +703,15 @@ private:
vkEndCommandBuffer(commandBuffer); vkEndCommandBuffer(commandBuffer);
} }
VkSemaphore imageAvailable = VK_NULL_HANDLE; std::vector<VkSemaphore> imageAvailableSemaphores;
VkSemaphore renderFinished = VK_NULL_HANDLE; std::vector<VkSemaphore> renderFinishedSemaphores;
VkFence inFlight = VK_NULL_HANDLE; std::vector<VkFence> inFlightFences;
void createSyncObjects(){ void createSyncObjects(){
imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
inFlightFences.resize(MAX_FRAMES_IN_FLIGHT);
VkSemaphoreCreateInfo semaphoreInfo {}; VkSemaphoreCreateInfo semaphoreInfo {};
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
@ -690,36 +719,46 @@ private:
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailable); for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++){
vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinished); vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphores[i]);
vkCreateFence(device, &fenceInfo, nullptr, &inFlight); vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphores[i]);
vkCreateFence(device, &fenceInfo, nullptr, &inFlightFences[i]);
}
} }
size_t currentFrame = 0;
void drawFrame(){ void drawFrame(){
vkWaitForFences(device, 1, &inFlight, VK_TRUE, UINT64_MAX); vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
vkResetFences(device, 1, &inFlight);
uint32_t imageIndex; uint32_t imageIndex;
vkAcquireNextImageKHR(device, swapchain, UINT64_MAX, imageAvailable, VK_NULL_HANDLE, &imageIndex); VkResult result = vkAcquireNextImageKHR(device, swapchain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
vkResetCommandBuffer(commandBuffer, 0); if (result == VK_ERROR_OUT_OF_DATE_KHR){
recordCommandBuffer(commandBuffer, imageIndex); recreateSwapchain();
return;
}
vkResetFences(device, 1, &inFlightFences[currentFrame]);
vkResetCommandBuffer(commandBuffers[currentFrame], 0);
recordCommandBuffer(commandBuffers[currentFrame], imageIndex);
VkSubmitInfo submitInfo {}; VkSubmitInfo submitInfo {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
VkSemaphore waitSemaphores[] = {imageAvailable}; VkSemaphore waitSemaphores[] = {imageAvailableSemaphores[currentFrame]};
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
submitInfo.waitSemaphoreCount = 1; submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitSemaphores = waitSemaphores;
submitInfo.pWaitDstStageMask = waitStages; submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = 1; submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer; submitInfo.pCommandBuffers = &commandBuffers[currentFrame];
VkSemaphore signalSemaphores[] = {renderFinished}; VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[currentFrame]};
submitInfo.signalSemaphoreCount = 1; submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores; submitInfo.pSignalSemaphores = signalSemaphores;
vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlight); vkQueueSubmit(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;
@ -731,7 +770,13 @@ private:
presentInfo.pSwapchains = swapchains; presentInfo.pSwapchains = swapchains;
presentInfo.pImageIndices = &imageIndex; presentInfo.pImageIndices = &imageIndex;
vkQueuePresentKHR(presentQueue, &presentInfo); result = vkQueuePresentKHR(presentQueue, &presentInfo);
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR){
recreateSwapchain();
return;
}
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
} }
void mainLoop(){ void mainLoop(){
@ -743,20 +788,16 @@ private:
vkDeviceWaitIdle(device); vkDeviceWaitIdle(device);
} }
void cleanup(){ void cleanup(){
vkDestroySemaphore(device, imageAvailable, nullptr); cleanupSwapchain();
vkDestroySemaphore(device, renderFinished, nullptr); for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++){
vkDestroyFence(device, inFlight, nullptr); vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr);
vkDestroyCommandPool(device, commandPool, nullptr); vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr);
for (auto framebuffer : swapchainFramebuffers){ vkDestroyFence(device, inFlightFences[i], nullptr);
vkDestroyFramebuffer(device, framebuffer, nullptr);
} }
vkDestroyCommandPool(device, commandPool, nullptr);
vkDestroyPipeline(device, graphicsPipeline, nullptr); vkDestroyPipeline(device, graphicsPipeline, nullptr);
vkDestroyPipelineLayout(device, pipelineLayout, nullptr); vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyRenderPass(device, renderPass, nullptr); vkDestroyRenderPass(device, renderPass, nullptr);
for (auto imageView : swapchainImageViews){
vkDestroyImageView(device, imageView, nullptr);
}
vkDestroySwapchainKHR(device, swapchain, nullptr);
vkDestroyDevice(device, nullptr); vkDestroyDevice(device, nullptr);
vkDestroySurfaceKHR(instance, surface, nullptr); vkDestroySurfaceKHR(instance, surface, nullptr);
vkDestroyInstance(instance, nullptr); vkDestroyInstance(instance, nullptr);

Loading…
Cancel
Save