Skip to main content

module

Function module 

Source
pub fn module(chunks: &[Chunk<'_>], kind: &[u8; 4]) -> Result<Option<Module>>
Expand description

The module of a container’s program part of this kind (DXIL, or STAT for the reflection module), if it has one.

Examples found in repository?
examples/inspect_dxil.rs (line 7)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4    let path = std::env::args().nth(1).ok_or("usage: inspect <shader.dxil>")?;
5    let container = std::fs::read(path)?;
6    let parts = dxil_reader::parts(&container)?;
7    let module = dxil_reader::module(&parts, b"DXIL")?.ok_or("no DXIL part")?;
8    println!("{} functions", module.functions.len());
9
10    // The records the file stores for its entry point:
11    let (inputs, outputs) = dxil_reader::reflection::elements(&module)?;
12    println!(
13        "{} input and {} output signature elements",
14        inputs.len(),
15        outputs.len()
16    );
17    for (range, name, _) in dxil_reader::reflection::ranges(&module)? {
18        println!("{name}: class {} register {}", range.class, range.lower);
19    }
20    Ok(())
21}
More examples
Hide additional examples
examples/pairs_dxil.rs (line 85)
73fn main() -> Result<(), Box<dyn std::error::Error>> {
74    let mut paths = Vec::new();
75    for argument in std::env::args().skip(1) {
76        files(Path::new(&argument), &mut paths)?;
77    }
78    let (mut programs, mut skipped) = (0_usize, 0_usize);
79    for path in &paths {
80        let bytes = std::fs::read(path)?;
81        let Ok(chunks) = dxil_reader::parts(&bytes) else {
82            skipped += 1;
83            continue;
84        };
85        let module = match dxil_reader::module(&chunks, b"DXIL") {
86            Ok(Some(module)) => module,
87            Ok(None) => {
88                skipped += 1;
89                continue;
90            }
91            Err(e) => {
92                eprintln!("{}: {e}", path.display());
93                continue;
94            }
95        };
96        let kind = dxil_reader::part(&bytes)?.program_version >> 16;
97        let reads = match texture_reads(&module) {
98            Ok(reads) => reads,
99            Err(e) => {
100                eprintln!("{}: {e}", path.display());
101                continue;
102            }
103        };
104        let samplers: Vec<_> = dxil_reader::reflection::ranges(&module)?
105            .into_iter()
106            .filter(|(range, _, _)| range.class == 3)
107            .map(|(range, _, _)| range)
108            .collect();
109        programs += 1;
110        let hash = fnv1a64(&bytes);
111        // (texture, sampler, comparison, declared kind) -> call count and operation names
112        type Key = ((String, String), (String, String), bool, String);
113        let mut pairs: BTreeMap<Key, (usize, BTreeMap<String, usize>)> = BTreeMap::new();
114        for read in reads {
115            let sampler = if read.sampled {
116                columns(read.sampler)
117            } else {
118                ("-".to_owned(), "-".to_owned())
119            };
120            let declared = read
121                .sampler
122                .and_then(|h| {
123                    let register = h.register?;
124                    samplers.iter().find(|r| {
125                        r.space == h.space
126                            && register >= r.lower
127                            && register
128                                .checked_sub(r.lower)
129                                .is_some_and(|offset| offset < r.count)
130                    })
131                })
132                .map_or_else(|| "-".to_owned(), |r| r.extra.to_string());
133            let entry = pairs
134                .entry((columns(read.texture), sampler, read.comparison, declared))
135                .or_default();
136            entry.0 += 1;
137            *entry.1.entry(operation(read.opcode)).or_default() += 1;
138        }
139        for ((texture, sampler, comparison, declared), (count, names)) in pairs {
140            let names: Vec<String> = names.iter().map(|(n, c)| format!("{n}x{c}")).collect();
141            println!(
142                "{hash:016x}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{declared}\t{count}\t{}",
143                path.display(),
144                stage(kind),
145                texture.0,
146                texture.1,
147                sampler.0,
148                sampler.1,
149                u8::from(comparison),
150                names.join(",")
151            );
152        }
153    }
154    eprintln!("{programs} programs, {skipped} files skipped");
155    Ok(())
156}