From 9a35684507b5f467bf140a6040d0acf901655121 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 6 Feb 2023 20:13:13 +0300 Subject: [PATCH] rsx: Don't accept garbage shader input --- .../RSX/Program/FragmentProgramDecompiler.cpp | 33 +++++++++++++++---- .../RSX/Program/FragmentProgramDecompiler.h | 9 +++-- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp index 6a9d0c8f9d..12275494db 100644 --- a/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp @@ -270,11 +270,6 @@ std::string FragmentProgramDecompiler::AddTex() return m_parr.AddParam(PF_PARAM_UNIFORM, sampler, std::string("tex") + std::to_string(dst.tex_num)); } -std::string FragmentProgramDecompiler::AddType3() -{ - return m_parr.AddParam(PF_PARAM_NONE, getFloatTypeName(4), "src3", getFloatTypeName(4) + "(1.)"); -} - std::string FragmentProgramDecompiler::AddX2d() { return m_parr.AddParam(PF_PARAM_NONE, getFloatTypeName(4), "x2d", getFloatTypeName(4) + "(0.)"); @@ -562,6 +557,12 @@ template std::string FragmentProgramDecompiler::GetSRC(T src) const std::string reg_var = (register_id < std::size(reg_table))? reg_table[register_id] : "unk"; bool insert = true; + if (reg_var == "unk") + { + m_is_valid_ucode = false; + insert = false; + } + if (src2.use_index_reg && m_loop_count) { // Dynamically load the input @@ -704,7 +705,10 @@ template std::string FragmentProgramDecompiler::GetSRC(T src) rsx_log.error("Src type 3 used, opcode=0x%X, dst=0x%X s0=0x%X s1=0x%X s2=0x%X", dst.opcode, dst.HEX, src0.HEX, src1.HEX, src2.HEX); - ret += AddType3(); + // This is not some special type, it is a bug indicating memory corruption + // Shaders that are even slightly off do not execute on realhw to any meaningful degree + m_is_valid_ucode = false; + ret += "src3"; precision_modifier = RSX_FP_PRECISION_REAL; break; @@ -801,6 +805,22 @@ std::string FragmentProgramDecompiler::BuildCode() } std::stringstream OS; + + if (!m_is_valid_ucode) + { + // If the code is broken, do not compile. Simply NOP main and write empty outputs + insertHeader(OS); + OS << "\n"; + OS << "void main()\n"; + OS << "{\n"; + OS << "#if 0\n"; + OS << main << "\n"; + OS << "#endif\n"; + OS << " discard;\n"; + OS << "}\n"; + return OS.str(); + } + insertHeader(OS); OS << "\n"; insertConstants(OS); @@ -1206,6 +1226,7 @@ std::string FragmentProgramDecompiler::Decompile() m_location = 0; m_loop_count = 0; m_code_level = 1; + m_is_valid_ucode = true; enum { diff --git a/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.h b/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.h index c0be1a5fca..c275eb2623 100644 --- a/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.h +++ b/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.h @@ -155,6 +155,8 @@ class FragmentProgramDecompiler std::vector m_end_offsets; std::vector m_else_offsets; + bool m_is_valid_ucode = true; + std::array temp_registers; std::string GetMask() const; @@ -169,13 +171,10 @@ class FragmentProgramDecompiler void AddFlowOp(const std::string& code); std::string Format(const std::string& code, bool ignore_redirects = false); - //Technically a temporary workaround until we know what type3 is - std::string AddType3(); - - //Support the transform-2d temp result for use with TEXBEM + // Support the transform-2d temp result for use with TEXBEM std::string AddX2d(); - //Prevents operations from overflowing the desired range (tested with fp_dynamic3 autotest sample, DS2 for src1.input_prec_mod) + // Prevents operations from overflowing the desired range (tested with fp_dynamic3 autotest sample, DS2 for src1.input_prec_mod) std::string ClampValue(const std::string& code, u32 precision); /**