From 74a519875b181496ea2492d878230934690779df Mon Sep 17 00:00:00 2001 From: MarcelMediaDev Date: Wed, 22 Jul 2026 22:18:47 +0100 Subject: [PATCH] fix(agc): add missing Cb/Dcb GetSize stubs for packet sizing probes (#535) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unresolved GetSize NIDs returned NOT_FOUND during RenderThread startup, leaving null packet pointers and an immediate write AV. Return fixed packet byte sizes in rax only — no guest memory writes. Co-authored-by: Cursor --- src/SharpEmu.Libs/Agc/AgcExports.cs | 80 +++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/SharpEmu.Libs/Agc/AgcExports.cs b/src/SharpEmu.Libs/Agc/AgcExports.cs index 1cc6ed8c..de9a59e3 100644 --- a/src/SharpEmu.Libs/Agc/AgcExports.cs +++ b/src/SharpEmu.Libs/Agc/AgcExports.cs @@ -965,6 +965,20 @@ public static partial class AgcExports return ReturnPointer(ctx, commandAddress); } + // RenderThread/Subrender probe this before writing a NOP. Unresolved + // GetSize returns NOT_FOUND and leaves command-buffer sizing broken. + // CbNop rejects dwordCount < 2, so report that floor. + [SysAbiExport( + Nid = "t7PlZ9nt5Lc", + ExportName = "sceAgcCbNopGetSize", + Target = Generation.Gen5, + LibraryName = "libSceAgc")] + public static int CbNopGetSize(CpuContext ctx) + { + ctx[CpuRegister.Rax] = 2u * sizeof(uint); + return (int)ctx[CpuRegister.Rax]; + } + [SysAbiExport( Nid = "k3GhuSNmBLU", ExportName = "sceAgcCbDispatch", @@ -1162,6 +1176,18 @@ public static partial class AgcExports return ReturnPointer(ctx, commandAddress); } + // Matches the fixed 8-dword ACQUIRE_MEM packet AcbAcquireMem writes above. + [SysAbiExport( + Nid = "ewobAQeMo5k", + ExportName = "sceAgcAcbAcquireMemGetSize", + Target = Generation.Gen5, + LibraryName = "libSceAgc")] + public static int AcbAcquireMemGetSize(CpuContext ctx) + { + ctx[CpuRegister.Rax] = 8u * sizeof(uint); + return (int)ctx[CpuRegister.Rax]; + } + [SysAbiExport( Nid = "htn36gPnBk4", ExportName = "sceAgcAcbWaitRegMem", @@ -1737,6 +1763,18 @@ public static partial class AgcExports return ReturnPointer(ctx, commandAddress); } + // Matches the fixed 8-dword ACQUIRE_MEM packet DcbAcquireMem writes above. + [SysAbiExport( + Nid = "-vnlTPPXPrw", + ExportName = "sceAgcDcbAcquireMemGetSize", + Target = Generation.Gen5, + LibraryName = "libSceAgc")] + public static int DcbAcquireMemGetSize(CpuContext ctx) + { + ctx[CpuRegister.Rax] = 8u * sizeof(uint); + return (int)ctx[CpuRegister.Rax]; + } + [SysAbiExport( Nid = "i1jyy49AjXU", ExportName = "sceAgcDcbWriteData", @@ -2390,6 +2428,20 @@ public static partial class AgcExports : OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } + // PatchAddress/PatchData touch UInt64 fields at +12/+20 of an RReleaseMem + // packet, so the packet is at least 7 dwords; use the 8-dword RELEASE_MEM + // family size already used elsewhere in this file. + [SysAbiExport( + Nid = "hL7C0IRpWZI", + ExportName = "sceAgcCbQueueEndOfPipeActionGetSize", + Target = Generation.Gen5, + LibraryName = "libSceAgc")] + public static int CbQueueEndOfPipeActionGetSize(CpuContext ctx) + { + ctx[CpuRegister.Rax] = 8u * sizeof(uint); + return (int)ctx[CpuRegister.Rax]; + } + [SysAbiExport( Nid = "0fWWK5uG9rQ", ExportName = "sceAgcQueueEndOfPipeActionPatchAddress", @@ -11469,6 +11521,34 @@ public static partial class AgcExports $"[LOADER][TRACE] agc.create_shader dst=0x{destinationAddress:X16} header=0x{headerAddress:X16} code=0x{codeAddress:X16} {detail}"); } + // Hardware REWIND is a fixed 2-dword header + valid-bit packet (same floor + // as CbNopGetSize). No Rewind writer is implemented yet; size-only is enough + // for callers that allocate the packet before filling it. + [SysAbiExport( + Nid = "QIXCsbipds0", + ExportName = "sceAgcDcbRewindGetSize", + Target = Generation.Gen5, + LibraryName = "libSceAgc")] + public static int DcbRewindGetSize(CpuContext ctx) + { + ctx[CpuRegister.Rax] = 2u * sizeof(uint); + return (int)ctx[CpuRegister.Rax]; + } + + // Matches the 4-dword INDIRECT_BUFFER packet DcbJump writes below. + // Returning NOT_FOUND here left callers with a null packet pointer and an + // immediate write AV on RenderThread. + [SysAbiExport( + Nid = "VEGu4dixjUg", + ExportName = "sceAgcDcbJumpGetSize", + Target = Generation.Gen5, + LibraryName = "libSceAgc")] + public static int DcbJumpGetSize(CpuContext ctx) + { + ctx[CpuRegister.Rax] = 4u * sizeof(uint); + return (int)ctx[CpuRegister.Rax]; + } + [SysAbiExport( Nid = "xSAR0LTcRKM", ExportName = "sceAgcDcbJump",