From efb135b74c9c0ff1de2dfd7d2a431bd23185ca66 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Thu, 16 Feb 2023 18:28:49 -0300 Subject: Clear CPU side data on GPU buffer clears (#4125) * Clear CPU side data on GPU buffer clears * Implement tracked fill operation that can signal other resource types except buffer * Fix tests, add missing XML doc * PR feedback --- Ryujinx.Graphics.Gpu/Memory/Buffer.cs | 4 +-- Ryujinx.Graphics.Gpu/Memory/BufferCache.cs | 2 +- Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs | 37 +++++++++++++++++++++------ Ryujinx.Graphics.Gpu/Memory/ResourceKind.cs | 13 ++++++++++ 4 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 Ryujinx.Graphics.Gpu/Memory/ResourceKind.cs (limited to 'Ryujinx.Graphics.Gpu/Memory') diff --git a/Ryujinx.Graphics.Gpu/Memory/Buffer.cs b/Ryujinx.Graphics.Gpu/Memory/Buffer.cs index a624386e..3778cd82 100644 --- a/Ryujinx.Graphics.Gpu/Memory/Buffer.cs +++ b/Ryujinx.Graphics.Gpu/Memory/Buffer.cs @@ -105,13 +105,13 @@ namespace Ryujinx.Graphics.Gpu.Memory if (_useGranular) { - _memoryTrackingGranular = physicalMemory.BeginGranularTracking(address, size, baseHandles); + _memoryTrackingGranular = physicalMemory.BeginGranularTracking(address, size, ResourceKind.Buffer, baseHandles); _memoryTrackingGranular.RegisterPreciseAction(address, size, PreciseAction); } else { - _memoryTracking = physicalMemory.BeginTracking(address, size); + _memoryTracking = physicalMemory.BeginTracking(address, size, ResourceKind.Buffer); if (baseHandles != null) { diff --git a/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs b/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs index 00f59083..a5a9b75e 100644 --- a/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs +++ b/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs @@ -368,7 +368,7 @@ namespace Ryujinx.Graphics.Gpu.Memory _context.Renderer.Pipeline.ClearBuffer(buffer.Handle, offset, (int)size, value); - buffer.SignalModified(address, size); + memoryManager.Physical.FillTrackedResource(address, size, value, ResourceKind.Buffer); } /// diff --git a/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs b/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs index c1fc0c5c..bd33383e 100644 --- a/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs +++ b/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs @@ -7,6 +7,7 @@ using Ryujinx.Memory.Range; using Ryujinx.Memory.Tracking; using System; using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading; namespace Ryujinx.Graphics.Gpu.Memory @@ -295,23 +296,41 @@ namespace Ryujinx.Graphics.Gpu.Memory } } + /// + /// Fills the specified memory region with a 32-bit integer value. + /// + /// CPU virtual address of the region + /// Size of the region + /// Value to fill the region with + /// Kind of the resource being filled, which will not be signalled as CPU modified + public void FillTrackedResource(ulong address, ulong size, uint value, ResourceKind kind) + { + _cpuMemory.SignalMemoryTracking(address, size, write: true, precise: true, (int)kind); + + using WritableRegion region = _cpuMemory.GetWritableRegion(address, (int)size); + + MemoryMarshal.Cast(region.Memory.Span).Fill(value); + } + /// /// Obtains a memory tracking handle for the given virtual region. This should be disposed when finished with. /// /// CPU virtual address of the region /// Size of the region + /// Kind of the resource being tracked /// The memory tracking handle - public CpuRegionHandle BeginTracking(ulong address, ulong size) + public CpuRegionHandle BeginTracking(ulong address, ulong size, ResourceKind kind) { - return _cpuMemory.BeginTracking(address, size); + return _cpuMemory.BeginTracking(address, size, (int)kind); } /// /// Obtains a memory tracking handle for the given virtual region. This should be disposed when finished with. /// /// Ranges of physical memory where the data is located + /// Kind of the resource being tracked /// The memory tracking handle - public GpuRegionHandle BeginTracking(MultiRange range) + public GpuRegionHandle BeginTracking(MultiRange range, ResourceKind kind) { var cpuRegionHandles = new CpuRegionHandle[range.Count]; int count = 0; @@ -321,7 +340,7 @@ namespace Ryujinx.Graphics.Gpu.Memory var currentRange = range.GetSubRange(i); if (currentRange.Address != MemoryManager.PteUnmapped) { - cpuRegionHandles[count++] = _cpuMemory.BeginTracking(currentRange.Address, currentRange.Size); + cpuRegionHandles[count++] = _cpuMemory.BeginTracking(currentRange.Address, currentRange.Size, (int)kind); } } @@ -338,12 +357,13 @@ namespace Ryujinx.Graphics.Gpu.Memory /// /// CPU virtual address of the region /// Size of the region + /// Kind of the resource being tracked /// Handles to inherit state from or reuse /// Desired granularity of write tracking /// The memory tracking handle - public CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, IEnumerable handles = null, ulong granularity = 4096) + public CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, ResourceKind kind, IEnumerable handles = null, ulong granularity = 4096) { - return _cpuMemory.BeginGranularTracking(address, size, handles, granularity); + return _cpuMemory.BeginGranularTracking(address, size, handles, granularity, (int)kind); } /// @@ -351,11 +371,12 @@ namespace Ryujinx.Graphics.Gpu.Memory /// /// CPU virtual address of the region /// Size of the region + /// Kind of the resource being tracked /// Desired granularity of write tracking /// The memory tracking handle - public CpuSmartMultiRegionHandle BeginSmartGranularTracking(ulong address, ulong size, ulong granularity = 4096) + public CpuSmartMultiRegionHandle BeginSmartGranularTracking(ulong address, ulong size, ResourceKind kind, ulong granularity = 4096) { - return _cpuMemory.BeginSmartGranularTracking(address, size, granularity); + return _cpuMemory.BeginSmartGranularTracking(address, size, granularity, (int)kind); } /// diff --git a/Ryujinx.Graphics.Gpu/Memory/ResourceKind.cs b/Ryujinx.Graphics.Gpu/Memory/ResourceKind.cs new file mode 100644 index 00000000..55d697b8 --- /dev/null +++ b/Ryujinx.Graphics.Gpu/Memory/ResourceKind.cs @@ -0,0 +1,13 @@ +namespace Ryujinx.Graphics.Gpu.Memory +{ + /// + /// Kind of a GPU resource. + /// + enum ResourceKind + { + None, + Buffer, + Texture, + Pool + } +} -- cgit v1.2.3