[msl] fake bindings

This commit is contained in:
Dzmitry Malyshau 2021-02-19 17:26:49 -05:00 committed by Dzmitry Malyshau
parent 0e3f745fb2
commit 99c1add358
3 changed files with 44 additions and 32 deletions

View File

@ -40,7 +40,7 @@ struct Parameters {
#[cfg_attr(not(feature = "spv-out"), allow(dead_code))]
spv_capabilities: naga::FastHashSet<spirv::Capability>,
#[cfg_attr(not(feature = "msl-out"), allow(dead_code))]
mtl_bindings: naga::FastHashMap<BindSource, BindTarget>,
mtl_bindings: Option<naga::FastHashMap<BindSource, BindTarget>>,
}
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();
}

View File

@ -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);

View File

@ -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();