Skip to content

Commit

Permalink
Get rid of a lot of ifdefs around presentation mode. Instead, set thi…
Browse files Browse the repository at this point in the history
…ngs dynamically.
  • Loading branch information
hrydgard committed Aug 14, 2023
1 parent 870c45e commit ff6e118
Show file tree
Hide file tree
Showing 44 changed files with 219 additions and 138 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Expand Up @@ -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
Expand Down
18 changes: 11 additions & 7 deletions Common/GPU/D3D11/thin3d_d3d11.cpp
Expand Up @@ -75,10 +75,6 @@ class D3D11DrawContext : public DrawContext {
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;
Expand Down Expand Up @@ -139,7 +135,7 @@ class D3D11DrawContext : public DrawContext {

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_; }

Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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_++;
Expand Down
11 changes: 5 additions & 6 deletions Common/GPU/D3D9/thin3d_d3d9.cpp
Expand Up @@ -518,10 +518,6 @@ class D3D9Context : public DrawContext {
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;
Expand Down Expand Up @@ -580,7 +576,7 @@ class D3D9Context : public DrawContext {
}

void EndFrame() override;
void Present(int vblanks) override;
void Present(PresentMode presentMode, int vblanks) override;

int GetFrameCount() override { return frameCount_; }

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
27 changes: 16 additions & 11 deletions Common/GPU/OpenGL/thin3d_gl.cpp
Expand Up @@ -322,7 +322,7 @@ class OpenGLTexture;

class OpenGLContext : public DrawContext {
public:
OpenGLContext();
OpenGLContext(bool canChangeSwapInterval);
~OpenGLContext();

void SetTargetSize(int w, int h) override {
Expand All @@ -347,11 +347,6 @@ class OpenGLContext : public DrawContext {
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;
Expand All @@ -366,7 +361,7 @@ class OpenGLContext : public DrawContext {

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_;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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_);
}

Expand All @@ -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_++;
}
Expand Down Expand Up @@ -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() {
Expand Down
23 changes: 19 additions & 4 deletions Common/GPU/Vulkan/thin3d_vulkan.cpp
Expand Up @@ -404,7 +404,7 @@ class VKContext : public DrawContext {
}
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...)
Expand Down Expand Up @@ -480,7 +480,7 @@ class VKContext : public DrawContext {

void BeginFrame(DebugFlags debugFlags) override;
void EndFrame() override;
void Present(int vblanks) override;
void Present(PresentMode presentMode, int vblanks) override;

void WipeQueue() override;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1120,8 +1133,10 @@ void VKContext::EndFrame() {
Invalidate(InvalidationFlags::CACHED_RENDER_STATE);
}

void VKContext::Present(int vblanks) {
_dbg_assert_(vblanks == 0 || vblanks == 1);
void VKContext::Present(PresentMode presentMode, int vblanks) {
if (presentMode == PresentMode::FIFO) {
_dbg_assert_(vblanks == 0 || vblanks == 1);
}
renderManager_.Present();
frameCount_++;
}
Expand Down
11 changes: 11 additions & 0 deletions Common/GPU/thin3d.cpp
Expand Up @@ -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
28 changes: 18 additions & 10 deletions Common/GPU/thin3d.h
Expand Up @@ -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!
Expand Down Expand Up @@ -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.
};
Expand Down Expand Up @@ -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();
Expand All @@ -696,8 +701,6 @@ class DrawContext {
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_;
Expand Down Expand Up @@ -815,7 +818,10 @@ class DrawContext {
// 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() {}

Expand Down Expand Up @@ -895,4 +901,6 @@ struct ShaderSource {

ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector<ShaderSource> &sources);

const char *PresentModeToString(PresentMode presentMode);

} // namespace Draw
2 changes: 1 addition & 1 deletion Common/GPU/thin3d_create.h
Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion Common/GraphicsContext.h
Expand Up @@ -14,7 +14,6 @@ class GraphicsContext {
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.
Expand Down
11 changes: 10 additions & 1 deletion Core/Config.cpp
Expand Up @@ -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.
Expand Down Expand Up @@ -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...
Expand Down

0 comments on commit ff6e118

Please sign in to comment.