Move solution and projects to src

This commit is contained in:
TSR Berry 2023-04-08 01:22:00 +02:00 committed by Mary
parent cd124bda58
commit cee7121058
3466 changed files with 55 additions and 55 deletions

View file

@ -0,0 +1,20 @@
namespace Ryujinx.Graphics.Host1x
{
public enum ClassId
{
Host1x = 0x1,
Mpeg = 0x20,
Nvenc = 0x21,
Vi = 0x30,
Isp = 0x32,
Ispb = 0x34,
Vii2c = 0x36,
Vic = 0x5d,
Gr3d = 0x60,
Gpu = 0x61,
Tsec = 0xe0,
Tsecb = 0xe1,
Nvjpg = 0xc0,
Nvdec = 0xf0
}
}

View file

@ -0,0 +1,32 @@
using Ryujinx.Graphics.Device;
using System;
using System.Collections.Generic;
namespace Ryujinx.Graphics.Host1x
{
class Devices : IDisposable
{
private readonly Dictionary<ClassId, IDeviceState> _devices = new Dictionary<ClassId, IDeviceState>();
public void RegisterDevice(ClassId classId, IDeviceState device)
{
_devices[classId] = device;
}
public IDeviceState GetDevice(ClassId classId)
{
return _devices.TryGetValue(classId, out IDeviceState device) ? device : null;
}
public void Dispose()
{
foreach (var device in _devices.Values)
{
if (device is ThiDevice thi)
{
thi.Dispose();
}
}
}
}
}

View file

@ -0,0 +1,33 @@
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Gpu.Synchronization;
using System.Collections.Generic;
using System.Threading;
namespace Ryujinx.Graphics.Host1x
{
public class Host1xClass : IDeviceState
{
private readonly SynchronizationManager _syncMgr;
private readonly DeviceState<Host1xClassRegisters> _state;
public Host1xClass(SynchronizationManager syncMgr)
{
_syncMgr = syncMgr;
_state = new DeviceState<Host1xClassRegisters>(new Dictionary<string, RwCallback>
{
{ nameof(Host1xClassRegisters.WaitSyncpt32), new RwCallback(WaitSyncpt32, null) }
});
}
public int Read(int offset) => _state.Read(offset);
public void Write(int offset, int data) => _state.Write(offset, data);
private void WaitSyncpt32(int data)
{
uint syncpointId = (uint)(data & 0xFF);
uint threshold = _state.State.LoadSyncptPayload32;
_syncMgr.WaitOnSyncpoint(syncpointId, threshold, Timeout.InfiniteTimeSpan);
}
}
}

View file

@ -0,0 +1,43 @@
using Ryujinx.Common.Memory;
namespace Ryujinx.Graphics.Host1x
{
struct Host1xClassRegisters
{
#pragma warning disable CS0649
public uint IncrSyncpt;
public uint IncrSyncptCntrl;
public uint IncrSyncptError;
public Array5<uint> ReservedC;
public uint WaitSyncpt;
public uint WaitSyncptBase;
public uint WaitSyncptIncr;
public uint LoadSyncptBase;
public uint IncrSyncptBase;
public uint Clear;
public uint Wait;
public uint WaitWithIntr;
public uint DelayUsec;
public uint TickcountHi;
public uint TickcountLo;
public uint Tickctrl;
public Array23<uint> Reserved50;
public uint Indctrl;
public uint Indoff2;
public uint Indoff;
public Array31<uint> Inddata;
public uint Reserved134;
public uint LoadSyncptPayload32;
public uint Stallctrl;
public uint WaitSyncpt32;
public uint WaitSyncptBase32;
public uint LoadSyncptBase32;
public uint IncrSyncptBase32;
public uint StallcountHi;
public uint StallcountLo;
public uint Xrefctrl;
public uint ChannelXrefHi;
public uint ChannelXrefLo;
#pragma warning restore CS0649
}
}

View file

