Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
76b53e018a | ||
|
28dd7d80af | ||
|
1e06b28b22 | ||
|
e768a54f17 | ||
|
4e2bb13080 |
@@ -7,14 +7,14 @@ namespace ARMeilleure.Translation
|
||||
internal class TranslatorCache<T>
|
||||
{
|
||||
private readonly IntervalTree<ulong, T> _tree;
|
||||
private readonly ReaderWriterLock _treeLock;
|
||||
private readonly ReaderWriterLockSlim _treeLock;
|
||||
|
||||
public int Count => _tree.Count;
|
||||
|
||||
public TranslatorCache()
|
||||
{
|
||||
_tree = new IntervalTree<ulong, T>();
|
||||
_treeLock = new ReaderWriterLock();
|
||||
_treeLock = new ReaderWriterLockSlim();
|
||||
}
|
||||
|
||||
public bool TryAdd(ulong address, ulong size, T value)
|
||||
@@ -24,70 +24,70 @@ namespace ARMeilleure.Translation
|
||||
|
||||
public bool AddOrUpdate(ulong address, ulong size, T value, Func<ulong, T, T> updateFactoryCallback)
|
||||
{
|
||||
_treeLock.AcquireWriterLock(Timeout.Infinite);
|
||||
_treeLock.EnterWriteLock();
|
||||
bool result = _tree.AddOrUpdate(address, address + size, value, updateFactoryCallback);
|
||||
_treeLock.ReleaseWriterLock();
|
||||
_treeLock.ExitWriteLock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public T GetOrAdd(ulong address, ulong size, T value)
|
||||
{
|
||||
_treeLock.AcquireWriterLock(Timeout.Infinite);
|
||||
_treeLock.EnterWriteLock();
|
||||
value = _tree.GetOrAdd(address, address + size, value);
|
||||
_treeLock.ReleaseWriterLock();
|
||||
_treeLock.ExitWriteLock();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public bool Remove(ulong address)
|
||||
{
|
||||
_treeLock.AcquireWriterLock(Timeout.Infinite);
|
||||
_treeLock.EnterWriteLock();
|
||||
bool removed = _tree.Remove(address) != 0;
|
||||
_treeLock.ReleaseWriterLock();
|
||||
_treeLock.ExitWriteLock();
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_treeLock.AcquireWriterLock(Timeout.Infinite);
|
||||
_treeLock.EnterWriteLock();
|
||||
_tree.Clear();
|
||||
_treeLock.ReleaseWriterLock();
|
||||
_treeLock.ExitWriteLock();
|
||||
}
|
||||
|
||||
public bool ContainsKey(ulong address)
|
||||
{
|
||||
_treeLock.AcquireReaderLock(Timeout.Infinite);
|
||||
_treeLock.EnterReadLock();
|
||||
bool result = _tree.ContainsKey(address);
|
||||
_treeLock.ReleaseReaderLock();
|
||||
_treeLock.ExitReadLock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool TryGetValue(ulong address, out T value)
|
||||
{
|
||||
_treeLock.AcquireReaderLock(Timeout.Infinite);
|
||||
_treeLock.EnterReadLock();
|
||||
bool result = _tree.TryGet(address, out value);
|
||||
_treeLock.ReleaseReaderLock();
|
||||
_treeLock.ExitReadLock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public int GetOverlaps(ulong address, ulong size, ref ulong[] overlaps)
|
||||
{
|
||||
_treeLock.AcquireReaderLock(Timeout.Infinite);
|
||||
_treeLock.EnterReadLock();
|
||||
int count = _tree.Get(address, address + size, ref overlaps);
|
||||
_treeLock.ReleaseReaderLock();
|
||||
_treeLock.ExitReadLock();
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public List<T> AsList()
|
||||
{
|
||||
_treeLock.AcquireReaderLock(Timeout.Infinite);
|
||||
_treeLock.EnterReadLock();
|
||||
List<T> list = _tree.AsList();
|
||||
_treeLock.ReleaseReaderLock();
|
||||
_treeLock.ExitReadLock();
|
||||
|
||||
return list;
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ namespace Ryujinx.Common
|
||||
{
|
||||
public class ReactiveObject<T>
|
||||
{
|
||||
private readonly ReaderWriterLock _readerWriterLock = new();
|
||||
private readonly ReaderWriterLockSlim _readerWriterLock = new();
|
||||
private bool _isInitialized;
|
||||
private T _value;
|
||||
|
||||
@@ -15,15 +15,15 @@ namespace Ryujinx.Common
|
||||
{
|
||||
get
|
||||
{
|
||||
_readerWriterLock.AcquireReaderLock(Timeout.Infinite);
|
||||
_readerWriterLock.EnterReadLock();
|
||||
T value = _value;
|
||||
_readerWriterLock.ReleaseReaderLock();
|
||||
_readerWriterLock.ExitReadLock();
|
||||
|
||||
return value;
|
||||
}
|
||||
set
|
||||
{
|
||||
_readerWriterLock.AcquireWriterLock(Timeout.Infinite);
|
||||
_readerWriterLock.EnterWriteLock();
|
||||
|
||||
T oldValue = _value;
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Ryujinx.Common
|
||||
_isInitialized = true;
|
||||
_value = value;
|
||||
|
||||
_readerWriterLock.ReleaseWriterLock();
|
||||
_readerWriterLock.ExitWriteLock();
|
||||
|
||||
if (!oldIsInitialized || oldValue == null || !oldValue.Equals(_value))
|
||||
{
|
||||
|
@@ -38,6 +38,7 @@ namespace Ryujinx.Graphics.GAL
|
||||
public readonly bool SupportsShaderBallot;
|
||||
public readonly bool SupportsShaderBarrierDivergence;
|
||||
public readonly bool SupportsShaderFloat64;
|
||||
public readonly bool SupportsTextureGatherOffsets;
|
||||
public readonly bool SupportsTextureShadowLod;
|
||||
public readonly bool SupportsVertexStoreAndAtomics;
|
||||
public readonly bool SupportsViewportIndexVertexTessellation;
|
||||
@@ -92,6 +93,7 @@ namespace Ryujinx.Graphics.GAL
|
||||
bool supportsShaderBallot,
|
||||
bool supportsShaderBarrierDivergence,
|
||||
bool supportsShaderFloat64,
|
||||
bool supportsTextureGatherOffsets,
|
||||
bool supportsTextureShadowLod,
|
||||
bool supportsVertexStoreAndAtomics,
|
||||
bool supportsViewportIndexVertexTessellation,
|
||||
@@ -142,6 +144,7 @@ namespace Ryujinx.Graphics.GAL
|
||||
SupportsShaderBallot = supportsShaderBallot;
|
||||
SupportsShaderBarrierDivergence = supportsShaderBarrierDivergence;
|
||||
SupportsShaderFloat64 = supportsShaderFloat64;
|
||||
SupportsTextureGatherOffsets = supportsTextureGatherOffsets;
|
||||
SupportsTextureShadowLod = supportsTextureShadowLod;
|
||||
SupportsVertexStoreAndAtomics = supportsVertexStoreAndAtomics;
|
||||
SupportsViewportIndexVertexTessellation = supportsViewportIndexVertexTessellation;
|
||||
|
@@ -374,6 +374,13 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
return stride == rhs.Stride ? TextureViewCompatibility.CopyOnly : TextureViewCompatibility.LayoutIncompatible;
|
||||
}
|
||||
else if (lhs.Target.IsMultisample() != rhs.Target.IsMultisample() && alignedWidthMatches && lhsAlignedSize.Height == rhsAlignedSize.Height)
|
||||
{
|
||||
// Copy between multisample and non-multisample textures with mismatching size is allowed,
|
||||
// as long aligned size matches.
|
||||
|
||||
return TextureViewCompatibility.CopyOnly;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TextureViewCompatibility.LayoutIncompatible;
|
||||
|
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
||||
private const ushort FileFormatVersionMajor = 1;
|
||||
private const ushort FileFormatVersionMinor = 2;
|
||||
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
||||
private const uint CodeGenVersion = 5767;
|
||||
private const uint CodeGenVersion = 5791;
|
||||
|
||||
private const string SharedTocFileName = "shared.toc";
|
||||
private const string SharedDataFileName = "shared.data";
|
||||
|
@@ -186,6 +186,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
|
||||
public bool QueryHostSupportsSnormBufferTextureFormat() => _context.Capabilities.SupportsSnormBufferTextureFormat;
|
||||
|
||||
public bool QueryHostSupportsTextureGatherOffsets() => _context.Capabilities.SupportsTextureGatherOffsets;
|
||||
|
||||
public bool QueryHostSupportsTextureShadowLod() => _context.Capabilities.SupportsTextureShadowLod;
|
||||
|
||||
public bool QueryHostSupportsTransformFeedback() => _context.Capabilities.SupportsTransformFeedback;
|
||||
|
@@ -163,6 +163,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||
supportsShaderBallot: HwCapabilities.SupportsShaderBallot,
|
||||
supportsShaderBarrierDivergence: !(intelWindows || intelUnix),
|
||||
supportsShaderFloat64: true,
|
||||
supportsTextureGatherOffsets: true,
|
||||
supportsTextureShadowLod: HwCapabilities.SupportsTextureShadowLod,
|
||||
supportsVertexStoreAndAtomics: true,
|
||||
supportsViewportIndexVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
|
||||
|
@@ -339,6 +339,15 @@ namespace Ryujinx.Graphics.Shader
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries host GPU texture gather with multiple offsets support.
|
||||
/// </summary>
|
||||
/// <returns>True if the GPU and driver supports texture gather offsets, false otherwise</returns>
|
||||
bool QueryHostSupportsTextureGatherOffsets()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries host GPU texture shadow LOD support.
|
||||
/// </summary>
|
||||
|
@@ -303,7 +303,9 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
||||
bool hasOffset = (texOp.Flags & TextureFlags.Offset) != 0;
|
||||
bool hasOffsets = (texOp.Flags & TextureFlags.Offsets) != 0;
|
||||
|
||||
bool hasInvalidOffset = (hasOffset || hasOffsets) && !gpuAccessor.QueryHostSupportsNonConstantTextureOffset();
|
||||
bool needsOffsetsEmulation = hasOffsets && !gpuAccessor.QueryHostSupportsTextureGatherOffsets();
|
||||
|
||||
bool hasInvalidOffset = needsOffsetsEmulation || ((hasOffset || hasOffsets) && !gpuAccessor.QueryHostSupportsNonConstantTextureOffset());
|
||||
|
||||
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
|
||||
|
||||
@@ -402,11 +404,14 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
||||
offsets[index] = offset;
|
||||
}
|
||||
|
||||
hasInvalidOffset &= !areAllOffsetsConstant;
|
||||
|
||||
if (!hasInvalidOffset)
|
||||
if (!needsOffsetsEmulation)
|
||||
{
|
||||
return node;
|
||||
hasInvalidOffset &= !areAllOffsetsConstant;
|
||||
|
||||
if (!hasInvalidOffset)
|
||||
{
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasLodBias)
|
||||
@@ -434,13 +439,13 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
||||
|
||||
LinkedListNode<INode> oldNode = node;
|
||||
|
||||
if (isGather && !isShadow)
|
||||
if (isGather && !isShadow && hasOffsets)
|
||||
{
|
||||
Operand[] newSources = new Operand[sources.Length];
|
||||
|
||||
sources.CopyTo(newSources, 0);
|
||||
|
||||
Operand[] texSizes = InsertTextureLod(node, texOp, lodSources, bindlessHandle, coordsCount, stage);
|
||||
Operand[] texSizes = InsertTextureBaseSize(node, texOp, bindlessHandle, coordsCount);
|
||||
|
||||
int destIndex = 0;
|
||||
|
||||
@@ -455,7 +460,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
||||
{
|
||||
Operand offset = Local();
|
||||
|
||||
Operand intOffset = offsets[index + (hasOffsets ? compIndex * coordsCount : 0)];
|
||||
Operand intOffset = offsets[index + compIndex * coordsCount];
|
||||
|
||||
node.List.AddBefore(node, new Operation(
|
||||
Instruction.FP32 | Instruction.Divide,
|
||||
@@ -478,7 +483,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
||||
texOp.Format,
|
||||
texOp.Flags & ~(TextureFlags.Offset | TextureFlags.Offsets),
|
||||
texOp.Binding,
|
||||
1,
|
||||
1 << 3, // W component: i=0, j=0
|
||||
new[] { dests[destIndex++] },
|
||||
newSources);
|
||||
|
||||
@@ -502,7 +507,9 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
||||
}
|
||||
else
|
||||
{
|
||||
Operand[] texSizes = InsertTextureLod(node, texOp, lodSources, bindlessHandle, coordsCount, stage);
|
||||
Operand[] texSizes = isGather
|
||||
? InsertTextureBaseSize(node, texOp, bindlessHandle, coordsCount)
|
||||
: InsertTextureLod(node, texOp, lodSources, bindlessHandle, coordsCount, stage);
|
||||
|
||||
for (int index = 0; index < coordsCount; index++)
|
||||
{
|
||||
@@ -549,6 +556,43 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
||||
return node;
|
||||
}
|
||||
|
||||
private static Operand[] InsertTextureBaseSize(
|
||||
LinkedListNode<INode> node,
|
||||
TextureOperation texOp,
|
||||
Operand bindlessHandle,
|
||||
int coordsCount)
|
||||
{
|
||||
Operand[] texSizes = new Operand[coordsCount];
|
||||
|
||||
for (int index = 0; index < coordsCount; index++)
|
||||
{
|
||||
texSizes[index] = Local();
|
||||
|
||||
Operand[] texSizeSources;
|
||||
|
||||
if (bindlessHandle != null)
|
||||
{
|
||||
texSizeSources = new Operand[] { bindlessHandle, Const(0) };
|
||||
}
|
||||
else
|
||||
{
|
||||
texSizeSources = new Operand[] { Const(0) };
|
||||
}
|
||||
|
||||
node.List.AddBefore(node, new TextureOperation(
|
||||
Instruction.TextureQuerySize,
|
||||
texOp.Type,
|
||||
texOp.Format,
|
||||
texOp.Flags,
|
||||
texOp.Binding,
|
||||
index,
|
||||
new[] { texSizes[index] },
|
||||
texSizeSources));
|
||||
}
|
||||
|
||||
return texSizes;
|
||||
}
|
||||
|
||||
private static Operand[] InsertTextureLod(
|
||||
LinkedListNode<INode> node,
|
||||
TextureOperation texOp,
|
||||
|
@@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private int _flushTemp;
|
||||
private int _lastFlushWrite = -1;
|
||||
|
||||
private readonly ReaderWriterLock _flushLock;
|
||||
private readonly ReaderWriterLockSlim _flushLock;
|
||||
private FenceHolder _flushFence;
|
||||
private int _flushWaiting;
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_currentType = currentType;
|
||||
DesiredType = currentType;
|
||||
|
||||
_flushLock = new ReaderWriterLock();
|
||||
_flushLock = new ReaderWriterLockSlim();
|
||||
_useMirrors = gd.IsTBDR;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_currentType = currentType;
|
||||
DesiredType = currentType;
|
||||
|
||||
_flushLock = new ReaderWriterLock();
|
||||
_flushLock = new ReaderWriterLockSlim();
|
||||
}
|
||||
|
||||
public bool TryBackingSwap(ref CommandBufferScoped? cbs)
|
||||
@@ -116,7 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
// Only swap if the buffer is not used in any queued command buffer.
|
||||
bool isRented = _buffer.HasRentedCommandBufferDependency(_gd.CommandBufferPool);
|
||||
|
||||
if (!isRented && _gd.CommandBufferPool.OwnedByCurrentThread && !_flushLock.IsReaderLockHeld && (_pendingData == null || cbs != null))
|
||||
if (!isRented && _gd.CommandBufferPool.OwnedByCurrentThread && !_flushLock.IsReadLockHeld && (_pendingData == null || cbs != null))
|
||||
{
|
||||
var currentAllocation = _allocationAuto;
|
||||
var currentBuffer = _buffer;
|
||||
@@ -131,7 +131,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ClearMirrors(cbs.Value, 0, Size);
|
||||
}
|
||||
|
||||
_flushLock.AcquireWriterLock(Timeout.Infinite);
|
||||
_flushLock.EnterWriteLock();
|
||||
|
||||
ClearFlushFence();
|
||||
|
||||
@@ -185,7 +185,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
_gd.PipelineInternal.SwapBuffer(currentBuffer, _buffer);
|
||||
|
||||
_flushLock.ReleaseWriterLock();
|
||||
_flushLock.ExitWriteLock();
|
||||
}
|
||||
|
||||
_swapQueued = false;
|
||||
@@ -548,42 +548,44 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
private void WaitForFlushFence()
|
||||
{
|
||||
// Assumes the _flushLock is held as reader, returns in same state.
|
||||
if (_flushFence == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If storage has changed, make sure the fence has been reached so that the data is in place.
|
||||
_flushLock.ExitReadLock();
|
||||
_flushLock.EnterWriteLock();
|
||||
|
||||
if (_flushFence != null)
|
||||
{
|
||||
// If storage has changed, make sure the fence has been reached so that the data is in place.
|
||||
var fence = _flushFence;
|
||||
Interlocked.Increment(ref _flushWaiting);
|
||||
|
||||
var cookie = _flushLock.UpgradeToWriterLock(Timeout.Infinite);
|
||||
// Don't wait in the lock.
|
||||
|
||||
if (_flushFence != null)
|
||||
_flushLock.ExitWriteLock();
|
||||
|
||||
fence.Wait();
|
||||
|
||||
_flushLock.EnterWriteLock();
|
||||
|
||||
if (Interlocked.Decrement(ref _flushWaiting) == 0)
|
||||
{
|
||||
var fence = _flushFence;
|
||||
Interlocked.Increment(ref _flushWaiting);
|
||||
|
||||
// Don't wait in the lock.
|
||||
|
||||
var restoreCookie = _flushLock.ReleaseLock();
|
||||
|
||||
fence.Wait();
|
||||
|
||||
_flushLock.RestoreLock(ref restoreCookie);
|
||||
|
||||
if (Interlocked.Decrement(ref _flushWaiting) == 0)
|
||||
{
|
||||
fence.Put();
|
||||
}
|
||||
|
||||
_flushFence = null;
|
||||
fence.Put();
|
||||
}
|
||||
|
||||
_flushLock.DowngradeFromWriterLock(ref cookie);
|
||||
_flushFence = null;
|
||||
}
|
||||
|
||||
// Assumes the _flushLock is held as reader, returns in same state.
|
||||
_flushLock.ExitWriteLock();
|
||||
_flushLock.EnterReadLock();
|
||||
}
|
||||
|
||||
public PinnedSpan<byte> GetData(int offset, int size)
|
||||
{
|
||||
_flushLock.AcquireReaderLock(Timeout.Infinite);
|
||||
_flushLock.EnterReadLock();
|
||||
|
||||
WaitForFlushFence();
|
||||
|
||||
@@ -603,7 +605,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
// Need to be careful here, the buffer can't be unmapped while the data is being used.
|
||||
_buffer.IncrementReferenceCount();
|
||||
|
||||
_flushLock.ReleaseReaderLock();
|
||||
_flushLock.ExitReadLock();
|
||||
|
||||
return PinnedSpan<byte>.UnsafeFromSpan(result, _buffer.DecrementReferenceCount);
|
||||
}
|
||||
@@ -621,7 +623,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
result = resource.GetFlushBuffer().GetBufferData(resource.GetPool(), this, offset, size);
|
||||
}
|
||||
|
||||
_flushLock.ReleaseReaderLock();
|
||||
_flushLock.ExitReadLock();
|
||||
|
||||
// Flush buffer is pinned until the next GetBufferData on the thread, which is fine for current uses.
|
||||
return PinnedSpan<byte>.UnsafeFromSpan(result);
|
||||
@@ -1073,11 +1075,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_allocationAuto.Dispose();
|
||||
}
|
||||
|
||||
_flushLock.AcquireWriterLock(Timeout.Infinite);
|
||||
_flushLock.EnterWriteLock();
|
||||
|
||||
ClearFlushFence();
|
||||
|
||||
_flushLock.ReleaseWriterLock();
|
||||
_flushLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -605,6 +605,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
supportsShaderBallot: false,
|
||||
supportsShaderBarrierDivergence: Vendor != Vendor.Intel,
|
||||
supportsShaderFloat64: Capabilities.SupportsShaderFloat64,
|
||||
supportsTextureGatherOffsets: features2.Features.ShaderImageGatherExtended && !IsMoltenVk,
|
||||
supportsTextureShadowLod: false,
|
||||
supportsVertexStoreAndAtomics: features2.Features.VertexPipelineStoresAndAtomics,
|
||||
supportsViewportIndexVertexTessellation: featuresVk12.ShaderOutputViewportIndex,
|
||||
|
@@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Ins
|
||||
{
|
||||
[Service("ins:r")]
|
||||
class IReceiverManager : IpcService
|
||||
{
|
||||
public IReceiverManager(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Ins
|
||||
{
|
||||
[Service("ins:s")]
|
||||
class ISenderManager : IpcService
|
||||
{
|
||||
public ISenderManager(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -29,6 +29,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
|
||||
private const bool IsDevelopment = false;
|
||||
|
||||
private readonly KEvent _stateChangeEvent;
|
||||
private int _stateChangeEventHandle;
|
||||
|
||||
private NetworkState _state;
|
||||
private DisconnectReason _disconnectReason;
|
||||
@@ -277,12 +278,12 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
|
||||
// AttachStateChangeEvent() -> handle<copy>
|
||||
public ResultCode AttachStateChangeEvent(ServiceCtx context)
|
||||
{
|
||||
if (context.Process.HandleTable.GenerateHandle(_stateChangeEvent.ReadableEvent, out int stateChangeEventHandle) != Result.Success)
|
||||
if (_stateChangeEventHandle == 0 && context.Process.HandleTable.GenerateHandle(_stateChangeEvent.ReadableEvent, out _stateChangeEventHandle) != Result.Success)
|
||||
{
|
||||
throw new InvalidOperationException("Out of handles!");
|
||||
}
|
||||
|
||||
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(stateChangeEventHandle);
|
||||
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_stateChangeEventHandle);
|
||||
|
||||
// Returns ResultCode.InvalidArgument if handle is null, doesn't occur in our case since we already throw an Exception.
|
||||
|
||||
@@ -964,6 +965,12 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
|
||||
SetDisconnectReason(DisconnectReason.None);
|
||||
}
|
||||
|
||||
if (_stateChangeEventHandle != 0)
|
||||
{
|
||||
context.Process.HandleTable.CloseHandle(_stateChangeEventHandle);
|
||||
_stateChangeEventHandle = 0;
|
||||
}
|
||||
|
||||
return resultCode;
|
||||
}
|
||||
|
||||
@@ -1021,7 +1028,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
|
||||
|
||||
SetState(NetworkState.None);
|
||||
|
||||
NetworkClient?.DisconnectAndStop();
|
||||
NetworkClient?.Dispose();
|
||||
NetworkClient = null;
|
||||
|
||||
return ResultCode.Success;
|
||||
@@ -1072,7 +1079,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: Service returns differents ResultCode here related to the nifm ResultCode.
|
||||
// NOTE: Service returns different ResultCode here related to the nifm ResultCode.
|
||||
resultCode = ResultCode.DeviceDisabled;
|
||||
_nifmResultCode = resultCode;
|
||||
}
|
||||
@@ -1084,14 +1091,13 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (NetworkClient != null)
|
||||
{
|
||||
_station?.Dispose();
|
||||
_accessPoint?.Dispose();
|
||||
_station?.Dispose();
|
||||
_station = null;
|
||||
|
||||
NetworkClient.DisconnectAndStop();
|
||||
}
|
||||
_accessPoint?.Dispose();
|
||||
_accessPoint = null;
|
||||
|
||||
NetworkClient?.Dispose();
|
||||
NetworkClient = null;
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Ovln
|
||||
{
|
||||
[Service("ovln:rcv")]
|
||||
class IReceiverService : IpcService
|
||||
{
|
||||
public IReceiverService(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Ovln
|
||||
{
|
||||
[Service("ovln:snd")]
|
||||
class ISenderService : IpcService
|
||||
{
|
||||
public ISenderService(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Psc
|
||||
{
|
||||
[Service("psc:c")]
|
||||
class IPmControl : IpcService
|
||||
{
|
||||
public IPmControl(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Psc
|
||||
{
|
||||
[Service("psc:m")]
|
||||
class IPmService : IpcService
|
||||
{
|
||||
public IPmService(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Psc
|
||||
{
|
||||
[Service("psc:l")] // 9.0.0+
|
||||
class IPmUnknown : IpcService
|
||||
{
|
||||
public IPmUnknown(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Srepo
|
||||
{
|
||||
[Service("srepo:a")] // 5.0.0+
|
||||
[Service("srepo:u")] // 5.0.0+
|
||||
class ISrepoService : IpcService
|
||||
{
|
||||
public ISrepoService(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Usb
|
||||
{
|
||||
[Service("usb:hs")]
|
||||
[Service("usb:hs:a")] // 7.0.0+
|
||||
class IClientRootSession : IpcService
|
||||
{
|
||||
public IClientRootSession(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Usb
|
||||
{
|
||||
[Service("usb:ds")]
|
||||
class IDsService : IpcService
|
||||
{
|
||||
public IDsService(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Usb
|
||||
{
|
||||
[Service("usb:pd:c")]
|
||||
class IPdCradleManager : IpcService
|
||||
{
|
||||
public IPdCradleManager(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Usb
|
||||
{
|
||||
[Service("usb:pd")]
|
||||
class IPdManager : IpcService
|
||||
{
|
||||
public IPdManager(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Usb
|
||||
{
|
||||
[Service("usb:pm")]
|
||||
class IPmService : IpcService
|
||||
{
|
||||
public IPmService(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Usb
|
||||
{
|
||||
[Service("usb:qdb")] // 7.0.0+
|
||||
class IUnknown1 : IpcService
|
||||
{
|
||||
public IUnknown1(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Usb
|
||||
{
|
||||
[Service("usb:obsv")] // 8.0.0+
|
||||
class IUnknown2 : IpcService
|
||||
{
|
||||
public IUnknown2(ServiceCtx context) { }
|
||||
}
|
||||
}
|
@@ -93,7 +93,7 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
||||
generator.LeaveScope();
|
||||
generator.LeaveScope();
|
||||
|
||||
context.AddSource($"{className}.g.cs", generator.ToString());
|
||||
context.AddSource($"{GetNamespaceName(commandInterface.ClassDeclarationSyntax)}.{className}.g.cs", generator.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
47
src/Ryujinx.Horizon/Hshl/HshlIpcServer.cs
Normal file
47
src/Ryujinx.Horizon/Hshl/HshlIpcServer.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using Ryujinx.Horizon.Hshl.Ipc;
|
||||
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
||||
using Ryujinx.Horizon.Sdk.Sm;
|
||||
|
||||
namespace Ryujinx.Horizon.Hshl
|
||||
{
|
||||
class HshlIpcServer
|
||||
{
|
||||
private const int HshlMaxSessionsCount = 10;
|
||||
private const int TotalMaxSessionsCount = HshlMaxSessionsCount * 2;
|
||||
|
||||
private const int PointerBufferSize = 0;
|
||||
private const int MaxDomains = 0;
|
||||
private const int MaxDomainObjects = 0;
|
||||
private const int MaxPortsCount = 2;
|
||||
|
||||
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
||||
|
||||
private SmApi _sm;
|
||||
private ServerManager _serverManager;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
HeapAllocator allocator = new();
|
||||
|
||||
_sm = new SmApi();
|
||||
_sm.Initialize().AbortOnFailure();
|
||||
|
||||
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
_serverManager.RegisterObjectForServer(new SetterManager(), ServiceName.Encode("hshl:set"), HshlMaxSessionsCount); // 11.0.0+
|
||||
_serverManager.RegisterObjectForServer(new Manager(), ServiceName.Encode("hshl:sys"), HshlMaxSessionsCount); // 11.0.0+
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
|
||||
public void ServiceRequests()
|
||||
{
|
||||
_serverManager.ServiceRequests();
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
_serverManager.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
17
src/Ryujinx.Horizon/Hshl/HshlMain.cs
Normal file
17
src/Ryujinx.Horizon/Hshl/HshlMain.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace Ryujinx.Horizon.Hshl
|
||||
{
|
||||
class HshlMain : IService
|
||||
{
|
||||
public static void Main(ServiceTable serviceTable)
|
||||
{
|
||||
HshlIpcServer ipcServer = new();
|
||||
|
||||
ipcServer.Initialize();
|
||||
|
||||
serviceTable.SignalServiceReady();
|
||||
|
||||
ipcServer.ServiceRequests();
|
||||
ipcServer.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Hshl/Ipc/Manager.cs
Normal file
8
src/Ryujinx.Horizon/Hshl/Ipc/Manager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Hshl;
|
||||
|
||||
namespace Ryujinx.Horizon.Hshl.Ipc
|
||||
{
|
||||
partial class Manager : IManager
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Hshl/Ipc/SetterManager.cs
Normal file
8
src/Ryujinx.Horizon/Hshl/Ipc/SetterManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Hshl;
|
||||
|
||||
namespace Ryujinx.Horizon.Hshl.Ipc
|
||||
{
|
||||
partial class SetterManager : ISetterManager
|
||||
{
|
||||
}
|
||||
}
|
47
src/Ryujinx.Horizon/Ins/InsIpcServer.cs
Normal file
47
src/Ryujinx.Horizon/Ins/InsIpcServer.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using Ryujinx.Horizon.Ins.Ipc;
|
||||
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
||||
using Ryujinx.Horizon.Sdk.Sm;
|
||||
|
||||
namespace Ryujinx.Horizon.Ins
|
||||
{
|
||||
class InsIpcServer
|
||||
{
|
||||
private const int InsMaxSessionsCount = 8;
|
||||
private const int TotalMaxSessionsCount = InsMaxSessionsCount * 2;
|
||||
|
||||
private const int PointerBufferSize = 0x200;
|
||||
private const int MaxDomains = 0;
|
||||
private const int MaxDomainObjects = 0;
|
||||
private const int MaxPortsCount = 2;
|
||||
|
||||
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
||||
|
||||
private SmApi _sm;
|
||||
private ServerManager _serverManager;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
HeapAllocator allocator = new();
|
||||
|
||||
_sm = new SmApi();
|
||||
_sm.Initialize().AbortOnFailure();
|
||||
|
||||
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
_serverManager.RegisterObjectForServer(new ReceiverManager(), ServiceName.Encode("ins:r"), InsMaxSessionsCount); // 9.0.0+
|
||||
_serverManager.RegisterObjectForServer(new SenderManager(), ServiceName.Encode("ins:s"), InsMaxSessionsCount); // 9.0.0+
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
|
||||
public void ServiceRequests()
|
||||
{
|
||||
_serverManager.ServiceRequests();
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
_serverManager.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
17
src/Ryujinx.Horizon/Ins/InsMain.cs
Normal file
17
src/Ryujinx.Horizon/Ins/InsMain.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace Ryujinx.Horizon.Ins
|
||||
{
|
||||
class InsMain : IService
|
||||
{
|
||||
public static void Main(ServiceTable serviceTable)
|
||||
{
|
||||
InsIpcServer ipcServer = new();
|
||||
|
||||
ipcServer.Initialize();
|
||||
|
||||
serviceTable.SignalServiceReady();
|
||||
|
||||
ipcServer.ServiceRequests();
|
||||
ipcServer.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Ins/Ipc/ReceiverManager.cs
Normal file
8
src/Ryujinx.Horizon/Ins/Ipc/ReceiverManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Ins;
|
||||
|
||||
namespace Ryujinx.Horizon.Ins.Ipc
|
||||
{
|
||||
partial class ReceiverManager : IReceiverManager
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Ins/Ipc/SenderManager.cs
Normal file
8
src/Ryujinx.Horizon/Ins/Ipc/SenderManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Ins;
|
||||
|
||||
namespace Ryujinx.Horizon.Ins.Ipc
|
||||
{
|
||||
partial class SenderManager : ISenderManager
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Ovln/Ipc/ReceiverService.cs
Normal file
8
src/Ryujinx.Horizon/Ovln/Ipc/ReceiverService.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Ovln;
|
||||
|
||||
namespace Ryujinx.Horizon.Ovln.Ipc
|
||||
{
|
||||
partial class ReceiverService : IReceiverService
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Ovln/Ipc/SenderService.cs
Normal file
8
src/Ryujinx.Horizon/Ovln/Ipc/SenderService.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Ovln;
|
||||
|
||||
namespace Ryujinx.Horizon.Ovln.Ipc
|
||||
{
|
||||
partial class SenderService : ISenderService
|
||||
{
|
||||
}
|
||||
}
|
48
src/Ryujinx.Horizon/Ovln/OvlnIpcServer.cs
Normal file
48
src/Ryujinx.Horizon/Ovln/OvlnIpcServer.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using Ryujinx.Horizon.Ovln.Ipc;
|
||||
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
||||
using Ryujinx.Horizon.Sdk.Sm;
|
||||
|
||||
namespace Ryujinx.Horizon.Ovln
|
||||
{
|
||||
class OvlnIpcServer
|
||||
{
|
||||
private const int OvlnRcvMaxSessionsCount = 2;
|
||||
private const int OvlnSndMaxSessionsCount = 20;
|
||||
private const int TotalMaxSessionsCount = OvlnRcvMaxSessionsCount + OvlnSndMaxSessionsCount;
|
||||
|
||||
private const int PointerBufferSize = 0;
|
||||
private const int MaxDomains = 21;
|
||||
private const int MaxDomainObjects = 60;
|
||||
private const int MaxPortsCount = 2;
|
||||
|
||||
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
||||
|
||||
private SmApi _sm;
|
||||
private ServerManager _serverManager;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
HeapAllocator allocator = new();
|
||||
|
||||
_sm = new SmApi();
|
||||
_sm.Initialize().AbortOnFailure();
|
||||
|
||||
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
_serverManager.RegisterObjectForServer(new ReceiverService(), ServiceName.Encode("ovln:rcv"), OvlnRcvMaxSessionsCount); // 8.0.0+
|
||||
_serverManager.RegisterObjectForServer(new SenderService(), ServiceName.Encode("ovln:snd"), OvlnSndMaxSessionsCount); // 8.0.0+
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
|
||||
public void ServiceRequests()
|
||||
{
|
||||
_serverManager.ServiceRequests();
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
_serverManager.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
17
src/Ryujinx.Horizon/Ovln/OvlnMain.cs
Normal file
17
src/Ryujinx.Horizon/Ovln/OvlnMain.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace Ryujinx.Horizon.Ovln
|
||||
{
|
||||
class OvlnMain : IService
|
||||
{
|
||||
public static void Main(ServiceTable serviceTable)
|
||||
{
|
||||
OvlnIpcServer ipcServer = new();
|
||||
|
||||
ipcServer.Initialize();
|
||||
|
||||
serviceTable.SignalServiceReady();
|
||||
|
||||
ipcServer.ServiceRequests();
|
||||
ipcServer.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Psc/Ipc/PmControl.cs
Normal file
8
src/Ryujinx.Horizon/Psc/Ipc/PmControl.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Psc;
|
||||
|
||||
namespace Ryujinx.Horizon.Psc.Ipc
|
||||
{
|
||||
partial class PmControl : IPmControl
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Psc/Ipc/PmService.cs
Normal file
8
src/Ryujinx.Horizon/Psc/Ipc/PmService.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Psc;
|
||||
|
||||
namespace Ryujinx.Horizon.Psc.Ipc
|
||||
{
|
||||
partial class PmService : IPmService
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Psc/Ipc/PmStateLock.cs
Normal file
8
src/Ryujinx.Horizon/Psc/Ipc/PmStateLock.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Psc;
|
||||
|
||||
namespace Ryujinx.Horizon.Psc.Ipc
|
||||
{
|
||||
partial class PmStateLock : IPmStateLock
|
||||
{
|
||||
}
|
||||
}
|
50
src/Ryujinx.Horizon/Psc/PscIpcServer.cs
Normal file
50
src/Ryujinx.Horizon/Psc/PscIpcServer.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using Ryujinx.Horizon.Psc.Ipc;
|
||||
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
||||
using Ryujinx.Horizon.Sdk.Sm;
|
||||
|
||||
namespace Ryujinx.Horizon.Psc
|
||||
{
|
||||
class PscIpcServer
|
||||
{
|
||||
private const int PscCMaxSessionsCount = 1;
|
||||
private const int PscMMaxSessionsCount = 50;
|
||||
private const int PscLMaxSessionsCount = 5;
|
||||
private const int TotalMaxSessionsCount = PscCMaxSessionsCount + PscMMaxSessionsCount + PscLMaxSessionsCount;
|
||||
|
||||
private const int PointerBufferSize = 0;
|
||||
private const int MaxDomains = 0;
|
||||
private const int MaxDomainObjects = 0;
|
||||
private const int MaxPortsCount = 3;
|
||||
|
||||
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
||||
|
||||
private SmApi _sm;
|
||||
private ServerManager _serverManager;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
HeapAllocator allocator = new();
|
||||
|
||||
_sm = new SmApi();
|
||||
_sm.Initialize().AbortOnFailure();
|
||||
|
||||
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
_serverManager.RegisterObjectForServer(new PmControl(), ServiceName.Encode("psc:c"), PscCMaxSessionsCount);
|
||||
_serverManager.RegisterObjectForServer(new PmService(), ServiceName.Encode("psc:m"), PscMMaxSessionsCount);
|
||||
_serverManager.RegisterObjectForServer(new PmStateLock(), ServiceName.Encode("psc:l"), PscLMaxSessionsCount); // 9.0.0+
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
|
||||
public void ServiceRequests()
|
||||
{
|
||||
_serverManager.ServiceRequests();
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
_serverManager.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
17
src/Ryujinx.Horizon/Psc/PscMain.cs
Normal file
17
src/Ryujinx.Horizon/Psc/PscMain.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace Ryujinx.Horizon.Psc
|
||||
{
|
||||
class PscMain : IService
|
||||
{
|
||||
public static void Main(ServiceTable serviceTable)
|
||||
{
|
||||
PscIpcServer ipcServer = new();
|
||||
|
||||
ipcServer.Initialize();
|
||||
|
||||
serviceTable.SignalServiceReady();
|
||||
|
||||
ipcServer.ServiceRequests();
|
||||
ipcServer.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Hshl/IManager.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Hshl/IManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Hshl
|
||||
{
|
||||
interface IManager : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Hshl/ISetterManager.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Hshl/ISetterManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Hshl
|
||||
{
|
||||
interface ISetterManager : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Ins/IReceiverManager.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Ins/IReceiverManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Ins
|
||||
{
|
||||
interface IReceiverManager : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Ins/ISenderManager.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Ins/ISenderManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Ins
|
||||
{
|
||||
interface ISenderManager : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Ovln/IReceiverService.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Ovln/IReceiverService.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Ovln
|
||||
{
|
||||
interface IReceiverService : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Ovln/ISenderService.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Ovln/ISenderService.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Ovln
|
||||
{
|
||||
interface ISenderService : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Psc/IPmControl.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Psc/IPmControl.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Psc
|
||||
{
|
||||
interface IPmControl : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Psc/IPmService.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Psc/IPmService.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Psc
|
||||
{
|
||||
interface IPmService : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Psc/IPmStateLock.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Psc/IPmStateLock.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Psc
|
||||
{
|
||||
interface IPmStateLock : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Srepo/ISrepoService.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Srepo/ISrepoService.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Srepo
|
||||
{
|
||||
interface ISrepoService : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Usb/IClientRootSession.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Usb/IClientRootSession.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Usb
|
||||
{
|
||||
interface IClientRootSession : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Usb/IDsRootSession.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Usb/IDsRootSession.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Usb
|
||||
{
|
||||
interface IDsRootSession : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Usb/IPdCradleManager.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Usb/IPdCradleManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Usb
|
||||
{
|
||||
interface IPdCradleManager : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Usb/IPdManager.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Usb/IPdManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Usb
|
||||
{
|
||||
interface IPdManager : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Usb/IPdManufactureManager.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Usb/IPdManufactureManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Usb
|
||||
{
|
||||
interface IPdManufactureManager : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Usb/IPmObserverService.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Usb/IPmObserverService.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Usb
|
||||
{
|
||||
interface IPmObserverService : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Usb/IPmService.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Usb/IPmService.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Usb
|
||||
{
|
||||
interface IPmService : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Sdk/Usb/IQdbManager.cs
Normal file
8
src/Ryujinx.Horizon/Sdk/Usb/IQdbManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Usb
|
||||
{
|
||||
interface IQdbManager : IServiceObject
|
||||
{
|
||||
}
|
||||
}
|
@@ -1,9 +1,15 @@
|
||||
using Ryujinx.Horizon.Bcat;
|
||||
using Ryujinx.Horizon.Hshl;
|
||||
using Ryujinx.Horizon.Ins;
|
||||
using Ryujinx.Horizon.Lbl;
|
||||
using Ryujinx.Horizon.LogManager;
|
||||
using Ryujinx.Horizon.MmNv;
|
||||
using Ryujinx.Horizon.Ngc;
|
||||
using Ryujinx.Horizon.Ovln;
|
||||
using Ryujinx.Horizon.Prepo;
|
||||
using Ryujinx.Horizon.Psc;
|
||||
using Ryujinx.Horizon.Srepo;
|
||||
using Ryujinx.Horizon.Usb;
|
||||
using Ryujinx.Horizon.Wlan;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
@@ -27,12 +33,18 @@ namespace Ryujinx.Horizon
|
||||
}
|
||||
|
||||
RegisterService<BcatMain>();
|
||||
RegisterService<HshlMain>();
|
||||
RegisterService<InsMain>();
|
||||
RegisterService<LblMain>();
|
||||
RegisterService<LmMain>();
|
||||
RegisterService<MmNvMain>();
|
||||
RegisterService<PrepoMain>();
|
||||
RegisterService<WlanMain>();
|
||||
RegisterService<NgcMain>();
|
||||
RegisterService<OvlnMain>();
|
||||
RegisterService<PrepoMain>();
|
||||
RegisterService<PscMain>();
|
||||
RegisterService<SrepoMain>();
|
||||
RegisterService<UsbMain>();
|
||||
RegisterService<WlanMain>();
|
||||
|
||||
_totalServices = entries.Count;
|
||||
|
||||
|
8
src/Ryujinx.Horizon/Srepo/Ipc/SrepoService.cs
Normal file
8
src/Ryujinx.Horizon/Srepo/Ipc/SrepoService.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Srepo;
|
||||
|
||||
namespace Ryujinx.Horizon.Srepo.Ipc
|
||||
{
|
||||
partial class SrepoService : ISrepoService
|
||||
{
|
||||
}
|
||||
}
|
46
src/Ryujinx.Horizon/Srepo/SrepoIpcServer.cs
Normal file
46
src/Ryujinx.Horizon/Srepo/SrepoIpcServer.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
||||
using Ryujinx.Horizon.Sdk.Sm;
|
||||
using Ryujinx.Horizon.Srepo.Ipc;
|
||||
|
||||
namespace Ryujinx.Horizon.Srepo
|
||||
{
|
||||
class SrepoIpcServer
|
||||
{
|
||||
private const int SrepoAMaxSessionsCount = 2;
|
||||
private const int SrepoUMaxSessionsCount = 30;
|
||||
private const int TotalMaxSessionsCount = SrepoAMaxSessionsCount + SrepoUMaxSessionsCount;
|
||||
|
||||
private const int PointerBufferSize = 0x80;
|
||||
private const int MaxDomains = 32;
|
||||
private const int MaxDomainObjects = 192;
|
||||
private const int MaxPortsCount = 2;
|
||||
|
||||
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
||||
|
||||
private SmApi _sm;
|
||||
private ServerManager _serverManager;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
HeapAllocator allocator = new();
|
||||
|
||||
_sm = new SmApi();
|
||||
_sm.Initialize().AbortOnFailure();
|
||||
|
||||
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
|
||||
|
||||
_serverManager.RegisterObjectForServer(new SrepoService(), ServiceName.Encode("srepo:a"), SrepoAMaxSessionsCount); // 5.0.0+
|
||||
_serverManager.RegisterObjectForServer(new SrepoService(), ServiceName.Encode("srepo:u"), SrepoUMaxSessionsCount); // 5.0.0+
|
||||
}
|
||||
|
||||
public void ServiceRequests()
|
||||
{
|
||||
_serverManager.ServiceRequests();
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
_serverManager.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
17
src/Ryujinx.Horizon/Srepo/SrepoMain.cs
Normal file
17
src/Ryujinx.Horizon/Srepo/SrepoMain.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace Ryujinx.Horizon.Srepo
|
||||
{
|
||||
class SrepoMain : IService
|
||||
{
|
||||
public static void Main(ServiceTable serviceTable)
|
||||
{
|
||||
SrepoIpcServer ipcServer = new();
|
||||
|
||||
ipcServer.Initialize();
|
||||
|
||||
serviceTable.SignalServiceReady();
|
||||
|
||||
ipcServer.ServiceRequests();
|
||||
ipcServer.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Usb/Ipc/ClientRootSession.cs
Normal file
8
src/Ryujinx.Horizon/Usb/Ipc/ClientRootSession.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Usb;
|
||||
|
||||
namespace Ryujinx.Horizon.Usb.Ipc
|
||||
{
|
||||
partial class ClientRootSession : IClientRootSession
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Usb/Ipc/DsRootSession.cs
Normal file
8
src/Ryujinx.Horizon/Usb/Ipc/DsRootSession.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Usb;
|
||||
|
||||
namespace Ryujinx.Horizon.Usb.Ipc
|
||||
{
|
||||
partial class DsRootSession : IDsRootSession
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Usb/Ipc/PdCradleManager.cs
Normal file
8
src/Ryujinx.Horizon/Usb/Ipc/PdCradleManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Usb;
|
||||
|
||||
namespace Ryujinx.Horizon.Usb.Ipc
|
||||
{
|
||||
partial class PdCradleManager : IPdCradleManager
|
||||
{
|
||||
}
|
||||
}
|
9
src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs
Normal file
9
src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
||||
using Ryujinx.Horizon.Sdk.Usb;
|
||||
|
||||
namespace Ryujinx.Horizon.Usb.Ipc
|
||||
{
|
||||
partial class PdManager : IPdManager
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Usb/Ipc/PdManufactureManager.cs
Normal file
8
src/Ryujinx.Horizon/Usb/Ipc/PdManufactureManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Usb;
|
||||
|
||||
namespace Ryujinx.Horizon.Usb.Ipc
|
||||
{
|
||||
partial class PdManufactureManager : IPdManufactureManager
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Usb/Ipc/PmObserverService.cs
Normal file
8
src/Ryujinx.Horizon/Usb/Ipc/PmObserverService.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Usb;
|
||||
|
||||
namespace Ryujinx.Horizon.Usb.Ipc
|
||||
{
|
||||
partial class PmObserverService : IPmObserverService
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Usb/Ipc/PmService.cs
Normal file
8
src/Ryujinx.Horizon/Usb/Ipc/PmService.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Usb;
|
||||
|
||||
namespace Ryujinx.Horizon.Usb.Ipc
|
||||
{
|
||||
partial class PmService : IPmService
|
||||
{
|
||||
}
|
||||
}
|
8
src/Ryujinx.Horizon/Usb/Ipc/QdbManager.cs
Normal file
8
src/Ryujinx.Horizon/Usb/Ipc/QdbManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Ryujinx.Horizon.Sdk.Usb;
|
||||
|
||||
namespace Ryujinx.Horizon.Usb.Ipc
|
||||
{
|
||||
partial class QdbManager : IQdbManager
|
||||
{
|
||||
}
|
||||
}
|
71
src/Ryujinx.Horizon/Usb/UsbIpcServer.cs
Normal file
71
src/Ryujinx.Horizon/Usb/UsbIpcServer.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
||||
using Ryujinx.Horizon.Sdk.Sm;
|
||||
using Ryujinx.Horizon.Usb.Ipc;
|
||||
|
||||
namespace Ryujinx.Horizon.Usb
|
||||
{
|
||||
class UsbIpcServer
|
||||
{
|
||||
private const int UsbDsMaxSessionsCount = 4;
|
||||
private const int UsbHsMaxSessionsCount = 20;
|
||||
private const int UsbHsAMaxSessionsCount = 3;
|
||||
private const int UsbObsvMaxSessionsCount = 2;
|
||||
private const int UsbPdMaxSessionsCount = 6;
|
||||
private const int UsbPdCMaxSessionsCount = 4;
|
||||
private const int UsbPdMMaxSessionsCount = 1;
|
||||
private const int UsbPmMaxSessionsCount = 5;
|
||||
private const int UsbQdbMaxSessionsCount = 4;
|
||||
private const int TotalMaxSessionsCount =
|
||||
UsbDsMaxSessionsCount +
|
||||
UsbHsMaxSessionsCount +
|
||||
UsbHsAMaxSessionsCount +
|
||||
UsbObsvMaxSessionsCount +
|
||||
UsbPdMaxSessionsCount +
|
||||
UsbPdCMaxSessionsCount +
|
||||
UsbPdMMaxSessionsCount +
|
||||
UsbPmMaxSessionsCount +
|
||||
UsbQdbMaxSessionsCount;
|
||||
|
||||
private const int PointerBufferSize = 0;
|
||||
private const int MaxDomains = 0;
|
||||
private const int MaxDomainObjects = 0;
|
||||
private const int MaxPortsCount = 9;
|
||||
|
||||
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
||||
|
||||
private SmApi _sm;
|
||||
private ServerManager _serverManager;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
HeapAllocator allocator = new();
|
||||
|
||||
_sm = new SmApi();
|
||||
_sm.Initialize().AbortOnFailure();
|
||||
|
||||
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
_serverManager.RegisterObjectForServer(new DsRootSession(), ServiceName.Encode("usb:ds"), UsbDsMaxSessionsCount);
|
||||
_serverManager.RegisterObjectForServer(new ClientRootSession(), ServiceName.Encode("usb:hs"), UsbHsMaxSessionsCount);
|
||||
_serverManager.RegisterObjectForServer(new ClientRootSession(), ServiceName.Encode("usb:hs:a"), UsbHsAMaxSessionsCount); // 7.0.0+
|
||||
_serverManager.RegisterObjectForServer(new PmObserverService(), ServiceName.Encode("usb:obsv"), UsbObsvMaxSessionsCount); // 8.0.0+
|
||||
_serverManager.RegisterObjectForServer(new PdManager(), ServiceName.Encode("usb:pd"), UsbPdMaxSessionsCount);
|
||||
_serverManager.RegisterObjectForServer(new PdCradleManager(), ServiceName.Encode("usb:pd:c"), UsbPdCMaxSessionsCount);
|
||||
_serverManager.RegisterObjectForServer(new PdManufactureManager(), ServiceName.Encode("usb:pd:m"), UsbPdMMaxSessionsCount); // 1.0.0
|
||||
_serverManager.RegisterObjectForServer(new PmService(), ServiceName.Encode("usb:pm"), UsbPmMaxSessionsCount);
|
||||
_serverManager.RegisterObjectForServer(new QdbManager(), ServiceName.Encode("usb:qdb"), UsbQdbMaxSessionsCount); // 7.0.0+
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
|
||||
public void ServiceRequests()
|
||||
{
|
||||
_serverManager.ServiceRequests();
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
_serverManager.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
17
src/Ryujinx.Horizon/Usb/UsbMain.cs
Normal file
17
src/Ryujinx.Horizon/Usb/UsbMain.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace Ryujinx.Horizon.Usb
|
||||
{
|
||||
class UsbMain : IService
|
||||
{
|
||||
public static void Main(ServiceTable serviceTable)
|
||||
{
|
||||
UsbIpcServer ipcServer = new();
|
||||
|
||||
ipcServer.Initialize();
|
||||
|
||||
serviceTable.SignalServiceReady();
|
||||
|
||||
ipcServer.ServiceRequests();
|
||||
ipcServer.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user