GPU: Track basic buffer copies that modify texture memory (#5554)

This branch changes the buffer copy fast path to notify memory tracking for all resources that aren't buffers. This fixes cases where games would copy buffer data directly into texture memory, which before would only work if the texture did not already exist. I imagine this happens when the guest driver is moving data between allocations or uploading it.

Since this only affects the fast path, cases where the source data has been modified from GPU (fast path copy destination doesn't count) will still fail to notify the texture, though I don't imagine games will do this. This should be resolved in future.

This should fix some texture issues with guest OpenGL games on switch, such as Dragon Quest Builders.

This may also be useful in future for games that move shader data around memory, if we end up using memory tracking for those.
This commit is contained in:
riperiperi 2023-08-14 07:41:11 +01:00 committed by GitHub
parent b423197619
commit 33f544fd92
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 1 deletions

View file

@ -344,7 +344,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
// Optimization: If the data being copied is already in memory, then copy it directly instead of flushing from GPU. // Optimization: If the data being copied is already in memory, then copy it directly instead of flushing from GPU.
dstBuffer.ClearModified(dstAddress, size); dstBuffer.ClearModified(dstAddress, size);
memoryManager.Physical.WriteUntracked(dstAddress, memoryManager.Physical.GetSpan(srcAddress, (int)size)); memoryManager.Physical.WriteTrackedResource(dstAddress, memoryManager.Physical.GetSpan(srcAddress, (int)size), ResourceKind.Buffer);
} }
} }

View file

@ -236,6 +236,18 @@ namespace Ryujinx.Graphics.Gpu.Memory
_cpuMemory.WriteUntracked(address, data); _cpuMemory.WriteUntracked(address, data);
} }
/// <summary>
/// Writes data to the application process, triggering a precise memory tracking event.
/// </summary>
/// <param name="address">Address to write into</param>
/// <param name="data">Data to be written</param>
/// <param name="kind">Kind of the resource being written, which will not be signalled as CPU modified</param>
public void WriteTrackedResource(ulong address, ReadOnlySpan<byte> data, ResourceKind kind)
{
_cpuMemory.SignalMemoryTracking(address, (ulong)data.Length, true, precise: true, exemptId: (int)kind);
_cpuMemory.WriteUntracked(address, data);
}
/// <summary> /// <summary>
/// Writes data to the application process. /// Writes data to the application process.
/// </summary> /// </summary>