From 73fe9b51de22ab7cbf1795072cec294a95fce83f Mon Sep 17 00:00:00 2001 From: kd-11 Date: Tue, 2 Jun 2020 23:00:29 +0300 Subject: [PATCH] rsx/fp: Ignore self-referencing register writes. - Sometimes, usually with shaders that do pack/unpack operations, there is a write-to-self operation. For example r0.xy = r0.xy Obviously no new data was introduced into "r0" by this, so we should not mark the register as having new data. - TODO: Investigate on realhw if self-reference is needed to "cast" the overlapping half registers to their full register counterparts. --- .../RSX/Common/FragmentProgramDecompiler.cpp | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index a4e7fcc1b7..244b7ae00d 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -1,7 +1,6 @@ #include "stdafx.h" #include "Emu/System.h" #include "../rsx_methods.h" - #include "FragmentProgramDecompiler.h" #include @@ -121,9 +120,10 @@ void FragmentProgramDecompiler::SetDst(std::string code, u32 flags) return; } - std::string dest = AddReg(dst.dest_reg, !!dst.fp16) + "$m"; + const std::string dest = AddReg(dst.dest_reg, !!dst.fp16) + "$m"; + const std::string decoded_dest = Format(dest); - AddCodeCond(Format(dest), code); + AddCodeCond(decoded_dest, code); //AddCode("$ifcond " + dest + code + (append_mask ? "$m;" : ";")); if (dst.set_cond) @@ -134,6 +134,20 @@ void FragmentProgramDecompiler::SetDst(std::string code, u32 flags) u32 reg_index = dst.fp16 ? dst.dest_reg >> 1 : dst.dest_reg; verify(HERE), reg_index < temp_registers.size(); + + if (dst.opcode == RSX_FP_OPCODE_MOV && + src0.reg_type == RSX_FP_REGISTER_TYPE_TEMP && + src0.tmp_reg_index == reg_index) + { + // The register did not acquire any new data + // Common in code with structures like r0.xy = r0.xy + // Unsure why such code would exist, maybe placeholders for dynamically generated shader code? + if (decoded_dest == Format(code)) + { + return; + } + } + temp_registers[reg_index].tag(dst.dest_reg, !!dst.fp16, dst.mask_x, dst.mask_y, dst.mask_z, dst.mask_w); }