Compare commits

..

7 Commits

Author SHA1 Message Date
gdkchan
7bfb5f79b8 When copying linear textures, DMA should ignore region X/Y (#3121) 2022-02-16 11:13:45 +01:00
skrek
8cc2479825 Adjusting how deadzones are calculated (#3079)
* Making deadzones feel nice and smooth + adding rider files to .gitignore

* removing unnecessary parentheses and fixing possibility of divide by 0

* formatting :)

* fixing up ClampAxis

* fixing up ClampAxis
2022-02-16 11:06:52 +01:00
Berkan Diler
8f35345729 Use Enum and Delegate.CreateDelegate generic overloads (#3111)
* Use Enum generic overloads

* Remove EnumExtensions.cs

* Use Delegate.CreateDelegate generic overloads
2022-02-13 10:50:07 -03:00
merry
ce71f9144e InstEmitMemory32: Literal loads always have word-aligned PC (#3104) 2022-02-11 17:51:03 -03:00
gdkchan
f861f0bca2 Fix missing geometry shader passthrough inputs (#3106)
* Fix missing geometry shader passthrough inputs

* Shader cache version bump
2022-02-11 19:52:20 +01:00
edisionnano
571496d243 Ship SoundIO library only for the specified runtime (#3103)
* Add RuntimeIdentifers properties

For Linux, Windows and OS X x86-64
This ensures that the SoundIO project gets this property when built as a subproject

* Address gdkchan's nit

Merge tags into one
2022-02-11 00:15:13 +01:00
gdkchan
c3c3914ed3 Add a limit on the number of uses a constant may have (#3097) 2022-02-09 17:42:47 -03:00
23 changed files with 76 additions and 49 deletions

3
.gitignore vendored
View File

@@ -74,6 +74,9 @@ _TeamCity*
# DotCover is a Code Coverage Tool # DotCover is a Code Coverage Tool
*.dotCover *.dotCover
# Rider is a Visual Studio alternative
.idea/*
# NCrunch # NCrunch
*.ncrunch* *.ncrunch*
.*crunch*.local.xml .*crunch*.local.xml

View File

@@ -9,13 +9,17 @@ namespace ARMeilleure.CodeGen.X86
{ {
static class X86Optimizer static class X86Optimizer
{ {
private const int MaxConstantUses = 10000;
public static void RunPass(ControlFlowGraph cfg) public static void RunPass(ControlFlowGraph cfg)
{ {
var constants = new Dictionary<ulong, Operand>(); var constants = new Dictionary<ulong, Operand>();
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source) Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
{ {
if (!constants.TryGetValue(source.Value, out var constant)) // If the constant has many uses, we also force a new constant mov to be added, in order
// to avoid overflow of the counts field (that is limited to 16 bits).
if (!constants.TryGetValue(source.Value, out var constant) || constant.UsesCount > MaxConstantUses)
{ {
constant = Local(source.Type); constant = Local(source.Type);
@@ -23,7 +27,7 @@ namespace ARMeilleure.CodeGen.X86
block.Operations.AddBefore(operation, copyOp); block.Operations.AddBefore(operation, copyOp);
constants.Add(source.Value, constant); constants[source.Value] = constant;
} }
return constant; return constant;

View File

@@ -47,6 +47,20 @@ namespace ARMeilleure.Instructions
} }
} }
public static Operand GetIntA32AlignedPC(ArmEmitterContext context, int regIndex)
{
if (regIndex == RegisterAlias.Aarch32Pc)
{
OpCode32 op = (OpCode32)context.CurrOp;
return Const((int)(op.GetPc() & 0xfffffffc));
}
else
{
return Register(GetRegisterAlias(context.Mode, regIndex), RegisterType.Integer, OperandType.I32);
}
}
public static Operand GetVecA32(int regIndex) public static Operand GetVecA32(int regIndex)
{ {
return Register(regIndex, RegisterType.Vector, OperandType.V128); return Register(regIndex, RegisterType.Vector, OperandType.V128);

View File

@@ -153,7 +153,7 @@ namespace ARMeilleure.Instructions
{ {
OpCode32Mem op = (OpCode32Mem)context.CurrOp; OpCode32Mem op = (OpCode32Mem)context.CurrOp;
Operand n = context.Copy(GetIntA32(context, op.Rn)); Operand n = context.Copy(GetIntA32AlignedPC(context, op.Rn));
Operand m = GetMemM(context, setCarry: false); Operand m = GetMemM(context, setCarry: false);
Operand temp = default; Operand temp = default;

View File

@@ -3,6 +3,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@@ -1,12 +0,0 @@
using System;
namespace Ryujinx.Common
{
public static class EnumExtensions
{
public static T[] GetValues<T>()
{
return (T[])Enum.GetValues(typeof(T));
}
}
}

View File

@@ -94,7 +94,7 @@ namespace Ryujinx.Common.Logging
static Logger() static Logger()
{ {
m_EnabledClasses = new bool[Enum.GetNames(typeof(LogClass)).Length]; m_EnabledClasses = new bool[Enum.GetNames<LogClass>().Length];
for (int index = 0; index < m_EnabledClasses.Length; index++) for (int index = 0; index < m_EnabledClasses.Length; index++)
{ {

View File

@@ -85,9 +85,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
} }
int alignWidth = Constants.StrideAlignment / bpp; int alignWidth = Constants.StrideAlignment / bpp;
return tex.RegionX == 0 && return stride / bpp == BitUtils.AlignUp(xCount, alignWidth);
tex.RegionY == 0 &&
stride / bpp == BitUtils.AlignUp(xCount, alignWidth);
} }
else else
{ {
@@ -161,6 +159,20 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
var dst = Unsafe.As<uint, DmaTexture>(ref _state.State.SetDstBlockSize); var dst = Unsafe.As<uint, DmaTexture>(ref _state.State.SetDstBlockSize);
var src = Unsafe.As<uint, DmaTexture>(ref _state.State.SetSrcBlockSize); var src = Unsafe.As<uint, DmaTexture>(ref _state.State.SetSrcBlockSize);
int srcRegionX = 0, srcRegionY = 0, dstRegionX = 0, dstRegionY = 0;
if (!srcLinear)
{
srcRegionX = src.RegionX;
srcRegionY = src.RegionY;
}
if (!dstLinear)
{
dstRegionX = dst.RegionX;
dstRegionY = dst.RegionY;
}
int srcStride = (int)_state.State.PitchIn; int srcStride = (int)_state.State.PitchIn;
int dstStride = (int)_state.State.PitchOut; int dstStride = (int)_state.State.PitchOut;
@@ -182,8 +194,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
dst.MemoryLayout.UnpackGobBlocksInZ(), dst.MemoryLayout.UnpackGobBlocksInZ(),
dstBpp); dstBpp);
(int srcBaseOffset, int srcSize) = srcCalculator.GetRectangleRange(src.RegionX, src.RegionY, xCount, yCount); (int srcBaseOffset, int srcSize) = srcCalculator.GetRectangleRange(srcRegionX, srcRegionY, xCount, yCount);
(int dstBaseOffset, int dstSize) = dstCalculator.GetRectangleRange(dst.RegionX, dst.RegionY, xCount, yCount); (int dstBaseOffset, int dstSize) = dstCalculator.GetRectangleRange(dstRegionX, dstRegionY, xCount, yCount);
if (srcLinear && srcStride < 0) if (srcLinear && srcStride < 0)
{ {
@@ -272,13 +284,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
for (int y = 0; y < yCount; y++) for (int y = 0; y < yCount; y++)
{ {
srcCalculator.SetY(src.RegionY + y); srcCalculator.SetY(srcRegionY + y);
dstCalculator.SetY(dst.RegionY + y); dstCalculator.SetY(dstRegionY + y);
for (int x = 0; x < xCount; x++) for (int x = 0; x < xCount; x++)
{ {
int srcOffset = srcCalculator.GetOffset(src.RegionX + x); int srcOffset = srcCalculator.GetOffset(srcRegionX + x);
int dstOffset = dstCalculator.GetOffset(dst.RegionX + x); int dstOffset = dstCalculator.GetOffset(dstRegionX + x);
*(T*)(dstBase + dstOffset) = *(T*)(srcBase + srcOffset); *(T*)(dstBase + dstOffset) = *(T*)(srcBase + srcOffset);
} }

View File

@@ -112,7 +112,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
_ilGen.Emit(OpCodes.Ret); _ilGen.Emit(OpCodes.Ret);
} }
return (MacroExecute)_meth.CreateDelegate(typeof(MacroExecute)); return _meth.CreateDelegate<MacroExecute>();
} }
/// <summary> /// <summary>

View File

@@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <summary> /// <summary>
/// Version of the codegen (to be changed when codegen or guest format change). /// Version of the codegen (to be changed when codegen or guest format change).
/// </summary> /// </summary>
private const ulong ShaderCodeGenVersion = 3012; private const ulong ShaderCodeGenVersion = 3106;
// Progress reporting helpers // Progress reporting helpers
private volatile int _shaderCount; private volatile int _shaderCount;

View File

@@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.OpenGL
static FormatTable() static FormatTable()
{ {
int tableSize = Enum.GetNames(typeof(Format)).Length; int tableSize = Enum.GetNames<Format>().Length;
Table = new FormatInfo[tableSize]; Table = new FormatInfo[tableSize];
TableImage = new SizedInternalFormat[tableSize]; TableImage = new SizedInternalFormat[tableSize];

View File

@@ -9,7 +9,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
public Counters() public Counters()
{ {
int count = Enum.GetNames(typeof(CounterType)).Length; int count = Enum.GetNames<CounterType>().Length;
_counterQueues = new CounterQueue[count]; _counterQueues = new CounterQueue[count];
} }

View File

@@ -490,7 +490,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
} }
else else
{ {
int usedAttributes = context.Config.UsedInputAttributes; int usedAttributes = context.Config.UsedInputAttributes | context.Config.PassthroughAttributes;
while (usedAttributes != 0) while (usedAttributes != 0)
{ {
int index = BitOperations.TrailingZeroCount(usedAttributes); int index = BitOperations.TrailingZeroCount(usedAttributes);

View File

@@ -102,7 +102,7 @@ namespace Ryujinx.HLE.FileSystem.Content
_contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>(); _contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>();
_locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>(); _locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
foreach (StorageId storageId in Enum.GetValues(typeof(StorageId))) foreach (StorageId storageId in Enum.GetValues<StorageId>())
{ {
string contentDirectory = null; string contentDirectory = null;
string contentPathString = null; string contentPathString = null;

View File

@@ -433,7 +433,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
generator.Emit(OpCodes.Ret); generator.Emit(OpCodes.Ret);
return (Action<T, ExecutionContext>)method.CreateDelegate(typeof(Action<T, ExecutionContext>)); return method.CreateDelegate<Action<T, ExecutionContext>>();
} }
private static void CheckIfTypeIsSupported(Type type, string svcName) private static void CheckIfTypeIsSupported(Type type, string svcName)

View File

@@ -1021,7 +1021,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
HidVibrationDeviceType vibrationDeviceType = HidVibrationDeviceType.None; HidVibrationDeviceType vibrationDeviceType = HidVibrationDeviceType.None;
if (Enum.IsDefined(typeof(NpadStyleIndex), deviceType)) if (Enum.IsDefined<NpadStyleIndex>(deviceType))
{ {
vibrationDeviceType = HidVibrationDeviceType.LinearResonantActuator; vibrationDeviceType = HidVibrationDeviceType.LinearResonantActuator;
} }

View File

@@ -60,7 +60,7 @@ namespace Ryujinx.HLE.HOS.SystemState
SystemLanguage.TraditionalChinese => TitleLanguage.Taiwanese, SystemLanguage.TraditionalChinese => TitleLanguage.Taiwanese,
SystemLanguage.Chinese or SystemLanguage.Chinese or
SystemLanguage.SimplifiedChinese => TitleLanguage.Chinese, SystemLanguage.SimplifiedChinese => TitleLanguage.Chinese,
_ => Enum.Parse<TitleLanguage>(Enum.GetName(typeof(SystemLanguage), language)), _ => Enum.Parse<TitleLanguage>(Enum.GetName<SystemLanguage>(language)),
}; };
} }

View File

@@ -391,24 +391,29 @@ namespace Ryujinx.Input.HLE
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static JoystickPosition ApplyDeadzone(float x, float y, float deadzone) private static JoystickPosition ApplyDeadzone(float x, float y, float deadzone)
{ {
return new JoystickPosition float magnitudeClamped = Math.Min(MathF.Sqrt(x * x + y * y), 1f);
if (magnitudeClamped <= deadzone)
{ {
Dx = ClampAxis(MathF.Abs(x) > deadzone ? x : 0.0f), return new JoystickPosition() {Dx = 0, Dy = 0};
Dy = ClampAxis(MathF.Abs(y) > deadzone ? y : 0.0f) }
return new JoystickPosition()
{
Dx = ClampAxis((x / magnitudeClamped) * ((magnitudeClamped - deadzone) / (1 - deadzone))),
Dy = ClampAxis((y / magnitudeClamped) * ((magnitudeClamped - deadzone) / (1 - deadzone)))
}; };
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static short ClampAxis(float value) private static short ClampAxis(float value)
{ {
if (value <= -short.MaxValue) if (Math.Sign(value) < 0)
{ {
return -short.MaxValue; return (short)Math.Max(value * -short.MinValue, short.MinValue);
}
else
{
return (short)(value * short.MaxValue);
} }
return (short)Math.Min(value * short.MaxValue, short.MaxValue);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

View File

@@ -27,8 +27,8 @@ namespace Ryujinx.Input.Motion.CemuHook
private readonly Dictionary<int, Dictionary<int, MotionInput>> _motionData; private readonly Dictionary<int, Dictionary<int, MotionInput>> _motionData;
private readonly Dictionary<int, UdpClient> _clients; private readonly Dictionary<int, UdpClient> _clients;
private readonly bool[] _clientErrorStatus = new bool[Enum.GetValues(typeof(PlayerIndex)).Length]; private readonly bool[] _clientErrorStatus = new bool[Enum.GetValues<PlayerIndex>().Length];
private readonly long[] _clientRetryTimer = new long[Enum.GetValues(typeof(PlayerIndex)).Length]; private readonly long[] _clientRetryTimer = new long[Enum.GetValues<PlayerIndex>().Length];
private NpadManager _npadManager; private NpadManager _npadManager;
public Client(NpadManager npadManager) public Client(NpadManager npadManager)

View File

@@ -58,7 +58,7 @@ namespace Ryujinx.Configuration
{ {
bool noFilter = e.NewValue.Length == 0; bool noFilter = e.NewValue.Length == 0;
foreach (var logClass in EnumExtensions.GetValues<LogClass>()) foreach (var logClass in Enum.GetValues<LogClass>())
{ {
Logger.SetEnable(logClass, noFilter); Logger.SetEnable(logClass, noFilter);
} }

View File

@@ -150,7 +150,7 @@ namespace Ryujinx.Input.GTK3
static GTK3MappingHelper() static GTK3MappingHelper()
{ {
var inputKeys = Enum.GetValues(typeof(Key)); var inputKeys = Enum.GetValues<Key>();
// GtkKey is not contiguous and quite large, so use a dictionary instead of an array. // GtkKey is not contiguous and quite large, so use a dictionary instead of an array.
_gtkKeyMapping = new Dictionary<GtkKey, Key>(); _gtkKeyMapping = new Dictionary<GtkKey, Key>();

View File

@@ -1209,7 +1209,7 @@ namespace Ryujinx.Ui
{ {
AspectRatio aspectRatio = ConfigurationState.Instance.Graphics.AspectRatio.Value; AspectRatio aspectRatio = ConfigurationState.Instance.Graphics.AspectRatio.Value;
ConfigurationState.Instance.Graphics.AspectRatio.Value = ((int)aspectRatio + 1) > Enum.GetNames(typeof(AspectRatio)).Length - 1 ? AspectRatio.Fixed4x3 : aspectRatio + 1; ConfigurationState.Instance.Graphics.AspectRatio.Value = ((int)aspectRatio + 1) > Enum.GetNames<AspectRatio>().Length - 1 ? AspectRatio.Fixed4x3 : aspectRatio + 1;
} }
private void Row_Clicked(object sender, ButtonReleaseEventArgs args) private void Row_Clicked(object sender, ButtonReleaseEventArgs args)

View File

@@ -181,7 +181,7 @@ namespace Ryujinx.Ui.Windows
_fsAccessLogToggle.Click(); _fsAccessLogToggle.Click();
} }
foreach (GraphicsDebugLevel level in Enum.GetValues(typeof(GraphicsDebugLevel))) foreach (GraphicsDebugLevel level in Enum.GetValues<GraphicsDebugLevel>())
{ {
_graphicsDebugLevel.Append(level.ToString(), level.ToString()); _graphicsDebugLevel.Append(level.ToString(), level.ToString());
} }