From 79750ed1ad5c225b4b3764092e81dde87a096b77 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 20 Jan 2016 22:00:07 -0800 Subject: [PATCH] Add a config setting to control depth quality. For those who want 1x PSP like behavior. --- Core/Config.cpp | 1 + Core/Config.h | 1 + GPU/Common/GPUStateUtils.cpp | 18 ++++++++++++------ GPU/Directx9/GPU_DX9.cpp | 4 +++- GPU/GLES/GLES_GPU.cpp | 14 ++++++++------ GPU/GPUState.h | 1 + 6 files changed, 26 insertions(+), 13 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index a438ebcce5..d182a1ab32 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -442,6 +442,7 @@ static ConfigSetting graphicsSettings[] = { ReportedConfigSetting("BufferFiltering", &g_Config.iBufFilter, 1, true, true), ReportedConfigSetting("InternalResolution", &g_Config.iInternalResolution, &DefaultInternalResolution, true, true), ReportedConfigSetting("AndroidHwScale", &g_Config.iAndroidHwScale, &DefaultAndroidHwScale), + ReportedConfigSetting("HighQualityDepth", &g_Config.bHighQualityDepth, true, true, true), ReportedConfigSetting("FrameSkip", &g_Config.iFrameSkip, 0, true, true), ReportedConfigSetting("AutoFrameSkip", &g_Config.bAutoFrameSkip, false, true, true), ReportedConfigSetting("FrameRate", &g_Config.iFpsLimit, 0, true, true), diff --git a/Core/Config.h b/Core/Config.h index ac5b990554..3333dd3602 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -173,6 +173,7 @@ public: bool bFullScreen; int iInternalResolution; // 0 = Auto (native), 1 = 1x (480x272), 2 = 2x, 3 = 3x, 4 = 4x and so on. int iAnisotropyLevel; // 0 - 5, powers of 2: 0 = 1x = no aniso + int bHighQualityDepth; bool bTrueColor; bool bMipMap; int iTexScalingLevel; // 1 = off, 2 = 2x, ..., 5 = 5x diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 29676f5fd8..8a6065c6f3 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -498,10 +498,19 @@ LogicOpReplaceType ReplaceLogicOpType() { return LOGICOPTYPE_NORMAL; } -static const float depthSliceFactor = 4.0f; +static const float DEPTH_SLICE_FACTOR_HIGH = 4.0f; +static const float DEPTH_SLICE_FACTOR_16BIT = 256.0f; + +float DepthSliceFactor() { + if (gstate_c.Supports(GPU_SCALE_DEPTH_FROM_24BIT_TO_16BIT)) { + return DEPTH_SLICE_FACTOR_16BIT; + } + return DEPTH_SLICE_FACTOR_HIGH; +} // This is used for float values which might not be integers, but are in the integer scale of 65535. static float ToScaledDepthFromInteger(float z) { + const float depthSliceFactor = DepthSliceFactor(); const float offset = 0.5f * (depthSliceFactor - 1.0f) * (1.0f / depthSliceFactor); return z * (1.0f / depthSliceFactor) * (1.0f / 65535.0f) + offset; } @@ -511,14 +520,11 @@ float ToScaledDepth(u16 z) { } float FromScaledDepth(float z) { + const float depthSliceFactor = DepthSliceFactor(); const float offset = 0.5f * (depthSliceFactor - 1.0f) * (1.0f / depthSliceFactor); return (z - offset) * depthSliceFactor * 65535.0f; } -float DepthSliceFactor() { - return depthSliceFactor; -} - void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, float renderHeight, int bufferWidth, int bufferHeight, ViewportAndScissor &out) { bool throughmode = gstate.isModeThrough(); out.dirtyProj = false; @@ -662,7 +668,7 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo // Here, we should "clamp." But clamping per fragment would be slow. // So, instead, we just increase the available range and hope. // If depthSliceFactor is 4, it means (75% / 2) of the depth lies in each direction. - float fullDepthRange = 65535.0f * (depthSliceFactor - 1.0f) * (1.0f / 2.0f); + float fullDepthRange = 65535.0f * (DepthSliceFactor() - 1.0f) * (1.0f / 2.0f); if (minz == 0) { minz -= fullDepthRange; } diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index ab62acfc3e..73ea41c7dd 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -478,7 +478,9 @@ void DIRECTX9_GPU::CheckGPUFeatures() { features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; features |= GPU_PREFER_CPU_DOWNLOAD; - if (PSP_CoreParameter().compat.flags().VertexDepthRounding) { + if (!g_Config.bHighQualityDepth) { + features |= GPU_SCALE_DEPTH_FROM_24BIT_TO_16BIT; + } else if (PSP_CoreParameter().compat.flags().VertexDepthRounding) { features |= GPU_ROUND_DEPTH_TO_16BIT; } diff --git a/GPU/GLES/GLES_GPU.cpp b/GPU/GLES/GLES_GPU.cpp index aa22c23549..3c7bf702a6 100644 --- a/GPU/GLES/GLES_GPU.cpp +++ b/GPU/GLES/GLES_GPU.cpp @@ -565,13 +565,15 @@ void GLES_GPU::CheckGPUFeatures() { if (gl_extensions.GLES3 || !gl_extensions.IsGLES) features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; - // In the future, also disable this when we get a proper 16-bit depth buffer. - if ((!gl_extensions.IsGLES || gl_extensions.GLES3) && PSP_CoreParameter().compat.flags().PixelDepthRounding) { - features |= GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT; - } else { - if (PSP_CoreParameter().compat.flags().VertexDepthRounding) { - features |= GPU_ROUND_DEPTH_TO_16BIT; + if (!g_Config.bHighQualityDepth) { + features |= GPU_SCALE_DEPTH_FROM_24BIT_TO_16BIT; + } else if (PSP_CoreParameter().compat.flags().PixelDepthRounding) { + if (!gl_extensions.IsGLES || gl_extensions.GLES3) { + // Use fragment rounding on desktop and GLES3, most accurate. + features |= GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT; } + } else if (PSP_CoreParameter().compat.flags().VertexDepthRounding) { + features |= GPU_ROUND_DEPTH_TO_16BIT; } #ifdef MOBILE_DEVICE diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 814ae686d9..b3467c39b2 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -458,6 +458,7 @@ enum { GPU_SUPPORTS_VAO = FLAG_BIT(18), GPU_SUPPORTS_ANY_COPY_IMAGE = FLAG_BIT(19), GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH = FLAG_BIT(20), + GPU_SCALE_DEPTH_FROM_24BIT_TO_16BIT = FLAG_BIT(21), GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT = FLAG_BIT(22), GPU_ROUND_DEPTH_TO_16BIT = FLAG_BIT(23), // Can be disabled either per game or if we use a real 16-bit depth buffer GPU_SUPPORTS_TEXTURE_LOD_CONTROL = FLAG_BIT(24),