aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2022-11-24 01:41:16 +0000
committerGitHub <noreply@github.com>2022-11-24 01:41:16 +0000
commit5a39d3c4a13d9de67aa324a487af3756e4ce4930 (patch)
tree9daca942f24c9d5ef402b486430a0bf2e4494bd8
parentcc51a03af96d2ed24d06ff0e44c38af8e5565194 (diff)
GPU: Relax locking on Buffer Cache (#3883)1.1.375
I did this on ncbuffer2 when we were using it for LDN 3, but I noticed that it can apply to the current buffer manager too, and it's an easy performance win. The only buffer access that can come from another thread is the overlap search for buffers that have been unmapped. Everything else, including modifications, come from the main GPU thread. That means we only need to lock the range list when it's being modified, as that's the only time where we'll cause a race with the unmapped handler. This has a significant performance improvements in situations where FIFO is high, like the other two PRs. Joined together they give a nice boost (73.6 master -> 79 -> 83 fps in SMO).
-rw-r--r--Ryujinx.Graphics.Gpu/Memory/BufferCache.cs28
1 files changed, 8 insertions, 20 deletions
diff --git a/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs b/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs
index 85ed49d5..a523c76f 100644
--- a/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs
@@ -22,6 +22,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
private readonly GpuContext _context;
private readonly PhysicalMemory _physicalMemory;
+ /// <remarks>
+ /// Only modified from the GPU thread. Must lock for add/remove.
+ /// Must lock for any access from other threads.
+ /// </remarks>
private readonly RangeList<Buffer> _buffers;
private Buffer[] _bufferOverlaps;
@@ -200,12 +204,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// <param name="size">Size in bytes of the buffer</param>
private void CreateBufferAligned(ulong address, ulong size)
{
- int overlapsCount;
-
- lock (_buffers)
- {
- overlapsCount = _buffers.FindOverlapsNonOverlapping(address, size, ref _bufferOverlaps);
- }
+ int overlapsCount = _buffers.FindOverlapsNonOverlapping(address, size, ref _bufferOverlaps);
if (overlapsCount != 0)
{
@@ -410,10 +409,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
if (size != 0)
{
- lock (_buffers)
- {
- buffer = _buffers.FindFirstOverlap(address, size);
- }
+ buffer = _buffers.FindFirstOverlap(address, size);
buffer.SynchronizeMemory(address, size);
@@ -424,10 +420,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
}
else
{
- lock (_buffers)
- {
- buffer = _buffers.FindFirstOverlap(address, 1);
- }
+ buffer = _buffers.FindFirstOverlap(address, 1);
}
return buffer;
@@ -442,12 +435,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
{
if (size != 0)
{
- Buffer buffer;
-
- lock (_buffers)
- {
- buffer = _buffers.FindFirstOverlap(address, size);
- }
+ Buffer buffer = _buffers.FindFirstOverlap(address, size);
buffer.SynchronizeMemory(address, size);
}