mirror of https://github.com/RPCS3/rpcs3.git
rsx: Separate loop interrupts from graphics state
- The interrupts are for multithreaded signals andmake the main loop run more aggressively for the next cycle
This commit is contained in:
parent
257556bbf5
commit
ec2d529832
|
@ -89,5 +89,10 @@ namespace rsx
|
||||||
{
|
{
|
||||||
m_data.release(0);
|
m_data.release(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator bool () const
|
||||||
|
{
|
||||||
|
return m_data.observe() != 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -967,7 +967,7 @@ bool GLGSRender::on_access_violation(u32 address, bool is_writing)
|
||||||
{
|
{
|
||||||
auto &task = post_flush_request(address, result);
|
auto &task = post_flush_request(address, result);
|
||||||
|
|
||||||
m_graphics_state |= rsx::pipeline_state::backend_interrupt;
|
m_eng_interrupt_mask |= rsx::backend_interrupt;
|
||||||
vm::temporary_unlock();
|
vm::temporary_unlock();
|
||||||
task.producer_wait();
|
task.producer_wait();
|
||||||
}
|
}
|
||||||
|
|
|
@ -521,6 +521,7 @@ namespace rsx
|
||||||
method_registers.current_draw_clause.post_execute_cleanup();
|
method_registers.current_draw_clause.post_execute_cleanup();
|
||||||
|
|
||||||
m_graphics_state |= rsx::pipeline_state::framebuffer_reads_dirty;
|
m_graphics_state |= rsx::pipeline_state::framebuffer_reads_dirty;
|
||||||
|
m_eng_interrupt_mask |= rsx::backend_interrupt;
|
||||||
ROP_sync_timestamp = rsx::get_shared_tag();
|
ROP_sync_timestamp = rsx::get_shared_tag();
|
||||||
|
|
||||||
if (m_graphics_state & rsx::pipeline_state::push_buffer_arrays_dirty)
|
if (m_graphics_state & rsx::pipeline_state::push_buffer_arrays_dirty)
|
||||||
|
@ -766,8 +767,7 @@ namespace rsx
|
||||||
// Update sub-units every 64 cycles. The local handler is invoked for other functions externally on-demand anyway.
|
// Update sub-units every 64 cycles. The local handler is invoked for other functions externally on-demand anyway.
|
||||||
// This avoids expensive calls to check timestamps which involves reading some values from TLS storage on windows.
|
// This avoids expensive calls to check timestamps which involves reading some values from TLS storage on windows.
|
||||||
// If something is going on in the backend that requires an update, set the interrupt bit explicitly.
|
// If something is going on in the backend that requires an update, set the interrupt bit explicitly.
|
||||||
if ((m_cycles_counter++ & 63) == 0 ||
|
if ((m_cycles_counter++ & 63) == 0 || m_eng_interrupt_mask)
|
||||||
m_graphics_state & rsx::pipeline_state::backend_interrupt_bits)
|
|
||||||
{
|
{
|
||||||
// Execute backend-local tasks first
|
// Execute backend-local tasks first
|
||||||
do_local_task(performance_counters.state);
|
do_local_task(performance_counters.state);
|
||||||
|
@ -1049,7 +1049,7 @@ namespace rsx
|
||||||
|
|
||||||
void thread::do_local_task(FIFO_state state)
|
void thread::do_local_task(FIFO_state state)
|
||||||
{
|
{
|
||||||
m_graphics_state &= ~rsx::pipeline_state::backend_interrupt;
|
m_eng_interrupt_mask.clear(rsx::backend_interrupt);
|
||||||
|
|
||||||
if (async_flip_requested & flip_request::emu_requested)
|
if (async_flip_requested & flip_request::emu_requested)
|
||||||
{
|
{
|
||||||
|
@ -2480,6 +2480,8 @@ namespace rsx
|
||||||
|
|
||||||
void thread::flip(const display_flip_info_t& info)
|
void thread::flip(const display_flip_info_t& info)
|
||||||
{
|
{
|
||||||
|
m_eng_interrupt_mask.clear(rsx::display_interrupt);
|
||||||
|
|
||||||
if (async_flip_requested & flip_request::any)
|
if (async_flip_requested & flip_request::any)
|
||||||
{
|
{
|
||||||
// Deferred flip
|
// Deferred flip
|
||||||
|
@ -2965,14 +2967,14 @@ namespace rsx
|
||||||
m_invalidated_memory_range = unmap_range;
|
m_invalidated_memory_range = unmap_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_graphics_state |= rsx::pipeline_state::memory_config_interrupt;
|
m_eng_interrupt_mask |= rsx::memory_config_interrupt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: m_mtx_task lock must be acquired before calling this method
|
// NOTE: m_mtx_task lock must be acquired before calling this method
|
||||||
void thread::handle_invalidated_memory_range()
|
void thread::handle_invalidated_memory_range()
|
||||||
{
|
{
|
||||||
m_graphics_state &= ~rsx::pipeline_state::memory_config_interrupt;
|
m_eng_interrupt_mask.clear(rsx::memory_config_interrupt);
|
||||||
|
|
||||||
if (!m_invalidated_memory_range.valid())
|
if (!m_invalidated_memory_range.valid())
|
||||||
return;
|
return;
|
||||||
|
@ -3159,7 +3161,7 @@ namespace rsx
|
||||||
|
|
||||||
async_flip_buffer = buffer;
|
async_flip_buffer = buffer;
|
||||||
async_flip_requested |= flip_request::emu_requested;
|
async_flip_requested |= flip_request::emu_requested;
|
||||||
m_graphics_state |= rsx::pipeline_state::backend_interrupt;
|
m_eng_interrupt_mask |= rsx::display_interrupt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,19 +132,24 @@ namespace rsx
|
||||||
|
|
||||||
push_buffer_arrays_dirty = 0x20000, // Push buffers have data written to them (immediate mode vertex buffers)
|
push_buffer_arrays_dirty = 0x20000, // Push buffers have data written to them (immediate mode vertex buffers)
|
||||||
|
|
||||||
backend_interrupt = 0x80000000, // Backend interrupt, must serve immediately
|
|
||||||
memory_config_interrupt = 0x40000000, // Memory configuration changed
|
|
||||||
|
|
||||||
fragment_program_dirty = fragment_program_ucode_dirty | fragment_program_state_dirty,
|
fragment_program_dirty = fragment_program_ucode_dirty | fragment_program_state_dirty,
|
||||||
vertex_program_dirty = vertex_program_ucode_dirty | vertex_program_state_dirty,
|
vertex_program_dirty = vertex_program_ucode_dirty | vertex_program_state_dirty,
|
||||||
invalidate_pipeline_bits = fragment_program_dirty | vertex_program_dirty,
|
invalidate_pipeline_bits = fragment_program_dirty | vertex_program_dirty,
|
||||||
invalidate_zclip_bits = vertex_state_dirty | zclip_config_state_dirty,
|
invalidate_zclip_bits = vertex_state_dirty | zclip_config_state_dirty,
|
||||||
memory_barrier_bits = framebuffer_reads_dirty,
|
memory_barrier_bits = framebuffer_reads_dirty,
|
||||||
backend_interrupt_bits = memory_barrier_bits | memory_config_interrupt | backend_interrupt,
|
|
||||||
|
|
||||||
all_dirty = ~0u
|
all_dirty = ~0u
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum eng_interrupt_reason : u32
|
||||||
|
{
|
||||||
|
backend_interrupt = 0x0001, // Backend-related interrupt
|
||||||
|
memory_config_interrupt = 0x0002, // Memory configuration changed
|
||||||
|
display_interrupt = 0x0004, // Display handling
|
||||||
|
|
||||||
|
all_interrupt_bits = memory_config_interrupt | backend_interrupt | display_interrupt
|
||||||
|
};
|
||||||
|
|
||||||
enum FIFO_state : u8
|
enum FIFO_state : u8
|
||||||
{
|
{
|
||||||
running = 0,
|
running = 0,
|
||||||
|
@ -565,6 +570,7 @@ namespace rsx
|
||||||
bool m_framebuffer_state_contested = false;
|
bool m_framebuffer_state_contested = false;
|
||||||
rsx::framebuffer_creation_context m_current_framebuffer_context = rsx::framebuffer_creation_context::context_draw;
|
rsx::framebuffer_creation_context m_current_framebuffer_context = rsx::framebuffer_creation_context::context_draw;
|
||||||
|
|
||||||
|
rsx::atomic_bitmask_t<rsx::eng_interrupt_reason> m_eng_interrupt_mask;
|
||||||
u32 m_graphics_state = 0;
|
u32 m_graphics_state = 0;
|
||||||
u64 ROP_sync_timestamp = 0;
|
u64 ROP_sync_timestamp = 0;
|
||||||
|
|
||||||
|
|
|
@ -804,7 +804,7 @@ bool VKGSRender::on_access_violation(u32 address, bool is_writing)
|
||||||
|
|
||||||
g_fxo->get<rsx::dma_manager>().set_mem_fault_flag();
|
g_fxo->get<rsx::dma_manager>().set_mem_fault_flag();
|
||||||
m_queue_status |= flush_queue_state::deadlock;
|
m_queue_status |= flush_queue_state::deadlock;
|
||||||
m_graphics_state |= rsx::pipeline_state::backend_interrupt;
|
m_eng_interrupt_mask |= rsx::backend_interrupt;
|
||||||
|
|
||||||
// Wait for deadlock to clear
|
// Wait for deadlock to clear
|
||||||
while (m_queue_status & flush_queue_state::deadlock)
|
while (m_queue_status & flush_queue_state::deadlock)
|
||||||
|
@ -825,7 +825,7 @@ bool VKGSRender::on_access_violation(u32 address, bool is_writing)
|
||||||
std::lock_guard lock(m_flush_queue_mutex);
|
std::lock_guard lock(m_flush_queue_mutex);
|
||||||
|
|
||||||
m_flush_requests.post(false);
|
m_flush_requests.post(false);
|
||||||
m_graphics_state |= rsx::pipeline_state::backend_interrupt;
|
m_eng_interrupt_mask |= rsx::backend_interrupt;
|
||||||
has_queue_ref = true;
|
has_queue_ref = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue