mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-25 20:28:48 +08:00
[AGC] Implement the owner-scoped resource unregister exports (#469)
sceAgcDriverUnregisterOwnerAndResources (ZLJk9r2+2Aw) and sceAgcDriverUnregisterAllResourcesForOwner (SCoAN5fYlUM) were unresolved. We already register owners and resources, and the guest registers a resource owner per streaming batch, so with no way to release one the fixed owner pool filled up: sceAgcDriverRegisterOwner started failing and the guest logged its own "Agc registerOwner error: 0x80020003", after which it kept half-registering records. Demon's Souls then crashed scanning that registry. Owner-scoped teardown is straightforward because RegisteredAgcResource already carries its owner, so both entry points share one sweep over the resource table. UnregisterOwnerAndResources additionally drops the owner itself and its compute queue, and reports INVALID_ARGUMENT for an owner that was never registered. The existing single-resource sceAgcDriverUnregisterResource (pWLG7WOpVcw) is unchanged. Both NIDs are checked against their export names by the SHEM004 analyzer, which fails the build on a mismatch. Tested on Demon's Souls (PPSA01342): the registerOwner error no longer appears and the registry stays consistent across streaming batches. 470 tests pass.
This commit is contained in:
@@ -11506,6 +11506,69 @@ public static partial class AgcExports
|
|||||||
return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK);
|
return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int RemoveResourcesForOwner(SubmittedGpuState state, uint owner)
|
||||||
|
{
|
||||||
|
var stale = new List<uint>();
|
||||||
|
foreach (var (handle, resource) in state.RegisteredResources)
|
||||||
|
{
|
||||||
|
if (resource.Owner == owner)
|
||||||
|
{
|
||||||
|
stale.Add(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var handle in stale)
|
||||||
|
{
|
||||||
|
state.RegisteredResources.Remove(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stale.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SysAbiExport(
|
||||||
|
Nid = "ZLJk9r2+2Aw",
|
||||||
|
ExportName = "sceAgcDriverUnregisterOwnerAndResources",
|
||||||
|
Target = Generation.Gen5,
|
||||||
|
LibraryName = "libSceAgc")]
|
||||||
|
public static int DriverUnregisterOwnerAndResources(CpuContext ctx)
|
||||||
|
{
|
||||||
|
var owner = (uint)ctx[CpuRegister.Rdi];
|
||||||
|
var state = _submittedGpuStates.GetValue(ctx.Memory, static _ => new SubmittedGpuState());
|
||||||
|
int resources;
|
||||||
|
lock (state.Gate)
|
||||||
|
{
|
||||||
|
if (!state.ResourceOwners.Remove(owner))
|
||||||
|
{
|
||||||
|
return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
resources = RemoveResourcesForOwner(state, owner);
|
||||||
|
state.ComputeQueues.Remove(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
TraceAgc($"agc.driver_unregister_owner owner={owner} resources={resources}");
|
||||||
|
return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
[SysAbiExport(
|
||||||
|
Nid = "SCoAN5fYlUM",
|
||||||
|
ExportName = "sceAgcDriverUnregisterAllResourcesForOwner",
|
||||||
|
Target = Generation.Gen5,
|
||||||
|
LibraryName = "libSceAgc")]
|
||||||
|
public static int DriverUnregisterAllResourcesForOwner(CpuContext ctx)
|
||||||
|
{
|
||||||
|
var owner = (uint)ctx[CpuRegister.Rdi];
|
||||||
|
var state = _submittedGpuStates.GetValue(ctx.Memory, static _ => new SubmittedGpuState());
|
||||||
|
int resources;
|
||||||
|
lock (state.Gate)
|
||||||
|
{
|
||||||
|
resources = RemoveResourcesForOwner(state, owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
TraceAgc($"agc.driver_unregister_owner_resources owner={owner} resources={resources}");
|
||||||
|
return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK);
|
||||||
|
}
|
||||||
|
|
||||||
[SysAbiExport(
|
[SysAbiExport(
|
||||||
Nid = "pWLG7WOpVcw",
|
Nid = "pWLG7WOpVcw",
|
||||||
ExportName = "sceAgcDriverUnregisterResource",
|
ExportName = "sceAgcDriverUnregisterResource",
|
||||||
|
|||||||
Reference in New Issue
Block a user