This commit is contained in:
2026-02-03 18:26:14 -05:00
commit 82acaafaac
32 changed files with 1468 additions and 0 deletions
+136
View File
@@ -0,0 +1,136 @@
#include "app.h"
#include <cstdint>
#include <stdexcept>
#include <vulkan/vulkan.hpp>
#include <vulkan/vulkan_core.h>
#include "vulkan/vulkan.hpp"
void Application::run() {
initWindow();
initVulkan();
mainLoop();
cleanup();
}
void Application::initVulkan() {
createInstance();
setupDebugMessenger();
createSurface();
pickPhysicalDevice();
createLogicalDevice();
createSwapChain();
createImageViews();
createGraphicsPipeline();
createCommandPool();
createCommandBuffer();
createSyncObjects();
}
void Application::mainLoop() {
// Loop until the window should be closed
while (!glfwWindowShouldClose(m_window)) {
// Poll for new window events
glfwPollEvents();
// Draw the next frame
drawFrame();
}
// Once the window is closed, its time to clean up everything. Which once we are out of this function GPU objects
// are de-allocated Since there is a high chance the GPU is still working on stuff, we need to wait for the device
// to idle before we return.
m_device.waitIdle();
}
void Application::drawFrame() {
// Wait for the previous frame to end
auto fenceResult = m_device.waitForFences(*m_inFlightFences[m_frameIndex], vk::True, UINT64_MAX);
// Get the next image in the swapchain
auto [result, imageIndex] =
m_swapchain.acquireNextImage(UINT64_MAX, *m_presentCompleteSemaphores[m_frameIndex], nullptr);
// Check to make sure the swapchain didn't report an eErrorOutOfDateKHR error
if (result == vk::Result::eErrorOutOfDateKHR) {
// Recreate the swapchain
recreateSwapchain();
return;
}
// If the result isn't a eSuccess or eSuboptimalKHR, something has gone wrong and we should report on it.
if (result != vk::Result::eSuccess && result != vk::Result::eSuboptimalKHR) {
throw std::runtime_error("Failed to acquire next swapchain image");
}
// Reset the fence of the current image
m_device.resetFences(*m_inFlightFences[m_frameIndex]);
// Record the command buffer
recordCommandBuffer(imageIndex);
// Submit the command buffer to the queue
vk::PipelineStageFlags waitDestinationStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput);
const vk::SubmitInfo submitInfo{// Wait for the current frames present semaphore
.waitSemaphoreCount = 1,
.pWaitSemaphores = &*m_presentCompleteSemaphores[m_frameIndex],
// Set our destination
.pWaitDstStageMask = &waitDestinationStageMask,
// Pass the command buffer/s to submit
.commandBufferCount = 1,
.pCommandBuffers = &*m_commandBuffers[m_frameIndex],
// Pass the rendering semaphore to signal when done
.signalSemaphoreCount = 1,
.pSignalSemaphores = &*m_renderFinishedSemaphores[imageIndex]};
// Submit to the graphics queue
m_queue.submit(submitInfo, *m_inFlightFences[m_frameIndex]);
// Present the image
try {
const vk::PresentInfoKHR presentInfo{
// Wait for the rendering semaphore
.waitSemaphoreCount = 1,
.pWaitSemaphores = &*m_renderFinishedSemaphores[imageIndex],
// Pass the swapchain we want to present with
.swapchainCount = 1,
.pSwapchains = &*m_swapchain,
// Pass the imageIndex of image we want to present in the swapchain
.pImageIndices = &imageIndex,
.pResults = nullptr // Optional, allows you to specify an array of vk::Result values to check for every
// swapchain. We only have one so we can just use the vk::Result returned from the
// present function
};
result = m_queue.presentKHR(presentInfo);
// If the result is eErrorOutOfDateKHR || eSuboptimalKHR || if the windows framebuffer has been resized we need
// to recreate the swapchain
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || m_framebufferResized) {
m_framebufferResized = false;
recreateSwapchain();
} else if (result != vk::Result::eSuccess) {
// If we get any other error, we should error out
throw std::runtime_error("Failed to present swapchain image");
}
} catch (const vk::SystemError &e) {
// There is a chance that a SystemError will be thrown when presenting. The SystemError.code() could also be a
// eErrorOutOfDateKHR as well, so that should also be checked for so we can just recreate the swapchain as
// normal. All other errors should crash out.
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR)) {
recreateSwapchain();
} else {
throw;
}
}
// Rotate the frame index
m_frameIndex = (m_frameIndex + 1) % MAX_FRAMES_IN_FLIGHT;
}
void Application::cleanup() {
// Destroy the swapchain
cleanupSwapchain();
// Destroy the window
glfwDestroyWindow(m_window);
// Terminate GLFW
glfwTerminate();
}