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.
This commit is contained in:
kd-11 2020-06-02 23:00:29 +03:00 committed by kd-11
parent 26b2e4253d
commit 73fe9b51de

View File

@ -1,7 +1,6 @@
#include "stdafx.h"
#include "Emu/System.h"
#include "../rsx_methods.h"
#include "FragmentProgramDecompiler.h"
#include <algorithm>
@ -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);
}