From 285a855e199221878ec3afb894faff1dec2dd8ee Mon Sep 17 00:00:00 2001 From: Ashley Date: Fri, 16 Apr 2021 20:11:26 +0200 Subject: [PATCH] Impl `Hash` for `msl::Options` (#716) * Impl `Hash` for `msl::Options` * Remove ordered float * [msl] derive everything on Options manually * [msl] switch from Arena to Vec for the options * Fix the clippy error by allowing derive_hash_xor_eq * Fix skybox test Co-authored-by: Dzmitry Malyshau --- src/back/msl/mod.rs | 31 ++++++++++++++++--------------- src/back/msl/sampler.rs | 38 +++++++++++++++++++++++++++++++++----- tests/in/skybox.param.ron | 2 +- 3 files changed, 50 insertions(+), 21 deletions(-) diff --git a/src/back/msl/mod.rs b/src/back/msl/mod.rs index db1fcedf00..59b5097c6e 100644 --- a/src/back/msl/mod.rs +++ b/src/back/msl/mod.rs @@ -23,11 +23,7 @@ For the result type, if it's a structure, we re-compose it with a temporary valu holding the result. !*/ -use crate::{ - arena::{Arena, Handle}, - valid::ModuleInfo, - FastHashMap, -}; +use crate::{arena::Handle, valid::ModuleInfo}; use std::fmt::{Error as FmtError, Write}; mod keywords; @@ -37,15 +33,18 @@ mod writer; pub use writer::Writer; pub type Slot = u8; +pub type InlineSamplerIndex = u8; -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(serde::Serialize))] #[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] pub enum BindSamplerTarget { Resource(Slot), - Inline(Handle), + Inline(InlineSamplerIndex), } -#[derive(Clone, Debug, Default, PartialEq)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(serde::Serialize))] #[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] pub struct BindTarget { #[cfg_attr(feature = "deserialize", serde(default))] @@ -67,7 +66,7 @@ pub struct BindSource { pub binding: u32, } -pub type BindingMap = FastHashMap; +pub type BindingMap = std::collections::BTreeMap; #[derive(Clone, Debug, Default, Hash, Eq, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "serialize", derive(serde::Serialize))] @@ -127,7 +126,8 @@ enum LocationMode { Uniform, } -#[derive(Debug)] +#[derive(Clone, Debug, Hash, PartialEq)] +#[cfg_attr(feature = "serialize", derive(serde::Serialize))] #[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] pub struct Options { /// (Major, Minor) target version of the Metal Shading Language. @@ -137,7 +137,7 @@ pub struct Options { /// Push constants mapping to Metal. pub push_constants_map: PushConstantsMap, /// Samplers to be inlined into the code. - pub inline_samplers: Arena, + pub inline_samplers: Vec, /// Make it possible to link different stages via SPIRV-Cross. pub spirv_cross_compatibility: bool, /// Don't panic on missing bindings, instead generate invalid MSL. @@ -150,7 +150,7 @@ impl Default for Options { lang_version: (1, 0), binding_map: BindingMap::default(), push_constants_map: PushConstantsMap::default(), - inline_samplers: Arena::new(), + inline_samplers: Vec::new(), spirv_cross_compatibility: false, fake_missing_bindings: true, } @@ -158,7 +158,8 @@ impl Default for Options { } // A subset of options that are meant to be changed per pipeline. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(serde::Serialize))] #[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] pub struct PipelineOptions { /// Allow `BuiltIn::PointSize` in the vertex shader. @@ -253,9 +254,9 @@ impl ResolvedBinding { fn as_inline_sampler<'a>(&self, options: &'a Options) -> Option<&'a sampler::InlineSampler> { match *self { Self::Resource(BindTarget { - sampler: Some(BindSamplerTarget::Inline(handle)), + sampler: Some(BindSamplerTarget::Inline(index)), .. - }) => Some(&options.inline_samplers[handle]), + }) => Some(&options.inline_samplers[index as usize]), _ => None, } } diff --git a/src/back/msl/sampler.rs b/src/back/msl/sampler.rs index 7d76aac921..c603fac1b1 100644 --- a/src/back/msl/sampler.rs +++ b/src/back/msl/sampler.rs @@ -1,8 +1,11 @@ #[cfg(feature = "deserialize")] use serde::Deserialize; +#[cfg(feature = "serialize")] +use serde::Serialize; use std::{num::NonZeroU32, ops::Range}; -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "deserialize", derive(Deserialize))] pub enum Coord { Normalized, @@ -24,7 +27,8 @@ impl Coord { } } -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "deserialize", derive(Deserialize))] pub enum Address { Repeat, @@ -52,7 +56,8 @@ impl Address { } } -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "deserialize", derive(Deserialize))] pub enum BorderColor { TransparentBlack, @@ -76,7 +81,8 @@ impl BorderColor { } } -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "deserialize", derive(Deserialize))] pub enum Filter { Nearest, @@ -98,7 +104,8 @@ impl Default for Filter { } } -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "deserialize", derive(Deserialize))] pub enum CompareFunc { Never, @@ -133,6 +140,7 @@ impl CompareFunc { } #[derive(Clone, Debug, Default, PartialEq)] +#[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "deserialize", derive(Deserialize))] pub struct InlineSampler { pub coord: Coord, @@ -145,3 +153,23 @@ pub struct InlineSampler { pub max_anisotropy: Option, pub compare_func: CompareFunc, } + +impl Eq for InlineSampler {} + +#[allow(clippy::derive_hash_xor_eq)] +impl std::hash::Hash for InlineSampler { + fn hash(&self, hasher: &mut H) { + self.coord.hash(hasher); + self.address.hash(hasher); + self.border_color.hash(hasher); + self.mag_filter.hash(hasher); + self.min_filter.hash(hasher); + self.mip_filter.hash(hasher); + self.lod_clamp + .as_ref() + .map(|range| (range.start.to_bits(), range.end.to_bits())) + .hash(hasher); + self.max_anisotropy.hash(hasher); + self.compare_func.hash(hasher); + } +} diff --git a/tests/in/skybox.param.ron b/tests/in/skybox.param.ron index dec89803e3..aae6af7cae 100644 --- a/tests/in/skybox.param.ron +++ b/tests/in/skybox.param.ron @@ -10,7 +10,7 @@ binding_map: { (stage: Vertex, group: 0, binding: 0): (buffer: Some(0)), (stage: Fragment, group: 0, binding: 1): (texture: Some(0)), - (stage: Fragment, group: 0, binding: 2): (sampler: Some(Inline(1))), + (stage: Fragment, group: 0, binding: 2): (sampler: Some(Inline(0))), }, push_constants_map: ( ),