aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs9
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureCache.cs12
-rw-r--r--Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs22
3 files changed, 37 insertions, 6 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs b/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs
index 75b8e220..e3e8d5ba 100644
--- a/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs
@@ -110,9 +110,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
ulong dstGpuVa = ((ulong)state.OffsetOutUpperValue << 32) | state.OffsetOut;
- // Trigger read tracking, to flush any managed resources in the destination region.
- _channel.MemoryManager.GetSpan(dstGpuVa, _size, true);
-
_dstGpuVa = dstGpuVa;
_dstX = state.SetDstOriginBytesXV;
_dstY = state.SetDstOriginSamplesYV;
@@ -174,7 +171,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
if (_isLinear && _lineCount == 1)
{
- memoryManager.Write(_dstGpuVa, data);
+ memoryManager.Physical.CacheResourceWrite(memoryManager, _dstGpuVa, data);
}
else
{
@@ -227,11 +224,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
memoryManager.Write(dstAddress, data[srcOffset]);
}
}
+
+ _context.AdvanceSequence();
}
_finished = true;
-
- _context.AdvanceSequence();
}
}
}
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureCache.cs b/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
index ea64f46c..a6fa9652 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
@@ -100,6 +100,18 @@ namespace Ryujinx.Graphics.Gpu.Image
}
/// <summary>
+ /// Determines if any texture exists within the target memory range.
+ /// </summary>
+ /// <param name="memoryManager">The GPU memory manager</param>
+ /// <param name="gpuVa">GPU virtual address to search for textures</param>
+ /// <param name="size">The size of the range</param>
+ /// <returns>True if any texture exists in the range, false otherwise</returns>
+ public bool IsTextureInRange(MemoryManager memoryManager, ulong gpuVa, ulong size)
+ {
+ return _textures.FindOverlaps(memoryManager.GetPhysicalRegions(gpuVa, size), ref _textureOverlaps) != 0;
+ }
+
+ /// <summary>
/// Determines if a given texture is "safe" for upscaling from its info.
/// Note that this is different from being compatible - this elilinates targets that would have detrimental effects when scaled.
/// </summary>
diff --git a/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs b/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs
index fd2a7476..0ec41a8f 100644
--- a/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs
@@ -81,6 +81,28 @@ namespace Ryujinx.Graphics.Gpu.Memory
}
/// <summary>
+ /// Write data to memory that is destined for a resource in a cache.
+ /// This avoids triggering write tracking when possible, which can avoid flushes and incrementing sequence number.
+ /// </summary>
+ /// <param name="memoryManager">The GPU memory manager</param>
+ /// <param name="gpuVa">GPU virtual address to write the data into</param>
+ /// <param name="data">The data to be written</param>
+ public void CacheResourceWrite(MemoryManager memoryManager, ulong gpuVa, ReadOnlySpan<byte> data)
+ {
+ if (TextureCache.IsTextureInRange(memoryManager, gpuVa, (ulong)data.Length))
+ {
+ // No fast path yet - copy the data back and trigger write tracking.
+ memoryManager.Write(gpuVa, data);
+ _context.AdvanceSequence();
+ }
+ else
+ {
+ BufferCache.ForceDirty(memoryManager, gpuVa, (ulong)data.Length);
+ memoryManager.WriteUntracked(gpuVa, data);
+ }
+ }
+
+ /// <summary>
/// Gets a span of data from the application process.
/// </summary>
/// <param name="address">Start address of the range</param>