aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2021-10-19 17:25:32 -0300
committerGitHub <noreply@github.com>2021-10-19 17:25:32 -0300
commit0d174cbd4555e69660a900577a52f3d4bf7391b9 (patch)
treeed68e5f55d2f9ba1d365d877d7f66dad8fa3df19 /Ryujinx.HLE/HOS
parent63f1663fa959d8809d1762d99e9364565ba9b3d8 (diff)
EventWait should not signal the event when it returns Success (#2739)
* Fix race when EventWait is called and a wait is done on the CPU * This is useless now * Fix EventSignal * Ensure the signal belongs to the current fence, to avoid stale signals
Diffstat (limited to 'Ryujinx.HLE/HOS')
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/NvHostCtrlDeviceFile.cs21
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostEvent.cs28
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs2
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/AndroidFence.cs5
4 files changed, 28 insertions, 28 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/NvHostCtrlDeviceFile.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/NvHostCtrlDeviceFile.cs
index f0e5634e..9af1ce7d 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/NvHostCtrlDeviceFile.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/NvHostCtrlDeviceFile.cs
@@ -314,24 +314,11 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
return NvInternalResult.InvalidInput;
}
- lock (hostEvent.Lock)
- {
-
- NvHostEventState oldState = hostEvent.State;
-
- if (oldState == NvHostEventState.Waiting)
- {
- hostEvent.State = NvHostEventState.Cancelling;
-
- hostEvent.Cancel(_device.Gpu);
- }
-
- hostEvent.State = NvHostEventState.Cancelled;
+ hostEvent.Cancel(_device.Gpu);
- _device.System.HostSyncpoint.UpdateMin(hostEvent.Fence.Id);
+ _device.System.HostSyncpoint.UpdateMin(hostEvent.Fence.Id);
- return NvInternalResult.Success;
- }
+ return NvInternalResult.Success;
}
}
@@ -486,7 +473,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
if (Event != null)
{
if (Event.State == NvHostEventState.Available ||
- Event.State == NvHostEventState.Signaled ||
+ Event.State == NvHostEventState.Signaled ||
Event.State == NvHostEventState.Cancelled)
{
eventIndex = index;
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostEvent.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostEvent.cs
index 76e1564b..f57a4eff 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostEvent.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostEvent.cs
@@ -68,10 +68,17 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
}
}
- private void GpuSignaled()
+ private void GpuSignaled(SyncpointWaiterHandle waiterInformation)
{
lock (Lock)
{
+ // If the signal does not match our current waiter,
+ // then it is from a past fence and we should just ignore it.
+ if (waiterInformation != null && waiterInformation != _waiterInformation)
+ {
+ return;
+ }
+
ResetFailingState();
Signal();
@@ -82,9 +89,14 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
{
lock (Lock)
{
- if (_waiterInformation != null)
+ NvHostEventState oldState = State;
+
+ State = NvHostEventState.Cancelling;
+
+ if (oldState == NvHostEventState.Waiting && _waiterInformation != null)
{
gpuContext.Synchronization.UnregisterCallback(Fence.Id, _waiterInformation);
+ _waiterInformation = null;
if (_previousFailingFence.Id == Fence.Id && _previousFailingFence.Value == Fence.Value)
{
@@ -96,10 +108,10 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
_previousFailingFence = Fence;
}
-
- Signal();
}
+ State = NvHostEventState.Cancelled;
+
Event.WritableEvent.Clear();
}
}
@@ -108,9 +120,6 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
{
lock (Lock)
{
- Fence = fence;
- State = NvHostEventState.Waiting;
-
// NOTE: nvservices code should always wait on the GPU side.
// If we do this, we may get an abort or undefined behaviour when the GPU processing thread is blocked for a long period (for example, during shader compilation).
// The reason for this is that the NVN code will try to wait until giving up.
@@ -123,12 +132,15 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
bool timedOut = Fence.Wait(gpuContext, Timeout.InfiniteTimeSpan);
- GpuSignaled();
+ ResetFailingState();
return timedOut;
}
else
{
+ Fence = fence;
+ State = NvHostEventState.Waiting;
+
_waiterInformation = gpuContext.Synchronization.RegisterCallbackOnSyncpoint(Fence.Id, Fence.Value, GpuSignaled);
return true;
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
index 39aebde5..c45c4b9d 100644
--- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
@@ -392,7 +392,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
}
else
{
- item.Fence.RegisterCallback(_device.Gpu, () =>
+ item.Fence.RegisterCallback(_device.Gpu, (x) =>
{
_device.Gpu.Window.SignalFrameReady();
_device.Gpu.GPFifo.Interrupt();
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/AndroidFence.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/AndroidFence.cs
index 515efd05..5b72e257 100644
--- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/AndroidFence.cs
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/AndroidFence.cs
@@ -1,5 +1,6 @@
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu;
+using Ryujinx.Graphics.Gpu.Synchronization;
using Ryujinx.HLE.HOS.Services.Nv.Types;
using System;
using System.Runtime.CompilerServices;
@@ -66,7 +67,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
return false;
}
- public void RegisterCallback(GpuContext gpuContext, Action callback)
+ public void RegisterCallback(GpuContext gpuContext, Action<SyncpointWaiterHandle> callback)
{
ref NvFence fence = ref NvFences[FenceCount - 1];
@@ -76,7 +77,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
}
else
{
- callback();
+ callback(null);
}
}