Compare commits

..

8 Commits

Author SHA1 Message Date
gnisman
b402b4e7f6 Change GetPageSize to use Environment.SystemPageSize (#4291)
* Change GetPageSize to use Environment.SystemPageSize

* Fix PR comment
2023-01-14 15:37:04 -03:00
gdkchan
93df366b2c Fix texture flush from CPU WaitSync regression on OpenGL (#4289) 2023-01-14 11:23:57 -03:00
gdkchan
cd3a15aea5 Fix NRE when MemoryUnmappedHandler is called for a destroyed channel (#4285) 2023-01-14 00:16:06 -03:00
gdkchan
070136b3f7 Fix texture modified on CPU from GPU thread after being modified on GPU not being updated (#4284) 2023-01-13 23:46:45 -03:00
Ac_K
08ab47c6c0 Update Program.cs 2023-01-13 07:56:41 +01:00
Ac_K
85faa9d8fa Revert "Relax Vulkan requirements (#4228)" (#4279)
This reverts commit dca5b14493.
2023-01-13 06:04:59 +00:00
gdkchan
dca5b14493 Relax Vulkan requirements (#4228) 2023-01-13 06:09:48 +01:00
Ac_K
4d2c8e2a44 Prepo: Fix SaveSystemReport* IPC definitions (#4278)
* Prepo: Fix SaveSystemReport IPC definitions

* Follow original code

* Fix args index in HipcGenerator

* Addresses feedback

* oops
2023-01-13 01:50:14 +01:00
11 changed files with 108 additions and 48 deletions

View File

@@ -28,7 +28,7 @@ namespace Ryujinx.Ava
public static double DesktopScaleFactor { get; set; } = 1.0;
public static string Version { get; private set; }
public static string ConfigurationPath { get; private set; }
public static bool PreviewerDetached { get; private set; }
public static bool PreviewerDetached { get; private set; }
[LibraryImport("user32.dll", SetLastError = true)]
public static partial int MessageBoxA(IntPtr hWnd, [MarshalAs(UnmanagedType.LPStr)] string text, [MarshalAs(UnmanagedType.LPStr)] string caption, uint type);
@@ -276,4 +276,4 @@ namespace Ryujinx.Ava
Logger.Shutdown();
}
}
}
}

View File

@@ -73,7 +73,7 @@ namespace Ryujinx.Graphics.Gpu
// Since the memory manager changed, make sure we will get pools from addresses of the new memory manager.
TextureManager.ReloadPools();
MemoryManager.Physical.BufferCache.QueuePrune();
memoryManager.Physical.BufferCache.QueuePrune();
}
/// <summary>
@@ -84,7 +84,9 @@ namespace Ryujinx.Graphics.Gpu
private void MemoryUnmappedHandler(object sender, UnmapEventArgs e)
{
TextureManager.ReloadPools();
MemoryManager.Physical.BufferCache.QueuePrune();
var memoryManager = Volatile.Read(ref _memoryManager);
memoryManager?.Physical.BufferCache.QueuePrune();
}
/// <summary>

View File

@@ -1431,9 +1431,20 @@ namespace Ryujinx.Graphics.Gpu.Image
return;
}
bool isGpuThread = _context.IsGpuThread();
if (isGpuThread)
{
// No need to wait if we're on the GPU thread, we can just clear the modified flag immediately.
handle.Modified = false;
}
_context.Renderer.BackgroundContextAction(() =>
{
handle.Sync(_context);
if (!isGpuThread)
{
handle.Sync(_context);
}
Storage.SignalModifiedDirty();

View File

@@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// A tracking handle for a texture group, which represents a range of views in a storage texture.
/// Retains a list of overlapping texture views, a modified flag, and tracking for each
/// CPU VA range that the views cover.
/// Also tracks copy dependencies for the handle - references to other handles that must be kept
/// Also tracks copy dependencies for the handle - references to other handles that must be kept
/// in sync with this one before use.
/// </summary>
class TextureGroupHandle : IDisposable
@@ -232,32 +232,23 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="context">The GPU context used to wait for sync</param>
public void Sync(GpuContext context)
{
bool needsSync = !context.IsGpuThread();
ulong registeredSync = _registeredSync;
long diff = (long)(context.SyncNumber - registeredSync);
if (needsSync)
if (diff > 0)
{
ulong registeredSync = _registeredSync;
long diff = (long)(context.SyncNumber - registeredSync);
context.Renderer.WaitSync(registeredSync);
if (diff > 0)
if ((long)(_modifiedSync - registeredSync) > 0)
{
context.Renderer.WaitSync(registeredSync);
if ((long)(_modifiedSync - registeredSync) > 0)
{
// Flush the data in a previous state. Do not remove the modified flag - it will be removed to ignore following writes.
return;
}
Modified = false;
// Flush the data in a previous state. Do not remove the modified flag - it will be removed to ignore following writes.
return;
}
// If the difference is <= 0, no data is not ready yet. Flush any data we can without waiting or removing modified flag.
}
else
{
Modified = false;
}
// If the difference is <= 0, no data is not ready yet. Flush any data we can without waiting or removing modified flag.
}
/// <summary>

View File

@@ -267,6 +267,8 @@ namespace Ryujinx.Horizon.Generators.Hipc
}
int index = 0;
int inArgIndex = 0;
int outArgIndex = 0;
int inCopyHandleIndex = 0;
int inMoveHandleIndex = 0;
int inObjectIndex = 0;
@@ -284,7 +286,7 @@ namespace Ryujinx.Horizon.Generators.Hipc
{
if (IsNonSpanOutBuffer(compilation, parameter))
{
generator.AppendLine($"using var {argName} = CommandSerialization.GetWritableRegion(processor.GetBufferRange({index}));");
generator.AppendLine($"using var {argName} = CommandSerialization.GetWritableRegion(processor.GetBufferRange({outArgIndex++}));");
argName = $"out {GenerateSpanCastElement0(canonicalTypeName, $"{argName}.Memory.Span")}";
}
@@ -302,7 +304,7 @@ namespace Ryujinx.Horizon.Generators.Hipc
switch (argType)
{
case CommandArgType.InArgument:
value = $"CommandSerialization.DeserializeArg<{canonicalTypeName}>(inRawData, processor.GetInArgOffset({index}))";
value = $"CommandSerialization.DeserializeArg<{canonicalTypeName}>(inRawData, processor.GetInArgOffset({inArgIndex++}))";
break;
case CommandArgType.InCopyHandle:
value = $"CommandSerialization.DeserializeCopyHandle(ref context, {inCopyHandleIndex++})";

View File

@@ -42,7 +42,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc
return PrepoResult.PermissionDenied;
}
ProcessPlayReport(PlayReportKind.Normal, pid, gameRoomBuffer, reportBuffer, Uid.Null);
ProcessPlayReport(PlayReportKind.Normal, gameRoomBuffer, reportBuffer, pid, Uid.Null);
return Result.Success;
}
@@ -57,7 +57,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc
return PrepoResult.PermissionDenied;
}
ProcessPlayReport(PlayReportKind.Normal, pid, gameRoomBuffer, reportBuffer, userId, true);
ProcessPlayReport(PlayReportKind.Normal, gameRoomBuffer, reportBuffer, pid, userId, true);
return Result.Success;
}
@@ -107,25 +107,25 @@ namespace Ryujinx.Horizon.Prepo.Ipc
}
[CmifCommand(20100)]
public Result SaveSystemReport([Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer, [ClientProcessId] ulong pid)
public Result SaveSystemReport([Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, Sdk.Ncm.ApplicationId applicationId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer)
{
if ((_permissionLevel & PrepoServicePermissionLevel.System) != 0)
{
return PrepoResult.PermissionDenied;
}
return ProcessPlayReport(PlayReportKind.System, pid, gameRoomBuffer, reportBuffer, Uid.Null);
return ProcessPlayReport(PlayReportKind.System, gameRoomBuffer, reportBuffer, 0, Uid.Null, false, applicationId);
}
[CmifCommand(20101)]
public Result SaveSystemReportWithUser(Uid userId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer, [ClientProcessId] ulong pid)
public Result SaveSystemReportWithUser(Uid userId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, Sdk.Ncm.ApplicationId applicationId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer)
{
if ((_permissionLevel & PrepoServicePermissionLevel.System) != 0)
{
return PrepoResult.PermissionDenied;
}
return ProcessPlayReport(PlayReportKind.System, pid, gameRoomBuffer, reportBuffer, userId, true);
return ProcessPlayReport(PlayReportKind.System, gameRoomBuffer, reportBuffer, 0, userId, true, applicationId);
}
[CmifCommand(40100)] // 2.0.0+
@@ -164,7 +164,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc
return PrepoResult.PermissionDenied;
}
private static Result ProcessPlayReport(PlayReportKind playReportKind, ulong pid, ReadOnlySpan<byte> gameRoomBuffer, ReadOnlySpan<byte> reportBuffer, Uid userId, bool withUserId = false)
private static Result ProcessPlayReport(PlayReportKind playReportKind, ReadOnlySpan<byte> gameRoomBuffer, ReadOnlySpan<byte> reportBuffer, ulong pid, Uid userId, bool withUserId = false, Sdk.Ncm.ApplicationId applicationId = default)
{
if (withUserId)
{
@@ -191,16 +191,23 @@ namespace Ryujinx.Horizon.Prepo.Ipc
return PrepoResult.InvalidBufferSize;
}
// NOTE: The service calls arp:r using the pid to get the application id, if it fails PrepoResult.InvalidPid is returned.
// Reports are stored internally and an event is signaled to transmit them.
StringBuilder builder = new();
MessagePackObject deserializedReport = MessagePackSerializer.UnpackMessagePackObject(reportBuffer.ToArray());
builder.AppendLine();
builder.AppendLine("PlayReport log:");
builder.AppendLine($" Kind: {playReportKind}");
builder.AppendLine($" Pid: {pid}");
// NOTE: The service calls arp:r using the pid to get the application id, if it fails PrepoResult.InvalidPid is returned.
// Reports are stored internally and an event is signaled to transmit them.
if (pid != 0)
{
builder.AppendLine($" Pid: {pid}");
}
else
{
builder.AppendLine($" ApplicationId: {applicationId}");
}
if (!userId.IsNull)
{

View File

@@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.Horizon.Sdk.Account
{
[StructLayout(LayoutKind.Sequential)]
public readonly record struct Uid
readonly record struct Uid
{
public readonly long High;
public readonly long Low;

View File

@@ -0,0 +1,52 @@
namespace Ryujinx.Horizon.Sdk.Ncm
{
readonly struct ApplicationId
{
public readonly ulong Id;
public static int Length => sizeof(ulong);
public static ApplicationId First => new(0x0100000000010000);
public static ApplicationId Last => new(0x01FFFFFFFFFFFFFF);
public static ApplicationId Invalid => new(0);
public bool IsValid => Id >= First.Id && Id <= Last.Id;
public ApplicationId(ulong id)
{
Id = id;
}
public override bool Equals(object obj)
{
return obj is ApplicationId applicationId && applicationId.Equals(this);
}
public bool Equals(ApplicationId other)
{
return other.Id == Id;
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
public static bool operator ==(ApplicationId lhs, ApplicationId rhs)
{
return lhs.Equals(rhs);
}
public static bool operator !=(ApplicationId lhs, ApplicationId rhs)
{
return !lhs.Equals(rhs);
}
public override string ToString()
{
return $"0x{Id:x}";
}
}
}

View File

@@ -12,8 +12,8 @@ namespace Ryujinx.Horizon.Sdk.Prepo
Result RequestImmediateTransmission();
Result GetTransmissionStatus(out int status);
Result GetSystemSessionId(out ulong systemSessionId);
Result SaveSystemReport(ReadOnlySpan<byte> gameRoomBuffer, ReadOnlySpan<byte> reportBuffer, ulong pid);
Result SaveSystemReportWithUser(Uid userId, ReadOnlySpan<byte> gameRoomBuffer, ReadOnlySpan<byte> reportBuffer, ulong pid);
Result SaveSystemReport(ReadOnlySpan<byte> gameRoomBuffer, Ncm.ApplicationId applicationId, ReadOnlySpan<byte> reportBuffer);
Result SaveSystemReportWithUser(Uid userId, ReadOnlySpan<byte> gameRoomBuffer, Ncm.ApplicationId applicationId, ReadOnlySpan<byte> reportBuffer);
Result IsUserAgreementCheckEnabled(out bool enabled);
Result SetUserAgreementCheckEnabled(bool enabled);
}

View File

@@ -8,7 +8,7 @@ namespace Ryujinx.Horizon.Sdk.Sm
{
public static ServiceName Invalid { get; } = new ServiceName(0);
public bool IsInvalid => Packed == 0;
public bool IsValid => Packed != 0;
public int Length => sizeof(ulong);

View File

@@ -435,12 +435,7 @@ namespace Ryujinx.Memory
public static ulong GetPageSize()
{
if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
{
return 1UL << 14;
}
return 1UL << 12;
return (ulong)Environment.SystemPageSize;
}
private static void ThrowInvalidMemoryRegionException() => throw new InvalidMemoryRegionException();