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 <kvarkus@gmail.com>
This commit is contained in:
Ashley
2021-04-16 20:11:26 +02:00
committed by GitHub
parent 2eb3e81e19
commit 285a855e19
3 changed files with 50 additions and 21 deletions

View File

@@ -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<sampler::InlineSampler>),
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<BindSource, BindTarget>;
pub type BindingMap = std::collections::BTreeMap<BindSource, BindTarget>;
#[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<sampler::InlineSampler>,
pub inline_samplers: Vec<sampler::InlineSampler>,
/// 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,
}
}

View File

@@ -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<NonZeroU32>,
pub compare_func: CompareFunc,
}
impl Eq for InlineSampler {}
#[allow(clippy::derive_hash_xor_eq)]
impl std::hash::Hash for InlineSampler {
fn hash<H: std::hash::Hasher>(&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);
}
}

View File

@@ -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: (
),