summaryrefslogtreecommitdiffstats
path: root/third_party/rust/naga/src/front/spv/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/naga/src/front/spv/mod.rs')
-rw-r--r--third_party/rust/naga/src/front/spv/mod.rs68
1 files changed, 35 insertions, 33 deletions
diff --git a/third_party/rust/naga/src/front/spv/mod.rs b/third_party/rust/naga/src/front/spv/mod.rs
index 8b1c854358..b793448597 100644
--- a/third_party/rust/naga/src/front/spv/mod.rs
+++ b/third_party/rust/naga/src/front/spv/mod.rs
@@ -577,6 +577,9 @@ pub struct Frontend<I> {
lookup_function_type: FastHashMap<spirv::Word, LookupFunctionType>,
lookup_function: FastHashMap<spirv::Word, LookupFunction>,
lookup_entry_point: FastHashMap<spirv::Word, EntryPoint>,
+ // When parsing functions, each entry point function gets an entry here so that additional
+ // processing for them can be performed after all function parsing.
+ deferred_entry_points: Vec<(EntryPoint, spirv::Word)>,
//Note: each `OpFunctionCall` gets a single entry here, indexed by the
// dummy `Handle<crate::Function>` of the call site.
deferred_function_calls: Vec<spirv::Word>,
@@ -628,6 +631,7 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
lookup_function_type: FastHashMap::default(),
lookup_function: FastHashMap::default(),
lookup_entry_point: FastHashMap::default(),
+ deferred_entry_points: Vec::default(),
deferred_function_calls: Vec::default(),
dummy_functions: Arena::new(),
function_call_graph: GraphMap::new(),
@@ -1561,12 +1565,10 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
span,
);
- if ty.name.as_deref() == Some("gl_PerVertex") {
- if let Some(crate::Binding::BuiltIn(built_in)) =
- members[index as usize].binding
- {
- self.gl_per_vertex_builtin_access.insert(built_in);
- }
+ if let Some(crate::Binding::BuiltIn(built_in)) =
+ members[index as usize].binding
+ {
+ self.gl_per_vertex_builtin_access.insert(built_in);
}
AccessExpression {
@@ -3956,6 +3958,12 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
}?;
}
+ // Do entry point specific processing after all functions are parsed so that we can
+ // cull unused problematic builtins of gl_PerVertex.
+ for (ep, fun_id) in core::mem::take(&mut self.deferred_entry_points) {
+ self.process_entry_point(&mut module, ep, fun_id)?;
+ }
+
log::info!("Patching...");
{
let mut nodes = petgraph::algo::toposort(&self.function_call_graph, None)
@@ -4868,6 +4876,11 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
let low = self.next()?;
match width {
4 => crate::Literal::U32(low),
+ 8 => {
+ inst.expect(5)?;
+ let high = self.next()?;
+ crate::Literal::U64(u64::from(high) << 32 | u64::from(low))
+ }
_ => return Err(Error::InvalidTypeWidth(width as u32)),
}
}
@@ -5081,7 +5094,7 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
None
};
let span = self.span_from_with_op(start);
- let mut dec = self.future_decor.remove(&id).unwrap_or_default();
+ let dec = self.future_decor.remove(&id).unwrap_or_default();
let original_ty = self.lookup_type.lookup(type_id)?.handle;
let mut ty = original_ty;
@@ -5127,17 +5140,6 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
None => map_storage_class(storage_class)?,
};
- // Fix empty name for gl_PerVertex struct generated by glslang
- if let crate::TypeInner::Pointer { .. } = module.types[original_ty].inner {
- if ext_class == ExtendedClass::Input || ext_class == ExtendedClass::Output {
- if let Some(ref dec_name) = dec.name {
- if dec_name.is_empty() {
- dec.name = Some("perVertexStruct".to_string())
- }
- }
- }
- }
-
let (inner, var) = match ext_class {
ExtendedClass::Global(mut space) => {
if let crate::AddressSpace::Storage { ref mut access } = space {
@@ -5323,6 +5325,21 @@ pub fn parse_u8_slice(data: &[u8], options: &Options) -> Result<crate::Module, E
Frontend::new(words, options).parse()
}
+/// Helper function to check if `child` is in the scope of `parent`
+fn is_parent(mut child: usize, parent: usize, block_ctx: &BlockContext) -> bool {
+ loop {
+ if child == parent {
+ // The child is in the scope parent
+ break true;
+ } else if child == 0 {
+ // Searched finished at the root the child isn't in the parent's body
+ break false;
+ }
+
+ child = block_ctx.bodies[child].parent;
+ }
+}
+
#[cfg(test)]
mod test {
#[test]
@@ -5339,18 +5356,3 @@ mod test {
let _ = super::parse_u8_slice(&bin, &Default::default()).unwrap();
}
}
-
-/// Helper function to check if `child` is in the scope of `parent`
-fn is_parent(mut child: usize, parent: usize, block_ctx: &BlockContext) -> bool {
- loop {
- if child == parent {
- // The child is in the scope parent
- break true;
- } else if child == 0 {
- // Searched finished at the root the child isn't in the parent's body
- break false;
- }
-
- child = block_ctx.bodies[child].parent;
- }
-}