summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 5071314..e7a0172 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -10447,6 +10447,51 @@ int gsp_sema_gl_sph_blob_version(void)
}
/*
+ * r1625: the engine-visible known-good program image for a refused
+ * program page (CODESRC-SUSPECT relocation in the GR launch builder).
+ * A program page the engine is about to I-fetch must contain an SPH+SASS
+ * image, not raw filler: the client's per-window program upload never
+ * ran on this lane, so the page reads empty while the client's own
+ * SPH+SASS image is already published (`svc_gl_vs`/`svc_gl_ps`, the
+ * captured upload or the built-in known-good image). Return the image
+ * for the pipeline stage the section bound at this VA (the sticky
+ * SET_PIPELINE_SHADER TYPE: 5 = PIXEL, otherwise VTG), falling back to
+ * the PIXEL image - the observed empty-program class is the pixel stage
+ * (its 0x2154 upload was never captured). NULL when no image is loaded.
+ */
+const u8 *gsp_sema_gl_prog_img(u64 va, u32 *len_out)
+{
+ u64 page = va & ~(u64)(SEMA_PAGE_SIZE - 1);
+ u32 i, slot = 0, t = 0xff;
+
+ if (len_out)
+ *len_out = 0;
+ for (i = 0; i < svc_gl.n_progs && i < SVC_GL_PROG_MAX; i++) {
+ if ((svc_gl.progs[i] & ~(u64)(SEMA_PAGE_SIZE - 1)) != page)
+ continue;
+ slot = svc_gl.prog_slot[i] < 32 ? svc_gl.prog_slot[i] : 0;
+ t = svc_gl_shader_type[slot];
+ break;
+ }
+ if (t != 5 && t != 0xff && svc_gl_vs_len) {
+ if (len_out)
+ *len_out = svc_gl_vs_len;
+ return svc_gl_vs;
+ }
+ if (svc_gl_ps_len) {
+ if (len_out)
+ *len_out = svc_gl_ps_len;
+ return svc_gl_ps;
+ }
+ if (svc_gl_vs_len) {
+ if (len_out)
+ *len_out = svc_gl_vs_len;
+ return svc_gl_vs;
+ }
+ return NULL;
+}
+
+/*
* SESSION 153 (GL client draw sections): the GL client's own per-frame
* pushes bind TURING_A (0xC597) exactly like the X server's one-shot
* section, but carry no program/param/release operands at all (measured: