mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 15:01:28 +12:00
rsx/vp: Fix double dst commands
- Test the vec_result mask before assigning to actual output Sometimes, VEC op is used to write to Rx, and SCA op is used to write to o[x]!
This commit is contained in:
parent
10d96a60f1
commit
7555be232f
1 changed files with 35 additions and 28 deletions
|
@ -40,42 +40,49 @@ std::string VertexProgramDecompiler::GetScaMask()
|
||||||
std::string VertexProgramDecompiler::GetDST(bool isSca)
|
std::string VertexProgramDecompiler::GetDST(bool isSca)
|
||||||
{
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
std::string mask = GetMask(isSca);
|
const std::string mask = GetMask(isSca);
|
||||||
|
|
||||||
// ARL writes to special integer registers
|
// ARL writes to special integer registers
|
||||||
const bool is_address_reg = !isSca && (d1.vec_opcode == RSX_VEC_OPCODE_ARL);
|
const bool is_address_reg = !isSca && (d1.vec_opcode == RSX_VEC_OPCODE_ARL);
|
||||||
|
const auto tmp_index = isSca ? d3.sca_dst_tmp : d0.dst_tmp;
|
||||||
|
const bool is_result = isSca ? (tmp_index == 0x3f) : d0.vec_result;
|
||||||
|
|
||||||
switch ((isSca && d3.sca_dst_tmp != 0x3f) ? 0x1f : d3.dst)
|
if (is_result)
|
||||||
{
|
{
|
||||||
case 0x1f:
|
// Write to output result register
|
||||||
|
// vec_result can mask out the VEC op from writing to o[] if SCA is writing to o[]
|
||||||
|
|
||||||
|
if (d3.dst != 0x1f)
|
||||||
|
{
|
||||||
|
if (d3.dst > 15)
|
||||||
|
{
|
||||||
|
LOG_ERROR(RSX, "dst index out of range: %u", d3.dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_address_reg)
|
||||||
|
{
|
||||||
|
LOG_ERROR(RSX, "ARL opcode writing to output register!");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto reg_type = getFloatTypeName(4);
|
||||||
|
const auto reg_name = std::string("dst_reg") + std::to_string(d3.dst);
|
||||||
|
const auto default_value = (d3.dst == 0 ? reg_type + "(0.0f, 0.0f, 0.0f, 1.0f)" : reg_type + "(0.0, 0.0, 0.0, 0.0)");
|
||||||
|
ret += m_parr.AddParam(PF_PARAM_OUT, reg_type, reg_name, default_value) + mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp_index != 0x3f)
|
||||||
{
|
{
|
||||||
|
if (!ret.empty())
|
||||||
|
{
|
||||||
|
// Double assignment. Only possible for vector ops
|
||||||
|
verify(HERE), !isSca;
|
||||||
|
ret += " = ";
|
||||||
|
}
|
||||||
|
|
||||||
const std::string reg_type = (is_address_reg) ? getIntTypeName(4) : getFloatTypeName(4);
|
const std::string reg_type = (is_address_reg) ? getIntTypeName(4) : getFloatTypeName(4);
|
||||||
const std::string reg_sel = (is_address_reg) ? "a" : "tmp";
|
const std::string reg_sel = (is_address_reg) ? "a" : "tmp";
|
||||||
ret += m_parr.AddParam(PF_PARAM_NONE, reg_type, reg_sel + std::to_string(isSca ? d3.sca_dst_tmp : d0.dst_tmp)) + mask;
|
ret += m_parr.AddParam(PF_PARAM_NONE, reg_type, reg_sel + std::to_string(tmp_index)) + mask;
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if (is_address_reg)
|
|
||||||
{
|
|
||||||
LOG_ERROR(RSX, "ARL opcode writing to output register!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d3.dst > 15)
|
|
||||||
{
|
|
||||||
LOG_ERROR(RSX, "dst index out of range: %u", d3.dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret += m_parr.AddParam(PF_PARAM_OUT, getFloatTypeName(4), std::string("dst_reg") + std::to_string(d3.dst), d3.dst == 0 ? getFloatTypeName(4) + "(0.0f, 0.0f, 0.0f, 1.0f)" : getFloatTypeName(4) + "(0.0, 0.0, 0.0, 0.0)") + mask;
|
|
||||||
|
|
||||||
if (d0.dst_tmp != 0x3f)
|
|
||||||
{
|
|
||||||
// Handle double destination register as 'dst_reg = tmp'
|
|
||||||
ret += " = " + m_parr.AddParam(PF_PARAM_NONE, getFloatTypeName(4), std::string("tmp") + std::to_string(d0.dst_tmp)) + mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue