mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +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/CoreTiming.h
|
||||||
Core/CwCheat.cpp
|
Core/CwCheat.cpp
|
||||||
Core/CwCheat.h
|
Core/CwCheat.h
|
||||||
|
Core/FrameTiming.cpp
|
||||||
|
Core/FrameTiming.h
|
||||||
Core/HDRemaster.cpp
|
Core/HDRemaster.cpp
|
||||||
Core/HDRemaster.h
|
Core/HDRemaster.h
|
||||||
Core/Instance.cpp
|
Core/Instance.cpp
|
||||||
|
@ -75,10 +75,6 @@ public:
|
|||||||
return (uint32_t)ShaderLanguage::HLSL_D3D11;
|
return (uint32_t)ShaderLanguage::HLSL_D3D11;
|
||||||
}
|
}
|
||||||
uint32_t GetDataFormatSupport(DataFormat fmt) const override;
|
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;
|
InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override;
|
||||||
DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override;
|
DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override;
|
||||||
@ -139,7 +135,7 @@ public:
|
|||||||
|
|
||||||
void BeginFrame(DebugFlags debugFlags) override;
|
void BeginFrame(DebugFlags debugFlags) override;
|
||||||
void EndFrame() override;
|
void EndFrame() override;
|
||||||
void Present(int vblanks) override;
|
void Present(PresentMode presentMode, int vblanks) override;
|
||||||
|
|
||||||
int GetFrameCount() override { return frameCount_; }
|
int GetFrameCount() override { return frameCount_; }
|
||||||
|
|
||||||
@ -284,6 +280,10 @@ D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *de
|
|||||||
caps_.blendMinMaxSupported = true;
|
caps_.blendMinMaxSupported = true;
|
||||||
caps_.multiSampleLevelsMask = 1; // More could be supported with some work.
|
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{};
|
D3D11_FEATURE_DATA_D3D11_OPTIONS options{};
|
||||||
HRESULT result = device_->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &options, sizeof(options));
|
HRESULT result = device_->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &options, sizeof(options));
|
||||||
if (SUCCEEDED(result)) {
|
if (SUCCEEDED(result)) {
|
||||||
@ -433,8 +433,12 @@ void D3D11DrawContext::EndFrame() {
|
|||||||
curPipeline_ = nullptr;
|
curPipeline_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11DrawContext::Present(int vblanks) {
|
void D3D11DrawContext::Present(PresentMode presentMode, int vblanks) {
|
||||||
swapChain_->Present(1, 0);
|
int interval = vblanks;
|
||||||
|
if (presentMode != PresentMode::FIFO) {
|
||||||
|
interval = 0;
|
||||||
|
}
|
||||||
|
swapChain_->Present(interval, 0);
|
||||||
curRenderTargetView_ = nullptr;
|
curRenderTargetView_ = nullptr;
|
||||||
curDepthStencilView_ = nullptr;
|
curDepthStencilView_ = nullptr;
|
||||||
frameCount_++;
|
frameCount_++;
|
||||||
|
@ -518,10 +518,6 @@ public:
|
|||||||
return (uint32_t)ShaderLanguage::HLSL_D3D9;
|
return (uint32_t)ShaderLanguage::HLSL_D3D9;
|
||||||
}
|
}
|
||||||
uint32_t GetDataFormatSupport(DataFormat fmt) const override;
|
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;
|
ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize, const char *tag) override;
|
||||||
DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override;
|
DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override;
|
||||||
@ -580,7 +576,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EndFrame() override;
|
void EndFrame() override;
|
||||||
void Present(int vblanks) override;
|
void Present(PresentMode presentMode, int vblanks) override;
|
||||||
|
|
||||||
int GetFrameCount() override { return frameCount_; }
|
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_.multiSampleLevelsMask = 1; // More could be supported with some work.
|
||||||
|
|
||||||
caps_.clipPlanesSupported = caps.MaxUserClipPlanes;
|
caps_.clipPlanesSupported = caps.MaxUserClipPlanes;
|
||||||
|
caps_.presentInstantModeChange = false;
|
||||||
|
caps_.presentMaxInterval = 1;
|
||||||
|
caps_.presentModesSupported = PresentMode::FIFO;
|
||||||
|
|
||||||
if ((caps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) != 0 && caps.MaxAnisotropy > 1) {
|
if ((caps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) != 0 && caps.MaxAnisotropy > 1) {
|
||||||
caps_.anisoSupported = true;
|
caps_.anisoSupported = true;
|
||||||
@ -970,7 +969,7 @@ void D3D9Context::EndFrame() {
|
|||||||
curPipeline_ = nullptr;
|
curPipeline_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D9Context::Present(int vblanks) {
|
void D3D9Context::Present(PresentMode presentMode, int vblanks) {
|
||||||
if (deviceEx_) {
|
if (deviceEx_) {
|
||||||
deviceEx_->EndScene();
|
deviceEx_->EndScene();
|
||||||
deviceEx_->PresentEx(NULL, NULL, NULL, NULL, 0);
|
deviceEx_->PresentEx(NULL, NULL, NULL, NULL, 0);
|
||||||
|
@ -322,7 +322,7 @@ class OpenGLTexture;
|
|||||||
|
|
||||||
class OpenGLContext : public DrawContext {
|
class OpenGLContext : public DrawContext {
|
||||||
public:
|
public:
|
||||||
OpenGLContext();
|
OpenGLContext(bool canChangeSwapInterval);
|
||||||
~OpenGLContext();
|
~OpenGLContext();
|
||||||
|
|
||||||
void SetTargetSize(int w, int h) override {
|
void SetTargetSize(int w, int h) override {
|
||||||
@ -347,11 +347,6 @@ public:
|
|||||||
renderManager_.SetErrorCallback(callback, userdata);
|
renderManager_.SetErrorCallback(callback, userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
PresentMode GetPresentMode() const override {
|
|
||||||
// TODO: Fix. Not yet used.
|
|
||||||
return PresentMode::FIFO;
|
|
||||||
}
|
|
||||||
|
|
||||||
DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override;
|
DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override;
|
||||||
BlendState *CreateBlendState(const BlendStateDesc &desc) override;
|
BlendState *CreateBlendState(const BlendStateDesc &desc) override;
|
||||||
SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override;
|
SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override;
|
||||||
@ -366,7 +361,7 @@ public:
|
|||||||
|
|
||||||
void BeginFrame(DebugFlags debugFlags) override;
|
void BeginFrame(DebugFlags debugFlags) override;
|
||||||
void EndFrame() override;
|
void EndFrame() override;
|
||||||
void Present(int vblanks) override;
|
void Present(PresentMode mode, int vblanks) override;
|
||||||
|
|
||||||
int GetFrameCount() override {
|
int GetFrameCount() override {
|
||||||
return frameCount_;
|
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.IsGLES) {
|
||||||
if (gl_extensions.OES_packed_depth_stencil || gl_extensions.OES_depth24) {
|
if (gl_extensions.OES_packed_depth_stencil || gl_extensions.OES_depth24) {
|
||||||
caps_.preferredDepthBufferFormat = DataFormat::D24_S8;
|
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_);
|
renderManager_.SetDeviceCaps(caps_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -802,7 +807,7 @@ void OpenGLContext::EndFrame() {
|
|||||||
Invalidate(InvalidationFlags::CACHED_RENDER_STATE);
|
Invalidate(InvalidationFlags::CACHED_RENDER_STATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLContext::Present(int vblanks) {
|
void OpenGLContext::Present(PresentMode presentMode, int vblanks) {
|
||||||
renderManager_.Present();
|
renderManager_.Present();
|
||||||
frameCount_++;
|
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_);
|
renderManager_.Clear(colorval, depthVal, stencilVal, glMask, 0xF, 0, 0, targetWidth_, targetHeight_);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawContext *T3DCreateGLContext() {
|
DrawContext *T3DCreateGLContext(bool canChangeSwapInterval) {
|
||||||
return new OpenGLContext();
|
return new OpenGLContext(canChangeSwapInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLInputLayout::~OpenGLInputLayout() {
|
OpenGLInputLayout::~OpenGLInputLayout() {
|
||||||
|
@ -404,7 +404,7 @@ public:
|
|||||||
}
|
}
|
||||||
uint32_t GetDataFormatSupport(DataFormat fmt) const override;
|
uint32_t GetDataFormatSupport(DataFormat fmt) const override;
|
||||||
|
|
||||||
PresentMode GetPresentMode() const override {
|
PresentMode GetPresentMode() const {
|
||||||
switch (vulkan_->GetPresentMode()) {
|
switch (vulkan_->GetPresentMode()) {
|
||||||
case VK_PRESENT_MODE_FIFO_KHR: return PresentMode::FIFO;
|
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...)
|
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 BeginFrame(DebugFlags debugFlags) override;
|
||||||
void EndFrame() override;
|
void EndFrame() override;
|
||||||
void Present(int vblanks) override;
|
void Present(PresentMode presentMode, int vblanks) override;
|
||||||
|
|
||||||
void WipeQueue() override;
|
void WipeQueue() override;
|
||||||
|
|
||||||
@ -899,6 +899,19 @@ VKContext::VKContext(VulkanContext *vulkan, bool useRenderThread)
|
|||||||
caps_.sampleRateShadingSupported = vulkan->GetDeviceFeatures().enabled.standard.sampleRateShading != 0;
|
caps_.sampleRateShadingSupported = vulkan->GetDeviceFeatures().enabled.standard.sampleRateShading != 0;
|
||||||
caps_.textureSwizzleSupported = true;
|
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;
|
const auto &limits = vulkan->GetPhysicalDeviceProperties().properties.limits;
|
||||||
|
|
||||||
auto deviceProps = vulkan->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDeviceIndex()).properties;
|
auto deviceProps = vulkan->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDeviceIndex()).properties;
|
||||||
@ -1120,8 +1133,10 @@ void VKContext::EndFrame() {
|
|||||||
Invalidate(InvalidationFlags::CACHED_RENDER_STATE);
|
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);
|
_dbg_assert_(vblanks == 0 || vblanks == 1);
|
||||||
|
}
|
||||||
renderManager_.Present();
|
renderManager_.Present();
|
||||||
frameCount_++;
|
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
|
} // namespace Draw
|
||||||
|
@ -570,6 +570,13 @@ struct PipelineDesc {
|
|||||||
const Slice<SamplerDef> samplers;
|
const Slice<SamplerDef> samplers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class PresentMode {
|
||||||
|
FIFO = 1,
|
||||||
|
IMMEDIATE = 2,
|
||||||
|
MAILBOX = 4,
|
||||||
|
};
|
||||||
|
ENUM_CLASS_BITOPS(PresentMode);
|
||||||
|
|
||||||
struct DeviceCaps {
|
struct DeviceCaps {
|
||||||
GPUVendor vendor;
|
GPUVendor vendor;
|
||||||
uint32_t deviceID; // use caution!
|
uint32_t deviceID; // use caution!
|
||||||
@ -614,6 +621,11 @@ struct DeviceCaps {
|
|||||||
// Old style, for older GL or Direct3D 9.
|
// Old style, for older GL or Direct3D 9.
|
||||||
u32 clipPlanesSupported;
|
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.
|
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.
|
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_BITOPS(DebugFlags);
|
||||||
|
|
||||||
enum class PresentMode {
|
|
||||||
FIFO,
|
|
||||||
IMMEDIATE,
|
|
||||||
MAILBOX,
|
|
||||||
// Retired FIFO_RELAXED. May reintroduce at some point.
|
|
||||||
};
|
|
||||||
|
|
||||||
class DrawContext {
|
class DrawContext {
|
||||||
public:
|
public:
|
||||||
virtual ~DrawContext();
|
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> GetExtensionList(bool device, bool enabledOnly) const { return std::vector<std::string>(); }
|
||||||
virtual std::vector<std::string> GetDeviceList() 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.
|
// Describes the primary shader language that this implementation prefers.
|
||||||
const ShaderLanguageDesc &GetShaderLanguageDesc() {
|
const ShaderLanguageDesc &GetShaderLanguageDesc() {
|
||||||
return shaderLanguageDesc_;
|
return shaderLanguageDesc_;
|
||||||
@ -815,7 +818,10 @@ public:
|
|||||||
// Frame management (for the purposes of sync and resource management, necessary with modern APIs). Default implementations here.
|
// Frame management (for the purposes of sync and resource management, necessary with modern APIs). Default implementations here.
|
||||||
virtual void BeginFrame(DebugFlags debugFlags) {}
|
virtual void BeginFrame(DebugFlags debugFlags) {}
|
||||||
virtual void EndFrame() = 0;
|
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() {}
|
virtual void WipeQueue() {}
|
||||||
|
|
||||||
@ -895,4 +901,6 @@ struct ShaderSource {
|
|||||||
|
|
||||||
ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector<ShaderSource> &sources);
|
ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector<ShaderSource> &sources);
|
||||||
|
|
||||||
|
const char *PresentModeToString(PresentMode presentMode);
|
||||||
|
|
||||||
} // namespace Draw
|
} // namespace Draw
|
||||||
|
@ -24,7 +24,7 @@ class VulkanContext;
|
|||||||
|
|
||||||
namespace Draw {
|
namespace Draw {
|
||||||
|
|
||||||
DrawContext *T3DCreateGLContext();
|
DrawContext *T3DCreateGLContext(bool canChangeSwapInterval);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx);
|
DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx);
|
||||||
|
@ -14,7 +14,6 @@ public:
|
|||||||
virtual void ShutdownFromRenderThread() {}
|
virtual void ShutdownFromRenderThread() {}
|
||||||
|
|
||||||
virtual void Shutdown() = 0;
|
virtual void Shutdown() = 0;
|
||||||
virtual void SwapInterval(int interval) = 0;
|
|
||||||
|
|
||||||
// Used during window resize. Must be called from the window thread,
|
// Used during window resize. Must be called from the window thread,
|
||||||
// not the rendering thread or CPU thread.
|
// not the rendering thread or CPU thread.
|
||||||
|
@ -147,6 +147,15 @@ static bool DefaultCodeGen() {
|
|||||||
#endif
|
#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() {
|
static bool DefaultEnableStateUndo() {
|
||||||
#ifdef MOBILE_DEVICE
|
#ifdef MOBILE_DEVICE
|
||||||
// Off on mobile to save disk space.
|
// 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("TexScalingType", &g_Config.iTexScalingType, 0, CfgFlag::PER_GAME | CfgFlag::REPORT),
|
||||||
ConfigSetting("TexDeposterize", &g_Config.bTexDeposterize, false, 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("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),
|
ConfigSetting("BloomHack", &g_Config.iBloomHack, 0, CfgFlag::PER_GAME | CfgFlag::REPORT),
|
||||||
|
|
||||||
// Not really a graphics setting...
|
// Not really a graphics setting...
|
||||||
|
@ -10,3 +10,65 @@
|
|||||||
#include "Core/FrameTiming.h"
|
#include "Core/FrameTiming.h"
|
||||||
|
|
||||||
FrameTiming g_frameTiming;
|
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
|
#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;
|
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 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.
|
// 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.
|
// TODO: We'll clean this up in a more backend-independent way later.
|
||||||
fastForwardSkipFlip = true;
|
fastForwardSkipFlip = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!g_Config.bSkipBufferEffects) {
|
if (!g_Config.bSkipBufferEffects) {
|
||||||
postEffectRequiresFlip = duplicateFrames || g_Config.bShaderChainRequires60FPS;
|
postEffectRequiresFlip = duplicateFrames || g_Config.bShaderChainRequires60FPS;
|
||||||
|
@ -846,6 +846,8 @@ namespace MIPSComp {
|
|||||||
case VecDo3Op::VSLT:
|
case VecDo3Op::VSLT:
|
||||||
allowSIMD = false;
|
allowSIMD = false;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 sregs[4], tregs[4], dregs[4];
|
u8 sregs[4], tregs[4], dregs[4];
|
||||||
@ -941,6 +943,8 @@ namespace MIPSComp {
|
|||||||
ir.Write(IROp::FMovFromGPR, tempregs[i], IRTEMP_1);
|
ir.Write(IROp::FMovFromGPR, tempregs[i], IRTEMP_1);
|
||||||
ir.Write(IROp::FCvtSW, tempregs[i], tempregs[i]);
|
ir.Write(IROp::FCvtSW, tempregs[i], tempregs[i]);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
|
|
||||||
GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
||||||
: GPUCommonHW(gfxCtx, draw), drawEngine_(draw), fragmentTestCache_(draw) {
|
: GPUCommonHW(gfxCtx, draw), drawEngine_(draw), fragmentTestCache_(draw) {
|
||||||
UpdateVsyncInterval(true);
|
|
||||||
gstate_c.SetUseFlags(CheckGPUFeatures());
|
gstate_c.SetUseFlags(CheckGPUFeatures());
|
||||||
|
|
||||||
shaderManagerGL_ = new ShaderManagerGLES(draw);
|
shaderManagerGL_ = new ShaderManagerGLES(draw);
|
||||||
@ -86,8 +85,6 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
|||||||
UpdateCmdInfo();
|
UpdateCmdInfo();
|
||||||
|
|
||||||
BuildReportingInfo();
|
BuildReportingInfo();
|
||||||
// Update again after init to be sure of any silly driver problems.
|
|
||||||
UpdateVsyncInterval(true);
|
|
||||||
|
|
||||||
textureCache_->NotifyConfigChanged();
|
textureCache_->NotifyConfigChanged();
|
||||||
|
|
||||||
@ -251,7 +248,6 @@ void GPU_GLES::DeviceRestore(Draw::DrawContext *draw) {
|
|||||||
GPUCommonHW::DeviceRestore(draw);
|
GPUCommonHW::DeviceRestore(draw);
|
||||||
|
|
||||||
fragmentTestCache_.DeviceRestore(draw_);
|
fragmentTestCache_.DeviceRestore(draw_);
|
||||||
UpdateVsyncInterval(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_GLES::BeginHostFrame() {
|
void GPU_GLES::BeginHostFrame() {
|
||||||
|
@ -67,13 +67,11 @@ GPUCommon::GPUCommon(GraphicsContext *gfxCtx, Draw::DrawContext *draw) :
|
|||||||
gstate_c.Reset();
|
gstate_c.Reset();
|
||||||
gpuStats.Reset();
|
gpuStats.Reset();
|
||||||
|
|
||||||
UpdateVsyncInterval(true);
|
|
||||||
PPGeSetDrawContext(draw);
|
PPGeSetDrawContext(draw);
|
||||||
ResetMatrices();
|
ResetMatrices();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUCommon::BeginHostFrame() {
|
void GPUCommon::BeginHostFrame() {
|
||||||
UpdateVsyncInterval(displayResized_);
|
|
||||||
ReapplyGfxState();
|
ReapplyGfxState();
|
||||||
|
|
||||||
// TODO: Assume config may have changed - maybe move to resize.
|
// TODO: Assume config may have changed - maybe move to resize.
|
||||||
@ -115,38 +113,6 @@ void GPUCommon::Reinitialize() {
|
|||||||
framebufferManager_->DestroyAllFBOs();
|
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() {
|
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.
|
||||||
|
@ -243,7 +243,6 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BeginFrame() override;
|
void BeginFrame() override;
|
||||||
void UpdateVsyncInterval(bool force);
|
|
||||||
|
|
||||||
virtual void CheckDepthUsage(VirtualFramebuffer *vfb) {}
|
virtual void CheckDepthUsage(VirtualFramebuffer *vfb) {}
|
||||||
virtual void FastRunLoop(DisplayList &list) = 0;
|
virtual void FastRunLoop(DisplayList &list) = 0;
|
||||||
|
@ -84,8 +84,6 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BuildReportingInfo();
|
BuildReportingInfo();
|
||||||
// Update again after init to be sure of any silly driver problems.
|
|
||||||
UpdateVsyncInterval(true);
|
|
||||||
|
|
||||||
textureCache_->NotifyConfigChanged();
|
textureCache_->NotifyConfigChanged();
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ class QtGLGraphicsContext : public GraphicsContext {
|
|||||||
public:
|
public:
|
||||||
QtGLGraphicsContext() {
|
QtGLGraphicsContext() {
|
||||||
CheckGLExtensions();
|
CheckGLExtensions();
|
||||||
draw_ = Draw::T3DCreateGLContext();
|
draw_ = Draw::T3DCreateGLContext(false);
|
||||||
SetGPUBackend(GPUBackend::OPENGL);
|
SetGPUBackend(GPUBackend::OPENGL);
|
||||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||||
@ -66,10 +66,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown() override {}
|
void Shutdown() override {}
|
||||||
void SwapInterval(int interval) override {
|
|
||||||
// See TODO in constructor.
|
|
||||||
// renderManager_->SwapInterval(interval);
|
|
||||||
}
|
|
||||||
void Resize() override {}
|
void Resize() override {}
|
||||||
|
|
||||||
Draw::DrawContext *GetDrawContext() 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.
|
// Finally we can do the regular initialization.
|
||||||
CheckGLExtensions();
|
CheckGLExtensions();
|
||||||
draw_ = Draw::T3DCreateGLContext();
|
draw_ = Draw::T3DCreateGLContext(true);
|
||||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||||
SetGPUBackend(GPUBackend::OPENGL);
|
SetGPUBackend(GPUBackend::OPENGL);
|
||||||
|
@ -19,9 +19,6 @@ public:
|
|||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
void ShutdownFromRenderThread() override;
|
void ShutdownFromRenderThread() override;
|
||||||
|
|
||||||
// Gets forwarded to the render thread.
|
|
||||||
void SwapInterval(int interval) override;
|
|
||||||
|
|
||||||
void Resize() override {}
|
void Resize() override {}
|
||||||
|
|
||||||
Draw::DrawContext *GetDrawContext() override {
|
Draw::DrawContext *GetDrawContext() override {
|
||||||
|
@ -30,8 +30,6 @@ public:
|
|||||||
|
|
||||||
void Poll() override;
|
void Poll() override;
|
||||||
|
|
||||||
void SwapInterval(int interval) override {
|
|
||||||
}
|
|
||||||
void *GetAPIContext() override {
|
void *GetAPIContext() override {
|
||||||
return vulkan_;
|
return vulkan_;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "Common/System/System.h"
|
#include "Common/System/System.h"
|
||||||
#include "UI/DebugOverlay.h"
|
#include "UI/DebugOverlay.h"
|
||||||
#include "Core/HW/Display.h"
|
#include "Core/HW/Display.h"
|
||||||
|
#include "Core/FrameTiming.h"
|
||||||
#include "Core/HLE/sceSas.h"
|
#include "Core/HLE/sceSas.h"
|
||||||
#include "Core/ControlMapper.h"
|
#include "Core/ControlMapper.h"
|
||||||
#include "Core/Config.h"
|
#include "Core/Config.h"
|
||||||
@ -113,7 +114,14 @@ static void DrawFrameTiming(UIContext *ctx, const Bounds &bounds) {
|
|||||||
ctx->BindFontTexture();
|
ctx->BindFontTexture();
|
||||||
ctx->Draw()->SetFontScale(0.5f, 0.5f);
|
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 data = ctx->GetDrawContext()->GetFrameTimeData(6 + i);
|
||||||
FrameTimeData prevData = ctx->GetDrawContext()->GetFrameTimeData(7 + i);
|
FrameTimeData prevData = ctx->GetDrawContext()->GetFrameTimeData(7 + i);
|
||||||
if (data.frameBegin == 0.0) {
|
if (data.frameBegin == 0.0) {
|
||||||
@ -153,7 +161,7 @@ static void DrawFrameTiming(UIContext *ctx, const Bounds &bounds) {
|
|||||||
presentStats
|
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->Draw()->SetFontScale(1.0f, 1.0f);
|
||||||
ctx->Flush();
|
ctx->Flush();
|
||||||
|
@ -605,10 +605,17 @@ void SystemInfoScreen::CreateTabs() {
|
|||||||
g_display.dpi)));
|
g_display.dpi)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !PPSSPP_PLATFORM(WINDOWS)
|
|
||||||
// Don't show on Windows, since it's always treated as 60 there.
|
// 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))));
|
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")));
|
CollapsibleSection *versionInfo = deviceSpecs->Add(new CollapsibleSection(si->T("Version Information")));
|
||||||
std::string apiVersion;
|
std::string apiVersion;
|
||||||
|
@ -335,13 +335,14 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings)
|
|||||||
}
|
}
|
||||||
#endif
|
#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")));
|
CheckBox *vSync = graphicsSettings->Add(new CheckBox(&g_Config.bVSync, gr->T("VSync")));
|
||||||
vSync->OnClick.Add([=](EventParams &e) {
|
vSync->OnClick.Add([=](EventParams &e) {
|
||||||
NativeResized();
|
NativeResized();
|
||||||
return UI::EVENT_CONTINUE;
|
return UI::EVENT_CONTINUE;
|
||||||
});
|
});
|
||||||
#endif
|
}
|
||||||
|
|
||||||
#if PPSSPP_PLATFORM(ANDROID)
|
#if PPSSPP_PLATFORM(ANDROID)
|
||||||
// Hide Immersive Mode on pre-kitkat 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) {
|
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;
|
Matrix4x4 ortho;
|
||||||
switch (GetGPUBackend()) {
|
switch (GetGPUBackend()) {
|
||||||
case GPUBackend::VULKAN:
|
case GPUBackend::VULKAN:
|
||||||
@ -1132,6 +1133,8 @@ void NativeFrame(GraphicsContext *graphicsContext) {
|
|||||||
if (g_Config.bGpuLogProfiler)
|
if (g_Config.bGpuLogProfiler)
|
||||||
debugFlags |= Draw::DebugFlags::PROFILE_SCOPES;
|
debugFlags |= Draw::DebugFlags::PROFILE_SCOPES;
|
||||||
|
|
||||||
|
g_frameTiming.Reset(g_draw);
|
||||||
|
|
||||||
g_draw->BeginFrame(debugFlags);
|
g_draw->BeginFrame(debugFlags);
|
||||||
|
|
||||||
ui_draw2d.PushDrawMatrix(ortho);
|
ui_draw2d.PushDrawMatrix(ortho);
|
||||||
@ -1158,7 +1161,9 @@ void NativeFrame(GraphicsContext *graphicsContext) {
|
|||||||
ClearFailedGPUBackends();
|
ClearFailedGPUBackends();
|
||||||
}
|
}
|
||||||
|
|
||||||
g_draw->Present(1);
|
int interval;
|
||||||
|
Draw::PresentMode presentMode = ComputePresentMode(g_draw, &interval);
|
||||||
|
g_draw->Present(presentMode, interval);
|
||||||
|
|
||||||
if (resized) {
|
if (resized) {
|
||||||
INFO_LOG(G3D, "Resized flag set - recalculating bounds");
|
INFO_LOG(G3D, "Resized flag set - recalculating bounds");
|
||||||
|
@ -19,7 +19,6 @@ public:
|
|||||||
UWPGraphicsContext(std::shared_ptr<DX::DeviceResources> resources);
|
UWPGraphicsContext(std::shared_ptr<DX::DeviceResources> resources);
|
||||||
|
|
||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
void SwapInterval(int interval) override {}
|
|
||||||
void Resize() override {}
|
void Resize() override {}
|
||||||
Draw::DrawContext * GetDrawContext() override {
|
Draw::DrawContext * GetDrawContext() override {
|
||||||
return draw_;
|
return draw_;
|
||||||
|
@ -33,10 +33,6 @@
|
|||||||
#error This file should not be compiled for UWP.
|
#error This file should not be compiled for UWP.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void D3D11Context::SwapInterval(int interval) {
|
|
||||||
swapInterval_ = interval;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT D3D11Context::CreateTheDevice(IDXGIAdapter *adapter) {
|
HRESULT D3D11Context::CreateTheDevice(IDXGIAdapter *adapter) {
|
||||||
bool windowed = true;
|
bool windowed = true;
|
||||||
// D3D11 has no need for display rotation.
|
// D3D11 has no need for display rotation.
|
||||||
|
@ -30,7 +30,6 @@ class D3D11Context : public WindowsGraphicsContext {
|
|||||||
public:
|
public:
|
||||||
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
|
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
|
||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
void SwapInterval(int interval) override;
|
|
||||||
|
|
||||||
void Resize() override;
|
void Resize() override;
|
||||||
|
|
||||||
|
@ -23,10 +23,6 @@
|
|||||||
|
|
||||||
typedef HRESULT (__stdcall *DIRECT3DCREATE9EX)(UINT, IDirect3D9Ex**);
|
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 D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
||||||
bool windowed = true;
|
bool windowed = true;
|
||||||
hWnd_ = wnd;
|
hWnd_ = wnd;
|
||||||
|
@ -34,7 +34,6 @@ public:
|
|||||||
|
|
||||||
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
|
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
|
||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
void SwapInterval(int interval) override;
|
|
||||||
|
|
||||||
void Resize() override;
|
void Resize() override;
|
||||||
|
|
||||||
|
@ -412,7 +412,7 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) {
|
|||||||
resumeRequested = false;
|
resumeRequested = false;
|
||||||
|
|
||||||
CheckGLExtensions();
|
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.
|
bool success = draw_->CreatePresets(); // if we get this far, there will always be a GLSL compiler capable of compiling these.
|
||||||
if (!success) {
|
if (!success) {
|
||||||
delete draw_;
|
delete draw_;
|
||||||
@ -443,11 +443,6 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) {
|
|||||||
return true; // Success
|
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() {
|
void WindowsGLContext::Shutdown() {
|
||||||
glslang::FinalizeProcess();
|
glslang::FinalizeProcess();
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ public:
|
|||||||
void ShutdownFromRenderThread() override;
|
void ShutdownFromRenderThread() override;
|
||||||
|
|
||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
void SwapInterval(int interval) override;
|
|
||||||
|
|
||||||
void Poll() override;
|
void Poll() override;
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@ public:
|
|||||||
WindowsVulkanContext() : draw_(nullptr) {}
|
WindowsVulkanContext() : draw_(nullptr) {}
|
||||||
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
|
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
|
||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
void SwapInterval(int interval) override {}
|
|
||||||
void Resize() override;
|
void Resize() override;
|
||||||
void Poll() override;
|
void Poll() override;
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ bool AndroidJavaEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int
|
|||||||
g_display.rotation = DisplayRotation::ROTATE_0;
|
g_display.rotation = DisplayRotation::ROTATE_0;
|
||||||
g_display.rot_matrix.setIdentity();
|
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_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ public:
|
|||||||
void ShutdownFromRenderThread() override;
|
void ShutdownFromRenderThread() override;
|
||||||
|
|
||||||
void Shutdown() override {}
|
void Shutdown() override {}
|
||||||
void SwapInterval(int interval) override {}
|
|
||||||
void Resize() override {}
|
void Resize() override {}
|
||||||
|
|
||||||
Draw::DrawContext *GetDrawContext() override {
|
Draw::DrawContext *GetDrawContext() override {
|
||||||
|
@ -175,6 +175,3 @@ void AndroidVulkanContext::Resize() {
|
|||||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
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());
|
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 ShutdownFromRenderThread() override; // Inverses InitFromRenderThread.
|
||||||
|
|
||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
void SwapInterval(int interval) override;
|
|
||||||
void Resize() override;
|
void Resize() override;
|
||||||
|
|
||||||
void *GetAPIContext() override { return g_Vulkan; }
|
void *GetAPIContext() override { return g_Vulkan; }
|
||||||
|
@ -95,7 +95,6 @@ public:
|
|||||||
|
|
||||||
void Shutdown() override {}
|
void Shutdown() override {}
|
||||||
void Resize() override {}
|
void Resize() override {}
|
||||||
void SwapInterval(int interval) override {}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Draw::DrawContext *draw_ = nullptr;
|
Draw::DrawContext *draw_ = nullptr;
|
||||||
@ -157,7 +156,7 @@ bool GLDummyGraphicsContext::InitFromRenderThread(std::string *errorMessage) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
CheckGLExtensions();
|
CheckGLExtensions();
|
||||||
draw_ = Draw::T3DCreateGLContext();
|
draw_ = Draw::T3DCreateGLContext(false);
|
||||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||||
SetGPUBackend(GPUBackend::OPENGL);
|
SetGPUBackend(GPUBackend::OPENGL);
|
||||||
@ -166,6 +165,7 @@ bool GLDummyGraphicsContext::InitFromRenderThread(std::string *errorMessage) {
|
|||||||
renderManager_->SetSwapFunction([&]() {
|
renderManager_->SetSwapFunction([&]() {
|
||||||
SDL_GL_SwapWindow(screen_);
|
SDL_GL_SwapWindow(screen_);
|
||||||
});
|
});
|
||||||
|
// TODO: Support SwapInterval
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ class IOSGraphicsContext : public GraphicsContext {
|
|||||||
public:
|
public:
|
||||||
IOSGraphicsContext() {
|
IOSGraphicsContext() {
|
||||||
CheckGLExtensions();
|
CheckGLExtensions();
|
||||||
draw_ = Draw::T3DCreateGLContext();
|
draw_ = Draw::T3DCreateGLContext(false);
|
||||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||||
SetGPUBackend(GPUBackend::OPENGL);
|
SetGPUBackend(GPUBackend::OPENGL);
|
||||||
@ -63,7 +63,6 @@ public:
|
|||||||
return draw_;
|
return draw_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapInterval(int interval) override {}
|
|
||||||
void Resize() override {}
|
void Resize() override {}
|
||||||
void Shutdown() override {}
|
void Shutdown() override {}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ void LibretroGLContext::CreateDrawContext() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
CheckGLExtensions();
|
CheckGLExtensions();
|
||||||
draw_ = Draw::T3DCreateGLContext();
|
draw_ = Draw::T3DCreateGLContext(false);
|
||||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||||
SetGPUBackend(GPUBackend::OPENGL);
|
SetGPUBackend(GPUBackend::OPENGL);
|
||||||
|
@ -26,7 +26,7 @@ void LibretroGLCoreContext::CreateDrawContext() {
|
|||||||
glewInitDone = true;
|
glewInitDone = true;
|
||||||
CheckGLExtensions();
|
CheckGLExtensions();
|
||||||
}
|
}
|
||||||
draw_ = Draw::T3DCreateGLContext();
|
draw_ = Draw::T3DCreateGLContext(false);
|
||||||
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||||
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
||||||
SetGPUBackend(GPUBackend::OPENGL);
|
SetGPUBackend(GPUBackend::OPENGL);
|
||||||
|
@ -21,7 +21,6 @@ public:
|
|||||||
void Shutdown() override {
|
void Shutdown() override {
|
||||||
DestroyDrawContext();
|
DestroyDrawContext();
|
||||||
}
|
}
|
||||||
void SwapInterval(int interval) override {}
|
|
||||||
virtual void SwapBuffers() = 0;
|
virtual void SwapBuffers() = 0;
|
||||||
void Resize() override {}
|
void Resize() override {}
|
||||||
|
|
||||||
|
@ -1178,7 +1178,7 @@ namespace Libretro
|
|||||||
|
|
||||||
if (ctx->GetDrawContext()) {
|
if (ctx->GetDrawContext()) {
|
||||||
ctx->GetDrawContext()->EndFrame();
|
ctx->GetDrawContext()->EndFrame();
|
||||||
ctx->GetDrawContext()->Present(1);
|
ctx->GetDrawContext()->Present(Draw::PresentMode::FIFO, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user