From 6ce4933db82685e30ed56d728e6798c41174d5e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 2 Feb 2024 10:35:10 +0100 Subject: [PATCH] Split the discard-stencil-bug flag into separate flags for Adreno and Mali --- Common/GPU/Vulkan/thin3d_vulkan.cpp | 7 +++++-- Common/GPU/thin3d.cpp | 3 ++- Common/GPU/thin3d.h | 3 ++- Core/Util/GameManager.cpp | 4 ++-- GPU/Common/FragmentShaderGenerator.cpp | 2 +- GPU/Common/ShaderId.cpp | 11 +++++++---- GPU/Common/StencilCommon.cpp | 4 ++-- 7 files changed, 21 insertions(+), 13 deletions(-) diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index f853ecf5d1..fb2f4c2f3f 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -973,7 +973,7 @@ VKContext::VKContext(VulkanContext *vulkan, bool useRenderThread) // See: https://github.com/hrydgard/ppsspp/pull/11684 if (deviceProps.deviceID >= 0x05000000 && deviceProps.deviceID < 0x06000000) { if (deviceProps.driverVersion < 0x80180000) { - bugs_.Infest(Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL); + bugs_.Infest(Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL_ADRENO); } } // Color write mask not masking write in certain scenarios with a depth test, see #10421. @@ -1006,8 +1006,9 @@ VKContext::VKContext(VulkanContext *vulkan, bool useRenderThread) bugs_.Infest(Bugs::EQUAL_WZ_CORRUPTS_DEPTH); // Nearly identical to the the Adreno bug, see #13833 (Midnight Club map broken) and other issues. + // It has the additional caveat that combining depth writes with NEVER depth tests crashes the driver. // Reported fixed in major version 40 - let's add a check once confirmed. - bugs_.Infest(Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL); + bugs_.Infest(Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL_MALI); // This started in driver 31 or 32, fixed in 40 - let's add a check once confirmed. if (majorVersion >= 32) { @@ -1042,6 +1043,8 @@ VKContext::VKContext(VulkanContext *vulkan, bool useRenderThread) INFO_LOG(G3D, "KHR_depth_stencil_resolve not supported, disabling multisampling"); } + bugs_.Infest(Draw::Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL_MALI); + // We limit multisampling functionality to reasonably recent and known-good tiling GPUs. if (multisampleAllowed) { // Check for depth stencil resolve. Without it, depth textures won't work, and we don't want that mess diff --git a/Common/GPU/thin3d.cpp b/Common/GPU/thin3d.cpp index c5170bbe35..d98f53667a 100644 --- a/Common/GPU/thin3d.cpp +++ b/Common/GPU/thin3d.cpp @@ -751,7 +751,8 @@ void ConvertToD16(uint8_t *dst, const uint8_t *src, uint32_t dstStride, uint32_t const char *Bugs::GetBugName(uint32_t bug) { switch (bug) { - case NO_DEPTH_CANNOT_DISCARD_STENCIL: return "NO_DEPTH_CANNOT_DISCARD_STENCIL"; + case NO_DEPTH_CANNOT_DISCARD_STENCIL_MALI: return "NO_DEPTH_CANNOT_DISCARD_STENCIL_MALI"; + case NO_DEPTH_CANNOT_DISCARD_STENCIL_ADRENO: return "NO_DEPTH_CANNOT_DISCARD_STENCIL_ADRENO"; case DUAL_SOURCE_BLENDING_BROKEN: return "DUAL_SOURCE_BLENDING_BROKEN"; case ANY_MAP_BUFFER_RANGE_SLOW: return "ANY_MAP_BUFFER_RANGE_SLOW"; case PVR_GENMIPMAP_HEIGHT_GREATER: return "PVR_GENMIPMAP_HEIGHT_GREATER"; diff --git a/Common/GPU/thin3d.h b/Common/GPU/thin3d.h index 44e01fdef1..41a648c249 100644 --- a/Common/GPU/thin3d.h +++ b/Common/GPU/thin3d.h @@ -336,7 +336,7 @@ public: const char *GetBugName(uint32_t bug); enum : uint32_t { - NO_DEPTH_CANNOT_DISCARD_STENCIL = 0, + NO_DEPTH_CANNOT_DISCARD_STENCIL_ADRENO = 0, DUAL_SOURCE_BLENDING_BROKEN = 1, ANY_MAP_BUFFER_RANGE_SLOW = 2, PVR_GENMIPMAP_HEIGHT_GREATER = 3, @@ -351,6 +351,7 @@ public: ADRENO_RESOURCE_DEADLOCK = 12, UNIFORM_INDEXING_BROKEN = 13, // not a properly diagnosed issue, a workaround attempt: #17386 PVR_BAD_16BIT_TEXFORMATS = 14, + NO_DEPTH_CANNOT_DISCARD_STENCIL_MALI = 15, MAX_BUG, }; diff --git a/Core/Util/GameManager.cpp b/Core/Util/GameManager.cpp index 6693c4cdb0..844983e21a 100644 --- a/Core/Util/GameManager.cpp +++ b/Core/Util/GameManager.cpp @@ -625,7 +625,7 @@ bool GameManager::InstallMemstickGame(struct zip *z, const Path &zipfile, const g_OSD.SetProgressBar("install", di->T("Installing..."), 0.0f, 1.0f, 0.1f + (i + 1) / (float)info.numFiles * 0.9f, 0.1f); } - INFO_LOG(HLE, "Extracted %d files from zip (%d bytes / %d).", info.numFiles, (int)bytesCopied, (int)allBytes); + INFO_LOG(HLE, "Unzipped %d files (%d bytes / %d).", info.numFiles, (int)bytesCopied, (int)allBytes); zip_close(z); z = nullptr; installProgress_ = 1.0f; @@ -733,7 +733,7 @@ bool GameManager::InstallZippedISO(struct zip *z, int isoFileIndex, const Path & auto di = GetI18NCategory(I18NCat::DIALOG); g_OSD.SetProgressBar("install", di->T("Installing..."), 0.0f, 0.0f, 0.0f, 0.1f); if (ExtractFile(z, isoFileIndex, outputISOFilename, &bytesCopied, allBytes)) { - INFO_LOG(IO, "Successfully extracted ISO file to '%s'", outputISOFilename.c_str()); + INFO_LOG(IO, "Successfully unzipped ISO file to '%s'", outputISOFilename.c_str()); success = true; } zip_close(z); diff --git a/GPU/Common/FragmentShaderGenerator.cpp b/GPU/Common/FragmentShaderGenerator.cpp index 1bbdd19ace..decdd26d5c 100644 --- a/GPU/Common/FragmentShaderGenerator.cpp +++ b/GPU/Common/FragmentShaderGenerator.cpp @@ -192,7 +192,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu std::vector samplers; if (compat.shaderLanguage == ShaderLanguage::GLSL_VULKAN) { - if (useDiscardStencilBugWorkaround && !gstate_c.Use(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT)) { + if (useDiscardStencilBugWorkaround && !writeDepth) { WRITE(p, "layout (depth_unchanged) out float gl_FragDepth;\n"); } diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index 570b5407e6..492b2d8e48 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -387,10 +387,13 @@ void ComputeFragmentShaderID(FShaderID *id_out, const ComputedPipelineState &pip id.SetBit(FS_BIT_STEREO); } - if (g_Config.bVendorBugChecksEnabled && bugs.Has(Draw::Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL)) { - bool stencilWithoutDepth = !IsStencilTestOutputDisabled() && (!gstate.isDepthTestEnabled() || !gstate.isDepthWriteEnabled()); - if (stencilWithoutDepth) { - id.SetBit(FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL, stencilWithoutDepth); + if (g_Config.bVendorBugChecksEnabled) { + if (bugs.Has(Draw::Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL_ADRENO) || bugs.Has(Draw::Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL_MALI)) { + // On Adreno, the workaround is safe, so we do simple checks. + bool stencilWithoutDepth = (!gstate.isDepthTestEnabled() || !gstate.isDepthWriteEnabled()) && !IsStencilTestOutputDisabled(); + if (stencilWithoutDepth) { + id.SetBit(FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL, stencilWithoutDepth); + } } } diff --git a/GPU/Common/StencilCommon.cpp b/GPU/Common/StencilCommon.cpp index 98d73836d2..71f6c4e599 100644 --- a/GPU/Common/StencilCommon.cpp +++ b/GPU/Common/StencilCommon.cpp @@ -119,7 +119,7 @@ void GenerateStencilFs(char *buffer, const ShaderLanguageDesc &lang, const Draw: writer.HighPrecisionFloat(); writer.DeclareSamplers(samplers); - if (bugs.Has(Draw::Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL)) { + if (bugs.Has(Draw::Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL_MALI) || bugs.Has(Draw::Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL_ADRENO)) { writer.C("layout (depth_unchanged) out float gl_FragDepth;\n"); } @@ -137,7 +137,7 @@ void GenerateStencilFs(char *buffer, const ShaderLanguageDesc &lang, const Draw: writer.C(" if (mod(floor(shifted), 2.0) < 0.99) DISCARD;\n"); } - if (bugs.Has(Draw::Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL)) { + if (bugs.Has(Draw::Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL_MALI) || bugs.Has(Draw::Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL_ADRENO)) { writer.C(" gl_FragDepth = gl_FragCoord.z;\n"); }