From 2a2ef36852c6f8b68cfaac31c3ffd2cb48b3387f Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 7 May 2026 11:25:26 -0400 Subject: [PATCH] i915/corm: use utemp for vec texcoord to avoid phase boundaries When a vec construction feeds a single-use tex instruction, use a utemp (unpreserved temp) instead of an R-file temp for the vec dest. R-file temps written by ALU trigger tex indirect phase boundaries when read by subsequent texld instructions; utemps do not. Preserve the utemp allocation across i915_release_utemps so the value survives until the texld consumer reads it. shader-db (I915_FS=nir): 249/403 compiled, 3495 alu shader-db (I915_FS=both): nir won 249 (26 identical, 1 tied, 217 better, 5 only), 40 TGSI, 114 neither Assisted-by: Claude --- src/gallium/drivers/i915/i915_fpc_nir.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/gallium/drivers/i915/i915_fpc_nir.c b/src/gallium/drivers/i915/i915_fpc_nir.c index 15e935cd67b..99f1b664142 100644 --- a/src/gallium/drivers/i915/i915_fpc_nir.c +++ b/src/gallium/drivers/i915/i915_fpc_nir.c @@ -523,6 +523,7 @@ emit_alu(struct nir_to_i915 *c, nir_alu_instr *alu) /* If this vec's only consumer is a store_output, write directly * to the output register instead of going through a temp. + * If it's a tex instruction, use a utemp to avoid phase boundaries. */ if (list_is_singular(&def->uses)) { nir_src *use = list_first_entry(&def->uses, nir_src, use_link); @@ -539,6 +540,11 @@ emit_alu(struct nir_to_i915 *c, nir_alu_instr *alu) dest = out; set_ureg(c, def, dest); } + } else if (use_instr->type == nir_instr_type_tex) { + i915_release_temp(p, GET_UREG_NR(dest)); + uint32_t utemp = i915_get_utemp(p); + dest = utemp; + set_ureg(c, def, dest); } } @@ -757,7 +763,11 @@ emit_alu(struct nir_to_i915 *c, nir_alu_instr *alu) if (p->csr == pre_csr + 3) c->def_csr[def->index] = pre_csr; + uint32_t save = 0; + if (GET_UREG_TYPE(dest) == REG_TYPE_U) + save = p->utemp_flag & (1 << GET_UREG_NR(dest)); i915_release_utemps(p); + p->utemp_flag |= save; } static uint32_t