From 41f112f5a10c80f3dcd00faae09de4bd5ce341fc Mon Sep 17 00:00:00 2001 From: andriyDev Date: Sun, 17 Sep 2023 10:32:37 -0700 Subject: [PATCH] Prevent using multiple push constant variables in one entry point. --- src/valid/interface.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/valid/interface.rs b/src/valid/interface.rs index 2416e89216..9aecca4c55 100644 --- a/src/valid/interface.rs +++ b/src/valid/interface.rs @@ -90,6 +90,8 @@ pub enum EntryPointError { ForbiddenStageOperations, #[error("Global variable {0:?} is used incorrectly as {1:?}")] InvalidGlobalUsage(Handle, GlobalUse), + #[error("More than 1 push constant variable is used")] + MoreThanOnePushConstantUsed(Handle), #[error("Bindings for {0:?} conflict with other resource")] BindingCollision(Handle), #[error("Argument {0} varying error")] @@ -701,6 +703,31 @@ impl super::Validator { bg.clear(); } + #[cfg(feature = "validate")] + { + let mut used_push_constants = module + .global_variables + .iter() + .filter(|(_, var)| var.space == crate::AddressSpace::PushConstant) + .map(|(handle, _)| handle) + .filter(|handle| { + let usage = info[*handle]; + return !usage.is_empty(); + }); + // Check if there is one push constant. Some iterators can restart iteration after + // `next` returns None, so don't continue if the iterator returns None. + if let Some(_) = used_push_constants.next() { + // Check if there is a second push constant. + match used_push_constants.next() { + None => {} + Some(handle) => { + return Err(EntryPointError::MoreThanOnePushConstantUsed(handle) + .with_span_handle(handle, &module.global_variables)) + } + } + } + } + #[cfg(feature = "validate")] for (var_handle, var) in module.global_variables.iter() { let usage = info[var_handle];