pub fn part(container: &[u8]) -> Result<Part<'_>>Expand description
Find and check a container’s DXIL part.
Examples found in repository?
examples/pairs_dxil.rs (line 96)
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}