From 99c1add3588484b189120bc2e19f462e182ae989 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Fri, 19 Feb 2021 17:26:49 -0500 Subject: [PATCH] [msl] fake bindings --- examples/convert.rs | 51 +++++++++++++++++++++++++-------------------- src/back/msl/mod.rs | 22 ++++++++++++------- tests/snapshots.rs | 3 ++- 3 files changed, 44 insertions(+), 32 deletions(-) diff --git a/examples/convert.rs b/examples/convert.rs index 7e832e0162..03bdcdae03 100644 --- a/examples/convert.rs +++ b/examples/convert.rs @@ -40,7 +40,7 @@ struct Parameters { #[cfg_attr(not(feature = "spv-out"), allow(dead_code))] spv_capabilities: naga::FastHashSet, #[cfg_attr(not(feature = "msl-out"), allow(dead_code))] - mtl_bindings: naga::FastHashMap, + mtl_bindings: Option>, } trait PrettyResult { @@ -177,31 +177,36 @@ fn main() { #[cfg(feature = "msl-out")] "metal" => { use naga::back::msl; - let mut binding_map = msl::BindingMap::default(); - for (key, value) in params.mtl_bindings { - binding_map.insert( - msl::BindSource { - stage: match key.stage { - Stage::Vertex => naga::ShaderStage::Vertex, - Stage::Fragment => naga::ShaderStage::Fragment, - Stage::Compute => naga::ShaderStage::Compute, - }, - group: key.group, - binding: key.binding, - }, - msl::BindTarget { - buffer: value.buffer, - texture: value.texture, - sampler: value.sampler, - mutable: value.mutable, - }, - ); - } - let options = msl::Options { + let mut options = msl::Options { lang_version: (1, 0), + binding_map: msl::BindingMap::default(), spirv_cross_compatibility: false, - binding_map, + fake_missing_bindings: false, }; + if let Some(map) = params.mtl_bindings { + for (key, value) in map { + options.binding_map.insert( + msl::BindSource { + stage: match key.stage { + Stage::Vertex => naga::ShaderStage::Vertex, + Stage::Fragment => naga::ShaderStage::Fragment, + Stage::Compute => naga::ShaderStage::Compute, + }, + group: key.group, + binding: key.binding, + }, + msl::BindTarget { + buffer: value.buffer, + texture: value.texture, + sampler: value.sampler, + mutable: value.mutable, + }, + ); + } + } else { + log::warn!("Metal binding map is missing"); + options.fake_missing_bindings = true; + } let (msl, _) = msl::write_string(&module, &analysis, &options).unwrap(); fs::write(&args[2], msl).unwrap(); } diff --git a/src/back/msl/mod.rs b/src/back/msl/mod.rs index 9adeed2c62..ecf9eee7d7 100644 --- a/src/back/msl/mod.rs +++ b/src/back/msl/mod.rs @@ -92,18 +92,21 @@ enum LocationMode { pub struct Options { /// (Major, Minor) target version of the Metal Shading Language. pub lang_version: (u8, u8), - /// Make it possible to link different stages via SPIRV-Cross. - pub spirv_cross_compatibility: bool, /// Binding model mapping to Metal. pub binding_map: BindingMap, + /// 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. + pub fake_missing_bindings: bool, } impl Default for Options { fn default() -> Self { Options { lang_version: (1, 0), - spirv_cross_compatibility: false, binding_map: BindingMap::default(), + spirv_cross_compatibility: false, + fake_missing_bindings: false, } } } @@ -142,11 +145,14 @@ impl Options { group, binding, }; - self.binding_map - .get(&source) - .cloned() - .map(ResolvedBinding::Resource) - .ok_or(Error::MissingBindTarget(source)) + match self.binding_map.get(&source) { + Some(target) => Ok(ResolvedBinding::Resource(target.clone())), + None if self.fake_missing_bindings => Ok(ResolvedBinding::User { + prefix: "fake", + index: 0, + }), + None => Err(Error::MissingBindTarget(source)), + } } None => { log::error!("Missing binding for {:?}", var.name); diff --git a/tests/snapshots.rs b/tests/snapshots.rs index f68f4d6afc..02e8cd2dac 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -164,8 +164,9 @@ fn check_output_msl( } let options = msl::Options { lang_version: (1, 0), - spirv_cross_compatibility: false, binding_map, + spirv_cross_compatibility: false, + fake_missing_bindings: false, }; let (msl, _) = msl::write_string(module, analysis, &options).unwrap();