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