@@ -12,16 +12,17 @@ mod encoder;
1212mod init;
1313mod mutex;
1414mod panicking;
15+ mod spirv;
1516mod texture_blitter;
1617
17- use alloc:: { borrow:: Cow , format, string:: String , vec} ;
18- use core:: { mem, ptr:: copy_nonoverlapping} ;
18+ use alloc:: { format, string:: String } ;
1919
2020#[ cfg( std) ]
2121pub use belt:: StagingBelt ;
2222pub use device:: { BufferInitDescriptor , DeviceExt } ;
2323pub use encoder:: RenderEncoder ;
2424pub use init:: * ;
25+ pub use spirv:: * ;
2526#[ cfg( feature = "wgsl" ) ]
2627pub use texture_blitter:: { TextureBlitter , TextureBlitterBuilder } ;
2728pub use wgt:: {
@@ -33,124 +34,6 @@ pub(crate) use panicking::is_panicking;
3334
3435use crate :: dispatch;
3536
36- /// Treat the given byte slice as a SPIR-V module.
37- ///
38- /// # Panic
39- ///
40- /// This function panics if:
41- ///
42- /// - Input length isn't multiple of 4
43- /// - Input is longer than [`usize::MAX`]
44- /// - Input is empty
45- /// - SPIR-V magic number is missing from beginning of stream
46- #[ cfg( feature = "spirv" ) ]
47- pub fn make_spirv ( data : & [ u8 ] ) -> super :: ShaderSource < ' _ > {
48- super :: ShaderSource :: SpirV ( make_spirv_raw ( data) )
49- }
50-
51- const SPIRV_MAGIC_NUMBER : u32 = 0x0723_0203 ;
52-
53- const fn check_spirv_len ( data : & [ u8 ] ) {
54- assert ! (
55- data. len( ) % size_of:: <u32 >( ) == 0 ,
56- "SPIRV data size must be a multiple of 4."
57- ) ;
58- assert ! ( !data. is_empty( ) , "SPIRV data must not be empty." ) ;
59- }
60-
61- const fn verify_spirv_magic ( words : & [ u32 ] ) {
62- assert ! (
63- words[ 0 ] == SPIRV_MAGIC_NUMBER ,
64- "Wrong magic word in data. Make sure you are using a binary SPIRV file." ,
65- ) ;
66- }
67-
68- /// Version of `make_spirv` intended for use with [`Device::create_shader_module_passthrough`].
69- /// Returns a raw slice instead of [`ShaderSource`](super::ShaderSource).
70- ///
71- /// [`Device::create_shader_module_passthrough`]: crate::Device::create_shader_module_passthrough
72- pub fn make_spirv_raw ( data : & [ u8 ] ) -> Cow < ' _ , [ u32 ] > {
73- check_spirv_len ( data) ;
74-
75- // If the data happens to be aligned, directly use the byte array,
76- // otherwise copy the byte array in an owned vector and use that instead.
77- let mut words = if data. as_ptr ( ) . align_offset ( align_of :: < u32 > ( ) ) == 0 {
78- let ( pre, words, post) = unsafe { data. align_to :: < u32 > ( ) } ;
79- debug_assert ! ( pre. is_empty( ) ) ;
80- debug_assert ! ( post. is_empty( ) ) ;
81- Cow :: from ( words)
82- } else {
83- let mut words = vec ! [ 0u32 ; data. len( ) / size_of:: <u32 >( ) ] ;
84- unsafe {
85- copy_nonoverlapping ( data. as_ptr ( ) , words. as_mut_ptr ( ) as * mut u8 , data. len ( ) ) ;
86- }
87- Cow :: from ( words)
88- } ;
89-
90- // Before checking if the data starts with the magic, check if it starts
91- // with the magic in non-native endianness, own & swap the data if so.
92- if words[ 0 ] == SPIRV_MAGIC_NUMBER . swap_bytes ( ) {
93- for word in Cow :: to_mut ( & mut words) {
94- * word = word. swap_bytes ( ) ;
95- }
96- }
97-
98- verify_spirv_magic ( & words) ;
99-
100- words
101- }
102-
103- /// Version of `make_spirv_raw` used for implementing [`include_spirv!`] and [`include_spirv_raw!`] macros.
104- ///
105- /// Not public API. Also, don't even try calling at runtime; you'll get a stack overflow.
106- ///
107- /// [`include_spirv!`]: crate::include_spirv
108- #[ doc( hidden) ]
109- pub const fn make_spirv_const < const IN : usize , const OUT : usize > ( data : [ u8 ; IN ] ) -> [ u32 ; OUT ] {
110- #[ repr( align( 4 ) ) ]
111- struct Aligned < T : ?Sized > ( T ) ;
112-
113- check_spirv_len ( & data) ;
114-
115- // NOTE: to get around lack of generic const expressions
116- assert ! ( IN / 4 == OUT ) ;
117-
118- let aligned = Aligned ( data) ;
119- let mut words: [ u32 ; OUT ] = unsafe { mem:: transmute_copy ( & aligned) } ;
120-
121- // Before checking if the data starts with the magic, check if it starts
122- // with the magic in non-native endianness, own & swap the data if so.
123- if words[ 0 ] == SPIRV_MAGIC_NUMBER . swap_bytes ( ) {
124- let mut idx = 0 ;
125- while idx < words. len ( ) {
126- words[ idx] = words[ idx] . swap_bytes ( ) ;
127- idx += 1 ;
128- }
129- }
130-
131- verify_spirv_magic ( & words) ;
132-
133- words
134- }
135-
136- #[ should_panic = "multiple of 4" ]
137- #[ test]
138- fn make_spirv_le_fail ( ) {
139- let _: [ u32 ; 1 ] = make_spirv_const ( [ 0x03 , 0x02 , 0x23 , 0x07 , 0x44 , 0x33 ] ) ;
140- }
141-
142- #[ should_panic = "multiple of 4" ]
143- #[ test]
144- fn make_spirv_be_fail ( ) {
145- let _: [ u32 ; 1 ] = make_spirv_const ( [ 0x07 , 0x23 , 0x02 , 0x03 , 0x11 , 0x22 ] ) ;
146- }
147-
148- #[ should_panic = "empty" ]
149- #[ test]
150- fn make_spirv_empty ( ) {
151- let _: [ u32 ; 0 ] = make_spirv_const ( [ ] ) ;
152- }
153-
15437/// CPU accessible buffer used to download data back from the GPU.
15538pub struct DownloadBuffer {
15639 _gpu_buffer : super :: Buffer ,
0 commit comments