Handling swap chain recreation
This commit is contained in:
@@ -69,6 +69,7 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
std::vector<VkSemaphore> imageAvailableSemaphores;
|
std::vector<VkSemaphore> imageAvailableSemaphores;
|
||||||
std::vector<VkSemaphore> renderFinishedSemaphores;
|
std::vector<VkSemaphore> renderFinishedSemaphores;
|
||||||
std::vector<VkFence> inFlightFences;
|
std::vector<VkFence> inFlightFences;
|
||||||
|
bool framebufferResized = false;
|
||||||
|
|
||||||
uint32_t currentFrame = 0;
|
uint32_t currentFrame = 0;
|
||||||
|
|
||||||
@@ -83,9 +84,17 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
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(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
|
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
|
||||||
|
glfwSetWindowUserPointer(window, this);
|
||||||
|
glfwSetFramebufferSizeCallback(window, framebufferResizeCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void framebufferResizeCallback(GLFWwindow* window, int width, int height) {
|
||||||
|
auto app = reinterpret_cast<HelloTriangleApplication*>(glfwGetWindowUserPointer(window));
|
||||||
|
app->framebufferResized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initVulkan() {
|
void initVulkan() {
|
||||||
@@ -104,6 +113,41 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
createSyncObjects();
|
createSyncObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void recreateSwapChain() {
|
||||||
|
int width = 0, height = 0;
|
||||||
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
|
|
||||||
|
while (width == 0 || height == 0) {
|
||||||
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
|
glfwWaitEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vkDeviceWaitIdle(device);
|
||||||
|
|
||||||
|
cleanupSwapChain();
|
||||||
|
|
||||||
|
createSwapChain();
|
||||||
|
createImageViews();
|
||||||
|
createFramebuffers();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanupSwapChain() {
|
||||||
|
for (size_t i = 0; i < swapchainFrameBuffers.size(); i++) {
|
||||||
|
vkDestroyFramebuffer(device, swapchainFrameBuffers[i], nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < swapChainImageViews.size(); i++) {
|
||||||
|
vkDestroyImageView(device, swapChainImageViews[i], nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkDestroySwapchainKHR(device, swapChain, nullptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void createSyncObjects() {
|
void createSyncObjects() {
|
||||||
imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
||||||
renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
||||||
@@ -867,10 +911,19 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
|
|
||||||
void drawFrame() {
|
void drawFrame() {
|
||||||
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
|
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
|
||||||
vkResetFences(device, 1, &inFlightFences[currentFrame]);
|
|
||||||
|
|
||||||
uint32_t imageIndex;
|
uint32_t imageIndex;
|
||||||
vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
|
VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
|
||||||
|
|
||||||
|
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||||
|
recreateSwapChain();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
|
||||||
|
throw std::runtime_error("failed to acquire swap chain image!");
|
||||||
|
}
|
||||||
|
|
||||||
|
vkResetFences(device, 1, &inFlightFences[currentFrame]);
|
||||||
|
|
||||||
vkResetCommandBuffer(commandBuffers[currentFrame], 0);
|
vkResetCommandBuffer(commandBuffers[currentFrame], 0);
|
||||||
recordCommandBuffer(commandBuffers[currentFrame], imageIndex);
|
recordCommandBuffer(commandBuffers[currentFrame], imageIndex);
|
||||||
@@ -906,14 +959,27 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
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 || framebufferResized) {
|
||||||
|
framebufferResized = false;
|
||||||
|
recreateSwapChain();
|
||||||
|
}
|
||||||
|
else if (result != VK_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to present swap chain image!");
|
||||||
|
}
|
||||||
|
|
||||||
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
|
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup(){
|
void cleanup(){
|
||||||
|
cleanupSwapChain();
|
||||||
|
|
||||||
|
|
||||||
|
vkDestroyPipeline(device, graphicsPipeline, nullptr);
|
||||||
|
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||||
|
vkDestroyRenderPass(device, renderPass, nullptr);
|
||||||
|
|
||||||
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
||||||
vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr);
|
vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr);
|
||||||
vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr);
|
vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr);
|
||||||
@@ -923,19 +989,6 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
|
|
||||||
vkDestroyCommandPool(device, commandPool, nullptr);
|
vkDestroyCommandPool(device, commandPool, nullptr);
|
||||||
|
|
||||||
for (auto framebuffer : swapchainFrameBuffers) {
|
|
||||||
vkDestroyFramebuffer(device, framebuffer, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
vkDestroyPipeline(device, graphicsPipeline, nullptr);
|
|
||||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
|
||||||
vkDestroyRenderPass(device, renderPass, nullptr);
|
|
||||||
|
|
||||||
for (auto imageView : swapChainImageViews) {
|
|
||||||
vkDestroyImageView(device, imageView, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
vkDestroySwapchainKHR(device, swapChain, nullptr);
|
|
||||||
|
|
||||||
vkDestroyDevice(device, nullptr);
|
vkDestroyDevice(device, nullptr);
|
||||||
if(enableValidationLayers){
|
if(enableValidationLayers){
|
||||||
|
|||||||
Reference in New Issue
Block a user