Skip to content

Commit

Permalink
[naga] Retain unnamed overrides' types during compaction.
Browse files Browse the repository at this point in the history
Ensure that unnamed overrides' types are retained, even when the
overrides are used only by global expressions. Add a test case.

Fixes gfx-rs#7072.
  • Loading branch information
jimblandy committed Feb 7, 2025
1 parent 7081cff commit bea7832
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 10 deletions.
4 changes: 3 additions & 1 deletion naga/src/compact/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ impl ExpressionTracer<'_> {
}
Ex::Override(handle) => {
self.overrides_used.insert(handle);
if let Some(init) = self.overrides[handle].init {
let r#override = &self.overrides[handle];
self.types_used.insert(r#override.ty);
if let Some(init) = r#override.init {
match self.global_expressions_used {
Some(ref mut used) => used.insert(init),
None => self.expressions_used.insert(init),
Expand Down
82 changes: 73 additions & 9 deletions naga/src/compact/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ pub fn compact(module: &mut crate::Module) {
if r#override.name.is_some() {
log::trace!("tracing override {:?}", r#override.name.as_ref().unwrap());
module_tracer.overrides_used.insert(handle);
module_tracer.types_used.insert(r#override.ty);
if let Some(init) = r#override.init {
module_tracer.global_expressions_used.insert(init);
}
Expand Down Expand Up @@ -171,15 +172,6 @@ pub fn compact(module: &mut crate::Module) {
})
.collect();

// Overrides' initializers are taken care of already, because
// expression tracing sees through overrides. But we still need to
// note type usage.
for (handle, r#override) in module.overrides.iter() {
if module_tracer.overrides_used.contains(handle) {
module_tracer.types_used.insert(r#override.ty);
}
}

// Treat all named types as used.
for (handle, ty) in module.types.iter() {
log::trace!("tracing type {:?}, name {:?}", handle, ty.name);
Expand Down Expand Up @@ -1006,3 +998,75 @@ fn unnamed_constant_type() {
compact(&mut module);
assert!(validator.validate(&module).is_ok());
}

#[test]
fn unnamed_override_type() {
let mut module = crate::Module::default();
let nowhere = crate::Span::default();

// This type is used only by the unnamed override.
let ty_u32 = module.types.insert(
crate::Type {
name: None,
inner: crate::TypeInner::Scalar(crate::Scalar::U32),
},
nowhere,
);

// This type is used by the named override.
let ty_i32 = module.types.insert(
crate::Type {
name: None,
inner: crate::TypeInner::Scalar(crate::Scalar::I32),
},
nowhere,
);

let unnamed_init = module
.global_expressions
.append(crate::Expression::Literal(crate::Literal::U32(0)), nowhere);

let unnamed_override = module.overrides.append(
crate::Override {
name: None,
id: Some(42),
ty: ty_u32,
init: Some(unnamed_init),
},
nowhere,
);

// The named override is initialized using a Splat expression, to
// give the named override a type distinct from the unnamed
// override's.
let unnamed_override_expr = module
.global_expressions
.append(crate::Expression::Override(unnamed_override), nowhere);
let named_init = module.global_expressions.append(
crate::Expression::As {
expr: unnamed_override_expr,
kind: crate::ScalarKind::Sint,
convert: None,
},
nowhere,
);

let _named_override = module.overrides.append(
crate::Override {
name: Some("totally_named".to_string()),
id: None,
ty: ty_i32,
init: Some(named_init),
},
nowhere,
);

let mut validator = super::valid::Validator::new(
super::valid::ValidationFlags::all(),
super::valid::Capabilities::all(),
);

assert!(validator.validate(&module).is_ok());
compact(&mut module);
assert!(validator.validate(&module).is_ok());
}

0 comments on commit bea7832

Please sign in to comment.