From ca2d7e40eaab6f5278d6b70aa1f6fbae2f308aa7 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sun, 25 Aug 2024 19:34:56 +0300 Subject: [PATCH] Shader decompiler: Add support for compilation errors --- include/PICA/shader_decompiler.hpp | 1 + src/core/PICA/shader_decompiler.cpp | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/PICA/shader_decompiler.hpp b/include/PICA/shader_decompiler.hpp index b7bd869c..4a5cdc13 100644 --- a/include/PICA/shader_decompiler.hpp +++ b/include/PICA/shader_decompiler.hpp @@ -99,6 +99,7 @@ namespace PICA::ShaderGen { API api; Language language; + bool compilationError = false; void compileInstruction(u32& pc, bool& finished); // Compile range "range" and returns the end PC or if we're "finished" with the program (called an END instruction) diff --git a/src/core/PICA/shader_decompiler.cpp b/src/core/PICA/shader_decompiler.cpp index 75de4e50..2d4d2963 100644 --- a/src/core/PICA/shader_decompiler.cpp +++ b/src/core/PICA/shader_decompiler.cpp @@ -247,6 +247,7 @@ std::string ShaderDecompiler::decompile() { return ""; } + compilationError = false; decompiledShader = ""; switch (api) { @@ -324,6 +325,13 @@ std::string ShaderDecompiler::decompile() { } } + // We allow some leeway for "compilation errors" in addition to control flow errors, in cases where eg an unimplemented instruction + // or an instruction that we can't emulate in GLSL is found in the instruction stream. Just like control flow errors, these return an empty string + // and the renderer core will decide to use CPU shaders instead + if (compilationError) [[unlikely]] { + return ""; + } + return decompiledShader; } @@ -707,7 +715,11 @@ void ShaderDecompiler::compileInstruction(u32& pc, bool& finished) { return; case ShaderOpcodes::NOP: break; - default: Helpers::panic("GLSL recompiler: Unknown opcode: %X", opcode); break; + + default: + Helpers::warn("GLSL recompiler: Unknown opcode: %X. Falling back to CPU shaders", opcode); + compilationError = true; + break; } }