mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-22 18:15:14 +00:00
memory_tracker: Improve locking more on invalidation
This commit is contained in:
parent
212e37b8ec
commit
70b4b981df
@ -136,11 +136,9 @@ void BufferCache::InvalidateMemory(VAddr device_addr, u64 size) {
|
|||||||
if (!IsRegionRegistered(device_addr, size)) {
|
if (!IsRegionRegistered(device_addr, size)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Config::readbacks() && memory_tracker->IsRegionGpuModified(device_addr, size)) {
|
memory_tracker->InvalidateRegion(
|
||||||
ReadMemory(device_addr, size, true);
|
device_addr, size, Config::readbacks(),
|
||||||
} else {
|
[this, device_addr, size] { ReadMemory(device_addr, size, true); });
|
||||||
memory_tracker->MarkRegionAsCpuModified(device_addr, size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferCache::ReadMemory(VAddr device_addr, u64 size, bool is_write) {
|
void BufferCache::ReadMemory(VAddr device_addr, u64 size, bool is_write) {
|
||||||
|
@ -51,16 +51,6 @@ public:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark region as modified from the host GPU
|
|
||||||
void MarkRegionAsGpuModified(VAddr dirty_cpu_addr, u64 query_size) noexcept {
|
|
||||||
IteratePages<false>(dirty_cpu_addr, query_size,
|
|
||||||
[](RegionManager* manager, u64 offset, size_t size) {
|
|
||||||
std::scoped_lock lk{manager->lock};
|
|
||||||
manager->template ChangeRegionState<Type::GPU, true>(
|
|
||||||
manager->GetCpuAddr() + offset, size);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unmark region as modified from the host GPU
|
/// Unmark region as modified from the host GPU
|
||||||
void UnmarkRegionAsGpuModified(VAddr dirty_cpu_addr, u64 query_size) noexcept {
|
void UnmarkRegionAsGpuModified(VAddr dirty_cpu_addr, u64 query_size) noexcept {
|
||||||
IteratePages<false>(dirty_cpu_addr, query_size,
|
IteratePages<false>(dirty_cpu_addr, query_size,
|
||||||
@ -71,6 +61,30 @@ public:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes all protection from a page and ensures GPU data has been flushed if requested
|
||||||
|
void InvalidateRegion(VAddr cpu_addr, u64 size, bool try_flush, auto&& on_flush) noexcept {
|
||||||
|
IteratePages<false>(
|
||||||
|
cpu_addr, size,
|
||||||
|
[try_flush, &on_flush](RegionManager* manager, u64 offset, size_t size) {
|
||||||
|
const bool should_flush = [&] {
|
||||||
|
// Perform both the GPU modification check and CPU state change with the lock
|
||||||
|
// in case we are racing with GPU thread trying to mark the page as GPU
|
||||||
|
// modified. If we need to flush the flush function is going to perform CPU
|
||||||
|
// state change.
|
||||||
|
std::scoped_lock lk{manager->lock};
|
||||||
|
if (try_flush && manager->template IsRegionModified<Type::GPU>(offset, size)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
manager->template ChangeRegionState<Type::CPU, true>(
|
||||||
|
manager->GetCpuAddr() + offset, size);
|
||||||
|
return false;
|
||||||
|
}();
|
||||||
|
if (should_flush) {
|
||||||
|
on_flush();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Call 'func' for each CPU modified range and unmark those pages as CPU modified
|
/// Call 'func' for each CPU modified range and unmark those pages as CPU modified
|
||||||
void ForEachUploadRange(VAddr query_cpu_range, u64 query_size, bool is_written, auto&& func) {
|
void ForEachUploadRange(VAddr query_cpu_range, u64 query_size, bool is_written, auto&& func) {
|
||||||
IteratePages<true>(query_cpu_range, query_size,
|
IteratePages<true>(query_cpu_range, query_size,
|
||||||
|
@ -201,7 +201,8 @@ struct PageManager::Impl {
|
|||||||
RENDERER_TRACE;
|
RENDERER_TRACE;
|
||||||
auto* memory = Core::Memory::Instance();
|
auto* memory = Core::Memory::Instance();
|
||||||
auto& impl = memory->GetAddressSpace();
|
auto& impl = memory->GetAddressSpace();
|
||||||
// ASSERT(perms != Core::MemoryPermission::Write);
|
ASSERT_MSG(perms != Core::MemoryPermission::Write,
|
||||||
|
"Attempted to protect region as write-only which is not a valid permission");
|
||||||
impl.Protect(address, size, perms);
|
impl.Protect(address, size, perms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user