diff --git a/src/nouveau/compiler/nak/api.rs b/src/nouveau/compiler/nak/api.rs index d665853d834..71aaa730296 100644 --- a/src/nouveau/compiler/nak/api.rs +++ b/src/nouveau/compiler/nak/api.rs @@ -2,11 +2,9 @@ // SPDX-License-Identifier: MIT use crate::from_nir::*; -use crate::ir::{ShaderInfo, ShaderIoInfo, ShaderModel, ShaderStageInfo}; -use crate::sm20::ShaderModel20; -use crate::sm32::ShaderModel32; -use crate::sm50::ShaderModel50; -use crate::sm70::ShaderModel70; +use crate::ir::{ + ShaderInfo, ShaderIoInfo, ShaderModel, ShaderModelInfo, ShaderStageInfo, +}; use crate::sph; use compiler::bindings::*; @@ -435,18 +433,7 @@ fn nak_compile_shader_internal( Some(unsafe { &*fs_key }) }; - let sm: Box = if nak.sm >= 70 { - Box::new(ShaderModel70::new(nak.sm)) - } else if nak.sm >= 50 { - Box::new(ShaderModel50::new(nak.sm)) - } else if nak.sm >= 32 { - Box::new(ShaderModel32::new(nak.sm)) - } else if nak.sm >= 20 { - Box::new(ShaderModel20::new(nak.sm)) - } else { - panic!("Unsupported shader model"); - }; - + let sm = Box::new(ShaderModelInfo::new(nak.sm)); let mut s = nak_shader_from_nir(nak, nir, sm.as_ref()); if DEBUG.print() { diff --git a/src/nouveau/compiler/nak/hw_tests.rs b/src/nouveau/compiler/nak/hw_tests.rs index e8a428c4a5a..d9ff7ca49f0 100644 --- a/src/nouveau/compiler/nak/hw_tests.rs +++ b/src/nouveau/compiler/nak/hw_tests.rs @@ -4,10 +4,6 @@ use crate::api::{GetDebugFlags, ShaderBin, DEBUG}; use crate::hw_runner::{Context, Runner, BO, CB0}; use crate::ir::*; -use crate::sm20::ShaderModel20; -use crate::sm32::ShaderModel32; -use crate::sm50::ShaderModel50; -use crate::sm70::ShaderModel70; use acorn::Acorn; use compiler::bindings::MESA_SHADER_COMPUTE; @@ -41,17 +37,7 @@ impl RunSingleton { let run = Runner::new(dev_id); let sm_nr = run.dev_info().sm; - let sm: Box = if sm_nr >= 70 { - Box::new(ShaderModel70::new(sm_nr)) - } else if sm_nr >= 50 { - Box::new(ShaderModel50::new(sm_nr)) - } else if sm_nr >= 32 { - Box::new(ShaderModel32::new(sm_nr)) - } else if sm_nr >= 20 { - Box::new(ShaderModel20::new(sm_nr)) - } else { - panic!("Unsupported shader model"); - }; + let sm = Box::new(ShaderModelInfo::new(sm_nr)); RunSingleton { sm, run } }) } diff --git a/src/nouveau/compiler/nak/ir.rs b/src/nouveau/compiler/nak/ir.rs index 0dd22c42852..9949fe7d4ea 100644 --- a/src/nouveau/compiler/nak/ir.rs +++ b/src/nouveau/compiler/nak/ir.rs @@ -9,6 +9,10 @@ use nak_bindings::*; pub use crate::builder::{Builder, InstrBuilder, SSABuilder, SSAInstrBuilder}; use crate::legalize::LegalizeBuilder; +use crate::sm20::ShaderModel20; +use crate::sm32::ShaderModel32; +use crate::sm50::ShaderModel50; +use crate::sm70::ShaderModel70; use crate::sph::{OutputTopology, PixelImap}; pub use crate::ssa_value::*; use compiler::as_slice::*; @@ -9299,6 +9303,114 @@ pub trait ShaderModel { fn encode_shader(&self, s: &Shader<'_>) -> Vec; } +pub struct ShaderModelInfo { + sm: u8, +} + +impl ShaderModelInfo { + pub fn new(sm: u8) -> Self { + ShaderModelInfo { sm } + } +} + +macro_rules! sm_match { + ($self: expr, |$x: ident| $y: expr) => { + if $self.sm >= 70 { + let $x = ShaderModel70::new($self.sm); + $y + } else if $self.sm >= 50 { + let $x = ShaderModel50::new($self.sm); + $y + } else if $self.sm >= 32 { + let $x = ShaderModel32::new($self.sm); + $y + } else if $self.sm >= 20 { + let $x = ShaderModel20::new($self.sm); + $y + } else { + panic!("Unsupported shader model"); + } + }; +} + +impl ShaderModel for ShaderModelInfo { + fn sm(&self) -> u8 { + self.sm + } + + fn num_regs(&self, file: RegFile) -> u32 { + sm_match!(self, |sm| sm.num_regs(file)) + } + fn hw_reserved_gprs(&self) -> u32 { + sm_match!(self, |sm| sm.hw_reserved_gprs()) + } + fn crs_size(&self, max_crs_depth: u32) -> u32 { + sm_match!(self, |sm| sm.crs_size(max_crs_depth)) + } + fn op_can_be_uniform(&self, op: &Op) -> bool { + sm_match!(self, |sm| sm.op_can_be_uniform(op)) + } + + /// Latency before another non-NOP can execute + fn exec_latency(&self, op: &Op) -> u32 { + sm_match!(self, |sm| sm.exec_latency(op)) + } + + /// Read-after-read latency + fn raw_latency( + &self, + write: &Op, + dst_idx: usize, + read: &Op, + src_idx: usize, + ) -> u32 { + sm_match!(self, |sm| sm.raw_latency(write, dst_idx, read, src_idx)) + } + + /// Write-after-read latency + fn war_latency( + &self, + read: &Op, + src_idx: usize, + write: &Op, + dst_idx: usize, + ) -> u32 { + sm_match!(self, |sm| sm.war_latency(read, src_idx, write, dst_idx)) + } + + /// Write-after-write latency + fn waw_latency( + &self, + a: &Op, + a_dst_idx: usize, + a_has_pred: bool, + b: &Op, + b_dst_idx: usize, + ) -> u32 { + sm_match!(self, |sm| sm + .waw_latency(a, a_dst_idx, a_has_pred, b, b_dst_idx)) + } + + fn paw_latency(&self, write: &Op, dst_idx: usize) -> u32 { + sm_match!(self, |sm| sm.paw_latency(write, dst_idx)) + } + fn worst_latency(&self, write: &Op, dst_idx: usize) -> u32 { + sm_match!(self, |sm| sm.worst_latency(write, dst_idx)) + } + fn latency_upper_bound(&self) -> u32 { + sm_match!(self, |sm| sm.latency_upper_bound()) + } + fn max_instr_delay(&self) -> u8 { + sm_match!(self, |sm| sm.max_instr_delay()) + } + fn legalize_op(&self, b: &mut LegalizeBuilder, op: &mut Op) { + sm_match!(self, |sm| sm.legalize_op(b, op)) + } + fn encode_shader(&self, s: &Shader<'_>) -> Vec { + sm_match!(self, |sm| sm.encode_shader(s)) + } +} + /// For compute shaders, large values of local_size impose an additional limit /// on the number of GPRs per thread pub fn gpr_limit_from_local_size(local_size: &[u16; 3]) -> u32 { diff --git a/src/nouveau/compiler/nak/nvdisasm_tests.rs b/src/nouveau/compiler/nak/nvdisasm_tests.rs index cb7e9ad2ddc..92f32db7656 100644 --- a/src/nouveau/compiler/nak/nvdisasm_tests.rs +++ b/src/nouveau/compiler/nak/nvdisasm_tests.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: MIT use crate::ir::*; -use crate::sm70::ShaderModel70; use compiler::cfg::CFGBuilder; use rustc_hash::FxBuildHasher; @@ -88,7 +87,7 @@ fn disassemble_instrs(instrs: Vec, sm: u8) -> Vec { io: ShaderIoInfo::None, }; - let sm: Box = Box::new(ShaderModel70::new(sm)); + let sm: Box = Box::new(ShaderModelInfo::new(sm)); let s = Shader { sm: &*sm, info: info,