Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rsx: Fix duplicate data removal checks in surface cache #11497

Merged
merged 2 commits into from
Feb 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 40 additions & 22 deletions rpcs3/Emu/RSX/Common/surface_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -660,48 +660,61 @@ namespace rsx

void remove_duplicates_fallback_impl(std::vector<surface_overlap_info>& sections, const rsx::address_range& range)
{
// Originally used to debug crashes but this function breaks often enough that I'll leave the checks in for now.
// Safe to remove after some time if no asserts are reported.
constexpr u32 overrun_cookie_value = 0xCAFEBABEu;

// Generic painter's algorithm to detect obsolete sections
ensure(range.length() < 64 * 0x100000);
std::vector<u8> marker(range.length(), 0);
std::vector<u8> marker(range.length() + sizeof(overrun_cookie_value), 0);

// Tag end
u32* overrun_test_ptr = utils::bless<u32>(marker.data() + range.length());
*overrun_test_ptr = overrun_cookie_value;

auto compare_and_tag_row = [&](u32 offset, u32 length) -> bool
auto compare_and_tag_row = [&](const u32 offset, u32 length) -> bool
{
bool valid = false;
for (u32 i = 0; i < (length / 8); ++i, offset += 8, length -= 8)
u64 mask = 0;
u8* dst_ptr = marker.data() + offset;

while (length >= 8)
{
auto dest = reinterpret_cast<u64*>(marker.data() + offset);
valid |= (*dest != umax);
*dest = umax;
auto& value = *utils::bless<u64>(dst_ptr);
mask |= (~value); // If the value is not all 1s, set valid to true
value = umax;

dst_ptr += 8;
length -= 8;
}

if (length >= 4)
{
auto dest = reinterpret_cast<u32*>(marker.data() + offset);
valid |= (*dest != umax);
*dest = umax;
auto& value = *utils::bless<u32>(dst_ptr);
mask |= (~value);
value = umax;

offset += 4;
dst_ptr += 4;
length -= 4;
}

if (length >= 2)
{
auto dest = reinterpret_cast<u16*>(marker.data() + offset);
valid |= (*dest != umax);
*dest = umax;
auto& value = *utils::bless<u16>(dst_ptr);
mask |= (~value);
value = umax;

offset += 2;
dst_ptr += 2;
length -= 2;
}

if (length)
{
auto dest = (marker.data() + offset);
valid |= (*dest != umax);
*dest = umax;
auto& value = *dst_ptr;
mask |= (~value);
value = umax;
}

return valid;
return !!mask;
};

for (auto it = sections.crbegin(); it != sections.crend(); ++it)
Expand Down Expand Up @@ -750,17 +763,22 @@ namespace rsx
num_rows = utils::aligned_div(this_range.length(), rsx_pitch);
}

for (u32 row = 0, offset = (this_range.start - range.start); row < num_rows; ++row, offset += rsx_pitch)
for (u32 row = 0, offset = (this_range.start - range.start), section_len = (this_range.end - range.start + 1);
row < num_rows;
++row, offset += rsx_pitch)
{
valid |= compare_and_tag_row(offset, std::min<u32>(native_pitch, (this_range.end - offset + 1)));
valid |= compare_and_tag_row(offset, std::min<u32>(native_pitch, (section_len - offset)));
}

if (!valid)
{
rsx_log.error("Stale surface at address 0x%x will be deleted", it->base_address);
rsx_log.warning("Stale surface at address 0x%x will be deleted", it->base_address);
invalidate_surface_address(it->base_address, it->is_depth);
}
}

// Verify no OOB
ensure(*overrun_test_ptr == overrun_cookie_value);
}

protected:
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/RSX/Common/texture_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -1928,7 +1928,7 @@ namespace rsx
if (const auto coverage_ratio = (coverage_size * 100ull) / memory_range.length();
coverage_ratio > max_overdraw_ratio)
{
rsx_log.error("[Performance warning] Texture gather routine encountered too many objects! Operation=%d, Mipmaps=%d, Depth=%d, Sections=%zu, Ratio=%llu%",
rsx_log.warning("[Performance warning] Texture gather routine encountered too many objects! Operation=%d, Mipmaps=%d, Depth=%d, Sections=%zu, Ratio=%llu%",
static_cast<int>(result.external_subresource_desc.op), attr.mipmaps, attr.depth, overlapping_fbos.size(), coverage_ratio);
m_rtts.check_for_duplicates(overlapping_fbos, memory_range);
}
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/RSX/VK/VKDraw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ void VKGSRender::emit_geometry(u32 sub_index)
if (occlusion_id == umax)
{
// Force flush
rsx_log.error("[Performance Warning] Out of free occlusion slots. Forcing hard sync.");
rsx_log.warning("[Performance Warning] Out of free occlusion slots. Forcing hard sync.");
ZCULL_control::sync(this);

occlusion_id = m_occlusion_query_manager->allocate_query(*m_current_command_buffer);
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/RSX/VK/VKGSRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2473,7 +2473,7 @@ void VKGSRender::get_occlusion_query_result(rsx::reports::occlusion_query_info*
m_flush_requests.clear_pending_flag();
}

rsx_log.error("[Performance warning] Unexpected ZCULL read caused a hard sync");
rsx_log.warning("[Performance warning] Unexpected ZCULL read caused a hard sync");
busy_wait();
}

Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/RSX/VK/VKTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ namespace vk
{
if (src->format_class() == dst->format_class())
{
rsx_log.error("[Performance warning] Image copy requested incorrectly for matching formats.");
rsx_log.warning("[Performance warning] Image copy requested incorrectly for matching formats.");
copy_image(cmd, src, dst, src_rect, dst_rect, mipmaps, src_transfer_mask, dst_transfer_mask);
return;
}
Expand Down Expand Up @@ -417,7 +417,7 @@ namespace vk
src->format() != dst->format())
{
// Copying between two depth formats must match exactly or crashes will happen
rsx_log.error("[Performance warning] Image copy was requested incorrectly for mismatched depth formats");
rsx_log.warning("[Performance warning] Image copy was requested incorrectly for mismatched depth formats");
copy_image_typeless(cmd, src, dst, src_rect, dst_rect, mipmaps);
return;
}
Expand Down