From 5acb70691dc0ec6a74a931ecf23b32ee0fa02510 Mon Sep 17 00:00:00 2001 From: 1e1001 Date: Fri, 20 Jan 2023 20:04:55 -0800 Subject: [PATCH] Make `make_spirv_raw` and `make_spirv` handle big-endian binaries (#3411) Fixes https://github.com/gfx-rs/wgpu/issues/3408 --- CHANGELOG.md | 1 + wgpu/src/util/mod.rs | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f95b6565d5..ca808acc24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -242,6 +242,7 @@ let texture = device.create_texture(&wgpu::TextureDescriptor { - Validate texture ids in `Global::queue_texture_write`. By @jimblandy in [#3378](https://github.com/gfx-rs/wgpu/pull/3378). - Don't panic on mapped buffer in queue_submit. By @crowlKats in [#3364](https://github.com/gfx-rs/wgpu/pull/3364). - Fix being able to sample a depth texture with a filtering sampler. By @teoxoy in [#3394](https://github.com/gfx-rs/wgpu/pull/3394). +- Make `make_spirv_raw` and `make_spirv` handle big-endian binaries. By @1e1001 in [#3411](https://github.com/gfx-rs/wgpu/pull/3411). #### Metal - Fix texture view creation with full-resource views when using an explicit `mip_level_count` or `array_layer_count`. By @cwfitzgerald in [#3323](https://github.com/gfx-rs/wgpu/pull/3323) diff --git a/wgpu/src/util/mod.rs b/wgpu/src/util/mod.rs index 71572ca23f..1382056450 100644 --- a/wgpu/src/util/mod.rs +++ b/wgpu/src/util/mod.rs @@ -31,6 +31,7 @@ pub use init::*; /// /// - Input length isn't multiple of 4 /// - Input is longer than [`usize::max_value`] +/// - Input is empty /// - SPIR-V magic number is missing from beginning of stream #[cfg(feature = "spirv")] pub fn make_spirv(data: &[u8]) -> super::ShaderSource { @@ -48,10 +49,11 @@ pub fn make_spirv_raw(data: &[u8]) -> Cow<[u32]> { 0, "data size is not a multiple of 4" ); + assert_ne!(data.len(), 0, "data size must be larger than zero"); //If the data happens to be aligned, directly use the byte array, // otherwise copy the byte array in an owned vector and use that instead. - let words = if data.as_ptr().align_offset(align_of::()) == 0 { + let mut words = if data.as_ptr().align_offset(align_of::()) == 0 { let (pre, words, post) = unsafe { data.align_to::() }; debug_assert!(pre.is_empty()); debug_assert!(post.is_empty()); @@ -64,6 +66,14 @@ pub fn make_spirv_raw(data: &[u8]) -> Cow<[u32]> { Cow::from(words) }; + // Before checking if the data starts with the magic, check if it starts + // with the magic in non-native endianness, own & swap the data if so. + if words[0] == MAGIC_NUMBER.swap_bytes() { + for word in Cow::to_mut(&mut words) { + *word = word.swap_bytes(); + } + } + assert_eq!( words[0], MAGIC_NUMBER, "wrong magic word {:x}. Make sure you are using a binary SPIRV file.",