[AGC/Vulkan] Extend PS5 runtime and rendering compatibility (#216)

* [Core] Add POSIX native execution and PS5 SELF support

Extend the native backend, guest TLS, fixed-address memory, and loader paths needed by PS5 titles on Windows, Linux, and macOS. Keep workstation GC so high-core-count hosts do not reserve over fixed guest image bases.

* [HLE] Expand PS5 service and media compatibility

Add the kernel, threading, save-data, networking, audio, video-codec, font, dialog, and service exports required by newer PS5 software. Preserve every SysAbi NID currently registered by main while adding the compatibility surface used by ASTRO BOT.

* [AGC/Vulkan] Extend Gen5 shader and presentation support

Expand PM4 handling, Gen5 shader translation, MRT and packed export support, guest image tracking, depth initialization, texture aliasing, and Vulkan presentation. Add the performance overlay and address-filtered diagnostics used to validate ASTRO BOT with original shaders.

* [Core] Align static TLS reservation across hosts

* [Pad] Align primary user ID with UserService

* [Gpu] Preserve runtime scalar buffers across renderer seam

* [AGC] Restore omitted command helper exports

* [Vulkan] Reuse primary views for promoted MRT targets

* [Vulkan] Preserve scratch storage bindings in compute dispatches
This commit is contained in:
Miguel Cruz
2026-07-15 19:02:34 -04:00
committed by GitHub
parent ad5a7d3799
commit 864cbb0fa0
85 changed files with 36299 additions and 9176 deletions
+78 -30
View File
@@ -10,7 +10,7 @@ public static class NpManagerExports
{
private const int NpTitleIdSize = 16;
private const int NpTitleSecretSize = 128;
private const int NpReachabilityStateUnavailable = 0;
private const int NpErrorInvalidArgument = unchecked((int)0x80550003);
[SysAbiExport(
Nid = "3Zl8BePTh9Y",
@@ -58,35 +58,6 @@ public static class NpManagerExports
return WriteOfflineOnlineId(ctx, ctx[CpuRegister.Rsi]);
}
[SysAbiExport(
Nid = "rbknaUjpqWo",
ExportName = "sceNpGetAccountIdA",
Target = Generation.Gen5,
LibraryName = "libSceNpManager")]
public static int NpGetOnlineIdA(CpuContext ctx)
{
// The A variant takes a user ID before OnlineId.
return WriteOfflineOnlineId(ctx, ctx[CpuRegister.Rsi]);
}
[SysAbiExport(
Nid = "e-ZuhGEoeC4",
ExportName = "sceNpGetNpReachabilityState",
Target = Generation.Gen4 | Generation.Gen5,
LibraryName = "libSceNpManager")]
public static int NpGetNpReachabilityState(CpuContext ctx)
{
var stateAddress = ctx[CpuRegister.Rsi];
if (stateAddress == 0)
{
return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT);
}
return ctx.TryWriteInt32(stateAddress, NpReachabilityStateUnavailable)
? ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK)
: ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT);
}
[SysAbiExport(
Nid = "VfRSmPmj8Q8",
ExportName = "sceNpRegisterStateCallback",
@@ -140,6 +111,77 @@ public static class NpManagerExports
: ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT);
}
[SysAbiExport(
Nid = "rbknaUjpqWo",
ExportName = "sceNpGetAccountIdA",
Target = Generation.Gen4 | Generation.Gen5,
LibraryName = "libSceNpManager")]
public static int NpGetAccountIdA(CpuContext ctx)
{
var userId = unchecked((int)ctx[CpuRegister.Rdi]);
var accountIdAddress = ctx[CpuRegister.Rsi];
if (userId == -1 || accountIdAddress == 0)
{
return SetReturn(ctx, NpErrorInvalidArgument);
}
// The offline profile exposed by sceNpGetState is signed in. Keep the
// account query consistent with that state: Unity's PSN integration
// treats SIGNED_OUT as an exceptional state and retries it every frame.
// A stable local-only id is sufficient for titles which only use the
// value as a profile key.
Span<byte> accountId = stackalloc byte[sizeof(ulong)];
BinaryPrimitives.WriteUInt64LittleEndian(accountId, 1);
return ctx.Memory.TryWrite(accountIdAddress, accountId)
? SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_OK)
: SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT);
}
[SysAbiExport(
Nid = "JT+t00a3TxA",
ExportName = "sceNpGetAccountCountryA",
Target = Generation.Gen4 | Generation.Gen5,
LibraryName = "libSceNpManager")]
public static int NpGetAccountCountryA(CpuContext ctx)
{
var userId = unchecked((int)ctx[CpuRegister.Rdi]);
var countryAddress = ctx[CpuRegister.Rsi];
if (userId == -1 || countryAddress == 0)
{
return SetReturn(ctx, NpErrorInvalidArgument);
}
Span<byte> country = stackalloc byte[4];
country[0] = (byte)'U';
country[1] = (byte)'S';
country[2] = 0;
country[3] = 0;
return ctx.Memory.TryWrite(countryAddress, country)
? SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_OK)
: SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT);
}
[SysAbiExport(
Nid = "e-ZuhGEoeC4",
ExportName = "sceNpGetNpReachabilityState",
Target = Generation.Gen4 | Generation.Gen5,
LibraryName = "libSceNpManager")]
public static int NpGetNpReachabilityState(CpuContext ctx)
{
var userId = unchecked((int)ctx[CpuRegister.Rdi]);
var stateAddress = ctx[CpuRegister.Rsi];
if (userId == -1 || stateAddress == 0)
{
return SetReturn(ctx, NpErrorInvalidArgument);
}
Span<byte> state = stackalloc byte[sizeof(uint)];
BinaryPrimitives.WriteUInt32LittleEndian(state, 0); // Unavailable while offline.
return ctx.Memory.TryWrite(stateAddress, state)
? SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_OK)
: SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT);
}
[SysAbiExport(
Nid = "Ec63y59l9tw",
ExportName = "sceNpSetNpTitleId",
@@ -166,6 +208,12 @@ public static class NpManagerExports
return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK);
}
private static int SetReturn(CpuContext ctx, int result)
{
ctx[CpuRegister.Rax] = unchecked((ulong)result);
return result;
}
private static string ReadTitleId(ReadOnlySpan<byte> bytes)
{
var length = 0;