mirror of
https://git.ryujinx.app/kenji-nx/ryujinx.git
synced 2025-12-13 22:37:07 +00:00
misc: chore: Fix numerous NullReferenceExceptions, InvalidOperationExceptions
This commit is contained in:
parent
a90db3464d
commit
d2a532f971
90 changed files with 667 additions and 533 deletions
|
|
@ -59,7 +59,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
|||
|
||||
for (int y = 0; y < context.SampleCount; y++)
|
||||
{
|
||||
context.MemoryManager.Write(targetOffset + (ulong)y * TargetChannelCount, PcmHelper.Saturate(inputBuffer[y]));
|
||||
if (inputBuffer != null)
|
||||
{
|
||||
context.MemoryManager.Write(targetOffset + (ulong)y * TargetChannelCount,
|
||||
PcmHelper.Saturate(inputBuffer[y]));
|
||||
}
|
||||
}
|
||||
|
||||
currentOffset += context.SampleCount * TargetChannelCount;
|
||||
|
|
|
|||
|
|
@ -318,14 +318,17 @@ namespace Ryujinx.Common.Collections
|
|||
{
|
||||
Root = newNode;
|
||||
}
|
||||
else if (start.CompareTo(parent.Start) < 0)
|
||||
else if (parent != null && start.CompareTo(parent.Start) < 0)
|
||||
{
|
||||
parent.Left = newNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parent != null)
|
||||
{
|
||||
parent.Right = newNode;
|
||||
}
|
||||
}
|
||||
|
||||
PropagateIncrease(newNode);
|
||||
Count++;
|
||||
|
|
|
|||
|
|
@ -279,14 +279,17 @@ namespace Ryujinx.Common.Collections
|
|||
{
|
||||
Root = newNode;
|
||||
}
|
||||
else if (key.CompareTo(parent.Key) < 0)
|
||||
else if (parent != null && key.CompareTo(parent.Key) < 0)
|
||||
{
|
||||
parent.Left = newNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parent != null)
|
||||
{
|
||||
parent.Right = newNode;
|
||||
}
|
||||
}
|
||||
Count++;
|
||||
return newNode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ namespace Ryujinx.Common.Configuration
|
|||
{
|
||||
FileSystemInfo resolvedDirectoryInfo =
|
||||
Directory.ResolveLinkTarget(correctApplicationDataDirectoryPath, true);
|
||||
string resolvedPath = resolvedDirectoryInfo.FullName;
|
||||
string resolvedPath = resolvedDirectoryInfo?.FullName;
|
||||
Logger.Error?.Print(LogClass.Application, $"Please manually move your Ryujinx data from {resolvedPath} to {correctApplicationDataDirectoryPath}, and remove the symlink.");
|
||||
}
|
||||
catch (Exception symlinkException)
|
||||
|
|
@ -297,7 +297,7 @@ namespace Ryujinx.Common.Configuration
|
|||
{
|
||||
FileSystemInfo resolvedDirectoryInfo =
|
||||
Directory.ResolveLinkTarget(correctApplicationDataDirectoryPath, true);
|
||||
string resolvedPath = resolvedDirectoryInfo.FullName;
|
||||
string resolvedPath = resolvedDirectoryInfo?.FullName;
|
||||
Logger.Error?.Print(LogClass.Application, $"Please manually move your Ryujinx data from {resolvedPath} to {correctApplicationDataDirectoryPath}, and remove the symlink.");
|
||||
}
|
||||
catch (Exception symlinkException)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
|
|||
{
|
||||
string propertyName = tempReader.GetString();
|
||||
|
||||
if (propertyName.Equals("motion_backend"))
|
||||
if (propertyName is "motion_backend")
|
||||
{
|
||||
tempReader.Read();
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace Ryujinx.Common.Configuration.Hid
|
|||
{
|
||||
string propertyName = tempReader.GetString();
|
||||
|
||||
if (propertyName.Equals("backend"))
|
||||
if (propertyName is "backend")
|
||||
{
|
||||
tempReader.Read();
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Ryujinx.Common.Logging
|
|||
public readonly struct Log
|
||||
{
|
||||
private static readonly string _homeDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
private static readonly string _homeDirRedacted = Path.Combine(Directory.GetParent(_homeDir).FullName, "[redacted]");
|
||||
private static readonly string _homeDirRedacted = Path.Combine(Directory.GetParent(_homeDir)?.FullName ?? string.Empty, "[redacted]");
|
||||
|
||||
internal readonly LogLevel Level;
|
||||
|
||||
|
|
|
|||
|
|
@ -258,6 +258,8 @@ namespace ARMeilleure.Common
|
|||
for (int i = 0; i < Levels.Length - 1; i++)
|
||||
{
|
||||
ref AddressTableLevel level = ref Levels[i];
|
||||
if (page != null)
|
||||
{
|
||||
ref TEntry* nextPage = ref page[level.GetValue(address)];
|
||||
|
||||
if (nextPage == null || nextPage == _fillBottomLevelPtr)
|
||||
|
|
@ -276,6 +278,7 @@ namespace ARMeilleure.Common
|
|||
|
||||
page = (TEntry**)nextPage;
|
||||
}
|
||||
}
|
||||
|
||||
return (TEntry*)page;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -388,9 +388,14 @@ namespace Ryujinx.Cpu.Jit.HostTracked
|
|||
_treeLock.ExitReadLock();
|
||||
}
|
||||
|
||||
if (_firstPagePa != null)
|
||||
{
|
||||
return (_backingMemory, _firstPagePa.Value);
|
||||
}
|
||||
|
||||
return (null, 0);
|
||||
}
|
||||
|
||||
public PrivateRange GetPrivateAllocation(ulong va)
|
||||
{
|
||||
_treeLock.EnterReadLock();
|
||||
|
|
|
|||
|
|
@ -135,8 +135,11 @@ namespace Ryujinx.Cpu.Jit
|
|||
offset += (int)copySize;
|
||||
}
|
||||
|
||||
if (last != null)
|
||||
{
|
||||
return new ReadOnlySequence<byte>(first, 0, last, (int)(size - last.RunningIndex));
|
||||
}
|
||||
}
|
||||
catch (InvalidMemoryRegionException)
|
||||
{
|
||||
if (_invalidAccessHandler == null || !_invalidAccessHandler(va))
|
||||
|
|
@ -146,6 +149,8 @@ namespace Ryujinx.Cpu.Jit
|
|||
|
||||
return ReadOnlySequence<byte>.Empty;
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
|
|||
|
|
@ -872,7 +872,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||
|
||||
if (unscaled)
|
||||
{
|
||||
writeInstUnscaled(rt, tempRegister.Operand, offs);
|
||||
writeInstUnscaled?.Invoke(rt, tempRegister.Operand, offs);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
|
||||
if (Volatile.Read(ref _interruptAction) != null)
|
||||
{
|
||||
_interruptAction();
|
||||
_interruptAction?.Invoke();
|
||||
_interruptRun.Set();
|
||||
|
||||
Interlocked.Exchange(ref _interruptAction, null);
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
|||
EmitLoadGprA(opCode);
|
||||
EmitLoadImm(opCode);
|
||||
_ilGen.Emit(OpCodes.Add);
|
||||
_ilGen.Emit(OpCodes.Call, typeof(MacroJitContext).GetMethod(nameof(MacroJitContext.Read)));
|
||||
_ilGen.Emit(OpCodes.Call, typeof(MacroJitContext).GetMethod(nameof(MacroJitContext.Read))!);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -457,7 +457,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
|||
private void EmitFetchParam()
|
||||
{
|
||||
_ilGen.Emit(OpCodes.Ldarg_0);
|
||||
_ilGen.Emit(OpCodes.Call, typeof(MacroJitContext).GetMethod(nameof(MacroJitContext.FetchParam)));
|
||||
_ilGen.Emit(OpCodes.Call, typeof(MacroJitContext).GetMethod(nameof(MacroJitContext.FetchParam))!);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -508,7 +508,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
|||
{
|
||||
_ilGen.Emit(OpCodes.Ldarg_1);
|
||||
_ilGen.Emit(OpCodes.Ldloc_S, _methAddr);
|
||||
_ilGen.Emit(OpCodes.Call, typeof(MacroJitContext).GetMethod(nameof(MacroJitContext.Send)));
|
||||
_ilGen.Emit(OpCodes.Call, typeof(MacroJitContext).GetMethod(nameof(MacroJitContext.Send))!);
|
||||
_ilGen.Emit(OpCodes.Ldloc_S, _methAddr);
|
||||
_ilGen.Emit(OpCodes.Ldloc_S, _methIncr);
|
||||
_ilGen.Emit(OpCodes.Add);
|
||||
|
|
|
|||
|
|
@ -172,6 +172,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
/// Removes the least used texture from the cache.
|
||||
/// </summary>
|
||||
private void RemoveLeastUsedTexture()
|
||||
{
|
||||
if (_textures.First != null)
|
||||
{
|
||||
Texture oldestTexture = _textures.First.Value;
|
||||
|
||||
|
|
@ -192,6 +194,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
oldestTexture.DecrementReferenceCount();
|
||||
oldestTexture.CacheNode = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a texture from the cache.
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
public T FindOrCreate(GpuChannel channel, ulong address, int maximumId, TextureBindingsArrayCache bindingsArrayCache)
|
||||
{
|
||||
// Remove old entries from the cache, if possible.
|
||||
while (_pools.Count > MaxCapacity && (_currentTimestamp - _pools.First.Value.CacheTimestamp) >= MinDeltaForRemoval)
|
||||
while (_pools.Count > MaxCapacity && _pools.First != null &&
|
||||
(_currentTimestamp - _pools.First.Value.CacheTimestamp) >= MinDeltaForRemoval)
|
||||
{
|
||||
T oldestPool = _pools.First.Value;
|
||||
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
|
||||
if (rangeCount == -1)
|
||||
{
|
||||
_migrationTarget.WaitForAndFlushRanges(address, size);
|
||||
_migrationTarget?.WaitForAndFlushRanges(address, size);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -481,7 +481,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
}
|
||||
|
||||
int offset = Unsafe.SizeOf<TocHeader>() + programIndex * Unsafe.SizeOf<OffsetAndSize>();
|
||||
if (offset + Unsafe.SizeOf<OffsetAndSize>() > tocFileStream.Length)
|
||||
if (tocFileStream != null && offset + Unsafe.SizeOf<OffsetAndSize>() > tocFileStream.Length)
|
||||
{
|
||||
return (null, null);
|
||||
}
|
||||
|
|
@ -491,7 +491,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||
throw new DiskCacheLoadException(DiskCacheLoadResult.FileCorruptedGeneric);
|
||||
}
|
||||
|
||||
tocFileStream.Seek(offset, SeekOrigin.Begin);
|
||||
tocFileStream?.Seek(offset, SeekOrigin.Begin);
|
||||
|
||||
BinarySerializer tocReader = new(tocFileStream);
|
||||
|
||||
|
|
|
|||
|
|
@ -990,10 +990,13 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
dataWriter.Write(ref hasPipelineState);
|
||||
|
||||
if (hasPipelineState)
|
||||
{
|
||||
if (PipelineState != null)
|
||||
{
|
||||
ProgramPipelineState pipelineState = PipelineState.Value;
|
||||
dataWriter.WriteWithMagicAndSize(ref pipelineState, PgpsMagic);
|
||||
}
|
||||
}
|
||||
|
||||
if (_queriedState.HasFlag(QueriedStateFlags.TransformFeedback))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg
|
|||
|
||||
FFmpegApi.av_log_format_line(ptr, level, format, vl, lineBuffer, lineSize, &printPrefix);
|
||||
|
||||
string line = Marshal.PtrToStringAnsi((IntPtr)lineBuffer).Trim();
|
||||
string line = Marshal.PtrToStringAnsi((IntPtr)lineBuffer)?.Trim();
|
||||
|
||||
switch (level)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
IntPtr message,
|
||||
IntPtr userParam)
|
||||
{
|
||||
string msg = Marshal.PtrToStringUTF8(message).Replace('\n', ' ');
|
||||
string msg = Marshal.PtrToStringUTF8(message)?.Replace('\n', ' ');
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects
|
|||
GL.UseProgram(previousProgram);
|
||||
GL.MemoryBarrier(MemoryBarrierFlags.ShaderImageAccessBarrierBit);
|
||||
|
||||
(_renderer.Pipeline as Pipeline).RestoreImages1And2();
|
||||
(_renderer.Pipeline as Pipeline)?.RestoreImages1And2();
|
||||
|
||||
GL.ActiveTexture(TextureUnit.Texture0);
|
||||
GL.BindTexture(TextureTarget.Texture2D, previousTextureBinding);
|
||||
|
|
|
|||
|
|
@ -125,7 +125,10 @@ namespace Ryujinx.Graphics.OpenGL.Effects
|
|||
GL.ActiveTexture(TextureUnit.Texture0);
|
||||
int previousTextureBinding = GL.GetInteger(GetPName.TextureBinding2D);
|
||||
|
||||
GL.BindImageTexture(0, textureView.Handle, 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
if (textureView != null)
|
||||
{
|
||||
GL.BindImageTexture(0, textureView.Handle, 0, false, 0, TextureAccess.ReadWrite,
|
||||
SizedInternalFormat.Rgba8);
|
||||
|
||||
int threadGroupWorkRegionDim = 16;
|
||||
int dispatchX = (width + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
|
||||
|
|
@ -156,17 +159,19 @@ namespace Ryujinx.Graphics.OpenGL.Effects
|
|||
|
||||
// Sharpening Pass
|
||||
GL.UseProgram(_sharpeningShaderProgram);
|
||||
GL.BindImageTexture(0, destinationTexture.Handle, 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
GL.BindImageTexture(0, destinationTexture.Handle, 0, false, 0, TextureAccess.ReadWrite,
|
||||
SizedInternalFormat.Rgba8);
|
||||
textureView.Bind(0);
|
||||
GL.Uniform1(_inputUniform, 0);
|
||||
GL.Uniform1(_outputUniform, 0);
|
||||
GL.Uniform1(_sharpeningUniform, 1.5f - (Level * 0.01f * 1.5f));
|
||||
GL.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
}
|
||||
|
||||
GL.UseProgram(previousProgram);
|
||||
GL.MemoryBarrier(MemoryBarrierFlags.ShaderImageAccessBarrierBit);
|
||||
|
||||
(_renderer.Pipeline as Pipeline).RestoreImages1And2();
|
||||
(_renderer.Pipeline as Pipeline)?.RestoreImages1And2();
|
||||
|
||||
GL.ActiveTexture(TextureUnit.Texture0);
|
||||
GL.BindTexture(TextureTarget.Texture2D, previousTextureBinding);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects
|
|||
GL.UseProgram(previousProgram);
|
||||
GL.MemoryBarrier(MemoryBarrierFlags.ShaderImageAccessBarrierBit);
|
||||
|
||||
(_renderer.Pipeline as Pipeline).RestoreImages1And2();
|
||||
(_renderer.Pipeline as Pipeline)?.RestoreImages1And2();
|
||||
|
||||
GL.ActiveTexture(TextureUnit.Texture0);
|
||||
GL.BindTexture(TextureTarget.Texture2D, previousTextureBinding);
|
||||
|
|
|
|||
|
|
@ -222,8 +222,8 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
|
|||
GL.BindImageTexture(0, blendOutput.Handle, 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
GL.UseProgram(_blendShaderPrograms[Quality]);
|
||||
edgeOutput.Bind(0);
|
||||
areaTexture.Bind(1);
|
||||
searchTexture.Bind(2);
|
||||
areaTexture?.Bind(1);
|
||||
searchTexture?.Bind(2);
|
||||
GL.Uniform1(_inputUniform, 0);
|
||||
GL.Uniform1(_outputUniform, 0);
|
||||
GL.Uniform1(_samplerAreaUniform, 1);
|
||||
|
|
@ -243,7 +243,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
|
|||
GL.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
GL.MemoryBarrier(MemoryBarrierFlags.ShaderImageAccessBarrierBit);
|
||||
|
||||
(_renderer.Pipeline as Pipeline).RestoreImages1And2();
|
||||
(_renderer.Pipeline as Pipeline)?.RestoreImages1And2();
|
||||
|
||||
GL.UseProgram(previousProgram);
|
||||
|
||||
|
|
|
|||
|
|
@ -64,9 +64,12 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
|||
INode lastOp = GetLastOp();
|
||||
|
||||
if (lastOp is Operation operation && IsControlFlowInst(operation.Inst))
|
||||
{
|
||||
if (Operations.Last != null)
|
||||
{
|
||||
Operations.AddBefore(Operations.Last, node);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Operations.AddLast(node);
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
}
|
||||
}
|
||||
|
||||
if (handleAsgOp.Inst != Instruction.Load ||
|
||||
if (handleAsgOp is not { Inst: Instruction.Load } ||
|
||||
handleAsgOp.StorageKind != StorageKind.ConstantBuffer ||
|
||||
handleAsgOp.SourcesCount != 4)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
|
||||
operation.Dest = null;
|
||||
|
||||
LinkedListNode<INode> newNode = node.List.AddBefore(node, new Operation(Instruction.Call, 0, floatValue, callArgs));
|
||||
LinkedListNode<INode> newNode = node.List?.AddBefore(node, new Operation(Instruction.Call, 0, floatValue, callArgs));
|
||||
|
||||
Utils.DeleteNode(node, operation);
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
|
||||
Operand[] callArgs = [Const(functionId), operation.GetSource(0), resultLow, resultHigh];
|
||||
|
||||
LinkedListNode<INode> newNode = node.List.AddBefore(node, new Operation(Instruction.Call, 0, (Operand)null, callArgs));
|
||||
LinkedListNode<INode> newNode = node.List?.AddBefore(node, new Operation(Instruction.Call, 0, (Operand)null, callArgs));
|
||||
|
||||
Utils.DeleteNode(node, operation);
|
||||
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
LinkedListNode<INode> node)
|
||||
{
|
||||
Operation operation = node.Value as Operation;
|
||||
Operand globalAddress = operation.GetSource(0);
|
||||
Operand globalAddress = operation?.GetSource(0);
|
||||
SearchResult result = FindUniqueBaseAddressCb(gtsContext, block, globalAddress, needsOffset: true);
|
||||
|
||||
if (result.Found)
|
||||
|
|
@ -331,8 +331,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
Operation maskOp = new(Instruction.BitwiseAnd, baseAddressMasked, baseAddress, Const(-alignment));
|
||||
Operation subOp = new(Instruction.Subtract, hostOffset, globalAddress, baseAddressMasked);
|
||||
|
||||
node.List.AddBefore(node, maskOp);
|
||||
node.List.AddBefore(node, subOp);
|
||||
node.List?.AddBefore(node, maskOp);
|
||||
node.List?.AddBefore(node, subOp);
|
||||
|
||||
offset = hostOffset;
|
||||
}
|
||||
|
|
@ -342,7 +342,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
|
||||
Operation addOp = new(Instruction.Add, newOffset, offset, Const(result.ConstOffset));
|
||||
|
||||
node.List.AddBefore(node, addOp);
|
||||
node.List?.AddBefore(node, addOp);
|
||||
|
||||
offset = newOffset;
|
||||
}
|
||||
|
|
@ -441,8 +441,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
Operation shiftOp = new(Instruction.ShiftRightU32, wordOffset, offset, Const(2));
|
||||
Operation storageOp = new(operation.Inst, StorageKind.StorageBuffer, operation.Dest, sources);
|
||||
|
||||
node.List.AddBefore(node, shiftOp);
|
||||
LinkedListNode<INode> newNode = node.List.AddBefore(node, storageOp);
|
||||
node.List?.AddBefore(node, shiftOp);
|
||||
LinkedListNode<INode> newNode = node.List?.AddBefore(node, storageOp);
|
||||
|
||||
Utils.DeleteNode(node, operation);
|
||||
|
||||
|
|
@ -483,7 +483,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
|
||||
Operation callOp = new(Instruction.Call, returnValue, sources);
|
||||
|
||||
LinkedListNode<INode> newNode = node.List.AddBefore(node, callOp);
|
||||
LinkedListNode<INode> newNode = node.List?.AddBefore(node, callOp);
|
||||
|
||||
if (returnsValue)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
|
||||
public static void DeleteNode(LinkedListNode<INode> node, Operation operation)
|
||||
{
|
||||
node.List.Remove(node);
|
||||
node.List?.Remove(node);
|
||||
|
||||
for (int srcIndex = 0; srcIndex < operation.SourcesCount; srcIndex++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
{
|
||||
Operation operation = node.Value as Operation;
|
||||
|
||||
for (int srcIndex = 0; srcIndex < operation.SourcesCount; srcIndex++)
|
||||
for (int srcIndex = 0; srcIndex < operation?.SourcesCount; srcIndex++)
|
||||
{
|
||||
Operand source = operation.GetSource(srcIndex);
|
||||
|
||||
|
|
@ -155,7 +155,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
localInputs[block.Index] |= GetMask(register) & ~localOutputs[block.Index];
|
||||
}
|
||||
|
||||
for (int dstIndex = 0; dstIndex < operation.DestsCount; dstIndex++)
|
||||
for (int dstIndex = 0; dstIndex < operation?.DestsCount; dstIndex++)
|
||||
{
|
||||
Operand dest = operation.GetDest(dstIndex);
|
||||
|
||||
|
|
@ -296,7 +296,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
{
|
||||
Operation operation = node.Value as Operation;
|
||||
|
||||
if (operation.Inst == Instruction.Call)
|
||||
if (operation?.Inst == Instruction.Call)
|
||||
{
|
||||
Operand funcId = operation.GetSource(0);
|
||||
|
||||
|
|
@ -333,7 +333,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
return false;
|
||||
}
|
||||
|
||||
return block.Operations.First.Value is Operation operation && operation.Inst == inst;
|
||||
return block.Operations.First?.Value is Operation operation && operation.Inst == inst;
|
||||
}
|
||||
|
||||
private static bool EndsWith(BasicBlock block, Instruction inst)
|
||||
|
|
@ -343,7 +343,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
return false;
|
||||
}
|
||||
|
||||
return block.Operations.Last.Value is Operation operation && operation.Inst == inst;
|
||||
return block.Operations.Last?.Value is Operation operation && operation.Inst == inst;
|
||||
}
|
||||
|
||||
private static RegisterMask GetMask(Register register)
|
||||
|
|
@ -444,9 +444,12 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
Operation copyOp = new(Instruction.Copy, OperandHelper.Argument(argIndex++), OperandHelper.Register(register));
|
||||
|
||||
if (node == null)
|
||||
{
|
||||
if (block.Operations.Last != null)
|
||||
{
|
||||
node = block.Operations.AddBefore(block.Operations.Last, copyOp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
node = block.Operations.AddAfter(node, copyOp);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
Operand GenerateLoad(IoVariable ioVariable)
|
||||
{
|
||||
Operand value = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Load, StorageKind.Input, value, Const((int)ioVariable)));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Load, StorageKind.Input, value, Const((int)ioVariable)));
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
|
||||
Operand vertexElemOffset = GenerateVertexOffset(context.ResourceManager, node, inputOffset, primVertex);
|
||||
|
||||
newNode = node.List.AddBefore(node, new Operation(
|
||||
newNode = node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.StorageBuffer,
|
||||
operation.Dest,
|
||||
|
|
@ -80,7 +80,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
{
|
||||
if (TryGetOffset(context.ResourceManager, operation, StorageKind.Output, out int outputOffset))
|
||||
{
|
||||
newNode = node.List.AddBefore(node, new Operation(
|
||||
newNode = node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.LocalMemory,
|
||||
operation.Dest,
|
||||
|
|
@ -99,7 +99,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
{
|
||||
Operand value = operation.GetSource(operation.SourcesCount - 1);
|
||||
|
||||
newNode = node.List.AddBefore(node, new Operation(
|
||||
newNode = node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Store,
|
||||
StorageKind.LocalMemory,
|
||||
(Operand)null,
|
||||
|
|
@ -134,7 +134,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
definitions.MaxOutputVertices * definitions.ThreadsPerInputPrimitive,
|
||||
definitions.ThreadsPerInputPrimitive);
|
||||
Operand outputBaseVertex = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Add, outputBaseVertex, new[] { baseVertexOffset, outputPrimVertex }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Add, outputBaseVertex, new[] { baseVertexOffset, outputPrimVertex }));
|
||||
|
||||
Operand outputPrimIndex = IncrementLocalMemory(node, resourceManager.LocalGeometryOutputIndexCountMemoryId);
|
||||
Operand baseIndexOffset = GenerateBaseOffset(
|
||||
|
|
@ -143,16 +143,16 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
definitions.GetGeometryOutputIndexBufferStride(),
|
||||
definitions.ThreadsPerInputPrimitive);
|
||||
Operand outputBaseIndex = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Add, outputBaseIndex, new[] { baseIndexOffset, outputPrimIndex }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Add, outputBaseIndex, new[] { baseIndexOffset, outputPrimIndex }));
|
||||
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Store,
|
||||
StorageKind.StorageBuffer,
|
||||
null,
|
||||
new[] { Const(ibOutputBinding), Const(0), outputBaseIndex, outputBaseVertex }));
|
||||
|
||||
Operand baseOffset = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Multiply, baseOffset, new[] { outputBaseVertex, Const(stride) }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Multiply, baseOffset, new[] { outputBaseVertex, Const(stride) }));
|
||||
|
||||
LinkedListNode<INode> newNode = node;
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
if (offset > 0)
|
||||
{
|
||||
vertexOffset = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Add, vertexOffset, new[] { baseOffset, Const(offset) }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Add, vertexOffset, new[] { baseOffset, Const(offset) }));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -171,13 +171,13 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
}
|
||||
|
||||
Operand value = Local();
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.LocalMemory,
|
||||
value,
|
||||
new[] { Const(resourceManager.LocalVertexDataMemoryId), Const(offset) }));
|
||||
|
||||
newNode = node.List.AddBefore(node, new Operation(
|
||||
newNode = node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Store,
|
||||
StorageKind.StorageBuffer,
|
||||
null,
|
||||
|
|
@ -198,9 +198,9 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
definitions.GetGeometryOutputIndexBufferStride(),
|
||||
definitions.ThreadsPerInputPrimitive);
|
||||
Operand outputBaseIndex = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Add, outputBaseIndex, new[] { baseIndexOffset, outputPrimIndex }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Add, outputBaseIndex, new[] { baseIndexOffset, outputPrimIndex }));
|
||||
|
||||
return node.List.AddBefore(node, new Operation(
|
||||
return node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Store,
|
||||
StorageKind.StorageBuffer,
|
||||
null,
|
||||
|
|
@ -213,16 +213,16 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
GeneratePrimitiveId(resourceManager, node, primitiveId);
|
||||
|
||||
Operand baseOffset = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Multiply, baseOffset, new[] { primitiveId, Const(stride) }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Multiply, baseOffset, new[] { primitiveId, Const(stride) }));
|
||||
|
||||
Operand invocationId = Local();
|
||||
GenerateInvocationId(node, invocationId);
|
||||
|
||||
Operand invocationOffset = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Multiply, invocationOffset, new[] { invocationId, Const(stride / threadsPerInputPrimitive) }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Multiply, invocationOffset, new[] { invocationId, Const(stride / threadsPerInputPrimitive) }));
|
||||
|
||||
Operand combinedOffset = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Add, combinedOffset, new[] { baseOffset, invocationOffset }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Add, combinedOffset, new[] { baseOffset, invocationOffset }));
|
||||
|
||||
return combinedOffset;
|
||||
}
|
||||
|
|
@ -230,16 +230,16 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
private static Operand IncrementLocalMemory(LinkedListNode<INode> node, int memoryId)
|
||||
{
|
||||
Operand oldValue = Local();
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.LocalMemory,
|
||||
oldValue,
|
||||
new[] { Const(memoryId) }));
|
||||
|
||||
Operand newValue = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Add, newValue, new[] { oldValue, Const(1) }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Add, newValue, new[] { oldValue, Const(1) }));
|
||||
|
||||
node.List.AddBefore(node, new Operation(Instruction.Store, StorageKind.LocalMemory, null, new[] { Const(memoryId), newValue }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Store, StorageKind.LocalMemory, null, new[] { Const(memoryId), newValue }));
|
||||
|
||||
return oldValue;
|
||||
}
|
||||
|
|
@ -253,34 +253,34 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
int vertexInfoCbBinding = resourceManager.Reservations.VertexInfoConstantBufferBinding;
|
||||
|
||||
Operand vertexCount = Local();
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.ConstantBuffer,
|
||||
vertexCount,
|
||||
new[] { Const(vertexInfoCbBinding), Const((int)VertexInfoBufferField.VertexCounts), Const(0) }));
|
||||
|
||||
Operand primInputVertex = Local();
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.LocalMemory,
|
||||
primInputVertex,
|
||||
new[] { Const(resourceManager.LocalTopologyRemapMemoryId), primVertex }));
|
||||
|
||||
Operand instanceIndex = Local();
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.Input,
|
||||
instanceIndex,
|
||||
new[] { Const((int)IoVariable.GlobalId), Const(1) }));
|
||||
|
||||
Operand baseVertex = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Multiply, baseVertex, new[] { instanceIndex, vertexCount }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Multiply, baseVertex, new[] { instanceIndex, vertexCount }));
|
||||
|
||||
Operand vertexIndex = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Add, vertexIndex, new[] { baseVertex, primInputVertex }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Add, vertexIndex, new[] { baseVertex, primInputVertex }));
|
||||
|
||||
Operand vertexBaseOffset = Local();
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Multiply,
|
||||
vertexBaseOffset,
|
||||
new[] { vertexIndex, Const(resourceManager.Reservations.InputSizePerInvocation) }));
|
||||
|
|
@ -291,7 +291,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
{
|
||||
vertexElemOffset = Local();
|
||||
|
||||
node.List.AddBefore(node, new Operation(Instruction.Add, vertexElemOffset, new[] { vertexBaseOffset, Const(elementOffset) }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Add, vertexElemOffset, new[] { vertexBaseOffset, Const(elementOffset) }));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -306,35 +306,35 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
int vertexInfoCbBinding = resourceManager.Reservations.VertexInfoConstantBufferBinding;
|
||||
|
||||
Operand vertexCount = Local();
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.ConstantBuffer,
|
||||
vertexCount,
|
||||
new[] { Const(vertexInfoCbBinding), Const((int)VertexInfoBufferField.VertexCounts), Const(0) }));
|
||||
|
||||
Operand vertexIndex = Local();
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.Input,
|
||||
vertexIndex,
|
||||
new[] { Const((int)IoVariable.GlobalId), Const(0) }));
|
||||
|
||||
Operand instanceIndex = Local();
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.Input,
|
||||
instanceIndex,
|
||||
new[] { Const((int)IoVariable.GlobalId), Const(1) }));
|
||||
|
||||
Operand baseVertex = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Multiply, baseVertex, new[] { instanceIndex, vertexCount }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Multiply, baseVertex, new[] { instanceIndex, vertexCount }));
|
||||
|
||||
return node.List.AddBefore(node, new Operation(Instruction.Add, dest, new[] { baseVertex, vertexIndex }));
|
||||
return node.List?.AddBefore(node, new Operation(Instruction.Add, dest, new[] { baseVertex, vertexIndex }));
|
||||
}
|
||||
|
||||
private static LinkedListNode<INode> GenerateInvocationId(LinkedListNode<INode> node, Operand dest)
|
||||
{
|
||||
return node.List.AddBefore(node, new Operation(
|
||||
return node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.Input,
|
||||
dest,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
|
||||
Operand[] callArgs = [Const(functionId), byteOffset, value];
|
||||
|
||||
LinkedListNode<INode> newNode = node.List.AddBefore(node, new Operation(Instruction.Call, 0, result, callArgs));
|
||||
LinkedListNode<INode> newNode = node.List?.AddBefore(node, new Operation(Instruction.Call, 0, result, callArgs));
|
||||
|
||||
Utils.DeleteNode(node, operation);
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
|
||||
Operand[] callArgs = [Const(functionId), byteOffset, value];
|
||||
|
||||
LinkedListNode<INode> newNode = node.List.AddBefore(node, new Operation(Instruction.Call, 0, (Operand)null, callArgs));
|
||||
LinkedListNode<INode> newNode = node.List?.AddBefore(node, new Operation(Instruction.Call, 0, (Operand)null, callArgs));
|
||||
|
||||
Utils.DeleteNode(node, operation);
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
|
||||
Operand[] callArgs = [Const(functionId), value, index, mask, valid];
|
||||
|
||||
LinkedListNode<INode> newNode = node.List.AddBefore(node, new Operation(Instruction.Call, 0, result, callArgs));
|
||||
LinkedListNode<INode> newNode = node.List?.AddBefore(node, new Operation(Instruction.Call, 0, result, callArgs));
|
||||
|
||||
Utils.DeleteNode(node, operation);
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
callArgs = [Const(functionId), texOp.GetSource(coordsIndex + index), Const(samplerIndex)];
|
||||
}
|
||||
|
||||
node.List.AddBefore(node, new Operation(Instruction.Call, 0, scaledCoord, callArgs));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Call, 0, scaledCoord, callArgs));
|
||||
|
||||
texOp.SetSource(coordsIndex + index, scaledCoord);
|
||||
}
|
||||
|
|
@ -130,7 +130,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
|
||||
Operand[] callArgs = [Const(functionId), dest, Const(samplerIndex)];
|
||||
|
||||
node.List.AddAfter(node, new Operation(Instruction.Call, 0, unscaledSize, callArgs));
|
||||
node.List?.AddAfter(node, new Operation(Instruction.Call, 0, unscaledSize, callArgs));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -178,7 +178,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
|
||||
Operand[] texSizeSources = [Const(0)];
|
||||
|
||||
LinkedListNode<INode> textureSizeNode = node.List.AddBefore(node, new TextureOperation(
|
||||
LinkedListNode<INode> textureSizeNode = node.List?.AddBefore(node, new TextureOperation(
|
||||
Instruction.TextureQuerySize,
|
||||
texOp.Type,
|
||||
texOp.Format,
|
||||
|
|
@ -195,7 +195,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
|
||||
Operand coordNormalized = Local();
|
||||
|
||||
node.List.AddBefore(node, new Operation(Instruction.FP32 | Instruction.Divide, coordNormalized, source, GenerateI2f(node, coordSize)));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.FP32 | Instruction.Divide, coordNormalized, source, GenerateI2f(node, coordSize)));
|
||||
|
||||
texOp.SetSource(index, coordNormalized);
|
||||
|
||||
|
|
@ -248,7 +248,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
texSizeSources = [Const(0)];
|
||||
}
|
||||
|
||||
node.List.AddBefore(node, new TextureOperation(
|
||||
node.List?.AddBefore(node, new TextureOperation(
|
||||
Instruction.TextureQuerySize,
|
||||
texOp.Type,
|
||||
texOp.Format,
|
||||
|
|
@ -259,18 +259,18 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
[coordSize],
|
||||
texSizeSources));
|
||||
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.FP32 | Instruction.Multiply,
|
||||
scaledSize,
|
||||
GenerateI2f(node, coordSize),
|
||||
ConstF((float)(1 << (gatherBiasPrecision + 1)))));
|
||||
node.List.AddBefore(node, new Operation(Instruction.FP32 | Instruction.Divide, bias, ConstF(1f), scaledSize));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.FP32 | Instruction.Divide, bias, ConstF(1f), scaledSize));
|
||||
|
||||
Operand source = texOp.GetSource(coordsIndex + index);
|
||||
|
||||
Operand coordBiased = Local();
|
||||
|
||||
node.List.AddBefore(node, new Operation(Instruction.FP32 | Instruction.Add, coordBiased, source, bias));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.FP32 | Instruction.Add, coordBiased, source, bias));
|
||||
|
||||
texOp.SetSource(coordsIndex + index, coordBiased);
|
||||
}
|
||||
|
|
@ -573,7 +573,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
texSizeSources = [Const(0)];
|
||||
}
|
||||
|
||||
node.List.AddBefore(node, new TextureOperation(
|
||||
node.List?.AddBefore(node, new TextureOperation(
|
||||
Instruction.TextureQuerySize,
|
||||
texOp.Type,
|
||||
texOp.Format,
|
||||
|
|
@ -604,7 +604,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
{
|
||||
lod = Local();
|
||||
|
||||
node.List.AddBefore(node, new TextureOperation(
|
||||
node.List?.AddBefore(node, new TextureOperation(
|
||||
Instruction.Lod,
|
||||
texOp.Type,
|
||||
texOp.Format,
|
||||
|
|
@ -635,7 +635,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
texSizeSources = [GenerateF2i(node, lod)];
|
||||
}
|
||||
|
||||
node.List.AddBefore(node, new TextureOperation(
|
||||
node.List?.AddBefore(node, new TextureOperation(
|
||||
Instruction.TextureQuerySize,
|
||||
texOp.Type,
|
||||
texOp.Format,
|
||||
|
|
@ -692,8 +692,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
Operation convOp = new(Instruction.ConvertS32ToFP32, Local(), dest);
|
||||
Operation normOp = new(Instruction.FP32 | Instruction.Multiply, Local(), convOp.Dest, ConstF(1f / maxPositive));
|
||||
|
||||
node = node.List.AddAfter(node, convOp);
|
||||
node = node.List.AddAfter(node, normOp);
|
||||
node = node?.List?.AddAfter(node, convOp);
|
||||
node = node?.List?.AddAfter(node, normOp);
|
||||
|
||||
foreach (INode useOp in uses)
|
||||
{
|
||||
|
|
@ -720,7 +720,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
{
|
||||
Operand res = Local();
|
||||
|
||||
node.List.AddBefore(node, new Operation(Instruction.ConvertS32ToFP32, res, value));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.ConvertS32ToFP32, res, value));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
@ -729,7 +729,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
{
|
||||
Operand res = Local();
|
||||
|
||||
node.List.AddBefore(node, new Operation(Instruction.ConvertFP32ToS32, res, value));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.ConvertFP32ToS32, res, value));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
|
||||
Operation loadOp = new(Instruction.Load, StorageKind.ConstantBuffer, value, inputs);
|
||||
|
||||
node.List.AddBefore(node, loadOp);
|
||||
node.List?.AddBefore(node, loadOp);
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
|
|
@ -81,8 +81,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
Operation compareOp = new(Instruction.CompareEqual, isCurrentIndex, new Operand[] { elemIndex, Const(i) });
|
||||
Operation selectOp = new(Instruction.ConditionalSelect, selection, new Operand[] { isCurrentIndex, value, result });
|
||||
|
||||
node.List.AddBefore(node, compareOp);
|
||||
node.List.AddBefore(node, selectOp);
|
||||
node.List?.AddBefore(node, compareOp);
|
||||
node.List?.AddBefore(node, selectOp);
|
||||
|
||||
result = selection;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
Operand temp = needsSextNorm ? Local() : dest;
|
||||
Operand vertexElemOffset = GenerateVertexOffset(context.ResourceManager, node, location, 0);
|
||||
|
||||
newNode = node.List.AddBefore(node, new TextureOperation(
|
||||
newNode = node.List?.AddBefore(node, new TextureOperation(
|
||||
Instruction.TextureSample,
|
||||
SamplerType.TextureBuffer,
|
||||
TextureFormat.Unknown,
|
||||
|
|
@ -81,7 +81,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
Operand temp = component > 0 ? Local() : dest;
|
||||
Operand vertexElemOffset = GenerateVertexOffset(context.ResourceManager, node, location, component);
|
||||
|
||||
newNode = node.List.AddBefore(node, new TextureOperation(
|
||||
newNode = node.List?.AddBefore(node, new TextureOperation(
|
||||
Instruction.TextureSample,
|
||||
SamplerType.TextureBuffer,
|
||||
TextureFormat.Unknown,
|
||||
|
|
@ -116,7 +116,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
{
|
||||
if (TryGetOutputOffset(context.ResourceManager, operation, out int outputOffset))
|
||||
{
|
||||
newNode = node.List.AddBefore(node, new Operation(
|
||||
newNode = node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.LocalMemory,
|
||||
operation.Dest,
|
||||
|
|
@ -133,7 +133,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
{
|
||||
Operand value = operation.GetSource(operation.SourcesCount - 1);
|
||||
|
||||
newNode = node.List.AddBefore(node, new Operation(
|
||||
newNode = node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Store,
|
||||
StorageKind.LocalMemory,
|
||||
(Operand)null,
|
||||
|
|
@ -164,37 +164,37 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
GenerateVertexIdInstanceRateLoad(resourceManager, node, vertexIdIr);
|
||||
|
||||
Operand attributeOffset = Local();
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.ConstantBuffer,
|
||||
attributeOffset,
|
||||
new[] { Const(vertexInfoCbBinding), Const((int)VertexInfoBufferField.VertexOffsets), Const(location), Const(0) }));
|
||||
|
||||
Operand isInstanceRate = Local();
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.ConstantBuffer,
|
||||
isInstanceRate,
|
||||
new[] { Const(vertexInfoCbBinding), Const((int)VertexInfoBufferField.VertexOffsets), Const(location), Const(1) }));
|
||||
|
||||
Operand vertexId = Local();
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.ConditionalSelect,
|
||||
vertexId,
|
||||
new[] { isInstanceRate, vertexIdIr, vertexIdVr }));
|
||||
|
||||
Operand vertexStride = Local();
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.ConstantBuffer,
|
||||
vertexStride,
|
||||
new[] { Const(vertexInfoCbBinding), Const((int)VertexInfoBufferField.VertexStrides), Const(location), Const(0) }));
|
||||
|
||||
Operand vertexBaseOffset = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Multiply, vertexBaseOffset, new[] { vertexId, vertexStride }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Multiply, vertexBaseOffset, new[] { vertexId, vertexStride }));
|
||||
|
||||
Operand vertexOffset = Local();
|
||||
node.List.AddBefore(node, new Operation(Instruction.Add, vertexOffset, new[] { attributeOffset, vertexBaseOffset }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Add, vertexOffset, new[] { attributeOffset, vertexBaseOffset }));
|
||||
|
||||
Operand vertexElemOffset;
|
||||
|
||||
|
|
@ -202,7 +202,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
{
|
||||
vertexElemOffset = Local();
|
||||
|
||||
node.List.AddBefore(node, new Operation(Instruction.Add, vertexElemOffset, new[] { vertexOffset, Const(component) }));
|
||||
node.List?.AddBefore(node, new Operation(Instruction.Add, vertexElemOffset, new[] { vertexOffset, Const(component) }));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -215,13 +215,13 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
private static LinkedListNode<INode> CopySignExtendedNormalized(LinkedListNode<INode> node, int bits, bool normalize, Operand dest, Operand src)
|
||||
{
|
||||
Operand leftShifted = Local();
|
||||
node = node.List.AddAfter(node, new Operation(
|
||||
node = node.List?.AddAfter(node, new Operation(
|
||||
Instruction.ShiftLeft,
|
||||
leftShifted,
|
||||
new[] { src, Const(32 - bits) }));
|
||||
|
||||
Operand rightShifted = normalize ? Local() : dest;
|
||||
node = node.List.AddAfter(node, new Operation(
|
||||
node = node?.List?.AddAfter(node, new Operation(
|
||||
Instruction.ShiftRightS32,
|
||||
rightShifted,
|
||||
new[] { leftShifted, Const(32 - bits) }));
|
||||
|
|
@ -229,8 +229,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
if (normalize)
|
||||
{
|
||||
Operand asFloat = Local();
|
||||
node = node.List.AddAfter(node, new Operation(Instruction.ConvertS32ToFP32, asFloat, new[] { rightShifted }));
|
||||
node = node.List.AddAfter(node, new Operation(
|
||||
node = node?.List?.AddAfter(node, new Operation(Instruction.ConvertS32ToFP32, asFloat, new[] { rightShifted }));
|
||||
node = node?.List?.AddAfter(node, new Operation(
|
||||
Instruction.FP32 | Instruction.Multiply,
|
||||
dest,
|
||||
new[] { asFloat, ConstF(1f / (1 << (bits - 1))) }));
|
||||
|
|
@ -249,13 +249,13 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
{
|
||||
Operand componentExists = Local();
|
||||
int vertexInfoCbBinding = resourceManager.Reservations.VertexInfoConstantBufferBinding;
|
||||
node = node.List.AddAfter(node, new Operation(
|
||||
node = node.List?.AddAfter(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.ConstantBuffer,
|
||||
componentExists,
|
||||
new[] { Const(vertexInfoCbBinding), Const((int)VertexInfoBufferField.VertexStrides), Const(location), Const(component) }));
|
||||
|
||||
return node.List.AddAfter(node, new Operation(
|
||||
return node?.List?.AddAfter(node, new Operation(
|
||||
Instruction.ConditionalSelect,
|
||||
dest,
|
||||
new[] { componentExists, src, ConstF(component == 3 ? 1f : 0f) }));
|
||||
|
|
@ -265,7 +265,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
{
|
||||
int vertexInfoCbBinding = resourceManager.Reservations.VertexInfoConstantBufferBinding;
|
||||
|
||||
return node.List.AddBefore(node, new Operation(
|
||||
return node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.ConstantBuffer,
|
||||
dest,
|
||||
|
|
@ -276,7 +276,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
{
|
||||
int vertexInfoCbBinding = resourceManager.Reservations.VertexInfoConstantBufferBinding;
|
||||
|
||||
return node.List.AddBefore(node, new Operation(
|
||||
return node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.ConstantBuffer,
|
||||
dest,
|
||||
|
|
@ -291,7 +291,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
GenerateBaseVertexLoad(resourceManager, node, baseVertex);
|
||||
GenerateVertexIdVertexRateLoad(resourceManager, node, vertexId);
|
||||
|
||||
return node.List.AddBefore(node, new Operation(Instruction.Add, dest, new[] { baseVertex, vertexId }));
|
||||
return node.List?.AddBefore(node, new Operation(Instruction.Add, dest, new[] { baseVertex, vertexId }));
|
||||
}
|
||||
|
||||
private static LinkedListNode<INode> GenerateInstanceIndexLoad(ResourceManager resourceManager, LinkedListNode<INode> node, Operand dest)
|
||||
|
|
@ -301,34 +301,34 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
|
|||
|
||||
GenerateBaseInstanceLoad(resourceManager, node, baseInstance);
|
||||
|
||||
node.List.AddBefore(node, new Operation(
|
||||
node.List?.AddBefore(node, new Operation(
|
||||
Instruction.Load,
|
||||
StorageKind.Input,
|
||||
instanceId,
|
||||
new[] { Const((int)IoVariable.GlobalId), Const(1) }));
|
||||
|
||||
return node.List.AddBefore(node, new Operation(Instruction.Add, dest, new[] { baseInstance, instanceId }));
|
||||
return node.List?.AddBefore(node, new Operation(Instruction.Add, dest, new[] { baseInstance, instanceId }));
|
||||
}
|
||||
|
||||
private static LinkedListNode<INode> GenerateVertexIdVertexRateLoad(ResourceManager resourceManager, LinkedListNode<INode> node, Operand dest)
|
||||
{
|
||||
Operand[] sources = [Const(resourceManager.LocalVertexIndexVertexRateMemoryId)];
|
||||
|
||||
return node.List.AddBefore(node, new Operation(Instruction.Load, StorageKind.LocalMemory, dest, sources));
|
||||
return node.List?.AddBefore(node, new Operation(Instruction.Load, StorageKind.LocalMemory, dest, sources));
|
||||
}
|
||||
|
||||
private static LinkedListNode<INode> GenerateVertexIdInstanceRateLoad(ResourceManager resourceManager, LinkedListNode<INode> node, Operand dest)
|
||||
{
|
||||
Operand[] sources = [Const(resourceManager.LocalVertexIndexInstanceRateMemoryId)];
|
||||
|
||||
return node.List.AddBefore(node, new Operation(Instruction.Load, StorageKind.LocalMemory, dest, sources));
|
||||
return node.List?.AddBefore(node, new Operation(Instruction.Load, StorageKind.LocalMemory, dest, sources));
|
||||
}
|
||||
|
||||
private static LinkedListNode<INode> GenerateInstanceIdLoad(LinkedListNode<INode> node, Operand dest)
|
||||
{
|
||||
Operand[] sources = [Const((int)IoVariable.GlobalId), Const(1)];
|
||||
|
||||
return node.List.AddBefore(node, new Operation(Instruction.Load, StorageKind.Input, dest, sources));
|
||||
return node.List?.AddBefore(node, new Operation(Instruction.Load, StorageKind.Input, dest, sources));
|
||||
}
|
||||
|
||||
private static bool TryGetOutputOffset(ResourceManager resourceManager, Operation operation, out int outputOffset)
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||
int dispatchY = (height + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
|
||||
|
||||
_pipeline.SetUniformBuffers([new BufferAssignment(2, buffer.Range)]);
|
||||
_pipeline.SetImage(ShaderStage.Compute, 0, _intermediaryTexture.GetView(FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)));
|
||||
_pipeline.SetImage(ShaderStage.Compute, 0, _intermediaryTexture?.GetView(FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)));
|
||||
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
_pipeline.ComputeBarrier();
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||
var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
|
||||
var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
|
||||
|
||||
_pipeline.SetImage(ShaderStage.Compute, 0, _texture.GetView(FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)));
|
||||
_pipeline.SetImage(ShaderStage.Compute, 0, _texture?.GetView(FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)));
|
||||
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
|
||||
_pipeline.ComputeBarrier();
|
||||
|
|
|
|||
|
|
@ -177,8 +177,8 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||
_areaTexture = _renderer.CreateTexture(areaInfo) as TextureView;
|
||||
_searchTexture = _renderer.CreateTexture(searchInfo) as TextureView;
|
||||
|
||||
_areaTexture.SetData(areaTexture);
|
||||
_searchTexture.SetData(searchTexture);
|
||||
_areaTexture?.SetData(areaTexture);
|
||||
_searchTexture?.SetData(searchTexture);
|
||||
}
|
||||
|
||||
public TextureView Run(TextureView view, CommandBufferScoped cbs, int width, int height)
|
||||
|
|
@ -216,7 +216,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||
|
||||
buffer.Holder.SetDataUnchecked(buffer.Offset, resolutionBuffer);
|
||||
_pipeline.SetUniformBuffers([new BufferAssignment(2, buffer.Range)]);
|
||||
_pipeline.SetImage(ShaderStage.Compute, 0, _edgeOutputTexture.GetView(FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)));
|
||||
_pipeline.SetImage(ShaderStage.Compute, 0, _edgeOutputTexture?.GetView(FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)));
|
||||
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
_pipeline.ComputeBarrier();
|
||||
|
||||
|
|
@ -226,7 +226,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 1, _edgeOutputTexture, _samplerLinear);
|
||||
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 3, _areaTexture, _samplerLinear);
|
||||
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 4, _searchTexture, _samplerLinear);
|
||||
_pipeline.SetImage(ShaderStage.Compute, 0, _blendOutputTexture.GetView(FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)));
|
||||
_pipeline.SetImage(ShaderStage.Compute, 0, _blendOutputTexture?.GetView(FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)));
|
||||
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
_pipeline.ComputeBarrier();
|
||||
|
||||
|
|
@ -235,7 +235,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||
_pipeline.Specialize(_specConstants);
|
||||
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 3, _blendOutputTexture, _samplerLinear);
|
||||
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 1, view, _samplerLinear);
|
||||
_pipeline.SetImage(ShaderStage.Compute, 0, _outputTexture.GetView(FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)));
|
||||
_pipeline.SetImage(ShaderStage.Compute, 0, _outputTexture?.GetView(FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)));
|
||||
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
_pipeline.ComputeBarrier();
|
||||
|
||||
|
|
|
|||
|
|
@ -28,15 +28,15 @@ namespace Ryujinx.HLE.Generators
|
|||
continue;
|
||||
var constructors = className.ChildNodes().Where(x => x.IsKind(SyntaxKind.ConstructorDeclaration)).Select(y => y as ConstructorDeclarationSyntax);
|
||||
|
||||
if (!constructors.Any(x => x.ParameterList.Parameters.Count >= 1))
|
||||
if (!constructors.Any(x => x != null && x.ParameterList.Parameters.Count >= 1))
|
||||
continue;
|
||||
|
||||
if (constructors.Where(x => x.ParameterList.Parameters.Count >= 1).FirstOrDefault().ParameterList.Parameters[0].Type.ToString() == "ServiceCtx")
|
||||
if (constructors.FirstOrDefault(x => x != null && x.ParameterList.Parameters.Count >= 1).ParameterList.Parameters[0].Type.ToString() == "ServiceCtx")
|
||||
{
|
||||
generator.EnterScope($"if (type == typeof({GetFullName(className, context)}))");
|
||||
if (constructors.Any(x => x.ParameterList.Parameters.Count == 2))
|
||||
if (constructors.Any(x => x != null && x.ParameterList.Parameters.Count == 2))
|
||||
{
|
||||
var type = constructors.Where(x => x.ParameterList.Parameters.Count == 2).FirstOrDefault().ParameterList.Parameters[1].Type;
|
||||
var type = constructors.FirstOrDefault(x => x != null && x.ParameterList.Parameters.Count == 2).ParameterList.Parameters[1].Type;
|
||||
var model = context.Compilation.GetSemanticModel(type.SyntaxTree);
|
||||
var typeSymbol = model.GetSymbolInfo(type).Symbol as INamedTypeSymbol;
|
||||
var fullName = typeSymbol?.ToString();
|
||||
|
|
@ -45,7 +45,7 @@ namespace Ryujinx.HLE.Generators
|
|||
generator.LeaveScope();
|
||||
}
|
||||
|
||||
if (constructors.Any(x => x.ParameterList.Parameters.Count == 1))
|
||||
if (constructors.Any(x => x != null && x.ParameterList.Parameters.Count == 1))
|
||||
{
|
||||
generator.AppendLine($"return new {GetFullName(className, context)}(context);");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ namespace Ryujinx.HLE.Exceptions
|
|||
while ((frame = trace.GetFrame(i++)) != null)
|
||||
{
|
||||
var method = frame.GetMethod();
|
||||
var declType = method.DeclaringType;
|
||||
var declType = method?.DeclaringType;
|
||||
|
||||
if (typeof(IpcService).IsAssignableFrom(declType))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -551,7 +551,7 @@ namespace Ryujinx.HLE.FileSystem
|
|||
new DirectoryInfo(registeredDirectory).Delete(true);
|
||||
}
|
||||
|
||||
Directory.Move(temporaryDirectory, registeredDirectory);
|
||||
Directory.Move(temporaryDirectory, registeredDirectory ?? string.Empty);
|
||||
|
||||
LoadEntries();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,8 +31,12 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
|||
}
|
||||
}
|
||||
|
||||
if (bytes != null)
|
||||
{
|
||||
writer.Write(bytes);
|
||||
writer.Seek((int)maxSize - bytes.Length, SeekOrigin.Current);
|
||||
}
|
||||
|
||||
writer.Write((uint)text.Length); // String size
|
||||
|
||||
return (uint)text.Length; // Return the cursor position at the end of the text
|
||||
|
|
|
|||
|
|
@ -61,8 +61,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
KernelContext.CriticalSection.Enter();
|
||||
|
||||
if (list.Count != 0)
|
||||
{
|
||||
if (list.First != null)
|
||||
{
|
||||
session = list.First.Value;
|
||||
}
|
||||
|
||||
list.RemoveFirst();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1369,6 +1369,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||
|
||||
LinkedListNode<KPageNode> pageListNode = pageList.Nodes.First;
|
||||
|
||||
if (pageListNode != null)
|
||||
{
|
||||
KPageNode pageNode = pageListNode.Value;
|
||||
|
||||
ulong srcPa = pageNode.Address;
|
||||
|
|
@ -1391,9 +1393,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||
{
|
||||
if (srcPaPages == 0)
|
||||
{
|
||||
pageListNode = pageListNode.Next;
|
||||
pageListNode = pageListNode?.Next;
|
||||
|
||||
if (pageListNode != null)
|
||||
{
|
||||
pageNode = pageListNode.Value;
|
||||
}
|
||||
|
||||
srcPa = pageNode.Address;
|
||||
srcPaPages = pageNode.PagesCount;
|
||||
|
|
@ -1409,6 +1414,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||
dstVaPages -= currentPagesCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PhysicalMemoryUsage += remainingSize;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,10 +33,13 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||
public ref T GetRef<T>(ulong offset) where T : unmanaged
|
||||
{
|
||||
if (_pageList.Nodes.Count == 1)
|
||||
{
|
||||
if (_pageList.Nodes.First != null)
|
||||
{
|
||||
ulong address = _pageList.Nodes.First.Value.Address - DramMemoryMap.DramBase;
|
||||
return ref _context.Memory.GetRef<T>(address + offset);
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotImplementedException("Non-contiguous shared memory is not yet supported.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
|||
|
||||
thread.SiblingsPerCore[core] = queue.AddLast(thread);
|
||||
|
||||
return queue.First.Value;
|
||||
return queue.First?.Value;
|
||||
}
|
||||
|
||||
public void Unschedule(int prio, int core, KThread thread)
|
||||
|
|
|
|||
|
|
@ -1302,7 +1302,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
|||
{
|
||||
Owner?.RemoveThread(this);
|
||||
|
||||
if (_tlsAddress != 0 && Owner.FreeThreadLocalStorage(_tlsAddress) != Result.Success)
|
||||
if (_tlsAddress != 0 && Owner?.FreeThreadLocalStorage(_tlsAddress) != Result.Success)
|
||||
{
|
||||
throw new InvalidOperationException("Unexpected failure freeing thread local storage.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
|||
{
|
||||
HipcSyntaxReceiver syntaxReceiver = (HipcSyntaxReceiver)context.SyntaxReceiver;
|
||||
|
||||
if (syntaxReceiver?.CommandInterfaces != null)
|
||||
{
|
||||
foreach (var commandInterface in syntaxReceiver.CommandInterfaces)
|
||||
{
|
||||
if (!NeedsIServiceObjectImplementation(context.Compilation, commandInterface.ClassDeclarationSyntax))
|
||||
|
|
@ -99,6 +101,7 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
|||
context.AddSource($"{GetNamespaceName(commandInterface.ClassDeclarationSyntax)}.{className}.g.cs", generator.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetNamespaceName(SyntaxNode syntaxNode)
|
||||
{
|
||||
|
|
@ -191,14 +194,18 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
|||
{
|
||||
ISymbol symbol = compilation.GetSemanticModel(syntaxNode.SyntaxTree).GetDeclaredSymbol(syntaxNode);
|
||||
|
||||
if (symbol != null)
|
||||
{
|
||||
foreach (var attribute in symbol.GetAttributes())
|
||||
{
|
||||
if (attribute.AttributeClass.ToDisplayString() == attributeName && (uint)argIndex < (uint)attribute.ConstructorArguments.Length)
|
||||
if (attribute.AttributeClass?.ToDisplayString() == attributeName &&
|
||||
(uint)argIndex < (uint)attribute.ConstructorArguments.Length)
|
||||
{
|
||||
yield return attribute.ConstructorArguments[argIndex].ToCSharpString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetFirstAttributeArgument(Compilation compilation, SyntaxNode syntaxNode, string attributeName, int argIndex)
|
||||
{
|
||||
|
|
@ -507,19 +514,22 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
|||
{
|
||||
TypeInfo typeInfo = compilation.GetSemanticModel(syntaxNode.SyntaxTree).GetTypeInfo(syntaxNode);
|
||||
|
||||
return typeInfo.Type.ToDisplayString();
|
||||
return typeInfo.Type?.ToDisplayString();
|
||||
}
|
||||
|
||||
private static string GetCanonicalTypeName(Compilation compilation, SyntaxNode syntaxNode)
|
||||
{
|
||||
TypeInfo typeInfo = compilation.GetSemanticModel(syntaxNode.SyntaxTree).GetTypeInfo(syntaxNode);
|
||||
string typeName = typeInfo.Type.ToDisplayString();
|
||||
string typeName = typeInfo.Type?.ToDisplayString();
|
||||
|
||||
if (typeName != null)
|
||||
{
|
||||
int genericArgsStartIndex = typeName.IndexOf('<');
|
||||
if (genericArgsStartIndex >= 0)
|
||||
{
|
||||
return typeName.Substring(0, genericArgsStartIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return typeName;
|
||||
}
|
||||
|
|
@ -528,7 +538,7 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
|||
{
|
||||
TypeInfo typeInfo = compilation.GetSemanticModel(syntaxNode.SyntaxTree).GetTypeInfo(syntaxNode);
|
||||
|
||||
return typeInfo.Type.SpecialType;
|
||||
return typeInfo.Type?.SpecialType ?? SpecialType.None;
|
||||
}
|
||||
|
||||
private static string GetTypeAlignmentExpression(Compilation compilation, SyntaxNode syntaxNode)
|
||||
|
|
@ -539,7 +549,7 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
|||
// "special" types are primitive types aligned to their own length.
|
||||
// Otherwise, assume that the type is a custom struct, that either defines an explicit alignment
|
||||
// or has an alignment of 1 which is the lowest possible value.
|
||||
if (typeInfo.Type.SpecialType == SpecialType.None)
|
||||
if (typeInfo.Type is { SpecialType: SpecialType.None })
|
||||
{
|
||||
string pack = GetTypeFirstNamedAttributeAgument(compilation, syntaxNode, TypeStructLayoutAttribute, "Pack");
|
||||
|
||||
|
|
@ -547,7 +557,7 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
|||
}
|
||||
else
|
||||
{
|
||||
return $"Unsafe.SizeOf<{typeInfo.Type.ToDisplayString()}>()";
|
||||
return $"Unsafe.SizeOf<{typeInfo.Type?.ToDisplayString()}>()";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -555,13 +565,13 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
|||
{
|
||||
ISymbol symbol = compilation.GetSemanticModel(syntaxNode.SyntaxTree).GetTypeInfo(syntaxNode).Type;
|
||||
|
||||
if (symbol != null)
|
||||
{
|
||||
foreach (var attribute in symbol.GetAttributes())
|
||||
{
|
||||
if (attribute.AttributeClass.ToDisplayString() == attributeName)
|
||||
if (attribute.AttributeClass?.ToDisplayString() == attributeName)
|
||||
{
|
||||
foreach (var kv in attribute.NamedArguments)
|
||||
{
|
||||
if (kv.Key == argName)
|
||||
foreach (var kv in attribute.NamedArguments.Where(kv => kv.Key == argName))
|
||||
{
|
||||
return kv.Value.ToCSharpString();
|
||||
}
|
||||
|
|
@ -664,7 +674,7 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
|||
{
|
||||
TypeInfo typeInfo = compilation.GetSemanticModel(syntaxNode.SyntaxTree).GetTypeInfo(syntaxNode);
|
||||
|
||||
return typeInfo.Type.IsUnmanagedType;
|
||||
return typeInfo.Type is { IsUnmanagedType: true };
|
||||
}
|
||||
|
||||
private static bool IsMemory(Compilation compilation, ParameterSyntax parameter)
|
||||
|
|
@ -707,10 +717,11 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
|||
private static bool IsObject(Compilation compilation, ParameterSyntax parameter)
|
||||
{
|
||||
SyntaxNode syntaxNode = parameter.Type;
|
||||
TypeInfo typeInfo = compilation.GetSemanticModel(syntaxNode.SyntaxTree).GetTypeInfo(syntaxNode);
|
||||
TypeInfo typeInfo = compilation.GetSemanticModel(syntaxNode!.SyntaxTree).GetTypeInfo(syntaxNode);
|
||||
|
||||
return typeInfo.Type.ToDisplayString() == TypeIServiceObject ||
|
||||
typeInfo.Type.AllInterfaces.Any(x => x.ToDisplayString() == TypeIServiceObject);
|
||||
return typeInfo.Type != null &&
|
||||
(typeInfo.Type.ToDisplayString() == TypeIServiceObject ||
|
||||
typeInfo.Type.AllInterfaces.Any(x => x.ToDisplayString() == TypeIServiceObject));
|
||||
}
|
||||
|
||||
private static bool IsProcessId(Compilation compilation, ParameterSyntax parameter)
|
||||
|
|
@ -781,7 +792,7 @@ namespace Ryujinx.Horizon.Generators.Hipc
|
|||
private static bool NeedsIServiceObjectImplementation(Compilation compilation, ClassDeclarationSyntax classDeclarationSyntax)
|
||||
{
|
||||
ITypeSymbol type = compilation.GetSemanticModel(classDeclarationSyntax.SyntaxTree).GetDeclaredSymbol(classDeclarationSyntax);
|
||||
var serviceObjectInterface = type.AllInterfaces.FirstOrDefault(x => x.ToDisplayString() == TypeIServiceObject);
|
||||
var serviceObjectInterface = type?.AllInterfaces.FirstOrDefault(x => x.ToDisplayString() == TypeIServiceObject);
|
||||
var interfaceMember = serviceObjectInterface?.GetMembers().FirstOrDefault(x => x.Name == "GetCommandHandlers");
|
||||
|
||||
// Return true only if the class implements IServiceObject but does not actually implement the method
|
||||
|
|
|
|||
|
|
@ -147,6 +147,8 @@ namespace Ryujinx.Horizon.Kernel.Generators
|
|||
|
||||
List<SyscallIdAndName> syscalls = [];
|
||||
|
||||
if (syntaxReceiver != null)
|
||||
{
|
||||
foreach (var method in syntaxReceiver.SvcImplementations)
|
||||
{
|
||||
GenerateMethod32(generator, context.Compilation, method);
|
||||
|
|
@ -155,6 +157,8 @@ namespace Ryujinx.Horizon.Kernel.Generators
|
|||
foreach (AttributeSyntax attribute in method.AttributeLists.SelectMany(attributeList =>
|
||||
attributeList.Attributes.Where(attribute =>
|
||||
GetCanonicalTypeName(context.Compilation, attribute) == TypeSvcAttribute)))
|
||||
{
|
||||
if (attribute.ArgumentList != null)
|
||||
{
|
||||
syscalls.AddRange(from attributeArg in attribute.ArgumentList.Arguments
|
||||
where attributeArg.Expression.Kind() == SyntaxKind.NumericLiteralExpression
|
||||
|
|
@ -163,6 +167,8 @@ namespace Ryujinx.Horizon.Kernel.Generators
|
|||
select new SyscallIdAndName((int)numericLiteral.Token.Value, method.Identifier.Text));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
syscalls.Sort();
|
||||
|
||||
|
|
|
|||
|
|
@ -127,7 +127,11 @@ namespace Ryujinx.Horizon.Arp.Ipc
|
|||
return ArpResult.InvalidInstanceId;
|
||||
}
|
||||
|
||||
applicationCertificate = _applicationInstanceManager.Entries[applicationInstanceId].Certificate.Value;
|
||||
ApplicationCertificate? certificate = _applicationInstanceManager.Entries[applicationInstanceId].Certificate;
|
||||
if (certificate != null)
|
||||
{
|
||||
applicationCertificate = certificate.Value;
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -510,7 +510,7 @@ namespace Ryujinx.Input.HLE
|
|||
{
|
||||
var keyboard = KeyboardDriver.GetGamepad("0") as IKeyboard;
|
||||
|
||||
KeyboardStateSnapshot keyboardState = keyboard.GetKeyboardStateSnapshot();
|
||||
KeyboardStateSnapshot keyboardState = keyboard?.GetKeyboardStateSnapshot();
|
||||
|
||||
KeyboardInput hidKeyboard = new()
|
||||
{
|
||||
|
|
@ -520,14 +520,14 @@ namespace Ryujinx.Input.HLE
|
|||
|
||||
foreach (HLEKeyboardMappingEntry entry in _keyMapping)
|
||||
{
|
||||
ulong value = keyboardState.IsPressed(entry.TargetKey) ? 1UL : 0UL;
|
||||
ulong value = keyboardState != null && keyboardState.IsPressed(entry.TargetKey) ? 1UL : 0UL;
|
||||
|
||||
hidKeyboard.Keys[entry.Target / 0x40] |= (value << (entry.Target % 0x40));
|
||||
}
|
||||
|
||||
foreach (HLEKeyboardMappingEntry entry in _keyModifierMapping)
|
||||
{
|
||||
int value = keyboardState.IsPressed(entry.TargetKey) ? 1 : 0;
|
||||
int value = keyboardState != null && keyboardState.IsPressed(entry.TargetKey) ? 1 : 0;
|
||||
|
||||
hidKeyboard.Modifier |= value << entry.Target;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -304,10 +304,13 @@ namespace Ryujinx.Input.HLE
|
|||
buttons |= 1 << 4;
|
||||
}
|
||||
|
||||
if (mouse != null)
|
||||
{
|
||||
var position = IMouse.GetScreenPosition(mouseInput.Position, mouse.ClientSize, aspectRatio);
|
||||
|
||||
_device.Hid.Mouse.Update((int)position.X, (int)position.Y, buttons, (int)mouseInput.Scroll.X, (int)mouseInput.Scroll.Y, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_device.Hid.Mouse.Update(0, 0);
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@ namespace Ryujinx.UI.App.Common
|
|||
private static byte[] GetResourceBytes(string resourceName)
|
||||
{
|
||||
Stream resourceStream = Assembly.GetCallingAssembly().GetManifestResourceStream(resourceName);
|
||||
if (resourceStream != null)
|
||||
{
|
||||
byte[] resourceByteArray = new byte[resourceStream.Length];
|
||||
|
||||
resourceStream.ReadExactly(resourceByteArray);
|
||||
|
|
@ -95,6 +97,9 @@ namespace Ryujinx.UI.App.Common
|
|||
return resourceByteArray;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/// <exception cref="Ryujinx.HLE.Exceptions.InvalidNpdmException">The npdm file doesn't contain valid data.</exception>
|
||||
/// <exception cref="NotImplementedException">The FsAccessHeader.ContentOwnerId section is not implemented.</exception>
|
||||
/// <exception cref="ArgumentException">An error occured while reading bytes from the stream.</exception>
|
||||
|
|
@ -1178,7 +1183,7 @@ namespace Ryujinx.UI.App.Common
|
|||
{
|
||||
string extension = Path.GetExtension(applicationPath)?.ToLower();
|
||||
|
||||
using FileStream file = new(applicationPath, FileMode.Open, FileAccess.Read);
|
||||
using FileStream file = new(applicationPath ?? string.Empty, FileMode.Open, FileAccess.Read);
|
||||
|
||||
if (extension == ".nsp" || extension == ".pfs0" || extension == ".xci")
|
||||
{
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ namespace Ryujinx.UI.Common.Helper
|
|||
|
||||
Logger.Debug?.Print(LogClass.Application, $"Adding type association {ext}");
|
||||
using var openCmd = key.CreateSubKey(@"shell\open\command");
|
||||
openCmd.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\"");
|
||||
openCmd?.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\"");
|
||||
Logger.Debug?.Print(LogClass.Application, $"Added type association {ext}");
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,11 +36,11 @@ namespace Ryujinx.UI.Common.SystemInfo
|
|||
{
|
||||
foreach (var cpuObj in cpuObjs)
|
||||
{
|
||||
return cpuObj["Name"].ToString().Trim();
|
||||
return cpuObj["Name"].ToString()?.Trim();
|
||||
}
|
||||
}
|
||||
|
||||
return Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER").Trim();
|
||||
return Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER")?.Trim();
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ namespace Ryujinx.Ava
|
|||
if (result == UserResult.Yes)
|
||||
{
|
||||
var path = Environment.ProcessPath;
|
||||
var proc = Process.Start(path, CommandLineState.Arguments);
|
||||
var proc = Process.Start(path ?? string.Empty, CommandLineState.Arguments);
|
||||
desktop.Shutdown();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
|
@ -144,7 +144,7 @@ namespace Ryujinx.Ava
|
|||
|
||||
public static ThemeVariant DetectSystemTheme()
|
||||
{
|
||||
if (Current is App app)
|
||||
if (Current is App { PlatformSettings: not null } app)
|
||||
{
|
||||
var colorValues = app.PlatformSettings.GetColorValues();
|
||||
|
||||
|
|
|
|||
|
|
@ -192,8 +192,11 @@ namespace Ryujinx.Modules
|
|||
|
||||
HttpResponseMessage message = await buildSizeClient.GetAsync(new Uri(_buildUrl), HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
if (message.Content.Headers.ContentRange?.Length != null)
|
||||
{
|
||||
_buildSize = message.Content.Headers.ContentRange.Length.Value;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Application, ex.Message);
|
||||
|
|
@ -375,17 +378,23 @@ namespace Ryujinx.Modules
|
|||
}
|
||||
|
||||
client.DownloadProgressChanged += (_, args) =>
|
||||
{
|
||||
if (args.UserState != null)
|
||||
{
|
||||
int index = (int)args.UserState;
|
||||
|
||||
Interlocked.Add(ref totalProgressPercentage, -1 * progressPercentage[index]);
|
||||
Interlocked.Exchange(ref progressPercentage[index], args.ProgressPercentage);
|
||||
}
|
||||
|
||||
Interlocked.Add(ref totalProgressPercentage, args.ProgressPercentage);
|
||||
|
||||
taskDialog.SetProgressBarState(totalProgressPercentage / ConnectionCount, TaskDialogProgressState.Normal);
|
||||
};
|
||||
|
||||
client.DownloadDataCompleted += (_, args) =>
|
||||
{
|
||||
if (args.UserState != null)
|
||||
{
|
||||
int index = (int)args.UserState;
|
||||
|
||||
|
|
@ -399,6 +408,8 @@ namespace Ryujinx.Modules
|
|||
}
|
||||
|
||||
list[index] = args.Result;
|
||||
}
|
||||
|
||||
Interlocked.Increment(ref completedRequests);
|
||||
|
||||
if (Equals(completedRequests, ConnectionCount))
|
||||
|
|
@ -465,6 +476,8 @@ namespace Ryujinx.Modules
|
|||
using Stream remoteFileStream = response.Content.ReadAsStreamAsync().Result;
|
||||
using Stream updateFileStream = File.Open(updateFile, FileMode.Create);
|
||||
|
||||
if (response.Content.Headers.ContentLength != null)
|
||||
{
|
||||
long totalBytes = response.Content.Headers.ContentLength.Value;
|
||||
long byteWritten = 0;
|
||||
|
||||
|
|
@ -485,6 +498,7 @@ namespace Ryujinx.Modules
|
|||
|
||||
updateFileStream.Write(buffer, 0, readSize);
|
||||
}
|
||||
}
|
||||
|
||||
InstallUpdate(taskDialog, updateFile);
|
||||
}
|
||||
|
|
@ -524,7 +538,7 @@ namespace Ryujinx.Modules
|
|||
|
||||
string outPath = Path.Combine(outputDirectoryPath, tarEntry.Name);
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(outPath));
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(outPath) ?? string.Empty);
|
||||
|
||||
using FileStream outStream = File.OpenWrite(outPath);
|
||||
tarStream.CopyEntryContents(outStream);
|
||||
|
|
@ -560,7 +574,7 @@ namespace Ryujinx.Modules
|
|||
|
||||
string outPath = Path.Combine(outputDirectoryPath, zipEntry.Name);
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(outPath));
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(outPath) ?? string.Empty);
|
||||
|
||||
using Stream zipStream = zipFile.GetInputStream(zipEntry);
|
||||
using FileStream outStream = File.OpenWrite(outPath);
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ namespace Ryujinx.Ava.UI.Applet
|
|||
{
|
||||
_parent = parent;
|
||||
|
||||
(_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyPressed += AvaloniaDynamicTextInputHandler_KeyPressed;
|
||||
(_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyRelease += AvaloniaDynamicTextInputHandler_KeyRelease;
|
||||
(_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).TextInput += AvaloniaDynamicTextInputHandler_TextInput;
|
||||
((AvaloniaKeyboardDriver)_parent.InputManager.KeyboardDriver).KeyPressed += AvaloniaDynamicTextInputHandler_KeyPressed;
|
||||
((AvaloniaKeyboardDriver)_parent.InputManager.KeyboardDriver).KeyRelease += AvaloniaDynamicTextInputHandler_KeyRelease;
|
||||
((AvaloniaKeyboardDriver)_parent.InputManager.KeyboardDriver).TextInput += AvaloniaDynamicTextInputHandler_TextInput;
|
||||
|
||||
_hiddenTextBox = _parent.HiddenTextBox;
|
||||
|
||||
|
|
@ -118,9 +118,9 @@ namespace Ryujinx.Ava.UI.Applet
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
(_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyPressed -= AvaloniaDynamicTextInputHandler_KeyPressed;
|
||||
(_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyRelease -= AvaloniaDynamicTextInputHandler_KeyRelease;
|
||||
(_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).TextInput -= AvaloniaDynamicTextInputHandler_TextInput;
|
||||
((AvaloniaKeyboardDriver)_parent.InputManager.KeyboardDriver).KeyPressed -= AvaloniaDynamicTextInputHandler_KeyPressed;
|
||||
((AvaloniaKeyboardDriver)_parent.InputManager.KeyboardDriver).KeyRelease -= AvaloniaDynamicTextInputHandler_KeyRelease;
|
||||
((AvaloniaKeyboardDriver)_parent.InputManager.KeyboardDriver).TextInput -= AvaloniaDynamicTextInputHandler_TextInput;
|
||||
|
||||
_textChangedSubscription?.Dispose();
|
||||
_selectionStartChangedSubscription?.Dispose();
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
viewModel.VirtualFileSystem,
|
||||
viewModel.SelectedApplication.IdString,
|
||||
viewModel.SelectedApplication.Name,
|
||||
viewModel.SelectedApplication.Path).ShowDialog(viewModel.TopLevel as Window);
|
||||
viewModel.SelectedApplication.Path).ShowDialog((Window)viewModel.TopLevel);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -396,11 +396,14 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
viewModel.SelectedApplication.Name);
|
||||
|
||||
var iconFile = await result[0].CreateFileAsync(selectedApp.IdString + ".png");
|
||||
if (iconFile != null)
|
||||
{
|
||||
await using var fileStream = await iconFile.OpenWriteAsync();
|
||||
|
||||
fileStream.Write(selectedApp.Icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateApplicationShortcut_Click(object sender, RoutedEventArgs args)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
|
||||
private void SearchBox_OnKeyUp(object sender, KeyEventArgs args)
|
||||
{
|
||||
(DataContext as MainWindowViewModel).SearchText = (sender as TextBox).Text;
|
||||
(DataContext as MainWindowViewModel).SearchText = (sender as TextBox)?.Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ namespace Ryujinx.Ava.UI.Controls
|
|||
|
||||
private void SearchBox_OnKeyUp(object sender, KeyEventArgs args)
|
||||
{
|
||||
(DataContext as MainWindowViewModel).SearchText = (sender as TextBox).Text;
|
||||
(DataContext as MainWindowViewModel).SearchText = (sender as TextBox)?.Text;
|
||||
}
|
||||
|
||||
private async void IdString_OnClick(object sender, RoutedEventArgs e)
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ namespace Ryujinx.Ava.UI.Models
|
|||
|
||||
if (InGameList)
|
||||
{
|
||||
Icon = appData.Icon;
|
||||
Title = appData.Name;
|
||||
Icon = appData?.Icon;
|
||||
Title = appData?.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ namespace Ryujinx.Ava.UI.Models
|
|||
private void UpdateBackground()
|
||||
{
|
||||
var currentApplication = Avalonia.Application.Current;
|
||||
currentApplication.Styles.TryGetResource("ControlFillColorSecondary", currentApplication.ActualThemeVariant, out object color);
|
||||
currentApplication!.Styles.TryGetResource("ControlFillColorSecondary", currentApplication.ActualThemeVariant, out object color);
|
||||
|
||||
if (color is not null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -127,8 +127,11 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||
X11Window = PlatformHelper.CreateOpenGLWindow(new FramebufferFormat(new ColorFormat(8, 8, 8, 0), 16, 0, ColorFormat.Zero, 0, 2, false), 0, 0, 100, 100) as GLXWindow;
|
||||
}
|
||||
|
||||
if (X11Window != null)
|
||||
{
|
||||
WindowHandle = X11Window.WindowHandle.RawHandle;
|
||||
X11Display = X11Window.DisplayHandle.RawHandle;
|
||||
}
|
||||
|
||||
return new PlatformHandle(WindowHandle, "X11");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
return app.Favorite ? -1 : 1;
|
||||
}
|
||||
|
||||
throw new InvalidCastException($"Cannot cast {o.GetType()} to {nameof(AppListFavoriteComparable)}");
|
||||
throw new InvalidCastException($"Cannot cast {o?.GetType()} to {nameof(AppListFavoriteComparable)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,9 +92,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
_applicationData = applicationData;
|
||||
|
||||
if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
_storageProvider = desktop.MainWindow.StorageProvider;
|
||||
_storageProvider = desktop.MainWindow?.StorageProvider;
|
||||
}
|
||||
|
||||
LoadDownloadableContents();
|
||||
|
|
|
|||
|
|
@ -254,10 +254,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||
|
||||
AvaloniaKeyboardDriver = new AvaloniaKeyboardDriver(owner);
|
||||
|
||||
if (_mainWindow != null)
|
||||
{
|
||||
_mainWindow.InputManager.GamepadDriver.OnGamepadConnected += HandleOnGamepadConnected;
|
||||
_mainWindow.InputManager.GamepadDriver.OnGamepadDisconnected += HandleOnGamepadDisconnected;
|
||||
|
||||
_mainWindow.ViewModel.AppHost?.NpadManager.BlockInputUpdates();
|
||||
}
|
||||
|
||||
_isLoaded = false;
|
||||
|
||||
|
|
@ -783,11 +786,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||
config = (ConfigViewModel as ControllerInputViewModel)?.Config.GetConfig();
|
||||
}
|
||||
|
||||
if (config != null)
|
||||
{
|
||||
config.ControllerType = Controllers[_controller].Type;
|
||||
|
||||
string jsonString = JsonHelper.Serialize(config, _serializerContext.InputConfig);
|
||||
|
||||
await File.WriteAllTextAsync(path, jsonString);
|
||||
}
|
||||
|
||||
LoadProfiles();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1332,7 +1332,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
}
|
||||
catch (MissingKeyException ex)
|
||||
{
|
||||
if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Application, ex.ToString());
|
||||
|
||||
|
|
@ -1553,7 +1553,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
{
|
||||
Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
Application.Current.Styles.TryGetResource(args.VSyncMode,
|
||||
Application.Current!.Styles.TryGetResource(args.VSyncMode,
|
||||
Application.Current.ActualThemeVariant,
|
||||
out object color);
|
||||
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
foreach (var dir in directories)
|
||||
{
|
||||
string dirToCreate = dir.Replace(directory.Parent.ToString(), destinationDir);
|
||||
string dirToCreate = dir.Replace(directory.Parent?.ToString() ?? string.Empty, destinationDir);
|
||||
|
||||
// Mod already exists
|
||||
if (Directory.Exists(dirToCreate))
|
||||
|
|
@ -302,7 +302,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
foreach (var file in files)
|
||||
{
|
||||
File.Copy(file, file.Replace(directory.Parent.ToString(), destinationDir), true);
|
||||
File.Copy(file, file.Replace(directory.Parent?.ToString() ?? string.Empty, destinationDir), true);
|
||||
}
|
||||
|
||||
LoadMods(_applicationId, _installedDlcIds);
|
||||
|
|
|
|||
|
|
@ -75,9 +75,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
ApplicationData = applicationData;
|
||||
|
||||
if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
StorageProvider = desktop.MainWindow.StorageProvider;
|
||||
StorageProvider = desktop.MainWindow?.StorageProvider;
|
||||
}
|
||||
|
||||
LoadUpdates();
|
||||
|
|
|
|||
|
|
@ -268,7 +268,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
result = String.Compare(x?.Name, y?.Name, StringComparison.Ordinal);
|
||||
break;
|
||||
case SortField.Saved:
|
||||
if (x != null && y != null)
|
||||
{
|
||||
result = x.PotentialSavingsB.CompareTo(y.PotentialSavingsB);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,11 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
{
|
||||
|
||||
var viewModel = (DataContext as ControllerInputViewModel);
|
||||
if (viewModel != null)
|
||||
{
|
||||
viewModel.ParentModel.IsModified = true;
|
||||
}
|
||||
|
||||
_changeSlider = (float)check.Value;
|
||||
}
|
||||
}
|
||||
|
|
@ -82,9 +86,11 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
{
|
||||
if ((bool)check.IsPointerOver)
|
||||
{
|
||||
|
||||
var viewModel = (DataContext as ControllerInputViewModel);
|
||||
if (DataContext is ControllerInputViewModel viewModel)
|
||||
{
|
||||
viewModel.ParentModel.IsModified = true;
|
||||
}
|
||||
|
||||
_currentAssigner?.Cancel();
|
||||
_currentAssigner = null;
|
||||
}
|
||||
|
|
@ -96,7 +102,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
{
|
||||
if (sender is ToggleButton button )
|
||||
{
|
||||
if ((bool)button.IsChecked)
|
||||
if (button.IsChecked != null && (bool)button.IsChecked)
|
||||
{
|
||||
if (_currentAssigner != null && button == _currentAssigner.ToggledButton)
|
||||
{
|
||||
|
|
@ -233,7 +239,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
var controllerInputViewModel = DataContext as ControllerInputViewModel;
|
||||
|
||||
assigner = new GamepadButtonAssigner(
|
||||
controllerInputViewModel.ParentModel.SelectedGamepad,
|
||||
controllerInputViewModel?.ParentModel.SelectedGamepad,
|
||||
(controllerInputViewModel.ParentModel.Config as StandardControllerInputConfig).TriggerThreshold,
|
||||
forStick);
|
||||
|
||||
|
|
|
|||
|
|
@ -72,10 +72,13 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
{
|
||||
ViewModel.IsModified = true;
|
||||
var player = (PlayerModel)e.AddedItems[0];
|
||||
if (player != null)
|
||||
{
|
||||
ViewModel.PlayerId = player.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
{
|
||||
if (sender is ToggleButton button)
|
||||
{
|
||||
if ((bool)button.IsChecked)
|
||||
if (button.IsChecked != null && (bool)button.IsChecked)
|
||||
{
|
||||
if (_currentAssigner != null && button == _currentAssigner.ToggledButton)
|
||||
{
|
||||
|
|
@ -60,6 +60,8 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
|
||||
var viewModel = (DataContext as KeyboardInputViewModel);
|
||||
|
||||
if (viewModel != null)
|
||||
{
|
||||
IKeyboard keyboard = (IKeyboard)viewModel.ParentModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
|
||||
IButtonAssigner assigner = CreateButtonAssigner();
|
||||
|
||||
|
|
@ -162,6 +164,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
|
||||
_currentAssigner.GetInputAndAssign(assigner, keyboard);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_currentAssigner != null)
|
||||
|
|
@ -193,7 +196,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||
{
|
||||
IButtonAssigner assigner;
|
||||
|
||||
assigner = new KeyboardKeyAssigner((IKeyboard)(DataContext as KeyboardInputViewModel).ParentModel.SelectedGamepad);
|
||||
assigner = new KeyboardKeyAssigner((IKeyboard)(DataContext as KeyboardInputViewModel)?.ParentModel.SelectedGamepad);
|
||||
|
||||
return assigner;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||
{
|
||||
if (sender is RadioButton button)
|
||||
{
|
||||
ViewModel.Sort(Enum.Parse<ApplicationSort>(button.Tag.ToString()));
|
||||
ViewModel.Sort(Enum.Parse<ApplicationSort>(button.Tag?.ToString() ?? string.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||
{
|
||||
if (sender is RadioButton button)
|
||||
{
|
||||
ViewModel.Sort(button.Tag.ToString() != "Descending");
|
||||
ViewModel.Sort(button.Tag?.ToString() != "Descending");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace Ryujinx.Ava.UI.Views.Settings
|
|||
{
|
||||
if (sender is ToggleButton button)
|
||||
{
|
||||
if ((bool)button.IsChecked)
|
||||
if (button.IsChecked != null && (bool)button.IsChecked)
|
||||
{
|
||||
if (_currentAssigner != null && button == _currentAssigner.ToggledButton)
|
||||
{
|
||||
|
|
@ -69,6 +69,8 @@ namespace Ryujinx.Ava.UI.Views.Settings
|
|||
var viewModel = (DataContext) as SettingsViewModel;
|
||||
var buttonValue = e.ButtonValue.Value;
|
||||
|
||||
if (viewModel != null)
|
||||
{
|
||||
switch (button.Name)
|
||||
{
|
||||
case "ToggleVSyncMode":
|
||||
|
|
@ -106,6 +108,7 @@ namespace Ryujinx.Ava.UI.Views.Settings
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_currentAssigner.GetInputAndAssign(assigner, keyboard);
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ namespace Ryujinx.Ava.UI.Views.User
|
|||
private async void Import_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var window = this.GetVisualRoot() as Window;
|
||||
var result = await window.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
var result = await window?.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false,
|
||||
FileTypeFilter = new List<FilePickerFileType>
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ namespace Ryujinx.Ava.UI.Views.User
|
|||
|
||||
private void Close(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((ContentDialog)_parent.Parent).Hide();
|
||||
((ContentDialog)_parent.Parent)?.Hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
}
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(_enabledCheatsPath));
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(_enabledCheatsPath) ?? string.Empty);
|
||||
|
||||
File.WriteAllLines(_enabledCheatsPath, enabledCheats);
|
||||
|
||||
|
|
|
|||
|
|
@ -53,12 +53,12 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
private void SaveAndClose(object sender, RoutedEventArgs routedEventArgs)
|
||||
{
|
||||
ViewModel.Save();
|
||||
((ContentDialog)Parent).Hide();
|
||||
((ContentDialog)Parent)?.Hide();
|
||||
}
|
||||
|
||||
private void Close(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((ContentDialog)Parent).Hide();
|
||||
((ContentDialog)Parent)?.Hide();
|
||||
}
|
||||
|
||||
private void RemoveDLC(object sender, RoutedEventArgs e)
|
||||
|
|
|
|||
|
|
@ -494,7 +494,10 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
/// <summary>
|
||||
/// Subscribe to the ColorValuesChanged event
|
||||
/// </summary>
|
||||
if (PlatformSettings != null)
|
||||
{
|
||||
PlatformSettings.ColorValuesChanged += OnPlatformColorValuesChanged;
|
||||
}
|
||||
|
||||
ViewModel.Initialize(
|
||||
ContentManager,
|
||||
|
|
@ -578,7 +581,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
var volumeSplitButton = sender as ToggleSplitButton;
|
||||
if (ViewModel.IsGameRunning)
|
||||
{
|
||||
if (!volumeSplitButton.IsChecked)
|
||||
if (volumeSplitButton is not { IsChecked: true })
|
||||
{
|
||||
ViewModel.AppHost.Device.SetVolume(ViewModel.VolumeBeforeMute);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,12 +53,12 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
private void SaveAndClose(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.Save();
|
||||
((ContentDialog)Parent).Hide();
|
||||
((ContentDialog)Parent)?.Hide();
|
||||
}
|
||||
|
||||
private void Close(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((ContentDialog)Parent).Hide();
|
||||
((ContentDialog)Parent)?.Hide();
|
||||
}
|
||||
|
||||
private async void DeleteMod(object sender, RoutedEventArgs e)
|
||||
|
|
|
|||
|
|
@ -50,14 +50,14 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
private void Close(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((ContentDialog)Parent).Hide();
|
||||
((ContentDialog)Parent)?.Hide();
|
||||
}
|
||||
|
||||
public void Save(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.Save();
|
||||
|
||||
((ContentDialog)Parent).Hide();
|
||||
((ContentDialog)Parent)?.Hide();
|
||||
}
|
||||
|
||||
private void OpenLocation(object sender, RoutedEventArgs e)
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
private void Close(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((ContentDialog)Parent).Hide();
|
||||
((ContentDialog)Parent)?.Hide();
|
||||
}
|
||||
|
||||
private void Cancel(Object sender, RoutedEventArgs e)
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ namespace Spv.Generator
|
|||
|
||||
public bool Equals(Instruction cmpObj)
|
||||
{
|
||||
bool result = Type == cmpObj.Type && Id == cmpObj.Id;
|
||||
bool result = cmpObj != null && Type == cmpObj.Type && Id == cmpObj.Id;
|
||||
|
||||
if (result)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ namespace Spv.Generator
|
|||
|
||||
public bool Equals(LiteralInteger cmpObj)
|
||||
{
|
||||
return Type == cmpObj.Type && _integerType == cmpObj._integerType && _data == cmpObj._data;
|
||||
return cmpObj != null && Type == cmpObj.Type && _integerType == cmpObj._integerType && _data == cmpObj._data;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ namespace Spv.Generator
|
|||
|
||||
public bool Equals(LiteralString cmpObj)
|
||||
{
|
||||
return Type == cmpObj.Type && _value.Equals(cmpObj._value);
|
||||
return cmpObj != null && Type == cmpObj.Type && _value.Equals(cmpObj._value);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue