Add support for releasing a semaphore to DmaClass (#2926)

* Add support for releasing a semaphore to DmaClass

Fixes freezes in OpenGL games, primarily GameMaker ones such as Undertale.

* Address Feedback
This commit is contained in:
riperiperi 2021-12-19 14:32:52 +00:00 committed by GitHub
parent e24949ca2c
commit 521a07e612
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,4 +1,5 @@
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Gpu.Engine.Threed; using Ryujinx.Graphics.Gpu.Engine.Threed;
using Ryujinx.Graphics.Texture; using Ryujinx.Graphics.Texture;
@ -98,11 +99,32 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
} }
} }
/// <summary>
/// Releases a semaphore for a given LaunchDma method call.
/// </summary>
/// <param name="argument">The LaunchDma call argument</param>
private void ReleaseSemaphore(int argument)
{
LaunchDmaSemaphoreType type = (LaunchDmaSemaphoreType)((argument >> 3) & 0x3);
if (type != LaunchDmaSemaphoreType.None)
{
ulong address = ((ulong)_state.State.SetSemaphoreA << 32) | _state.State.SetSemaphoreB;
if (type == LaunchDmaSemaphoreType.ReleaseOneWordSemaphore)
{
_channel.MemoryManager.Write(address, _state.State.SetSemaphorePayload);
}
else /* if (type == LaunchDmaSemaphoreType.ReleaseFourWordSemaphore) */
{
Logger.Warning?.Print(LogClass.Gpu, "DMA semaphore type ReleaseFourWordSemaphore was used, but is not currently implemented.");
}
}
}
/// <summary> /// <summary>
/// Performs a buffer to buffer, or buffer to texture copy. /// Performs a buffer to buffer, or buffer to texture copy.
/// </summary> /// </summary>
/// <param name="argument">Method call argument</param> /// <param name="argument">The LaunchDma call argument</param>
private void LaunchDma(int argument) private void DmaCopy(int argument)
{ {
var memoryManager = _channel.MemoryManager; var memoryManager = _channel.MemoryManager;
@ -296,5 +318,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
} }
} }
} }
/// <summary>
/// Performs a buffer to buffer, or buffer to texture copy, then optionally releases a semaphore.
/// </summary>
/// <param name="argument">Method call argument</param>
private void LaunchDma(int argument)
{
DmaCopy(argument);
ReleaseSemaphore(argument);
}
} }
} }