diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index cd4531028a..3410c9659f 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -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(); } } diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 6400e4c3eb..b5e94d65a8 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -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; diff --git a/rpcs3/Emu/RSX/rsx_cache.h b/rpcs3/Emu/RSX/rsx_cache.h index 84e66a6825..4c04573f71 100644 --- a/rpcs3/Emu/RSX/rsx_cache.h +++ b/rpcs3/Emu/RSX/rsx_cache.h @@ -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 with updated invalid range */ - std::tuple> overlaps_page(std::pair old_range, u32 address) const + std::tuple> overlaps_page(std::pair 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