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}