mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
renderer: invalidate buffers on memory unmap
This commit is contained in:
@@ -296,71 +296,6 @@ void BufferCache::ReadMemoryOnGpu(uint64_t vaddr, uint64_t size, bool is_write)
|
||||
}
|
||||
}
|
||||
|
||||
void BufferCache::UnmapMemory(uint64_t vaddr, uint64_t size) {
|
||||
if (vaddr == 0 || size == 0 || size > UINT64_MAX - vaddr) {
|
||||
EXIT("BufferCache: invalid unmap range\n");
|
||||
}
|
||||
std::vector<DownloadCopy> copies;
|
||||
std::vector<std::pair<uint64_t, uint64_t>> modified_buffers;
|
||||
std::vector<std::pair<uint64_t, uint64_t>> retired_buffers;
|
||||
for (const auto& [begin, id]: m_buffers) {
|
||||
const auto& buffer = m_slot_buffers[id];
|
||||
if (vaddr < begin + buffer.Size() && begin < vaddr + size) {
|
||||
retired_buffers.emplace_back(begin, buffer.Size());
|
||||
}
|
||||
}
|
||||
for (const auto& [begin, id]: m_buffers) {
|
||||
const auto& buffer = m_slot_buffers[id];
|
||||
if (vaddr >= begin + buffer.Size() || begin >= vaddr + size ||
|
||||
!m_memory_tracker.IsRegionGpuModified(begin, buffer.Size())) {
|
||||
continue;
|
||||
}
|
||||
if (!m_gpu_modified_ranges.Intersects(begin, buffer.Size())) {
|
||||
EXIT("BufferCache: GPU-modified buffer has no dirty ranges\n");
|
||||
}
|
||||
modified_buffers.emplace_back(begin, buffer.Size());
|
||||
}
|
||||
for (const auto& [begin, bytes]: modified_buffers) {
|
||||
auto owner = m_buffers.find(begin);
|
||||
if (owner == m_buffers.end() || m_slot_buffers[owner->second].Size() != bytes) {
|
||||
EXIT("BufferCache: unmap owner changed during collection\n");
|
||||
}
|
||||
auto& buffer = m_slot_buffers[owner->second];
|
||||
m_memory_tracker.ForEachDownloadRange<false>(
|
||||
begin, buffer.Size(),
|
||||
[&](uint64_t address, uint64_t bytes) noexcept {
|
||||
m_memory_tracker.ValidateGpuDirtyPages(m_gpu_modified_ranges, address, bytes,
|
||||
"unmap");
|
||||
},
|
||||
[&](uint64_t address, uint64_t bytes) noexcept {
|
||||
for (const auto& range: m_gpu_modified_ranges.Intersections(address, bytes)) {
|
||||
copies.push_back({&buffer, range.address - begin, range.address, range.size});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!copies.empty()) {
|
||||
DownloadBufferMemory(copies);
|
||||
}
|
||||
for (const auto& [begin, bytes]: modified_buffers) {
|
||||
m_gpu_modified_ranges.Subtract(begin, bytes);
|
||||
m_memory_tracker.UnmarkRegionAsGpuModified(begin, bytes);
|
||||
}
|
||||
for (const auto& [begin, bytes]: retired_buffers) {
|
||||
m_memory_tracker.MarkRegionAsCpuModified(begin, bytes);
|
||||
}
|
||||
if (m_gpu_modified_ranges.Intersects(vaddr, size)) {
|
||||
EXIT("BufferCache: unmap retained dirty byte ranges\n");
|
||||
}
|
||||
m_memory_tracker.UntrackMemory(vaddr, size);
|
||||
for (const auto& [begin, bytes]: retired_buffers) {
|
||||
(void)bytes;
|
||||
const auto found = m_buffers.find(begin);
|
||||
if (found != m_buffers.end()) {
|
||||
DeleteBuffer(found->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BufferId BufferCache::FindBuffer(uint64_t vaddr, uint64_t size) {
|
||||
if (vaddr == 0) {
|
||||
return NULL_BUFFER_ID;
|
||||
|
||||
@@ -35,7 +35,6 @@ public:
|
||||
|
||||
void InvalidateMemory(uint64_t vaddr, uint64_t size);
|
||||
void ReadMemory(uint64_t vaddr, uint64_t size, bool is_write = false);
|
||||
void UnmapMemory(uint64_t vaddr, uint64_t size);
|
||||
[[nodiscard]] Buffer& GetBuffer(BufferId id) { return m_slot_buffers[id]; }
|
||||
[[nodiscard]] BufferId FindBuffer(uint64_t vaddr, uint64_t size);
|
||||
[[nodiscard]] std::pair<Buffer*, uint64_t> ObtainBuffer(uint64_t vaddr, uint64_t size,
|
||||
|
||||
@@ -63,7 +63,7 @@ void GpuResourceManager::UnmapMemory(uint64_t vaddr, uint64_t size) {
|
||||
m_scheduler.FinishCurrent();
|
||||
m_scheduler.WaitPriorityOperations(tick);
|
||||
}
|
||||
m_buffer_cache.UnmapMemory(vaddr, size);
|
||||
m_buffer_cache.InvalidateMemory(vaddr, size);
|
||||
m_texture_cache.UnmapMemory(vaddr, size);
|
||||
m_page_manager.OnGpuUnmap(vaddr, size);
|
||||
std::lock_guard lock(m_mapped_ranges_mutex);
|
||||
|
||||
Reference in New Issue
Block a user