mirror of https://github.com/RPCS3/rpcs3.git
rsx: Fix vertex program analyser bug
This commit is contained in:
parent
1b1756de22
commit
85cefec5a3
|
@ -62,8 +62,9 @@ vertex_program_utils::vertex_program_metadata vertex_program_utils::analyse_vert
|
||||||
{
|
{
|
||||||
if (!has_printed_error)
|
if (!has_printed_error)
|
||||||
{
|
{
|
||||||
// This can be harmless if a dangling RET was encountered before
|
// This can be harmless if a dangling RET was encountered before.
|
||||||
rsx_log.error("vp_analyser: Possible infinite loop detected");
|
// This can also be legal in case of BRB...BRI loops since BRIs are conditional. Might just be a loop with exit cond.
|
||||||
|
rsx_log.warning("vp_analyser: Possible infinite loop detected");
|
||||||
has_printed_error = true;
|
has_printed_error = true;
|
||||||
}
|
}
|
||||||
current_instruction++;
|
current_instruction++;
|
||||||
|
@ -288,6 +289,17 @@ vertex_program_utils::vertex_program_metadata vertex_program_utils::analyse_vert
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Typical ubershaders have the dispatch at the top with subroutines following. However...
|
||||||
|
// some games have the dispatch block at the end and the subroutines above them.
|
||||||
|
// We need to simulate a jump-to-entry in this situation
|
||||||
|
// Normally this condition is handled by the conditional_targets walk, but sometimes this doesn't work due to cyclic branches
|
||||||
|
if (instruction_range.first < dst_prog.entry)
|
||||||
|
{
|
||||||
|
// Is there a subroutine that jumps into the entry? If not, add to jump table
|
||||||
|
const auto target = dst_prog.entry - instruction_range.first;
|
||||||
|
dst_prog.jump_table.insert(target);
|
||||||
|
}
|
||||||
|
|
||||||
// Verification
|
// Verification
|
||||||
for (const u32 target : dst_prog.jump_table)
|
for (const u32 target : dst_prog.jump_table)
|
||||||
{
|
{
|
||||||
|
|
|
@ -445,7 +445,7 @@ std::string VertexProgramDecompiler::Decompile()
|
||||||
const auto& data = m_prog.data;
|
const auto& data = m_prog.data;
|
||||||
m_instr_count = data.size() / 4;
|
m_instr_count = data.size() / 4;
|
||||||
|
|
||||||
bool is_has_BRA = false;
|
bool has_BRA = false;
|
||||||
bool program_end = false;
|
bool program_end = false;
|
||||||
u32 i = 1;
|
u32 i = 1;
|
||||||
u32 last_label_addr = 0;
|
u32 last_label_addr = 0;
|
||||||
|
@ -527,7 +527,7 @@ std::string VertexProgramDecompiler::Decompile()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (is_has_BRA || !m_prog.jump_table.empty())
|
if (has_BRA || !m_prog.jump_table.empty())
|
||||||
{
|
{
|
||||||
m_cur_instr = &m_instructions[0];
|
m_cur_instr = &m_instructions[0];
|
||||||
|
|
||||||
|
@ -573,7 +573,7 @@ std::string VertexProgramDecompiler::Decompile()
|
||||||
{
|
{
|
||||||
//TODO: Subroutines can also have arbitrary jumps!
|
//TODO: Subroutines can also have arbitrary jumps!
|
||||||
u32 jump_position = find_jump_lvl(i);
|
u32 jump_position = find_jump_lvl(i);
|
||||||
if (is_has_BRA || jump_position != umax)
|
if (has_BRA || jump_position != umax)
|
||||||
{
|
{
|
||||||
m_cur_instr->close_scopes++;
|
m_cur_instr->close_scopes++;
|
||||||
AddCode("}");
|
AddCode("}");
|
||||||
|
@ -782,7 +782,7 @@ std::string VertexProgramDecompiler::Decompile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_has_BRA || !m_prog.jump_table.empty())
|
if (has_BRA || !m_prog.jump_table.empty())
|
||||||
{
|
{
|
||||||
m_cur_instr = &m_instructions[m_instr_count - 1];
|
m_cur_instr = &m_instructions[m_instr_count - 1];
|
||||||
m_cur_instr->close_scopes++;
|
m_cur_instr->close_scopes++;
|
||||||
|
|
Loading…
Reference in New Issue