Skip to main content

ranges

Function ranges 

Source
pub fn ranges(m: &Module) -> Result<Vec<(Range, String, Option<TypeId>)>>
Expand description

The bound resource ranges of dx.resources (SRVs, UAVs, constant buffers, samplers), each with its variable’s name and the type its variable points to (the resource’s handle type).

Examples found in repository?
examples/inspect_dxil.rs (line 17)
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 104)
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}