1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-23 03:02:53 +01:00

rsx/surface_store: More aggressive tag sampling

- Use a 5-point tap with an X pattern across the target's memory space to reduce chances of false positives
- TODO: Potential false positives identified, requires some minor
restructuring of surface_store
This commit is contained in:
kd-11 2019-02-25 22:30:20 +03:00 committed by kd-11
parent 3a071a9c07
commit fa628f0ac4

View File

@ -93,8 +93,7 @@ namespace rsx
struct render_target_descriptor struct render_target_descriptor
{ {
u64 last_use_tag = 0; // tag indicating when this block was last confirmed to have been written to u64 last_use_tag = 0; // tag indicating when this block was last confirmed to have been written to
u32 memory_tag_address = 0u; // memory address of the start of the ROP block std::array<std::pair<u32, u64>, 5> memory_tag_samples;
u64 memory_tag_sample = 0ull; // memory sample taken at the memory_tag_address for change testing
bool dirty = false; bool dirty = false;
image_storage_type old_contents = nullptr; image_storage_type old_contents = nullptr;
@ -130,17 +129,34 @@ namespace rsx
LOG_TODO(RSX, "Resource used before memory initialization"); LOG_TODO(RSX, "Resource used before memory initialization");
} }
return (memory_tag_sample == *vm::get_super_ptr<u64>(memory_tag_address)); // Tags are tested in an X pattern
for (const auto &tag : memory_tag_samples)
{
if (tag.second != *reinterpret_cast<u64*>(vm::g_sudo_addr + tag.first))
return false;
}
return true;
} }
void queue_tag(u32 address) void queue_tag(u32 address)
{ {
memory_tag_address = address; const u32 pitch = get_native_pitch();
const u32 memory_length = pitch * get_surface_height();
memory_tag_samples[0].first = address; // Top left
memory_tag_samples[1].first = address + memory_length - 4; // Bottom right
memory_tag_samples[2].first = address + pitch; // Top right
memory_tag_samples[3].first = address + (memory_length / 2); // Center
memory_tag_samples[4].first = address + memory_length - pitch; // Bottom left
} }
void sync_tag() void sync_tag()
{ {
memory_tag_sample = *vm::get_super_ptr<u64>(memory_tag_address); for (auto &tag : memory_tag_samples)
{
tag.second = *reinterpret_cast<u64*>(vm::g_sudo_addr + tag.first);
}
} }
void on_write(u64 write_tag = 0) void on_write(u64 write_tag = 0)