mirror of
https://github.com/love2d/love.git
synced 2026-08-17 19:23:38 +02:00
handle resizing correctly
This commit is contained in:
@@ -74,37 +74,22 @@ namespace love {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Graphics::~Graphics() {
|
Graphics::~Graphics() {
|
||||||
if (init) {
|
cleanup();
|
||||||
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);
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::present(void* screenshotCallbackdata) {
|
void Graphics::present(void* screenshotCallbackdata) {
|
||||||
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
|
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
|
||||||
|
|
||||||
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 love::Exception("failed to acquire swap chain image");
|
||||||
|
}
|
||||||
|
|
||||||
if (imagesInFlight[imageIndex] != VK_NULL_HANDLE) {
|
if (imagesInFlight[imageIndex] != VK_NULL_HANDLE) {
|
||||||
vkWaitForFences(device, 1, &imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX);
|
vkWaitForFences(device, 1, &imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX);
|
||||||
@@ -145,11 +130,23 @@ namespace love {
|
|||||||
|
|
||||||
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 love::Exception("failed to present swap chain image");
|
||||||
|
}
|
||||||
|
|
||||||
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
|
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelheight) {
|
||||||
|
recreateSwapChain();
|
||||||
|
}
|
||||||
|
|
||||||
void Graphics::createVulkanInstance() {
|
void Graphics::createVulkanInstance() {
|
||||||
if (enableValidationLayers && !checkValidationSupport()) {
|
if (enableValidationLayers && !checkValidationSupport()) {
|
||||||
throw love::Exception("validation layers requested, but not available");
|
throw love::Exception("validation layers requested, but not available");
|
||||||
@@ -831,6 +828,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* createInstance() {
|
||||||
love::graphics::Graphics* instance = nullptr;
|
love::graphics::Graphics* instance = nullptr;
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace love {
|
|||||||
void clear(const std::vector<OptionalColorD>& colors, OptionalInt stencil, OptionalDouble depth) override {}
|
void clear(const std::vector<OptionalColorD>& colors, OptionalInt stencil, OptionalDouble depth) override {}
|
||||||
void discard(const std::vector<bool>& colorbuffers, bool depthstencil) override {}
|
void discard(const std::vector<bool>& colorbuffers, bool depthstencil) override {}
|
||||||
void present(void* screenshotCallbackdata) 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; }
|
bool setMode(void* context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override { return false; }
|
||||||
void unSetMode() override {}
|
void unSetMode() override {}
|
||||||
void setActive(bool active) override {}
|
void setActive(bool active) override {}
|
||||||
@@ -109,6 +109,9 @@ namespace love {
|
|||||||
void createCommandPool();
|
void createCommandPool();
|
||||||
void createCommandBuffers();
|
void createCommandBuffers();
|
||||||
void createSyncObjects();
|
void createSyncObjects();
|
||||||
|
void cleanup();
|
||||||
|
void cleanupSwapChain();
|
||||||
|
void recreateSwapChain();
|
||||||
|
|
||||||
VkInstance instance;
|
VkInstance instance;
|
||||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||||
@@ -133,6 +136,7 @@ namespace love {
|
|||||||
std::vector<VkFence> inFlightFences;
|
std::vector<VkFence> inFlightFences;
|
||||||
std::vector<VkFence> imagesInFlight;
|
std::vector<VkFence> imagesInFlight;
|
||||||
size_t currentFrame = 0;
|
size_t currentFrame = 0;
|
||||||
|
bool framebufferResized = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
#else
|
#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::Graphics* gfx = graphics.get();
|
||||||
love::graphics::vulkan::Graphics* vgfx = (love::graphics::vulkan::Graphics*)gfx;
|
love::graphics::vulkan::Graphics* vgfx = (love::graphics::vulkan::Graphics*)gfx;
|
||||||
|
|||||||
Reference in New Issue
Block a user