rsx: Improve GPU resource read prediction

This commit is contained in:
kd-11 2018-06-12 19:22:02 +03:00 committed by kd-11
parent 2afcf369ec
commit d77e62c94e
3 changed files with 75 additions and 20 deletions

View File

@ -72,8 +72,9 @@ namespace rsx
bool synchronized = false; bool synchronized = false;
bool flushed = false; bool flushed = false;
u32 num_writes = 0;
u32 required_writes = 1; u32 num_writes = 0;
std::deque<u32> read_history;
u64 cache_tag = 0; u64 cache_tag = 0;
@ -120,7 +121,12 @@ namespace rsx
void reset_write_statistics() void reset_write_statistics()
{ {
required_writes = num_writes; if (read_history.size() == 16)
{
read_history.pop_back();
}
read_history.push_front(num_writes);
num_writes = 0; num_writes = 0;
} }
@ -196,8 +202,51 @@ namespace rsx
bool writes_likely_completed() const bool writes_likely_completed() const
{ {
// TODO: Move this to the miss statistics block
if (context == rsx::texture_upload_context::blit_engine_dst) if (context == rsx::texture_upload_context::blit_engine_dst)
return num_writes >= required_writes; {
const auto num_records = read_history.size();
if (num_records == 0)
{
return false;
}
else if (num_records == 1)
{
return num_writes >= read_history.front();
}
else
{
const u32 last = read_history.front();
const u32 prev_last = read_history[1];
if (last == prev_last && num_records <= 3)
{
return num_writes >= last;
}
u32 compare = UINT32_MAX;
for (u32 n = 1; n < num_records; n++)
{
if (read_history[n] == last)
{
// Uncertain, but possible
compare = read_history[n - 1];
if (num_records > (n + 1))
{
if (read_history[n + 1] == prev_last)
{
// Confirmed with 2 values
break;
}
}
}
}
return num_writes >= compare;
}
}
return true; return true;
} }
@ -1045,7 +1094,7 @@ namespace rsx
} }
template <typename ...Args> template <typename ...Args>
bool flush_memory_to_cache(u32 memory_address, u32 memory_size, bool skip_synchronized, Args&&... extra) bool flush_memory_to_cache(u32 memory_address, u32 memory_size, bool skip_synchronized, u32 allowed_types_mask, Args&&... extra)
{ {
writer_lock lock(m_cache_mutex); writer_lock lock(m_cache_mutex);
section_storage_type* region = find_flushable_section(memory_address, memory_size); section_storage_type* region = find_flushable_section(memory_address, memory_size);
@ -1057,6 +1106,9 @@ namespace rsx
if (skip_synchronized && region->is_synchronized()) if (skip_synchronized && region->is_synchronized())
return false; return false;
if ((allowed_types_mask & region->get_context()) == 0)
return true;
if (!region->writes_likely_completed()) if (!region->writes_likely_completed())
return true; return true;
@ -1243,23 +1295,26 @@ namespace rsx
//Reset since the data has changed //Reset since the data has changed
//TODO: Keep track of all this information together //TODO: Keep track of all this information together
m_cache_miss_statistics_table[memory_address] = { 0, memory_size, fmt }; m_cache_miss_statistics_table[memory_address] = { 0, memory_size, fmt };
return false;
} }
//Properly synchronized - no miss // By default, blit targets are always to be tested for readback
if (!value.misses) return false; u32 flush_mask = rsx::texture_upload_context::blit_engine_dst;
//Auto flush if this address keeps missing (not properly synchronized) // Auto flush if this address keeps missing (not properly synchronized)
if (value.misses > 16) if (value.misses >= 4)
{ {
//TODO: Determine better way of setting threshold // TODO: Determine better way of setting threshold
if (!flush_memory_to_cache(memory_address, memory_size, true, std::forward<Args>(extras)...)) // Allow all types
value.misses--; flush_mask = 0xFF;
return true;
} }
return false; if (!flush_memory_to_cache(memory_address, memory_size, true, flush_mask, std::forward<Args>(extras)...) &&
value.misses > 0)
{
value.misses--;
}
return true;
} }
void purge_dirty() void purge_dirty()

View File

@ -706,7 +706,7 @@ void GLGSRender::write_buffers()
*/ */
const u32 range = m_surface_info[i].pitch * m_surface_info[i].height; const u32 range = m_surface_info[i].pitch * m_surface_info[i].height;
__glcheck m_gl_texture_cache.flush_memory_to_cache(m_surface_info[i].address, range, true); __glcheck m_gl_texture_cache.flush_memory_to_cache(m_surface_info[i].address, range, true, 0xFF);
} }
}; };
@ -721,6 +721,6 @@ void GLGSRender::write_buffers()
u32 range = m_depth_surface_info.width * m_depth_surface_info.height * 2; u32 range = m_depth_surface_info.width * m_depth_surface_info.height * 2;
if (m_depth_surface_info.depth_format != rsx::surface_depth_format::z16) range *= 2; if (m_depth_surface_info.depth_format != rsx::surface_depth_format::z16) range *= 2;
m_gl_texture_cache.flush_memory_to_cache(m_depth_surface_info.address, range, true); m_gl_texture_cache.flush_memory_to_cache(m_depth_surface_info.address, range, true, 0xFF);
} }
} }

View File

@ -1812,7 +1812,7 @@ void VKGSRender::copy_render_targets_to_dma_location()
if (!m_surface_info[index].pitch) if (!m_surface_info[index].pitch)
continue; continue;
m_texture_cache.flush_memory_to_cache(m_surface_info[index].address, m_surface_info[index].pitch * m_surface_info[index].height, true, m_texture_cache.flush_memory_to_cache(m_surface_info[index].address, m_surface_info[index].pitch * m_surface_info[index].height, true, 0xFF,
*m_current_command_buffer, m_swapchain->get_graphics_queue()); *m_current_command_buffer, m_swapchain->get_graphics_queue());
} }
} }
@ -1821,7 +1821,7 @@ void VKGSRender::copy_render_targets_to_dma_location()
{ {
if (m_depth_surface_info.pitch) if (m_depth_surface_info.pitch)
{ {
m_texture_cache.flush_memory_to_cache(m_depth_surface_info.address, m_depth_surface_info.pitch * m_depth_surface_info.height, true, m_texture_cache.flush_memory_to_cache(m_depth_surface_info.address, m_depth_surface_info.pitch * m_depth_surface_info.height, true, 0xFF,
*m_current_command_buffer, m_swapchain->get_graphics_queue()); *m_current_command_buffer, m_swapchain->get_graphics_queue());
} }
} }