Implement FIFO semaphore (#1286)

* Implement FIFO semaphore

* New enum for FIFO semaphore operation
This commit is contained in:
gdkchan 2020-05-29 05:51:10 -03:00 committed by GitHub
parent 12cfaf56f0
commit 44d7fcff39
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 50 additions and 14 deletions

View file

@ -1,11 +1,37 @@
using Ryujinx.Graphics.Gpu.State;
using System;
using System.Threading;
namespace Ryujinx.Graphics.Gpu.Engine
{
partial class Methods
{
/// <summary>
/// Writes a GPU counter to guest memory.
/// </summary>
/// <param name="state">Current GPU state</param>
/// <param name="argument">Method call argument</param>
public void Semaphore(GpuState state, int argument)
{
FifoSemaphoreOperation op = (FifoSemaphoreOperation)(argument & 3);
var semaphore = state.Get<SemaphoreState>(MethodOffset.Semaphore);
int value = semaphore.Payload;
if (op == FifoSemaphoreOperation.Counter)
{
// TODO: There's much more that should be done here.
// NVN only supports the "Accumulate" mode, so we
// can't currently guess which bits specify the
// reduction operation.
value += _context.MemoryAccessor.Read<int>(semaphore.Address.Pack());
}
_context.MemoryAccessor.Write(semaphore.Address.Pack(), value);
_context.AdvanceSequence();
}
/// <summary>
/// Waits for the GPU to be idle.
/// </summary>

View file

@ -21,14 +21,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
/// <param name="argument">Method call argument</param>
private void Report(GpuState state, int argument)
{
ReportMode mode = (ReportMode)(argument & 3);
SemaphoreOperation op = (SemaphoreOperation)(argument & 3);
ReportCounterType type = (ReportCounterType)((argument >> 23) & 0x1f);
switch (mode)
switch (op)
{
case ReportMode.Release: ReleaseSemaphore(state); break;
case ReportMode.Counter: ReportCounter(state, type); break;
case SemaphoreOperation.Release: ReleaseSemaphore(state); break;
case SemaphoreOperation.Counter: ReportCounter(state, type); break;
}
}
@ -38,7 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
/// <param name="state">Current GPU state</param>
private void ReleaseSemaphore(GpuState state)
{
var rs = state.Get<ReportState>(MethodOffset.ReportState);
var rs = state.Get<SemaphoreState>(MethodOffset.ReportState);
_context.MemoryAccessor.Write(rs.Address.Pack(), rs.Payload);
@ -64,7 +63,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
{
CounterData counterData = new CounterData();
var rs = state.Get<ReportState>(MethodOffset.ReportState);
var rs = state.Get<SemaphoreState>(MethodOffset.ReportState);
ulong gpuVa = rs.Address.Pack();

View file

@ -104,6 +104,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
/// <param name="state">GPU state where the triggers will be registered</param>
public void RegisterCallbacksForFifo(GpuState state)
{
state.RegisterCallback(MethodOffset.Semaphore, Semaphore);
state.RegisterCallback(MethodOffset.FenceAction, FenceAction);
state.RegisterCallback(MethodOffset.WaitForIdle, WaitForIdle);
state.RegisterCallback(MethodOffset.SendMacroCodeData, SendMacroCodeData);
@ -430,7 +431,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
_context.Renderer.Pipeline.SetOrigin(origin);
// The triangle rast flip flag only affects rasterization, the viewport is not flipped.
// Setting the origin mode to upper left on the host, however, not onlyy affects rasterization,
// Setting the origin mode to upper left on the host, however, not only affects rasterization,
// but also flips the viewport.
// We negate the effects of flipping the viewport by flipping it again using the viewport swizzle.
if (origin == Origin.UpperLeft)

View file

@ -0,0 +1,9 @@
namespace Ryujinx.Graphics.Gpu.State
{
enum FifoSemaphoreOperation
{
Counter = 0,
Acquire = 1,
Release = 2
}
}

View file

@ -8,7 +8,8 @@ namespace Ryujinx.Graphics.Gpu.State
/// </remarks>
enum MethodOffset
{
BindChannel = 0x00,
BindChannel = 0x0,
Semaphore = 0x4,
FenceValue = 0x1c,
FenceAction = 0x1d,
WaitForIdle = 0x44,

View file

@ -1,9 +1,9 @@
namespace Ryujinx.Graphics.Gpu.State
{
/// <summary>
/// GPU counter report mode.
/// GPU semaphore operation.
/// </summary>
enum ReportMode
enum SemaphoreOperation
{
Release = 0,
Acquire = 1,

View file

@ -1,9 +1,9 @@
namespace Ryujinx.Graphics.Gpu.State
{
/// <summary>
/// GPU counter report state.
/// GPU semaphore state.
/// </summary>
struct ReportState
struct SemaphoreState
{
#pragma warning disable CS0649
public GpuVa Address;