diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/gfx-auxil | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/gfx-auxil')
-rw-r--r-- | third_party/rust/gfx-auxil/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | third_party/rust/gfx-auxil/Cargo.toml | 20 | ||||
-rw-r--r-- | third_party/rust/gfx-auxil/src/lib.rs | 143 |
3 files changed, 164 insertions, 0 deletions
diff --git a/third_party/rust/gfx-auxil/.cargo-checksum.json b/third_party/rust/gfx-auxil/.cargo-checksum.json new file mode 100644 index 0000000000..3d2fe0ab08 --- /dev/null +++ b/third_party/rust/gfx-auxil/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"ef7358fc7e14a41a56fd317a898c4ad08f7252ab6bf61f798d05b1246ca9b3e8","src/lib.rs":"e51c05963a63a153436cb821d5ba01301442330a558564330d2262b98962ee1d"},"package":null}
\ No newline at end of file diff --git a/third_party/rust/gfx-auxil/Cargo.toml b/third_party/rust/gfx-auxil/Cargo.toml new file mode 100644 index 0000000000..b27df9ec4f --- /dev/null +++ b/third_party/rust/gfx-auxil/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "gfx-auxil" +version = "0.5.0" +description = "Implementation details shared between gfx-rs backends" +homepage = "https://github.com/gfx-rs/gfx" +repository = "https://github.com/gfx-rs/gfx" +keywords = ["graphics", "gamedev"] +license = "MIT OR Apache-2.0" +authors = ["The Gfx-rs Developers"] +documentation = "https://docs.rs/gfx-auxil" +workspace = "../../../" +edition = "2018" + +[dependencies] +hal = { path = "../../hal", version = "0.6", package = "gfx-hal" } +fxhash = "0.2.1" +spirv_cross = { version = "0.22", optional = true } + +[lib] +name = "gfx_auxil" diff --git a/third_party/rust/gfx-auxil/src/lib.rs b/third_party/rust/gfx-auxil/src/lib.rs new file mode 100644 index 0000000000..89a0109931 --- /dev/null +++ b/third_party/rust/gfx-auxil/src/lib.rs @@ -0,0 +1,143 @@ +use std::{io, slice}; +#[cfg(feature = "spirv_cross")] +use { + hal::{device::ShaderError, pso}, + spirv_cross::spirv, +}; + +/// Fast hash map used internally. +pub type FastHashMap<K, V> = + std::collections::HashMap<K, V, std::hash::BuildHasherDefault<fxhash::FxHasher>>; +pub type FastHashSet<K> = + std::collections::HashSet<K, std::hash::BuildHasherDefault<fxhash::FxHasher>>; + +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[repr(u8)] +pub enum ShaderStage { + Vertex, + Hull, + Domain, + Geometry, + Fragment, + Compute, + Task, + Mesh, +} + +impl ShaderStage { + pub fn to_flag(self) -> hal::pso::ShaderStageFlags { + use hal::pso::ShaderStageFlags as Ssf; + match self { + ShaderStage::Vertex => Ssf::VERTEX, + ShaderStage::Hull => Ssf::HULL, + ShaderStage::Domain => Ssf::DOMAIN, + ShaderStage::Geometry => Ssf::GEOMETRY, + ShaderStage::Fragment => Ssf::FRAGMENT, + ShaderStage::Compute => Ssf::COMPUTE, + ShaderStage::Task => Ssf::TASK, + ShaderStage::Mesh => Ssf::MESH, + } + } +} + +/// Safely read SPIR-V +/// +/// Converts to native endianness and returns correctly aligned storage without unnecessary +/// copying. Returns an `InvalidData` error if the input is trivially not SPIR-V. +/// +/// This function can also be used to convert an already in-memory `&[u8]` to a valid `Vec<u32>`, +/// but prefer working with `&[u32]` from the start whenever possible. +/// +/// # Examples +/// ```no_run +/// let mut file = std::fs::File::open("/path/to/shader.spv").unwrap(); +/// let words = gfx_auxil::read_spirv(&mut file).unwrap(); +/// ``` +/// ``` +/// const SPIRV: &[u8] = &[ +/// 0x03, 0x02, 0x23, 0x07, // ... +/// ]; +/// let words = gfx_auxil::read_spirv(std::io::Cursor::new(&SPIRV[..])).unwrap(); +/// ``` +pub fn read_spirv<R: io::Read + io::Seek>(mut x: R) -> io::Result<Vec<u32>> { + let size = x.seek(io::SeekFrom::End(0))?; + if size % 4 != 0 { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "input length not divisible by 4", + )); + } + if size > usize::max_value() as u64 { + return Err(io::Error::new(io::ErrorKind::InvalidData, "input too long")); + } + let words = (size / 4) as usize; + let mut result = Vec::<u32>::with_capacity(words); + x.seek(io::SeekFrom::Start(0))?; + unsafe { + // Writing all bytes through a pointer with less strict alignment when our type has no + // invalid bitpatterns is safe. + x.read_exact(slice::from_raw_parts_mut( + result.as_mut_ptr() as *mut u8, + words * 4, + ))?; + result.set_len(words); + } + const MAGIC_NUMBER: u32 = 0x07230203; + if result.len() > 0 && result[0] == MAGIC_NUMBER.swap_bytes() { + for word in &mut result { + *word = word.swap_bytes(); + } + } + if result.len() == 0 || result[0] != MAGIC_NUMBER { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "input missing SPIR-V magic number", + )); + } + Ok(result) +} + +#[cfg(feature = "spirv_cross")] +pub fn spirv_cross_specialize_ast<T>( + ast: &mut spirv::Ast<T>, + specialization: &pso::Specialization, +) -> Result<(), ShaderError> +where + T: spirv::Target, + spirv::Ast<T>: spirv::Compile<T> + spirv::Parse<T>, +{ + let spec_constants = ast.get_specialization_constants().map_err(|err| { + ShaderError::CompilationFailed(match err { + spirv_cross::ErrorCode::CompilationError(msg) => msg, + spirv_cross::ErrorCode::Unhandled => "Unexpected specialization constant error".into(), + }) + })?; + + for spec_constant in spec_constants { + if let Some(constant) = specialization + .constants + .iter() + .find(|c| c.id == spec_constant.constant_id) + { + // Override specialization constant values + let value = specialization.data + [constant.range.start as usize..constant.range.end as usize] + .iter() + .rev() + .fold(0u64, |u, &b| (u << 8) + b as u64); + + ast.set_scalar_constant(spec_constant.id, value) + .map_err(|err| { + ShaderError::CompilationFailed(match err { + spirv_cross::ErrorCode::CompilationError(msg) => msg, + spirv_cross::ErrorCode::Unhandled => { + "Unexpected specialization constant error".into() + } + }) + })?; + } + } + + Ok(()) +} |