mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Validate built-ins to not repeat
This commit is contained in:
committed by
Dzmitry Malyshau
parent
50de6ae9ac
commit
652b65cfa9
@@ -41,9 +41,9 @@ pub enum VaryingError {
|
||||
InvalidInterpolation,
|
||||
#[error("Interpolation must be specified on vertex shader outputs and fragment shader inputs")]
|
||||
MissingInterpolation,
|
||||
#[error("BuiltIn {0:?} is not available at this stage")]
|
||||
#[error("Built-in {0:?} is not available at this stage")]
|
||||
InvalidBuiltInStage(crate::BuiltIn),
|
||||
#[error("BuiltIn type for {0:?} is invalid")]
|
||||
#[error("Built-in type for {0:?} is invalid")]
|
||||
InvalidBuiltInType(crate::BuiltIn),
|
||||
#[error("Entry point arguments and return values must all have bindings")]
|
||||
MissingBinding,
|
||||
@@ -51,6 +51,8 @@ pub enum VaryingError {
|
||||
MemberMissingBinding(u32),
|
||||
#[error("Multiple bindings at location {location} are present")]
|
||||
BindingCollision { location: u32 },
|
||||
#[error("Built-in {0:?} is present more than once")]
|
||||
DuplicateBuiltIn(crate::BuiltIn),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, thiserror::Error)]
|
||||
@@ -96,6 +98,7 @@ struct VaryingContext<'a> {
|
||||
output: bool,
|
||||
types: &'a Arena<crate::Type>,
|
||||
location_mask: &'a mut BitSet,
|
||||
built_in_mask: u32,
|
||||
}
|
||||
|
||||
impl VaryingContext<'_> {
|
||||
@@ -107,6 +110,12 @@ impl VaryingContext<'_> {
|
||||
let ty_inner = &self.types[self.ty].inner;
|
||||
match *binding {
|
||||
crate::Binding::BuiltIn(built_in) => {
|
||||
let bit = 1 << built_in as u32;
|
||||
if self.built_in_mask & bit != 0 {
|
||||
return Err(VaryingError::DuplicateBuiltIn(built_in));
|
||||
}
|
||||
self.built_in_mask |= bit;
|
||||
|
||||
let width = 4;
|
||||
let (visible, type_good) = match built_in {
|
||||
Bi::BaseInstance | Bi::BaseVertex | Bi::InstanceIndex | Bi::VertexIndex => (
|
||||
@@ -257,7 +266,7 @@ impl VaryingContext<'_> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate(mut self, binding: Option<&crate::Binding>) -> Result<(), VaryingError> {
|
||||
fn validate(&mut self, binding: Option<&crate::Binding>) -> Result<(), VaryingError> {
|
||||
match binding {
|
||||
Some(binding) => self.validate_impl(binding),
|
||||
None => {
|
||||
@@ -409,26 +418,30 @@ impl super::Validator {
|
||||
}
|
||||
|
||||
self.location_mask.clear();
|
||||
let mut argument_built_ins = 0;
|
||||
for (index, fa) in ep.function.arguments.iter().enumerate() {
|
||||
let ctx = VaryingContext {
|
||||
let mut ctx = VaryingContext {
|
||||
ty: fa.ty,
|
||||
stage: ep.stage,
|
||||
output: false,
|
||||
types: &module.types,
|
||||
location_mask: &mut self.location_mask,
|
||||
built_in_mask: argument_built_ins,
|
||||
};
|
||||
ctx.validate(fa.binding.as_ref())
|
||||
.map_err(|e| EntryPointError::Argument(index as u32, e))?;
|
||||
argument_built_ins = ctx.built_in_mask;
|
||||
}
|
||||
|
||||
self.location_mask.clear();
|
||||
if let Some(ref fr) = ep.function.result {
|
||||
let ctx = VaryingContext {
|
||||
let mut ctx = VaryingContext {
|
||||
ty: fr.ty,
|
||||
stage: ep.stage,
|
||||
output: true,
|
||||
types: &module.types,
|
||||
location_mask: &mut self.location_mask,
|
||||
built_in_mask: 0,
|
||||
};
|
||||
ctx.validate(fr.binding.as_ref())
|
||||
.map_err(EntryPointError::Result)?;
|
||||
|
||||
Reference in New Issue
Block a user