summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c125
1 files changed, 105 insertions, 20 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 4903d5d..8da7abb 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -19270,9 +19270,15 @@ bool gsp_phys_rmcall_gr_sph_bind_value(void)
* 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.
+ * mode 3 adds the 1280x720 clip rect. Mode 4 is the same words with
+ * the clip-rect encoding verified against the class definitions
+ * (X0/Y0 in bits 15:0, WIDTH/HEIGHT in bits 31:16, integer pixel
+ * units) and the producer's (size << 16) | origin packing, so a
+ * 1280x720 target at a top-left origin emits 0x05000000,
+ * 0x02d00000, 0.0f (0x00000000) and 1.0f (0x3f800000); min_z/max_z
+ * 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.
*/
#define GSP_PHYS_GR_VP_PRE_WORDS 15u
static const u32 gsp_phys_gr_vp_pre[GSP_PHYS_GR_VP_PRE_WORDS] = {
@@ -19294,17 +19300,68 @@ static u32 gsp_phys_gr_vp_pre_len(int mode)
case 2:
return 10u;
case 3:
+ case 4:
return GSP_PHYS_GR_VP_PRE_WORDS;
default:
return 0u;
}
}
+/*
+ * 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
+ * the CALL drop pass (op = hdr[31:29], count = hdr[28:16] for op 1/3/5,
+ * run method = hdr[11:0] << 2; multi-word INC/NON_INCR runs cover
+ * m + 4k, IMM/ONE_INCR entries cover only their own method). Runs are
+ * 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.
+ */
+static u32 gsp_phys_gr_vp_insert_off(const u32 *win, u32 n, int pos)
+{
+ u32 r = 0;
+
+ if (pos != 1 && pos != 2)
+ return n;
+ 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 (pos == 1) {
+ if (m >= 0x3800u && m <= 0x39fcu)
+ return r;
+ } else if (m == 0x3910u) {
+ return r;
+ }
+ }
+ r += span;
+ }
+ return n;
+}
+
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)");
+ "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)");
+
+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)");
/*
* CONT-119 (r1450): the BINDING words of the synthesized stage-2/5
@@ -28583,44 +28640,72 @@ 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.
+ * sema_gl_vp_prelude comment). Insert the chosen literal
+ * sequence at sema_gl_vp_prelude_pos: the window head
+ * (legacy), immediately ahead of the first CALL run
+ * (0x3800..0x39fc) so every state bind - including the
+ * 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.
*/
{
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);
if (vpn) {
+ u32 vp_at = 0;
+
+ 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);
+ }
+ }
+ }
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,
+ memmove(&stream_patch[vp_at + vpn],
+ &stream_patch[vp_at],
+ (size_t)(win3d_n - vp_at) *
+ 4u);
+ memcpy(&stream_patch[vp_at],
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);
+ pr_info("vgsp-gr: VP-PRELUDE mode=%d pos=%d words=%u window=%u->%u at=%u\n",
+ vp_mode, vp_pos, vpn,
+ vp_old, win3d_n,
+ vp_at);
}
} 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,
+ pr_info("vgsp-gr: VP-PRELUDE skipped (no room) mode=%d pos=%d words=%u window=%u cap=%u\n",
+ vp_mode, vp_pos, vpn,
+ win3d_n,
GSP_PHYS_RMCALL_GR_METHOD_WORDS);
}
}