From 7692b8134d316b5b5f79ef2cb2ece9065d5c1af1 Mon Sep 17 00:00:00 2001 From: Shokunin <30949000+tetrisgm@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:46:50 -0700 Subject: [PATCH] Frame generation: in-between frames never rasterize native VRAM Under HD texture-pack authority (and dual-raster netplay) every draw was also rasterized into CPU VRAM unless a render pass was active. Replayed draws of a generated frame were not exempt, so each in-between frame wrote interpolated geometry into the guest's native VRAM. They are presentation only, like a pass. Fixture: compose under HD authority, VRAM unchanged. Co-Authored-By: Claude Opus 5.5 --- runtime/src/gpu_gl_renderer.c | 3 ++- runtime/tests/test_gl_frame_gen.c | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/runtime/src/gpu_gl_renderer.c b/runtime/src/gpu_gl_renderer.c index 186d71d9..9a6d0ef8 100644 --- a/runtime/src/gpu_gl_renderer.c +++ b/runtime/src/gpu_gl_renderer.c @@ -4262,8 +4262,9 @@ static int cpu_raster_required(void) { * GPU surface. The CPU mirror stays the authoritative record of the real * frame, so the pass never rasterizes into it. depth24 scanout still * presents from the CPU mirror and keeps its write-through. */ + /* A generated (in-between) frame is presentation only, like a pass. */ return !s_raster_ok || s_depth24_skip_up || - ((s_cpu_auth_dual || s_hd_native_authority) && !s_pass_active); + ((s_cpu_auth_dual || s_hd_native_authority) && !s_pass_active && !s_fg_drawing); } /* Bracket each authoritative draw so a later netplay/session policy change * cannot accidentally disable the faithful floor for HD replacement mode. */ diff --git a/runtime/tests/test_gl_frame_gen.c b/runtime/tests/test_gl_frame_gen.c index f9283900..1239092e 100644 --- a/runtime/tests/test_gl_frame_gen.c +++ b/runtime/tests/test_gl_frame_gen.c @@ -278,6 +278,15 @@ int main(int argc, char **argv) { FILE *f = fopen("pm.rgba", "wb"); fwrite(img, 4, (size_t)ww * wh, f); fclose(f); } check(dm != r0 && dm != r1, "phase 0.5 is neither endpoint"); + /* With an HD texture pack the CPU raster is native VRAM's authority; + * an in-between frame is presentation only and must not draw there. */ + gl_renderer_set_hd_texture_mode(1); + static uint16_t before[1024 * 512]; + memcpy(before, s_vram, sizeof before); + check(fg_generate(0.5, 0) == 1, "compose at phase 0.5 under HD authority"); + check(memcmp(before, s_vram, sizeof before) == 0, + "generated frame leaves native VRAM unchanged under HD authority"); + gl_renderer_set_hd_texture_mode(0); free(img); check(n_gen > 0, "generated frames were presented"); }