diff --git a/src/front/glsl/ast.rs b/src/front/glsl/ast.rs index 481ff99d8d..f98e2a2c7b 100644 --- a/src/front/glsl/ast.rs +++ b/src/front/glsl/ast.rs @@ -1,5 +1,3 @@ -use bit_set::BitSet; - use super::{ super::{Emitter, Typifier}, constants::ConstantSolver, @@ -30,19 +28,23 @@ pub struct GlobalLookup { } #[derive(Debug, Clone)] +pub struct ParameterInfo { + pub qualifier: ParameterQualifier, + /// Wether the parameter should be treated as a depth image instead of a + /// sampled image + pub depth: bool, +} + +#[derive(Debug)] pub struct FunctionDeclaration { /// Normalized function parameters, modifiers are not applied pub parameters: Vec>, - pub qualifiers: Vec, + pub parameters_info: Vec, pub handle: Handle, /// Wheter this function was already defined or is just a prototype pub defined: bool, /// Wheter or not this function returns void (nothing) pub void: bool, - /// [`BitSet`](BitSet) where each bit indicates if the argument in the - /// corresponding position should be treated as a depth image instead of a - /// regular image - pub depth_set: BitSet, } bitflags::bitflags! { @@ -187,7 +189,7 @@ pub struct Context<'function> { expressions: &'function mut Arena, pub locals: &'function mut Arena, pub arguments: &'function mut Vec, - pub depth_set: BitSet, + pub parameters_info: Vec, pub arg_use: Vec, //TODO: Find less allocation heavy representation @@ -212,7 +214,7 @@ impl<'function> Context<'function> { expressions, locals, arguments, - depth_set: BitSet::new(), + parameters_info: Vec::new(), arg_use: vec![EntryArgUse::empty(); program.entry_args.len()], scopes: vec![FastHashMap::default()], @@ -383,6 +385,11 @@ impl<'function> Context<'function> { self.arguments.push(arg); + self.parameters_info.push(ParameterInfo { + qualifier, + depth: false, + }); + if let Some(name) = name { let expr = self.add_expression(Expression::FunctionArgument(index as u32), body); let mutable = qualifier != ParameterQualifier::Const && !opaque; diff --git a/src/front/glsl/functions.rs b/src/front/glsl/functions.rs index c11c47457f..005bcb2a87 100644 --- a/src/front/glsl/functions.rs +++ b/src/front/glsl/functions.rs @@ -1,5 +1,3 @@ -use bit_set::BitSet; - use crate::{ proc::ensure_block_returns, Arena, BinaryOperator, Block, Constant, ConstantInner, EntryPoint, Expression, Function, FunctionArgument, FunctionResult, Handle, ImageClass, ImageDimension, @@ -823,7 +821,7 @@ impl Program<'_> { for ((i, decl_arg), mut call_arg) in decl.parameters.iter().enumerate().zip(args.iter().copied()) { - if decl.depth_set.contains(i) { + if decl.parameters_info[i].depth { call_arg.0 = sampled_to_depth(&mut self.module, ctx, call_arg, body)?; } @@ -902,24 +900,24 @@ impl Program<'_> { ErrorKind::SemanticError(meta, format!("Unknown function '{}'", name).into()) })?; - let qualifiers = decl.qualifiers.clone(); + let parameters_info = decl.parameters_info.clone(); let parameters = decl.parameters.clone(); let function = decl.handle; let is_void = decl.void; let mut arguments = Vec::with_capacity(args.len()); let mut proxy_writes = Vec::new(); - for (qualifier, (expr, parameter)) in qualifiers + for (parameter_info, (expr, parameter)) in parameters_info .iter() .zip(raw_args.iter().zip(parameters.iter())) { let (mut handle, meta) = - ctx.lower_expect(self, *expr, qualifier.is_lhs(), body)?; + ctx.lower_expect(self, *expr, parameter_info.qualifier.is_lhs(), body)?; if let TypeInner::Vector { size, kind, width } = *self.resolve_type(ctx, handle, meta)? { - if qualifier.is_lhs() + if parameter_info.qualifier.is_lhs() && matches!(*ctx.get_expression(handle), Expression::Swizzle { .. }) { let ty = self.module.types.fetch_or_append(Type { @@ -1024,8 +1022,7 @@ impl Program<'_> { name: String, // Normalized function parameters, modifiers are not applied parameters: Vec>, - depth_set: BitSet, - qualifiers: Vec, + parameters_info: Vec, meta: SourceMetadata, ) -> Result, ErrorKind> { ensure_block_returns(&mut function.body); @@ -1070,8 +1067,7 @@ impl Program<'_> { } decl.defined = true; - decl.qualifiers = qualifiers; - decl.depth_set = depth_set; + decl.parameters_info = parameters_info; *self.module.functions.get_mut(decl.handle) = function; return Ok(decl.handle); } @@ -1080,11 +1076,10 @@ impl Program<'_> { let handle = module.functions.append(function); declarations.push(FunctionDeclaration { parameters, - qualifiers, + parameters_info, handle, defined: true, void, - depth_set, }); handle }) @@ -1096,7 +1091,7 @@ impl Program<'_> { name: String, // Normalized function parameters, modifiers are not applied parameters: Vec>, - qualifiers: Vec, + parameters_info: Vec, meta: SourceMetadata, ) -> Result<(), ErrorKind> { let void = function.result.is_none(); @@ -1133,11 +1128,10 @@ impl Program<'_> { let handle = module.functions.append(function); declarations.push(FunctionDeclaration { parameters, - qualifiers, + parameters_info, handle, defined: false, void, - depth_set: BitSet::new(), }); Ok(()) @@ -1418,8 +1412,8 @@ impl Program<'_> { } } -/// Helper function to cast a expression holding a sampled a image to a -/// depth one. +/// Helper function to cast a expression holding a sampled image to a +/// depth image. /// /// Creates a new expression to make sure the typifier doesn't return a /// cached evaluation. @@ -1432,7 +1426,7 @@ fn sampled_to_depth( let ty = match ctx[image] { Expression::GlobalVariable(handle) => &mut module.global_variables.get_mut(handle).ty, Expression::FunctionArgument(i) => { - ctx.depth_set.insert(i as usize); + ctx.parameters_info[i as usize].depth = true; &mut ctx.arguments[i as usize].ty } _ => { diff --git a/src/front/glsl/parser.rs b/src/front/glsl/parser.rs index 03f3586818..a5b62e8caf 100644 --- a/src/front/glsl/parser.rs +++ b/src/front/glsl/parser.rs @@ -689,7 +689,6 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> { let mut arguments = Vec::new(); // Normalized function parameters, modifiers are not applied let mut parameters = Vec::new(); - let mut qualifiers = Vec::new(); let mut body = Block::new(); let mut context = Context::new( @@ -700,12 +699,7 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> { &mut arguments, ); - self.parse_function_args( - &mut context, - &mut body, - &mut qualifiers, - &mut parameters, - )?; + self.parse_function_args(&mut context, &mut body, &mut parameters)?; let end_meta = self.expect(TokenValue::RightParen)?.meta; meta = meta.union(&end_meta); @@ -714,6 +708,11 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> { return match token.value { TokenValue::Semicolon => { // This branch handles function prototypes + + let Context { + parameters_info, .. + } = context; + self.program.add_prototype( Function { name: Some(name.clone()), @@ -723,7 +722,7 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> { }, name, parameters, - qualifiers, + parameters_info, meta, )?; @@ -738,7 +737,9 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> { self.parse_compound_statement(&mut context, &mut body)?; let Context { - arg_use, depth_set, .. + arg_use, + parameters_info, + .. } = context; let handle = self.program.add_function( Function { @@ -752,8 +753,7 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> { }, name, parameters, - depth_set, - qualifiers, + parameters_info, meta, )?; @@ -1864,13 +1864,11 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> { &mut self, context: &mut Context, body: &mut Block, - qualifiers: &mut Vec, parameters: &mut Vec>, ) -> Result<()> { loop { if self.peek_type_name() || self.peek_parameter_qualifier() { let qualifier = self.parse_parameter_qualifier(); - qualifiers.push(qualifier); let ty = self.parse_type_non_void()?.0; match self.expect_peek()?.value {