mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Get rid of a lot of ifdefs around presentation mode. Instead, set things dynamically.
This commit is contained in:
parent
870c45edd7
commit
ff6e118fff
@ -1855,6 +1855,8 @@ add_library(${CoreLibName} ${CoreLinkType}
|
||||
Core/CoreTiming.h
|
||||
Core/CwCheat.cpp
|
||||
Core/CwCheat.h
|
||||
Core/FrameTiming.cpp
|
||||
Core/FrameTiming.h
|
||||
Core/HDRemaster.cpp
|
||||
Core/HDRemaster.h
|
||||
Core/Instance.cpp
|
||||
|
@ -75,10 +75,6 @@ public:
|
||||
return (uint32_t)ShaderLanguage::HLSL_D3D11;
|
||||
}
|
||||
uint32_t GetDataFormatSupport(DataFormat fmt) const override;
|
||||
PresentMode GetPresentMode() const override {
|
||||
// TODO: Fix. Not yet used.
|
||||
return PresentMode::FIFO;
|
||||
}
|
||||
|
||||
InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override;
|
||||
DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override;
|
||||
@ -139,7 +135,7 @@ public:
|
||||
|
||||
void BeginFrame(DebugFlags debugFlags) override;
|
||||
void EndFrame() override;
|
||||
void Present(int vblanks) override;
|
||||
void Present(PresentMode presentMode, int vblanks) override;
|
||||
|
||||
int GetFrameCount() override { return frameCount_; }
|
||||
|
||||
@ -284,6 +280,10 @@ D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *de
|
||||
caps_.blendMinMaxSupported = true;
|
||||
caps_.multiSampleLevelsMask = 1; // More could be supported with some work.
|
||||
|
||||
caps_.presentInstantModeChange = true;
|
||||
caps_.presentMaxInterval = 4;
|
||||
caps_.presentModesSupported = PresentMode::FIFO | PresentMode::IMMEDIATE;
|
||||
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS options{};
|
||||
HRESULT result = device_->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &options, sizeof(options));
|
||||
if (SUCCEEDED(result)) {
|
||||
@ -433,8 +433,12 @@ void D3D11DrawContext::EndFrame() {
|
||||
curPipeline_ = nullptr;
|
||||
}
|
||||
|
||||
void D3D11DrawContext::Present(int vblanks) {
|
||||
swapChain_->Present(1, 0);
|
||||
void D3D11DrawContext::Present(PresentMode presentMode, int vblanks) {
|
||||
int interval = vblanks;
|
||||
if (presentMode != PresentMode::FIFO) {
|
||||
interval = 0;
|
||||
}
|
||||
swapChain_->Present(interval, 0);
|
||||
curRenderTargetView_ = nullptr;
|
||||
curDepthStencilView_ = nullptr;
|
||||
frameCount_++;
|
||||
|
@ -518,10 +518,6 @@ public:
|
||||
return (uint32_t)ShaderLanguage::HLSL_D3D9;
|
||||
}
|
||||
uint32_t GetDataFormatSupport(DataFormat fmt) const override;
|
||||
PresentMode GetPresentMode() const override {
|
||||
// TODO: Fix. Not yet used.
|
||||
return PresentMode::FIFO;
|
||||
}
|
||||
|
||||
ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize, const char *tag) override;
|
||||
DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override;
|
||||
@ -580,7 +576,7 @@ public:
|
||||
}
|
||||
|
||||
void EndFrame() override;
|
||||
void Present(int vblanks) override;
|
||||
void Present(PresentMode presentMode, int vblanks) override;
|
||||
|
||||
int GetFrameCount() override { return frameCount_; }
|
||||
|
||||
@ -785,6 +781,9 @@ D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, ID
|
||||
caps_.multiSampleLevelsMask = 1; // More could be supported with some work.
|
||||
|
||||
caps_.clipPlanesSupported = caps.MaxUserClipPlanes;
|
||||
caps_.presentInstantModeChange = false;
|
||||
caps_.presentMaxInterval = 1;
|
||||
caps_.presentModesSupported = PresentMode::FIFO;
|
||||
|
||||
if ((caps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) != 0 && caps.MaxAnisotropy > 1) {
|
||||
caps_.anisoSupported = true;
|
||||
@ -970,7 +969,7 @@ void D3D9Context::EndFrame() {
|
||||
curPipeline_ = nullptr;
|
||||
}
|
||||
|
||||
void D3D9Context::Present(int vblanks) {
|
||||
void D3D9Context::Present(PresentMode presentMode, int vblanks) {
|
||||
if (deviceEx_) {
|
||||
deviceEx_->EndScene();
|
||||
deviceEx_->PresentEx(NULL, NULL, NULL, NULL, 0);
|
||||
|
@ -322,7 +322,7 @@ class OpenGLTexture;
|
||||
|
||||
class OpenGLContext : public DrawContext {
|
||||
public:
|
||||
OpenGLContext();
|
||||
OpenGLContext(bool canChangeSwapInterval);
|
||||
~OpenGLContext();
|
||||
|
||||
void SetTargetSize(int w, int h) override {
|
||||
@ -347,11 +347,6 @@ public:
|
||||
renderManager_.SetErrorCallback(callback, userdata);
|
||||
}
|
||||
|
||||
PresentMode GetPresentMode() const override {
|
||||
// TODO: Fix. Not yet used.
|
||||
return PresentMode::FIFO;
|
||||
}
|
||||
|
||||
DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override;
|
||||
BlendState *CreateBlendState(const BlendStateDesc &desc) override;
|
||||
SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override;
|
||||
@ -366,7 +361,7 @@ public:
|
||||
|
||||
void BeginFrame(DebugFlags debugFlags) override;
|
||||
void EndFrame() override;
|
||||
void Present(int vblanks) override;
|
||||
void Present(PresentMode mode, int vblanks) override;
|
||||
|
||||
int GetFrameCount() override {
|
||||
return frameCount_;
|
||||
@ -547,7 +542,7 @@ static bool HasIntelDualSrcBug(const int versions[4]) {
|
||||
}
|
||||
}
|
||||
|
||||
OpenGLContext::OpenGLContext() {
|
||||
OpenGLContext::OpenGLContext(bool canChangeSwapInterval) {
|
||||
if (gl_extensions.IsGLES) {
|
||||
if (gl_extensions.OES_packed_depth_stencil || gl_extensions.OES_depth24) {
|
||||
caps_.preferredDepthBufferFormat = DataFormat::D24_S8;
|
||||
@ -778,6 +773,16 @@ OpenGLContext::OpenGLContext() {
|
||||
}
|
||||
}
|
||||
|
||||
if (canChangeSwapInterval) {
|
||||
caps_.presentInstantModeChange = true;
|
||||
caps_.presentMaxInterval = 4;
|
||||
caps_.presentModesSupported = PresentMode::FIFO | PresentMode::IMMEDIATE;
|
||||
} else {
|
||||
caps_.presentInstantModeChange = false;
|
||||
caps_.presentModesSupported = PresentMode::FIFO;
|
||||
caps_.presentMaxInterval = 1;
|
||||
}
|
||||
|
||||
renderManager_.SetDeviceCaps(caps_);
|
||||
}
|
||||
|
||||
@ -802,7 +807,7 @@ void OpenGLContext::EndFrame() {
|
||||
Invalidate(InvalidationFlags::CACHED_RENDER_STATE);
|
||||
}
|
||||
|
||||
void OpenGLContext::Present(int vblanks) {
|
||||
void OpenGLContext::Present(PresentMode presentMode, int vblanks) {
|
||||
renderManager_.Present();
|
||||
frameCount_++;
|
||||
}
|
||||
@ -1414,8 +1419,8 @@ void OpenGLContext::Clear(int mask, uint32_t colorval, float depthVal, int stenc
|
||||
renderManager_.Clear(colorval, depthVal, stencilVal, glMask, 0xF, 0, 0, targetWidth_, targetHeight_);
|
||||
}
|
||||
|
||||
DrawContext *T3DCreateGLContext() {
|
||||
return new OpenGLContext();
|
||||
DrawContext *T3DCreateGLContext(bool canChangeSwapInterval) {
|
||||
return new OpenGLContext(canChangeSwapInterval);
|
||||
}
|
||||
|
||||
OpenGLInputLayout::~OpenGLInputLayout() {
|
||||
|
@ -404,7 +404,7 @@ public:
|
||||
}
|
||||
uint32_t GetDataFormatSupport(DataFormat fmt) const override;
|
||||
|
||||
PresentMode GetPresentMode() const override {
|
||||
PresentMode GetPresentMode() const {
|
||||
switch (vulkan_->GetPresentMode()) {
|
||||
case VK_PRESENT_MODE_FIFO_KHR: return PresentMode::FIFO;
|
||||
case VK_PRESENT_MODE_FIFO_RELAXED_KHR: return PresentMode::FIFO; // We treat is as FIFO for now (and won't ever enable it anyway...)
|
||||
@ -480,7 +480,7 @@ public:
|
||||
|
||||
void BeginFrame(DebugFlags debugFlags) override;
|
||||
void EndFrame() override;
|
||||
void Present(int vblanks) override;
|
||||
void Present(PresentMode presentMode, int vblanks) override;
|
||||
|
||||
void WipeQueue() override;
|
||||
|
||||
@ -899,6 +899,19 @@ VKContext::VKContext(VulkanContext *vulkan, bool useRenderThread)
|
||||
caps_.sampleRateShadingSupported = vulkan->GetDeviceFeatures().enabled.standard.sampleRateShading != 0;
|
||||
caps_.textureSwizzleSupported = true;
|
||||
|
||||
// Present mode stuff
|
||||
caps_.presentMaxInterval = 1;
|
||||
caps_.presentInstantModeChange = false; // TODO: Fix this with some work in VulkanContext
|
||||
caps_.presentModesSupported = (PresentMode)0;
|
||||
for (auto mode : vulkan->GetAvailablePresentModes()) {
|
||||
switch (mode) {
|
||||
case VK_PRESENT_MODE_FIFO_KHR: caps_.presentModesSupported |= PresentMode::FIFO; break;
|
||||
case VK_PRESENT_MODE_IMMEDIATE_KHR: caps_.presentModesSupported |= PresentMode::IMMEDIATE; break;
|
||||
case VK_PRESENT_MODE_MAILBOX_KHR: caps_.presentModesSupported |= PresentMode::MAILBOX; break;
|
||||
default: break; // Ignore any other modes.
|
||||
}
|
||||
}
|
||||
|
||||
const auto &limits = vulkan->GetPhysicalDeviceProperties().properties.limits;
|
||||
|
||||
auto deviceProps = vulkan->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDeviceIndex()).properties;
|
||||
@ -1120,8 +1133,10 @@ void VKContext::EndFrame() {
|
||||
Invalidate(InvalidationFlags::CACHED_RENDER_STATE);
|
||||
}
|
||||
|
||||
void VKContext::Present(int vblanks) {
|
||||
void VKContext::Present(PresentMode presentMode, int vblanks) {
|
||||
if (presentMode == PresentMode::FIFO) {
|
||||
_dbg_assert_(vblanks == 0 || vblanks == 1);
|
||||
}
|
||||
renderManager_.Present();
|
||||
frameCount_++;
|
||||
}
|
||||
|
@ -768,4 +768,15 @@ const char *Bugs::GetBugName(uint32_t bug) {
|
||||
}
|
||||
}
|
||||
|
||||
const char *PresentModeToString(PresentMode presentMode) {
|
||||
switch (presentMode) {
|
||||
case (PresentMode)0: return "NONE (bad)";
|
||||
case PresentMode::FIFO: return "FIFO";
|
||||
case PresentMode::IMMEDIATE: return "IMMEDIATE";
|
||||
case PresentMode::MAILBOX: return "MAILBOX";
|
||||
default:
|
||||
return "COMBO"; // TODO: Hardcode all the combinations?
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Draw
|
||||
|
@ -570,6 +570,13 @@ struct PipelineDesc {
|
||||
const Slice<SamplerDef> samplers;
|
||||
};
|
||||
|
||||
enum class PresentMode {
|
||||
FIFO = 1,
|
||||
IMMEDIATE = 2,
|
||||
MAILBOX = 4,
|
||||
};
|
||||
ENUM_CLASS_BITOPS(PresentMode);
|
||||
|
||||
struct DeviceCaps {
|
||||
GPUVendor vendor;
|
||||
uint32_t deviceID; // use caution!
|
||||
@ -614,6 +621,11 @@ struct DeviceCaps {
|
||||
// Old style, for older GL or Direct3D 9.
|
||||
u32 clipPlanesSupported;
|
||||
|
||||
// Presentation caps
|
||||
int presentMaxInterval; // 1 on many backends
|
||||
bool presentInstantModeChange; // Our VulkanContext doesn't currently support it so we mark it as such, but it can be supported with careful coding.
|
||||
PresentMode presentModesSupported;
|
||||
|
||||
u32 multiSampleLevelsMask; // Bit n is set if (1 << n) is a valid multisample level. Bit 0 is always set.
|
||||
std::string deviceName; // The device name to use when creating the thin3d context, to get the same one.
|
||||
};
|
||||
@ -675,13 +687,6 @@ enum class DebugFlags {
|
||||
};
|
||||
ENUM_CLASS_BITOPS(DebugFlags);
|
||||
|
||||
enum class PresentMode {
|
||||
FIFO,
|
||||
IMMEDIATE,
|
||||
MAILBOX,
|
||||
// Retired FIFO_RELAXED. May reintroduce at some point.
|
||||
};
|
||||
|
||||
class DrawContext {
|
||||
public:
|
||||
virtual ~DrawContext();
|
||||
@ -696,8 +701,6 @@ public:
|
||||
virtual std::vector<std::string> GetExtensionList(bool device, bool enabledOnly) const { return std::vector<std::string>(); }
|
||||
virtual std::vector<std::string> GetDeviceList() const { return std::vector<std::string>(); }
|
||||
|
||||
virtual PresentMode GetPresentMode() const = 0;
|
||||
|
||||
// Describes the primary shader language that this implementation prefers.
|
||||
const ShaderLanguageDesc &GetShaderLanguageDesc() {
|
||||
return shaderLanguageDesc_;
|
||||
@ -815,7 +818,10 @@ public:
|
||||
// Frame management (for the purposes of sync and resource management, necessary with modern APIs). Default implementations here.
|
||||
virtual void BeginFrame(DebugFlags debugFlags) {}
|
||||
virtual void EndFrame() = 0;
|
||||
virtual void Present(int vblanks) = 0; // NOTE: Not all backends support vblanks > 1.
|
||||
|
||||
// vblanks is only relevant in FIFO present mode.
|
||||
// NOTE: Not all backends support vblanks > 1. Some backends also can't change presentation mode immediately.
|
||||
virtual void Present(PresentMode presentMode, int vblanks) = 0;
|
||||
|
||||
virtual void WipeQueue() {}
|
||||
|
||||
@ -895,4 +901,6 @@ struct ShaderSource {
|
||||
|
||||
ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector<ShaderSource> &sources);
|
||||
|
||||
const char *PresentModeToString(PresentMode presentMode);
|
||||
|
||||
} // namespace Draw
|
||||
|
@ -24,7 +24,7 @@ class VulkanContext;
|
||||
|
||||
namespace Draw {
|
||||
|
||||
DrawContext *T3DCreateGLContext();
|
||||
DrawContext *T3DCreateGLContext(bool canChangeSwapInterval);
|
||||
|
||||
#ifdef _WIN32
|
||||
DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx);
|
||||
|
@ -14,7 +14,6 @@ public:
|
||||
virtual void ShutdownFromRenderThread() {}
|
||||
|
||||
virtual void Shutdown() = 0;
|
||||
virtual void SwapInterval(int interval) = 0;
|
||||
|
||||
// Used during window resize. Must be called from the window thread,
|
||||
// not the rendering thread or CPU thread.
|
||||
|
@ -147,6 +147,15 @@ static bool DefaultCodeGen() {
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool DefaultVSync() {
|
||||
#if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(UWP)
|
||||
// Previously we didn't allow turning off vsync/FIFO on Android. Let's set the default accordingly.
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool DefaultEnableStateUndo() {
|
||||
#ifdef MOBILE_DEVICE
|
||||
// Off on mobile to save disk space.
|
||||
@ -603,7 +612,7 @@ static const ConfigSetting graphicsSettings[] = {
|
||||
ConfigSetting("TexScalingType", &g_Config.iTexScalingType, 0, CfgFlag::PER_GAME | CfgFlag::REPORT),
|
||||
ConfigSetting("TexDeposterize", &g_Config.bTexDeposterize, false, CfgFlag::PER_GAME | CfgFlag::REPORT),
|
||||
ConfigSetting("TexHardwareScaling", &g_Config.bTexHardwareScaling, false, CfgFlag::PER_GAME | CfgFlag::REPORT),
|
||||
ConfigSetting("VSyncInterval", &g_Config.bVSync, false, CfgFlag::PER_GAME),
|
||||
ConfigSetting("VSync", &g_Config.bVSync, &DefaultVSync, CfgFlag::PER_GAME),
|
||||
ConfigSetting("BloomHack", &g_Config.iBloomHack, 0, CfgFlag::PER_GAME | CfgFlag::REPORT),
|
||||
|
||||
// Not really a graphics setting...
|
||||
|
@ -10,3 +10,65 @@
|
||||
#include "Core/FrameTiming.h"
|
||||
|
||||
FrameTiming g_frameTiming;
|
||||
|
||||
inline Draw::PresentMode GetBestImmediateMode(Draw::PresentMode supportedModes) {
|
||||
if (supportedModes & Draw::PresentMode::MAILBOX) {
|
||||
return Draw::PresentMode::MAILBOX;
|
||||
} else {
|
||||
return Draw::PresentMode::IMMEDIATE;
|
||||
}
|
||||
}
|
||||
|
||||
void FrameTiming::Reset(Draw::DrawContext *draw) {
|
||||
if (g_Config.bVSync) {
|
||||
presentMode = Draw::PresentMode::FIFO;
|
||||
presentInterval = 1;
|
||||
} else {
|
||||
presentMode = GetBestImmediateMode(draw->GetDeviceCaps().presentModesSupported);
|
||||
presentInterval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Draw::PresentMode ComputePresentMode(Draw::DrawContext *draw, int *interval) {
|
||||
Draw::PresentMode mode = Draw::PresentMode::FIFO;
|
||||
|
||||
if (draw->GetDeviceCaps().presentModesSupported & (Draw::PresentMode::IMMEDIATE | Draw::PresentMode::MAILBOX)) {
|
||||
// Switch to immediate if desired and possible.
|
||||
bool wantInstant = false;
|
||||
if (!g_Config.bVSync) {
|
||||
wantInstant = true;
|
||||
}
|
||||
|
||||
if (PSP_CoreParameter().fastForward) {
|
||||
wantInstant = true;
|
||||
}
|
||||
if (PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL) {
|
||||
int limit;
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1)
|
||||
limit = g_Config.iFpsLimit1;
|
||||
else if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2)
|
||||
limit = g_Config.iFpsLimit2;
|
||||
else
|
||||
limit = PSP_CoreParameter().analogFpsLimit;
|
||||
|
||||
// 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)) {
|
||||
wantInstant = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (wantInstant && g_Config.bVSync && !draw->GetDeviceCaps().presentInstantModeChange) {
|
||||
// If in vsync mode (which will be FIFO), and the backend can't switch immediately,
|
||||
// stick to FIFO.
|
||||
wantInstant = false;
|
||||
}
|
||||
|
||||
// If no instant modes are supported, stick to FIFO.
|
||||
if (wantInstant && (draw->GetDeviceCaps().presentModesSupported & (Draw::PresentMode::MAILBOX | Draw::PresentMode::IMMEDIATE))) {
|
||||
mode = GetBestImmediateMode(draw->GetDeviceCaps().presentModesSupported);
|
||||
}
|
||||
}
|
||||
|
||||
*interval = (mode == Draw::PresentMode::FIFO) ? 1 : 0;
|
||||
return mode;
|
||||
}
|
||||
|
@ -1,7 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
struct FrameTiming {
|
||||
#include "Common/GPU/thin3d.h"
|
||||
|
||||
namespace Draw {
|
||||
class DrawContext;
|
||||
}
|
||||
|
||||
struct FrameTiming {
|
||||
// Some backends won't allow changing this willy nilly.
|
||||
Draw::PresentMode presentMode;
|
||||
int presentInterval;
|
||||
|
||||
void Reset(Draw::DrawContext *draw);
|
||||
};
|
||||
|
||||
extern FrameTiming g_frameTiming;
|
||||
|
||||
Draw::PresentMode ComputePresentMode(Draw::DrawContext *draw, int *interval);
|
||||
|
@ -566,13 +566,18 @@ void __DisplayFlip(int cyclesLate) {
|
||||
|
||||
bool fastForwardSkipFlip = g_Config.iFastForwardMode != (int)FastForwardMode::CONTINUOUS;
|
||||
|
||||
bool fifo = gpu && gpu->GetDrawContext() && gpu->GetDrawContext()->GetPresentMode() == Draw::PresentMode::FIFO;
|
||||
if (gpu) {
|
||||
Draw::DrawContext *draw = gpu->GetDrawContext();
|
||||
|
||||
if (fifo && GetGPUBackend() == GPUBackend::VULKAN) {
|
||||
g_frameTiming.presentMode = ComputePresentMode(draw, &g_frameTiming.presentInterval);
|
||||
|
||||
if (!draw->GetDeviceCaps().presentInstantModeChange && g_frameTiming.presentMode == Draw::PresentMode::FIFO) {
|
||||
// Some backends can't just flip into MAILBOX/IMMEDIATE mode instantly.
|
||||
// Vulkan doesn't support the interval setting, so we force skipping the flip.
|
||||
// TODO: We'll clean this up in a more backend-independent way later.
|
||||
fastForwardSkipFlip = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_Config.bSkipBufferEffects) {
|
||||
postEffectRequiresFlip = duplicateFrames || g_Config.bShaderChainRequires60FPS;
|
||||
|
@ -846,6 +846,8 @@ namespace MIPSComp {
|
||||
case VecDo3Op::VSLT:
|
||||
allowSIMD = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
u8 sregs[4], tregs[4], dregs[4];
|
||||
@ -941,6 +943,8 @@ namespace MIPSComp {
|
||||
ir.Write(IROp::FMovFromGPR, tempregs[i], IRTEMP_1);
|
||||
ir.Write(IROp::FCvtSW, tempregs[i], tempregs[i]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,6 @@
|
||||
|
||||
GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
||||
: GPUCommonHW(gfxCtx, draw), drawEngine_(draw), fragmentTestCache_(draw) {
|
||||
UpdateVsyncInterval(true);
|
||||
gstate_c.SetUseFlags(CheckGPUFeatures());
|
||||
|
||||
shaderManagerGL_ = new ShaderManagerGLES(draw);
|
||||
@ -86,8 +85,6 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
||||
UpdateCmdInfo();
|
||||
|
||||
BuildReportingInfo();
|
||||
// Update again after init to be sure of any silly driver problems.
|
||||
UpdateVsyncInterval(true);
|
||||
|
||||
textureCache_->NotifyConfigChanged();
|
||||
|
||||
@ -251,7 +248,6 @@ void GPU_GLES::DeviceRestore(Draw::DrawContext *draw) {
|
||||
GPUCommonHW::DeviceRestore(draw);
|
||||
|
||||
fragmentTestCache_.DeviceRestore(draw_);
|
||||
UpdateVsyncInterval(true);
|
||||
}
|
||||
|
||||
void GPU_GLES::BeginHostFrame() {
|
||||
|
@ -67,13 +67,11 @@ GPUCommon::GPUCommon(GraphicsContext *gfxCtx, Draw::DrawContext *draw) :
|
||||
gstate_c.Reset();
|
||||
gpuStats.Reset();
|
||||
|
||||
UpdateVsyncInterval(true);
|
||||
PPGeSetDrawContext(draw);
|
||||
ResetMatrices();
|
||||
}
|
||||
|
||||
void GPUCommon::BeginHostFrame() {
|
||||
UpdateVsyncInterval(displayResized_);
|
||||
ReapplyGfxState();
|
||||
|
||||
// TODO: Assume config may have changed - maybe move to resize.
|
||||
@ -115,38 +113,6 @@ void GPUCommon::Reinitialize() {
|
||||
framebufferManager_->DestroyAllFBOs();
|
||||
}
|
||||
|
||||
void GPUCommon::UpdateVsyncInterval(bool force) {
|
||||
#if !(PPSSPP_PLATFORM(ANDROID) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP) || PPSSPP_PLATFORM(IOS))
|
||||
int desiredVSyncInterval = g_Config.bVSync ? 1 : 0;
|
||||
if (PSP_CoreParameter().fastForward) {
|
||||
desiredVSyncInterval = 0;
|
||||
}
|
||||
if (PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL) {
|
||||
int limit;
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1)
|
||||
limit = g_Config.iFpsLimit1;
|
||||
else if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2)
|
||||
limit = g_Config.iFpsLimit2;
|
||||
else
|
||||
limit = PSP_CoreParameter().analogFpsLimit;
|
||||
|
||||
// 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
|
||||
if (gfxCtx_)
|
||||
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.
|
||||
|
@ -243,7 +243,6 @@ protected:
|
||||
}
|
||||
|
||||
void BeginFrame() override;
|
||||
void UpdateVsyncInterval(bool force);
|
||||
|
||||
virtual void CheckDepthUsage(VirtualFramebuffer *vfb) {}
|
||||
virtual void FastRunLoop(DisplayList &list) = 0;
|
||||
|
@ -84,8 +84,6 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
||||
}
|
||||
|
||||
BuildReportingInfo();
|
||||
// Update again after init to be sure of any silly driver problems.
|
||||
UpdateVsyncInterval(true);
|
||||
|
||||
textureCache_->NotifyConfigChanged();
|
||||
|
||||
|
@ -49,7 +49,7 @@ class QtGLGraphicsContext : public GraphicsContext {
|
||||
public:
|
||||
QtGLGraphicsContext() {
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
draw_ = Draw::T3DCreateGLContext(false);
|
||||
SetGPUBackend(GPUBackend::OPENGL);
|
||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||
@ -66,10 +66,6 @@ public:
|
||||
}
|
||||
|
||||
void Shutdown() override {}
|
||||
void SwapInterval(int interval) override {
|
||||
// See TODO in constructor.
|
||||
// renderManager_->SwapInterval(interval);
|
||||
}
|
||||
void Resize() override {}
|
||||
|
||||
Draw::DrawContext *GetDrawContext() override {
|
||||
|
@ -414,7 +414,7 @@ int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int w, int h,
|
||||
|
||||
// Finally we can do the regular initialization.
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
draw_ = Draw::T3DCreateGLContext(true);
|
||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||
SetGPUBackend(GPUBackend::OPENGL);
|
||||
|
@ -19,9 +19,6 @@ public:
|
||||
void Shutdown() override;
|
||||
void ShutdownFromRenderThread() override;
|
||||
|
||||
// Gets forwarded to the render thread.
|
||||
void SwapInterval(int interval) override;
|
||||
|
||||
void Resize() override {}
|
||||
|
||||
Draw::DrawContext *GetDrawContext() override {
|
||||
|
@ -30,8 +30,6 @@ public:
|
||||
|
||||
void Poll() override;
|
||||
|
||||
void SwapInterval(int interval) override {
|
||||
}
|
||||
void *GetAPIContext() override {
|
||||
return vulkan_;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "Common/System/System.h"
|
||||
#include "UI/DebugOverlay.h"
|
||||
#include "Core/HW/Display.h"
|
||||
#include "Core/FrameTiming.h"
|
||||
#include "Core/HLE/sceSas.h"
|
||||
#include "Core/ControlMapper.h"
|
||||
#include "Core/Config.h"
|
||||
@ -113,7 +114,14 @@ static void DrawFrameTiming(UIContext *ctx, const Bounds &bounds) {
|
||||
ctx->BindFontTexture();
|
||||
ctx->Draw()->SetFontScale(0.5f, 0.5f);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
snprintf(statBuf, sizeof(statBuf),
|
||||
"Present mode (interval): %s (%d)",
|
||||
Draw::PresentModeToString(g_frameTiming.presentMode),
|
||||
g_frameTiming.presentInterval);
|
||||
|
||||
ctx->Draw()->DrawTextRect(ubuntu24, statBuf, bounds.x + 10, bounds.y + 50, bounds.w - 20, bounds.h - 30, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
FrameTimeData data = ctx->GetDrawContext()->GetFrameTimeData(6 + i);
|
||||
FrameTimeData prevData = ctx->GetDrawContext()->GetFrameTimeData(7 + i);
|
||||
if (data.frameBegin == 0.0) {
|
||||
@ -153,7 +161,7 @@ static void DrawFrameTiming(UIContext *ctx, const Bounds &bounds) {
|
||||
presentStats
|
||||
);
|
||||
}
|
||||
ctx->Draw()->DrawTextRect(ubuntu24, statBuf, bounds.x + 10 + i * 150, bounds.y + 50, bounds.w - 20, bounds.h - 30, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII);
|
||||
ctx->Draw()->DrawTextRect(ubuntu24, statBuf, bounds.x + 10 + i * 150, bounds.y + 150, bounds.w - 20, bounds.h - 30, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII);
|
||||
}
|
||||
ctx->Draw()->SetFontScale(1.0f, 1.0f);
|
||||
ctx->Flush();
|
||||
|
@ -605,10 +605,17 @@ void SystemInfoScreen::CreateTabs() {
|
||||
g_display.dpi)));
|
||||
#endif
|
||||
|
||||
#if !PPSSPP_PLATFORM(WINDOWS)
|
||||
// Don't show on Windows, since it's always treated as 60 there.
|
||||
displayInfo->Add(new InfoItem(si->T("Refresh rate"), StringFromFormat(si->T("%0.2f Hz"), (float)System_GetPropertyFloat(SYSPROP_DISPLAY_REFRESH_RATE))));
|
||||
#endif
|
||||
std::string presentModes;
|
||||
if (draw->GetDeviceCaps().presentModesSupported & Draw::PresentMode::FIFO) presentModes += "FIFO, ";
|
||||
if (draw->GetDeviceCaps().presentModesSupported & Draw::PresentMode::IMMEDIATE) presentModes += "IMMEDIATE, ";
|
||||
if (draw->GetDeviceCaps().presentModesSupported & Draw::PresentMode::MAILBOX) presentModes += "MAILBOX, ";
|
||||
if (!presentModes.empty()) {
|
||||
presentModes.pop_back();
|
||||
presentModes.pop_back();
|
||||
}
|
||||
displayInfo->Add(new InfoItem(si->T("Present modes"), presentModes));
|
||||
|
||||
CollapsibleSection *versionInfo = deviceSpecs->Add(new CollapsibleSection(si->T("Version Information")));
|
||||
std::string apiVersion;
|
||||
|
@ -335,13 +335,14 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !(PPSSPP_PLATFORM(ANDROID) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP) || PPSSPP_PLATFORM(IOS))
|
||||
// All backends support FIFO. Check if any immediate modes are supported, if so we can allow the user to choose.
|
||||
if (draw->GetDeviceCaps().presentModesSupported & (Draw::PresentMode::IMMEDIATE | Draw::PresentMode::MAILBOX)) {
|
||||
CheckBox *vSync = graphicsSettings->Add(new CheckBox(&g_Config.bVSync, gr->T("VSync")));
|
||||
vSync->OnClick.Add([=](EventParams &e) {
|
||||
NativeResized();
|
||||
return UI::EVENT_CONTINUE;
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
// Hide Immersive Mode on pre-kitkat Android
|
||||
|
@ -1051,6 +1051,7 @@ void RenderOverlays(UIContext *dc, void *userdata) {
|
||||
}
|
||||
|
||||
static Matrix4x4 ComputeOrthoMatrix(float xres, float yres) {
|
||||
// TODO: Should be able to share the y-flip logic here with the one in postprocessing/presentation, for example.
|
||||
Matrix4x4 ortho;
|
||||
switch (GetGPUBackend()) {
|
||||
case GPUBackend::VULKAN:
|
||||
@ -1132,6 +1133,8 @@ void NativeFrame(GraphicsContext *graphicsContext) {
|
||||
if (g_Config.bGpuLogProfiler)
|
||||
debugFlags |= Draw::DebugFlags::PROFILE_SCOPES;
|
||||
|
||||
g_frameTiming.Reset(g_draw);
|
||||
|
||||
g_draw->BeginFrame(debugFlags);
|
||||
|
||||
ui_draw2d.PushDrawMatrix(ortho);
|
||||
@ -1158,7 +1161,9 @@ void NativeFrame(GraphicsContext *graphicsContext) {
|
||||
ClearFailedGPUBackends();
|
||||
}
|
||||
|
||||
g_draw->Present(1);
|
||||
int interval;
|
||||
Draw::PresentMode presentMode = ComputePresentMode(g_draw, &interval);
|
||||
g_draw->Present(presentMode, interval);
|
||||
|
||||
if (resized) {
|
||||
INFO_LOG(G3D, "Resized flag set - recalculating bounds");
|
||||
|
@ -19,7 +19,6 @@ public:
|
||||
UWPGraphicsContext(std::shared_ptr<DX::DeviceResources> resources);
|
||||
|
||||
void Shutdown() override;
|
||||
void SwapInterval(int interval) override {}
|
||||
void Resize() override {}
|
||||
Draw::DrawContext * GetDrawContext() override {
|
||||
return draw_;
|
||||
|
@ -33,10 +33,6 @@
|
||||
#error This file should not be compiled for UWP.
|
||||
#endif
|
||||
|
||||
void D3D11Context::SwapInterval(int interval) {
|
||||
swapInterval_ = interval;
|
||||
}
|
||||
|
||||
HRESULT D3D11Context::CreateTheDevice(IDXGIAdapter *adapter) {
|
||||
bool windowed = true;
|
||||
// D3D11 has no need for display rotation.
|
||||
|
@ -30,7 +30,6 @@ class D3D11Context : public WindowsGraphicsContext {
|
||||
public:
|
||||
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
|
||||
void Shutdown() override;
|
||||
void SwapInterval(int interval) override;
|
||||
|
||||
void Resize() override;
|
||||
|
||||
|
@ -23,10 +23,6 @@
|
||||
|
||||
typedef HRESULT (__stdcall *DIRECT3DCREATE9EX)(UINT, IDirect3D9Ex**);
|
||||
|
||||
void D3D9Context::SwapInterval(int interval) {
|
||||
swapInterval_ = interval;
|
||||
}
|
||||
|
||||
bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
||||
bool windowed = true;
|
||||
hWnd_ = wnd;
|
||||
|
@ -34,7 +34,6 @@ public:
|
||||
|
||||
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
|
||||
void Shutdown() override;
|
||||
void SwapInterval(int interval) override;
|
||||
|
||||
void Resize() override;
|
||||
|
||||
|
@ -412,7 +412,7 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) {
|
||||
resumeRequested = false;
|
||||
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
draw_ = Draw::T3DCreateGLContext(wglSwapIntervalEXT != nullptr);
|
||||
bool success = draw_->CreatePresets(); // if we get this far, there will always be a GLSL compiler capable of compiling these.
|
||||
if (!success) {
|
||||
delete draw_;
|
||||
@ -443,11 +443,6 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) {
|
||||
return true; // Success
|
||||
}
|
||||
|
||||
void WindowsGLContext::SwapInterval(int interval) {
|
||||
// Delegate to the render manager to make sure it's done on the right thread.
|
||||
renderManager_->SwapInterval(interval);
|
||||
}
|
||||
|
||||
void WindowsGLContext::Shutdown() {
|
||||
glslang::FinalizeProcess();
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ public:
|
||||
void ShutdownFromRenderThread() override;
|
||||
|
||||
void Shutdown() override;
|
||||
void SwapInterval(int interval) override;
|
||||
|
||||
void Poll() override;
|
||||
|
||||
|
@ -29,7 +29,6 @@ public:
|
||||
WindowsVulkanContext() : draw_(nullptr) {}
|
||||
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
|
||||
void Shutdown() override;
|
||||
void SwapInterval(int interval) override {}
|
||||
void Resize() override;
|
||||
void Poll() override;
|
||||
|
||||
|
@ -22,7 +22,7 @@ bool AndroidJavaEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int
|
||||
g_display.rotation = DisplayRotation::ROTATE_0;
|
||||
g_display.rot_matrix.setIdentity();
|
||||
|
||||
draw_ = Draw::T3DCreateGLContext(); // Can't fail
|
||||
draw_ = Draw::T3DCreateGLContext(false); // Can't fail
|
||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||
|
||||
|
@ -15,7 +15,6 @@ public:
|
||||
void ShutdownFromRenderThread() override;
|
||||
|
||||
void Shutdown() override {}
|
||||
void SwapInterval(int interval) override {}
|
||||
void Resize() override {}
|
||||
|
||||
Draw::DrawContext *GetDrawContext() override {
|
||||
|
@ -175,6 +175,3 @@ void AndroidVulkanContext::Resize() {
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||
INFO_LOG(G3D, "AndroidVulkanContext::Resize end (final size: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||
}
|
||||
|
||||
void AndroidVulkanContext::SwapInterval(int interval) {
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ public:
|
||||
void ShutdownFromRenderThread() override; // Inverses InitFromRenderThread.
|
||||
|
||||
void Shutdown() override;
|
||||
void SwapInterval(int interval) override;
|
||||
void Resize() override;
|
||||
|
||||
void *GetAPIContext() override { return g_Vulkan; }
|
||||
|
@ -95,7 +95,6 @@ public:
|
||||
|
||||
void Shutdown() override {}
|
||||
void Resize() override {}
|
||||
void SwapInterval(int interval) override {}
|
||||
|
||||
private:
|
||||
Draw::DrawContext *draw_ = nullptr;
|
||||
@ -157,7 +156,7 @@ bool GLDummyGraphicsContext::InitFromRenderThread(std::string *errorMessage) {
|
||||
#endif
|
||||
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
draw_ = Draw::T3DCreateGLContext(false);
|
||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||
SetGPUBackend(GPUBackend::OPENGL);
|
||||
@ -166,6 +165,7 @@ bool GLDummyGraphicsContext::InitFromRenderThread(std::string *errorMessage) {
|
||||
renderManager_->SetSwapFunction([&]() {
|
||||
SDL_GL_SwapWindow(screen_);
|
||||
});
|
||||
// TODO: Support SwapInterval
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ class IOSGraphicsContext : public GraphicsContext {
|
||||
public:
|
||||
IOSGraphicsContext() {
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
draw_ = Draw::T3DCreateGLContext(false);
|
||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||
SetGPUBackend(GPUBackend::OPENGL);
|
||||
@ -63,7 +63,6 @@ public:
|
||||
return draw_;
|
||||
}
|
||||
|
||||
void SwapInterval(int interval) override {}
|
||||
void Resize() override {}
|
||||
void Shutdown() override {}
|
||||
|
||||
|
@ -31,7 +31,7 @@ void LibretroGLContext::CreateDrawContext() {
|
||||
#endif
|
||||
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
draw_ = Draw::T3DCreateGLContext(false);
|
||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||
SetGPUBackend(GPUBackend::OPENGL);
|
||||
|
@ -26,7 +26,7 @@ void LibretroGLCoreContext::CreateDrawContext() {
|
||||
glewInitDone = true;
|
||||
CheckGLExtensions();
|
||||
}
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
draw_ = Draw::T3DCreateGLContext(false);
|
||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||
SetGPUBackend(GPUBackend::OPENGL);
|
||||
|
@ -21,7 +21,6 @@ public:
|
||||
void Shutdown() override {
|
||||
DestroyDrawContext();
|
||||
}
|
||||
void SwapInterval(int interval) override {}
|
||||
virtual void SwapBuffers() = 0;
|
||||
void Resize() override {}
|
||||
|
||||
|
@ -1178,7 +1178,7 @@ namespace Libretro
|
||||
|
||||
if (ctx->GetDrawContext()) {
|
||||
ctx->GetDrawContext()->EndFrame();
|
||||
ctx->GetDrawContext()->Present(1);
|
||||
ctx->GetDrawContext()->Present(Draw::PresentMode::FIFO, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user