mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
rsx/lv2: Refactor DMA control stuff after VSH work
This commit is contained in:
parent
3dba894369
commit
73cda2324a
@ -34,11 +34,46 @@ void fmt_class_string<sys_rsx_error>::format(std::string& out, u64 arg)
|
||||
});
|
||||
}
|
||||
|
||||
u64 rsxTimeStamp()
|
||||
static u64 rsx_timeStamp()
|
||||
{
|
||||
return get_timebased_time();
|
||||
}
|
||||
|
||||
static void set_rsx_dmactl(rsx::thread* render, u64 get_put)
|
||||
{
|
||||
{
|
||||
rsx::eng_lock rlock(render);
|
||||
render->fifo_ctrl->abort();
|
||||
|
||||
// Unconditional set
|
||||
while (!render->new_get_put.compare_and_swap_test(u64{umax}, get_put))
|
||||
{
|
||||
utils::pause();
|
||||
}
|
||||
|
||||
// Schedule FIFO interrupt to deal with this immediately
|
||||
render->m_eng_interrupt_mask |= rsx::dma_control_interrupt;
|
||||
}
|
||||
|
||||
if (auto cpu = cpu_thread::get_current())
|
||||
{
|
||||
// Wait for the first store to complete (or be aborted)
|
||||
while (render->new_get_put != usz{umax})
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
if (render->new_get_put.compare_and_swap_test(get_put, umax))
|
||||
{
|
||||
// Retry
|
||||
cpu->state += cpu_flag::again;
|
||||
}
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool rsx::thread::send_event(u64 data1, u64 event_flags, u64 data3)
|
||||
{
|
||||
// Filter event bits, send them only if they are masked by gcm
|
||||
@ -473,43 +508,9 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
|
||||
const u64 get = static_cast<u32>(a3);
|
||||
const u64 put = static_cast<u32>(a4);
|
||||
const u64 get_put = put << 32 | get;
|
||||
bool changed_value = false;
|
||||
{
|
||||
rsx::eng_lock rlock(render);
|
||||
std::lock_guard lock(render->sys_rsx_mtx);
|
||||
render->fifo_ctrl->abort();
|
||||
|
||||
while (render->new_get_put == umax)
|
||||
{
|
||||
if (render->new_get_put.compare_and_swap_test(u64{umax}, get_put))
|
||||
{
|
||||
changed_value = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Assume CAS can fail spuriously here
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for the first store to complete (or be aborted)
|
||||
while (render->new_get_put != umax)
|
||||
{
|
||||
if (Emu.IsStopped() && changed_value)
|
||||
{
|
||||
// Abort
|
||||
if (render->new_get_put.compare_and_swap_test(get_put, u64{umax}))
|
||||
{
|
||||
if (auto cpu = cpu_thread::get_current())
|
||||
{
|
||||
cpu->state += cpu_flag::again;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(1000);
|
||||
}
|
||||
|
||||
std::lock_guard lock(render->sys_rsx_mtx);
|
||||
set_rsx_dmactl(render, get_put);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -835,7 +836,7 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
|
||||
{
|
||||
// we only ever use head 1 for now
|
||||
driverInfo.head[1].flipFlags |= 0x80000000;
|
||||
driverInfo.head[1].lastFlipTime = rsxTimeStamp(); // should rsxthread set this?
|
||||
driverInfo.head[1].lastFlipTime = rsx_timeStamp(); // should rsxthread set this?
|
||||
driverInfo.head[1].flipBufferId = static_cast<u32>(a3);
|
||||
|
||||
// seems gcmSysWaitLabel uses this offset, so lets set it to 0 every flip
|
||||
@ -865,7 +866,7 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
|
||||
});
|
||||
|
||||
// Time point is supplied in argument 4 (todo: convert it to MFTB rate and use it)
|
||||
const u64 current_time = rsxTimeStamp();
|
||||
const u64 current_time = rsx_timeStamp();
|
||||
|
||||
|
||||
// Note: not atomic
|
||||
|
@ -1274,9 +1274,9 @@ namespace rsx
|
||||
handle_emu_flip(async_flip_buffer);
|
||||
}
|
||||
|
||||
if (!in_begin_end && state != FIFO::state::lock_wait)
|
||||
if (state != FIFO::state::lock_wait)
|
||||
{
|
||||
if (atomic_storage<u32>::load(m_invalidated_memory_range.end) != 0)
|
||||
if (!in_begin_end && atomic_storage<u32>::load(m_invalidated_memory_range.end) != 0)
|
||||
{
|
||||
std::lock_guard lock(m_mtx_task);
|
||||
|
||||
@ -1285,6 +1285,22 @@ namespace rsx
|
||||
handle_invalidated_memory_range();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_eng_interrupt_mask & rsx::dma_control_interrupt && !is_stopped())
|
||||
{
|
||||
if (const u64 get_put = new_get_put.exchange(u64{umax});
|
||||
get_put != umax)
|
||||
{
|
||||
vm::_ref<atomic_be_t<u64>>(dma_address + ::offset32(&RsxDmaControl::put)).release(get_put);
|
||||
fifo_ctrl->set_get(static_cast<u32>(get_put));
|
||||
fifo_ctrl->abort();
|
||||
fifo_ret_addr = RSX_CALL_STACK_EMPTY;
|
||||
last_known_code_start = static_cast<u32>(get_put);
|
||||
sync_point_request.release(true);
|
||||
}
|
||||
|
||||
m_eng_interrupt_mask.clear(rsx::dma_control_interrupt);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_eng_interrupt_mask & rsx::pipe_flush_interrupt)
|
||||
@ -1299,21 +1315,6 @@ namespace rsx
|
||||
m_invalidated_memory_range = utils::address_range::start_end(0x2 << 28, constants::local_mem_base + local_mem_size - 1);
|
||||
handle_invalidated_memory_range();
|
||||
}
|
||||
else if (new_get_put != umax && state != FIFO_state::lock_wait)
|
||||
{
|
||||
const u64 get_put = new_get_put.exchange(u64{umax});
|
||||
|
||||
// Recheck in case aborted externally
|
||||
if (get_put != umax)
|
||||
{
|
||||
vm::_ref<atomic_be_t<u64>>(dma_address + ::offset32(&RsxDmaControl::put)).release(get_put);
|
||||
fifo_ctrl->set_get(static_cast<u32>(get_put));
|
||||
fifo_ctrl->abort();
|
||||
fifo_ret_addr = RSX_CALL_STACK_EMPTY;
|
||||
last_known_code_start = static_cast<u32>(get_put);
|
||||
sync_point_request.release(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::array<u32, 4> thread::get_color_surface_addresses() const
|
||||
@ -3268,11 +3269,8 @@ namespace rsx
|
||||
{
|
||||
external_interrupt_lock++;
|
||||
|
||||
while (!external_interrupt_ack)
|
||||
while (!external_interrupt_ack && !is_stopped())
|
||||
{
|
||||
if (is_stopped())
|
||||
break;
|
||||
|
||||
utils::pause();
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ namespace rsx
|
||||
memory_config_interrupt = 0x0002, // Memory configuration changed
|
||||
display_interrupt = 0x0004, // Display handling
|
||||
pipe_flush_interrupt = 0x0008, // Flush pipelines
|
||||
dma_control_interrupt = 0x0010, // DMA interrupt
|
||||
|
||||
all_interrupt_bits = memory_config_interrupt | backend_interrupt | display_interrupt | pipe_flush_interrupt
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user