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