spirv_webgpu_transform/lib.rs
1//! ##
2//!
3//! ## Features
4//!
5//! At the moment, the following transformations are supported:
6//!
7//! | Feature | `spirv-val` | `naga` | `tint` |
8//! | ------------------------- | ----------- | ------ | ------ |
9//! | Combined Image Samplers | ✅ | ✅ | ✅ |
10//! | Mixed Depth / Comparison | ✅ | ⚠️\* | ❌ |
11//! | isnan / isinf Patching | ✅ | ✅ | ✅ |
12//!
13//! > \* Simple cases are OK.
14//! > With some [special patches](https://github.com/davnotdev/wgpu/tree/trunk-naga-patches), `naga` can process these.
15//!
16//! ## Using the result
17//!
18//! After running an individual shader through one or multiple transformations, you will want to:
19//!
20//! 1. Know which set bindings were affected, use the output [`CorrectionMap`] for this purpose.
21//! 2. Ensure that your vertex and fragment shaders shader the same binding layout, use [`mirrorpatch`] for this purpose
22//!
23//! ## For more details
24//!
25//! See [https://github.com/davnotdev/spirv-webgpu-transform](https://github.com/davnotdev/spirv-webgpu-transform) for more details.
26//!
27
28use std::collections::{HashMap, HashSet};
29
30mod correction;
31mod isnanisinfpatch;
32mod mirrorpatch;
33mod splitcombined;
34mod splitdref;
35mod spv;
36mod util;
37
38#[cfg(test)]
39mod test;
40
41use spv::*;
42use util::*;
43
44pub use correction::*;
45pub use isnanisinfpatch::*;
46pub use mirrorpatch::*;
47pub use splitcombined::*;
48pub use splitdref::*;
49
50#[derive(Debug, Clone)]
51struct InstructionInsert {
52 previous_spv_idx: usize,
53 instruction: Vec<u32>,
54}
55
56#[derive(Debug, Clone)]
57struct WordInsert {
58 idx: usize,
59 word: u32,
60 head_idx: usize,
61}
62
63/// Helper to convert a `&[u8]` into a `Vec<u32>`.
64pub fn u8_slice_to_u32_vec(vec: &[u8]) -> Vec<u32> {
65 assert_eq!(
66 vec.len() % 4,
67 0,
68 "Input slice length must be a multiple of 4."
69 );
70
71 vec.chunks_exact(4)
72 .map(|chunk| {
73 (chunk[0] as u32)
74 | ((chunk[1] as u32) << 8)
75 | ((chunk[2] as u32) << 16)
76 | ((chunk[3] as u32) << 24)
77 })
78 .collect::<Vec<_>>()
79}
80
81/// Helper to convert a `&[u32]` into a `Vec<u8>`.
82pub fn u32_slice_to_u8_vec(vec: &[u32]) -> Vec<u8> {
83 vec.iter()
84 .flat_map(|&num| {
85 vec![
86 (num & 0xFF) as u8,
87 ((num >> 8) & 0xFF) as u8,
88 ((num >> 16) & 0xFF) as u8,
89 ((num >> 24) & 0xFF) as u8,
90 ]
91 })
92 .collect::<Vec<u8>>()
93}