mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-13 10:18:40 +12:00
rsx/fp: Better handling of flow control ops
This commit is contained in:
parent
ccb23d70a5
commit
18df292f90
2 changed files with 43 additions and 34 deletions
|
@ -80,6 +80,27 @@ void FragmentProgramDecompiler::SetDst(std::string code, bool append_mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FragmentProgramDecompiler::AddFlowOp(std::string code)
|
||||||
|
{
|
||||||
|
//Flow operations can only consider conditionals and have no dst
|
||||||
|
|
||||||
|
if (src0.exec_if_gr && src0.exec_if_lt && src0.exec_if_eq)
|
||||||
|
{
|
||||||
|
AddCode(code + ";");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!src0.exec_if_gr && !src0.exec_if_lt && !src0.exec_if_eq)
|
||||||
|
{
|
||||||
|
AddCode("//" + code + ";");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//We have a conditional expression
|
||||||
|
std::string cond = GetRawCond();
|
||||||
|
|
||||||
|
AddCode("if (any(" + cond + ")) " + code + ";");
|
||||||
|
}
|
||||||
|
|
||||||
void FragmentProgramDecompiler::AddCode(const std::string& code)
|
void FragmentProgramDecompiler::AddCode(const std::string& code)
|
||||||
{
|
{
|
||||||
main.append(m_code_level, '\t') += Format(code) + "\n";
|
main.append(m_code_level, '\t') += Format(code) + "\n";
|
||||||
|
@ -228,17 +249,8 @@ std::string FragmentProgramDecompiler::Format(const std::string& code)
|
||||||
return fmt::replace_all(code, repl_list);
|
return fmt::replace_all(code, repl_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FragmentProgramDecompiler::GetCond()
|
std::string FragmentProgramDecompiler::GetRawCond()
|
||||||
{
|
{
|
||||||
if (src0.exec_if_gr && src0.exec_if_lt && src0.exec_if_eq)
|
|
||||||
{
|
|
||||||
return "true";
|
|
||||||
}
|
|
||||||
else if (!src0.exec_if_gr && !src0.exec_if_lt && !src0.exec_if_eq)
|
|
||||||
{
|
|
||||||
return "false";
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char f[4] = { 'x', 'y', 'z', 'w' };
|
static const char f[4] = { 'x', 'y', 'z', 'w' };
|
||||||
|
|
||||||
std::string swizzle, cond;
|
std::string swizzle, cond;
|
||||||
|
@ -261,7 +273,21 @@ std::string FragmentProgramDecompiler::GetCond()
|
||||||
else //if(src0.exec_if_eq)
|
else //if(src0.exec_if_eq)
|
||||||
cond = compareFunction(COMPARE::FUNCTION_SEQ, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)");
|
cond = compareFunction(COMPARE::FUNCTION_SEQ, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)");
|
||||||
|
|
||||||
return "any(" + cond + ")";
|
return cond;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string FragmentProgramDecompiler::GetCond()
|
||||||
|
{
|
||||||
|
if (src0.exec_if_gr && src0.exec_if_lt && src0.exec_if_eq)
|
||||||
|
{
|
||||||
|
return "true";
|
||||||
|
}
|
||||||
|
else if (!src0.exec_if_gr && !src0.exec_if_lt && !src0.exec_if_eq)
|
||||||
|
{
|
||||||
|
return "false";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "any(" + GetRawCond() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void FragmentProgramDecompiler::AddCodeCond(const std::string& dst, const std::string& src)
|
void FragmentProgramDecompiler::AddCodeCond(const std::string& dst, const std::string& src)
|
||||||
|
@ -279,26 +305,7 @@ void FragmentProgramDecompiler::AddCodeCond(const std::string& dst, const std::s
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char f[4] = { 'x', 'y', 'z', 'w' };
|
static const char f[4] = { 'x', 'y', 'z', 'w' };
|
||||||
|
std::string cond = GetRawCond();
|
||||||
std::string swizzle, cond;
|
|
||||||
swizzle += f[src0.cond_swizzle_x];
|
|
||||||
swizzle += f[src0.cond_swizzle_y];
|
|
||||||
swizzle += f[src0.cond_swizzle_z];
|
|
||||||
swizzle += f[src0.cond_swizzle_w];
|
|
||||||
swizzle = swizzle == "xyzw" ? "" : "." + swizzle;
|
|
||||||
|
|
||||||
if (src0.exec_if_gr && src0.exec_if_eq)
|
|
||||||
cond = compareFunction(COMPARE::FUNCTION_SGE, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)");
|
|
||||||
else if (src0.exec_if_lt && src0.exec_if_eq)
|
|
||||||
cond = compareFunction(COMPARE::FUNCTION_SLE, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)");
|
|
||||||
else if (src0.exec_if_gr && src0.exec_if_lt)
|
|
||||||
cond = compareFunction(COMPARE::FUNCTION_SNE, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)");
|
|
||||||
else if (src0.exec_if_gr)
|
|
||||||
cond = compareFunction(COMPARE::FUNCTION_SGT, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)");
|
|
||||||
else if (src0.exec_if_lt)
|
|
||||||
cond = compareFunction(COMPARE::FUNCTION_SLT, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)");
|
|
||||||
else //if(src0.exec_if_eq)
|
|
||||||
cond = compareFunction(COMPARE::FUNCTION_SEQ, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)");
|
|
||||||
|
|
||||||
ShaderVariable dst_var(dst);
|
ShaderVariable dst_var(dst);
|
||||||
dst_var.symplify();
|
dst_var.symplify();
|
||||||
|
@ -641,7 +648,7 @@ std::string FragmentProgramDecompiler::Decompile()
|
||||||
{
|
{
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case RSX_FP_OPCODE_BRK: SetDst("break"); break;
|
case RSX_FP_OPCODE_BRK: AddFlowOp("break"); break;
|
||||||
case RSX_FP_OPCODE_CAL: LOG_ERROR(RSX, "Unimplemented SIP instruction: CAL"); break;
|
case RSX_FP_OPCODE_CAL: LOG_ERROR(RSX, "Unimplemented SIP instruction: CAL"); break;
|
||||||
case RSX_FP_OPCODE_FENCT: forced_unit = FORCE_SCT; break;
|
case RSX_FP_OPCODE_FENCT: forced_unit = FORCE_SCT; break;
|
||||||
case RSX_FP_OPCODE_FENCB: forced_unit = FORCE_SCB; break;
|
case RSX_FP_OPCODE_FENCB: forced_unit = FORCE_SCB; break;
|
||||||
|
@ -685,7 +692,7 @@ std::string FragmentProgramDecompiler::Decompile()
|
||||||
m_code_level++;
|
m_code_level++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RSX_FP_OPCODE_RET: SetDst("return"); break;
|
case RSX_FP_OPCODE_RET: AddFlowOp("return"); break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -697,7 +704,7 @@ std::string FragmentProgramDecompiler::Decompile()
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case RSX_FP_OPCODE_NOP: break;
|
case RSX_FP_OPCODE_NOP: break;
|
||||||
case RSX_FP_OPCODE_KIL: SetDst("discard", false); break;
|
case RSX_FP_OPCODE_KIL: AddFlowOp("discard"); break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
int prev_force_unit = forced_unit;
|
int prev_force_unit = forced_unit;
|
||||||
|
|
|
@ -44,6 +44,7 @@ class FragmentProgramDecompiler
|
||||||
std::string AddCond();
|
std::string AddCond();
|
||||||
std::string AddConst();
|
std::string AddConst();
|
||||||
std::string AddTex();
|
std::string AddTex();
|
||||||
|
void AddFlowOp(std::string code);
|
||||||
std::string Format(const std::string& code);
|
std::string Format(const std::string& code);
|
||||||
|
|
||||||
//Technically a temporary workaround until we know what type3 is
|
//Technically a temporary workaround until we know what type3 is
|
||||||
|
@ -58,6 +59,7 @@ class FragmentProgramDecompiler
|
||||||
std::string NoOverflow(const std::string& code);
|
std::string NoOverflow(const std::string& code);
|
||||||
|
|
||||||
void AddCodeCond(const std::string& dst, const std::string& src);
|
void AddCodeCond(const std::string& dst, const std::string& src);
|
||||||
|
std::string GetRawCond();
|
||||||
std::string GetCond();
|
std::string GetCond();
|
||||||
template<typename T> std::string GetSRC(T src);
|
template<typename T> std::string GetSRC(T src);
|
||||||
std::string BuildCode();
|
std::string BuildCode();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue