MemoryTracking: Initial setup of atomic writes.

This commit is contained in:
Fernando Sahmkow 2023-06-28 06:28:13 +02:00
parent b60b70e86d
commit 47d0d292d5
8 changed files with 183 additions and 14 deletions

View file

@ -115,7 +115,21 @@ void BufferCache<P>::WriteMemory(VAddr cpu_addr, u64 size) {
template <class P>
void BufferCache<P>::CachedWriteMemory(VAddr cpu_addr, u64 size) {
memory_tracker.CachedCpuWrite(cpu_addr, size);
const bool is_dirty = IsRegionRegistered(cpu_addr, size);
if (!is_dirty) {
return;
}
VAddr aligned_start = Common::AlignDown(cpu_addr, YUZU_PAGESIZE);
VAddr aligned_end = Common::AlignUp(cpu_addr + size, YUZU_PAGESIZE);
if (!IsRegionGpuModified(aligned_start, aligned_end - aligned_start)) {
WriteMemory(cpu_addr, size);
return;
}
tmp_buffer.resize_destructive(size);
cpu_memory.ReadBlockUnsafe(cpu_addr, tmp_buffer.data(), size);
InlineMemoryImplementation(cpu_addr, size, tmp_buffer);
}
template <class P>
@ -1553,6 +1567,14 @@ bool BufferCache<P>::InlineMemory(VAddr dest_address, size_t copy_size,
return false;
}
InlineMemoryImplementation(dest_address, copy_size, inlined_buffer);
return true;
}
template <class P>
void BufferCache<P>::InlineMemoryImplementation(VAddr dest_address, size_t copy_size,
std::span<const u8> inlined_buffer) {
const IntervalType subtract_interval{dest_address, dest_address + copy_size};
ClearDownload(subtract_interval);
common_ranges.subtract(subtract_interval);
@ -1574,8 +1596,6 @@ bool BufferCache<P>::InlineMemory(VAddr dest_address, size_t copy_size,
} else {
buffer.ImmediateUpload(buffer.Offset(dest_address), inlined_buffer.first(copy_size));
}
return true;
}
template <class P>

View file

@ -543,6 +543,8 @@ private:
void ClearDownload(IntervalType subtract_interval);
void InlineMemoryImplementation(VAddr dest_address, size_t copy_size, std::span<const u8> inlined_buffer);
VideoCore::RasterizerInterface& rasterizer;
Core::Memory::Memory& cpu_memory;

View file

@ -95,7 +95,9 @@ struct GPU::Impl {
/// Synchronizes CPU writes with Host GPU memory.
void InvalidateGPUCache() {
rasterizer->InvalidateGPUCache();
std::function<void(VAddr, size_t)> callback_writes(
[this](VAddr address, size_t size) { rasterizer->OnCPUWrite(address, size); });
system.GatherGPUDirtyMemory(callback_writes);
}
/// Signal the ending of command list.

View file

@ -570,7 +570,7 @@ void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) {
if (addr == 0 || size == 0) {
return;
}
pipeline_cache.OnCPUWrite(addr, size);
{
std::scoped_lock lock{texture_cache.mutex};
texture_cache.WriteMemory(addr, size);
@ -579,14 +579,11 @@ void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) {
std::scoped_lock lock{buffer_cache.mutex};
buffer_cache.CachedWriteMemory(addr, size);
}
pipeline_cache.InvalidateRegion(addr, size);
}
void RasterizerVulkan::InvalidateGPUCache() {
pipeline_cache.SyncGuestHost();
{
std::scoped_lock lock{buffer_cache.mutex};
buffer_cache.FlushCachedWrites();
}
gpu.InvalidateGPUCache();
}
void RasterizerVulkan::UnmapMemory(VAddr addr, u64 size) {