kraid: Add a SmallConstant struct and a Model::small_constants() hook

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41841>
This commit is contained in:
Faith Ekstrand 2026-05-27 15:19:44 -04:00 committed by Marge Bot
parent 4c1d579db4
commit 80ef2aa42e
4 changed files with 66 additions and 13 deletions

View file

@ -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

View file

@ -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<T>: Sized {
pub trait SmallConstantTable: TryDecode<u8> {
const TABLE_LEN: u8;
fn name(&self) -> &'static str;
fn const_value(&self) -> u32;
fn bit_pattern(&self) -> u32;
fn collect(arch: u8) -> Vec<SmallConstant> {
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)]

View file

@ -9,10 +9,21 @@ pub trait Model {
fn arch(&self) -> u8;
fn encode_shader(&self, s: &Shader<'_>) -> Vec<u32>;
fn small_constants(&self) -> &[SmallConstant];
}
struct ValhallModel {
arch: u8,
sc_table: Vec<SmallConstant>,
}
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<u32> {
encode_v9(s, self.arch)
}
fn small_constants(&self) -> &[SmallConstant] {
&self.sc_table
}
}
pub fn model_for_gpu_id(gpu_id: u64) -> Result<Box<dyn Model>, &'static str> {
@ -32,7 +47,7 @@ pub fn model_for_gpu_id(gpu_id: u64) -> Result<Box<dyn Model>, &'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")
}

View file

@ -15,7 +15,7 @@ pub struct EnumValue {
pub arch: ArchSet,
pub canonical: bool,
pub value: u8,
pub const_value: Option<u32>,
pub bit_pattern: Option<u32>,
}
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
}
}
}