mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 16:00:08 +01:00
nak/from_nir: Emit uniform instructions when !divergent
The really tricky case here is phis, which may have a uniform def even though some of the srcs are non-uniform. This happens because of the restriction elsewhere that requires UGPRs and UPreds to only ever be written in uniform control-flow. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29591>
This commit is contained in:
parent
3dfd92888a
commit
d09d3f5246
3 changed files with 36 additions and 2 deletions
|
|
@ -20,6 +20,7 @@ enum DebugFlags {
|
||||||
Serial,
|
Serial,
|
||||||
Spill,
|
Spill,
|
||||||
Annotate,
|
Annotate,
|
||||||
|
NoUgpr,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Debug {
|
pub struct Debug {
|
||||||
|
|
@ -43,6 +44,7 @@ impl Debug {
|
||||||
"serial" => flags |= 1 << DebugFlags::Serial as u8,
|
"serial" => flags |= 1 << DebugFlags::Serial as u8,
|
||||||
"spill" => flags |= 1 << DebugFlags::Spill as u8,
|
"spill" => flags |= 1 << DebugFlags::Spill as u8,
|
||||||
"annotate" => flags |= 1 << DebugFlags::Annotate as u8,
|
"annotate" => flags |= 1 << DebugFlags::Annotate as u8,
|
||||||
|
"nougpr" => flags |= 1 << DebugFlags::NoUgpr as u8,
|
||||||
unk => eprintln!("Unknown NAK_DEBUG flag \"{}\"", unk),
|
unk => eprintln!("Unknown NAK_DEBUG flag \"{}\"", unk),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -68,6 +70,10 @@ pub trait GetDebugFlags {
|
||||||
fn annotate(&self) -> bool {
|
fn annotate(&self) -> bool {
|
||||||
self.debug_flags() & (1 << DebugFlags::Annotate as u8) != 0
|
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<Debug> = OnceLock::new();
|
pub static DEBUG: OnceLock<Debug> = OnceLock::new();
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
use crate::api::GetDebugFlags;
|
use crate::api::GetDebugFlags;
|
||||||
use crate::api::DEBUG;
|
use crate::api::DEBUG;
|
||||||
|
use crate::builder::*;
|
||||||
use crate::cfg::CFGBuilder;
|
use crate::cfg::CFGBuilder;
|
||||||
use crate::ir::*;
|
use crate::ir::*;
|
||||||
use crate::nir::*;
|
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());
|
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());
|
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);
|
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_ {
|
match ni.type_ {
|
||||||
nir_instr_type_alu => {
|
nir_instr_type_alu => {
|
||||||
self.parse_alu(&mut b, ni.as_alu().unwrap())
|
self.parse_alu(&mut b, ni.as_alu().unwrap())
|
||||||
|
|
|
||||||
|
|
@ -467,6 +467,7 @@ pub trait NirInstr {
|
||||||
fn as_load_const(&self) -> Option<&nir_load_const_instr>;
|
fn as_load_const(&self) -> Option<&nir_load_const_instr>;
|
||||||
fn as_undef(&self) -> Option<&nir_undef_instr>;
|
fn as_undef(&self) -> Option<&nir_undef_instr>;
|
||||||
fn as_phi(&self) -> Option<&nir_phi_instr>;
|
fn as_phi(&self) -> Option<&nir_phi_instr>;
|
||||||
|
fn def(&self) -> Option<&nir_def>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NirInstr for nir_instr {
|
impl NirInstr for nir_instr {
|
||||||
|
|
@ -532,6 +533,13 @@ impl NirInstr for nir_instr {
|
||||||
None
|
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 {
|
pub trait NirBlock {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue