mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
rsx: Fix memory protection
- Fixes hanging when wcb is enabled
This commit is contained in:
parent
479aa91368
commit
86bf61ad35
3 changed files with 35 additions and 10 deletions
|
@ -209,7 +209,7 @@ namespace rsx
|
|||
if (tex.is_dirty()) continue;
|
||||
if (!tex.is_locked()) continue; //flushable sections can be 'clean' but unlocked. TODO: Handle this better
|
||||
|
||||
auto overlapped = tex.overlaps_page(trampled_range, address);
|
||||
auto overlapped = tex.overlaps_page(trampled_range, address, false);
|
||||
if (std::get<0>(overlapped))
|
||||
{
|
||||
auto &new_range = std::get<1>(overlapped);
|
||||
|
@ -277,9 +277,9 @@ namespace rsx
|
|||
auto &tex = range_data.data[i];
|
||||
|
||||
if (tex.is_dirty()) continue;
|
||||
if (!tex.is_flushable()) continue;
|
||||
if (!tex.is_locked()) continue;
|
||||
|
||||
auto overlapped = tex.overlaps_page(trampled_range, address);
|
||||
auto overlapped = tex.overlaps_page(trampled_range, address, true);
|
||||
if (std::get<0>(overlapped))
|
||||
{
|
||||
auto &new_range = std::get<1>(overlapped);
|
||||
|
@ -292,12 +292,20 @@ namespace rsx
|
|||
range_reset = true;
|
||||
}
|
||||
|
||||
//Defer actual flush operation until all affected regions are cleared to prevent recursion
|
||||
if (tex.is_flushable())
|
||||
{
|
||||
sections_to_flush.push_back(&tex);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_unreleased_texture_objects++;
|
||||
tex.set_dirty(true);
|
||||
}
|
||||
|
||||
tex.unprotect();
|
||||
sections_to_flush.push_back(&tex);
|
||||
range_data.remove_one();
|
||||
|
||||
response = true;
|
||||
range_data.remove_one();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -835,7 +835,7 @@ namespace rsx
|
|||
|
||||
const auto window_origin = rsx::method_registers.shader_window_origin();
|
||||
const u32 window_height = rsx::method_registers.shader_window_height();
|
||||
const f32 resolution_scale = (window_height <= g_cfg.video.min_scalable_dimension)? 1.f : rsx::get_resolution_scale();
|
||||
const f32 resolution_scale = (window_height <= (u32)g_cfg.video.min_scalable_dimension)? 1.f : rsx::get_resolution_scale();
|
||||
const f32 wpos_scale = (window_origin == rsx::window_origin::top) ? (1.f / resolution_scale) : (-1.f / resolution_scale);
|
||||
const f32 wpos_bias = (window_origin == rsx::window_origin::top) ? 0.f : window_height;
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ namespace rsx
|
|||
u32 cpu_address_range = 0;
|
||||
|
||||
utils::protection protection = utils::protection::rw;
|
||||
protection_policy guard_policy;
|
||||
|
||||
bool locked = false;
|
||||
bool dirty = false;
|
||||
|
@ -115,6 +116,7 @@ namespace rsx
|
|||
locked_address_range = align(base + length, 4096) - locked_address_base;
|
||||
|
||||
protection = utils::protection::rw;
|
||||
guard_policy = protect_policy;
|
||||
locked = false;
|
||||
}
|
||||
|
||||
|
@ -170,7 +172,7 @@ namespace rsx
|
|||
* Check if the page containing the address tramples this section. Also compares a former trampled page range to compare
|
||||
* If true, returns the range <min, max> with updated invalid range
|
||||
*/
|
||||
std::tuple<bool, std::pair<u32, u32>> overlaps_page(std::pair<u32, u32> old_range, u32 address) const
|
||||
std::tuple<bool, std::pair<u32, u32>> overlaps_page(std::pair<u32, u32> old_range, u32 address, bool full_range_check) const
|
||||
{
|
||||
const u32 page_base = address & ~4095;
|
||||
const u32 page_limit = address + 4096;
|
||||
|
@ -178,10 +180,25 @@ namespace rsx
|
|||
const u32 compare_min = std::min(old_range.first, page_base);
|
||||
const u32 compare_max = std::max(old_range.second, page_limit);
|
||||
|
||||
if (!region_overlaps(locked_address_base, locked_address_base + locked_address_range, compare_min, compare_max))
|
||||
u32 memory_base, memory_range;
|
||||
if (full_range_check && guard_policy != protection_policy::protect_policy_full_range)
|
||||
{
|
||||
//Make sure protection range is full range
|
||||
memory_base = (cpu_address_base & ~4095);
|
||||
memory_range = align(cpu_address_base + cpu_address_range, 4096u) - memory_base;
|
||||
}
|
||||
else
|
||||
{
|
||||
memory_base = locked_address_base;
|
||||
memory_range = locked_address_range;
|
||||
}
|
||||
|
||||
if (!region_overlaps(memory_base, memory_base + memory_range, compare_min, compare_max))
|
||||
return std::make_tuple(false, old_range);
|
||||
|
||||
return std::make_tuple(true, get_min_max(std::make_pair(compare_min, compare_max)));
|
||||
const u32 _min = std::min(memory_base, compare_min);
|
||||
const u32 _max = std::max(memory_base + memory_range, compare_max);
|
||||
return std::make_tuple(true, std::make_pair(_min, _max));
|
||||
}
|
||||
|
||||
bool is_locked() const
|
||||
|
|
Loading…
Add table
Reference in a new issue