mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-08-17 15:59:50 +00:00
rsx: Improve texture cache read speculation
This commit is contained in:
parent
c3d75e208f
commit
24f4c92759
4 changed files with 48 additions and 41 deletions
|
@ -9,10 +9,10 @@ namespace rsx
|
||||||
{
|
{
|
||||||
enum texture_upload_context
|
enum texture_upload_context
|
||||||
{
|
{
|
||||||
shader_read = 0,
|
shader_read = 1,
|
||||||
blit_engine_src = 1,
|
blit_engine_src = 2,
|
||||||
blit_engine_dst = 2,
|
blit_engine_dst = 4,
|
||||||
framebuffer_storage = 3
|
framebuffer_storage = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
enum texture_colorspace
|
enum texture_colorspace
|
||||||
|
|
|
@ -204,8 +204,6 @@ namespace rsx
|
||||||
bool writes_likely_completed() const
|
bool writes_likely_completed() const
|
||||||
{
|
{
|
||||||
// TODO: Move this to the miss statistics block
|
// TODO: Move this to the miss statistics block
|
||||||
if (context == rsx::texture_upload_context::blit_engine_dst)
|
|
||||||
{
|
|
||||||
const auto num_records = read_history.size();
|
const auto num_records = read_history.size();
|
||||||
|
|
||||||
if (num_records == 0)
|
if (num_records == 0)
|
||||||
|
@ -249,9 +247,6 @@ namespace rsx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reprotect(utils::protection prot, const std::pair<u32, u32>& range)
|
void reprotect(utils::protection prot, const std::pair<u32, u32>& range)
|
||||||
{
|
{
|
||||||
//Reset properties and protect again
|
//Reset properties and protect again
|
||||||
|
@ -473,8 +468,10 @@ namespace rsx
|
||||||
std::atomic<u32> m_texture_memory_in_use = { 0 };
|
std::atomic<u32> m_texture_memory_in_use = { 0 };
|
||||||
|
|
||||||
//Other statistics
|
//Other statistics
|
||||||
|
const u32 m_cache_miss_threshold = 8; // How many times an address can miss speculative writing before it is considered high priority
|
||||||
std::atomic<u32> m_num_flush_requests = { 0 };
|
std::atomic<u32> m_num_flush_requests = { 0 };
|
||||||
std::atomic<u32> m_num_cache_misses = { 0 };
|
std::atomic<u32> m_num_cache_misses = { 0 };
|
||||||
|
std::atomic<u32> m_num_cache_speculative_writes = { 0 };
|
||||||
std::atomic<u32> m_num_cache_mispredictions = { 0 };
|
std::atomic<u32> m_num_cache_mispredictions = { 0 };
|
||||||
|
|
||||||
/* Helpers */
|
/* Helpers */
|
||||||
|
@ -729,7 +726,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
if (obj.first->get_memory_read_flags() == rsx::memory_read_flags::flush_always)
|
if (obj.first->get_memory_read_flags() == rsx::memory_read_flags::flush_always)
|
||||||
{
|
{
|
||||||
// This region is set to always read from itself (unavoi
|
// This region is set to always read from itself (unavoidable hard sync)
|
||||||
const auto ROP_timestamp = rsx::get_current_renderer()->ROP_sync_timestamp;
|
const auto ROP_timestamp = rsx::get_current_renderer()->ROP_sync_timestamp;
|
||||||
if (obj.first->is_synchronized() && ROP_timestamp > obj.first->get_sync_timestamp())
|
if (obj.first->is_synchronized() && ROP_timestamp > obj.first->get_sync_timestamp())
|
||||||
{
|
{
|
||||||
|
@ -1072,6 +1069,7 @@ namespace rsx
|
||||||
region.set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
region.set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
||||||
region.set_image_type(rsx::texture_dimension_extended::texture_dimension_2d);
|
region.set_image_type(rsx::texture_dimension_extended::texture_dimension_2d);
|
||||||
region.set_memory_read_flags(memory_read_flags::flush_always);
|
region.set_memory_read_flags(memory_read_flags::flush_always);
|
||||||
|
region.touch();
|
||||||
|
|
||||||
m_flush_always_cache[memory_address] = memory_size;
|
m_flush_always_cache[memory_address] = memory_size;
|
||||||
|
|
||||||
|
@ -1151,6 +1149,7 @@ namespace rsx
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
region->copy_texture(false, std::forward<Args>(extra)...);
|
region->copy_texture(false, std::forward<Args>(extra)...);
|
||||||
|
m_num_cache_speculative_writes++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1256,7 +1255,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
if (tex->get_memory_read_flags() == rsx::memory_read_flags::flush_always)
|
if (tex->get_memory_read_flags() == rsx::memory_read_flags::flush_always)
|
||||||
{
|
{
|
||||||
// This region is set to always read from itself (unavoi
|
// This region is set to always read from itself (unavoidable hard sync)
|
||||||
const auto ROP_timestamp = rsx::get_current_renderer()->ROP_sync_timestamp;
|
const auto ROP_timestamp = rsx::get_current_renderer()->ROP_sync_timestamp;
|
||||||
if (tex->is_synchronized() && ROP_timestamp > tex->get_sync_timestamp())
|
if (tex->is_synchronized() && ROP_timestamp > tex->get_sync_timestamp())
|
||||||
{
|
{
|
||||||
|
@ -1351,7 +1350,7 @@ namespace rsx
|
||||||
u32 flush_mask = rsx::texture_upload_context::blit_engine_dst;
|
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 >= 4)
|
if (value.misses >= m_cache_miss_threshold)
|
||||||
{
|
{
|
||||||
// Disable prediction if memory is flagged as flush_always
|
// Disable prediction if memory is flagged as flush_always
|
||||||
if (m_flush_always_cache.find(memory_address) == m_flush_always_cache.end())
|
if (m_flush_always_cache.find(memory_address) == m_flush_always_cache.end())
|
||||||
|
@ -2485,6 +2484,7 @@ namespace rsx
|
||||||
m_num_flush_requests.store(0u);
|
m_num_flush_requests.store(0u);
|
||||||
m_num_cache_misses.store(0u);
|
m_num_cache_misses.store(0u);
|
||||||
m_num_cache_mispredictions.store(0u);
|
m_num_cache_mispredictions.store(0u);
|
||||||
|
m_num_cache_speculative_writes.store(0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const u32 get_unreleased_textures_count() const
|
virtual const u32 get_unreleased_textures_count() const
|
||||||
|
@ -2507,6 +2507,11 @@ namespace rsx
|
||||||
return m_num_cache_mispredictions;
|
return m_num_cache_mispredictions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual u32 get_num_cache_speculative_writes() const
|
||||||
|
{
|
||||||
|
return m_num_cache_speculative_writes;
|
||||||
|
}
|
||||||
|
|
||||||
virtual f32 get_cache_miss_ratio() const
|
virtual f32 get_cache_miss_ratio() const
|
||||||
{
|
{
|
||||||
const auto num_flushes = m_num_flush_requests.load();
|
const auto num_flushes = m_num_flush_requests.load();
|
||||||
|
|
|
@ -1518,10 +1518,11 @@ void GLGSRender::flip(int buffer)
|
||||||
const auto texture_memory_size = m_gl_texture_cache.get_texture_memory_in_use() / (1024 * 1024);
|
const auto texture_memory_size = m_gl_texture_cache.get_texture_memory_in_use() / (1024 * 1024);
|
||||||
const auto num_flushes = m_gl_texture_cache.get_num_flush_requests();
|
const auto num_flushes = m_gl_texture_cache.get_num_flush_requests();
|
||||||
const auto num_mispredict = m_gl_texture_cache.get_num_cache_mispredictions();
|
const auto num_mispredict = m_gl_texture_cache.get_num_cache_mispredictions();
|
||||||
|
const auto num_speculate = m_gl_texture_cache.get_num_cache_speculative_writes();
|
||||||
const auto cache_miss_ratio = (u32)ceil(m_gl_texture_cache.get_cache_miss_ratio() * 100);
|
const auto cache_miss_ratio = (u32)ceil(m_gl_texture_cache.get_cache_miss_ratio() * 100);
|
||||||
m_text_printer.print_text(0, 126, m_frame->client_width(), m_frame->client_height(), "Unreleased textures: " + std::to_string(num_dirty_textures));
|
m_text_printer.print_text(0, 126, m_frame->client_width(), m_frame->client_height(), "Unreleased textures: " + std::to_string(num_dirty_textures));
|
||||||
m_text_printer.print_text(0, 144, m_frame->client_width(), m_frame->client_height(), "Texture memory: " + std::to_string(texture_memory_size) + "M");
|
m_text_printer.print_text(0, 144, m_frame->client_width(), m_frame->client_height(), "Texture memory: " + std::to_string(texture_memory_size) + "M");
|
||||||
m_text_printer.print_text(0, 162, m_frame->client_width(), m_frame->client_height(), fmt::format("Flush requests: %d (%d%% hard faults, %d mispredictions)", num_flushes, cache_miss_ratio, num_mispredict));
|
m_text_printer.print_text(0, 162, m_frame->client_width(), m_frame->client_height(), fmt::format("Flush requests: %d (%d%% hard faults, %d misprediction(s), %d speculation(s))", num_flushes, cache_miss_ratio, num_mispredict, num_speculate));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_frame->flip(m_context);
|
m_frame->flip(m_context);
|
||||||
|
|
|
@ -3241,11 +3241,12 @@ void VKGSRender::flip(int buffer)
|
||||||
const auto tmp_texture_memory_size = m_texture_cache.get_temporary_memory_in_use() / (1024 * 1024);
|
const auto tmp_texture_memory_size = m_texture_cache.get_temporary_memory_in_use() / (1024 * 1024);
|
||||||
const auto num_flushes = m_texture_cache.get_num_flush_requests();
|
const auto num_flushes = m_texture_cache.get_num_flush_requests();
|
||||||
const auto num_mispredict = m_texture_cache.get_num_cache_mispredictions();
|
const auto num_mispredict = m_texture_cache.get_num_cache_mispredictions();
|
||||||
|
const auto num_speculate = m_texture_cache.get_num_cache_speculative_writes();
|
||||||
const auto cache_miss_ratio = (u32)ceil(m_texture_cache.get_cache_miss_ratio() * 100);
|
const auto cache_miss_ratio = (u32)ceil(m_texture_cache.get_cache_miss_ratio() * 100);
|
||||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 144, direct_fbo->width(), direct_fbo->height(), "Unreleased textures: " + std::to_string(num_dirty_textures));
|
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 144, direct_fbo->width(), direct_fbo->height(), "Unreleased textures: " + std::to_string(num_dirty_textures));
|
||||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 162, direct_fbo->width(), direct_fbo->height(), "Texture cache memory: " + std::to_string(texture_memory_size) + "M");
|
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 162, direct_fbo->width(), direct_fbo->height(), "Texture cache memory: " + std::to_string(texture_memory_size) + "M");
|
||||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 180, direct_fbo->width(), direct_fbo->height(), "Temporary texture memory: " + std::to_string(tmp_texture_memory_size) + "M");
|
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 180, direct_fbo->width(), direct_fbo->height(), "Temporary texture memory: " + std::to_string(tmp_texture_memory_size) + "M");
|
||||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 198, direct_fbo->width(), direct_fbo->height(), fmt::format("Flush requests: %d (%d%% hard faults, %d mispredictions)", num_flushes, cache_miss_ratio, num_mispredict));
|
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 198, direct_fbo->width(), direct_fbo->height(), fmt::format("Flush requests: %d (%d%% hard faults, %d misprediction(s), %d speculation(s))", num_flushes, cache_miss_ratio, num_mispredict, num_speculate));
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::change_image_layout(*m_current_command_buffer, target_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, present_layout, subres);
|
vk::change_image_layout(*m_current_command_buffer, target_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, present_layout, subres);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue