mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-27 10:20:49 +00:00
Merge pull request #12659 from unknownbrackets/vsync
Support vsync in all hardware backends, support runtime update
This commit is contained in:
commit
2ec82951a0
@ -949,20 +949,17 @@ bool VulkanContext::InitSwapchain() {
|
|||||||
ILOG("Supported present mode: %d (%s)", presentModes[i], PresentModeString(presentModes[i]));
|
ILOG("Supported present mode: %d (%s)", presentModes[i], PresentModeString(presentModes[i]));
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < presentModeCount; i++) {
|
for (size_t i = 0; i < presentModeCount; i++) {
|
||||||
if (swapchainPresentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) {
|
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.
|
// Default to the first present mode from the list.
|
||||||
|
if (match || swapchainPresentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) {
|
||||||
swapchainPresentMode = presentModes[i];
|
swapchainPresentMode = presentModes[i];
|
||||||
}
|
}
|
||||||
if ((flags_ & VULKAN_FLAG_PRESENT_MAILBOX) && presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
|
if (match) {
|
||||||
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;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ enum {
|
|||||||
VULKAN_FLAG_PRESENT_MAILBOX = 2,
|
VULKAN_FLAG_PRESENT_MAILBOX = 2,
|
||||||
VULKAN_FLAG_PRESENT_IMMEDIATE = 4,
|
VULKAN_FLAG_PRESENT_IMMEDIATE = 4,
|
||||||
VULKAN_FLAG_PRESENT_FIFO_RELAXED = 8,
|
VULKAN_FLAG_PRESENT_FIFO_RELAXED = 8,
|
||||||
|
VULKAN_FLAG_PRESENT_FIFO = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -136,6 +137,7 @@ public:
|
|||||||
VkDevice GetDevice() const { return device_; }
|
VkDevice GetDevice() const { return device_; }
|
||||||
VkInstance GetInstance() const { return instance_; }
|
VkInstance GetInstance() const { return instance_; }
|
||||||
uint32_t GetFlags() const { return flags_; }
|
uint32_t GetFlags() const { return flags_; }
|
||||||
|
void UpdateFlags(uint32_t flags) { flags_ = flags; }
|
||||||
|
|
||||||
VulkanDeleteList &Delete() { return globalDeleteList_; }
|
VulkanDeleteList &Delete() { return globalDeleteList_; }
|
||||||
|
|
||||||
|
@ -556,7 +556,12 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) {
|
|||||||
// we have nothing to do here.
|
// we have nothing to do here.
|
||||||
bool doFrameSkip = g_Config.iFrameSkip != 0;
|
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;
|
doFrameSkip = true;
|
||||||
skipFrame = true;
|
skipFrame = true;
|
||||||
if (numSkippedFrames >= 7) {
|
if (numSkippedFrames >= 7) {
|
||||||
|
@ -73,7 +73,6 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
|||||||
device_ = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE);
|
device_ = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE);
|
||||||
context_ = (ID3D11DeviceContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT);
|
context_ = (ID3D11DeviceContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT);
|
||||||
D3D_FEATURE_LEVEL featureLevel = (D3D_FEATURE_LEVEL)draw->GetNativeObject(Draw::NativeObject::FEATURE_LEVEL);
|
D3D_FEATURE_LEVEL featureLevel = (D3D_FEATURE_LEVEL)draw->GetNativeObject(Draw::NativeObject::FEATURE_LEVEL);
|
||||||
lastVsync_ = g_Config.bVSync ? 1 : 0;
|
|
||||||
|
|
||||||
stockD3D11.Create(device_);
|
stockD3D11.Create(device_);
|
||||||
|
|
||||||
|
@ -81,6 +81,4 @@ private:
|
|||||||
DepalShaderCacheD3D11 *depalShaderCache_;
|
DepalShaderCacheD3D11 *depalShaderCache_;
|
||||||
DrawEngineD3D11 drawEngine_;
|
DrawEngineD3D11 drawEngine_;
|
||||||
ShaderManagerD3D11 *shaderManagerD3D11_;
|
ShaderManagerD3D11 *shaderManagerD3D11_;
|
||||||
|
|
||||||
int lastVsync_;
|
|
||||||
};
|
};
|
||||||
|
@ -58,8 +58,6 @@ GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
|||||||
drawEngine_(draw) {
|
drawEngine_(draw) {
|
||||||
device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE);
|
device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE);
|
||||||
deviceEx_ = (LPDIRECT3DDEVICE9EX)draw->GetNativeObject(Draw::NativeObject::DEVICE_EX);
|
deviceEx_ = (LPDIRECT3DDEVICE9EX)draw->GetNativeObject(Draw::NativeObject::DEVICE_EX);
|
||||||
lastVsync_ = g_Config.bVSync ? 1 : 0;
|
|
||||||
dxstate.SetVSyncInterval(g_Config.bVSync);
|
|
||||||
|
|
||||||
shaderManagerDX9_ = new ShaderManagerDX9(draw, device_);
|
shaderManagerDX9_ = new ShaderManagerDX9(draw, device_);
|
||||||
framebufferManagerDX9_ = new FramebufferManagerDX9(draw);
|
framebufferManagerDX9_ = new FramebufferManagerDX9(draw);
|
||||||
@ -285,15 +283,6 @@ void GPU_DX9::ReapplyGfxState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GPU_DX9::BeginFrame() {
|
void GPU_DX9::BeginFrame() {
|
||||||
// Turn off vsync when unthrottled
|
|
||||||
int desiredVSyncInterval = g_Config.bVSync ? 1 : 0;
|
|
||||||
if (PSP_CoreParameter().unthrottle || PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL)
|
|
||||||
desiredVSyncInterval = 0;
|
|
||||||
if (desiredVSyncInterval != lastVsync_) {
|
|
||||||
dxstate.SetVSyncInterval(desiredVSyncInterval);
|
|
||||||
lastVsync_ = desiredVSyncInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
textureCacheDX9_->StartFrame();
|
textureCacheDX9_->StartFrame();
|
||||||
drawEngine_.DecimateTrackedVertexArrays();
|
drawEngine_.DecimateTrackedVertexArrays();
|
||||||
depalShaderCache_.Decimate();
|
depalShaderCache_.Decimate();
|
||||||
|
@ -80,8 +80,6 @@ private:
|
|||||||
DepalShaderCacheDX9 depalShaderCache_;
|
DepalShaderCacheDX9 depalShaderCache_;
|
||||||
DrawEngineDX9 drawEngine_;
|
DrawEngineDX9 drawEngine_;
|
||||||
ShaderManagerDX9 *shaderManagerDX9_;
|
ShaderManagerDX9 *shaderManagerDX9_;
|
||||||
|
|
||||||
int lastVsync_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace DX9
|
} // namespace DX9
|
||||||
|
@ -360,6 +360,7 @@ void GPU_GLES::BeginHostFrame() {
|
|||||||
drawEngine_.Resized();
|
drawEngine_.Resized();
|
||||||
shaderManagerGL_->DirtyShader();
|
shaderManagerGL_->DirtyShader();
|
||||||
textureCacheGL_->NotifyConfigChanged();
|
textureCacheGL_->NotifyConfigChanged();
|
||||||
|
resized_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawEngine_.BeginFrame();
|
drawEngine_.BeginFrame();
|
||||||
@ -369,42 +370,11 @@ void GPU_GLES::EndHostFrame() {
|
|||||||
drawEngine_.EndFrame();
|
drawEngine_.EndFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void GPU_GLES::UpdateVsyncInterval(bool force) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
int desiredVSyncInterval = g_Config.bVSync ? 1 : 0;
|
|
||||||
if (PSP_CoreParameter().unthrottle) {
|
|
||||||
desiredVSyncInterval = 0;
|
|
||||||
}
|
|
||||||
if (PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL) {
|
|
||||||
int limit = PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 ? g_Config.iFpsLimit1 : g_Config.iFpsLimit2;
|
|
||||||
// For an alternative speed that is a clean factor of 60, the user probably still wants vsync.
|
|
||||||
if (limit == 0 || (limit >= 0 && limit != 15 && limit != 30 && limit != 60)) {
|
|
||||||
desiredVSyncInterval = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desiredVSyncInterval != lastVsync_ || force) {
|
|
||||||
// Disabled EXT_swap_control_tear for now, it never seems to settle at the correct timing
|
|
||||||
// so it just keeps tearing. Not what I hoped for...
|
|
||||||
//if (gl_extensions.EXT_swap_control_tear) {
|
|
||||||
// // See http://developer.download.nvidia.com/opengl/specs/WGL_EXT_swap_control_tear.txt
|
|
||||||
// glstate.SetVSyncInterval(-desiredVSyncInterval);
|
|
||||||
//} else {
|
|
||||||
gfxCtx_->SwapInterval(desiredVSyncInterval);
|
|
||||||
//}
|
|
||||||
lastVsync_ = desiredVSyncInterval;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPU_GLES::ReapplyGfxState() {
|
void GPU_GLES::ReapplyGfxState() {
|
||||||
GPUCommon::ReapplyGfxState();
|
GPUCommon::ReapplyGfxState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_GLES::BeginFrame() {
|
void GPU_GLES::BeginFrame() {
|
||||||
UpdateVsyncInterval(resized_);
|
|
||||||
resized_ = false;
|
|
||||||
|
|
||||||
textureCacheGL_->StartFrame();
|
textureCacheGL_->StartFrame();
|
||||||
drawEngine_.DecimateTrackedVertexArrays();
|
drawEngine_.DecimateTrackedVertexArrays();
|
||||||
depalShaderCache_.Decimate();
|
depalShaderCache_.Decimate();
|
||||||
|
@ -79,8 +79,6 @@ private:
|
|||||||
void CopyDisplayToOutput() override;
|
void CopyDisplayToOutput() override;
|
||||||
void Reinitialize() override;
|
void Reinitialize() override;
|
||||||
|
|
||||||
inline void UpdateVsyncInterval(bool force);
|
|
||||||
|
|
||||||
FramebufferManagerGLES *framebufferManagerGL_;
|
FramebufferManagerGLES *framebufferManagerGL_;
|
||||||
TextureCacheGLES *textureCacheGL_;
|
TextureCacheGLES *textureCacheGL_;
|
||||||
DepalShaderCacheGLES depalShaderCache_;
|
DepalShaderCacheGLES depalShaderCache_;
|
||||||
@ -89,8 +87,4 @@ private:
|
|||||||
ShaderManagerGLES *shaderManagerGL_;
|
ShaderManagerGLES *shaderManagerGL_;
|
||||||
|
|
||||||
std::string shaderCachePath_;
|
std::string shaderCachePath_;
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
int lastVsync_;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "profiler/profiler.h"
|
#include "profiler/profiler.h"
|
||||||
|
|
||||||
#include "Common/ColorConv.h"
|
#include "Common/ColorConv.h"
|
||||||
|
#include "Common/GraphicsContext.h"
|
||||||
#include "Core/Reporting.h"
|
#include "Core/Reporting.h"
|
||||||
#include "GPU/GeDisasm.h"
|
#include "GPU/GeDisasm.h"
|
||||||
#include "GPU/GPU.h"
|
#include "GPU/GPU.h"
|
||||||
@ -408,6 +409,7 @@ GPUCommon::GPUCommon(GraphicsContext *gfxCtx, Draw::DrawContext *draw) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
UpdateCmdInfo();
|
UpdateCmdInfo();
|
||||||
|
UpdateVsyncInterval(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUCommon::~GPUCommon() {
|
GPUCommon::~GPUCommon() {
|
||||||
@ -432,6 +434,7 @@ void GPUCommon::UpdateCmdInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GPUCommon::BeginHostFrame() {
|
void GPUCommon::BeginHostFrame() {
|
||||||
|
UpdateVsyncInterval(resized_);
|
||||||
ReapplyGfxState();
|
ReapplyGfxState();
|
||||||
|
|
||||||
// TODO: Assume config may have changed - maybe move to resize.
|
// TODO: Assume config may have changed - maybe move to resize.
|
||||||
@ -458,6 +461,30 @@ void GPUCommon::Reinitialize() {
|
|||||||
interruptsEnabled_ = true;
|
interruptsEnabled_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPUCommon::UpdateVsyncInterval(bool force) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
int desiredVSyncInterval = g_Config.bVSync ? 1 : 0;
|
||||||
|
if (PSP_CoreParameter().unthrottle) {
|
||||||
|
desiredVSyncInterval = 0;
|
||||||
|
}
|
||||||
|
if (PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL) {
|
||||||
|
int limit = PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 ? g_Config.iFpsLimit1 : g_Config.iFpsLimit2;
|
||||||
|
// For an alternative speed that is a clean factor of 60, the user probably still wants vsync.
|
||||||
|
if (limit == 0 || (limit >= 0 && limit != 15 && limit != 30 && limit != 60)) {
|
||||||
|
desiredVSyncInterval = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desiredVSyncInterval != lastVsync_ || force) {
|
||||||
|
// Disabled EXT_swap_control_tear for now, it never seems to settle at the correct timing
|
||||||
|
// so it just keeps tearing. Not what I hoped for... (gl_extensions.EXT_swap_control_tear)
|
||||||
|
// See http://developer.download.nvidia.com/opengl/specs/WGL_EXT_swap_control_tear.txt
|
||||||
|
gfxCtx_->SwapInterval(desiredVSyncInterval);
|
||||||
|
lastVsync_ = desiredVSyncInterval;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int GPUCommon::EstimatePerVertexCost() {
|
int GPUCommon::EstimatePerVertexCost() {
|
||||||
// TODO: This is transform cost, also account for rasterization cost somehow... although it probably
|
// TODO: This is transform cost, also account for rasterization cost somehow... although it probably
|
||||||
// runs in parallel with transform.
|
// runs in parallel with transform.
|
||||||
|
@ -276,6 +276,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BeginFrame() override;
|
void BeginFrame() override;
|
||||||
|
void UpdateVsyncInterval(bool force);
|
||||||
|
|
||||||
virtual void FastRunLoop(DisplayList &list);
|
virtual void FastRunLoop(DisplayList &list);
|
||||||
|
|
||||||
@ -362,6 +363,10 @@ private:
|
|||||||
// Debug stats.
|
// Debug stats.
|
||||||
double timeSteppingStarted_;
|
double timeSteppingStarted_;
|
||||||
double timeSpentStepping_;
|
double timeSpentStepping_;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
int lastVsync_;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CommonCommandTableEntry {
|
struct CommonCommandTableEntry {
|
||||||
|
@ -57,7 +57,6 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
|||||||
drawEngine_(vulkan_, draw),
|
drawEngine_(vulkan_, draw),
|
||||||
depalShaderCache_(draw, vulkan_),
|
depalShaderCache_(draw, vulkan_),
|
||||||
vulkan2D_(vulkan_) {
|
vulkan2D_(vulkan_) {
|
||||||
UpdateVsyncInterval(true);
|
|
||||||
CheckGPUFeatures();
|
CheckGPUFeatures();
|
||||||
|
|
||||||
shaderManagerVulkan_ = new ShaderManagerVulkan(draw, vulkan_);
|
shaderManagerVulkan_ = new ShaderManagerVulkan(draw, vulkan_);
|
||||||
@ -419,10 +418,6 @@ void GPU_Vulkan::InitClear() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_Vulkan::UpdateVsyncInterval(bool force) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPU_Vulkan::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) {
|
void GPU_Vulkan::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) {
|
||||||
GPUDebug::NotifyDisplay(framebuf, stride, format);
|
GPUDebug::NotifyDisplay(framebuf, stride, format);
|
||||||
framebufferManager_->SetDisplayFramebuffer(framebuf, stride, format);
|
framebufferManager_->SetDisplayFramebuffer(framebuf, stride, format);
|
||||||
|
@ -80,7 +80,6 @@ private:
|
|||||||
void InitClear() override;
|
void InitClear() override;
|
||||||
void CopyDisplayToOutput() override;
|
void CopyDisplayToOutput() override;
|
||||||
void Reinitialize() override;
|
void Reinitialize() override;
|
||||||
inline void UpdateVsyncInterval(bool force);
|
|
||||||
|
|
||||||
void InitDeviceObjects();
|
void InitDeviceObjects();
|
||||||
void DestroyDeviceObjects();
|
void DestroyDeviceObjects();
|
||||||
|
@ -342,7 +342,11 @@ void GameSettingsScreen::CreateViews() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#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
|
#endif
|
||||||
|
|
||||||
CheckBox *hwTransform = graphicsSettings->Add(new CheckBox(&g_Config.bHardwareTransform, gr->T("Hardware Transform")));
|
CheckBox *hwTransform = graphicsSettings->Add(new CheckBox(&g_Config.bHardwareTransform, gr->T("Hardware Transform")));
|
||||||
|
@ -42,12 +42,12 @@ D3D11Context::~D3D11Context() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void D3D11Context::SwapBuffers() {
|
void D3D11Context::SwapBuffers() {
|
||||||
swapChain_->Present(0, 0);
|
swapChain_->Present(swapInterval_, 0);
|
||||||
draw_->HandleEvent(Draw::Event::PRESENTED, 0, 0, nullptr, nullptr);
|
draw_->HandleEvent(Draw::Event::PRESENTED, 0, 0, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11Context::SwapInterval(int interval) {
|
void D3D11Context::SwapInterval(int interval) {
|
||||||
// Dummy
|
swapInterval_ = interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT D3D11Context::CreateTheDevice(IDXGIAdapter *adapter) {
|
HRESULT D3D11Context::CreateTheDevice(IDXGIAdapter *adapter) {
|
||||||
|
@ -67,4 +67,5 @@ private:
|
|||||||
HMODULE hD3D11;
|
HMODULE hD3D11;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
int swapInterval_ = 0;
|
||||||
};
|
};
|
||||||
|
@ -56,7 +56,7 @@ static void GetRes(HWND hWnd, int &xres, int &yres) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void D3D9Context::SwapInterval(int interval) {
|
void D3D9Context::SwapInterval(int interval) {
|
||||||
// Dummy
|
swapInterval_ = interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
||||||
@ -159,7 +159,7 @@ bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
|||||||
presentParams_.hDeviceWindow = wnd;
|
presentParams_.hDeviceWindow = wnd;
|
||||||
presentParams_.EnableAutoDepthStencil = true;
|
presentParams_.EnableAutoDepthStencil = true;
|
||||||
presentParams_.AutoDepthStencilFormat = D3DFMT_D24S8;
|
presentParams_.AutoDepthStencilFormat = D3DFMT_D24S8;
|
||||||
presentParams_.PresentationInterval = (g_Config.bVSync) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
|
presentParams_.PresentationInterval = swapInterval_ == 1 ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||||
|
|
||||||
if (has9Ex_) {
|
if (has9Ex_) {
|
||||||
if (windowed && IsWin7OrLater()) {
|
if (windowed && IsWin7OrLater()) {
|
||||||
@ -205,13 +205,16 @@ void D3D9Context::Resize() {
|
|||||||
// This should only be called from the emu thread.
|
// This should only be called from the emu thread.
|
||||||
int xres, yres;
|
int xres, yres;
|
||||||
GetRes(hWnd_, xres, yres);
|
GetRes(hWnd_, xres, yres);
|
||||||
|
uint32_t newInterval = swapInterval_ == 1 ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;;
|
||||||
bool w_changed = presentParams_.BackBufferWidth != xres;
|
bool w_changed = presentParams_.BackBufferWidth != xres;
|
||||||
bool h_changed = presentParams_.BackBufferHeight != yres;
|
bool h_changed = presentParams_.BackBufferHeight != yres;
|
||||||
|
bool i_changed = presentParams_.PresentationInterval != newInterval;
|
||||||
|
|
||||||
if (device_ && (w_changed || h_changed)) {
|
if (device_ && (w_changed || h_changed || i_changed)) {
|
||||||
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, 0, 0, nullptr);
|
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, 0, 0, nullptr);
|
||||||
presentParams_.BackBufferWidth = xres;
|
presentParams_.BackBufferWidth = xres;
|
||||||
presentParams_.BackBufferHeight = yres;
|
presentParams_.BackBufferHeight = yres;
|
||||||
|
presentParams_.PresentationInterval = newInterval;
|
||||||
HRESULT hr = device_->Reset(&presentParams_);
|
HRESULT hr = device_->Reset(&presentParams_);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
// Had to remove DXGetErrorStringA calls here because dxerr.lib is deprecated and will not link with VS 2015.
|
// Had to remove DXGetErrorStringA calls here because dxerr.lib is deprecated and will not link with VS 2015.
|
||||||
|
@ -53,5 +53,6 @@ private:
|
|||||||
HWND hWnd_; // Holds Our Window Handle
|
HWND hWnd_; // Holds Our Window Handle
|
||||||
HMODULE hD3D9_;
|
HMODULE hD3D9_;
|
||||||
D3DPRESENT_PARAMETERS presentParams_;
|
D3DPRESENT_PARAMETERS presentParams_;
|
||||||
|
int swapInterval_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,6 +74,15 @@ static VulkanContext *g_Vulkan;
|
|||||||
|
|
||||||
static VulkanLogOptions g_LogOptions;
|
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) {
|
bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_message) {
|
||||||
*error_message = "N/A";
|
*error_message = "N/A";
|
||||||
|
|
||||||
@ -100,10 +109,7 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
|
|||||||
VulkanContext::CreateInfo info{};
|
VulkanContext::CreateInfo info{};
|
||||||
info.app_name = "PPSSPP";
|
info.app_name = "PPSSPP";
|
||||||
info.app_ver = gitVer.ToInteger();
|
info.app_ver = gitVer.ToInteger();
|
||||||
info.flags = VULKAN_FLAG_PRESENT_MAILBOX;
|
info.flags = FlagsFromConfig();
|
||||||
if (g_validate_) {
|
|
||||||
info.flags |= VULKAN_FLAG_VALIDATE;
|
|
||||||
}
|
|
||||||
if (VK_SUCCESS != g_Vulkan->CreateInstance(info)) {
|
if (VK_SUCCESS != g_Vulkan->CreateInstance(info)) {
|
||||||
*error_message = g_Vulkan->InitError();
|
*error_message = g_Vulkan->InitError();
|
||||||
delete g_Vulkan;
|
delete g_Vulkan;
|
||||||
@ -184,6 +190,7 @@ void WindowsVulkanContext::Resize() {
|
|||||||
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||||
g_Vulkan->DestroyObjects();
|
g_Vulkan->DestroyObjects();
|
||||||
|
|
||||||
|
g_Vulkan->UpdateFlags(FlagsFromConfig());
|
||||||
g_Vulkan->ReinitSurface();
|
g_Vulkan->ReinitSurface();
|
||||||
|
|
||||||
g_Vulkan->InitObjects();
|
g_Vulkan->InitObjects();
|
||||||
|
@ -739,6 +739,7 @@ namespace MainWindow {
|
|||||||
|
|
||||||
case ID_OPTIONS_VSYNC:
|
case ID_OPTIONS_VSYNC:
|
||||||
g_Config.bVSync = !g_Config.bVSync;
|
g_Config.bVSync = !g_Config.bVSync;
|
||||||
|
NativeResized();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_OPTIONS_FRAMESKIP_AUTO:
|
case ID_OPTIONS_FRAMESKIP_AUTO:
|
||||||
|
@ -81,6 +81,13 @@ AndroidVulkanContext::~AndroidVulkanContext() {
|
|||||||
g_Vulkan = nullptr;
|
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() {
|
bool AndroidVulkanContext::InitAPI() {
|
||||||
ILOG("AndroidVulkanContext::Init");
|
ILOG("AndroidVulkanContext::Init");
|
||||||
init_glslang();
|
init_glslang();
|
||||||
@ -105,7 +112,7 @@ bool AndroidVulkanContext::InitAPI() {
|
|||||||
VulkanContext::CreateInfo info{};
|
VulkanContext::CreateInfo info{};
|
||||||
info.app_name = "PPSSPP";
|
info.app_name = "PPSSPP";
|
||||||
info.app_ver = gitVer.ToInteger();
|
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);
|
VkResult res = g_Vulkan->CreateInstance(info);
|
||||||
if (res != VK_SUCCESS) {
|
if (res != VK_SUCCESS) {
|
||||||
ELOG("Failed to create vulkan context: %s", g_Vulkan->InitError().c_str());
|
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());
|
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||||
g_Vulkan->DestroyObjects();
|
g_Vulkan->DestroyObjects();
|
||||||
|
|
||||||
// backbufferResize updated these values. TODO: Notify another way?
|
g_Vulkan->UpdateFlags(FlagsFromConfig());
|
||||||
g_Vulkan->ReinitSurface();
|
g_Vulkan->ReinitSurface();
|
||||||
g_Vulkan->InitObjects();
|
g_Vulkan->InitObjects();
|
||||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||||
|
@ -73,9 +73,6 @@ void CheckGLExtensions() {
|
|||||||
memset(&gl_extensions, 0, sizeof(gl_extensions));
|
memset(&gl_extensions, 0, sizeof(gl_extensions));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirectXState::SetVSyncInterval(int interval) {
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace DX9
|
} // namespace DX9
|
||||||
|
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
@ -484,9 +484,6 @@ public:
|
|||||||
DxSampler0State1<D3DSAMP_MAXMIPLEVEL, 0> texMaxMipLevel;
|
DxSampler0State1<D3DSAMP_MAXMIPLEVEL, 0> texMaxMipLevel;
|
||||||
DxSampler0State1<D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP> texAddressU;
|
DxSampler0State1<D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP> texAddressU;
|
||||||
DxSampler0State1<D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP> texAddressV;
|
DxSampler0State1<D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP> texAddressV;
|
||||||
|
|
||||||
// Only works on Win32, all other platforms are "force-vsync"
|
|
||||||
void SetVSyncInterval(int interval); // one of the above VSYNC, or a higher number for multi-frame waits (could be useful for 30hz games)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef STATE1
|
#undef STATE1
|
||||||
|
Loading…
Reference in New Issue
Block a user