[msl] filter out entry points based on the bindings

This commit is contained in:
Dzmitry Malyshau 2021-03-15 10:25:10 -04:00 committed by Dzmitry Malyshau
parent 7d47a1b585
commit 0945889dd7
2 changed files with 35 additions and 8 deletions

View File

@ -73,8 +73,6 @@ pub enum Error {
Utf8(#[from] FromUtf8Error),
#[error(transparent)]
Type(#[from] TypifyError),
#[error("bind source for {0:?} is missing from the map")]
MissingBindTarget(BindSource),
#[error("bind target {0:?} is empty")]
UnimplementedBindTarget(BindTarget),
#[error("composing of {0:?} is not implemented yet")]
@ -89,6 +87,12 @@ pub enum Error {
Validation,
}
#[derive(Debug, thiserror::Error)]
pub enum EntryPointError {
#[error("bind source for {0:?} is missing from the map")]
MissingBinding(BindSource),
}
#[derive(Clone, Copy, Debug)]
enum LocationMode {
VertexInput,
@ -154,7 +158,7 @@ impl Options {
&self,
stage: crate::ShaderStage,
res_binding: &crate::ResourceBinding,
) -> Result<ResolvedBinding, Error> {
) -> Result<ResolvedBinding, EntryPointError> {
let source = BindSource {
stage,
group: res_binding.group,
@ -166,7 +170,7 @@ impl Options {
prefix: "fake",
index: 0,
}),
None => Err(Error::MissingBindTarget(source)),
None => Err(EntryPointError::MissingBinding(source)),
}
}
}
@ -232,8 +236,10 @@ impl ResolvedBinding {
/// for the use of the result.
pub struct TranslationInfo {
/// Mapping of the entry point names. Each item in the array
/// corresponds to an entry point in `module.entry_points.iter()`.
pub entry_point_names: Vec<String>,
/// corresponds to an entry point index.
///
///Note: Some entry points may fail translation because of missing bindings.
pub entry_point_names: Vec<Result<String, EntryPointError>>,
}
pub fn write_string(

View File

@ -1179,6 +1179,27 @@ impl<W: Write> Writer<W> {
for (ep_index, ep) in module.entry_points.iter().enumerate() {
let fun = &ep.function;
let fun_info = analysis.get_entry_point(ep_index);
// skip this entry point if any global bindings are missing
if !options.fake_missing_bindings {
if let Some(err) = module
.global_variables
.iter()
.find_map(|(var_handle, var)| {
if !fun_info[var_handle].is_empty() {
if let Some(ref br) = var.binding {
if let Err(e) = options.resolve_global_binding(ep.stage, br) {
return Some(e);
}
}
}
None
})
{
info.entry_point_names.push(Err(err));
continue;
}
}
self.typifier.resolve_all(
&fun.expressions,
&module.types,
@ -1192,7 +1213,7 @@ impl<W: Write> Writer<W> {
)?;
let fun_name = &self.names[&NameKey::EntryPoint(ep_index as _)];
info.entry_point_names.push(fun_name.clone());
info.entry_point_names.push(Ok(fun_name.clone()));
let stage_out_name = format!("{}Output", fun_name);
let stage_in_name = format!("{}Input", fun_name);
@ -1340,7 +1361,7 @@ impl<W: Write> Writer<W> {
write!(self.out, "{} ", separator)?;
tyvar.try_fmt(&mut self.out)?;
if let Some(ref binding) = var.binding {
let resolved = options.resolve_global_binding(ep.stage, binding)?;
let resolved = options.resolve_global_binding(ep.stage, binding).unwrap();
resolved.try_fmt_decorated(&mut self.out, "")?;
}
if let Some(value) = var.init {