diff --git a/runtime/include/pgxp.h b/runtime/include/pgxp.h index aa55b3aa..9b0df4bc 100644 --- a/runtime/include/pgxp.h +++ b/runtime/include/pgxp.h @@ -103,6 +103,16 @@ typedef struct PGXPStats { uint64_t w_valid; /* lookups that also carried a usable depth */ uint64_t produced; /* RTPS/RTPT projections pushed into shadows */ uint64_t swc2_stores; /* GTE reg shadows copied to RAM shadows */ + /* pgxp_load_precise_word outcomes (perspective texturing, per vertex): + * which check refused the depth. untracked = no shadow for that address in + * this generation; mismatch = shadow describes a different word; partial = + * only one half carries a projection; no_z = projection without depth. */ + uint64_t word_lookups; + uint64_t word_hit; + uint64_t word_untracked; + uint64_t word_mismatch; + uint64_t word_partial; + uint64_t word_no_z; } PGXPStats; void pgxp_get_stats(PGXPStats *out); diff --git a/runtime/src/debug_server.c b/runtime/src/debug_server.c index d5b821fa..514e8466 100644 --- a/runtime/src/debug_server.c +++ b/runtime/src/debug_server.c @@ -5289,7 +5289,9 @@ static void handle_geom_correction(int id, const char *json) "\"lookups\":%llu,\"dataflow_hit\":%llu,\"fallback_hit\":%llu," "\"native\":%llu,\"value_mismatch\":%llu,\"trunc_reject\":%llu," "\"tolerance_reject\":%llu,\"w_valid\":%llu," - "\"produced\":%llu,\"swc2_stores\":%llu}}", + "\"produced\":%llu,\"swc2_stores\":%llu," + "\"word\":{\"lookups\":%llu,\"hit\":%llu,\"untracked\":%llu," + "\"mismatch\":%llu,\"partial\":%llu,\"no_z\":%llu}}}", id, gte_geometry_correction_enabled(), (unsigned)hits, @@ -5308,7 +5310,13 @@ static void handle_geom_correction(int id, const char *json) (unsigned long long)ps.tolerance_reject, (unsigned long long)ps.w_valid, (unsigned long long)ps.produced, - (unsigned long long)ps.swc2_stores); + (unsigned long long)ps.swc2_stores, + (unsigned long long)ps.word_lookups, + (unsigned long long)ps.word_hit, + (unsigned long long)ps.word_untracked, + (unsigned long long)ps.word_mismatch, + (unsigned long long)ps.word_partial, + (unsigned long long)ps.word_no_z); } /* pgxp — live-tune the value-propagation engine for one-toggle isolation runs diff --git a/runtime/src/pgxp.cpp b/runtime/src/pgxp.cpp index c2906c9e..51ec0f61 100644 --- a/runtime/src/pgxp.cpp +++ b/runtime/src/pgxp.cpp @@ -809,12 +809,18 @@ extern "C" void pgxp_test_set_generation(uint32_t gen) { s_gen = gen; } extern "C" int pgxp_load_precise_word(uint32_t addr, uint32_t packed, int32_t *x16, int32_t *y16, uint16_t *z) { if (!s_enabled) return 0; + s_stats.word_lookups++; PGXPValue *pv = pgxp_ptr(addr); - if (!pv || pv->gen != s_gen || pv->value != packed || - (pv->flags & PGXP_F_VXY) != PGXP_F_VXY) + if (!pv || pv->gen != s_gen) { s_stats.word_untracked++; return 0; } + if (pv->value != packed) { s_stats.word_mismatch++; return 0; } + if ((pv->flags & PGXP_F_VXY) != PGXP_F_VXY) { + s_stats.word_partial++; return 0; + } if (x16) *x16 = pv->x16; if (y16) *y16 = pv->y16; if (z) *z = (pv->flags & PGXP_F_VZ) ? pv->z : 0; - return (pv->flags & PGXP_F_VZ) && pv->z != 0; + if (!(pv->flags & PGXP_F_VZ) || pv->z == 0) { s_stats.word_no_z++; return 0; } + s_stats.word_hit++; + return 1; }