GPU: Centralize vsync interval logic.

We already do unthrottle checking here.
This commit is contained in:
Unknown W. Brackets 2020-02-29 22:27:00 -08:00
parent e7ddc94fb9
commit 3c1e8abcfe
12 changed files with 33 additions and 65 deletions

View File

@ -73,7 +73,6 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
device_ = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE);
context_ = (ID3D11DeviceContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT);
D3D_FEATURE_LEVEL featureLevel = (D3D_FEATURE_LEVEL)draw->GetNativeObject(Draw::NativeObject::FEATURE_LEVEL);
lastVsync_ = g_Config.bVSync ? 1 : 0;
stockD3D11.Create(device_);

View File

@ -81,6 +81,4 @@ private:
DepalShaderCacheD3D11 *depalShaderCache_;
DrawEngineD3D11 drawEngine_;
ShaderManagerD3D11 *shaderManagerD3D11_;
int lastVsync_;
};

View File

@ -58,8 +58,6 @@ GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
drawEngine_(draw) {
device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE);
deviceEx_ = (LPDIRECT3DDEVICE9EX)draw->GetNativeObject(Draw::NativeObject::DEVICE_EX);
lastVsync_ = g_Config.bVSync ? 1 : 0;
dxstate.SetVSyncInterval(g_Config.bVSync);
shaderManagerDX9_ = new ShaderManagerDX9(draw, device_);
framebufferManagerDX9_ = new FramebufferManagerDX9(draw);
@ -285,15 +283,6 @@ void GPU_DX9::ReapplyGfxState() {
}
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();
drawEngine_.DecimateTrackedVertexArrays();
depalShaderCache_.Decimate();

View File

@ -80,8 +80,6 @@ private:
DepalShaderCacheDX9 depalShaderCache_;
DrawEngineDX9 drawEngine_;
ShaderManagerDX9 *shaderManagerDX9_;
int lastVsync_;
};
} // namespace DX9

View File

@ -360,6 +360,7 @@ void GPU_GLES::BeginHostFrame() {
drawEngine_.Resized();
shaderManagerGL_->DirtyShader();
textureCacheGL_->NotifyConfigChanged();
resized_ = false;
}
drawEngine_.BeginFrame();
@ -369,42 +370,11 @@ void GPU_GLES::EndHostFrame() {
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() {
GPUCommon::ReapplyGfxState();
}
void GPU_GLES::BeginFrame() {
UpdateVsyncInterval(resized_);
resized_ = false;
textureCacheGL_->StartFrame();
drawEngine_.DecimateTrackedVertexArrays();
depalShaderCache_.Decimate();

View File

@ -79,8 +79,6 @@ private:
void CopyDisplayToOutput() override;
void Reinitialize() override;
inline void UpdateVsyncInterval(bool force);
FramebufferManagerGLES *framebufferManagerGL_;
TextureCacheGLES *textureCacheGL_;
DepalShaderCacheGLES depalShaderCache_;
@ -89,8 +87,4 @@ private:
ShaderManagerGLES *shaderManagerGL_;
std::string shaderCachePath_;
#ifdef _WIN32
int lastVsync_;
#endif
};

View File

@ -6,6 +6,7 @@
#include "profiler/profiler.h"
#include "Common/ColorConv.h"
#include "Common/GraphicsContext.h"
#include "Core/Reporting.h"
#include "GPU/GeDisasm.h"
#include "GPU/GPU.h"
@ -408,6 +409,7 @@ GPUCommon::GPUCommon(GraphicsContext *gfxCtx, Draw::DrawContext *draw) :
}
UpdateCmdInfo();
UpdateVsyncInterval(true);
}
GPUCommon::~GPUCommon() {
@ -432,6 +434,7 @@ void GPUCommon::UpdateCmdInfo() {
}
void GPUCommon::BeginHostFrame() {
UpdateVsyncInterval(resized_);
ReapplyGfxState();
// TODO: Assume config may have changed - maybe move to resize.
@ -458,6 +461,30 @@ void GPUCommon::Reinitialize() {
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() {
// TODO: This is transform cost, also account for rasterization cost somehow... although it probably
// runs in parallel with transform.

View File

@ -276,6 +276,7 @@ protected:
}
void BeginFrame() override;
void UpdateVsyncInterval(bool force);
virtual void FastRunLoop(DisplayList &list);
@ -362,6 +363,10 @@ private:
// Debug stats.
double timeSteppingStarted_;
double timeSpentStepping_;
#ifdef _WIN32
int lastVsync_;
#endif
};
struct CommonCommandTableEntry {

View File

@ -57,7 +57,6 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
drawEngine_(vulkan_, draw),
depalShaderCache_(draw, vulkan_),
vulkan2D_(vulkan_) {
UpdateVsyncInterval(true);
CheckGPUFeatures();
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) {
GPUDebug::NotifyDisplay(framebuf, stride, format);
framebufferManager_->SetDisplayFramebuffer(framebuf, stride, format);

View File

@ -80,7 +80,6 @@ private:
void InitClear() override;
void CopyDisplayToOutput() override;
void Reinitialize() override;
inline void UpdateVsyncInterval(bool force);
void InitDeviceObjects();
void DestroyDeviceObjects();

View File

@ -73,9 +73,6 @@ void CheckGLExtensions() {
memset(&gl_extensions, 0, sizeof(gl_extensions));
}
void DirectXState::SetVSyncInterval(int interval) {
}
} // namespace DX9
#endif // _MSC_VER

View File

@ -484,9 +484,6 @@ public:
DxSampler0State1<D3DSAMP_MAXMIPLEVEL, 0> texMaxMipLevel;
DxSampler0State1<D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP> texAddressU;
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