mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Vulkan: Recreate the swapchain if we get too many "out of date" frames.
Should help an issue on my Linux laptop with Intel GPU.
This commit is contained in:
1 parent
b45128025f
commit
cd1d73436d
6 files changed
+33
-3
No files matched your search
@@ -34,6 +34,10 @@ public:
|
||||
virtual void ThreadEnd() {}
|
||||
virtual void StopThread() {}
|
||||
|
||||
// Useful for checks that need to be performed every frame.
|
||||
// Should strive to get rid of these.
|
||||
virtual void Poll() {}
|
||||
|
||||
virtual Draw::DrawContext *GetDrawContext() = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -1095,6 +1095,8 @@ void NativeRender(GraphicsContext *graphicsContext) {
|
||||
NativeMessageReceived("gpu_resized", "");
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
graphicsContext->Poll();
|
||||
}
|
||||
|
||||
ui_draw2d.PopDrawMatrix();
|
||||
|
||||
@@ -143,9 +143,9 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
|
||||
_assert_msg_(G3D, success, "Failed to compile preset shaders");
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||
|
||||
VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
renderManager->SetInflightFrames(g_Config.iInflightFrames);
|
||||
if (!renderManager->HasBackbuffers()) {
|
||||
renderManager_ = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||
if (!renderManager_->HasBackbuffers()) {
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
@@ -166,6 +166,7 @@ void WindowsVulkanContext::Shutdown() {
|
||||
|
||||
delete g_Vulkan;
|
||||
g_Vulkan = nullptr;
|
||||
renderManager_ = nullptr;
|
||||
|
||||
finalize_glslang();
|
||||
}
|
||||
@@ -181,6 +182,13 @@ void WindowsVulkanContext::Resize() {
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||
}
|
||||
|
||||
void WindowsVulkanContext::Poll() {
|
||||
// Check for existing swapchain to avoid issues during shutdown.
|
||||
if (g_Vulkan->GetSwapchain() && renderManager_->NeedsSwapchainRecreate()) {
|
||||
Resize();
|
||||
}
|
||||
}
|
||||
|
||||
void *WindowsVulkanContext::GetAPIContext() {
|
||||
return g_Vulkan;
|
||||
}
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "Windows/GPU/WindowsGraphicsContext.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
|
||||
class VulkanRenderManager;
|
||||
|
||||
class WindowsVulkanContext : public WindowsGraphicsContext {
|
||||
public:
|
||||
WindowsVulkanContext() : draw_(nullptr) {}
|
||||
@@ -29,11 +31,13 @@ public:
|
||||
void SwapInterval(int interval) override {}
|
||||
void SwapBuffers() override {}
|
||||
void Resize() override;
|
||||
void Poll() override;
|
||||
|
||||
void *GetAPIContext();
|
||||
|
||||
Draw::DrawContext *GetDrawContext() override { return draw_; }
|
||||
private:
|
||||
Draw::DrawContext *draw_;
|
||||
VulkanRenderManager *renderManager_ = nullptr;
|
||||
};
|
||||
|
||||
@@ -209,6 +209,8 @@ void VulkanRenderManager::CreateBackbuffers() {
|
||||
newInflightFrames_ = -1;
|
||||
}
|
||||
|
||||
outOfDateFrames_ = 0;
|
||||
|
||||
// Start the thread.
|
||||
if (useThread_ && HasBackbuffers()) {
|
||||
run_ = true;
|
||||
@@ -1029,11 +1031,14 @@ void VulkanRenderManager::BeginSubmitFrame(int frame) {
|
||||
if (res == VK_SUBOPTIMAL_KHR) {
|
||||
// Hopefully the resize will happen shortly. Ignore - one frame might look bad or something.
|
||||
WLOG("VK_SUBOPTIMAL_KHR returned - ignoring");
|
||||
outOfDateFrames_++;
|
||||
} else if (res == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
WLOG("VK_ERROR_OUT_OF_DATE_KHR returned - not presenting");
|
||||
frameData.skipSwap = true;
|
||||
outOfDateFrames_++;
|
||||
} else {
|
||||
_assert_msg_(G3D, res == VK_SUCCESS, "vkAcquireNextImageKHR failed! result=%s", VulkanResultToString(res));
|
||||
outOfDateFrames_ = 0;
|
||||
}
|
||||
|
||||
VkCommandBufferBeginInfo begin{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
|
||||
|
||||
@@ -285,6 +285,11 @@ public:
|
||||
return frameData_[vulkan_->GetCurFrame()].profile.profileSummary;
|
||||
}
|
||||
|
||||
bool NeedsSwapchainRecreate() const {
|
||||
// Accepting a few of these makes shutdown simpler.
|
||||
return outOfDateFrames_ > VulkanContext::MAX_INFLIGHT_FRAMES;
|
||||
}
|
||||
|
||||
private:
|
||||
bool InitBackbufferFramebuffers(int width, int height);
|
||||
bool InitDepthStencilBuffer(VkCommandBuffer cmd); // Used for non-buffered rendering.
|
||||
@@ -337,6 +342,8 @@ private:
|
||||
int newInflightFrames_ = -1;
|
||||
int inflightFramesAtStart_ = 0;
|
||||
|
||||
int outOfDateFrames_ = 0;
|
||||
|
||||
// Submission time state
|
||||
int curWidth_ = -1;
|
||||
int curHeight_ = -1;
|
||||
|
||||
Reference in new issue
Block a user