From 86e9501565e62946bdb2a761625db20e97e54098 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Thu, 5 Nov 2026 16:05:11 -0500 Subject: vgsp-gl: deliver the real pixel-stage image and receipt the active draw's topology/index args --- kernel/gsp_sema_service.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) (limited to 'kernel/gsp_sema_service.c') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 8668b6f..fc43b60 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -8385,6 +8385,20 @@ static bool sema_gl_vs_img = true; module_param_named(sema_gl_vs_img, sema_gl_vs_img, bool, 0644); MODULE_PARM_DESC(sema_gl_vs_img, "Deliver the built-in known-good VTG image (SPH+SASS) when the captured VS upload has no SASS body (default 1)"); +/* + * r1500: deliver the known-good pixel image. The active indexed draw + * binds a PIXEL stage (j=5) but no per-window upload of that program was + * ever captured (the 0x2154 pair is absent from the sliced window), so + * the PS slot page stayed empty and the fragment stage had no code. The + * client's real 384 B PS image (SPH V4 000a1482 + SASS) was recovered + * from its init-push page; deliver it at the PS bind VA exactly like the + * VTG image. Default 1; A/B via sema_gl_ps_img=0, overridden by + * sema_gl_ps_hex. + */ +static bool sema_gl_ps_img = true; +module_param_named(sema_gl_ps_img, sema_gl_ps_img, bool, 0644); +MODULE_PARM_DESC(sema_gl_ps_img, + "Deliver the built-in known-good PS image (SPH+SASS) when no captured PS upload/program exists (default 1)"); static u8 svc_gl_prog[GSP_BRIDGE_INLINE_BYTES]; static u32 svc_gl_prog_len; static u8 svc_gl_vs[GSP_BRIDGE_INLINE_BYTES]; @@ -8491,6 +8505,44 @@ static const u8 svc_gl_vs_img[1408] = { 0x47, 0x79, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0x03, 0x00, 0xc0, 0x0f, 0x00, }; +/* + * r1500: known-good pixel program image (SPH V4 000a1482 + SASS), the + * client's own compiled fragment shader recovered from its init-push + * page. The active indexed draw binds type-5 (PIXEL) at the program + * family base (j=5) but the sliced window carries no 0x2154 pair and no + * PS upload, so that page stayed empty and the fragment stage had no + * code. Delivered at the PS bind VA when no captured PS exists, analogous + * to svc_gl_vs_img for VTG. A/B via sema_gl_ps_img=0, overridden by + * sema_gl_ps_hex. The bytes are the client's compiled program. + */ +static const u8 svc_gl_ps_img[384] = { + + 0x82, 0x14, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x26, 0x73, 0x04, 0x00, 0xff, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x0e, 0x00, 0x00, 0x02, 0x0e, 0x04, + 0x26, 0x73, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x62, 0x0e, 0x00, + 0x26, 0x73, 0x01, 0x00, 0xff, 0x00, 0x00, 0x00, 0xa1, 0x80, 0x02, 0x00, 0x00, 0xa2, 0x0e, 0x00, + 0x26, 0x73, 0x02, 0x00, 0xff, 0x00, 0x00, 0x00, 0xa2, 0x80, 0x04, 0x00, 0x00, 0xe2, 0x0e, 0x00, + 0x26, 0x73, 0x03, 0x00, 0xff, 0x00, 0x00, 0x00, 0xa3, 0x80, 0x06, 0x00, 0x00, 0x22, 0x0f, 0x00, + 0x08, 0x73, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x64, 0x1e, 0x00, + 0x20, 0x82, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x41, 0x00, 0x00, 0xe4, 0x2f, 0x08, + 0x20, 0x92, 0x01, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x41, 0x00, 0x00, 0xe4, 0x4f, 0x08, + 0x20, 0xa2, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x41, 0x00, 0x00, 0xc4, 0x8f, 0x00, + 0x20, 0xb2, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x41, 0x00, 0x00, 0xe2, 0x0f, 0x01, + 0x4d, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0xee, 0x0f, 0x00, + 0x47, 0x79, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0x03, 0x00, 0xc0, 0x0f, 0x00, + 0x18, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x18, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x18, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x18, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, +}; + /* * r1481: shader-image cache filled from any push chunk that starts with a * real SPH magic. The client's init push carries its VS/PS images as raw @@ -8551,6 +8603,10 @@ static void svc_gl_prog_apply_param(void) memcpy(svc_gl_vs, svc_gl_vs_img, sizeof(svc_gl_vs_img)); svc_gl_vs_len = (u32)sizeof(svc_gl_vs_img); } + if (READ_ONCE(sema_gl_ps_img) && !svc_gl_ps_len) { + memcpy(svc_gl_ps, svc_gl_ps_img, sizeof(svc_gl_ps_img)); + svc_gl_ps_len = (u32)sizeof(svc_gl_ps_img); + } } /* @@ -8653,6 +8709,7 @@ static u32 svc_gl_open_log; /* bounded section-open witness */ static u32 svc_gl_skip_log; /* bounded flush-skip witness */ static u32 svc_gl_np_log; /* CONT.45 bounded no-param stream witness */ static u32 svc_gl_mark_log; /* CONT.45 bounded 3D-mark-failure witness */ +static u32 svc_gl_draw_args_log; /* r1500 bounded draw-args witness */ /* * SESSION 153-CONTINUED-18 (task 1): the kick NOTIFY executor. * @@ -10691,6 +10748,62 @@ static void svc_gl_flush(struct nv_vgpu_device *vgpu, len / 4u, svc_gr_cand.push_n, len); } } + /* + * r1500: draw-args receipt. The remaining wall is "is the captured + * window a real primitive with a real count?" Decode the window's + * own BEGIN immediate (topology), SET_INDEX_BUFFER_A/B (0x17c8/cc) + * and the E/F + DRAW_INDEX_BUFFER triple (0x17d8/dc/e0: index size, + * first, count) with the same 1+cnt run grammar the replay uses. + * This is read-only and names the exact values the ENGINE will see; + * an index size of 1 means the buffer is read as 16-bit indices. + */ + if ((op_src[0] == 's' || op_src[0] == 'h') && + svc_gl_draw_args_log < 64 && svc_gl.start_off < at_off && + at_off <= len) { + u32 o = svc_gl.start_off; + u32 topo = 0xffffffffu, isz = 0xffffffffu; + u32 first = 0, count = 0; + u64 iva = 0; + + while (o + 4 <= at_off) { + u32 h, op, cnt, ad, w0 = 0, w1 = 0, w2 = 0; + u32 span = 1; + + memcpy(&h, buf + o, 4); + op = (h >> 29) & 7u; + cnt = (h >> 16) & 0xfffu; + ad = (h & 0x1fffu) << 2; + if ((op == 1u || op == 3u || op == 5u) && cnt && + o + 4u + cnt * 4u <= at_off) + span = 1u + cnt; + if (span > 1u) { + memcpy(&w0, buf + o + 4, 4); + if (span > 2u) + memcpy(&w1, buf + o + 8, 4); + if (span > 3u) + memcpy(&w2, buf + o + 12, 4); + } + if (op == 4u && ad == 0x1618u && + topo == 0xffffffffu) + topo = cnt; + if (op == 1u && ad == 0x17c8u && cnt >= 2u) + iva = ((u64)(w0 & 0xffu) << 32) | + (u64)(w1 & 0xfffffffcu); + if ((op == 1u || op == 3u || op == 5u) && + ad == 0x17d8u && cnt >= 3u) { + isz = w0; + first = w1; + count = w2; + } + o += span * 4u; + } + if (topo != 0xffffffffu || iva || isz != 0xffffffffu) { + svc_gl_draw_args_log++; + pr_info("sema-gl: GL-DRAW h=0x%x push=0x%llx topo=%u isz=%u first=%u count=%u iva=0x%llx\n", + ch->h_object, push_va, topo, isz, first, + count, iva); + } + } out: /* * SESSION 149 R15 (M1.1a): preserve the last valid release across -- cgit v1.2.3