@ -0,0 +1,174 @@
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Gpu.Synchronization;
using System;
using System.Numerics;
namespace Ryujinx.Graphics.Host1x
{
public sealed class Host1xDevice : IDisposable
{
private readonly struct Command
{
public int[] Buffer { get; }
public long ContextId { get; }
public Command(int[] buffer, long contextId)
{
Buffer = buffer;
ContextId = contextId;
}
}
private readonly SyncptIncrManager _syncptIncrMgr;
private readonly AsyncWorkQueue<Command> _commandQueue;
private readonly Devices _devices = new Devices();
public Host1xClass Class { get; }
private IDeviceState _device;
private int _count;
private int _offset;
private int _mask;
private bool _incrementing;
public Host1xDevice(SynchronizationManager syncMgr)
{
_syncptIncrMgr = new SyncptIncrManager(syncMgr);
_commandQueue = new AsyncWorkQueue<Command>(Process, "Ryujinx.Host1xProcessor");
Class = new Host1xClass(syncMgr);
_devices.RegisterDevice(ClassId.Host1x, Class);
}
public void RegisterDevice(ClassId classId, IDeviceState device)
{
var thi = new ThiDevice(classId, device ?? throw new ArgumentNullException(nameof(device)), _syncptIncrMgr);
_devices.RegisterDevice(classId, thi);
}
public long CreateContext()
{
if (_devices.GetDevice(ClassId.Nvdec) is IDeviceStateWithContext nvdec)
{
return nvdec.CreateContext();
}
return -1;
}
public void DestroyContext(long id)
{
if (id == -1)
{
return;
}
if (_devices.GetDevice(ClassId.Nvdec) is IDeviceStateWithContext nvdec)
{
nvdec.DestroyContext(id);
}
}
private void SetNvdecContext(long id)
{
if (id == -1)
{
return;
}
if (_devices.GetDevice(ClassId.Nvdec) is IDeviceStateWithContext nvdec)
{
nvdec.BindContext(id);
}
}
public void Submit(ReadOnlySpan<int> commandBuffer, long contextId)
{
_commandQueue.Add(new Command(commandBuffer.ToArray(), contextId));
}
private void Process(Command command)
{
SetNvdecContext(command.ContextId);
int[] commandBuffer = command.Buffer;
for (int index = 0; index < commandBuffer.Length; index++)
{
Step(commandBuffer[index]);
}
}
private void Step(int value)
{
if (_mask != 0)
{
int lbs = BitOperations.TrailingZeroCount(_mask);
_mask &= ~(1 << lbs);
DeviceWrite(_offset + lbs, value);
return;
}
else if (_count != 0)
{
_count--;
DeviceWrite(_offset, value);
if (_incrementing)
{
_offset++;
}
return;
}
OpCode opCode = (OpCode)((value >> 28) & 0xf);
switch (opCode)
{
case OpCode.SetClass:
_mask = value & 0x3f;
ClassId classId = (ClassId)((value >> 6) & 0x3ff);
_offset = (value >> 16) & 0xfff;
_device = _devices.GetDevice(classId);
break;
case OpCode.Incr:
case OpCode.NonIncr:
_count = value & 0xffff;
_offset = (value >> 16) & 0xfff;
_incrementing = opCode == OpCode.Incr;
break;
case OpCode.Mask:
_mask = value & 0xffff;
_offset = (value >> 16) & 0xfff;
break;
case OpCode.Imm:
int data = value & 0xfff;
_offset = (value >> 16) & 0xfff;
DeviceWrite(_offset, data);
break;
default:
Logger.Error?.Print(LogClass.Host1x, $"Unsupported opcode \"{opCode}\".");
break;
}
}
private void DeviceWrite(int offset, int data)
{
_device?.Write(offset * 4, data);
}
public void Dispose()
{
_commandQueue.Dispose();
_devices.Dispose();
}
}
}

View file

@ -0,0 +1,21 @@
namespace Ryujinx.Graphics.Host1x
{
enum OpCode
{
SetClass,
Incr,
NonIncr,
Mask,
Imm,
Restart,
Gather,
SetStrmId,
SetAppId,
SetPyld,
IncrW,
NonIncrW,
GatherW,
RestartW,
Extend
}
}

View file

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Ryujinx.Graphics.Device\Ryujinx.Graphics.Device.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,99 @@
using Ryujinx.Graphics.Gpu.Synchronization;
using System.Collections.Generic;
namespace Ryujinx.Graphics.Host1x
{
class SyncptIncrManager
{
private readonly SynchronizationManager _syncMgr;
private readonly struct SyncptIncr
{
public uint Id { get; }
public ClassId ClassId { get; }
public uint SyncptId { get; }
public bool Done { get; }
public SyncptIncr(uint id, ClassId classId, uint syncptId, bool done = false)
{
Id = id;
ClassId = classId;
SyncptId = syncptId;
Done = done;
}
}
private readonly List<SyncptIncr> _incrs = new List<SyncptIncr>();
private uint _currentId;
public SyncptIncrManager(SynchronizationManager syncMgr)
{
_syncMgr = syncMgr;
}
public void Increment(uint id)
{
lock (_incrs)
{
_incrs.Add(new SyncptIncr(0, 0, id, true));
IncrementAllDone();
}
}
public uint IncrementWhenDone(ClassId classId, uint id)
{
lock (_incrs)
{
uint handle = _currentId++;
_incrs.Add(new SyncptIncr(handle, classId, id));
return handle;
}
}
public void SignalDone(uint handle)
{
lock (_incrs)
{
// Set pending increment with the given handle to "done".
for (int i = 0; i < _incrs.Count; i++)
{
SyncptIncr incr = _incrs[i];
if (_incrs[i].Id == handle)
{
_incrs[i] = new SyncptIncr(incr.Id, incr.ClassId, incr.SyncptId, true);
break;
}
}
IncrementAllDone();
}
}
private void IncrementAllDone()
{
lock (_incrs)
{
// Increment all sequential pending increments that are already done.
int doneCount = 0;
for (; doneCount < _incrs.Count; doneCount++)
{
if (!_incrs[doneCount].Done)
{
break;
}
_syncMgr.IncrementSyncpoint(_incrs[doneCount].SyncptId);
}
_incrs.RemoveRange(0, doneCount);
}
}
}
}

