From bf92f07d6bd228fece3a8a03baccfd9d0dd94988 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Wed, 4 Nov 2026 18:29:36 -0500 Subject: vgsp-gr: sema_gl_vp_prelude - synthesize the missing Turing viewport scale/offset (mode 1) plus optional pixel-centre/clip-control (2) and clip-rect (3) at the head of replayed 3D windows; the client push never writes the viewport family; default 0 = legacy bytes; r1459: FE accepts the words, draws still store nothing -> insertion position vs pipeline-group binding is the next variable --- kernel/gsp_phys_booter.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) (limited to 'kernel/gsp_phys_booter.c') diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index 9b1294a..4903d5d 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -19248,6 +19248,64 @@ bool gsp_phys_rmcall_gr_sph_bind_value(void) return READ_ONCE(gsp_phys_rmcall_gr_sph_bind); } +/* + * SESSION 154c (viewport wall): the replayed 3D window carries no + * viewport family state - the colour target, raster enable, shader + * binds, attributes, index buffer and draws are present, but the + * 0x0a00 scale/offset block, the 0x1924/0x192c/0x193c pixel and clip + * controls and the 0x0c00 clip rect are not (the client's captured + * push never writes them; the slot-31 viewport macro exists in the + * capture but is never called). In the fresh replayed context a + * missing viewport clips all geometry, so the engine executes the + * DRAW but stores no fragments. This knob synthesizes the missing + * state as a preamble ahead of each replayed 3D window. + * + * Words verified against the window decoder (op = hdr[31:29], + * count = hdr[28:16], method = hdr[12:0] << 2): + * 0x20060280 INC cnt=6 method 0x0a00 -> SET_VIEWPORT_SCALE_X/ + * Y/Z(0) and SET_VIEWPORT_OFFSET_X/Y/Z(0) + * 0x80000649 IMM data=0 method 0x1924 -> SET_VIEWPORT_PIXEL + * 0x8001064b IMM data=1 method 0x192c -> SET_VIEWPORT_SCALE_OFFSET + * 0x8001064f IMM data=1 method 0x193c -> SET_VIEWPORT_CLIP_CONTROL + * 0x20040300 INC cnt=4 method 0x0c00 -> SET_VIEWPORT_CLIP_ + * HORIZONTAL/VERTICAL/MIN_Z/MAX_Z(0) + * Mode 1 = scale/offset block; mode 2 adds the immediate controls; + * mode 3 adds the 1280x720 clip rect. None of the words is an + * address operand, so the sequence is emitted verbatim (no + * relocation pass). Default 0 keeps the legacy window bytes. + */ +#define GSP_PHYS_GR_VP_PRE_WORDS 15u +static const u32 gsp_phys_gr_vp_pre[GSP_PHYS_GR_VP_PRE_WORDS] = { + /* mode 1: viewport scale/offset */ + 0x20060280u, 0x44200000u, 0xc3b40000u, 0x3f000000u, + 0x44200000u, 0x43b40000u, 0x3f000000u, + /* mode 2: pixel centre, scale/offset enable, clip control */ + 0x80000649u, 0x8001064bu, 0x8001064fu, + /* mode 3: clip rect (x0=0, w=1280, y0=0, h=720, z 0..1) */ + 0x20040300u, 0x05000000u, 0x02d00000u, 0x00000000u, + 0x3f800000u, +}; + +static u32 gsp_phys_gr_vp_pre_len(int mode) +{ + switch (mode) { + case 1: + return 7u; + case 2: + return 10u; + case 3: + return GSP_PHYS_GR_VP_PRE_WORDS; + default: + return 0u; + } +} + +static int gsp_phys_rmcall_gr_vp_prelude; +module_param_named(sema_gl_vp_prelude, gsp_phys_rmcall_gr_vp_prelude, + int, 0644); +MODULE_PARM_DESC(sema_gl_vp_prelude, + "Synthesize the missing viewport state ahead of replayed 3D windows (0 = off (default); 1 = scale/offset; 2 = + pixel centre and clip control; 3 = + clip rect)"); + /* * CONT-119 (r1450): the BINDING words of the synthesized stage-2/5 * REGISTER_COUNT runs. CONT-90 emitted each as a 2-word @@ -28523,6 +28581,51 @@ gr_page_unmapped: } } } + /* + * SESSION 154c: synthesized viewport preamble (see the + * sema_gl_vp_prelude comment). Prepend the chosen literal + * sequence at the head of the final window so it precedes + * the window's first 0x840 (SET_COLOR_TARGET) run and the + * FE decodes it in the same window-carrier context. The + * words carry no address operand, so no relocation pass is + * applied - they are emitted verbatim. Same head-insertion + * path and block-size guard as SPH-BIND / SURF-PRELUDE. + */ + { + int vp_mode = READ_ONCE(gsp_phys_rmcall_gr_vp_prelude); + u32 vpn = gsp_phys_gr_vp_pre_len(vp_mode); + + if (vpn) { + if (win3d_n + vpn + 2u + 8u <= + GSP_PHYS_RMCALL_GR_METHOD_WORDS) { + static u32 vp_emit_log; + u32 vp_old = win3d_n; + + memmove(&stream_patch[vpn], + stream_patch, + (size_t)win3d_n * 4u); + memcpy(stream_patch, + gsp_phys_gr_vp_pre, + (size_t)vpn * 4u); + win3d_n += vpn; + if (vp_emit_log < 16u) { + vp_emit_log++; + pr_info("vgsp-gr: VP-PRELUDE mode=%d words=%u window=%u->%u\n", + vp_mode, vpn, vp_old, + win3d_n); + } + } else { + static u32 vp_skip_log; + + if (vp_skip_log < 8u) { + vp_skip_log++; + pr_info("vgsp-gr: VP-PRELUDE skipped (no room) mode=%d words=%u window=%u cap=%u\n", + vp_mode, vpn, win3d_n, + GSP_PHYS_RMCALL_GR_METHOD_WORDS); + } + } + } + } /* * SESSION 153-CONTINUED-57: patch the attr/pipeline prelude for * this launch (relocation exactly like the window: the -- cgit v1.2.3