From 93df366b2c1ddb073410b8ce95c8225f52a49f33 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sat, 14 Jan 2023 11:23:57 -0300 Subject: [PATCH] Fix texture flush from CPU WaitSync regression on OpenGL (#4289) --- Ryujinx.Graphics.Gpu/Image/TextureGroup.cs | 13 +++++++- .../Image/TextureGroupHandle.cs | 31 +++++++------------ 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs b/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs index a6e0616cc..c167dc0d3 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs @@ -1431,10 +1431,21 @@ namespace Ryujinx.Graphics.Gpu.Image return; } - handle.Sync(_context); + bool isGpuThread = _context.IsGpuThread(); + + if (isGpuThread) + { + // No need to wait if we're on the GPU thread, we can just clear the modified flag immediately. + handle.Modified = false; + } _context.Renderer.BackgroundContextAction(() => { + if (!isGpuThread) + { + handle.Sync(_context); + } + Storage.SignalModifiedDirty(); lock (handle.Overlaps) diff --git a/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs b/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs index 34b59cffe..1b83cb558 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs @@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Gpu.Image /// A tracking handle for a texture group, which represents a range of views in a storage texture. /// Retains a list of overlapping texture views, a modified flag, and tracking for each /// CPU VA range that the views cover. - /// Also tracks copy dependencies for the handle - references to other handles that must be kept + /// Also tracks copy dependencies for the handle - references to other handles that must be kept /// in sync with this one before use. /// class TextureGroupHandle : IDisposable @@ -232,32 +232,23 @@ namespace Ryujinx.Graphics.Gpu.Image /// The GPU context used to wait for sync public void Sync(GpuContext context) { - bool needsSync = !context.IsGpuThread(); + ulong registeredSync = _registeredSync; + long diff = (long)(context.SyncNumber - registeredSync); - if (needsSync) + if (diff > 0) { - ulong registeredSync = _registeredSync; - long diff = (long)(context.SyncNumber - registeredSync); + context.Renderer.WaitSync(registeredSync); - if (diff > 0) + if ((long)(_modifiedSync - registeredSync) > 0) { - context.Renderer.WaitSync(registeredSync); - - if ((long)(_modifiedSync - registeredSync) > 0) - { - // Flush the data in a previous state. Do not remove the modified flag - it will be removed to ignore following writes. - return; - } - - Modified = false; + // Flush the data in a previous state. Do not remove the modified flag - it will be removed to ignore following writes. + return; } - - // If the difference is <= 0, no data is not ready yet. Flush any data we can without waiting or removing modified flag. - } - else - { + Modified = false; } + + // If the difference is <= 0, no data is not ready yet. Flush any data we can without waiting or removing modified flag. } ///