aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.GAL
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2023-05-01 20:05:12 +0100
committerGitHub <noreply@github.com>2023-05-01 16:05:12 -0300
commite18d258fa09379f31ca4310fbbe9e1869581d49f (patch)
treec8427df586f4385feef9b8d201a648aeb2afec1b /src/Ryujinx.Graphics.GAL
parent36f10df775cf0c678548b97346432095823dfd8a (diff)
GPU: Pre-emptively flush textures that are flushed often (to imported memory when available) (#4711)
* WIP texture pre-flush Improve performance of TextureView GetData to buffer Fix copy/sync ordering Fix minor bug Make this actually work WIP host mapping stuff * Fix usage flags * message * Cleanup 1 * Fix rebase * Fix * Improve pre-flush rules * Fix pre-flush * A lot of cleanup * Use the host memory bits * Select the correct memory type * Cleanup TextureGroupHandle * Missing comment * Remove debugging logs * Revert BufferHandle _value access modifier * One interrupt action at a time. * Support D32S8 to D24S8 conversion, safeguards * Interrupt cannot happen in sync handle's lock Waitable needs to be checked twice now, but this should stop it from deadlocking. * Remove unused using * Address some feedback * Address feedback * Address more feedback * Address more feedback * Improve sync rules Should allow for faster sync in some cases.
Diffstat (limited to 'src/Ryujinx.Graphics.GAL')
-rw-r--r--src/Ryujinx.Graphics.GAL/BufferAccess.cs8
-rw-r--r--src/Ryujinx.Graphics.GAL/IRenderer.cs3
-rw-r--r--src/Ryujinx.Graphics.GAL/ITexture.cs1
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs3
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs3
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferAccessCommand.cs22
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateHostBufferCommand.cs22
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToBufferCommand.cs29
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs6
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs33
10 files changed, 127 insertions, 3 deletions
diff --git a/src/Ryujinx.Graphics.GAL/BufferAccess.cs b/src/Ryujinx.Graphics.GAL/BufferAccess.cs
new file mode 100644
index 00000000..3a2d6c9b
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/BufferAccess.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.Graphics.GAL
+{
+ public enum BufferAccess
+ {
+ Default,
+ FlushPersistent
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/IRenderer.cs b/src/Ryujinx.Graphics.GAL/IRenderer.cs
index 2af7b5db..d36dd26b 100644
--- a/src/Ryujinx.Graphics.GAL/IRenderer.cs
+++ b/src/Ryujinx.Graphics.GAL/IRenderer.cs
@@ -21,11 +21,14 @@ namespace Ryujinx.Graphics.GAL
{
return CreateBuffer(size, BufferHandle.Null);
}
+ BufferHandle CreateBuffer(nint pointer, int size);
+ BufferHandle CreateBuffer(int size, BufferAccess access);
IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info);
ISampler CreateSampler(SamplerCreateInfo info);
ITexture CreateTexture(TextureCreateInfo info, float scale);
+ bool PrepareHostMapping(nint address, ulong size);
void CreateSync(ulong id, bool strict);
diff --git a/src/Ryujinx.Graphics.GAL/ITexture.cs b/src/Ryujinx.Graphics.GAL/ITexture.cs
index 792c863c..2f9f5fbf 100644
--- a/src/Ryujinx.Graphics.GAL/ITexture.cs
+++ b/src/Ryujinx.Graphics.GAL/ITexture.cs
@@ -12,6 +12,7 @@ namespace Ryujinx.Graphics.GAL
void CopyTo(ITexture destination, int firstLayer, int firstLevel);
void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel);
void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter);
+ void CopyTo(BufferRange range, int layer, int level, int stride);
ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel);
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs b/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs
index 063b7edf..9f6e483c 100644
--- a/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs
@@ -43,6 +43,8 @@ namespace Ryujinx.Graphics.GAL.Multithreading
Register<ActionCommand>(CommandType.Action);
Register<CreateBufferCommand>(CommandType.CreateBuffer);
+ Register<CreateBufferAccessCommand>(CommandType.CreateBufferAccess);
+ Register<CreateHostBufferCommand>(CommandType.CreateHostBuffer);
Register<CreateProgramCommand>(CommandType.CreateProgram);
Register<CreateSamplerCommand>(CommandType.CreateSampler);
Register<CreateSyncCommand>(CommandType.CreateSync);
@@ -69,6 +71,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
Register<TextureCopyToCommand>(CommandType.TextureCopyTo);
Register<TextureCopyToScaledCommand>(CommandType.TextureCopyToScaled);
Register<TextureCopyToSliceCommand>(CommandType.TextureCopyToSlice);
+ Register<TextureCopyToBufferCommand>(CommandType.TextureCopyToBuffer);
Register<TextureCreateViewCommand>(CommandType.TextureCreateView);
Register<TextureGetDataCommand>(CommandType.TextureGetData);
Register<TextureGetDataSliceCommand>(CommandType.TextureGetDataSlice);
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs b/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs
index 61e729b4..8d9c1ec8 100644
--- a/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs
@@ -4,6 +4,8 @@
{
Action,
CreateBuffer,
+ CreateBufferAccess,
+ CreateHostBuffer,
CreateProgram,
CreateSampler,
CreateSync,
@@ -29,6 +31,7 @@
SamplerDispose,
TextureCopyTo,
+ TextureCopyToBuffer,
TextureCopyToScaled,
TextureCopyToSlice,
TextureCreateView,
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferAccessCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferAccessCommand.cs
new file mode 100644
index 00000000..ece98b70
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateBufferAccessCommand.cs
@@ -0,0 +1,22 @@
+namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
+{
+ struct CreateBufferAccessCommand : IGALCommand, IGALCommand<CreateBufferAccessCommand>
+ {
+ public CommandType CommandType => CommandType.CreateBufferAccess;
+ private BufferHandle _threadedHandle;
+ private int _size;
+ private BufferAccess _access;
+
+ public void Set(BufferHandle threadedHandle, int size, BufferAccess access)
+ {
+ _threadedHandle = threadedHandle;
+ _size = size;
+ _access = access;
+ }
+
+ public static void Run(ref CreateBufferAccessCommand command, ThreadedRenderer threaded, IRenderer renderer)
+ {
+ threaded.Buffers.AssignBuffer(command._threadedHandle, renderer.CreateBuffer(command._size, command._access));
+ }
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateHostBufferCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateHostBufferCommand.cs
new file mode 100644
index 00000000..e25f8468
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateHostBufferCommand.cs
@@ -0,0 +1,22 @@
+namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
+{
+ struct CreateHostBufferCommand : IGALCommand, IGALCommand<CreateHostBufferCommand>
+ {
+ public CommandType CommandType => CommandType.CreateHostBuffer;
+ private BufferHandle _threadedHandle;
+ private nint _pointer;
+ private int _size;
+
+ public void Set(BufferHandle threadedHandle, nint pointer, int size)
+ {
+ _threadedHandle = threadedHandle;
+ _pointer = pointer;
+ _size = size;
+ }
+
+ public static void Run(ref CreateHostBufferCommand command, ThreadedRenderer threaded, IRenderer renderer)
+ {
+ threaded.Buffers.AssignBuffer(command._threadedHandle, renderer.CreateBuffer(command._pointer, command._size));
+ }
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToBufferCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToBufferCommand.cs
new file mode 100644
index 00000000..ac0e07d6
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureCopyToBufferCommand.cs
@@ -0,0 +1,29 @@
+using Ryujinx.Graphics.GAL.Multithreading.Model;
+using Ryujinx.Graphics.GAL.Multithreading.Resources;
+
+namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
+{
+ struct TextureCopyToBufferCommand : IGALCommand, IGALCommand<TextureCopyToBufferCommand>
+ {
+ public CommandType CommandType => CommandType.TextureCopyToBuffer;
+ private TableRef<ThreadedTexture> _texture;
+ private BufferRange _range;
+ private int _layer;
+ private int _level;
+ private int _stride;
+
+ public void Set(TableRef<ThreadedTexture> texture, BufferRange range, int layer, int level, int stride)
+ {
+ _texture = texture;
+ _range = range;
+ _layer = layer;
+ _level = level;
+ _stride = stride;
+ }
+
+ public static void Run(ref TextureCopyToBufferCommand command, ThreadedRenderer threaded, IRenderer renderer)
+ {
+ command._texture.Get(threaded).Base.CopyTo(threaded.Buffers.MapBufferRange(command._range), command._layer, command._level, command._stride);
+ }
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs
index ee1cfa29..bb0b05fb 100644
--- a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs
@@ -108,6 +108,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
}
}
+ public void CopyTo(BufferRange range, int layer, int level, int stride)
+ {
+ _renderer.New<TextureCopyToBufferCommand>().Set(Ref(this), range, layer, level, stride);
+ _renderer.QueueCommand();
+ }
+
public void SetData(SpanOrArray<byte> data)
{
_renderer.New<TextureSetDataCommand>().Set(Ref(this), Ref(data.ToArray()));
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs
index 2148f43f..3e179621 100644
--- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs
@@ -57,6 +57,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
private int _refConsumerPtr;
private Action _interruptAction;
+ private object _interruptLock = new();
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
@@ -274,6 +275,24 @@ namespace Ryujinx.Graphics.GAL.Multithreading
return handle;
}
+ public BufferHandle CreateBuffer(nint pointer, int size)
+ {
+ BufferHandle handle = Buffers.CreateBufferHandle();
+ New<CreateHostBufferCommand>().Set(handle, pointer, size);
+ QueueCommand();
+
+ return handle;
+ }
+
+ public BufferHandle CreateBuffer(int size, BufferAccess access)
+ {
+ BufferHandle handle = Buffers.CreateBufferHandle();
+ New<CreateBufferAccessCommand>().Set(handle, size, access);
+ QueueCommand();
+
+ return handle;
+ }
+
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
{
var program = new ThreadedProgram(this);
@@ -448,11 +467,14 @@ namespace Ryujinx.Graphics.GAL.Multithreading
}
else
{
- while (Interlocked.CompareExchange(ref _interruptAction, action, null) != null) { }
+ lock (_interruptLock)
+ {
+ while (Interlocked.CompareExchange(ref _interruptAction, action, null) != null) { }
- _galWorkAvailable.Set();
+ _galWorkAvailable.Set();
- _interruptRun.WaitOne();
+ _interruptRun.WaitOne();
+ }
}
}
@@ -461,6 +483,11 @@ namespace Ryujinx.Graphics.GAL.Multithreading
// Threaded renderer ignores given interrupt action, as it provides its own to the child renderer.
}
+ public bool PrepareHostMapping(nint address, ulong size)
+ {
+ return _baseRenderer.PrepareHostMapping(address, size);
+ }
+
public void Dispose()
{
// Dispose must happen from the render thread, after all commands have completed.