View file

@ -0,0 +1,137 @@
using Ryujinx.Common;
using Ryujinx.Graphics.Device;
using System;
using System.Collections.Generic;
namespace Ryujinx.Graphics.Host1x
{
class ThiDevice : IDeviceStateWithContext, IDisposable
{
private readonly ClassId _classId;
private readonly IDeviceState _device;
private readonly SyncptIncrManager _syncptIncrMgr;
private long _currentContextId;
private long _previousContextId;
private class CommandAction
{
public long ContextId { get; }
public int Data { get; }
public CommandAction(long contextId, int data)
{
ContextId = contextId;
Data = data;
}
}
private class MethodCallAction : CommandAction
{
public int Method { get; }
public MethodCallAction(long contextId, int method, int data) : base(contextId, data)
{
Method = method;
}
}
private class SyncptIncrAction : CommandAction
{
public SyncptIncrAction(long contextId, uint syncptIncrHandle) : base(contextId, (int)syncptIncrHandle)
{
}
}
private readonly AsyncWorkQueue<CommandAction> _commandQueue;
private readonly DeviceState<ThiRegisters> _state;
public ThiDevice(ClassId classId, IDeviceState device, SyncptIncrManager syncptIncrMgr)
{
_classId = classId;
_device = device;
_syncptIncrMgr = syncptIncrMgr;
_commandQueue = new AsyncWorkQueue<CommandAction>(Process, $"Ryujinx.{classId}Processor");
_state = new DeviceState<ThiRegisters>(new Dictionary<string, RwCallback>
{
{ nameof(ThiRegisters.IncrSyncpt), new RwCallback(IncrSyncpt, null) },
{ nameof(ThiRegisters.Method1), new RwCallback(Method1, null) }
});
_previousContextId = -1;
}
public long CreateContext()
{
if (_device is IDeviceStateWithContext deviceWithContext)
{
return deviceWithContext.CreateContext();
}
return -1;
}
public void DestroyContext(long id)
{
if (_device is IDeviceStateWithContext deviceWithContext)
{
deviceWithContext.DestroyContext(id);
}
}
public void BindContext(long id)
{
_currentContextId = id;
}
public int Read(int offset) => _state.Read(offset);
public void Write(int offset, int data) => _state.Write(offset, data);
private void IncrSyncpt(int data)
{
uint syncpointId = (uint)(data & 0xFF);
uint cond = (uint)((data >> 8) & 0xFF); // 0 = Immediate, 1 = Done
if (cond == 0)
{
_syncptIncrMgr.Increment(syncpointId);
}
else
{
_commandQueue.Add(new SyncptIncrAction(_currentContextId, _syncptIncrMgr.IncrementWhenDone(_classId, syncpointId)));
}
}
private void Method1(int data)
{
_commandQueue.Add(new MethodCallAction(_currentContextId, (int)_state.State.Method0 * sizeof(uint), data));
}
private void Process(CommandAction cmdAction)
{
long contextId = cmdAction.ContextId;
if (contextId != _previousContextId)
{
_previousContextId = contextId;
if (_device is IDeviceStateWithContext deviceWithContext)
{
deviceWithContext.BindContext(contextId);
}
}
if (cmdAction is SyncptIncrAction syncptIncrAction)
{
_syncptIncrMgr.SignalDone((uint)syncptIncrAction.Data);
}
else if (cmdAction is MethodCallAction methodCallAction)
{
_device.Write(methodCallAction.Method, methodCallAction.Data);
}
}
public void Dispose() => _commandQueue.Dispose();
}
}

View file

@ -0,0 +1,24 @@
using Ryujinx.Common.Memory;
namespace Ryujinx.Graphics.Host1x
{
struct ThiRegisters
{
#pragma warning disable CS0649
public uint IncrSyncpt;
public uint Reserved4;
public uint IncrSyncptErr;
public uint CtxswIncrSyncpt;
public Array4<uint> Reserved10;
public uint Ctxsw;
public uint Reserved24;
public uint ContSyncptEof;
public Array5<uint> Reserved2C;
public uint Method0;
public uint Method1;
public Array12<uint> Reserved48;
public uint IntStatus;
public uint IntMask;
#pragma warning restore CS0649
}
}