Vulkan: Present using FIFO for vsync.

This allows the setting to be changed at runtime in Vulkan too.

Should help #10105.
This commit is contained in:
Unknown W. Brackets 2020-02-29 22:45:18 -08:00
parent 3c1e8abcfe
commit 2a3fd05651
7 changed files with 43 additions and 20 deletions

View File

@ -949,20 +949,17 @@ bool VulkanContext::InitSwapchain() {
ILOG("Supported present mode: %d (%s)", presentModes[i], PresentModeString(presentModes[i]));
}
for (size_t i = 0; i < presentModeCount; i++) {
if (swapchainPresentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) {
// Default to the first present mode from the list.
bool match = false;
match = match || ((flags_ & VULKAN_FLAG_PRESENT_MAILBOX) && presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR);
match = match || ((flags_ & VULKAN_FLAG_PRESENT_FIFO_RELAXED) && presentModes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR);
match = match || ((flags_ & VULKAN_FLAG_PRESENT_FIFO) && presentModes[i] == VK_PRESENT_MODE_FIFO_KHR);
match = match || ((flags_ & VULKAN_FLAG_PRESENT_IMMEDIATE) && presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR);
// Default to the first present mode from the list.
if (match || swapchainPresentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) {
swapchainPresentMode = presentModes[i];
}
if ((flags_ & VULKAN_FLAG_PRESENT_MAILBOX) && presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
break;
}
if ((flags_ & VULKAN_FLAG_PRESENT_FIFO_RELAXED) && presentModes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR) {
swapchainPresentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR;
break;
}
if ((flags_ & VULKAN_FLAG_PRESENT_IMMEDIATE) && presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR) {
swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
if (match) {
break;
}
}

View File

@ -13,6 +13,7 @@ enum {
VULKAN_FLAG_PRESENT_MAILBOX = 2,
VULKAN_FLAG_PRESENT_IMMEDIATE = 4,
VULKAN_FLAG_PRESENT_FIFO_RELAXED = 8,
VULKAN_FLAG_PRESENT_FIFO = 16,
};
enum {
@ -136,6 +137,7 @@ public:
VkDevice GetDevice() const { return device_; }
VkInstance GetInstance() const { return instance_; }
uint32_t GetFlags() const { return flags_; }
void UpdateFlags(uint32_t flags) { flags_ = flags; }
VulkanDeleteList &Delete() { return globalDeleteList_; }

View File

@ -553,7 +553,12 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) {
// we have nothing to do here.
bool doFrameSkip = g_Config.iFrameSkip != 0;
if (!throttle && g_Config.bFrameSkipUnthrottle) {
bool unthrottleNeedsSkip = g_Config.bFrameSkipUnthrottle;
if (g_Config.bVSync && GetGPUBackend() == GPUBackend::VULKAN) {
// Vulkan doesn't support the interval setting, so we force frameskip.
unthrottleNeedsSkip = true;
}
if (!throttle && unthrottleNeedsSkip) {
doFrameSkip = true;
skipFrame = true;
if (numSkippedFrames >= 7) {

View File

@ -342,7 +342,11 @@ void GameSettingsScreen::CreateViews() {
#endif
#ifdef _WIN32
graphicsSettings->Add(new CheckBox(&g_Config.bVSync, gr->T("VSync")));
CheckBox *vSync = graphicsSettings->Add(new CheckBox(&g_Config.bVSync, gr->T("VSync")));
vSync->OnClick.Add([=](EventParams &e) {
NativeResized();
return UI::EVENT_CONTINUE;
});
#endif
CheckBox *hwTransform = graphicsSettings->Add(new CheckBox(&g_Config.bHardwareTransform, gr->T("Hardware Transform")));

View File

@ -74,6 +74,15 @@ static VulkanContext *g_Vulkan;
static VulkanLogOptions g_LogOptions;
static uint32_t FlagsFromConfig() {
uint32_t flags = 0;
flags = g_Config.bVSync ? VULKAN_FLAG_PRESENT_FIFO : VULKAN_FLAG_PRESENT_MAILBOX;
if (g_validate_) {
flags |= VULKAN_FLAG_VALIDATE;
}
return flags;
}
bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_message) {
*error_message = "N/A";
@ -100,10 +109,7 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
VulkanContext::CreateInfo info{};
info.app_name = "PPSSPP";
info.app_ver = gitVer.ToInteger();
info.flags = VULKAN_FLAG_PRESENT_MAILBOX;
if (g_validate_) {
info.flags |= VULKAN_FLAG_VALIDATE;
}
info.flags = FlagsFromConfig();
if (VK_SUCCESS != g_Vulkan->CreateInstance(info)) {
*error_message = g_Vulkan->InitError();
delete g_Vulkan;
@ -184,6 +190,7 @@ void WindowsVulkanContext::Resize() {
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
g_Vulkan->DestroyObjects();
g_Vulkan->UpdateFlags(FlagsFromConfig());
g_Vulkan->ReinitSurface();
g_Vulkan->InitObjects();

View File

@ -739,6 +739,7 @@ namespace MainWindow {
case ID_OPTIONS_VSYNC:
g_Config.bVSync = !g_Config.bVSync;
NativeResized();
break;
case ID_OPTIONS_FRAMESKIP_AUTO:

View File

@ -81,6 +81,13 @@ AndroidVulkanContext::~AndroidVulkanContext() {
g_Vulkan = nullptr;
}
static uint32_t FlagsFromConfig() {
if (g_Config.bVSync) {
return VULKAN_FLAG_PRESENT_FIFO;
}
return VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED;
}
bool AndroidVulkanContext::InitAPI() {
ILOG("AndroidVulkanContext::Init");
init_glslang();
@ -105,7 +112,7 @@ bool AndroidVulkanContext::InitAPI() {
VulkanContext::CreateInfo info{};
info.app_name = "PPSSPP";
info.app_ver = gitVer.ToInteger();
info.flags = VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED;
info.flags = FlagsFromConfig();
VkResult res = g_Vulkan->CreateInstance(info);
if (res != VK_SUCCESS) {
ELOG("Failed to create vulkan context: %s", g_Vulkan->InitError().c_str());
@ -216,7 +223,7 @@ void AndroidVulkanContext::Resize() {
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
g_Vulkan->DestroyObjects();
// backbufferResize updated these values. TODO: Notify another way?
g_Vulkan->UpdateFlags(FlagsFromConfig());
g_Vulkan->ReinitSurface();
g_Vulkan->InitObjects();
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());