handle resizing correctly

This commit is contained in:
niki
2022-01-06 01:42:50 +01:00
parent 65074dae15
commit b80ef89e8d
3 changed files with 68 additions and 28 deletions
+62 -26
View File
@@ -87,37 +87,22 @@ namespace love {
}
Graphics::~Graphics() {
if (init) {
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vkDestroySemaphore(device, renderFinishedSemaphores.at(i), nullptr);
vkDestroySemaphore(device, imageAvailableSemaphores.at(i), nullptr);
vkDestroyFence(device, inFlightFences.at(i), nullptr);
}
if (vkDeviceWaitIdle(device) != VK_SUCCESS) {
throw love::Exception("vkDeviceWaitIdle failed");
}
vkDestroyCommandPool(device, commandPool, nullptr);
for (auto framebuffer : swapChainFramBuffers) {
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);
vkDestroySurfaceKHR(instance, surface, nullptr);
vkDestroyInstance(instance, nullptr);
}
cleanup();
}
void Graphics::present(void* screenshotCallbackdata) {
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
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 love::Exception("failed to acquire swap chain image");
}
if (imagesInFlight[imageIndex] != VK_NULL_HANDLE) {
vkWaitForFences(device, 1, &imagesInFlight.at(imageIndex), VK_TRUE, UINT64_MAX);
@@ -158,11 +143,23 @@ namespace love {
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 love::Exception("failed to present swap chain image");
}
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
}
void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelheight) {
recreateSwapChain();
}
void Graphics::createVulkanInstance() {
if (enableValidationLayers && !checkValidationSupport()) {
throw love::Exception("validation layers requested, but not available");
@@ -844,6 +841,45 @@ namespace love {
}
}
void Graphics::cleanup() {
cleanupSwapChain();
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr);
vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr);
vkDestroyFence(device, inFlightFences[i], nullptr);
}
vkDestroyCommandPool(device, commandPool, nullptr);
vkDestroyDevice(device, nullptr);
vkDestroySurfaceKHR(instance, surface, nullptr);
vkDestroyInstance(instance, nullptr);
}
void Graphics::cleanupSwapChain() {
for (size_t i = 0; i < swapChainFramBuffers.size(); i++) {
vkDestroyFramebuffer(device, swapChainFramBuffers[i], nullptr);
}
vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(commandBuffers.size()), commandBuffers.data());
vkDestroyPipeline(device, graphicsPipeline, nullptr);
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyRenderPass(device, renderPass, nullptr);
for (size_t i = 0; i < swapChainImageViews.size(); i++) {
vkDestroyImageView(device, swapChainImageViews[i], nullptr);
}
vkDestroySwapchainKHR(device, swapChain, nullptr);
}
void Graphics::recreateSwapChain() {
vkDeviceWaitIdle(device);
createSwapChain();
createImageViews();
createRenderPass();
createGraphicsPipeline();
createFramebuffers();
createCommandBuffers();
}
love::graphics::Graphics* createInstance() {
love::graphics::Graphics* instance = nullptr;
+5 -1
View File
@@ -35,7 +35,7 @@ namespace love {
Matrix4 computeDeviceProjection(const Matrix4& projection, bool rendertotexture) const override { return Matrix4(); }
void discard(const std::vector<bool>& colorbuffers, bool depthstencil) override { }
void present(void* screenshotCallbackdata) override;
void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override {}
void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;
bool setMode(void* context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override { return false; }
void unSetMode() override {}
void setActive(bool active) override {}
@@ -108,6 +108,9 @@ namespace love {
void createCommandPool();
void createCommandBuffers();
void createSyncObjects();
void cleanup();
void cleanupSwapChain();
void recreateSwapChain();
VkInstance instance;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
@@ -132,6 +135,7 @@ namespace love {
std::vector<VkFence> inFlightFences;
std::vector<VkFence> imagesInFlight;
size_t currentFrame = 0;
bool framebufferResized = false;
};
}
}
+1 -1
View File
@@ -378,7 +378,7 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
return true;
#else
window = SDL_CreateWindow(title.c_str(), x, y, w, h, SDL_WINDOW_VULKAN);
window = SDL_CreateWindow(title.c_str(), x, y, w, h, windowflags | SDL_WINDOW_VULKAN);
love::graphics::Graphics* gfx = graphics.get();
love::graphics::vulkan::Graphics* vgfx = (love::graphics::vulkan::Graphics*)gfx;