mirror of
https://github.com/par274/sharpemu.git
synced 2026-08-12 12:38:42 +08:00
[HLE] Fix AJM/ACM no-op stubs and accept Gen5 AudioOut2 mastering/batch calls (#807)
AjmModuleUnregister/AjmFinalize were pure no-ops (always returned success without touching state); they now validate the context and actually remove the codec registration / context entry, returning a real error when the context is unknown. AjmModuleUnregister traces whether the codec was actually registered, to help spot a title unregistering something it never registered. MaxCodecType was hardcoded to 25 based on known Sony codec ids, incorrectly rejecting valid Gen5 codec types (e.g. 24). Registration is pure bookkeeping (HashSet.Add); the only real constraint is that codecType must not overflow the 32-bit instanceId it gets packed into, i.e. codecType < 2^18. Named the instanceId bit-packing constants (InstanceIdSlotBits/InstanceIdSlotMask) so the four call sites that used to hardcode 14/0x3FFF independently can't drift out of sync, and MaxCodecType's formula is self-evident. Accept sceAcmBatchInitialize/InitializeLite/Start/StartMultiple/Process as successful no-ops -- the emulator runs no ACM DSP jobs, but Scream's workers trap on int 0x41/0x42 asserts whenever a submission call reports failure. Accept sceAudioOut2MasteringInit/Set3DLatency as no-ops -- the host mixer has no mastering/object pipeline to tune, but returning failure makes titles tear down their whole ACM context and abort audio arena bring-up. Tested on Ghost of Yotei (PPSA26344): sceAudioOut2MasteringInit/Set3DLatency unresolved-import warnings go from 2 to 0, unblocking 5 audio-related guest threads that never spawned before (MovieDecoder, snd_stream_parsing_thread, snd_stream_reader_thread, Psn, NCA::PumpThread), watchdog stall errors from 1 to 0. This alone gets the title past its Scream audio-init stall into further boot, but it still hits an unrelated infinite retry loop in sceVideoOutGetFlipStatus shortly after -- fixed by the separate videoout-agc-hle-misc change; combined, the title renders and presents a real GPU frame. Regression-checked on Demon's Souls, Astro Bot, Outer Wilds, Cult of the Lamb, Ghost of Tsushima, GTA, Minecraft, Quake: 0 calls to any export touched by this change on any of them, byte-for-byte identical to upstream/main.
This commit is contained in:
@@ -83,6 +83,30 @@ public sealed class AjmExportsTests : IDisposable
|
||||
Assert.Equal(InvalidContext, RegisterCodec(contextId + 1, 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ModuleUnregister_RemovesRegisteredCodecAndRejectsUnknownContext()
|
||||
{
|
||||
var contextId = Initialize();
|
||||
|
||||
Assert.Equal(0, RegisterCodec(contextId, 1));
|
||||
Assert.Equal(0, UnregisterCodec(contextId, 1));
|
||||
// The codec is actually gone, not just a no-op stub: it's unusable
|
||||
// for a new instance, and re-registering no longer hits
|
||||
// CodecAlreadyRegistered.
|
||||
Assert.Equal(CodecNotRegistered, CreateInstance(contextId, 1, 0x401, InstanceAddress));
|
||||
Assert.Equal(0, RegisterCodec(contextId, 1));
|
||||
|
||||
Assert.Equal(InvalidContext, UnregisterCodec(contextId + 1, 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ModuleUnregister_UnknownCodecIsToleratedAsANoOp()
|
||||
{
|
||||
var contextId = Initialize();
|
||||
|
||||
Assert.Equal(0, UnregisterCodec(contextId, 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MemoryRegistration_TracksValidContextAndToleratesRepeatedUnregister()
|
||||
{
|
||||
@@ -353,6 +377,13 @@ public sealed class AjmExportsTests : IDisposable
|
||||
return AjmExports.AjmModuleRegister(_ctx);
|
||||
}
|
||||
|
||||
private int UnregisterCodec(uint contextId, uint codecType)
|
||||
{
|
||||
_ctx[CpuRegister.Rdi] = contextId;
|
||||
_ctx[CpuRegister.Rsi] = codecType;
|
||||
return AjmExports.AjmModuleUnregister(_ctx);
|
||||
}
|
||||
|
||||
private int RegisterMemory(uint contextId, ulong address, ulong pages)
|
||||
{
|
||||
_ctx[CpuRegister.Rdi] = contextId;
|
||||
|
||||
Reference in New Issue
Block a user