mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-25 18:05:12 -04:00
Qualify shared state across local temporal render-pass exits
Co-Authored-By: GPT-6.1-Sol <noreply@openai.com>
This commit is contained in:
@@ -213,6 +213,12 @@ on a fixed region -> next.
|
||||
|
||||
## 5. Status / Log (update every session)
|
||||
|
||||
- **2026-10-24 — scoped render-pass qualification.** The sandbox now compares
|
||||
shared RAM/register/clock/interrupt digests before and after an actual
|
||||
opted-in local temporal pass, discard, device-read abort, rollback refusal,
|
||||
and a nonparticipating peer. The HD GL fixture separately opens a pass under
|
||||
native authority. Consuming-title and matched-performance evidence remains
|
||||
required for upstream promotion.
|
||||
- **2026-10-24 — render-pass HD/local-view scope.** Re-scope the fork's
|
||||
permission change onto current master without replay controls or host tracing.
|
||||
Title-level positive HD/local-view digest and abort qualification remains
|
||||
|
||||
@@ -999,6 +999,34 @@ static int local_temporal_draw(CPUState *cpu, void *user, uint32_t alpha) {
|
||||
return local_draw(cpu, user, 0);
|
||||
}
|
||||
|
||||
/* Shared-state digest deliberately excludes the local presentation image. */
|
||||
static uint64_t shared_digest(const CPUState *cpu) {
|
||||
uint64_t h = 0xcbf29ce484222325ull;
|
||||
const uint8_t *parts[] = { (const uint8_t *)cpu->gpr, s_ram, s_spad };
|
||||
const size_t sizes[] = { sizeof cpu->gpr, s_ram_live, sizeof s_spad };
|
||||
for (size_t p = 0; p < sizeof parts / sizeof parts[0]; ++p)
|
||||
for (size_t i = 0; i < sizes[p]; ++i) {
|
||||
h ^= parts[p][i];
|
||||
h *= 0x100000001b3ull;
|
||||
}
|
||||
h ^= psx_cycle_count;
|
||||
h *= 0x100000001b3ull;
|
||||
h ^= ((uint64_t)i_mask << 32) | i_stat;
|
||||
return h * 0x100000001b3ull;
|
||||
}
|
||||
|
||||
static int local_temporal_discard(CPUState *cpu, void *user, uint32_t alpha) {
|
||||
(void)local_temporal_draw(cpu, user, alpha);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int local_temporal_abort(CPUState *cpu, void *user, uint32_t alpha) {
|
||||
(void)local_temporal_draw(cpu, user, alpha);
|
||||
(void)render_pass_mmio_read_allowed(0x1F801800u, 1);
|
||||
CHECK(0, "device-read abort must not return to guest code");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Netplay local view: forward netplay frames only; guest state restored
|
||||
* exactly; a committed image cancels the crop request. */
|
||||
static void test_local_view(void) {
|
||||
@@ -1006,6 +1034,7 @@ static void test_local_view(void) {
|
||||
PSXModRenderPass r;
|
||||
RenderPassStats st;
|
||||
uint64_t cycle;
|
||||
uint64_t digest;
|
||||
render_pass_reset_session(); s_gl_status = 0; s_begin_ok = 1;
|
||||
memset(&r, 0, sizeof r);
|
||||
r.struct_size = sizeof r;
|
||||
@@ -1049,8 +1078,17 @@ static void test_local_view(void) {
|
||||
"guest state restored after the local view");
|
||||
psx_mod_set_render_pass_netplay(1);
|
||||
r.alpha_q16 = 32768u;
|
||||
digest = shared_digest(&cpu);
|
||||
CHECK(psx_mod_render_pass(&cpu, &r, local_temporal_draw, NULL) == 1,
|
||||
"opted-in temporal pass uses own-view scope");
|
||||
CHECK(shared_digest(&cpu) == digest,
|
||||
"actual opted-in temporal pass preserves shared digest");
|
||||
CHECK(!psx_mod_render_pass(&cpu, &r, local_temporal_discard, NULL) &&
|
||||
shared_digest(&cpu) == digest,
|
||||
"discarded temporal pass preserves shared digest");
|
||||
CHECK(!psx_mod_render_pass(&cpu, &r, local_temporal_abort, NULL) &&
|
||||
shared_digest(&cpu) == digest && s_open_passes == 0,
|
||||
"aborted temporal pass restores shared state and closes transaction");
|
||||
CHECK(s_ws_scope == 0 && psx_mod_local_view_scope() == 0 &&
|
||||
cpu.gpr[8] == 7 && s_ram[0x456] == 0x77 && psx_cycle_count == cycle,
|
||||
"temporal local pass restores scope, RAM, registers and clock");
|
||||
@@ -1058,6 +1096,10 @@ static void test_local_view(void) {
|
||||
CHECK(!psx_mod_render_pass(&cpu, &r, never_fn, NULL),
|
||||
"temporal local rendering never runs during rollback replay");
|
||||
s_resim = 0;
|
||||
psx_mod_set_render_pass_netplay(0);
|
||||
CHECK(!psx_mod_render_pass(&cpu, &r, never_fn, NULL) &&
|
||||
shared_digest(&cpu) == digest,
|
||||
"nonparticipating peer refuses temporal pass without shared-state change");
|
||||
r.x = 900;
|
||||
CHECK(!psx_mod_render_local_view(&cpu, &r, never_fn, NULL),
|
||||
"rect outside VRAM refused");
|
||||
|
||||
Reference in New Issue
Block a user