mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-12 01:38:37 +12:00
rsx: Implement report transfer deferring
- Allow delaying report flushes triggered by image_in or buffer_notify - When the report is ready, all the delayed transfers will automatically be done. - TODO: Make this configurable?
This commit is contained in:
parent
3e0f9dff4d
commit
2a8f2c64d2
4 changed files with 134 additions and 29 deletions
|
@ -296,7 +296,7 @@ namespace rsx
|
|||
if (conditional_render_enabled && conditional_render_test_address)
|
||||
{
|
||||
// Evaluate conditional rendering test
|
||||
zcull_ctrl->read_barrier(this, conditional_render_test_address, 4);
|
||||
zcull_ctrl->read_barrier(this, conditional_render_test_address, 4, reports::sync_no_notify);
|
||||
vm::ptr<CellGcmReportData> result = vm::cast(conditional_render_test_address);
|
||||
conditional_render_test_failed = (result->value == 0);
|
||||
conditional_render_test_address = 0;
|
||||
|
@ -2348,6 +2348,11 @@ namespace rsx
|
|||
vm::_ref<atomic_t<CellGcmReportData>>(sink).store({ timestamp(), value, 0});
|
||||
}
|
||||
|
||||
u32 thread::copy_zcull_stats(u32 memory_range_start, u32 memory_range, u32 destination)
|
||||
{
|
||||
return zcull_ctrl->copy_reports_to(memory_range_start, memory_range, destination);
|
||||
}
|
||||
|
||||
void thread::sync()
|
||||
{
|
||||
zcull_ctrl->sync(this);
|
||||
|
@ -2384,9 +2389,10 @@ namespace rsx
|
|||
return fifo_ctrl->last_cmd();
|
||||
}
|
||||
|
||||
void thread::read_barrier(u32 memory_address, u32 memory_range)
|
||||
flags32_t thread::read_barrier(u32 memory_address, u32 memory_range, bool unconditional)
|
||||
{
|
||||
zcull_ctrl->read_barrier(this, memory_address, memory_range);
|
||||
flags32_t zcull_flags = (unconditional)? reports::sync_none : reports::sync_defer_copy;
|
||||
return zcull_ctrl->read_barrier(this, memory_address, memory_range, zcull_flags);
|
||||
}
|
||||
|
||||
void thread::notify_zcull_info_changed()
|
||||
|
@ -2938,6 +2944,16 @@ namespace rsx
|
|||
vm::_ref<atomic_t<CellGcmReportData>>(sink).store({ timestamp, value, 0});
|
||||
}
|
||||
|
||||
void ZCULL_control::write(queued_report_write* writer, u64 timestamp, u32 value)
|
||||
{
|
||||
write(writer->sink, timestamp, writer->type, value);
|
||||
|
||||
for (auto &addr : writer->sink_alias)
|
||||
{
|
||||
write(addr, timestamp, writer->type, value);
|
||||
}
|
||||
}
|
||||
|
||||
void ZCULL_control::sync(::rsx::thread* ptimer)
|
||||
{
|
||||
if (!m_pending_writes.empty())
|
||||
|
@ -2979,8 +2995,10 @@ namespace rsx
|
|||
}
|
||||
|
||||
if (!writer.forwarder)
|
||||
//No other queries in the chain, write result
|
||||
write(writer.sink, ptimer->timestamp(), writer.type, result);
|
||||
{
|
||||
// No other queries in the chain, write result
|
||||
write(&writer, ptimer->timestamp(), result);
|
||||
}
|
||||
|
||||
processed++;
|
||||
}
|
||||
|
@ -2997,7 +3015,7 @@ namespace rsx
|
|||
|
||||
if (remaining == 1)
|
||||
{
|
||||
m_pending_writes.front() = m_pending_writes.back();
|
||||
m_pending_writes[0] = std::move(m_pending_writes.back());
|
||||
m_pending_writes.resize(1);
|
||||
}
|
||||
else
|
||||
|
@ -3156,10 +3174,12 @@ namespace rsx
|
|||
|
||||
stat_tag_to_remove = writer.counter_tag;
|
||||
|
||||
//only zpass supported right now
|
||||
// only zpass supported right now
|
||||
if (!writer.forwarder)
|
||||
//No other queries in the chain, write result
|
||||
write(writer.sink, ptimer->timestamp(), writer.type, result);
|
||||
{
|
||||
// No other queries in the chain, write result
|
||||
write(&writer, ptimer->timestamp(), result);
|
||||
}
|
||||
|
||||
processed++;
|
||||
}
|
||||
|
@ -3172,7 +3192,7 @@ namespace rsx
|
|||
auto remaining = m_pending_writes.size() - processed;
|
||||
if (remaining == 1)
|
||||
{
|
||||
m_pending_writes.front() = m_pending_writes.back();
|
||||
m_pending_writes[0] = std::move(m_pending_writes.back());
|
||||
m_pending_writes.resize(1);
|
||||
}
|
||||
else if (remaining)
|
||||
|
@ -3189,10 +3209,10 @@ namespace rsx
|
|||
}
|
||||
}
|
||||
|
||||
void ZCULL_control::read_barrier(::rsx::thread* ptimer, u32 memory_address, u32 memory_range)
|
||||
flags32_t ZCULL_control::read_barrier(::rsx::thread* ptimer, u32 memory_address, u32 memory_range, flags32_t flags)
|
||||
{
|
||||
if (m_pending_writes.empty())
|
||||
return;
|
||||
return result_none;
|
||||
|
||||
const auto memory_end = memory_address + memory_range;
|
||||
u32 sync_address = 0;
|
||||
|
@ -3208,11 +3228,21 @@ namespace rsx
|
|||
}
|
||||
}
|
||||
|
||||
if (sync_address)
|
||||
if (!sync_address)
|
||||
return result_none;
|
||||
|
||||
if (!(flags & sync_defer_copy))
|
||||
{
|
||||
ptimer->sync_hint(FIFO_hint::hint_zcull_sync, reinterpret_cast<uintptr_t>(query));
|
||||
if (!(flags & sync_no_notify))
|
||||
{
|
||||
ptimer->sync_hint(FIFO_hint::hint_zcull_sync, reinterpret_cast<uintptr_t>(query));
|
||||
}
|
||||
|
||||
update(ptimer, sync_address);
|
||||
return result_none;
|
||||
}
|
||||
|
||||
return result_zcull_intr;
|
||||
}
|
||||
|
||||
occlusion_query_info* ZCULL_control::find_query(vm::addr_t sink_address)
|
||||
|
@ -3225,5 +3255,24 @@ namespace rsx
|
|||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
u32 ZCULL_control::copy_reports_to(u32 start, u32 range, u32 dest)
|
||||
{
|
||||
u32 bytes_to_write = 0;
|
||||
const auto memory_range = utils::address_range::start_length(start, range);
|
||||
for (auto &writer : m_pending_writes)
|
||||
{
|
||||
if (!writer.sink)
|
||||
break;
|
||||
|
||||
if (!writer.forwarder && memory_range.overlaps(writer.sink))
|
||||
{
|
||||
u32 address = (writer.sink - start) + dest;
|
||||
writer.sink_alias.push_back(vm::cast(address));
|
||||
}
|
||||
}
|
||||
|
||||
return bytes_to_write;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue