Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
0d3b82477e | ||
|
470be03c2f | ||
|
c963b3c804 |
@@ -80,10 +80,7 @@ namespace ARMeilleure.Common
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_disposed)
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
{
|
|
||||||
throw new ObjectDisposedException(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (_pages)
|
lock (_pages)
|
||||||
{
|
{
|
||||||
@@ -100,10 +97,7 @@ namespace ARMeilleure.Common
|
|||||||
/// <exception cref="ArgumentException">Length of <paramref name="levels"/> is less than 2</exception>
|
/// <exception cref="ArgumentException">Length of <paramref name="levels"/> is less than 2</exception>
|
||||||
public AddressTable(Level[] levels)
|
public AddressTable(Level[] levels)
|
||||||
{
|
{
|
||||||
if (levels == null)
|
ArgumentNullException.ThrowIfNull(levels);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(levels));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (levels.Length < 2)
|
if (levels.Length < 2)
|
||||||
{
|
{
|
||||||
@@ -141,10 +135,7 @@ namespace ARMeilleure.Common
|
|||||||
/// <exception cref="ArgumentException"><paramref name="address"/> is not mapped</exception>
|
/// <exception cref="ArgumentException"><paramref name="address"/> is not mapped</exception>
|
||||||
public ref TEntry GetValue(ulong address)
|
public ref TEntry GetValue(ulong address)
|
||||||
{
|
{
|
||||||
if (_disposed)
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
{
|
|
||||||
throw new ObjectDisposedException(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsValid(address))
|
if (!IsValid(address))
|
||||||
{
|
{
|
||||||
|
@@ -49,10 +49,7 @@ namespace ARMeilleure.Common
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_disposed)
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
{
|
|
||||||
throw new ObjectDisposedException(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ref _countTable.GetValue(_index);
|
return ref _countTable.GetValue(_index);
|
||||||
}
|
}
|
||||||
|
@@ -53,10 +53,7 @@ namespace ARMeilleure.Common
|
|||||||
/// <exception cref="ObjectDisposedException"><see cref="EntryTable{TEntry}"/> instance was disposed</exception>
|
/// <exception cref="ObjectDisposedException"><see cref="EntryTable{TEntry}"/> instance was disposed</exception>
|
||||||
public int Allocate()
|
public int Allocate()
|
||||||
{
|
{
|
||||||
if (_disposed)
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
{
|
|
||||||
throw new ObjectDisposedException(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (_allocated)
|
lock (_allocated)
|
||||||
{
|
{
|
||||||
@@ -83,10 +80,7 @@ namespace ARMeilleure.Common
|
|||||||
/// <exception cref="ObjectDisposedException"><see cref="EntryTable{TEntry}"/> instance was disposed</exception>
|
/// <exception cref="ObjectDisposedException"><see cref="EntryTable{TEntry}"/> instance was disposed</exception>
|
||||||
public void Free(int index)
|
public void Free(int index)
|
||||||
{
|
{
|
||||||
if (_disposed)
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
{
|
|
||||||
throw new ObjectDisposedException(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (_allocated)
|
lock (_allocated)
|
||||||
{
|
{
|
||||||
@@ -108,10 +102,7 @@ namespace ARMeilleure.Common
|
|||||||
/// <exception cref="ArgumentException">Entry at <paramref name="index"/> is not allocated</exception>
|
/// <exception cref="ArgumentException">Entry at <paramref name="index"/> is not allocated</exception>
|
||||||
public ref TEntry GetValue(int index)
|
public ref TEntry GetValue(int index)
|
||||||
{
|
{
|
||||||
if (_disposed)
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
{
|
|
||||||
throw new ObjectDisposedException(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (_allocated)
|
lock (_allocated)
|
||||||
{
|
{
|
||||||
|
@@ -48,10 +48,7 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||||||
|
|
||||||
public void AddSuccessor(BasicBlock block)
|
public void AddSuccessor(BasicBlock block)
|
||||||
{
|
{
|
||||||
if (block == null)
|
ArgumentNullException.ThrowIfNull(block);
|
||||||
{
|
|
||||||
ThrowNull(nameof(block));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((uint)_succCount + 1 > MaxSuccessors)
|
if ((uint)_succCount + 1 > MaxSuccessors)
|
||||||
{
|
{
|
||||||
@@ -100,10 +97,7 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||||||
|
|
||||||
public void SetSuccessor(int index, BasicBlock block)
|
public void SetSuccessor(int index, BasicBlock block)
|
||||||
{
|
{
|
||||||
if (block == null)
|
ArgumentNullException.ThrowIfNull(block);
|
||||||
{
|
|
||||||
ThrowNull(nameof(block));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((uint)index >= (uint)_succCount)
|
if ((uint)index >= (uint)_succCount)
|
||||||
{
|
{
|
||||||
@@ -144,7 +138,6 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ThrowNull(string name) => throw new ArgumentNullException(name);
|
|
||||||
private static void ThrowOutOfRange(string name) => throw new ArgumentOutOfRangeException(name);
|
private static void ThrowOutOfRange(string name) => throw new ArgumentOutOfRangeException(name);
|
||||||
private static void ThrowSuccessorOverflow() => throw new OverflowException($"BasicBlock can only have {MaxSuccessors} successors.");
|
private static void ThrowSuccessorOverflow() => throw new OverflowException($"BasicBlock can only have {MaxSuccessors} successors.");
|
||||||
|
|
||||||
|
@@ -25,10 +25,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
public static Delegate GetDelegate(MethodInfo info)
|
public static Delegate GetDelegate(MethodInfo info)
|
||||||
{
|
{
|
||||||
if (info == null)
|
ArgumentNullException.ThrowIfNull(info);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
Type[] parameters = info.GetParameters().Select(pI => pI.ParameterType).ToArray();
|
Type[] parameters = info.GetParameters().Select(pI => pI.ParameterType).ToArray();
|
||||||
Type returnType = info.ReturnType;
|
Type returnType = info.ReturnType;
|
||||||
|
@@ -35,10 +35,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
public static IntPtr GetDelegateFuncPtr(MethodInfo info)
|
public static IntPtr GetDelegateFuncPtr(MethodInfo info)
|
||||||
{
|
{
|
||||||
if (info == null)
|
ArgumentNullException.ThrowIfNull(info);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
string key = GetKey(info);
|
string key = GetKey(info);
|
||||||
|
|
||||||
@@ -52,10 +49,7 @@ namespace ARMeilleure.Translation
|
|||||||
|
|
||||||
public static int GetDelegateIndex(MethodInfo info)
|
public static int GetDelegateIndex(MethodInfo info)
|
||||||
{
|
{
|
||||||
if (info == null)
|
ArgumentNullException.ThrowIfNull(info);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
string key = GetKey(info);
|
string key = GetKey(info);
|
||||||
|
|
||||||
|
@@ -67,10 +67,7 @@ namespace ARMeilleure.Translation
|
|||||||
/// <returns>True if the value was added, false if the start key was already in the dictionary</returns>
|
/// <returns>True if the value was added, false if the start key was already in the dictionary</returns>
|
||||||
public bool AddOrUpdate(K start, K end, V value, Func<K, V, V> updateFactoryCallback)
|
public bool AddOrUpdate(K start, K end, V value, Func<K, V, V> updateFactoryCallback)
|
||||||
{
|
{
|
||||||
if (value == null)
|
ArgumentNullException.ThrowIfNull(value);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
return BSTInsert(start, end, value, updateFactoryCallback, out IntervalTreeNode<K, V> node);
|
return BSTInsert(start, end, value, updateFactoryCallback, out IntervalTreeNode<K, V> node);
|
||||||
}
|
}
|
||||||
@@ -85,10 +82,7 @@ namespace ARMeilleure.Translation
|
|||||||
/// <returns><paramref name="value"/> if <paramref name="start"/> is not yet on the tree, or the existing value otherwise</returns>
|
/// <returns><paramref name="value"/> if <paramref name="start"/> is not yet on the tree, or the existing value otherwise</returns>
|
||||||
public V GetOrAdd(K start, K end, V value)
|
public V GetOrAdd(K start, K end, V value)
|
||||||
{
|
{
|
||||||
if (value == null)
|
ArgumentNullException.ThrowIfNull(value);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
BSTInsert(start, end, value, null, out IntervalTreeNode<K, V> node);
|
BSTInsert(start, end, value, null, out IntervalTreeNode<K, V> node);
|
||||||
return node.Value;
|
return node.Value;
|
||||||
@@ -152,10 +146,7 @@ namespace ARMeilleure.Translation
|
|||||||
/// <returns>Node reference in the tree</returns>
|
/// <returns>Node reference in the tree</returns>
|
||||||
private IntervalTreeNode<K, V> GetNode(K key)
|
private IntervalTreeNode<K, V> GetNode(K key)
|
||||||
{
|
{
|
||||||
if (key == null)
|
ArgumentNullException.ThrowIfNull(key);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
IntervalTreeNode<K, V> node = _root;
|
IntervalTreeNode<K, V> node = _root;
|
||||||
while (node != null)
|
while (node != null)
|
||||||
|
@@ -30,10 +30,7 @@ namespace ARMeilleure.Translation
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_disposed)
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
{
|
|
||||||
throw new ObjectDisposedException(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _dispatchStub.Value;
|
return _dispatchStub.Value;
|
||||||
}
|
}
|
||||||
@@ -47,10 +44,7 @@ namespace ARMeilleure.Translation
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_disposed)
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
{
|
|
||||||
throw new ObjectDisposedException(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _slowDispatchStub.Value;
|
return _slowDispatchStub.Value;
|
||||||
}
|
}
|
||||||
@@ -64,10 +58,7 @@ namespace ARMeilleure.Translation
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_disposed)
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
{
|
|
||||||
throw new ObjectDisposedException(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _dispatchLoop.Value;
|
return _dispatchLoop.Value;
|
||||||
}
|
}
|
||||||
@@ -81,7 +72,9 @@ namespace ARMeilleure.Translation
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="translator"/> is null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="translator"/> is null</exception>
|
||||||
public TranslatorStubs(Translator translator)
|
public TranslatorStubs(Translator translator)
|
||||||
{
|
{
|
||||||
_translator = translator ?? throw new ArgumentNullException(nameof(translator));
|
ArgumentNullException.ThrowIfNull(translator);
|
||||||
|
|
||||||
|
_translator = translator;
|
||||||
_dispatchStub = new(GenerateDispatchStub, isThreadSafe: true);
|
_dispatchStub = new(GenerateDispatchStub, isThreadSafe: true);
|
||||||
_dispatchLoop = new(GenerateDispatchLoop, isThreadSafe: true);
|
_dispatchLoop = new(GenerateDispatchLoop, isThreadSafe: true);
|
||||||
}
|
}
|
||||||
|
@@ -23,7 +23,7 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
|
|
||||||
if (size != 0)
|
if (size != 0)
|
||||||
{
|
{
|
||||||
ulong alignedOffset = BitUtils.AlignUp(Offset, align);
|
ulong alignedOffset = BitUtils.AlignUp<ulong>(Offset, (ulong)align);
|
||||||
|
|
||||||
if (alignedOffset + size <= (ulong)BackingMemory.Length)
|
if (alignedOffset + size <= (ulong)BackingMemory.Length)
|
||||||
{
|
{
|
||||||
@@ -55,7 +55,7 @@ namespace Ryujinx.Audio.Renderer.Common
|
|||||||
|
|
||||||
public static ulong GetTargetSize<T>(ulong currentSize, ulong count, int align) where T : unmanaged
|
public static ulong GetTargetSize<T>(ulong currentSize, ulong count, int align) where T : unmanaged
|
||||||
{
|
{
|
||||||
return BitUtils.AlignUp(currentSize, align) + (ulong)Unsafe.SizeOf<T>() * count;
|
return BitUtils.AlignUp<ulong>(currentSize, (ulong)align) + (ulong)Unsafe.SizeOf<T>() * count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -167,7 +167,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
return ResultCode.WorkBufferTooSmall;
|
return ResultCode.WorkBufferTooSmall;
|
||||||
}
|
}
|
||||||
|
|
||||||
_depopBuffer = workBufferAllocator.Allocate<float>((ulong)BitUtils.AlignUp(parameter.MixBufferCount, Constants.BufferAlignment), Constants.BufferAlignment);
|
_depopBuffer = workBufferAllocator.Allocate<float>(BitUtils.AlignUp<ulong>(parameter.MixBufferCount, Constants.BufferAlignment), Constants.BufferAlignment);
|
||||||
|
|
||||||
if (_depopBuffer.IsEmpty)
|
if (_depopBuffer.IsEmpty)
|
||||||
{
|
{
|
||||||
@@ -772,7 +772,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
size = WorkBufferAllocator.GetTargetSize<float>(size, Constants.TargetSampleCount * (Constants.VoiceChannelCountMax + parameter.MixBufferCount) * (parameter.SinkCount + parameter.SubMixBufferCount), 0x10);
|
size = WorkBufferAllocator.GetTargetSize<float>(size, Constants.TargetSampleCount * (Constants.VoiceChannelCountMax + parameter.MixBufferCount) * (parameter.SinkCount + parameter.SubMixBufferCount), 0x10);
|
||||||
|
|
||||||
// Depop buffer
|
// Depop buffer
|
||||||
size = WorkBufferAllocator.GetTargetSize<float>(size, (ulong)BitUtils.AlignUp(parameter.MixBufferCount, Constants.BufferAlignment), Constants.BufferAlignment);
|
size = WorkBufferAllocator.GetTargetSize<float>(size, BitUtils.AlignUp<ulong>(parameter.MixBufferCount, Constants.BufferAlignment), Constants.BufferAlignment);
|
||||||
|
|
||||||
// Voice
|
// Voice
|
||||||
size = WorkBufferAllocator.GetTargetSize<VoiceState>(size, parameter.VoiceCount, VoiceState.Alignment);
|
size = WorkBufferAllocator.GetTargetSize<VoiceState>(size, parameter.VoiceCount, VoiceState.Alignment);
|
||||||
@@ -804,10 +804,10 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
ulong performanceMetricsPerFramesSize = PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter, ref behaviourContext) * (parameter.PerformanceMetricFramesCount + 1) + 0xC;
|
ulong performanceMetricsPerFramesSize = PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter, ref behaviourContext) * (parameter.PerformanceMetricFramesCount + 1) + 0xC;
|
||||||
|
|
||||||
size += BitUtils.AlignUp(performanceMetricsPerFramesSize, Constants.PerformanceMetricsPerFramesSizeAlignment);
|
size += BitUtils.AlignUp<ulong>(performanceMetricsPerFramesSize, Constants.PerformanceMetricsPerFramesSizeAlignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
return BitUtils.AlignUp(size, Constants.WorkBufferAlignment);
|
return BitUtils.AlignUp<ulong>(size, Constants.WorkBufferAlignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultCode QuerySystemEvent(out IWritableEvent systemEvent)
|
public ResultCode QuerySystemEvent(out IWritableEvent systemEvent)
|
||||||
|
@@ -24,10 +24,7 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception>
|
||||||
public int Get(K key, ref V[] overlaps)
|
public int Get(K key, ref V[] overlaps)
|
||||||
{
|
{
|
||||||
if (key == null)
|
ArgumentNullException.ThrowIfNull(key);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
IntervalTreeNode<K, V> node = GetNode(key);
|
IntervalTreeNode<K, V> node = GetNode(key);
|
||||||
|
|
||||||
@@ -61,15 +58,8 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="start"/> or <paramref name="end"/> is null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="start"/> or <paramref name="end"/> is null</exception>
|
||||||
public int Get(K start, K end, ref V[] overlaps, int overlapCount = 0)
|
public int Get(K start, K end, ref V[] overlaps, int overlapCount = 0)
|
||||||
{
|
{
|
||||||
if (start == null)
|
ArgumentNullException.ThrowIfNull(start);
|
||||||
{
|
ArgumentNullException.ThrowIfNull(end);
|
||||||
throw new ArgumentNullException(nameof(start));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(end));
|
|
||||||
}
|
|
||||||
|
|
||||||
GetValues(Root, start, end, ref overlaps, ref overlapCount);
|
GetValues(Root, start, end, ref overlaps, ref overlapCount);
|
||||||
|
|
||||||
@@ -85,20 +75,9 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="start"/>, <paramref name="end"/> or <paramref name="value"/> are null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="start"/>, <paramref name="end"/> or <paramref name="value"/> are null</exception>
|
||||||
public void Add(K start, K end, V value)
|
public void Add(K start, K end, V value)
|
||||||
{
|
{
|
||||||
if (start == null)
|
ArgumentNullException.ThrowIfNull(start);
|
||||||
{
|
ArgumentNullException.ThrowIfNull(end);
|
||||||
throw new ArgumentNullException(nameof(start));
|
ArgumentNullException.ThrowIfNull(value);
|
||||||
}
|
|
||||||
|
|
||||||
if (end == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(end));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
Insert(start, end, value);
|
Insert(start, end, value);
|
||||||
}
|
}
|
||||||
@@ -112,10 +91,7 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <returns>Number of deleted values</returns>
|
/// <returns>Number of deleted values</returns>
|
||||||
public int Remove(K key, V value)
|
public int Remove(K key, V value)
|
||||||
{
|
{
|
||||||
if (key == null)
|
ArgumentNullException.ThrowIfNull(key);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
int removed = Delete(key, value);
|
int removed = Delete(key, value);
|
||||||
|
|
||||||
@@ -168,10 +144,7 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception>
|
||||||
private IntervalTreeNode<K, V> GetNode(K key)
|
private IntervalTreeNode<K, V> GetNode(K key)
|
||||||
{
|
{
|
||||||
if (key == null)
|
ArgumentNullException.ThrowIfNull(key);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
IntervalTreeNode<K, V> node = Root;
|
IntervalTreeNode<K, V> node = Root;
|
||||||
while (node != null)
|
while (node != null)
|
||||||
@@ -462,10 +435,8 @@ namespace Ryujinx.Common.Collections
|
|||||||
|
|
||||||
public bool ContainsKey(K key)
|
public bool ContainsKey(K key)
|
||||||
{
|
{
|
||||||
if (key == null)
|
ArgumentNullException.ThrowIfNull(key);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(key));
|
|
||||||
}
|
|
||||||
return GetNode(key) != null;
|
return GetNode(key) != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,10 +17,7 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="node"/> is null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="node"/> is null</exception>
|
||||||
public void Add(T node)
|
public void Add(T node)
|
||||||
{
|
{
|
||||||
if (node == null)
|
ArgumentNullException.ThrowIfNull(node);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(node));
|
|
||||||
}
|
|
||||||
|
|
||||||
Insert(node);
|
Insert(node);
|
||||||
}
|
}
|
||||||
@@ -32,10 +29,8 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="node"/> is null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="node"/> is null</exception>
|
||||||
public void Remove(T node)
|
public void Remove(T node)
|
||||||
{
|
{
|
||||||
if (node == null)
|
ArgumentNullException.ThrowIfNull(node);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(node));
|
|
||||||
}
|
|
||||||
if (Delete(node) != null)
|
if (Delete(node) != null)
|
||||||
{
|
{
|
||||||
Count--;
|
Count--;
|
||||||
@@ -50,10 +45,7 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="searchNode"/> is null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="searchNode"/> is null</exception>
|
||||||
public T GetNode(T searchNode)
|
public T GetNode(T searchNode)
|
||||||
{
|
{
|
||||||
if (searchNode == null)
|
ArgumentNullException.ThrowIfNull(searchNode);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(searchNode));
|
|
||||||
}
|
|
||||||
|
|
||||||
T node = Root;
|
T node = Root;
|
||||||
while (node != null)
|
while (node != null)
|
||||||
|
@@ -92,10 +92,8 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="node"/> is null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="node"/> is null</exception>
|
||||||
protected static T Minimum(T node)
|
protected static T Minimum(T node)
|
||||||
{
|
{
|
||||||
if (node == null)
|
ArgumentNullException.ThrowIfNull(node);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(node));
|
|
||||||
}
|
|
||||||
T tmp = node;
|
T tmp = node;
|
||||||
while (tmp.Left != null)
|
while (tmp.Left != null)
|
||||||
{
|
{
|
||||||
|
@@ -22,10 +22,7 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception>
|
||||||
public V Get(K key)
|
public V Get(K key)
|
||||||
{
|
{
|
||||||
if (key == null)
|
ArgumentNullException.ThrowIfNull(key);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
Node<K, V> node = GetNode(key);
|
Node<K, V> node = GetNode(key);
|
||||||
|
|
||||||
@@ -47,14 +44,8 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="key"/> or <paramref name="value"/> are null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="key"/> or <paramref name="value"/> are null</exception>
|
||||||
public void Add(K key, V value)
|
public void Add(K key, V value)
|
||||||
{
|
{
|
||||||
if (key == null)
|
ArgumentNullException.ThrowIfNull(key);
|
||||||
{
|
ArgumentNullException.ThrowIfNull(value);
|
||||||
throw new ArgumentNullException(nameof(key));
|
|
||||||
}
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
Insert(key, value);
|
Insert(key, value);
|
||||||
}
|
}
|
||||||
@@ -66,10 +57,8 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception>
|
||||||
public void Remove(K key)
|
public void Remove(K key)
|
||||||
{
|
{
|
||||||
if (key == null)
|
ArgumentNullException.ThrowIfNull(key);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(key));
|
|
||||||
}
|
|
||||||
if (Delete(key) != null)
|
if (Delete(key) != null)
|
||||||
{
|
{
|
||||||
Count--;
|
Count--;
|
||||||
@@ -217,10 +206,7 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception>
|
||||||
private Node<K, V> GetNode(K key)
|
private Node<K, V> GetNode(K key)
|
||||||
{
|
{
|
||||||
if (key == null)
|
ArgumentNullException.ThrowIfNull(key);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
Node<K, V> node = Root;
|
Node<K, V> node = Root;
|
||||||
while (node != null)
|
while (node != null)
|
||||||
@@ -370,10 +356,8 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception>
|
||||||
private Node<K, V> FloorNode(K key)
|
private Node<K, V> FloorNode(K key)
|
||||||
{
|
{
|
||||||
if (key == null)
|
ArgumentNullException.ThrowIfNull(key);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(key));
|
|
||||||
}
|
|
||||||
Node<K, V> tmp = Root;
|
Node<K, V> tmp = Root;
|
||||||
|
|
||||||
while (tmp != null)
|
while (tmp != null)
|
||||||
@@ -424,10 +408,8 @@ namespace Ryujinx.Common.Collections
|
|||||||
/// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="key"/> is null</exception>
|
||||||
private Node<K, V> CeilingNode(K key)
|
private Node<K, V> CeilingNode(K key)
|
||||||
{
|
{
|
||||||
if (key == null)
|
ArgumentNullException.ThrowIfNull(key);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(key));
|
|
||||||
}
|
|
||||||
Node<K, V> tmp = Root;
|
Node<K, V> tmp = Root;
|
||||||
|
|
||||||
while (tmp != null)
|
while (tmp != null)
|
||||||
@@ -477,10 +459,8 @@ namespace Ryujinx.Common.Collections
|
|||||||
// Method descriptions are not provided as they are already included as part of the interface.
|
// Method descriptions are not provided as they are already included as part of the interface.
|
||||||
public bool ContainsKey(K key)
|
public bool ContainsKey(K key)
|
||||||
{
|
{
|
||||||
if (key == null)
|
ArgumentNullException.ThrowIfNull(key);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(key));
|
|
||||||
}
|
|
||||||
return GetNode(key) != null;
|
return GetNode(key) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,10 +473,8 @@ namespace Ryujinx.Common.Collections
|
|||||||
|
|
||||||
public bool TryGetValue(K key, [MaybeNullWhen(false)] out V value)
|
public bool TryGetValue(K key, [MaybeNullWhen(false)] out V value)
|
||||||
{
|
{
|
||||||
if (null == key)
|
ArgumentNullException.ThrowIfNull(key);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(key));
|
|
||||||
}
|
|
||||||
Node<K, V> node = GetNode(key);
|
Node<K, V> node = GetNode(key);
|
||||||
value = node != null ? node.Value : default;
|
value = node != null ? node.Value : default;
|
||||||
return node != null;
|
return node != null;
|
||||||
@@ -504,10 +482,7 @@ namespace Ryujinx.Common.Collections
|
|||||||
|
|
||||||
public void Add(KeyValuePair<K, V> item)
|
public void Add(KeyValuePair<K, V> item)
|
||||||
{
|
{
|
||||||
if (item.Key == null)
|
ArgumentNullException.ThrowIfNull(item.Key);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(item.Key));
|
|
||||||
}
|
|
||||||
|
|
||||||
Add(item.Key, item.Value);
|
Add(item.Key, item.Value);
|
||||||
}
|
}
|
||||||
|
@@ -1,82 +1,26 @@
|
|||||||
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
namespace Ryujinx.Common
|
namespace Ryujinx.Common
|
||||||
{
|
{
|
||||||
public static class BitUtils
|
public static class BitUtils
|
||||||
{
|
{
|
||||||
public static uint AlignUp(uint value, int size)
|
public static T AlignUp<T>(T value, T size)
|
||||||
|
where T : IBinaryInteger<T>
|
||||||
{
|
{
|
||||||
return (uint)AlignUp((int)value, size);
|
return (value + (size - T.One)) & -size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int AlignUp(int value, int size)
|
public static T AlignDown<T>(T value, T size)
|
||||||
{
|
where T : IBinaryInteger<T>
|
||||||
return (value + (size - 1)) & -size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ulong AlignUp(ulong value, int size)
|
|
||||||
{
|
|
||||||
return (ulong)AlignUp((long)value, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long AlignUp(long value, int size)
|
|
||||||
{
|
|
||||||
return AlignUp(value, (long)size);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ulong AlignUp(ulong value, ulong size)
|
|
||||||
{
|
|
||||||
return (ulong)AlignUp((long)value, (long)size);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long AlignUp(long value, long size)
|
|
||||||
{
|
|
||||||
return (value + (size - 1)) & -size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static uint AlignDown(uint value, int size)
|
|
||||||
{
|
|
||||||
return (uint)AlignDown((int)value, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int AlignDown(int value, int size)
|
|
||||||
{
|
{
|
||||||
return value & -size;
|
return value & -size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ulong AlignDown(ulong value, int size)
|
public static T DivRoundUp<T>(T value, T dividend)
|
||||||
|
where T : IBinaryInteger<T>
|
||||||
{
|
{
|
||||||
return (ulong)AlignDown((long)value, size);
|
return (value + (dividend - T.One)) / dividend;
|
||||||
}
|
|
||||||
|
|
||||||
public static long AlignDown(long value, int size)
|
|
||||||
{
|
|
||||||
return AlignDown(value, (long)size);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ulong AlignDown(ulong value, ulong size)
|
|
||||||
{
|
|
||||||
return (ulong)AlignDown((long)value, (long)size);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long AlignDown(long value, long size)
|
|
||||||
{
|
|
||||||
return value & -size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int DivRoundUp(int value, int dividend)
|
|
||||||
{
|
|
||||||
return (value + dividend - 1) / dividend;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ulong DivRoundUp(ulong value, uint dividend)
|
|
||||||
{
|
|
||||||
return (value + dividend - 1) / dividend;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long DivRoundUp(long value, int dividend)
|
|
||||||
{
|
|
||||||
return (value + dividend - 1) / dividend;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int Pow2RoundUp(int value)
|
public static int Pow2RoundUp(int value)
|
||||||
|
@@ -18,7 +18,9 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
public readonly bool Supports3DTextureCompression;
|
public readonly bool Supports3DTextureCompression;
|
||||||
public readonly bool SupportsBgraFormat;
|
public readonly bool SupportsBgraFormat;
|
||||||
public readonly bool SupportsR4G4Format;
|
public readonly bool SupportsR4G4Format;
|
||||||
|
public readonly bool SupportsR4G4B4A4Format;
|
||||||
public readonly bool SupportsSnormBufferTextureFormat;
|
public readonly bool SupportsSnormBufferTextureFormat;
|
||||||
|
public readonly bool Supports5BitComponentFormat;
|
||||||
public readonly bool SupportsFragmentShaderInterlock;
|
public readonly bool SupportsFragmentShaderInterlock;
|
||||||
public readonly bool SupportsFragmentShaderOrderingIntel;
|
public readonly bool SupportsFragmentShaderOrderingIntel;
|
||||||
public readonly bool SupportsGeometryShaderPassthrough;
|
public readonly bool SupportsGeometryShaderPassthrough;
|
||||||
@@ -55,7 +57,9 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
bool supports3DTextureCompression,
|
bool supports3DTextureCompression,
|
||||||
bool supportsBgraFormat,
|
bool supportsBgraFormat,
|
||||||
bool supportsR4G4Format,
|
bool supportsR4G4Format,
|
||||||
|
bool supportsR4G4B4A4Format,
|
||||||
bool supportsSnormBufferTextureFormat,
|
bool supportsSnormBufferTextureFormat,
|
||||||
|
bool supports5BitComponentFormat,
|
||||||
bool supportsFragmentShaderInterlock,
|
bool supportsFragmentShaderInterlock,
|
||||||
bool supportsFragmentShaderOrderingIntel,
|
bool supportsFragmentShaderOrderingIntel,
|
||||||
bool supportsGeometryShaderPassthrough,
|
bool supportsGeometryShaderPassthrough,
|
||||||
@@ -89,7 +93,9 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
Supports3DTextureCompression = supports3DTextureCompression;
|
Supports3DTextureCompression = supports3DTextureCompression;
|
||||||
SupportsBgraFormat = supportsBgraFormat;
|
SupportsBgraFormat = supportsBgraFormat;
|
||||||
SupportsR4G4Format = supportsR4G4Format;
|
SupportsR4G4Format = supportsR4G4Format;
|
||||||
|
SupportsR4G4B4A4Format = supportsR4G4B4A4Format;
|
||||||
SupportsSnormBufferTextureFormat = supportsSnormBufferTextureFormat;
|
SupportsSnormBufferTextureFormat = supportsSnormBufferTextureFormat;
|
||||||
|
Supports5BitComponentFormat = supports5BitComponentFormat;
|
||||||
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
|
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
|
||||||
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
|
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
|
||||||
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
||||||
|
@@ -448,6 +448,27 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the texture format is 16 bit packed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">Texture format</param>
|
||||||
|
/// <returns>True if the texture format is 16 bit packed, false otherwise</returns>
|
||||||
|
public static bool Is16BitPacked(this Format format)
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case Format.B5G6R5Unorm:
|
||||||
|
case Format.B5G5R5A1Unorm:
|
||||||
|
case Format.R5G5B5X1Unorm:
|
||||||
|
case Format.R5G5B5A1Unorm:
|
||||||
|
case Format.R5G6B5Unorm:
|
||||||
|
case Format.R4G4B4A4Unorm:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if the texture format is an ASTC format.
|
/// Checks if the texture format is an ASTC format.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -100,7 +100,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
|||||||
_isLinear = (argument & 1) != 0;
|
_isLinear = (argument & 1) != 0;
|
||||||
|
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
_size = (int)(BitUtils.AlignUp(state.LineLengthIn, 4) * state.LineCount);
|
_size = (int)(BitUtils.AlignUp<uint>(state.LineLengthIn, 4) * state.LineCount);
|
||||||
|
|
||||||
int count = _size / 4;
|
int count = _size / 4;
|
||||||
|
|
||||||
|
@@ -911,7 +911,40 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
}
|
}
|
||||||
else if (!_context.Capabilities.SupportsR4G4Format && Format == Format.R4G4Unorm)
|
else if (!_context.Capabilities.SupportsR4G4Format && Format == Format.R4G4Unorm)
|
||||||
{
|
{
|
||||||
result = PixelConverter.ConvertR4G4ToR4G4B4A4(result);
|
result = PixelConverter.ConvertR4G4ToR4G4B4A4(result, width);
|
||||||
|
|
||||||
|
if (!_context.Capabilities.SupportsR4G4B4A4Format)
|
||||||
|
{
|
||||||
|
result = PixelConverter.ConvertR4G4B4A4ToR8G8B8A8(result, width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Format == Format.R4G4B4A4Unorm)
|
||||||
|
{
|
||||||
|
if (!_context.Capabilities.SupportsR4G4B4A4Format)
|
||||||
|
{
|
||||||
|
result = PixelConverter.ConvertR4G4B4A4ToR8G8B8A8(result, width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!_context.Capabilities.Supports5BitComponentFormat && Format.Is16BitPacked())
|
||||||
|
{
|
||||||
|
switch (Format)
|
||||||
|
{
|
||||||
|
case Format.B5G6R5Unorm:
|
||||||
|
case Format.R5G6B5Unorm:
|
||||||
|
result = PixelConverter.ConvertR5G6B5ToR8G8B8A8(result, width);
|
||||||
|
break;
|
||||||
|
case Format.B5G5R5A1Unorm:
|
||||||
|
case Format.R5G5B5X1Unorm:
|
||||||
|
case Format.R5G5B5A1Unorm:
|
||||||
|
result = PixelConverter.ConvertR5G5B5ToR8G8B8A8(result, width, Format == Format.R5G5B5X1Unorm);
|
||||||
|
break;
|
||||||
|
case Format.A1B5G5R5Unorm:
|
||||||
|
result = PixelConverter.ConvertA1B5G5R5ToR8G8B8A8(result, width);
|
||||||
|
break;
|
||||||
|
case Format.R4G4B4A4Unorm:
|
||||||
|
result = PixelConverter.ConvertR4G4B4A4ToR8G8B8A8(result, width);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@@ -131,9 +131,28 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!caps.SupportsR4G4Format && info.FormatInfo.Format == Format.R4G4Unorm)
|
if (!caps.SupportsR4G4Format && info.FormatInfo.Format == Format.R4G4Unorm)
|
||||||
|
{
|
||||||
|
if (caps.SupportsR4G4B4A4Format)
|
||||||
{
|
{
|
||||||
return new FormatInfo(Format.R4G4B4A4Unorm, 1, 1, 2, 4);
|
return new FormatInfo(Format.R4G4B4A4Unorm, 1, 1, 2, 4);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new FormatInfo(Format.R8G8B8A8Unorm, 1, 1, 4, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.FormatInfo.Format == Format.R4G4B4A4Unorm)
|
||||||
|
{
|
||||||
|
if (!caps.SupportsR4G4B4A4Format)
|
||||||
|
{
|
||||||
|
return new FormatInfo(Format.R8G8B8A8Unorm, 1, 1, 4, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!caps.Supports5BitComponentFormat && info.FormatInfo.Format.Is16BitPacked())
|
||||||
|
{
|
||||||
|
return new FormatInfo(info.FormatInfo.Format.IsBgr() ? Format.B8G8R8A8Unorm : Format.R8G8B8A8Unorm, 1, 1, 4, 4);
|
||||||
|
}
|
||||||
|
|
||||||
return info.FormatInfo;
|
return info.FormatInfo;
|
||||||
}
|
}
|
||||||
|
@@ -252,7 +252,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
|
|
||||||
RecordStorageAlignment(_cpStorageBuffers, index, gpuVa);
|
RecordStorageAlignment(_cpStorageBuffers, index, gpuVa);
|
||||||
|
|
||||||
gpuVa = BitUtils.AlignDown(gpuVa, _context.Capabilities.StorageBufferOffsetAlignment);
|
gpuVa = BitUtils.AlignDown<ulong>(gpuVa, (ulong)_context.Capabilities.StorageBufferOffsetAlignment);
|
||||||
|
|
||||||
ulong address = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size);
|
ulong address = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size);
|
||||||
|
|
||||||
@@ -276,7 +276,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
|
|
||||||
RecordStorageAlignment(buffers, index, gpuVa);
|
RecordStorageAlignment(buffers, index, gpuVa);
|
||||||
|
|
||||||
gpuVa = BitUtils.AlignDown(gpuVa, _context.Capabilities.StorageBufferOffsetAlignment);
|
gpuVa = BitUtils.AlignDown<ulong>(gpuVa, (ulong)_context.Capabilities.StorageBufferOffsetAlignment);
|
||||||
|
|
||||||
ulong address = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size);
|
ulong address = _channel.MemoryManager.Physical.BufferCache.TranslateAndCreateBuffer(_channel.MemoryManager, gpuVa, size);
|
||||||
|
|
||||||
|
@@ -114,7 +114,9 @@ namespace Ryujinx.Graphics.OpenGL
|
|||||||
supports3DTextureCompression: false,
|
supports3DTextureCompression: false,
|
||||||
supportsBgraFormat: false,
|
supportsBgraFormat: false,
|
||||||
supportsR4G4Format: false,
|
supportsR4G4Format: false,
|
||||||
|
supportsR4G4B4A4Format: true,
|
||||||
supportsSnormBufferTextureFormat: false,
|
supportsSnormBufferTextureFormat: false,
|
||||||
|
supports5BitComponentFormat: true,
|
||||||
supportsFragmentShaderInterlock: HwCapabilities.SupportsFragmentShaderInterlock,
|
supportsFragmentShaderInterlock: HwCapabilities.SupportsFragmentShaderInterlock,
|
||||||
supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
|
supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
|
||||||
supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough,
|
supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough,
|
||||||
|
@@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Texture
|
|||||||
{
|
{
|
||||||
public static class LayoutConverter
|
public static class LayoutConverter
|
||||||
{
|
{
|
||||||
private const int HostStrideAlignment = 4;
|
public const int HostStrideAlignment = 4;
|
||||||
|
|
||||||
public static void ConvertBlockLinearToLinear(
|
public static void ConvertBlockLinearToLinear(
|
||||||
Span<byte> dst,
|
Span<byte> dst,
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
using Ryujinx.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Intrinsics;
|
using System.Runtime.Intrinsics;
|
||||||
@@ -7,9 +8,27 @@ namespace Ryujinx.Graphics.Texture
|
|||||||
{
|
{
|
||||||
public static class PixelConverter
|
public static class PixelConverter
|
||||||
{
|
{
|
||||||
public unsafe static byte[] ConvertR4G4ToR4G4B4A4(ReadOnlySpan<byte> data)
|
private static (int remainder, int outRemainder, int height) GetLineRemainders(int length, int width, int bpp, int outBpp)
|
||||||
|
{
|
||||||
|
int stride = BitUtils.AlignUp(width * bpp, LayoutConverter.HostStrideAlignment);
|
||||||
|
int remainder = stride / bpp - width;
|
||||||
|
|
||||||
|
int outStride = BitUtils.AlignUp(width * outBpp, LayoutConverter.HostStrideAlignment);
|
||||||
|
int outRemainder = outStride / outBpp - width;
|
||||||
|
|
||||||
|
return (remainder, outRemainder, length / stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe static byte[] ConvertR4G4ToR4G4B4A4(ReadOnlySpan<byte> data, int width)
|
||||||
{
|
{
|
||||||
byte[] output = new byte[data.Length * 2];
|
byte[] output = new byte[data.Length * 2];
|
||||||
|
|
||||||
|
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 1, 2);
|
||||||
|
|
||||||
|
Span<ushort> outputSpan = MemoryMarshal.Cast<byte, ushort>(output);
|
||||||
|
|
||||||
|
if (remainder == 0)
|
||||||
|
{
|
||||||
int start = 0;
|
int start = 0;
|
||||||
|
|
||||||
if (Sse41.IsSupported)
|
if (Sse41.IsSupported)
|
||||||
@@ -26,12 +45,170 @@ namespace Ryujinx.Graphics.Texture
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Span<ushort> outputSpan = MemoryMarshal.Cast<byte, ushort>(output);
|
|
||||||
|
|
||||||
for (int i = start; i < data.Length; i++)
|
for (int i = start; i < data.Length; i++)
|
||||||
{
|
{
|
||||||
outputSpan[i] = (ushort)data[i];
|
outputSpan[i] = (ushort)data[i];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int offset = 0;
|
||||||
|
int outOffset = 0;
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
outputSpan[outOffset++] = data[offset++];
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += remainder;
|
||||||
|
outOffset += outRemainder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe static byte[] ConvertR5G6B5ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
|
||||||
|
{
|
||||||
|
byte[] output = new byte[data.Length * 2];
|
||||||
|
int offset = 0;
|
||||||
|
int outOffset = 0;
|
||||||
|
|
||||||
|
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
|
||||||
|
|
||||||
|
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
|
||||||
|
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output);
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
uint packed = inputSpan[offset++];
|
||||||
|
|
||||||
|
uint outputPacked = 0xff000000;
|
||||||
|
outputPacked |= (packed << 3) & 0x000000f8;
|
||||||
|
outputPacked |= (packed << 8) & 0x00f80000;
|
||||||
|
|
||||||
|
// Replicate 5 bit components.
|
||||||
|
outputPacked |= (outputPacked >> 5) & 0x00070007;
|
||||||
|
|
||||||
|
// Include and replicate 6 bit component.
|
||||||
|
outputPacked |= ((packed << 5) & 0x0000fc00) | ((packed >> 1) & 0x00000300);
|
||||||
|
|
||||||
|
outputSpan[outOffset++] = outputPacked;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += remainder;
|
||||||
|
outOffset += outRemainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe static byte[] ConvertR5G5B5ToR8G8B8A8(ReadOnlySpan<byte> data, int width, bool forceAlpha)
|
||||||
|
{
|
||||||
|
byte[] output = new byte[data.Length * 2];
|
||||||
|
int offset = 0;
|
||||||
|
int outOffset = 0;
|
||||||
|
|
||||||
|
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
|
||||||
|
|
||||||
|
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
|
||||||
|
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output);
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
uint packed = inputSpan[offset++];
|
||||||
|
|
||||||
|
uint a = forceAlpha ? 1 : (packed >> 15);
|
||||||
|
|
||||||
|
uint outputPacked = a * 0xff000000;
|
||||||
|
outputPacked |= (packed << 3) & 0x000000f8;
|
||||||
|
outputPacked |= (packed << 6) & 0x0000f800;
|
||||||
|
outputPacked |= (packed << 9) & 0x00f80000;
|
||||||
|
|
||||||
|
// Replicate 5 bit components.
|
||||||
|
outputPacked |= (outputPacked >> 5) & 0x00070707;
|
||||||
|
|
||||||
|
outputSpan[outOffset++] = outputPacked;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += remainder;
|
||||||
|
outOffset += outRemainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe static byte[] ConvertA1B5G5R5ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
|
||||||
|
{
|
||||||
|
byte[] output = new byte[data.Length * 2];
|
||||||
|
int offset = 0;
|
||||||
|
int outOffset = 0;
|
||||||
|
|
||||||
|
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
|
||||||
|
|
||||||
|
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
|
||||||
|
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output);
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
uint packed = inputSpan[offset++];
|
||||||
|
|
||||||
|
uint a = packed >> 15;
|
||||||
|
|
||||||
|
uint outputPacked = a * 0xff000000;
|
||||||
|
outputPacked |= (packed >> 8) & 0x000000f8;
|
||||||
|
outputPacked |= (packed << 5) & 0x0000f800;
|
||||||
|
outputPacked |= (packed << 18) & 0x00f80000;
|
||||||
|
|
||||||
|
// Replicate 5 bit components.
|
||||||
|
outputPacked |= (outputPacked >> 5) & 0x00070707;
|
||||||
|
|
||||||
|
outputSpan[outOffset++] = outputPacked;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += remainder;
|
||||||
|
outOffset += outRemainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe static byte[] ConvertR4G4B4A4ToR8G8B8A8(ReadOnlySpan<byte> data, int width)
|
||||||
|
{
|
||||||
|
byte[] output = new byte[data.Length * 2];
|
||||||
|
int offset = 0;
|
||||||
|
int outOffset = 0;
|
||||||
|
|
||||||
|
(int remainder, int outRemainder, int height) = GetLineRemainders(data.Length, width, 2, 4);
|
||||||
|
|
||||||
|
ReadOnlySpan<ushort> inputSpan = MemoryMarshal.Cast<byte, ushort>(data);
|
||||||
|
Span<uint> outputSpan = MemoryMarshal.Cast<byte, uint>(output);
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
uint packed = inputSpan[offset++];
|
||||||
|
|
||||||
|
uint outputPacked = packed & 0x0000000f;
|
||||||
|
outputPacked |= (packed << 4) & 0x00000f00;
|
||||||
|
outputPacked |= (packed << 8) & 0x000f0000;
|
||||||
|
outputPacked |= (packed << 12) & 0x0f000000;
|
||||||
|
|
||||||
|
outputSpan[outOffset++] = outputPacked * 0x11;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += remainder;
|
||||||
|
outOffset += outRemainder;
|
||||||
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
var range = _freeRanges[i];
|
var range = _freeRanges[i];
|
||||||
|
|
||||||
ulong alignedOffset = BitUtils.AlignUp(range.Offset, (int)alignment);
|
ulong alignedOffset = BitUtils.AlignUp<ulong>(range.Offset, alignment);
|
||||||
ulong sizeDelta = alignedOffset - range.Offset;
|
ulong sizeDelta = alignedOffset - range.Offset;
|
||||||
ulong usableSize = range.Size - sizeDelta;
|
ulong usableSize = range.Size - sizeDelta;
|
||||||
|
|
||||||
@@ -196,7 +196,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong blockAlignedSize = BitUtils.AlignUp(size, _blockAlignment);
|
ulong blockAlignedSize = BitUtils.AlignUp<ulong>(size, (ulong)_blockAlignment);
|
||||||
|
|
||||||
var memoryAllocateInfo = new MemoryAllocateInfo()
|
var memoryAllocateInfo = new MemoryAllocateInfo()
|
||||||
{
|
{
|
||||||
|
@@ -396,6 +396,17 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
GAL.Format.Etc2RgbSrgb,
|
GAL.Format.Etc2RgbSrgb,
|
||||||
GAL.Format.Etc2RgbUnorm);
|
GAL.Format.Etc2RgbUnorm);
|
||||||
|
|
||||||
|
bool supports5BitComponentFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||||
|
GAL.Format.R5G6B5Unorm,
|
||||||
|
GAL.Format.R5G5B5A1Unorm,
|
||||||
|
GAL.Format.R5G5B5X1Unorm,
|
||||||
|
GAL.Format.B5G6R5Unorm,
|
||||||
|
GAL.Format.B5G5R5A1Unorm,
|
||||||
|
GAL.Format.A1B5G5R5Unorm);
|
||||||
|
|
||||||
|
bool supportsR4G4B4A4Format = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||||
|
GAL.Format.R4G4B4A4Unorm);
|
||||||
|
|
||||||
PhysicalDeviceVulkan12Features featuresVk12 = new PhysicalDeviceVulkan12Features()
|
PhysicalDeviceVulkan12Features featuresVk12 = new PhysicalDeviceVulkan12Features()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceVulkan12Features
|
SType = StructureType.PhysicalDeviceVulkan12Features
|
||||||
@@ -425,7 +436,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
supports3DTextureCompression: true,
|
supports3DTextureCompression: true,
|
||||||
supportsBgraFormat: true,
|
supportsBgraFormat: true,
|
||||||
supportsR4G4Format: false,
|
supportsR4G4Format: false,
|
||||||
|
supportsR4G4B4A4Format: supportsR4G4B4A4Format,
|
||||||
supportsSnormBufferTextureFormat: true,
|
supportsSnormBufferTextureFormat: true,
|
||||||
|
supports5BitComponentFormat: supports5BitComponentFormat,
|
||||||
supportsFragmentShaderInterlock: Capabilities.SupportsFragmentShaderInterlock,
|
supportsFragmentShaderInterlock: Capabilities.SupportsFragmentShaderInterlock,
|
||||||
supportsFragmentShaderOrderingIntel: false,
|
supportsFragmentShaderOrderingIntel: false,
|
||||||
supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough,
|
supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough,
|
||||||
|
@@ -81,8 +81,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||||||
attributeMask |= MemoryAttribute.DeviceMapped;
|
attributeMask |= MemoryAttribute.DeviceMapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong clientAddrTruncated = BitUtils.AlignDown(desc.ClientAddress, KPageTableBase.PageSize);
|
ulong clientAddrTruncated = BitUtils.AlignDown<ulong>(desc.ClientAddress, KPageTableBase.PageSize);
|
||||||
ulong clientAddrRounded = BitUtils.AlignUp (desc.ClientAddress, KPageTableBase.PageSize);
|
ulong clientAddrRounded = BitUtils.AlignUp<ulong>(desc.ClientAddress, KPageTableBase.PageSize);
|
||||||
|
|
||||||
// Check if address is not aligned, in this case we need to perform 2 copies.
|
// Check if address is not aligned, in this case we need to perform 2 copies.
|
||||||
if (clientAddrTruncated != clientAddrRounded)
|
if (clientAddrTruncated != clientAddrRounded)
|
||||||
@@ -113,9 +113,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||||||
ulong clientEndAddr = desc.ClientAddress + desc.Size;
|
ulong clientEndAddr = desc.ClientAddress + desc.Size;
|
||||||
ulong serverEndAddr = desc.ServerAddress + desc.Size;
|
ulong serverEndAddr = desc.ServerAddress + desc.Size;
|
||||||
|
|
||||||
ulong clientEndAddrTruncated = BitUtils.AlignDown(clientEndAddr, KPageTableBase.PageSize);
|
ulong clientEndAddrTruncated = BitUtils.AlignDown<ulong>(clientEndAddr, (ulong)KPageTableBase.PageSize);
|
||||||
ulong clientEndAddrRounded = BitUtils.AlignUp (clientEndAddr, KPageTableBase.PageSize);
|
ulong clientEndAddrRounded = BitUtils.AlignUp<ulong>(clientEndAddr, KPageTableBase.PageSize);
|
||||||
ulong serverEndAddrTruncated = BitUtils.AlignDown(serverEndAddr, KPageTableBase.PageSize);
|
ulong serverEndAddrTruncated = BitUtils.AlignDown<ulong>(serverEndAddr, (ulong)KPageTableBase.PageSize);
|
||||||
|
|
||||||
if (clientEndAddrTruncated < clientEndAddrRounded &&
|
if (clientEndAddrTruncated < clientEndAddrRounded &&
|
||||||
(clientAddrTruncated == clientAddrRounded || clientAddrTruncated < clientEndAddrTruncated))
|
(clientAddrTruncated == clientAddrRounded || clientAddrTruncated < clientEndAddrTruncated))
|
||||||
|
@@ -1005,7 +1005,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||||||
recvListEndAddr = recvListBaseAddr + size;
|
recvListEndAddr = recvListBaseAddr + size;
|
||||||
}
|
}
|
||||||
|
|
||||||
recvListBufferAddress = BitUtils.AlignUp(recvListBaseAddr + dstOffset, 0x10);
|
recvListBufferAddress = BitUtils.AlignUp<ulong>(recvListBaseAddr + dstOffset, 0x10);
|
||||||
|
|
||||||
ulong endAddress = recvListBufferAddress + descriptor.BufferSize;
|
ulong endAddress = recvListBufferAddress + descriptor.BufferSize;
|
||||||
|
|
||||||
|
@@ -44,7 +44,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
|
|
||||||
public KernelResult Map(ulong address, ulong size, KMemoryPermission perm)
|
public KernelResult Map(ulong address, ulong size, KMemoryPermission perm)
|
||||||
{
|
{
|
||||||
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp(size, KPageTableBase.PageSize))
|
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp<ulong>(size, (ulong)KPageTableBase.PageSize))
|
||||||
{
|
{
|
||||||
return KernelResult.InvalidSize;
|
return KernelResult.InvalidSize;
|
||||||
}
|
}
|
||||||
@@ -73,7 +73,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
|
|
||||||
public KernelResult MapToOwner(ulong address, ulong size, KMemoryPermission permission)
|
public KernelResult MapToOwner(ulong address, ulong size, KMemoryPermission permission)
|
||||||
{
|
{
|
||||||
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp(size, KPageTableBase.PageSize))
|
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp<ulong>(size, (ulong)KPageTableBase.PageSize))
|
||||||
{
|
{
|
||||||
return KernelResult.InvalidSize;
|
return KernelResult.InvalidSize;
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
|
|
||||||
public KernelResult Unmap(ulong address, ulong size)
|
public KernelResult Unmap(ulong address, ulong size)
|
||||||
{
|
{
|
||||||
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp(size, KPageTableBase.PageSize))
|
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp<ulong>(size, (ulong)KPageTableBase.PageSize))
|
||||||
{
|
{
|
||||||
return KernelResult.InvalidSize;
|
return KernelResult.InvalidSize;
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
|
|
||||||
public KernelResult UnmapFromOwner(ulong address, ulong size)
|
public KernelResult UnmapFromOwner(ulong address, ulong size)
|
||||||
{
|
{
|
||||||
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp(size, KPageTableBase.PageSize))
|
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp<ulong>(size, KPageTableBase.PageSize))
|
||||||
{
|
{
|
||||||
return KernelResult.InvalidSize;
|
return KernelResult.InvalidSize;
|
||||||
}
|
}
|
||||||
|
@@ -101,7 +101,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
for (int depth = HighestDepthIndex; depth >= 0; depth--)
|
for (int depth = HighestDepthIndex; depth >= 0; depth--)
|
||||||
{
|
{
|
||||||
_bitStorages[depth] = storage;
|
_bitStorages[depth] = storage;
|
||||||
size = BitUtils.DivRoundUp(size, UInt64BitSize);
|
size = BitUtils.DivRoundUp<ulong>(size, (ulong)UInt64BitSize);
|
||||||
storage = storage.Slice((int)size);
|
storage = storage.Slice((int)size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +288,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
|
|
||||||
for (int depth = GetRequiredDepth(regionSize) - 1; depth >= 0; depth--)
|
for (int depth = GetRequiredDepth(regionSize) - 1; depth >= 0; depth--)
|
||||||
{
|
{
|
||||||
regionSize = BitUtils.DivRoundUp(regionSize, UInt64BitSize);
|
regionSize = BitUtils.DivRoundUp<ulong>(regionSize, UInt64BitSize);
|
||||||
overheadBits += (int)regionSize;
|
overheadBits += (int)regionSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -48,7 +48,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
{
|
{
|
||||||
int diff = 1 << (NextShift - Shift);
|
int diff = 1 << (NextShift - Shift);
|
||||||
|
|
||||||
offset = BitUtils.AlignDown(offset, diff);
|
offset = BitUtils.AlignDown(offset, (ulong)diff);
|
||||||
|
|
||||||
if (_bitmap.ClearRange(offset, diff))
|
if (_bitmap.ClearRange(offset, diff))
|
||||||
{
|
{
|
||||||
|
@@ -203,8 +203,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
heapRegion.Size = 0x180000000;
|
heapRegion.Size = 0x180000000;
|
||||||
stackRegion.Size = 0x80000000;
|
stackRegion.Size = 0x80000000;
|
||||||
tlsIoRegion.Size = 0x1000000000;
|
tlsIoRegion.Size = 0x1000000000;
|
||||||
CodeRegionStart = BitUtils.AlignDown(address, 0x200000);
|
CodeRegionStart = BitUtils.AlignDown<ulong>(address, 0x200000);
|
||||||
codeRegionSize = BitUtils.AlignUp(endAddr, 0x200000) - CodeRegionStart;
|
codeRegionSize = BitUtils.AlignUp<ulong>(endAddr, 0x200000) - CodeRegionStart;
|
||||||
stackAndTlsIoStart = 0;
|
stackAndTlsIoStart = 0;
|
||||||
stackAndTlsIoEnd = 0;
|
stackAndTlsIoEnd = 0;
|
||||||
baseAddress = 0x8000000;
|
baseAddress = 0x8000000;
|
||||||
@@ -1584,8 +1584,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
return KernelResult.OutOfResource;
|
return KernelResult.OutOfResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong srcMapAddress = BitUtils.AlignUp(src, PageSize);
|
ulong srcMapAddress = BitUtils.AlignUp<ulong>(src, PageSize);
|
||||||
ulong srcMapEndAddr = BitUtils.AlignDown(src + size, PageSize);
|
ulong srcMapEndAddr = BitUtils.AlignDown<ulong>(src + size, PageSize);
|
||||||
ulong srcMapSize = srcMapEndAddr - srcMapAddress;
|
ulong srcMapSize = srcMapEndAddr - srcMapAddress;
|
||||||
|
|
||||||
result = MapPagesFromClientProcess(size, src, permission, state, srcPageTable, send, out ulong va);
|
result = MapPagesFromClientProcess(size, src, permission, state, srcPageTable, send, out ulong va);
|
||||||
@@ -1659,10 +1659,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
attributeMask |= MemoryAttribute.DeviceMapped;
|
attributeMask |= MemoryAttribute.DeviceMapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong addressRounded = BitUtils.AlignUp(address, PageSize);
|
ulong addressRounded = BitUtils.AlignUp<ulong>(address, PageSize);
|
||||||
ulong addressTruncated = BitUtils.AlignDown(address, PageSize);
|
ulong addressTruncated = BitUtils.AlignDown<ulong>(address, PageSize);
|
||||||
ulong endAddrRounded = BitUtils.AlignUp(endAddr, PageSize);
|
ulong endAddrRounded = BitUtils.AlignUp<ulong>(endAddr, PageSize);
|
||||||
ulong endAddrTruncated = BitUtils.AlignDown(endAddr, PageSize);
|
ulong endAddrTruncated = BitUtils.AlignDown<ulong>(endAddr, PageSize);
|
||||||
|
|
||||||
if (!_slabManager.CanAllocate(MaxBlocksNeededForInsertion))
|
if (!_slabManager.CanAllocate(MaxBlocksNeededForInsertion))
|
||||||
{
|
{
|
||||||
@@ -1769,10 +1769,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
|
|
||||||
ulong endAddr = address + size;
|
ulong endAddr = address + size;
|
||||||
|
|
||||||
ulong addressTruncated = BitUtils.AlignDown(address, PageSize);
|
ulong addressTruncated = BitUtils.AlignDown<ulong>(address, PageSize);
|
||||||
ulong addressRounded = BitUtils.AlignUp(address, PageSize);
|
ulong addressRounded = BitUtils.AlignUp<ulong>(address, PageSize);
|
||||||
ulong endAddrTruncated = BitUtils.AlignDown(endAddr, PageSize);
|
ulong endAddrTruncated = BitUtils.AlignDown<ulong>(endAddr, PageSize);
|
||||||
ulong endAddrRounded = BitUtils.AlignUp(endAddr, PageSize);
|
ulong endAddrRounded = BitUtils.AlignUp<ulong>(endAddr, PageSize);
|
||||||
|
|
||||||
ulong neededSize = endAddrRounded - addressTruncated;
|
ulong neededSize = endAddrRounded - addressTruncated;
|
||||||
|
|
||||||
@@ -1983,10 +1983,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
return KernelResult.OutOfResource;
|
return KernelResult.OutOfResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong addressTruncated = BitUtils.AlignDown(address, PageSize);
|
ulong addressTruncated = BitUtils.AlignDown<ulong>(address, PageSize);
|
||||||
ulong addressRounded = BitUtils.AlignUp(address, PageSize);
|
ulong addressRounded = BitUtils.AlignUp<ulong>(address, PageSize);
|
||||||
ulong endAddrTruncated = BitUtils.AlignDown(endAddr, PageSize);
|
ulong endAddrTruncated = BitUtils.AlignDown<ulong>(endAddr, PageSize);
|
||||||
ulong endAddrRounded = BitUtils.AlignUp(endAddr, PageSize);
|
ulong endAddrRounded = BitUtils.AlignUp<ulong>(endAddr, PageSize);
|
||||||
|
|
||||||
ulong pagesCount = (endAddrRounded - addressTruncated) / PageSize;
|
ulong pagesCount = (endAddrRounded - addressTruncated) / PageSize;
|
||||||
|
|
||||||
@@ -2010,10 +2010,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
{
|
{
|
||||||
ulong endAddr = address + size;
|
ulong endAddr = address + size;
|
||||||
|
|
||||||
ulong addressRounded = BitUtils.AlignUp(address, PageSize);
|
ulong addressRounded = BitUtils.AlignUp<ulong>(address, PageSize);
|
||||||
ulong addressTruncated = BitUtils.AlignDown(address, PageSize);
|
ulong addressTruncated = BitUtils.AlignDown<ulong>(address, PageSize);
|
||||||
ulong endAddrRounded = BitUtils.AlignUp(endAddr, PageSize);
|
ulong endAddrRounded = BitUtils.AlignUp<ulong>(endAddr, PageSize);
|
||||||
ulong endAddrTruncated = BitUtils.AlignDown(endAddr, PageSize);
|
ulong endAddrTruncated = BitUtils.AlignDown<ulong>(endAddr, PageSize);
|
||||||
|
|
||||||
ulong pagesCount = addressRounded < endAddrTruncated ? (endAddrTruncated - addressRounded) / PageSize : 0;
|
ulong pagesCount = addressRounded < endAddrTruncated ? (endAddrTruncated - addressRounded) / PageSize : 0;
|
||||||
|
|
||||||
@@ -2540,7 +2540,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
|
|
||||||
for (int attempt = 0; attempt < 8; attempt++)
|
for (int attempt = 0; attempt < 8; attempt++)
|
||||||
{
|
{
|
||||||
ulong aslrAddress = BitUtils.AlignDown(regionStart + GetRandomValue(0, aslrMaxOffset) * (ulong)alignment, alignment);
|
ulong aslrAddress = BitUtils.AlignDown(regionStart + GetRandomValue(0, aslrMaxOffset) * (ulong)alignment, (ulong)alignment);
|
||||||
ulong aslrEndAddr = aslrAddress + totalNeededSize;
|
ulong aslrEndAddr = aslrAddress + totalNeededSize;
|
||||||
|
|
||||||
KMemoryInfo info = _blockManager.FindBlock(aslrAddress).GetInfo();
|
KMemoryInfo info = _blockManager.FindBlock(aslrAddress).GetInfo();
|
||||||
@@ -2618,7 +2618,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
|
|
||||||
currBaseAddr += reservedSize;
|
currBaseAddr += reservedSize;
|
||||||
|
|
||||||
ulong address = BitUtils.AlignDown(currBaseAddr, alignment) + reservedStart;
|
ulong address = BitUtils.AlignDown<ulong>(currBaseAddr, (ulong)alignment) + reservedStart;
|
||||||
|
|
||||||
if (currBaseAddr > address)
|
if (currBaseAddr > address)
|
||||||
{
|
{
|
||||||
@@ -2834,7 +2834,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
{
|
{
|
||||||
lock (_blockManager)
|
lock (_blockManager)
|
||||||
{
|
{
|
||||||
return BitUtils.DivRoundUp(GetMmUsedSize(), PageSize);
|
return BitUtils.DivRoundUp<ulong>(GetMmUsedSize(), PageSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
KProcess process,
|
KProcess process,
|
||||||
KMemoryPermission permission)
|
KMemoryPermission permission)
|
||||||
{
|
{
|
||||||
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp(size, KPageTableBase.PageSize))
|
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp<ulong>(size, KPageTableBase.PageSize))
|
||||||
{
|
{
|
||||||
return KernelResult.InvalidSize;
|
return KernelResult.InvalidSize;
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
|
|
||||||
public KernelResult UnmapFromProcess(KPageTableBase memoryManager, ulong address, ulong size, KProcess process)
|
public KernelResult UnmapFromProcess(KPageTableBase memoryManager, ulong address, ulong size, KProcess process)
|
||||||
{
|
{
|
||||||
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp(size, KPageTableBase.PageSize))
|
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp<ulong>(size, KPageTableBase.PageSize))
|
||||||
{
|
{
|
||||||
return KernelResult.InvalidSize;
|
return KernelResult.InvalidSize;
|
||||||
}
|
}
|
||||||
|
@@ -67,7 +67,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
KProcess process,
|
KProcess process,
|
||||||
KMemoryPermission permission)
|
KMemoryPermission permission)
|
||||||
{
|
{
|
||||||
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp(size, KPageTableBase.PageSize))
|
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp<ulong>(size, KPageTableBase.PageSize))
|
||||||
{
|
{
|
||||||
return KernelResult.InvalidSize;
|
return KernelResult.InvalidSize;
|
||||||
}
|
}
|
||||||
@@ -95,7 +95,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
ulong size,
|
ulong size,
|
||||||
KProcess process)
|
KProcess process)
|
||||||
{
|
{
|
||||||
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp(size, KPageTableBase.PageSize))
|
if (_pageList.GetPagesCount() != BitUtils.DivRoundUp<ulong>(size, (ulong)KPageTableBase.PageSize))
|
||||||
{
|
{
|
||||||
return KernelResult.InvalidSize;
|
return KernelResult.InvalidSize;
|
||||||
}
|
}
|
||||||
|
@@ -472,7 +472,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||||||
|
|
||||||
public KernelResult FreeThreadLocalStorage(ulong tlsSlotAddr)
|
public KernelResult FreeThreadLocalStorage(ulong tlsSlotAddr)
|
||||||
{
|
{
|
||||||
ulong tlsPageAddr = BitUtils.AlignDown(tlsSlotAddr, KPageTableBase.PageSize);
|
ulong tlsPageAddr = BitUtils.AlignDown<ulong>(tlsSlotAddr, KPageTableBase.PageSize);
|
||||||
|
|
||||||
KernelContext.CriticalSection.Enter();
|
KernelContext.CriticalSection.Enter();
|
||||||
|
|
||||||
@@ -554,7 +554,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||||||
throw new InvalidOperationException("Trying to start a process with a invalid state!");
|
throw new InvalidOperationException("Trying to start a process with a invalid state!");
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong stackSizeRounded = BitUtils.AlignUp(stackSize, KPageTableBase.PageSize);
|
ulong stackSizeRounded = BitUtils.AlignUp<ulong>(stackSize, KPageTableBase.PageSize);
|
||||||
|
|
||||||
ulong neededSize = stackSizeRounded + _imageSize;
|
ulong neededSize = stackSizeRounded + _imageSize;
|
||||||
|
|
||||||
|
@@ -47,7 +47,7 @@ namespace Ryujinx.HLE.HOS
|
|||||||
endOffset = kip.BssOffset + kip.BssSize;
|
endOffset = kip.BssOffset + kip.BssSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint codeSize = BitUtils.AlignUp(kip.TextOffset + endOffset, KPageTableBase.PageSize);
|
uint codeSize = BitUtils.AlignUp<uint>(kip.TextOffset + endOffset, KPageTableBase.PageSize);
|
||||||
|
|
||||||
int codePagesCount = (int)(codeSize / KPageTableBase.PageSize);
|
int codePagesCount = (int)(codeSize / KPageTableBase.PageSize);
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ namespace Ryujinx.HLE.HOS
|
|||||||
nsoSize = dataEnd;
|
nsoSize = dataEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsoSize = BitUtils.AlignUp(nsoSize, KPageTableBase.PageSize);
|
nsoSize = BitUtils.AlignUp<uint>(nsoSize, KPageTableBase.PageSize);
|
||||||
|
|
||||||
nsoBase[index] = codeStart + (ulong)codeSize;
|
nsoBase[index] = codeStart + (ulong)codeSize;
|
||||||
|
|
||||||
@@ -349,7 +349,7 @@ namespace Ryujinx.HLE.HOS
|
|||||||
return KernelResult.Success;
|
return KernelResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = BitUtils.AlignUp(size, KPageTableBase.PageSize);
|
size = BitUtils.AlignUp<ulong>(size, KPageTableBase.PageSize);
|
||||||
|
|
||||||
return process.MemoryManager.SetProcessMemoryPermission(address, size, permission);
|
return process.MemoryManager.SetProcessMemoryPermission(address, size, permission);
|
||||||
}
|
}
|
||||||
|
@@ -321,7 +321,7 @@ namespace Ryujinx.HLE.HOS.Services.Ro
|
|||||||
|
|
||||||
ulong bssStart = dataStart + (ulong)relocatableObject.Data.Length;
|
ulong bssStart = dataStart + (ulong)relocatableObject.Data.Length;
|
||||||
|
|
||||||
ulong bssEnd = BitUtils.AlignUp(bssStart + (ulong)relocatableObject.BssSize, KPageTableBase.PageSize);
|
ulong bssEnd = BitUtils.AlignUp<ulong>(bssStart + relocatableObject.BssSize, KPageTableBase.PageSize);
|
||||||
|
|
||||||
process.CpuMemory.Write(textStart, relocatableObject.Text);
|
process.CpuMemory.Write(textStart, relocatableObject.Text);
|
||||||
process.CpuMemory.Write(roStart, relocatableObject.Ro);
|
process.CpuMemory.Write(roStart, relocatableObject.Ro);
|
||||||
|
@@ -36,7 +36,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||||||
{
|
{
|
||||||
uint headerSize = (uint)Unsafe.SizeOf<ParcelHeader>();
|
uint headerSize = (uint)Unsafe.SizeOf<ParcelHeader>();
|
||||||
|
|
||||||
_rawData = new byte[BitUtils.AlignUp(headerSize + payloadSize + objectsSize, 4)];
|
_rawData = new byte[BitUtils.AlignUp<uint>(headerSize + payloadSize + objectsSize, 4)];
|
||||||
|
|
||||||
Header.PayloadSize = payloadSize;
|
Header.PayloadSize = payloadSize;
|
||||||
Header.ObjectsSize = objectsSize;
|
Header.ObjectsSize = objectsSize;
|
||||||
|
@@ -32,20 +32,9 @@ namespace Ryujinx.HLE
|
|||||||
|
|
||||||
public Switch(HLEConfiguration configuration)
|
public Switch(HLEConfiguration configuration)
|
||||||
{
|
{
|
||||||
if (configuration.GpuRenderer == null)
|
ArgumentNullException.ThrowIfNull(configuration.GpuRenderer);
|
||||||
{
|
ArgumentNullException.ThrowIfNull(configuration.AudioDeviceDriver);
|
||||||
throw new ArgumentNullException(nameof(configuration.GpuRenderer));
|
ArgumentNullException.ThrowIfNull(configuration.UserChannelPersistence);
|
||||||
}
|
|
||||||
|
|
||||||
if (configuration.AudioDeviceDriver == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(configuration.AudioDeviceDriver));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configuration.UserChannelPersistence == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(configuration.UserChannelPersistence));
|
|
||||||
}
|
|
||||||
|
|
||||||
Configuration = configuration;
|
Configuration = configuration;
|
||||||
FileSystem = Configuration.VirtualFileSystem;
|
FileSystem = Configuration.VirtualFileSystem;
|
||||||
|
@@ -279,10 +279,7 @@ namespace Ryujinx.Memory
|
|||||||
{
|
{
|
||||||
IntPtr ptr = _pointer;
|
IntPtr ptr = _pointer;
|
||||||
|
|
||||||
if (ptr == IntPtr.Zero)
|
ObjectDisposedException.ThrowIf(ptr == IntPtr.Zero, this);
|
||||||
{
|
|
||||||
ThrowObjectDisposed();
|
|
||||||
}
|
|
||||||
|
|
||||||
int size = Unsafe.SizeOf<T>();
|
int size = Unsafe.SizeOf<T>();
|
||||||
|
|
||||||
@@ -312,10 +309,7 @@ namespace Ryujinx.Memory
|
|||||||
{
|
{
|
||||||
IntPtr ptr = _pointer;
|
IntPtr ptr = _pointer;
|
||||||
|
|
||||||
if (ptr == IntPtr.Zero)
|
ObjectDisposedException.ThrowIf(ptr == IntPtr.Zero, this);
|
||||||
{
|
|
||||||
ThrowObjectDisposed();
|
|
||||||
}
|
|
||||||
|
|
||||||
ulong endOffset = offset + size;
|
ulong endOffset = offset + size;
|
||||||
|
|
||||||
@@ -454,7 +448,6 @@ namespace Ryujinx.Memory
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ThrowObjectDisposed() => throw new ObjectDisposedException(nameof(MemoryBlock));
|
|
||||||
private static void ThrowInvalidMemoryRegionException() => throw new InvalidMemoryRegionException();
|
private static void ThrowInvalidMemoryRegionException() => throw new InvalidMemoryRegionException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -411,10 +411,7 @@ namespace Ryujinx.Memory.Tracking
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (_disposed)
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
{
|
|
||||||
throw new ObjectDisposedException(GetType().FullName);
|
|
||||||
}
|
|
||||||
|
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user