nak: Add ShaderModelInfo

which statically dispatches into the right ShaderModel implementation.

Reviewed-by: Mary Guillemard <mary@mary.zone>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38913>
This commit is contained in:
Mel Henning 2025-12-11 14:19:10 -05:00 committed by Marge Bot
parent 68c1a8230d
commit 3063802d6d
4 changed files with 118 additions and 34 deletions

View file

@ -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<dyn ShaderModel> = 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() {

View file

@ -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<dyn ShaderModel + Send + Sync> = 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 }
})
}

View file

@ -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<u32>;
}
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<u32> {
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 {

View file

@ -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<Instr>, sm: u8) -> Vec<String> {
io: ShaderIoInfo::None,
};
let sm: Box<dyn ShaderModel> = Box::new(ShaderModel70::new(sm));
let sm: Box<dyn ShaderModel> = Box::new(ShaderModelInfo::new(sm));
let s = Shader {
sm: &*sm,
info: info,