Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
666e05f5cb | ||
|
8d9d508dc7 | ||
|
e27f5522e2 | ||
|
add2a9d151 |
@@ -11,6 +11,7 @@ using Ryujinx.Audio.Renderer.Server.Voice;
|
|||||||
using Ryujinx.Audio.Renderer.Utils;
|
using Ryujinx.Audio.Renderer.Utils;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
@@ -149,12 +150,16 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
state.InUse = false;
|
state.InUse = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Memory<VoiceUpdateState>[] voiceUpdateStatesArray = ArrayPool<Memory<VoiceUpdateState>>.Shared.Rent(Constants.VoiceChannelCountMax);
|
||||||
|
|
||||||
|
Span<Memory<VoiceUpdateState>> voiceUpdateStates = voiceUpdateStatesArray.AsSpan(0, Constants.VoiceChannelCountMax);
|
||||||
|
|
||||||
// Start processing
|
// Start processing
|
||||||
for (int i = 0; i < context.GetCount(); i++)
|
for (int i = 0; i < context.GetCount(); i++)
|
||||||
{
|
{
|
||||||
VoiceInParameter parameter = parameters[i];
|
VoiceInParameter parameter = parameters[i];
|
||||||
|
|
||||||
Memory<VoiceUpdateState>[] voiceUpdateStates = new Memory<VoiceUpdateState>[Constants.VoiceChannelCountMax];
|
voiceUpdateStates.Fill(Memory<VoiceUpdateState>.Empty);
|
||||||
|
|
||||||
ref VoiceOutStatus outStatus = ref SpanIOHelper.GetWriteRef<VoiceOutStatus>(ref _output)[0];
|
ref VoiceOutStatus outStatus = ref SpanIOHelper.GetWriteRef<VoiceOutStatus>(ref _output)[0];
|
||||||
|
|
||||||
@@ -197,6 +202,8 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArrayPool<Memory<VoiceUpdateState>>.Shared.Return(voiceUpdateStatesArray);
|
||||||
|
|
||||||
int currentOutputSize = _output.Length;
|
int currentOutputSize = _output.Length;
|
||||||
|
|
||||||
OutputHeader.VoicesSize = (uint)(Unsafe.SizeOf<VoiceOutStatus>() * context.GetCount());
|
OutputHeader.VoicesSize = (uint)(Unsafe.SizeOf<VoiceOutStatus>() * context.GetCount());
|
||||||
|
@@ -378,7 +378,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
|
|||||||
/// <param name="outStatus">The given user output.</param>
|
/// <param name="outStatus">The given user output.</param>
|
||||||
/// <param name="parameter">The user parameter.</param>
|
/// <param name="parameter">The user parameter.</param>
|
||||||
/// <param name="voiceUpdateStates">The voice states associated to the <see cref="VoiceState"/>.</param>
|
/// <param name="voiceUpdateStates">The voice states associated to the <see cref="VoiceState"/>.</param>
|
||||||
public void WriteOutStatus(ref VoiceOutStatus outStatus, ref VoiceInParameter parameter, Memory<VoiceUpdateState>[] voiceUpdateStates)
|
public void WriteOutStatus(ref VoiceOutStatus outStatus, ref VoiceInParameter parameter, ReadOnlySpan<Memory<VoiceUpdateState>> voiceUpdateStates)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// Sanity check in debug mode of the internal state
|
// Sanity check in debug mode of the internal state
|
||||||
@@ -424,7 +424,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
|
|||||||
/// <param name="voiceUpdateStates">The voice states associated to the <see cref="VoiceState"/>.</param>
|
/// <param name="voiceUpdateStates">The voice states associated to the <see cref="VoiceState"/>.</param>
|
||||||
/// <param name="mapper">The mapper to use.</param>
|
/// <param name="mapper">The mapper to use.</param>
|
||||||
/// <param name="behaviourContext">The behaviour context.</param>
|
/// <param name="behaviourContext">The behaviour context.</param>
|
||||||
public void UpdateWaveBuffers(out ErrorInfo[] errorInfos, ref VoiceInParameter parameter, Memory<VoiceUpdateState>[] voiceUpdateStates, ref PoolMapper mapper, ref BehaviourContext behaviourContext)
|
public void UpdateWaveBuffers(out ErrorInfo[] errorInfos, ref VoiceInParameter parameter, ReadOnlySpan<Memory<VoiceUpdateState>> voiceUpdateStates, ref PoolMapper mapper, ref BehaviourContext behaviourContext)
|
||||||
{
|
{
|
||||||
errorInfos = new ErrorInfo[Constants.VoiceWaveBufferCount * 2];
|
errorInfos = new ErrorInfo[Constants.VoiceWaveBufferCount * 2];
|
||||||
|
|
||||||
|
51
Ryujinx.Common/Memory/ByteMemoryPool.ByteMemoryPoolBuffer.cs
Normal file
51
Ryujinx.Common/Memory/ByteMemoryPool.ByteMemoryPoolBuffer.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace Ryujinx.Common.Memory
|
||||||
|
{
|
||||||
|
public sealed partial class ByteMemoryPool
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a <see cref="IMemoryOwner{Byte}"/> that wraps an array rented from
|
||||||
|
/// <see cref="ArrayPool{Byte}.Shared"/> and exposes it as <see cref="Memory{Byte}"/>
|
||||||
|
/// with a length of the requested size.
|
||||||
|
/// </summary>
|
||||||
|
private sealed class ByteMemoryPoolBuffer : IMemoryOwner<byte>
|
||||||
|
{
|
||||||
|
private byte[] _array;
|
||||||
|
private readonly int _length;
|
||||||
|
|
||||||
|
public ByteMemoryPoolBuffer(int length)
|
||||||
|
{
|
||||||
|
_array = ArrayPool<byte>.Shared.Rent(length);
|
||||||
|
_length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a <see cref="Memory{Byte}"/> belonging to this owner.
|
||||||
|
/// </summary>
|
||||||
|
public Memory<byte> Memory
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
byte[] array = _array;
|
||||||
|
|
||||||
|
ObjectDisposedException.ThrowIf(array is null, this);
|
||||||
|
|
||||||
|
return new Memory<byte>(array, 0, _length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
var array = Interlocked.Exchange(ref _array, null);
|
||||||
|
|
||||||
|
if (array != null)
|
||||||
|
{
|
||||||
|
ArrayPool<byte>.Shared.Return(array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
108
Ryujinx.Common/Memory/ByteMemoryPool.cs
Normal file
108
Ryujinx.Common/Memory/ByteMemoryPool.cs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
|
|
||||||
|
namespace Ryujinx.Common.Memory
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides a pool of re-usable byte array instances.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class ByteMemoryPool
|
||||||
|
{
|
||||||
|
private static readonly ByteMemoryPool _shared = new ByteMemoryPool();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a <see cref="ByteMemoryPool"/> instance. Private to force access through
|
||||||
|
/// the <see cref="ByteMemoryPool.Shared"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
private ByteMemoryPool()
|
||||||
|
{
|
||||||
|
// No implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves a shared <see cref="ByteMemoryPool"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
public static ByteMemoryPool Shared => _shared;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the maximum buffer size supported by this pool.
|
||||||
|
/// </summary>
|
||||||
|
public int MaxBufferSize => Array.MaxLength;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>.
|
||||||
|
/// The buffer may contain data from a prior use.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="length">The buffer's required length in bytes</param>
|
||||||
|
/// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns>
|
||||||
|
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||||
|
public IMemoryOwner<byte> Rent(long length)
|
||||||
|
=> RentImpl(checked((int)length));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>.
|
||||||
|
/// The buffer may contain data from a prior use.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="length">The buffer's required length in bytes</param>
|
||||||
|
/// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns>
|
||||||
|
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||||
|
public IMemoryOwner<byte> Rent(ulong length)
|
||||||
|
=> RentImpl(checked((int)length));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>.
|
||||||
|
/// The buffer may contain data from a prior use.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="length">The buffer's required length in bytes</param>
|
||||||
|
/// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns>
|
||||||
|
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||||
|
public IMemoryOwner<byte> Rent(int length)
|
||||||
|
=> RentImpl(length);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>.
|
||||||
|
/// The buffer's contents are cleared (set to all 0s) before returning.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="length">The buffer's required length in bytes</param>
|
||||||
|
/// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns>
|
||||||
|
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||||
|
public IMemoryOwner<byte> RentCleared(long length)
|
||||||
|
=> RentCleared(checked((int)length));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>.
|
||||||
|
/// The buffer's contents are cleared (set to all 0s) before returning.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="length">The buffer's required length in bytes</param>
|
||||||
|
/// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns>
|
||||||
|
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||||
|
public IMemoryOwner<byte> RentCleared(ulong length)
|
||||||
|
=> RentCleared(checked((int)length));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>.
|
||||||
|
/// The buffer's contents are cleared (set to all 0s) before returning.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="length">The buffer's required length in bytes</param>
|
||||||
|
/// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns>
|
||||||
|
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||||
|
public IMemoryOwner<byte> RentCleared(int length)
|
||||||
|
{
|
||||||
|
var buffer = RentImpl(length);
|
||||||
|
|
||||||
|
buffer.Memory.Span.Clear();
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ByteMemoryPoolBuffer RentImpl(int length)
|
||||||
|
{
|
||||||
|
if ((uint)length > Array.MaxLength)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(length), length, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ByteMemoryPoolBuffer(length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -33,6 +33,11 @@ namespace Ryujinx.Common.Memory
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReadOnlySpan<byte> GetSpanSafe(int size)
|
||||||
|
{
|
||||||
|
return GetSpan((int)Math.Min((uint)_input.Length, (uint)size));
|
||||||
|
}
|
||||||
|
|
||||||
public T ReadAt<T>(int offset) where T : unmanaged
|
public T ReadAt<T>(int offset) where T : unmanaged
|
||||||
{
|
{
|
||||||
return MemoryMarshal.Cast<byte, T>(_input.Slice(offset))[0];
|
return MemoryMarshal.Cast<byte, T>(_input.Slice(offset))[0];
|
||||||
|
@@ -48,6 +48,8 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
public readonly float MaximumSupportedAnisotropy;
|
public readonly float MaximumSupportedAnisotropy;
|
||||||
public readonly int StorageBufferOffsetAlignment;
|
public readonly int StorageBufferOffsetAlignment;
|
||||||
|
|
||||||
|
public readonly int GatherBiasPrecision;
|
||||||
|
|
||||||
public Capabilities(
|
public Capabilities(
|
||||||
TargetApi api,
|
TargetApi api,
|
||||||
string vendorName,
|
string vendorName,
|
||||||
@@ -87,7 +89,8 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
uint maximumImagesPerStage,
|
uint maximumImagesPerStage,
|
||||||
int maximumComputeSharedMemorySize,
|
int maximumComputeSharedMemorySize,
|
||||||
float maximumSupportedAnisotropy,
|
float maximumSupportedAnisotropy,
|
||||||
int storageBufferOffsetAlignment)
|
int storageBufferOffsetAlignment,
|
||||||
|
int gatherBiasPrecision)
|
||||||
{
|
{
|
||||||
Api = api;
|
Api = api;
|
||||||
VendorName = vendorName;
|
VendorName = vendorName;
|
||||||
@@ -128,6 +131,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
MaximumComputeSharedMemorySize = maximumComputeSharedMemorySize;
|
MaximumComputeSharedMemorySize = maximumComputeSharedMemorySize;
|
||||||
MaximumSupportedAnisotropy = maximumSupportedAnisotropy;
|
MaximumSupportedAnisotropy = maximumSupportedAnisotropy;
|
||||||
StorageBufferOffsetAlignment = storageBufferOffsetAlignment;
|
StorageBufferOffsetAlignment = storageBufferOffsetAlignment;
|
||||||
|
GatherBiasPrecision = gatherBiasPrecision;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
private const ushort FileFormatVersionMajor = 1;
|
private const ushort FileFormatVersionMajor = 1;
|
||||||
private const ushort FileFormatVersionMinor = 2;
|
private const ushort FileFormatVersionMinor = 2;
|
||||||
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
|
||||||
private const uint CodeGenVersion = 4404;
|
private const uint CodeGenVersion = 4703;
|
||||||
|
|
||||||
private const string SharedTocFileName = "shared.toc";
|
private const string SharedTocFileName = "shared.toc";
|
||||||
private const string SharedDataFileName = "shared.data";
|
private const string SharedDataFileName = "shared.data";
|
||||||
|
@@ -112,6 +112,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int QueryHostGatherBiasPrecision() => _context.Capabilities.GatherBiasPrecision;
|
||||||
|
|
||||||
public bool QueryHostReducedPrecision() => _context.Capabilities.ReduceShaderPrecision;
|
public bool QueryHostReducedPrecision() => _context.Capabilities.ReduceShaderPrecision;
|
||||||
|
|
||||||
public bool QueryHostHasFrontFacingBug() => _context.Capabilities.HasFrontFacingBug;
|
public bool QueryHostHasFrontFacingBug() => _context.Capabilities.HasFrontFacingBug;
|
||||||
|
@@ -103,11 +103,14 @@ namespace Ryujinx.Graphics.OpenGL
|
|||||||
|
|
||||||
public Capabilities GetCapabilities()
|
public Capabilities GetCapabilities()
|
||||||
{
|
{
|
||||||
|
bool intelWindows = HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows;
|
||||||
|
bool amdWindows = HwCapabilities.Vendor == HwCapabilities.GpuVendor.AmdWindows;
|
||||||
|
|
||||||
return new Capabilities(
|
return new Capabilities(
|
||||||
api: TargetApi.OpenGL,
|
api: TargetApi.OpenGL,
|
||||||
vendorName: GpuVendor,
|
vendorName: GpuVendor,
|
||||||
hasFrontFacingBug: HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows,
|
hasFrontFacingBug: intelWindows,
|
||||||
hasVectorIndexingBug: HwCapabilities.Vendor == HwCapabilities.GpuVendor.AmdWindows,
|
hasVectorIndexingBug: amdWindows,
|
||||||
needsFragmentOutputSpecialization: false,
|
needsFragmentOutputSpecialization: false,
|
||||||
reduceShaderPrecision: false,
|
reduceShaderPrecision: false,
|
||||||
supportsAstcCompression: HwCapabilities.SupportsAstcCompression,
|
supportsAstcCompression: HwCapabilities.SupportsAstcCompression,
|
||||||
@@ -142,7 +145,8 @@ namespace Ryujinx.Graphics.OpenGL
|
|||||||
maximumImagesPerStage: 8,
|
maximumImagesPerStage: 8,
|
||||||
maximumComputeSharedMemorySize: HwCapabilities.MaximumComputeSharedMemorySize,
|
maximumComputeSharedMemorySize: HwCapabilities.MaximumComputeSharedMemorySize,
|
||||||
maximumSupportedAnisotropy: HwCapabilities.MaximumSupportedAnisotropy,
|
maximumSupportedAnisotropy: HwCapabilities.MaximumSupportedAnisotropy,
|
||||||
storageBufferOffsetAlignment: HwCapabilities.StorageBufferOffsetAlignment);
|
storageBufferOffsetAlignment: HwCapabilities.StorageBufferOffsetAlignment,
|
||||||
|
gatherBiasPrecision: intelWindows || amdWindows ? 8 : 0); // Precision is 8 for these vendors on Vulkan.
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetBufferData(BufferHandle buffer, int offset, ReadOnlySpan<byte> data)
|
public void SetBufferData(BufferHandle buffer, int offset, ReadOnlySpan<byte> data)
|
||||||
|
@@ -677,7 +677,28 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
|||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
Append(ApplyScaling(AssemblePVector(pCount)));
|
string ApplyBias(string vector)
|
||||||
|
{
|
||||||
|
int gatherBiasPrecision = context.Config.GpuAccessor.QueryHostGatherBiasPrecision();
|
||||||
|
if (isGather && gatherBiasPrecision != 0)
|
||||||
|
{
|
||||||
|
// GPU requires texture gather to be slightly offset to match NVIDIA behaviour when point is exactly between two texels.
|
||||||
|
// Offset by the gather precision divided by 2 to correct for rounding.
|
||||||
|
|
||||||
|
if (pCount == 1)
|
||||||
|
{
|
||||||
|
vector = $"{vector} + (1.0 / (float(textureSize({samplerName}, 0)) * float({1 << (gatherBiasPrecision + 1)})))";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vector = $"{vector} + (1.0 / (vec{pCount}(textureSize({samplerName}, 0).{"xyz".Substring(0, pCount)}) * float({1 << (gatherBiasPrecision + 1)})))";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
Append(ApplyBias(ApplyScaling(AssemblePVector(pCount))));
|
||||||
|
|
||||||
string AssembleDerivativesVector(int count)
|
string AssembleDerivativesVector(int count)
|
||||||
{
|
{
|
||||||
|
@@ -4,6 +4,7 @@ using Ryujinx.Graphics.Shader.Translation;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using static Spv.Specification;
|
using static Spv.Specification;
|
||||||
|
|
||||||
@@ -1556,6 +1557,33 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpvInstruction ApplyBias(SpvInstruction vector, SpvInstruction image)
|
||||||
|
{
|
||||||
|
int gatherBiasPrecision = context.Config.GpuAccessor.QueryHostGatherBiasPrecision();
|
||||||
|
if (isGather && gatherBiasPrecision != 0)
|
||||||
|
{
|
||||||
|
// GPU requires texture gather to be slightly offset to match NVIDIA behaviour when point is exactly between two texels.
|
||||||
|
// Offset by the gather precision divided by 2 to correct for rounding.
|
||||||
|
var sizeType = pCount == 1 ? context.TypeS32() : context.TypeVector(context.TypeS32(), pCount);
|
||||||
|
var pVectorType = pCount == 1 ? context.TypeFP32() : context.TypeVector(context.TypeFP32(), pCount);
|
||||||
|
|
||||||
|
var bias = context.Constant(context.TypeFP32(), (float)(1 << (gatherBiasPrecision + 1)));
|
||||||
|
var biasVector = context.CompositeConstruct(pVectorType, Enumerable.Repeat(bias, pCount).ToArray());
|
||||||
|
|
||||||
|
var one = context.Constant(context.TypeFP32(), 1f);
|
||||||
|
var oneVector = context.CompositeConstruct(pVectorType, Enumerable.Repeat(one, pCount).ToArray());
|
||||||
|
|
||||||
|
var divisor = context.FMul(
|
||||||
|
pVectorType,
|
||||||
|
context.ConvertSToF(pVectorType, context.ImageQuerySize(sizeType, image)),
|
||||||
|
biasVector);
|
||||||
|
|
||||||
|
vector = context.FAdd(pVectorType, vector, context.FDiv(pVectorType, oneVector, divisor));
|
||||||
|
}
|
||||||
|
|
||||||
|
return vector;
|
||||||
|
}
|
||||||
|
|
||||||
SpvInstruction pCoords = AssemblePVector(pCount);
|
SpvInstruction pCoords = AssemblePVector(pCount);
|
||||||
pCoords = ScalingHelpers.ApplyScaling(context, texOp, pCoords, intCoords, isBindless, isIndexed, isArray, pCount);
|
pCoords = ScalingHelpers.ApplyScaling(context, texOp, pCoords, intCoords, isBindless, isIndexed, isArray, pCount);
|
||||||
|
|
||||||
@@ -1716,6 +1744,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||||||
image = context.Image(imageType, image);
|
image = context.Image(imageType, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pCoords = ApplyBias(pCoords, image);
|
||||||
|
|
||||||
var operands = operandsList.ToArray();
|
var operands = operandsList.ToArray();
|
||||||
|
|
||||||
SpvInstruction result;
|
SpvInstruction result;
|
||||||
|
@@ -196,6 +196,15 @@ namespace Ryujinx.Graphics.Shader
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queries host's gather operation precision bits for biasing their coordinates. Zero means no bias.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Bits of gather operation precision to use for coordinate bias</returns>
|
||||||
|
int QueryHostGatherBiasPrecision()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Queries host about whether to reduce precision to improve performance.
|
/// Queries host about whether to reduce precision to improve performance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -46,6 +46,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
public readonly SampleCountFlags SupportedSampleCounts;
|
public readonly SampleCountFlags SupportedSampleCounts;
|
||||||
public readonly PortabilitySubsetFlags PortabilitySubset;
|
public readonly PortabilitySubsetFlags PortabilitySubset;
|
||||||
public readonly uint VertexBufferAlignment;
|
public readonly uint VertexBufferAlignment;
|
||||||
|
public readonly uint SubTexelPrecisionBits;
|
||||||
|
|
||||||
public HardwareCapabilities(
|
public HardwareCapabilities(
|
||||||
bool supportsIndexTypeUint8,
|
bool supportsIndexTypeUint8,
|
||||||
@@ -77,7 +78,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ShaderStageFlags requiredSubgroupSizeStages,
|
ShaderStageFlags requiredSubgroupSizeStages,
|
||||||
SampleCountFlags supportedSampleCounts,
|
SampleCountFlags supportedSampleCounts,
|
||||||
PortabilitySubsetFlags portabilitySubset,
|
PortabilitySubsetFlags portabilitySubset,
|
||||||
uint vertexBufferAlignment)
|
uint vertexBufferAlignment,
|
||||||
|
uint subTexelPrecisionBits)
|
||||||
{
|
{
|
||||||
SupportsIndexTypeUint8 = supportsIndexTypeUint8;
|
SupportsIndexTypeUint8 = supportsIndexTypeUint8;
|
||||||
SupportsCustomBorderColor = supportsCustomBorderColor;
|
SupportsCustomBorderColor = supportsCustomBorderColor;
|
||||||
@@ -109,6 +111,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
SupportedSampleCounts = supportedSampleCounts;
|
SupportedSampleCounts = supportedSampleCounts;
|
||||||
PortabilitySubset = portabilitySubset;
|
PortabilitySubset = portabilitySubset;
|
||||||
VertexBufferAlignment = vertexBufferAlignment;
|
VertexBufferAlignment = vertexBufferAlignment;
|
||||||
|
SubTexelPrecisionBits = subTexelPrecisionBits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -311,7 +311,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
propertiesSubgroupSizeControl.RequiredSubgroupSizeStages,
|
propertiesSubgroupSizeControl.RequiredSubgroupSizeStages,
|
||||||
supportedSampleCounts,
|
supportedSampleCounts,
|
||||||
portabilityFlags,
|
portabilityFlags,
|
||||||
vertexBufferAlignment);
|
vertexBufferAlignment,
|
||||||
|
properties.Limits.SubTexelPrecisionBits);
|
||||||
|
|
||||||
IsSharedMemory = MemoryAllocator.IsDeviceMemoryShared(_physicalDevice);
|
IsSharedMemory = MemoryAllocator.IsDeviceMemoryShared(_physicalDevice);
|
||||||
|
|
||||||
@@ -576,7 +577,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
maximumImagesPerStage: Constants.MaxImagesPerStage,
|
maximumImagesPerStage: Constants.MaxImagesPerStage,
|
||||||
maximumComputeSharedMemorySize: (int)limits.MaxComputeSharedMemorySize,
|
maximumComputeSharedMemorySize: (int)limits.MaxComputeSharedMemorySize,
|
||||||
maximumSupportedAnisotropy: (int)limits.MaxSamplerAnisotropy,
|
maximumSupportedAnisotropy: (int)limits.MaxSamplerAnisotropy,
|
||||||
storageBufferOffsetAlignment: (int)limits.MinStorageBufferOffsetAlignment);
|
storageBufferOffsetAlignment: (int)limits.MinStorageBufferOffsetAlignment,
|
||||||
|
gatherBiasPrecision: IsIntelWindows || IsAmdWindows ? (int)Capabilities.SubTexelPrecisionBits : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HardwareInfo GetHardwareInfo()
|
public HardwareInfo GetHardwareInfo()
|
||||||
|
@@ -27,27 +27,21 @@ namespace Ryujinx.HLE.HOS.Ipc
|
|||||||
|
|
||||||
public IpcMessage()
|
public IpcMessage()
|
||||||
{
|
{
|
||||||
PtrBuff = new List<IpcPtrBuffDesc>();
|
PtrBuff = new List<IpcPtrBuffDesc>(0);
|
||||||
SendBuff = new List<IpcBuffDesc>();
|
SendBuff = new List<IpcBuffDesc>(0);
|
||||||
ReceiveBuff = new List<IpcBuffDesc>();
|
ReceiveBuff = new List<IpcBuffDesc>(0);
|
||||||
ExchangeBuff = new List<IpcBuffDesc>();
|
ExchangeBuff = new List<IpcBuffDesc>(0);
|
||||||
RecvListBuff = new List<IpcRecvListBuffDesc>();
|
RecvListBuff = new List<IpcRecvListBuffDesc>(0);
|
||||||
|
|
||||||
ObjectIds = new List<int>();
|
ObjectIds = new List<int>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IpcMessage(ReadOnlySpan<byte> data, long cmdPtr) : this()
|
public IpcMessage(ReadOnlySpan<byte> data, long cmdPtr)
|
||||||
{
|
{
|
||||||
using (RecyclableMemoryStream ms = MemoryStreamManager.Shared.GetStream(data))
|
using (RecyclableMemoryStream ms = MemoryStreamManager.Shared.GetStream(data))
|
||||||
{
|
{
|
||||||
BinaryReader reader = new BinaryReader(ms);
|
BinaryReader reader = new BinaryReader(ms);
|
||||||
|
|
||||||
Initialize(reader, cmdPtr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Initialize(BinaryReader reader, long cmdPtr)
|
|
||||||
{
|
|
||||||
int word0 = reader.ReadInt32();
|
int word0 = reader.ReadInt32();
|
||||||
int word1 = reader.ReadInt32();
|
int word1 = reader.ReadInt32();
|
||||||
|
|
||||||
@@ -67,22 +61,28 @@ namespace Ryujinx.HLE.HOS.Ipc
|
|||||||
HandleDesc = new IpcHandleDesc(reader);
|
HandleDesc = new IpcHandleDesc(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PtrBuff = new List<IpcPtrBuffDesc>(ptrBuffCount);
|
||||||
|
|
||||||
for (int index = 0; index < ptrBuffCount; index++)
|
for (int index = 0; index < ptrBuffCount; index++)
|
||||||
{
|
{
|
||||||
PtrBuff.Add(new IpcPtrBuffDesc(reader));
|
PtrBuff.Add(new IpcPtrBuffDesc(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadBuff(List<IpcBuffDesc> buff, int count)
|
static List<IpcBuffDesc> ReadBuff(BinaryReader reader, int count)
|
||||||
{
|
{
|
||||||
|
List<IpcBuffDesc> buff = new List<IpcBuffDesc>(count);
|
||||||
|
|
||||||
for (int index = 0; index < count; index++)
|
for (int index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
buff.Add(new IpcBuffDesc(reader));
|
buff.Add(new IpcBuffDesc(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadBuff(SendBuff, sendBuffCount);
|
SendBuff = ReadBuff(reader, sendBuffCount);
|
||||||
ReadBuff(ReceiveBuff, recvBuffCount);
|
ReceiveBuff = ReadBuff(reader, recvBuffCount);
|
||||||
ReadBuff(ExchangeBuff, xchgBuffCount);
|
ExchangeBuff = ReadBuff(reader, xchgBuffCount);
|
||||||
|
|
||||||
rawDataSize *= 4;
|
rawDataSize *= 4;
|
||||||
|
|
||||||
@@ -116,10 +116,15 @@ namespace Ryujinx.HLE.HOS.Ipc
|
|||||||
|
|
||||||
reader.BaseStream.Seek(recvListPos, SeekOrigin.Begin);
|
reader.BaseStream.Seek(recvListPos, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
RecvListBuff = new List<IpcRecvListBuffDesc>(recvListCount);
|
||||||
|
|
||||||
for (int index = 0; index < recvListCount; index++)
|
for (int index = 0; index < recvListCount; index++)
|
||||||
{
|
{
|
||||||
RecvListBuff.Add(new IpcRecvListBuffDesc(reader.ReadUInt64()));
|
RecvListBuff.Add(new IpcRecvListBuffDesc(reader.ReadUInt64()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObjectIds = new List<int>(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public RecyclableMemoryStream GetStream(long cmdPtr, ulong recvListAddr)
|
public RecyclableMemoryStream GetStream(long cmdPtr, ulong recvListAddr)
|
||||||
|
@@ -71,7 +71,13 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
|
|||||||
{
|
{
|
||||||
lock (_context.CriticalSection.Lock)
|
lock (_context.CriticalSection.Lock)
|
||||||
{
|
{
|
||||||
_waitingObjects.RemoveAll(x => x.Object == schedulerObj);
|
for (int index = _waitingObjects.Count - 1; index >= 0; index--)
|
||||||
|
{
|
||||||
|
if (_waitingObjects[index].Object == schedulerObj)
|
||||||
|
{
|
||||||
|
_waitingObjects.RemoveAt(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,17 +111,20 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (Interlocked.Read(ref _enforceWakeupFromSpinWait) != 1 && PerformanceCounter.ElapsedTicks <= next.TimePoint)
|
while (Interlocked.Read(ref _enforceWakeupFromSpinWait) != 1 && PerformanceCounter.ElapsedTicks < next.TimePoint)
|
||||||
{
|
{
|
||||||
|
// Our time is close - don't let SpinWait go off and potentially Thread.Sleep().
|
||||||
if (spinWait.NextSpinWillYield)
|
if (spinWait.NextSpinWillYield)
|
||||||
{
|
{
|
||||||
Thread.Yield();
|
Thread.Yield();
|
||||||
|
|
||||||
spinWait.Reset();
|
spinWait.Reset();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
spinWait.SpinOnce();
|
spinWait.SpinOnce();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
spinWait.Reset();
|
spinWait.Reset();
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,7 @@ using Ryujinx.HLE.HOS.Kernel.Process;
|
|||||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||||
using Ryujinx.Horizon.Common;
|
using Ryujinx.Horizon.Common;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||||
@@ -553,7 +554,9 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||||||
|
|
||||||
KProcess currentProcess = KernelStatic.GetCurrentProcess();
|
KProcess currentProcess = KernelStatic.GetCurrentProcess();
|
||||||
|
|
||||||
KSynchronizationObject[] syncObjs = handles.Length == 0 ? Array.Empty<KSynchronizationObject>() : new KSynchronizationObject[handles.Length];
|
KSynchronizationObject[] syncObjsArray = ArrayPool<KSynchronizationObject>.Shared.Rent(handles.Length);
|
||||||
|
|
||||||
|
Span<KSynchronizationObject> syncObjs = syncObjsArray.AsSpan(0, handles.Length);
|
||||||
|
|
||||||
for (int index = 0; index < handles.Length; index++)
|
for (int index = 0; index < handles.Length; index++)
|
||||||
{
|
{
|
||||||
@@ -606,6 +609,8 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArrayPool<KSynchronizationObject>.Shared.Return(syncObjsArray);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
using Ryujinx.HLE.HOS.Kernel.Common;
|
using Ryujinx.HLE.HOS.Kernel.Common;
|
||||||
using Ryujinx.Horizon.Common;
|
using Ryujinx.Horizon.Common;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Kernel.Threading
|
namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||||
@@ -59,7 +60,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LinkedListNode<KThread>[] syncNodes = syncObjs.Length == 0 ? Array.Empty<LinkedListNode<KThread>>() : new LinkedListNode<KThread>[syncObjs.Length];
|
LinkedListNode<KThread>[] syncNodesArray = ArrayPool<LinkedListNode<KThread>>.Shared.Rent(syncObjs.Length);
|
||||||
|
|
||||||
|
Span<LinkedListNode<KThread>> syncNodes = syncNodesArray.AsSpan(0, syncObjs.Length);
|
||||||
|
|
||||||
for (int index = 0; index < syncObjs.Length; index++)
|
for (int index = 0; index < syncObjs.Length; index++)
|
||||||
{
|
{
|
||||||
@@ -101,6 +104,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
|||||||
handleIndex = index;
|
handleIndex = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArrayPool<LinkedListNode<KThread>>.Shared.Return(syncNodesArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
_context.CriticalSection.Leave();
|
_context.CriticalSection.Leave();
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.HLE.HOS.Ipc;
|
using Ryujinx.HLE.HOS.Ipc;
|
||||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||||
using Ryujinx.Horizon.Common;
|
using Ryujinx.Horizon.Common;
|
||||||
@@ -68,8 +69,11 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer
|
|||||||
|
|
||||||
ReadOnlyMemory<byte> input = context.Memory.GetSpan(inputPosition, (int)inputSize).ToArray();
|
ReadOnlyMemory<byte> input = context.Memory.GetSpan(inputPosition, (int)inputSize).ToArray();
|
||||||
|
|
||||||
Memory<byte> output = new byte[outputSize];
|
using (IMemoryOwner<byte> outputOwner = ByteMemoryPool.Shared.RentCleared(outputSize))
|
||||||
Memory<byte> performanceOutput = new byte[performanceOutputSize];
|
using (IMemoryOwner<byte> performanceOutputOwner = ByteMemoryPool.Shared.RentCleared(performanceOutputSize))
|
||||||
|
{
|
||||||
|
Memory<byte> output = outputOwner.Memory;
|
||||||
|
Memory<byte> performanceOutput = performanceOutputOwner.Memory;
|
||||||
|
|
||||||
using MemoryHandle outputHandle = output.Pin();
|
using MemoryHandle outputHandle = output.Pin();
|
||||||
using MemoryHandle performanceOutputHandle = performanceOutput.Pin();
|
using MemoryHandle performanceOutputHandle = performanceOutput.Pin();
|
||||||
@@ -88,6 +92,7 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[CommandCmif(5)]
|
[CommandCmif(5)]
|
||||||
// Start()
|
// Start()
|
||||||
|
@@ -76,6 +76,8 @@ namespace Ryujinx.HLE.HOS.Services
|
|||||||
|
|
||||||
context.RequestData.BaseStream.Seek(0x10 + dataPayloadSize, SeekOrigin.Begin);
|
context.RequestData.BaseStream.Seek(0x10 + dataPayloadSize, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
context.Request.ObjectIds.EnsureCapacity(inputObjCount);
|
||||||
|
|
||||||
for (int index = 0; index < inputObjCount; index++)
|
for (int index = 0; index < inputObjCount; index++)
|
||||||
{
|
{
|
||||||
context.Request.ObjectIds.Add(context.RequestData.ReadInt32());
|
context.Request.ObjectIds.Add(context.RequestData.ReadInt32());
|
||||||
|
@@ -217,6 +217,8 @@ namespace Ryujinx.HLE.HOS.Services
|
|||||||
|
|
||||||
if (noReceive)
|
if (noReceive)
|
||||||
{
|
{
|
||||||
|
response.PtrBuff.EnsureCapacity(request.RecvListBuff.Count);
|
||||||
|
|
||||||
for (int i = 0; i < request.RecvListBuff.Count; i++)
|
for (int i = 0; i < request.RecvListBuff.Count; i++)
|
||||||
{
|
{
|
||||||
ulong size = (ulong)BinaryPrimitives.ReadInt16LittleEndian(request.RawData.AsSpan(sizesOffset + i * 2, 2));
|
ulong size = (ulong)BinaryPrimitives.ReadInt16LittleEndian(request.RawData.AsSpan(sizesOffset + i * 2, 2));
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
using Ryujinx.HLE.HOS.Ipc;
|
using Ryujinx.Common.Memory;
|
||||||
|
using Ryujinx.HLE.HOS.Ipc;
|
||||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||||
using Ryujinx.Horizon.Common;
|
using Ryujinx.Horizon.Common;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||||
{
|
{
|
||||||
@@ -83,7 +85,9 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||||||
|
|
||||||
ReadOnlySpan<byte> inputParcel = context.Memory.GetSpan(dataPos, (int)dataSize);
|
ReadOnlySpan<byte> inputParcel = context.Memory.GetSpan(dataPos, (int)dataSize);
|
||||||
|
|
||||||
Span<byte> outputParcel = new Span<byte>(new byte[replySize]);
|
using (IMemoryOwner<byte> outputParcelOwner = ByteMemoryPool.Shared.RentCleared(replySize))
|
||||||
|
{
|
||||||
|
Span<byte> outputParcel = outputParcelOwner.Memory.Span;
|
||||||
|
|
||||||
ResultCode result = OnTransact(binderId, code, flags, inputParcel, outputParcel);
|
ResultCode result = OnTransact(binderId, code, flags, inputParcel, outputParcel);
|
||||||
|
|
||||||
@@ -94,6 +98,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract ResultCode AdjustRefcount(int binderId, int addVal, int type);
|
protected abstract ResultCode AdjustRefcount(int binderId, int addVal, int type);
|
||||||
|
|
||||||
|
@@ -113,7 +113,7 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
|||||||
}
|
}
|
||||||
else if (key == LogDataChunkKey.Message)
|
else if (key == LogDataChunkKey.Message)
|
||||||
{
|
{
|
||||||
string text = Encoding.UTF8.GetString(reader.GetSpan(size)).TrimEnd();
|
string text = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
||||||
|
|
||||||
if (isHeadPacket && isTailPacket)
|
if (isHeadPacket && isTailPacket)
|
||||||
{
|
{
|
||||||
@@ -131,23 +131,23 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
|||||||
}
|
}
|
||||||
else if (key == LogDataChunkKey.Filename)
|
else if (key == LogDataChunkKey.Filename)
|
||||||
{
|
{
|
||||||
_logPacket.Filename = Encoding.UTF8.GetString(reader.GetSpan(size)).TrimEnd();
|
_logPacket.Filename = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
||||||
}
|
}
|
||||||
else if (key == LogDataChunkKey.Function)
|
else if (key == LogDataChunkKey.Function)
|
||||||
{
|
{
|
||||||
_logPacket.Function = Encoding.UTF8.GetString(reader.GetSpan(size)).TrimEnd();
|
_logPacket.Function = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
||||||
}
|
}
|
||||||
else if (key == LogDataChunkKey.Module)
|
else if (key == LogDataChunkKey.Module)
|
||||||
{
|
{
|
||||||
_logPacket.Module = Encoding.UTF8.GetString(reader.GetSpan(size)).TrimEnd();
|
_logPacket.Module = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
||||||
}
|
}
|
||||||
else if (key == LogDataChunkKey.Thread)
|
else if (key == LogDataChunkKey.Thread)
|
||||||
{
|
{
|
||||||
_logPacket.Thread = Encoding.UTF8.GetString(reader.GetSpan(size)).TrimEnd();
|
_logPacket.Thread = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
||||||
}
|
}
|
||||||
else if (key == LogDataChunkKey.ProgramName)
|
else if (key == LogDataChunkKey.ProgramName)
|
||||||
{
|
{
|
||||||
_logPacket.ProgramName = Encoding.UTF8.GetString(reader.GetSpan(size)).TrimEnd();
|
_logPacket.ProgramName = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -12,17 +12,7 @@ namespace Ryujinx.Input.SDL2
|
|||||||
{
|
{
|
||||||
private bool HasConfiguration => _configuration != null;
|
private bool HasConfiguration => _configuration != null;
|
||||||
|
|
||||||
private class ButtonMappingEntry
|
private record struct ButtonMappingEntry(GamepadButtonInputId To, GamepadButtonInputId From);
|
||||||
{
|
|
||||||
public readonly GamepadButtonInputId To;
|
|
||||||
public readonly GamepadButtonInputId From;
|
|
||||||
|
|
||||||
public ButtonMappingEntry(GamepadButtonInputId to, GamepadButtonInputId from)
|
|
||||||
{
|
|
||||||
To = to;
|
|
||||||
From = from;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private StandardControllerInputConfig _configuration;
|
private StandardControllerInputConfig _configuration;
|
||||||
|
|
||||||
@@ -85,7 +75,7 @@ namespace Ryujinx.Input.SDL2
|
|||||||
public SDL2Gamepad(IntPtr gamepadHandle, string driverId)
|
public SDL2Gamepad(IntPtr gamepadHandle, string driverId)
|
||||||
{
|
{
|
||||||
_gamepadHandle = gamepadHandle;
|
_gamepadHandle = gamepadHandle;
|
||||||
_buttonsUserMapping = new List<ButtonMappingEntry>();
|
_buttonsUserMapping = new List<ButtonMappingEntry>(20);
|
||||||
|
|
||||||
Name = SDL_GameControllerName(_gamepadHandle);
|
Name = SDL_GameControllerName(_gamepadHandle);
|
||||||
Id = driverId;
|
Id = driverId;
|
||||||
|
@@ -12,7 +12,6 @@ namespace Ryujinx.Input
|
|||||||
public Vector3 Rotation { get; set; }
|
public Vector3 Rotation { get; set; }
|
||||||
|
|
||||||
private readonly MotionSensorFilter _filter;
|
private readonly MotionSensorFilter _filter;
|
||||||
private int _calibrationFrame = 0;
|
|
||||||
|
|
||||||
public MotionInput()
|
public MotionInput()
|
||||||
{
|
{
|
||||||
@@ -29,26 +28,6 @@ namespace Ryujinx.Input
|
|||||||
{
|
{
|
||||||
if (TimeStamp != 0)
|
if (TimeStamp != 0)
|
||||||
{
|
{
|
||||||
if (gyro.Length() <= 1f && accel.Length() >= 0.8f && accel.Z >= 0.8f)
|
|
||||||
{
|
|
||||||
_calibrationFrame++;
|
|
||||||
|
|
||||||
if (_calibrationFrame >= 90)
|
|
||||||
{
|
|
||||||
gyro = Vector3.Zero;
|
|
||||||
|
|
||||||
Rotation = Vector3.Zero;
|
|
||||||
|
|
||||||
_filter.Reset();
|
|
||||||
|
|
||||||
_calibrationFrame = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_calibrationFrame = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Accelerometer = -accel;
|
Accelerometer = -accel;
|
||||||
|
|
||||||
if (gyro.Length() < deadzone)
|
if (gyro.Length() < deadzone)
|
||||||
|
Reference in New Issue
Block a user