diff --git a/src/nouveau/compiler/nak.rs b/src/nouveau/compiler/nak.rs index fa8456c2865..e3cf2666b3b 100644 --- a/src/nouveau/compiler/nak.rs +++ b/src/nouveau/compiler/nak.rs @@ -239,10 +239,10 @@ fn encode_hdr_for_nir( let zs_self_dep = fs_key.map_or(false, |key| key.zs_self_dep); cw0.set_bit(15, fs_info.uses_kill || zs_self_dep); } - cw0.set_bit(16, false /* TODO: DoesGlobalStore */); + cw0.set_bit(16, shader_info.writes_global_mem); cw0.set_field(17..21, 1_u32 /* SassVersion */); cw0.set_field(21..26, 0_u32 /* Reserved */); - cw0.set_bit(26, false /* TODO: DoesLoadOrStore */); + cw0.set_bit(26, shader_info.uses_global_mem); cw0.set_bit(27, false /* TODO: DoesFp64 */); cw0.set_field(28..32, 0_u32 /* StreamOutMask */); @@ -486,6 +486,8 @@ pub extern "C" fn nak_compile_shader( eprintln!("NAK IR:\n{}", &s); } + s.gather_global_mem_usage(); + let info = nak_shader_info { stage: nir.info.stage(), num_gprs: s.info.num_gprs, diff --git a/src/nouveau/compiler/nak_from_nir.rs b/src/nouveau/compiler/nak_from_nir.rs index 5c8a6fe82f8..101e70b4b8d 100644 --- a/src/nouveau/compiler/nak_from_nir.rs +++ b/src/nouveau/compiler/nak_from_nir.rs @@ -21,6 +21,8 @@ fn init_info_from_nir(nir: &nir_shader, sm: u8) -> ShaderInfo { sm: sm, num_gprs: 0, tls_size: nir.scratch_size, + uses_global_mem: false, + writes_global_mem: false, stage: match nir.info.stage() { MESA_SHADER_COMPUTE => { ShaderStageInfo::Compute(ComputeShaderInfo { diff --git a/src/nouveau/compiler/nak_ir.rs b/src/nouveau/compiler/nak_ir.rs index b710911aa5b..c55cf8b3043 100644 --- a/src/nouveau/compiler/nak_ir.rs +++ b/src/nouveau/compiler/nak_ir.rs @@ -4119,6 +4119,27 @@ impl Instr { } } + pub fn uses_global_mem(&self) -> bool { + match &self.op { + Op::Atom(op) => op.mem_space != MemSpace::Local, + Op::AtomCas(op) => op.mem_space != MemSpace::Local, + Op::Ld(op) => op.access.space != MemSpace::Local, + Op::St(op) => op.access.space != MemSpace::Local, + Op::SuAtom(_) | Op::SuLd(_) | Op::SuSt(_) => true, + _ => false, + } + } + + pub fn writes_global_mem(&self) -> bool { + match &self.op { + Op::Atom(op) => op.mem_space == MemSpace::Global, + Op::AtomCas(op) => op.mem_space == MemSpace::Global, + Op::St(op) => op.access.space == MemSpace::Global, + Op::SuAtom(_) | Op::SuSt(_) => true, + _ => false, + } + } + pub fn can_eliminate(&self) -> bool { match self.op { Op::ASt(_) @@ -4475,6 +4496,8 @@ pub struct ShaderInfo { pub sm: u8, pub num_gprs: u8, pub tls_size: u32, + pub uses_global_mem: bool, + pub writes_global_mem: bool, pub stage: ShaderStageInfo, } @@ -4514,6 +4537,28 @@ impl Shader { } }) } + + pub fn gather_global_mem_usage(&mut self) { + if let ShaderStageInfo::Compute(_) = self.info.stage { + return; + } + + let mut uses_global_mem = false; + let mut writes_global_mem = false; + + self.for_each_instr(&mut |instr| { + if !uses_global_mem { + uses_global_mem = instr.uses_global_mem(); + } + + if !writes_global_mem { + writes_global_mem = instr.writes_global_mem(); + } + }); + + self.info.uses_global_mem = uses_global_mem; + self.info.writes_global_mem = writes_global_mem; + } } impl fmt::Display for Shader {