From 64f02ac16d4232c28a12a225fea9db76cd6b4530 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Wed, 10 Apr 2024 14:40:36 -0500 Subject: [PATCH] nouveau/headers: Generate Rust for QMDs This also involves adding array support to the struct parser. Fortunately, the header files for QMDs are really consistent here and we can make lots of assumptions like that i is always the index variable. Part-of: --- src/nouveau/headers/meson.build | 11 ++++++++++ src/nouveau/headers/struct_parser.py | 32 +++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/nouveau/headers/meson.build b/src/nouveau/headers/meson.build index 75b99fd87c3..f716658c8c3 100644 --- a/src/nouveau/headers/meson.build +++ b/src/nouveau/headers/meson.build @@ -79,6 +79,17 @@ if with_nouveau_vk depend_files: nvk_cl_header_depend_files, ) + fs = import('fs') + if cl.endswith('c0') and fs.is_file('nvidia/classes/'+cl+'qmd.h') + cl_rs_generated += custom_target( + 'nvh_classes_' + cl + '_qmd.rs', + input : ['struct_parser.py', 'nvidia/classes/'+cl+'qmd.h'], + output : ['nvh_classes_'+cl+'_qmd.rs'], + command : [prog_python, '@INPUT0@', '--in-h', '@INPUT1@', + '--out-rs', '@OUTPUT0@'] + ) + endif + if cl.endswith('97') cl_rs_generated += custom_target( 'nvh_classes_' + cl + '_tex.rs', diff --git a/src/nouveau/headers/struct_parser.py b/src/nouveau/headers/struct_parser.py index 70f5de3cb26..3ca9d18dd4d 100644 --- a/src/nouveau/headers/struct_parser.py +++ b/src/nouveau/headers/struct_parser.py @@ -17,11 +17,20 @@ TEMPLATE_RS = Template("""\ // This file is generated by struct_parser.py. DO NOT EDIT! +#![allow(non_snake_case)] + use std::ops::Range; % for s in structs: % for f in s.fields: + % if f.stride: +#[inline] +pub fn ${s.name}_${f.name}(i: usize) -> Range { + (i * ${f.stride} + ${f.lo})..(i * ${f.stride} + ${f.hi + 1}) +} + % else: pub const ${s.name}_${f.name}: Range = ${f.lo}..${f.hi + 1}; + % endif: % for e in f.enums: pub const ${s.name}_${f.name}_${e.name}: u32 = ${e.value}; % endfor @@ -38,15 +47,24 @@ STRUCTS = [ # This one goes last because it's a substring of the others 'TEXHEAD', 'TEXSAMP', + 'QMDV00_06', + 'QMDV01_06', + 'QMDV01_07', + 'QMDV02_01', + 'QMDV02_02', + 'QMDV02_03', + 'QMDV02_04', + 'QMDV03_00', ] Enum = namedtuple('Enum', ['name', 'value']) class Field(object): - def __init__(self, name, lo, hi): + def __init__(self, name, lo, hi, stride=0): self.name = name self.lo = lo self.hi = hi + self.stride = stride self.enums = [] def add_enum(self, name, value): @@ -57,12 +75,13 @@ class Struct(object): self.name = name self.fields = [] - def add_field(self, name, lo, hi): - self.fields.append(Field(name, lo, hi)) + def add_field(self, name, lo, hi, stride=0): + self.fields.append(Field(name, lo, hi, stride)) DRF_RE = re.compile(r'(?P[0-9]+):(?P[0-9]+)') FIELD_NAME_RE = re.compile(r'_?(?P[0-9]+)?_?(?P.*)') MW_RE = re.compile(r'MW\((?P[0-9]+):(?P[0-9]+)\)') +MW_ARR_RE = re.compile(r'MW\(\((?P\d+)\+\(i\)\*(?P\d+)\):\((?P[0-9]+)\+\(i\)\*(?P=stride)\)\)') def parse_header(nvcl, file): structs = {} @@ -96,6 +115,7 @@ def parse_header(nvcl, file): drf = DRF_RE.match(line[2]) mw = MW_RE.match(line[2]) + mw_arr = MW_ARR_RE.match(line[2]) if drf: dw = int(name_m.group('dw')) lo = int(drf.group('lo')) + dw * 32 @@ -105,6 +125,12 @@ def parse_header(nvcl, file): lo = int(mw.group('lo')) hi = int(mw.group('hi')) struct.add_field(name, lo, hi) + elif mw_arr: + lo = int(mw_arr.group('lo')) + hi = int(mw_arr.group('hi')) + stride = int(mw_arr.group('stride')) + assert name.endswith('(i)') + struct.add_field(name.removesuffix('(i)'), lo, hi, stride) else: for f in struct.fields: if name.startswith(f.name + '_'):