summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-04 20:22:07 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-04 20:22:07 -0500
commit6c6b544c73f24cd2b33c04ab0b79df4529520805 (patch)
treeb84a3db4a1a1ad87787a76f36dd9ec79034def1c /kernel/gsp_phys_booter.c
parent1f08cc93b514f7267a1c536a2e61b7ff3afe84a5 (diff)
downloadopen-iov-6c6b544c73f24cd2b33c04ab0b79df4529520805.tar.gz
open-iov-6c6b544c73f24cd2b33c04ab0b79df4529520805.zip
vgsp-gr: authoritative viewport/RT closure - sema_gl_vp_prelude modes 5/6 use live slot 33 (CALL 0x3908) / raw driver words with scaleY=+360, clip 0x0c00/0x0c04 and 0x193c=0x21800 (ZERO_ONE|FRUSTUM_XYZ); sema_gl_rt0_bind binds SET_COLOR_TARGET(0)=0x800 plus SET_CT_SELECT count=2 (the PS has MRT_ENABLE=0 and writes RT0 while the client binds only RT1); both preludes gated to windows with a CALL run so Xorg 2D windows are untouched; r1465: CALL(33) executes (mac=0x21) on the beef window, RT0 bound, DRAW blocked by the 0x1614 pair poison
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c213
1 files changed, 190 insertions, 23 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 8da7abb..5aeee31 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -19279,6 +19279,16 @@ bool gsp_phys_rmcall_gr_sph_bind_value(void)
* are IEEE-754 floats. None of the words is an address operand, so
* the sequence is emitted verbatim (no relocation pass). Default 0
* keeps the legacy window bytes.
+ *
+ * Mode 5 is the driver's own viewport macro path: CALL_MME_MACRO(33)
+ * (0x3908) with (x,y,w,h) = (0,0,1280,720) followed by the macro's
+ * appended state. Mode 6 is the raw equivalent without the CALL
+ * (scale/offset included, scaleY = +360). Header check against the
+ * decoder above: 0xa0040e42 = op 5 ONE_INC, cnt 4, method 0x3908
+ * (four data words follow); 0x8001064b = op 4 IMM, data 1 in the
+ * count field, method 0x192c (single word, consumes no data);
+ * 0x2001064f + 0x00021800 = op 1 INC, cnt 1, method 0x193c (one
+ * data word).
*/
#define GSP_PHYS_GR_VP_PRE_WORDS 15u
static const u32 gsp_phys_gr_vp_pre[GSP_PHYS_GR_VP_PRE_WORDS] = {
@@ -19292,6 +19302,25 @@ static const u32 gsp_phys_gr_vp_pre[GSP_PHYS_GR_VP_PRE_WORDS] = {
0x3f800000u,
};
+#define GSP_PHYS_GR_VP_PRE_M5_WORDS 17u
+static const u32 gsp_phys_gr_vp_pre_m5[GSP_PHYS_GR_VP_PRE_M5_WORDS] = {
+ 0xa0040e42u, 0x00000000u, 0x00000000u, 0x00000500u, 0x000002d0u,
+ 0x20010282u, 0x3f000000u, 0x20010285u, 0x3f000000u,
+ 0x20020302u, 0x00000000u, 0x3f800000u,
+ 0x20010649u, 0x00000000u, 0x8001064bu,
+ 0x2001064fu, 0x00021800u,
+};
+
+#define GSP_PHYS_GR_VP_PRE_M6_WORDS 19u
+static const u32 gsp_phys_gr_vp_pre_m6[GSP_PHYS_GR_VP_PRE_M6_WORDS] = {
+ 0x20020280u, 0x44200000u, 0x43b40000u,
+ 0x20040282u, 0x3f000000u, 0x44200000u, 0x43b40000u, 0x3f000000u,
+ 0x20020300u, 0x05000000u, 0x02d00000u,
+ 0x20020302u, 0x00000000u, 0x3f800000u,
+ 0x20010649u, 0x00000000u, 0x8001064bu,
+ 0x2001064fu, 0x00021800u,
+};
+
static u32 gsp_phys_gr_vp_pre_len(int mode)
{
switch (mode) {
@@ -19302,11 +19331,27 @@ static u32 gsp_phys_gr_vp_pre_len(int mode)
case 3:
case 4:
return GSP_PHYS_GR_VP_PRE_WORDS;
+ case 5:
+ return GSP_PHYS_GR_VP_PRE_M5_WORDS;
+ case 6:
+ return GSP_PHYS_GR_VP_PRE_M6_WORDS;
default:
return 0u;
}
}
+static const u32 *gsp_phys_gr_vp_pre_src(int mode)
+{
+ switch (mode) {
+ case 5:
+ return gsp_phys_gr_vp_pre_m5;
+ case 6:
+ return gsp_phys_gr_vp_pre_m6;
+ default:
+ return gsp_phys_gr_vp_pre;
+ }
+}
+
/*
* Insertion word offset for the viewport prelude inside an emitted 3D
* window. The walk is the same run grammar as the MME-WINRUN census and
@@ -19316,8 +19361,8 @@ static u32 gsp_phys_gr_vp_pre_len(int mode)
* never split. pos 1 stops at the first run touching the CALL_MME
* family 0x3800..0x39fc (after the window's state binds, ahead of its
* macro calls); pos 2 stops at the first run touching 0x3910. A window
- * without the requested run returns n so the caller falls back to the
- * head.
+ * without the requested run returns n so the caller can skip it
+ * (non-draw window).
*/
static u32 gsp_phys_gr_vp_insert_off(const u32 *win, u32 n, int pos)
{
@@ -19351,17 +19396,73 @@ static u32 gsp_phys_gr_vp_insert_off(const u32 *win, u32 n, int pos)
return n;
}
+/*
+ * First-run offset of a method in a window, using the same run grammar
+ * as the scanners above (op 1/3/5 carry 1+cnt data words; op 5 writes
+ * only its header method, op 4 IMM carries data in the count field and
+ * is a single word). Returns n when no run touches the method.
+ */
+static u32 gsp_phys_gr_method_run_off(const u32 *win, u32 n, u32 method)
+{
+ u32 r = 0;
+
+ while (r < n) {
+ u32 h = win[r];
+ u32 op = (h >> 29) & 7u;
+ u32 cnt = (h >> 16) & 0x1fffu;
+ u32 span = 1u, k;
+
+ if ((op == 1u || op == 3u || op == 5u) && cnt &&
+ r + 1u + cnt <= n)
+ span = 1u + cnt;
+ for (k = 0; k < span; k++) {
+ u32 m = ((h & 0xfffu) << 2) + 4u * k;
+
+ if (k && op != 1u && op != 3u)
+ break;
+ if (m == method)
+ return r;
+ }
+ r += span;
+ }
+ return n;
+}
+
+/*
+ * The client's pixel shader has MRT_ENABLE=0 and writes RT0 (0x800),
+ * while its init push selects CT target0=0 (0x121c = 0x0fac6881) and
+ * the replayed draw window binds only RT1 (0x840) - so the colour
+ * write has no enabled target. When sema_gl_rt0_bind=1 and the window
+ * does not write 0x800 itself, insert the missing RT0 bind (same
+ * 1280x720 X8R8G8B8 target at B=0x0a000000) plus a count-2 CT select
+ * (target0=0, target1=1) ahead of the window's first 0x840 run, and
+ * only when the window carries a CALL run (0x3800..0x39fc); a non-draw
+ * window is left unchanged.
+ * Constant words, no relocation. Default 0 is a strict no-op.
+ */
+#define GSP_PHYS_GR_RT0_BIND_WORDS 9u
+static const u32 gsp_phys_gr_rt0_bind[GSP_PHYS_GR_RT0_BIND_WORDS] = {
+ 0x20060200u, 0x00000000u, 0x0a000000u, 0x00000500u, 0x000002d0u,
+ 0x000000e6u, 0x00000040u, 0x20010487u, 0x0fac6882u,
+};
+
+static int gsp_phys_rmcall_gr_rt0_bind;
+module_param_named(sema_gl_rt0_bind, gsp_phys_rmcall_gr_rt0_bind, int,
+ 0644);
+MODULE_PARM_DESC(sema_gl_rt0_bind,
+ "Insert the missing RT0 colour-target bind and count-2 SET_CT_SELECT ahead of a replayed window's first 0x840 (RT1) run when the window does not bind 0x800 and carries a CALL run (non-draw windows are left unchanged; default 0 = off)");
+
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; 4 = same clip rect with the verified pixel-unit encoding)");
+ "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; 4 = same clip rect with the verified pixel-unit encoding; 5 = driver viewport macro CALL(33) 0x3908 + appended state; 6 = raw mode-5 state without the CALL)");
static int gsp_phys_rmcall_gr_vp_prelude_pos = 1;
module_param_named(sema_gl_vp_prelude_pos, gsp_phys_rmcall_gr_vp_prelude_pos,
int, 0644);
MODULE_PARM_DESC(sema_gl_vp_prelude_pos,
- "Insertion point of the synthesized viewport prelude in a replayed 3D window (0 = window head (legacy); 1 = before the first CALL run 0x3800..0x39fc, after the state binds (default); 2 = before the first 0x3910 run); falls back to the head when no such run exists)");
+ "Insertion point of the synthesized viewport prelude in a replayed 3D window (0 = window head (legacy); 1 = before the first CALL run 0x3800..0x39fc, after the state binds (default); 2 = before the first 0x3910 run); pos 1/2 leave a window without the requested run unchanged (non-draw window), only 0 inserts without a CALL run)");
/*
* CONT-119 (r1450): the BINDING words of the synthesized stage-2/5
@@ -28647,38 +28748,39 @@ gr_page_unmapped:
* 0x2080 SET_PIPELINE(2)=0x21 run - has landed before the
* macro calls, or ahead of the first 0x3910 run. The scan
* uses the MME-WINRUN run grammar; a window without the
- * requested run falls back to the head. The words carry no
- * address operand, so no relocation pass is applied - they
- * are emitted verbatim. Same block-size guard as SPH-BIND /
- * SURF-PRELUDE.
+ * requested run is left unchanged (non-draw window); only
+ * pos 0 inserts at the head without a CALL run. The words
+ * carry no address operand, so no relocation pass is
+ * applied - they are emitted verbatim. Same block-size
+ * guard as SPH-BIND / SURF-PRELUDE.
*/
{
int vp_mode = READ_ONCE(gsp_phys_rmcall_gr_vp_prelude);
int vp_pos = READ_ONCE(gsp_phys_rmcall_gr_vp_prelude_pos);
u32 vpn = gsp_phys_gr_vp_pre_len(vp_mode);
+ const u32 *vp_src = gsp_phys_gr_vp_pre_src(vp_mode);
- if (vpn) {
+ if (vpn && vp_src) {
u32 vp_at = 0;
+ bool vp_skip = false;
if (vp_pos == 1 || vp_pos == 2) {
vp_at = gsp_phys_gr_vp_insert_off(
stream_patch, win3d_n, vp_pos);
if (vp_at >= win3d_n) {
- static bool vp_fb_log;
-
- vp_at = 0;
- if (!vp_fb_log) {
- vp_fb_log = true;
- pr_info("vgsp-gr: VP-PRELUDE pos=%d found no %s run; fallback to head (window=%u mode=%d)\n",
- vp_pos,
- vp_pos == 2 ?
- "0x3910" :
- "CALL",
- win3d_n, vp_mode);
+ static bool vp_nd_log;
+
+ vp_skip = true;
+ if (!vp_nd_log) {
+ vp_nd_log = true;
+ pr_info("vgsp-gr: VP-PRELUDE skipped (no CALL run; non-draw window) window=%u pos=%d mode=%d\n",
+ win3d_n, vp_pos,
+ vp_mode);
}
}
}
- if (win3d_n + vpn + 2u + 8u <=
+ if (!vp_skip &&
+ win3d_n + vpn + 2u + 8u <=
GSP_PHYS_RMCALL_GR_METHOD_WORDS) {
static u32 vp_emit_log;
u32 vp_old = win3d_n;
@@ -28688,7 +28790,7 @@ gr_page_unmapped:
(size_t)(win3d_n - vp_at) *
4u);
memcpy(&stream_patch[vp_at],
- gsp_phys_gr_vp_pre,
+ vp_src,
(size_t)vpn * 4u);
win3d_n += vpn;
if (vp_emit_log < 16u) {
@@ -28698,7 +28800,7 @@ gr_page_unmapped:
vp_old, win3d_n,
vp_at);
}
- } else {
+ } else if (!vp_skip) {
static u32 vp_skip_log;
if (vp_skip_log < 8u) {
@@ -28712,6 +28814,71 @@ gr_page_unmapped:
}
}
/*
+ * Missing RT0 bind (see the sema_gl_rt0_bind comment).
+ * Insert the RT0 colour-target run and the count-2 CT
+ * select ahead of the window's first 0x840 (RT1) run.
+ * Skip when the window binds 0x800 itself; skip when it
+ * has no 0x840 anchor. Same run grammar and block-size
+ * guard as the viewport prelude; constant words, no
+ * relocation pass.
+ */
+ if (READ_ONCE(gsp_phys_rmcall_gr_rt0_bind)) {
+ static u32 rt0_emit_log;
+ static u32 rt0_skip_log;
+ static bool rt0_nd_log;
+ u32 rt0_at = gsp_phys_gr_method_run_off(
+ stream_patch, win3d_n, 0x840u);
+ u32 rt0_have = gsp_phys_gr_method_run_off(
+ stream_patch, win3d_n, 0x800u);
+ u32 rt0_call = gsp_phys_gr_vp_insert_off(
+ stream_patch, win3d_n, 1);
+
+ if (rt0_call >= win3d_n) {
+ if (!rt0_nd_log) {
+ rt0_nd_log = true;
+ pr_info("vgsp-gr: RT0-BIND skipped (non-draw window) window=%u\n",
+ win3d_n);
+ }
+ } else if (rt0_have < win3d_n) {
+ if (rt0_skip_log < 8u) {
+ rt0_skip_log++;
+ pr_info("vgsp-gr: RT0-BIND skipped (window already binds 0x800) window=%u at=%u\n",
+ win3d_n, rt0_at);
+ }
+ } else if (rt0_at >= win3d_n) {
+ if (rt0_skip_log < 8u) {
+ rt0_skip_log++;
+ pr_info("vgsp-gr: RT0-BIND skipped (no 0x840 run) window=%u\n",
+ win3d_n);
+ }
+ } else if (win3d_n + GSP_PHYS_GR_RT0_BIND_WORDS +
+ 2u + 8u <=
+ GSP_PHYS_RMCALL_GR_METHOD_WORDS) {
+ u32 rt0_old = win3d_n;
+
+ memmove(&stream_patch[rt0_at +
+ GSP_PHYS_GR_RT0_BIND_WORDS],
+ &stream_patch[rt0_at],
+ (size_t)(win3d_n - rt0_at) * 4u);
+ memcpy(&stream_patch[rt0_at],
+ gsp_phys_gr_rt0_bind,
+ sizeof(gsp_phys_gr_rt0_bind));
+ win3d_n += GSP_PHYS_GR_RT0_BIND_WORDS;
+ if (rt0_emit_log < 16u) {
+ rt0_emit_log++;
+ pr_info("vgsp-gr: RT0-BIND emitted window=%u->%u at=%u\n",
+ rt0_old, win3d_n, rt0_at);
+ }
+ } else {
+ if (rt0_skip_log < 8u) {
+ rt0_skip_log++;
+ pr_info("vgsp-gr: RT0-BIND skipped (no room) window=%u cap=%u\n",
+ 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
* SET_PIPELINE_PROGRAM_ADDRESS pairs and any other recognised