Skip to main content

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}