mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 19:45:20 +00:00
rsx: Improve separate treatment of write exceptions vs read exceptions
- Optimizes search functionality and avoids thrashing valid sections
This commit is contained in:
parent
5fc36d64b6
commit
e9f293f522
5 changed files with 27 additions and 25 deletions
|
@ -192,6 +192,7 @@ namespace rsx
|
|||
std::vector<std::pair<section_storage_type*, ranged_storage*>> result;
|
||||
u64 cache_tag = get_system_time();
|
||||
u32 last_dirty_block = UINT32_MAX;
|
||||
|
||||
std::pair<u32, u32> trampled_range = std::make_pair(address, address + range);
|
||||
|
||||
for (auto It = m_cache.begin(); It != m_cache.end(); It++)
|
||||
|
@ -250,7 +251,7 @@ namespace rsx
|
|||
//2. A vector of all sections that should be flushed if the caller did not set the allow_flush method. That way the caller can make preparations on how to deal with sections that require flushing
|
||||
// Note that the sections will be unlocked regardless of the allow_flush flag
|
||||
template <typename ...Args>
|
||||
std::pair<bool, std::vector<section_storage_type*>> invalidate_range_impl_base(u32 address, u32 range, bool discard_only, bool rebuild_cache, bool allow_flush, Args&&... extras)
|
||||
std::pair<bool, std::vector<section_storage_type*>> invalidate_range_impl_base(u32 address, u32 range, bool is_writing, bool discard_only, bool rebuild_cache, bool allow_flush, Args&&... extras)
|
||||
{
|
||||
auto trampled_set = get_intersecting_set(address, range, allow_flush);
|
||||
|
||||
|
@ -260,6 +261,9 @@ namespace rsx
|
|||
const auto to_reprotect = std::remove_if(trampled_set.begin(), trampled_set.end(),
|
||||
[&](const std::pair<section_storage_type*, ranged_storage*>& obj)
|
||||
{
|
||||
if (!is_writing && obj.first->get_protection() != utils::protection::no)
|
||||
return true;
|
||||
|
||||
if (!rebuild_cache && !obj.first->is_flushable())
|
||||
return false;
|
||||
|
||||
|
@ -300,7 +304,10 @@ namespace rsx
|
|||
obj.first->set_dirty(false);
|
||||
}
|
||||
|
||||
trampled_set.erase(to_reprotect, trampled_set.end());
|
||||
if (discard_only)
|
||||
return{ true, {} };
|
||||
|
||||
//trampled_set.erase(to_reprotect, trampled_set.end());
|
||||
|
||||
if (allow_flush)
|
||||
{
|
||||
|
@ -324,9 +331,9 @@ namespace rsx
|
|||
}
|
||||
|
||||
template <typename ...Args>
|
||||
std::pair<bool, std::vector<section_storage_type*>> invalidate_range_impl(u32 address, u32 range, bool discard, bool allow_flush, Args&&... extras)
|
||||
std::pair<bool, std::vector<section_storage_type*>> invalidate_range_impl(u32 address, u32 range, bool is_writing, bool discard, bool allow_flush, Args&&... extras)
|
||||
{
|
||||
return invalidate_range_impl_base(address, range, discard, false, allow_flush, std::forward<Args>(extras)...);
|
||||
return invalidate_range_impl_base(address, range, is_writing, discard, false, allow_flush, std::forward<Args>(extras)...);
|
||||
}
|
||||
|
||||
bool is_hw_blit_engine_compatible(const u32 format) const
|
||||
|
@ -565,19 +572,13 @@ namespace rsx
|
|||
}
|
||||
|
||||
template <typename ...Args>
|
||||
std::pair<bool, std::vector<section_storage_type*>> invalidate_address(u32 address, bool allow_flush, Args&&... extras)
|
||||
std::pair<bool, std::vector<section_storage_type*>> invalidate_address(u32 address, bool is_writing, bool allow_flush, Args&&... extras)
|
||||
{
|
||||
return invalidate_range(address, 4096 - (address & 4095), false, allow_flush, std::forward<Args>(extras)...);
|
||||
return invalidate_range(address, 4096 - (address & 4095), is_writing, false, allow_flush, std::forward<Args>(extras)...);
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
std::pair<bool, std::vector<section_storage_type*>> flush_address(u32 address, Args&&... extras)
|
||||
{
|
||||
return invalidate_range(address, 4096 - (address & 4095), false, true, std::forward<Args>(extras)...);
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
std::pair<bool, std::vector<section_storage_type*>> invalidate_range(u32 address, u32 range, bool discard, bool allow_flush, Args&&... extras)
|
||||
std::pair<bool, std::vector<section_storage_type*>> invalidate_range(u32 address, u32 range, bool is_writing, bool discard, bool allow_flush, Args&&... extras)
|
||||
{
|
||||
std::pair<u32, u32> trampled_range = std::make_pair(address, address + range);
|
||||
|
||||
|
@ -591,7 +592,7 @@ namespace rsx
|
|||
}
|
||||
|
||||
writer_lock lock(m_cache_mutex);
|
||||
return invalidate_range_impl(address, range, discard, allow_flush, std::forward<Args>(extras)...);
|
||||
return invalidate_range_impl(address, range, is_writing, discard, allow_flush, std::forward<Args>(extras)...);
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
|
@ -908,7 +909,7 @@ namespace rsx
|
|||
auto subresources_layout = get_subresources_layout(tex);
|
||||
auto remap_vector = tex.decoded_remap();
|
||||
|
||||
invalidate_range_impl(texaddr, tex_size, false, true, std::forward<Args>(extras)...);
|
||||
invalidate_range_impl(texaddr, tex_size, false, false, true, std::forward<Args>(extras)...);
|
||||
|
||||
m_texture_memory_in_use += (tex_pitch * tex_height);
|
||||
return upload_image_from_cpu(cmd, texaddr, tex_width, tex_height, depth, tex.get_exact_mipmap_count(), tex_pitch, format,
|
||||
|
@ -1001,8 +1002,8 @@ namespace rsx
|
|||
const u32 memcpy_bytes_length = dst.clip_width * bpp * dst.clip_height;
|
||||
|
||||
lock.upgrade();
|
||||
invalidate_range_impl(src_address, memcpy_bytes_length, false, true, std::forward<Args>(extras)...);
|
||||
invalidate_range_impl(dst_address, memcpy_bytes_length, false, true, std::forward<Args>(extras)...);
|
||||
invalidate_range_impl(src_address, memcpy_bytes_length, false, false, true, std::forward<Args>(extras)...);
|
||||
invalidate_range_impl(dst_address, memcpy_bytes_length, true, false, true, std::forward<Args>(extras)...);
|
||||
memcpy(dst.pixels, src.pixels, memcpy_bytes_length);
|
||||
return true;
|
||||
}
|
||||
|
@ -1104,7 +1105,7 @@ namespace rsx
|
|||
{
|
||||
lock.upgrade();
|
||||
|
||||
invalidate_range_impl(src_address, src.pitch * src.slice_h, false, true, std::forward<Args>(extras)...);
|
||||
invalidate_range_impl(src_address, src.pitch * src.slice_h, false, false, true, std::forward<Args>(extras)...);
|
||||
|
||||
const u16 pitch_in_block = src_is_argb8 ? src.pitch >> 2 : src.pitch >> 1;
|
||||
std::vector<rsx_subresource_layout> subresource_layout;
|
||||
|
@ -1176,7 +1177,7 @@ namespace rsx
|
|||
if (format_mismatch)
|
||||
{
|
||||
lock.upgrade();
|
||||
invalidate_range_impl(cached_dest->get_section_base(), cached_dest->get_section_size(), false, true, std::forward<Args>(extras)...);
|
||||
invalidate_range_impl(cached_dest->get_section_base(), cached_dest->get_section_size(), true, false, true, std::forward<Args>(extras)...);
|
||||
|
||||
dest_texture = 0;
|
||||
cached_dest = nullptr;
|
||||
|
@ -1184,7 +1185,7 @@ namespace rsx
|
|||
else if (invalidate_dst_range)
|
||||
{
|
||||
lock.upgrade();
|
||||
invalidate_range_impl(dst_address, dst.pitch * dst.height, false, true, std::forward<Args>(extras)...);
|
||||
invalidate_range_impl(dst_address, dst.pitch * dst.height, true, false, true, std::forward<Args>(extras)...);
|
||||
}
|
||||
|
||||
//Validate clipping region
|
||||
|
|
|
@ -1210,7 +1210,7 @@ u64 GLGSRender::timestamp() const
|
|||
bool GLGSRender::on_access_violation(u32 address, bool is_writing)
|
||||
{
|
||||
bool can_flush = (std::this_thread::get_id() == m_thread_id);
|
||||
auto result = m_gl_texture_cache.invalidate_address(address, can_flush);
|
||||
auto result = m_gl_texture_cache.invalidate_address(address, is_writing, can_flush);
|
||||
|
||||
if (!result.first)
|
||||
return false;
|
||||
|
@ -1235,7 +1235,7 @@ bool GLGSRender::on_access_violation(u32 address, bool is_writing)
|
|||
void GLGSRender::on_notify_memory_unmapped(u32 address_base, u32 size)
|
||||
{
|
||||
//Discard all memory in that range without bothering with writeback (Force it for strict?)
|
||||
if (std::get<0>(m_gl_texture_cache.invalidate_range(address_base, size, true, false)))
|
||||
if (std::get<0>(m_gl_texture_cache.invalidate_range(address_base, size, true, true, false)))
|
||||
m_gl_texture_cache.purge_dirty();
|
||||
}
|
||||
|
||||
|
|
|
@ -403,7 +403,7 @@ void GLGSRender::read_buffers()
|
|||
}
|
||||
else
|
||||
{
|
||||
m_gl_texture_cache.invalidate_range(texaddr, range, false, true);
|
||||
m_gl_texture_cache.invalidate_range(texaddr, range, false, false, true);
|
||||
|
||||
std::unique_ptr<u8[]> buffer(new u8[pitch * height]);
|
||||
color_buffer.read(buffer.get(), width, height, pitch);
|
||||
|
|
|
@ -473,6 +473,7 @@ namespace gl
|
|||
|
||||
glBindTexture(target, id);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, mipmaps - 1);
|
||||
|
||||
|
|
|
@ -740,7 +740,7 @@ VKGSRender::~VKGSRender()
|
|||
bool VKGSRender::on_access_violation(u32 address, bool is_writing)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_secondary_cb_guard);
|
||||
auto result = m_texture_cache.invalidate_address(address, false, *m_device, m_secondary_command_buffer, m_memory_type_mapping, m_swap_chain->get_present_queue());
|
||||
auto result = m_texture_cache.invalidate_address(address, is_writing, false, *m_device, m_secondary_command_buffer, m_memory_type_mapping, m_swap_chain->get_present_queue());
|
||||
|
||||
if (!result.first)
|
||||
return false;
|
||||
|
@ -831,7 +831,7 @@ bool VKGSRender::on_access_violation(u32 address, bool is_writing)
|
|||
void VKGSRender::on_notify_memory_unmapped(u32 address_base, u32 size)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_secondary_cb_guard);
|
||||
if (std::get<0>(m_texture_cache.invalidate_range(address_base, size, false, false,
|
||||
if (std::get<0>(m_texture_cache.invalidate_range(address_base, size, true, true, false,
|
||||
*m_device, m_secondary_command_buffer, m_memory_type_mapping, m_swap_chain->get_present_queue())))
|
||||
{
|
||||
m_texture_cache.purge_dirty();
|
||||
|
|
Loading…
Add table
Reference in a new issue