mirror of
https://github.com/love2d/love.git
synced 2026-08-16 00:02:12 +02:00
handle resizing correctly
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user