rsx/fp: Implement TEXBEM (untested)

This commit is contained in:
kd-11 2017-12-11 01:34:44 +03:00
parent 6f8dd20f03
commit f7c52d3bb7
2 changed files with 27 additions and 4 deletions

View file

@ -186,6 +186,11 @@ std::string FragmentProgramDecompiler::AddType3()
return m_parr.AddParam(PF_PARAM_NONE, getFloatTypeName(4), "src3", getFloatTypeName(4) + "(1., 1., 1., 1.)");
}
std::string FragmentProgramDecompiler::AddX2d()
{
return m_parr.AddParam(PF_PARAM_NONE, getFloatTypeName(4), "x2d", getFloatTypeName(4) + "(0., 0., 0., 0.)");
}
//Both of these were tested with a trace SoulCalibur IV title screen
//Failure to catch causes infinite values since theres alot of rcp(0)
std::string FragmentProgramDecompiler::NotZero(const std::string& code)
@ -233,7 +238,7 @@ bool FragmentProgramDecompiler::DstExpectsSca()
return (writes == 1);
}
std::string FragmentProgramDecompiler::Format(const std::string& code)
std::string FragmentProgramDecompiler::Format(const std::string& code, bool ignore_redirects)
{
const std::pair<std::string, std::function<std::string()>> repl_list[] =
{
@ -255,6 +260,20 @@ std::string FragmentProgramDecompiler::Format(const std::string& code)
{ "$_c", std::bind(std::mem_fn(&FragmentProgramDecompiler::AddConst), this) }
};
if (!ignore_redirects)
{
//Special processing redirects
if (dst.opcode == RSX_FP_OPCODE_TEXBEM)
{
//Redirect parameter 0 to the x2d temp register for TEXBEM
//TODO: Organize this a little better
std::pair<std::string, std::string> repl[] = { { "$0", "x2d" } };
std::string result = fmt::replace_all(code, repl);
return fmt::replace_all(code, repl_list);
}
}
return fmt::replace_all(code, repl_list);
}
@ -573,8 +592,9 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
case RSX_FP_OPCODE_NRM: SetDst("normalize($0.xyz)"); return true;
case RSX_FP_OPCODE_BEM: SetDst("$0.xyxy + $1.xxxx * $2.xzxz + $1.yyyy * $2.ywyw"); return true;
case RSX_FP_OPCODE_TEXBEM:
//treat as TEX for now
LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: TEXBEM");
//Untested, should be x2d followed by TEX
AddX2d();
AddCode(Format("x2d = $0.xyxy + $1.xxxx * $2.xzxz + $1.yyyy * $2.ywyw", true));
case RSX_FP_OPCODE_TEX:
switch (m_prog.get_texture_dimension(dst.tex_num))
{

View file

@ -126,11 +126,14 @@ class FragmentProgramDecompiler
std::string AddConst();
std::string AddTex();
void AddFlowOp(std::string code);
std::string Format(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
std::string AddX2d();
//Prevent division by zero by catching denormals
//Simpler variant where input and output are expected to be positive
std::string NotZero(const std::string& code);