mirror of
https://github.com/par274/sharpemu.git
synced 2026-08-02 16:09:47 +08:00
Astro Bot stack: VEH/TBB, title clear, swapchain fallback, Psml MFSR (#528)
* Cpu/Kernel: harden VEH trampoline and keep TBB on native workers Route FastFail/CLR/stack-overflow around managed VEH, serialize managed entry with a recursive spinlock, require native workers for tbb_thead, and abandon pthread mutexes when a guest thread is torn down by worker abort so splash waiters are not left holding locks forever. * Cpu: soft-fail TBB native worker storms and cap concurrent Runs Throwing on worker/prologue faults killed the process mid tbb_thead burst (FailFast 0xC0000409). Soft-return 0x80020012, limit in-flight native Runs (default 2), and keep prewarm small so back-to-back boots do not need an artificial settle delay. * Agc/VideoOut: poison-only empty-SRT reject and clear procedural ES/PS Skip QueueSubmit only when Address-0 image slots remain; run the Astro title clear pair via CmdClearColorImage so the pass executes without descriptors that lose the device. * VideoOut: recreate swapchain with fallback extent on 0x0 surface Minimized Win32 surfaces report 0x0 / MaxImageExtent=0; deferring recreate forever left an OutOfDate swapchain with no presents. Clamp to last/default size and recreate instead of early-return. * Psml: stub MFSR init/shared/context and dispatch packet size Astro Bot asserts in GfxRenderStagePSSR when scePsmlMfsrInit is unresolved (Mfsr initialized failed). Soft HLE for the MFSR shared-resource and 800M3_2 context path plus dispatch packet size lets boot pass splash to first frame without claiming real upscaling. * Psml: stub MFSR GetDispatchMfsrPacket900 for logo PSSR Astro StartLevel ps_logo asserted GfxRenderStagePSSR.cpp:266 when GetDispatchMfsrPacket900 (RUNLFro+qok) was unresolved. Return SCE_OK from SizeInDwords so the 900 fill runs, soft-clear the guest packet buffer, and register 1000/1100 siblings for the same ABI.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
using SharpEmu.HLE;
|
||||
using System.Buffers;
|
||||
using System.Buffers.Binary;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
|
||||
@@ -35,6 +36,14 @@ public static class Gen5ShaderScalarEvaluator
|
||||
StringComparison.Ordinal);
|
||||
private static readonly object _scalarFallbackTraceGate = new();
|
||||
private static readonly HashSet<(ulong Shader, uint Pc)> _tracedScalarFallbacks = [];
|
||||
// Shaders whose empty SRT/EUD caused a null-base scalar pointer load.
|
||||
// Host submit of those translations has lost the Vulkan device; Agc skips
|
||||
// them before QueueSubmit.
|
||||
private static readonly ConcurrentDictionary<ulong, byte> _emptySrtScalarPointerFallbacks =
|
||||
new();
|
||||
|
||||
public static bool WasEmptySrtScalarPointerFallback(ulong shaderAddress) =>
|
||||
_emptySrtScalarPointerFallbacks.ContainsKey(shaderAddress);
|
||||
|
||||
// Uniform forward branches select material/resource bodies that remain
|
||||
// statically present in the translated shader. Discover the skipped body's
|
||||
@@ -2101,6 +2110,15 @@ public static class Gen5ShaderScalarEvaluator
|
||||
$"dynamic={dynamicOffset} definitions=[{string.Join(';', definitions)}] " +
|
||||
$"user_data=[{userData}] metadata=" +
|
||||
$"{(state.Metadata is null ? "missing" : $"srt={state.Metadata.ShaderResourceTableSizeDwords},eud={state.Metadata.ExtendedUserDataSizeDwords}")}");
|
||||
if (baseAddress == 0 &&
|
||||
state.Metadata is
|
||||
{
|
||||
ShaderResourceTableSizeDwords: 0,
|
||||
ExtendedUserDataSizeDwords: 0,
|
||||
})
|
||||
{
|
||||
_emptySrtScalarPointerFallbacks.TryAdd(state.Program.Address, 0);
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
|
||||
@@ -305,6 +305,23 @@ public static class Gen5ShaderTranslator
|
||||
count |= 0x20;
|
||||
}
|
||||
|
||||
// Primary SH defaults leave SPI_SHADER_PGM_RSRC2_PS at 0. Draws that
|
||||
// still wrote USER_DATA_n via SetShReg would otherwise translate with
|
||||
// an empty SRT window (Astro title PS → Address-0 descriptors →
|
||||
// device lost). Recover the window from contiguous live registers.
|
||||
if (count == 0 &&
|
||||
userDataBaseRegister is not ComputeUserDataRegister)
|
||||
{
|
||||
var probed = 0;
|
||||
while (probed < MaximumHardwareUserSgprs &&
|
||||
shaderRegisters.ContainsKey(userDataBaseRegister + (uint)probed))
|
||||
{
|
||||
probed++;
|
||||
}
|
||||
|
||||
count = probed;
|
||||
}
|
||||
|
||||
if (userDataBaseRegister is not (PsUserDataRegister or
|
||||
VsUserDataRegister or
|
||||
GsUserDataRegister or
|
||||
|
||||
Reference in New Issue
Block a user