mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
gpu/a0_history: add per-upload frame stamp (load-vs-upload ordering proof)
a0_history had no timestamp, so an upload's timing couldn't be compared against the CD-load timeline. Add frame_stamp (s_frame_count at the upload) to the entry, return it from gpu_get_a0_src, and emit "frame" in the a0_history JSON. This pinned the MMX5 font bug: the (896/832/960,256) font uploads run at frames 1374/1381/1388 reading zero/0x77 garbage, while the CD delivers that buffer run (LBA 10473 -> 0x800D5208..0x800DD208, real data) at frame ~1508 — the upload races ~130 frames ahead of the font's CD load. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -5030,7 +5030,7 @@ extern int gpu_get_a0_history(int index, int *x, int *y, int *w, int *h,
|
||||
uint32_t *fw0, uint32_t *fw1, int *wcount);
|
||||
extern int gpu_get_a0_extra(int index, uint32_t *func, uint32_t *sp, uint32_t *ra,
|
||||
uint32_t *s1, uint32_t *stack10);
|
||||
extern int gpu_get_a0_src(int index, uint32_t *s2, uint32_t *a0, uint32_t *a1);
|
||||
extern int gpu_get_a0_src(int index, uint32_t *s2, uint32_t *a0, uint32_t *a1, uint32_t *frame);
|
||||
|
||||
static void handle_a0_history(int id, const char *json)
|
||||
{
|
||||
@@ -5044,20 +5044,20 @@ static void handle_a0_history(int id, const char *json)
|
||||
for (int i = 0; i < count && pos < bufsz - 500; i++) {
|
||||
int x, y, w, h, wcount;
|
||||
uint32_t fw0, fw1, func, sp, ra, s1, stk[10];
|
||||
uint32_t s2 = 0, a0r = 0, a1r = 0;
|
||||
uint32_t s2 = 0, a0r = 0, a1r = 0, aframe = 0;
|
||||
gpu_get_a0_history(i, &x, &y, &w, &h, &fw0, &fw1, &wcount);
|
||||
gpu_get_a0_extra(i, &func, &sp, &ra, &s1, stk);
|
||||
gpu_get_a0_src(i, &s2, &a0r, &a1r);
|
||||
gpu_get_a0_src(i, &s2, &a0r, &a1r, &aframe);
|
||||
pos += snprintf(buf + pos, bufsz - pos,
|
||||
"%s{\"i\":%d,\"x\":%d,\"y\":%d,\"w\":%d,\"h\":%d,"
|
||||
"\"fw0\":\"0x%08X\",\"fw1\":\"0x%08X\",\"words\":%d,"
|
||||
"\"func\":\"0x%08X\",\"sp\":\"0x%08X\",\"ra\":\"0x%08X\","
|
||||
"\"s1\":\"0x%08X\",\"s2\":\"0x%08X\",\"a0\":\"0x%08X\",\"a1\":\"0x%08X\","
|
||||
"\"s1\":\"0x%08X\",\"s2\":\"0x%08X\",\"a0\":\"0x%08X\",\"a1\":\"0x%08X\",\"frame\":%u,"
|
||||
"\"stk\":[\"0x%08X\",\"0x%08X\",\"0x%08X\",\"0x%08X\","
|
||||
"\"0x%08X\",\"0x%08X\",\"0x%08X\",\"0x%08X\","
|
||||
"\"0x%08X\",\"0x%08X\"]}",
|
||||
i ? "," : "", i, x, y, w, h, fw0, fw1, wcount,
|
||||
func, sp, ra, s1, s2, a0r, a1r,
|
||||
func, sp, ra, s1, s2, a0r, a1r, aframe,
|
||||
stk[0], stk[1], stk[2], stk[3], stk[4], stk[5], stk[6], stk[7],
|
||||
stk[8], stk[9]);
|
||||
}
|
||||
|
||||
+5
-2
@@ -2146,6 +2146,7 @@ typedef struct {
|
||||
uint32_t s2_val; /* CPU $s2 = TRUE source pixel ptr (`move s2,a1` at entry) */
|
||||
uint32_t a0_val; /* CPU $a0 at capture (RECT arg; may be clobbered) */
|
||||
uint32_t a1_val; /* CPU $a1 at capture (source arg; may be clobbered) */
|
||||
uint32_t frame_stamp; /* s_frame_count at the upload — for load-vs-upload ordering */
|
||||
uint32_t stack[10]; /* first 10 words from sp (sp+32=saved $s1, sp+36=saved $ra) */
|
||||
} A0HistEntry;
|
||||
static A0HistEntry a0_history[A0_HISTORY_CAP];
|
||||
@@ -2175,12 +2176,13 @@ int gpu_get_a0_extra(int index, uint32_t *func, uint32_t *sp, uint32_t *ra,
|
||||
memcpy(stack10, a0_history[index].stack, 10 * sizeof(uint32_t));
|
||||
return 1;
|
||||
}
|
||||
/* True source pointer + arg regs for the LoadImage upload (s2 = pixel source). */
|
||||
int gpu_get_a0_src(int index, uint32_t *s2, uint32_t *a0, uint32_t *a1) {
|
||||
/* True source pointer + arg regs + frame for the LoadImage upload (s2 = source). */
|
||||
int gpu_get_a0_src(int index, uint32_t *s2, uint32_t *a0, uint32_t *a1, uint32_t *frame) {
|
||||
if (index < 0 || index >= a0_history_count) return 0;
|
||||
*s2 = a0_history[index].s2_val;
|
||||
*a0 = a0_history[index].a0_val;
|
||||
*a1 = a0_history[index].a1_val;
|
||||
*frame = a0_history[index].frame_stamp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2217,6 +2219,7 @@ static void gp0_exec_cpu_to_vram(void) {
|
||||
a0_history[slot].s2_val = 0;
|
||||
a0_history[slot].a0_val = 0;
|
||||
a0_history[slot].a1_val = 0;
|
||||
a0_history[slot].frame_stamp = (uint32_t)s_frame_count;
|
||||
memset(a0_history[slot].stack, 0, sizeof(a0_history[slot].stack));
|
||||
if (debug_cpu_ptr) {
|
||||
uint32_t sp = debug_cpu_ptr->gpr[29];
|
||||
|
||||
Reference in New Issue
Block a user