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