vk: fix crash when resizing window in boxart mode
This commit is contained in:
parent
3915c55251
commit
1523fafce0
|
@ -2402,7 +2402,11 @@ static void gui_display_content()
|
||||||
u8 *imgData = loadImage(art->boxartPath, width, height);
|
u8 *imgData = loadImage(art->boxartPath, width, height);
|
||||||
if (imgData != nullptr)
|
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);
|
free(imgData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,6 +278,7 @@ bool VulkanContext::InitInstance(const char** extensions, uint32_t extensions_co
|
||||||
|
|
||||||
void VulkanContext::InitImgui()
|
void VulkanContext::InitImgui()
|
||||||
{
|
{
|
||||||
|
imguiDriver.reset();
|
||||||
imguiDriver = std::unique_ptr<ImGuiDriver>(new VulkanDriver());
|
imguiDriver = std::unique_ptr<ImGuiDriver>(new VulkanDriver());
|
||||||
ImGui_ImplVulkan_InitInfo initInfo{};
|
ImGui_ImplVulkan_InitInfo initInfo{};
|
||||||
initInfo.Instance = (VkInstance)*instance;
|
initInfo.Instance = (VkInstance)*instance;
|
||||||
|
@ -751,13 +752,21 @@ bool VulkanContext::init()
|
||||||
return InitDevice();
|
return InitDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanContext::NewFrame()
|
bool VulkanContext::recreateSwapChainIfNeeded()
|
||||||
{
|
{
|
||||||
if (resized || HasSurfaceDimensionChanged())
|
if (resized || HasSurfaceDimensionChanged())
|
||||||
{
|
{
|
||||||
CreateSwapChain();
|
CreateSwapChain();
|
||||||
lastFrameView = vk::ImageView();
|
lastFrameView = vk::ImageView();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanContext::NewFrame()
|
||||||
|
{
|
||||||
|
recreateSwapChainIfNeeded();
|
||||||
if (!IsValid())
|
if (!IsValid())
|
||||||
throw InvalidVulkanContext();
|
throw InvalidVulkanContext();
|
||||||
device->acquireNextImageKHR(*swapChain, UINT64_MAX, *imageAcquiredSemaphores[currentSemaphore], nullptr, ¤tImage);
|
device->acquireNextImageKHR(*swapChain, UINT64_MAX, *imageAcquiredSemaphores[currentSemaphore], nullptr, ¤tImage);
|
||||||
|
|
|
@ -109,6 +109,7 @@ public:
|
||||||
vk::SubmitInfo(0, nullptr, nullptr, bufferCount, buffers), fence);
|
vk::SubmitInfo(0, nullptr, nullptr, bufferCount, buffers), fence);
|
||||||
}
|
}
|
||||||
bool hasPerPixel() override { return fragmentStoresAndAtomics; }
|
bool hasPerPixel() override { return fragmentStoresAndAtomics; }
|
||||||
|
bool recreateSwapChainIfNeeded();
|
||||||
|
|
||||||
#ifdef VK_DEBUG
|
#ifdef VK_DEBUG
|
||||||
void setObjectName(u64 object, VkDebugReportObjectTypeEXT objectType, const std::string& name)
|
void setObjectName(u64 object, VkDebugReportObjectTypeEXT objectType, const std::string& name)
|
||||||
|
|
|
@ -41,7 +41,11 @@ public:
|
||||||
try {
|
try {
|
||||||
bool rendering = context->IsRendering();
|
bool rendering = context->IsRendering();
|
||||||
if (!rendering)
|
if (!rendering)
|
||||||
|
{
|
||||||
|
if (context->recreateSwapChainIfNeeded())
|
||||||
|
return;
|
||||||
context->NewFrame();
|
context->NewFrame();
|
||||||
|
}
|
||||||
vk::CommandBuffer vmuCmdBuffer{};
|
vk::CommandBuffer vmuCmdBuffer{};
|
||||||
if (!rendering || newFrameStarted)
|
if (!rendering || newFrameStarted)
|
||||||
{
|
{
|
||||||
|
@ -50,8 +54,10 @@ public:
|
||||||
context->PresentLastFrame();
|
context->PresentLastFrame();
|
||||||
context->DrawOverlay(settings.display.uiScale, true, false);
|
context->DrawOverlay(settings.display.uiScale, true, false);
|
||||||
}
|
}
|
||||||
// Record Imgui Draw Data and draw funcs into command buffer
|
if (!justStarted)
|
||||||
ImGui_ImplVulkan_RenderDrawData(drawData, (VkCommandBuffer)getCommandBuffer());
|
// Record Imgui Draw Data and draw funcs into command buffer
|
||||||
|
ImGui_ImplVulkan_RenderDrawData(drawData, (VkCommandBuffer)getCommandBuffer());
|
||||||
|
justStarted = false;
|
||||||
if (!rendering || newFrameStarted)
|
if (!rendering || newFrameStarted)
|
||||||
context->EndFrame(vmuCmdBuffer);
|
context->EndFrame(vmuCmdBuffer);
|
||||||
newFrameStarted = false;
|
newFrameStarted = false;
|
||||||
|
@ -60,7 +66,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void present() override {
|
void present() override {
|
||||||
getContext()->Present();
|
getContext()->Present(); // may destroy this driver
|
||||||
}
|
}
|
||||||
|
|
||||||
ImTextureID getTexture(const std::string& name) override {
|
ImTextureID getTexture(const std::string& name) override {
|
||||||
|
@ -118,15 +124,19 @@ private:
|
||||||
|
|
||||||
vk::CommandBuffer getCommandBuffer()
|
vk::CommandBuffer getCommandBuffer()
|
||||||
{
|
{
|
||||||
if (!getContext()->IsRendering())
|
VulkanContext *context = getContext();
|
||||||
|
if (!context->IsRendering())
|
||||||
{
|
{
|
||||||
getContext()->NewFrame();
|
if (context->recreateSwapChainIfNeeded())
|
||||||
|
throw InvalidVulkanContext();
|
||||||
|
context->NewFrame();
|
||||||
newFrameStarted = true;
|
newFrameStarted = true;
|
||||||
}
|
}
|
||||||
return getContext()->GetCurrentCommandBuffer();
|
return context->GetCurrentCommandBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<std::string, VkTexture> textures;
|
std::unordered_map<std::string, VkTexture> textures;
|
||||||
vk::UniqueSampler linearSampler;
|
vk::UniqueSampler linearSampler;
|
||||||
bool newFrameStarted = false;
|
bool newFrameStarted = false;
|
||||||
|
bool justStarted = true;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue