diff --git a/src/nouveau/compiler/nak/api.rs b/src/nouveau/compiler/nak/api.rs index 3c45c9fe396..5e8aab8dba5 100644 --- a/src/nouveau/compiler/nak/api.rs +++ b/src/nouveau/compiler/nak/api.rs @@ -20,6 +20,7 @@ enum DebugFlags { Serial, Spill, Annotate, + NoUgpr, } pub struct Debug { @@ -43,6 +44,7 @@ impl Debug { "serial" => flags |= 1 << DebugFlags::Serial as u8, "spill" => flags |= 1 << DebugFlags::Spill as u8, "annotate" => flags |= 1 << DebugFlags::Annotate as u8, + "nougpr" => flags |= 1 << DebugFlags::NoUgpr as u8, unk => eprintln!("Unknown NAK_DEBUG flag \"{}\"", unk), } } @@ -68,6 +70,10 @@ pub trait GetDebugFlags { fn annotate(&self) -> bool { self.debug_flags() & (1 << DebugFlags::Annotate as u8) != 0 } + + fn no_ugpr(&self) -> bool { + self.debug_flags() & (1 << DebugFlags::NoUgpr as u8) != 0 + } } pub static DEBUG: OnceLock = OnceLock::new(); diff --git a/src/nouveau/compiler/nak/from_nir.rs b/src/nouveau/compiler/nak/from_nir.rs index 4ae8f2c8ce8..64604d88d3a 100644 --- a/src/nouveau/compiler/nak/from_nir.rs +++ b/src/nouveau/compiler/nak/from_nir.rs @@ -5,6 +5,7 @@ use crate::api::GetDebugFlags; use crate::api::DEBUG; +use crate::builder::*; use crate::cfg::CFGBuilder; use crate::ir::*; use crate::nir::*; @@ -3122,10 +3123,23 @@ impl<'a> ShaderFromNir<'a> { }); } + let uniform = !nb.divergent + && self.info.sm >= 75 + && !DEBUG.no_ugpr() + && !np.def.divergent; + + // This should be ensured by nak_nir_lower_cf() + if uniform { + for ps in np.iter_srcs() { + assert!(!ps.pred().divergent); + } + } + + let mut b = UniformBuilder::new(&mut b, uniform); let dst = alloc_ssa_for_nir(&mut b, np.def.as_def()); - for (i, dst) in dst.iter().enumerate() { + for i in 0..dst.len() { let phi_id = phi_map.get_phi_id(np, i.try_into().unwrap()); - phi.dsts.push(phi_id, (*dst).into()); + phi.dsts.push(phi_id, dst[i].into()); } self.set_ssa(np.def.as_def(), dst); } @@ -3148,6 +3162,12 @@ impl<'a> ShaderFromNir<'a> { }); } + let uniform = !nb.divergent + && self.info.sm >= 75 + && !DEBUG.no_ugpr() + && ni.def().is_some_and(|d| !d.divergent); + let mut b = UniformBuilder::new(&mut b, uniform); + match ni.type_ { nir_instr_type_alu => { self.parse_alu(&mut b, ni.as_alu().unwrap()) diff --git a/src/nouveau/compiler/nak/nir.rs b/src/nouveau/compiler/nak/nir.rs index 07087e1fb07..4ba27a5c54e 100644 --- a/src/nouveau/compiler/nak/nir.rs +++ b/src/nouveau/compiler/nak/nir.rs @@ -467,6 +467,7 @@ pub trait NirInstr { fn as_load_const(&self) -> Option<&nir_load_const_instr>; fn as_undef(&self) -> Option<&nir_undef_instr>; fn as_phi(&self) -> Option<&nir_phi_instr>; + fn def(&self) -> Option<&nir_def>; } impl NirInstr for nir_instr { @@ -532,6 +533,13 @@ impl NirInstr for nir_instr { None } } + + fn def(&self) -> Option<&nir_def> { + unsafe { + let def = nir_instr_def(self as *const _ as *mut _); + NonNull::new(def).map(|d| d.as_ref()) + } + } } pub trait NirBlock {