From 80ef2aa42e62eb99244e403bec609ff32285788b Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Wed, 27 May 2026 15:19:44 -0400 Subject: [PATCH] kraid: Add a SmallConstant struct and a Model::small_constants() hook Part-of: --- src/panfrost/compiler/kraid/ir.rs | 22 +++++++++++++++++++ src/panfrost/compiler/kraid/isa.rs | 18 ++++++++++++++- src/panfrost/compiler/kraid/model.rs | 17 +++++++++++++- src/panfrost/compiler/kraid/proc/isa/enums.rs | 22 +++++++++---------- 4 files changed, 66 insertions(+), 13 deletions(-) diff --git a/src/panfrost/compiler/kraid/ir.rs b/src/panfrost/compiler/kraid/ir.rs index d61fdda21d0..f6ba0d57a42 100644 --- a/src/panfrost/compiler/kraid/ir.rs +++ b/src/panfrost/compiler/kraid/ir.rs @@ -14,6 +14,18 @@ use compiler::as_slice::*; use std::fmt; use std::ops::{Deref, DerefMut}; +pub struct SmallConstant { + pub idx: u8, + pub imm32: u32, + pub name: &'static str, +} + +impl fmt::Display for SmallConstant { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.name) + } +} + #[derive(Clone, Copy, Eq, Hash, PartialEq)] pub enum FAUPage { /// The user FAU table. This assumes a single, flat table, unlike the @@ -77,6 +89,16 @@ impl fmt::Display for FAURef { } } +impl From<&SmallConstant> for FAURef { + fn from(sc: &SmallConstant) -> FAURef { + FAURef { + page: FAUPage::SmallConst, + idx: sc.idx.into(), + load64: false, + } + } +} + /// This struct describes the range of registers read or written by a RegRef. /// The range provided here acts as a mask on the destination but is purely /// informational for sources. In all cases, the instruction operates relative diff --git a/src/panfrost/compiler/kraid/isa.rs b/src/panfrost/compiler/kraid/isa.rs index a8d2beb7506..86485f01521 100644 --- a/src/panfrost/compiler/kraid/isa.rs +++ b/src/panfrost/compiler/kraid/isa.rs @@ -1,6 +1,8 @@ // Copyright © 2026 Collabora, Ltd. // SPDX-License-Identifier: MIT +use crate::ir::SmallConstant; + #[derive(Debug)] pub enum EncodeError { Int(std::num::TryFromIntError), @@ -67,7 +69,21 @@ pub trait TryDecode: Sized { pub trait SmallConstantTable: TryDecode { const TABLE_LEN: u8; fn name(&self) -> &'static str; - fn const_value(&self) -> u32; + fn bit_pattern(&self) -> u32; + + fn collect(arch: u8) -> Vec { + let mut vec = Vec::new(); + for idx in 0..Self::TABLE_LEN { + if let Ok(sc) = Self::try_decode(idx, arch) { + vec.push(SmallConstant { + idx, + imm32: sc.bit_pattern(), + name: sc.name(), + }); + } + } + vec + } } #[derive(Clone, Copy)] diff --git a/src/panfrost/compiler/kraid/model.rs b/src/panfrost/compiler/kraid/model.rs index 2ff3f6f36c4..d04ec19e5d3 100644 --- a/src/panfrost/compiler/kraid/model.rs +++ b/src/panfrost/compiler/kraid/model.rs @@ -9,10 +9,21 @@ pub trait Model { fn arch(&self) -> u8; fn encode_shader(&self, s: &Shader<'_>) -> Vec; + + fn small_constants(&self) -> &[SmallConstant]; } struct ValhallModel { arch: u8, + sc_table: Vec, +} + +impl ValhallModel { + fn new(arch: u8) -> ValhallModel { + use crate::isa::{v9, SmallConstantTable}; + let sc_table = v9::SmallConstantT::collect(arch); + ValhallModel { arch, sc_table } + } } impl Model for ValhallModel { @@ -23,6 +34,10 @@ impl Model for ValhallModel { fn encode_shader(&self, s: &Shader<'_>) -> Vec { encode_v9(s, self.arch) } + + fn small_constants(&self) -> &[SmallConstant] { + &self.sc_table + } } pub fn model_for_gpu_id(gpu_id: u64) -> Result, &'static str> { @@ -32,7 +47,7 @@ pub fn model_for_gpu_id(gpu_id: u64) -> Result, &'static str> { if arch >= 15 { Err("Kraid does not yet support this GPU") } else if arch >= 9 { - Ok(Box::new(ValhallModel { arch })) + Ok(Box::new(ValhallModel::new(arch))) } else { Err("Kraid only supports Valhall (v9) and later GPUs") } diff --git a/src/panfrost/compiler/kraid/proc/isa/enums.rs b/src/panfrost/compiler/kraid/proc/isa/enums.rs index 82ad97d45cb..a8287b61050 100644 --- a/src/panfrost/compiler/kraid/proc/isa/enums.rs +++ b/src/panfrost/compiler/kraid/proc/isa/enums.rs @@ -15,7 +15,7 @@ pub struct EnumValue { pub arch: ArchSet, pub canonical: bool, pub value: u8, - pub const_value: Option, + pub bit_pattern: Option, } impl EnumValue { @@ -39,7 +39,7 @@ impl EnumValue { .get_u8_attr("value") .ok_or(err("Enum value has no value"))? .into(), - const_value: xml.get_u32_attr("const_value"), + bit_pattern: xml.get_u32_attr("bit_pattern"), }) } @@ -248,17 +248,17 @@ impl Enum { } if self.name == "small_constant_t" { - let mut const_name_cases_ts = TokenStream2::new(); - let mut const_value_cases_ts = TokenStream2::new(); + let mut name_cases_ts = TokenStream2::new(); + let mut bit_pattern_cases_ts = TokenStream2::new(); for v in self.values.values() { let v_name = &v.name; let v_ident = &v.ident; - let const_value = v.const_value.unwrap(); - const_name_cases_ts.extend(quote! { + let bit_pattern = v.bit_pattern.unwrap(); + name_cases_ts.extend(quote! { #e_ident::#v_ident => #v_name, }); - const_value_cases_ts.extend(quote! { - #e_ident::#v_ident => #const_value, + bit_pattern_cases_ts.extend(quote! { + #e_ident::#v_ident => #bit_pattern, }); } let table_len = max_value + 1; @@ -268,13 +268,13 @@ impl Enum { fn name(&self) -> &'static str { match self { - #const_name_cases_ts + #name_cases_ts } } - fn const_value(&self) -> u32 { + fn bit_pattern(&self) -> u32 { match self { - #const_value_cases_ts + #bit_pattern_cases_ts } } }