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 + '_'):