nak: Move instruction encoding into ShaderModel

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30141>
This commit is contained in:
Faith Ekstrand
2024-07-09 11:14:29 -05:00
committed by Marge Bot
parent d4db2f43de
commit 57667aeac8
6 changed files with 4945 additions and 97 deletions
+1 -7
View File
@@ -449,13 +449,7 @@ pub extern "C" fn nak_compile_shader(
s.remove_annotations();
let code = if nak.sm >= 70 {
s.encode_sm70()
} else if nak.sm >= 50 {
s.encode_sm50()
} else {
panic!("Unsupported shader model");
};
let code = sm.encode_shader(&s);
if DEBUG.print() {
let stage_name = unsafe {
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2
View File
@@ -6251,6 +6251,8 @@ pub trait ShaderModel {
fn num_regs(&self, file: RegFile) -> u32;
fn op_can_be_uniform(&self, op: &Op) -> bool;
fn encode_shader(&self, s: &Shader<'_>) -> Vec<u32>;
}
pub struct Shader<'a> {
+64 -62
View File
@@ -38,6 +38,10 @@ impl ShaderModel for ShaderModel50 {
fn op_can_be_uniform(&self, _op: &Op) -> bool {
false
}
fn encode_shader(&self, s: &Shader<'_>) -> Vec<u32> {
encode_sm50_shader(self, s)
}
}
impl Src {
@@ -2212,70 +2216,68 @@ fn encode_instr(
res.inst
}
impl Shader<'_> {
pub fn encode_sm50(&self) -> Vec<u32> {
assert!(self.functions.len() == 1);
let func = &self.functions[0];
fn encode_sm50_shader(sm: &ShaderModel50, s: &Shader<'_>) -> Vec<u32> {
assert!(s.functions.len() == 1);
let func = &s.functions[0];
let mut num_instrs = 0_usize;
let mut labels = HashMap::new();
for b in &func.blocks {
// We ensure blocks will have groups of 3 instructions with a
// schedule instruction before each groups. As we should never jump
// to a schedule instruction, we account for that here.
labels.insert(b.label, num_instrs + 8);
let mut num_instrs = 0_usize;
let mut labels = HashMap::new();
for b in &func.blocks {
// We ensure blocks will have groups of 3 instructions with a
// schedule instruction before each groups. As we should never jump
// to a schedule instruction, we account for that here.
labels.insert(b.label, num_instrs + 8);
let block_num_instrs = b.instrs.len().next_multiple_of(3);
let block_num_instrs = b.instrs.len().next_multiple_of(3);
// Every 3 instructions, we have a new schedule instruction so we
// need to account for that.
num_instrs += (block_num_instrs + (block_num_instrs / 3)) * 8;
}
let mut encoded = Vec::new();
for b in &func.blocks {
// A block is composed of groups of 3 instructions.
let block_num_instrs = b.instrs.len().next_multiple_of(3);
let mut instrs_iter = b.instrs.iter();
for _ in 0..(block_num_instrs / 3) {
let mut ip = ((encoded.len() / 2) + 1) * 8;
let mut sched_instr = [0x0; 2];
let instr0 = encode_instr(
0,
instrs_iter.next(),
self.sm.sm(),
&labels,
&mut ip,
&mut sched_instr,
);
let instr1 = encode_instr(
1,
instrs_iter.next(),
self.sm.sm(),
&labels,
&mut ip,
&mut sched_instr,
);
let instr2 = encode_instr(
2,
instrs_iter.next(),
self.sm.sm(),
&labels,
&mut ip,
&mut sched_instr,
);
encoded.extend_from_slice(&sched_instr[..]);
encoded.extend_from_slice(&instr0[..]);
encoded.extend_from_slice(&instr1[..]);
encoded.extend_from_slice(&instr2[..]);
}
}
encoded
// Every 3 instructions, we have a new schedule instruction so we
// need to account for that.
num_instrs += (block_num_instrs + (block_num_instrs / 3)) * 8;
}
let mut encoded = Vec::new();
for b in &func.blocks {
// A block is composed of groups of 3 instructions.
let block_num_instrs = b.instrs.len().next_multiple_of(3);
let mut instrs_iter = b.instrs.iter();
for _ in 0..(block_num_instrs / 3) {
let mut ip = ((encoded.len() / 2) + 1) * 8;
let mut sched_instr = [0x0; 2];
let instr0 = encode_instr(
0,
instrs_iter.next(),
sm.sm,
&labels,
&mut ip,
&mut sched_instr,
);
let instr1 = encode_instr(
1,
instrs_iter.next(),
sm.sm,
&labels,
&mut ip,
&mut sched_instr,
);
let instr2 = encode_instr(
2,
instrs_iter.next(),
sm.sm,
&labels,
&mut ip,
&mut sched_instr,
);
encoded.extend_from_slice(&sched_instr[..]);
encoded.extend_from_slice(&instr0[..]);
encoded.extend_from_slice(&instr1[..]);
encoded.extend_from_slice(&instr2[..]);
}
}
encoded
}
+25 -28
View File
@@ -91,6 +91,10 @@ impl ShaderModel for ShaderModel70 {
_ => false,
}
}
fn encode_shader(&self, s: &Shader<'_>) -> Vec<u32> {
encode_sm70_shader(self, s)
}
}
struct ALURegRef {
@@ -2656,37 +2660,30 @@ impl SM70Instr {
}
}
impl Shader<'_> {
pub fn encode_sm70(&self) -> Vec<u32> {
assert!(self.functions.len() == 1);
let func = &self.functions[0];
fn encode_sm70_shader(sm: &ShaderModel70, s: &Shader<'_>) -> Vec<u32> {
assert!(s.functions.len() == 1);
let func = &s.functions[0];
let mut ip = 0_usize;
let mut labels = HashMap::new();
for b in &func.blocks {
labels.insert(b.label, ip);
for instr in &b.instrs {
if let Op::Nop(op) = &instr.op {
if let Some(label) = op.label {
labels.insert(label, ip);
}
let mut ip = 0_usize;
let mut labels = HashMap::new();
for b in &func.blocks {
labels.insert(b.label, ip);
for instr in &b.instrs {
if let Op::Nop(op) = &instr.op {
if let Some(label) = op.label {
labels.insert(label, ip);
}
ip += 4;
}
ip += 4;
}
let mut encoded = Vec::new();
for b in &func.blocks {
for instr in &b.instrs {
let e = SM70Instr::encode(
instr,
self.sm.sm(),
encoded.len(),
&labels,
);
encoded.extend_from_slice(&e[..]);
}
}
encoded
}
let mut encoded = Vec::new();
for b in &func.blocks {
for instr in &b.instrs {
let e = SM70Instr::encode(instr, sm.sm, encoded.len(), &labels);
encoded.extend_from_slice(&e[..]);
}
}
encoded
}