diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index 7f0ec47269..6be33200bf 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -41,5 +41,6 @@ void Compatibility::Clear() { void Compatibility::LoadIniSection(IniFile &iniFile, std::string section) { iniFile.Get(section.c_str(), "NoDepthRounding", &flags_.NoDepthRounding, flags_.NoDepthRounding); + iniFile.Get(section.c_str(), "PixelDepthRounding", &flags_.PixelDepthRounding, flags_.PixelDepthRounding); iniFile.Get(section.c_str(), "GTAMusicFix", &flags_.GTAMusicFix, flags_.GTAMusicFix); } diff --git a/Core/Compatibility.h b/Core/Compatibility.h index 5f03cd4bed..a5a3a7fa07 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -46,6 +46,7 @@ struct CompatFlags { bool NoDepthRounding; + bool PixelDepthRounding; bool GTAMusicFix; }; diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index 20a09bd314..8e4794aeb7 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -1045,6 +1045,13 @@ bool GenerateFragmentShader(const ShaderID &id, char *buffer) { WRITE(p, " %s = vec4(1,0,1,1);\n", fragColor0); } #endif + + if (gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT)) { + WRITE(p, " highp float z = gl_FragCoord.z;\n"); + WRITE(p, " z = (1.0/65535.0) * floor(z * 65535.0);\n"); + WRITE(p, " gl_FragDepth = z;\n"); + } + WRITE(p, "}\n"); return true; diff --git a/GPU/GLES/GLES_GPU.cpp b/GPU/GLES/GLES_GPU.cpp index f5a2d7e7a1..c7a8b8d188 100644 --- a/GPU/GLES/GLES_GPU.cpp +++ b/GPU/GLES/GLES_GPU.cpp @@ -562,9 +562,13 @@ void GLES_GPU::CheckGPUFeatures() { features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; // In the future, also disable this when we get a proper 16-bit depth buffer. - if (!PSP_CoreParameter().compat.flags().NoDepthRounding) - features |= GPU_ROUND_DEPTH_TO_16BIT; - + 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().NoDepthRounding) { + features |= GPU_ROUND_DEPTH_TO_16BIT; + } + } #ifdef MOBILE_DEVICE // Arguably, we should turn off GPU_IS_MOBILE on like modern Tegras, etc. diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 4bfdb83a07..e5d68333b3 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -454,6 +454,7 @@ enum { GPU_SUPPORTS_BLEND_MINMAX = FLAG_BIT(4), GPU_SUPPORTS_LOGIC_OP = FLAG_BIT(5), GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH = FLAG_BIT(20), + 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), GPU_SUPPORTS_FBO = FLAG_BIT(25), diff --git a/assets/compat.ini b/assets/compat.ini index a041af774c..155751c110 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -66,6 +66,15 @@ NoDepthRounding = true NoDepthRounding = true +# Heroes Phantasia requires pixel depth rounding. +[NPJH50558] +PixelDepthRounding = true +[ULJS00456] +PixelDepthRounding = true +[ULJS00454] +PixelDepthRounding = true + + # GTA audio issues # These games stream their radio stations from disc as giant audio files. They seek into # the correct position. Our ATRAC3 module (sceAtrac) implementation is still not very accurate