vk: fix crash when resizing window in boxart mode

This commit is contained in:
Flyinghead 2022-06-17 16:17:58 +02:00
parent 3915c55251
commit 1523fafce0
4 changed files with 32 additions and 8 deletions

View File

@ -2402,7 +2402,11 @@ static void gui_display_content()
u8 *imgData = loadImage(art->boxartPath, width, height);
if (imgData != nullptr)
{
textureId = imguiDriver->updateTexture(art->boxartPath, imgData, width, height);
try {
textureId = imguiDriver->updateTexture(art->boxartPath, imgData, width, height);
} catch (const std::exception&) {
// vulkan can throw during resizing
}
free(imgData);
}
}

View File

@ -278,6 +278,7 @@ bool VulkanContext::InitInstance(const char** extensions, uint32_t extensions_co
void VulkanContext::InitImgui()
{
imguiDriver.reset();
imguiDriver = std::unique_ptr<ImGuiDriver>(new VulkanDriver());
ImGui_ImplVulkan_InitInfo initInfo{};
initInfo.Instance = (VkInstance)*instance;
@ -751,13 +752,21 @@ bool VulkanContext::init()
return InitDevice();
}
void VulkanContext::NewFrame()
bool VulkanContext::recreateSwapChainIfNeeded()
{
if (resized || HasSurfaceDimensionChanged())
{
CreateSwapChain();
lastFrameView = vk::ImageView();
return true;
}
else
return false;
}
void VulkanContext::NewFrame()
{
recreateSwapChainIfNeeded();
if (!IsValid())
throw InvalidVulkanContext();
device->acquireNextImageKHR(*swapChain, UINT64_MAX, *imageAcquiredSemaphores[currentSemaphore], nullptr, &currentImage);

View File

@ -109,6 +109,7 @@ public:
vk::SubmitInfo(0, nullptr, nullptr, bufferCount, buffers), fence);
}
bool hasPerPixel() override { return fragmentStoresAndAtomics; }
bool recreateSwapChainIfNeeded();
#ifdef VK_DEBUG
void setObjectName(u64 object, VkDebugReportObjectTypeEXT objectType, const std::string& name)

View File

@ -41,7 +41,11 @@ public:
try {
bool rendering = context->IsRendering();
if (!rendering)
{
if (context->recreateSwapChainIfNeeded())
return;
context->NewFrame();
}
vk::CommandBuffer vmuCmdBuffer{};
if (!rendering || newFrameStarted)
{
@ -50,8 +54,10 @@ public:
context->PresentLastFrame();
context->DrawOverlay(settings.display.uiScale, true, false);
}
// Record Imgui Draw Data and draw funcs into command buffer
ImGui_ImplVulkan_RenderDrawData(drawData, (VkCommandBuffer)getCommandBuffer());
if (!justStarted)
// Record Imgui Draw Data and draw funcs into command buffer
ImGui_ImplVulkan_RenderDrawData(drawData, (VkCommandBuffer)getCommandBuffer());
justStarted = false;
if (!rendering || newFrameStarted)
context->EndFrame(vmuCmdBuffer);
newFrameStarted = false;
@ -60,7 +66,7 @@ public:
}
void present() override {
getContext()->Present();
getContext()->Present(); // may destroy this driver
}
ImTextureID getTexture(const std::string& name) override {
@ -118,15 +124,19 @@ private:
vk::CommandBuffer getCommandBuffer()
{
if (!getContext()->IsRendering())
VulkanContext *context = getContext();
if (!context->IsRendering())
{
getContext()->NewFrame();
if (context->recreateSwapChainIfNeeded())
throw InvalidVulkanContext();
context->NewFrame();
newFrameStarted = true;
}
return getContext()->GetCurrentCommandBuffer();
return context->GetCurrentCommandBuffer();
}
std::unordered_map<std::string, VkTexture> textures;
vk::UniqueSampler linearSampler;
bool newFrameStarted = false;
bool justStarted = true;
};