mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 22:11:26 +12:00
Rsx: fix CALL and RET cmd
This commit is contained in:
parent
801089cf44
commit
c80eb1ba02
2 changed files with 15 additions and 6 deletions
|
@ -566,6 +566,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
//New internal get is valid, use it
|
//New internal get is valid, use it
|
||||||
restore_point = internal_get.load();
|
restore_point = internal_get.load();
|
||||||
|
restore_ret_addr = m_return_addr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -623,6 +624,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
LOG_ERROR(RSX, "Application has failed to recover, resetting FIFO queue");
|
LOG_ERROR(RSX, "Application has failed to recover, resetting FIFO queue");
|
||||||
internal_get = restore_point.load();
|
internal_get = restore_point.load();
|
||||||
|
m_return_addr = restore_ret_addr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -677,23 +679,28 @@ namespace rsx
|
||||||
}
|
}
|
||||||
if ((cmd & RSX_METHOD_CALL_CMD_MASK) == RSX_METHOD_CALL_CMD)
|
if ((cmd & RSX_METHOD_CALL_CMD_MASK) == RSX_METHOD_CALL_CMD)
|
||||||
{
|
{
|
||||||
m_call_stack.push(internal_get + 4);
|
if (m_return_addr != -1)
|
||||||
|
{
|
||||||
|
// Only one layer is allowed in the call stack.
|
||||||
|
LOG_ERROR(RSX, "FIFO: CALL found inside a subroutine. Discarding subroutine");
|
||||||
|
internal_get = std::exchange(m_return_addr, -1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
u32 offs = cmd & ~3;
|
u32 offs = cmd & ~3;
|
||||||
//LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get);
|
//LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get);
|
||||||
internal_get = offs;
|
m_return_addr = std::exchange(internal_get.raw(), offs) + 4;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cmd == RSX_METHOD_RETURN_CMD)
|
if (cmd == RSX_METHOD_RETURN_CMD)
|
||||||
{
|
{
|
||||||
if (m_call_stack.size() == 0)
|
if (m_return_addr == -1)
|
||||||
{
|
{
|
||||||
LOG_ERROR(RSX, "FIFO: RET found without corresponding CALL. Discarding queue");
|
LOG_ERROR(RSX, "FIFO: RET found without corresponding CALL. Discarding queue");
|
||||||
internal_get = put;
|
internal_get = put;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 get = m_call_stack.top();
|
u32 get = std::exchange(m_return_addr, -1);
|
||||||
m_call_stack.pop();
|
|
||||||
//LOG_WARNING(RSX, "rsx return(0x%x)", get);
|
//LOG_WARNING(RSX, "rsx return(0x%x)", get);
|
||||||
internal_get = get;
|
internal_get = get;
|
||||||
continue;
|
continue;
|
||||||
|
@ -721,6 +728,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
LOG_ERROR(RSX, "Application has failed to recover, resetting FIFO queue");
|
LOG_ERROR(RSX, "Application has failed to recover, resetting FIFO queue");
|
||||||
internal_get = restore_point.load();
|
internal_get = restore_point.load();
|
||||||
|
m_return_addr = restore_ret_addr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -987,6 +995,7 @@ namespace rsx
|
||||||
//Ignore the rest of the chain
|
//Ignore the rest of the chain
|
||||||
LOG_ERROR(RSX, "FIFO contents may be corrupted. Resetting...");
|
LOG_ERROR(RSX, "FIFO contents may be corrupted. Resetting...");
|
||||||
internal_get = restore_point.load();
|
internal_get = restore_point.load();
|
||||||
|
m_return_addr = restore_ret_addr;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,7 @@ namespace rsx
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
atomic_t<bool> m_rsx_thread_exiting{false};
|
atomic_t<bool> m_rsx_thread_exiting{false};
|
||||||
std::stack<u32> m_call_stack;
|
s32 m_return_addr{-1}, restore_ret_addr{-1};
|
||||||
std::array<push_buffer_vertex_info, 16> vertex_push_buffers;
|
std::array<push_buffer_vertex_info, 16> vertex_push_buffers;
|
||||||
std::vector<u32> element_push_buffer;
|
std::vector<u32> element_push_buffer;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue