From 717063eb2151bc7a5e7df3731792fbddd34b68de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Capucho?= Date: Sat, 31 Jul 2021 16:40:39 +0100 Subject: [PATCH] [glsl-in] Convert Sampled image to depth image --- src/front/glsl/ast.rs | 17 ++++++ src/front/glsl/functions.rs | 119 ++++++++++++++++++++++++++++++++---- src/front/glsl/parser.rs | 5 +- 3 files changed, 129 insertions(+), 12 deletions(-) diff --git a/src/front/glsl/ast.rs b/src/front/glsl/ast.rs index 3deecf4836..481ff99d8d 100644 --- a/src/front/glsl/ast.rs +++ b/src/front/glsl/ast.rs @@ -1,3 +1,5 @@ +use bit_set::BitSet; + use super::{ super::{Emitter, Typifier}, constants::ConstantSolver, @@ -11,6 +13,7 @@ use crate::{ StorageClass, Type, TypeInner, UnaryOperator, VectorSize, }; use core::convert::TryFrom; +use std::ops::Index; #[derive(Debug, Clone, Copy)] pub enum GlobalLookupKind { @@ -36,6 +39,10 @@ pub struct FunctionDeclaration { 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! { @@ -180,6 +187,7 @@ pub struct Context<'function> { expressions: &'function mut Arena, pub locals: &'function mut Arena, pub arguments: &'function mut Vec, + pub depth_set: BitSet, pub arg_use: Vec, //TODO: Find less allocation heavy representation @@ -204,6 +212,7 @@ impl<'function> Context<'function> { expressions, locals, arguments, + depth_set: BitSet::new(), arg_use: vec![EntryArgUse::empty(); program.entry_args.len()], scopes: vec![FastHashMap::default()], @@ -924,6 +933,14 @@ impl<'function> Context<'function> { } } +impl<'function> Index> for Context<'function> { + type Output = Expression; + + fn index(&self, index: Handle) -> &Self::Output { + &self.expressions[index] + } +} + pub fn scalar_components(ty: &TypeInner) -> Option<(ScalarKind, crate::Bytes)> { match *ty { TypeInner::Scalar { kind, width } => Some((kind, width)), diff --git a/src/front/glsl/functions.rs b/src/front/glsl/functions.rs index 78afdd1802..3a438b44dd 100644 --- a/src/front/glsl/functions.rs +++ b/src/front/glsl/functions.rs @@ -1,3 +1,5 @@ +use bit_set::BitSet; + use crate::{ proc::ensure_block_returns, Arena, BinaryOperator, Block, Constant, ConstantInner, EntryPoint, Expression, Function, FunctionArgument, FunctionResult, Handle, ImageQuery, LocalVariable, @@ -270,16 +272,15 @@ impl Program<'_> { meta: SourceMetadata, ) -> Result>, ErrorKind> { match name.as_str() { - "sampler1D" - | "sampler1DArray" - | "sampler2D" - | "sampler2DArray" - | "sampler2DMS" - | "sampler2DMSArray" - | "sampler3D" - | "samplerCube" - | "samplerCubeArray" - | "sampler1DShadow" + "sampler1D" | "sampler1DArray" | "sampler2D" | "sampler2DArray" | "sampler2DMS" + | "sampler2DMSArray" | "sampler3D" | "samplerCube" | "samplerCubeArray" => { + if args.len() != 2 { + return Err(ErrorKind::wrong_function_args(name, 2, args.len(), meta)); + } + ctx.samplers.insert(args[0].0, args[1].0); + Ok(Some(args[0].0)) + } + "sampler1DShadow" | "sampler1DArrayShadow" | "sampler2DShadow" | "sampler2DArrayShadow" @@ -288,7 +289,48 @@ impl Program<'_> { if args.len() != 2 { return Err(ErrorKind::wrong_function_args(name, 2, args.len(), meta)); } + + let ty = match ctx[args[0].0] { + crate::Expression::GlobalVariable(handle) => { + &mut self.module.global_variables.get_mut(handle).ty + } + crate::Expression::FunctionArgument(i) => { + ctx.depth_set.insert(i as usize); + &mut ctx.arguments[i as usize].ty + } + _ => { + return Err(ErrorKind::SemanticError( + args[0].1, + "Not a valid texture expression".into(), + )) + } + }; + match self.module.types[*ty].inner { + TypeInner::Image { + class, + dim, + arrayed, + } => match class { + crate::ImageClass::Sampled { multi, .. } => { + *ty = self.module.types.fetch_or_append(Type { + name: None, + inner: TypeInner::Image { + dim, + arrayed, + class: crate::ImageClass::Depth { multi }, + }, + }) + } + crate::ImageClass::Depth { .. } => {} + _ => { + return Err(ErrorKind::SemanticError(args[0].1, "Not a texture".into())) + } + }, + _ => return Err(ErrorKind::SemanticError(args[0].1, "Not a texture".into())), + }; + ctx.samplers.insert(args[0].0, args[1].0); + Ok(Some(args[0].0)) } "texture" => { @@ -845,7 +887,58 @@ impl Program<'_> { let mut exact = true; - for (decl_arg, call_arg) in decl.parameters.iter().zip(args.iter()) { + for ((i, decl_arg), call_arg) in + decl.parameters.iter().enumerate().zip(args.iter()) + { + if decl.depth_set.contains(i) { + let ty = match ctx[args[0].0] { + crate::Expression::GlobalVariable(handle) => { + &mut self.module.global_variables.get_mut(handle).ty + } + crate::Expression::FunctionArgument(i) => { + ctx.depth_set.insert(i as usize); + &mut ctx.arguments[i as usize].ty + } + _ => { + return Err(ErrorKind::SemanticError( + args[0].1, + "Not a valid texture expression".into(), + )) + } + }; + match self.module.types[*ty].inner { + TypeInner::Image { + class, + dim, + arrayed, + } => match class { + crate::ImageClass::Sampled { multi, .. } => { + *ty = self.module.types.fetch_or_append(Type { + name: None, + inner: TypeInner::Image { + dim, + arrayed, + class: crate::ImageClass::Depth { multi }, + }, + }) + } + crate::ImageClass::Depth { .. } => {} + _ => { + return Err(ErrorKind::SemanticError( + args[0].1, + "Not a texture".into(), + )) + } + }, + _ => { + return Err(ErrorKind::SemanticError( + args[0].1, + "Not a texture".into(), + )) + } + }; + } + let decl_inner = &self.module.types[*decl_arg].inner; let call_inner = self.resolve_type(ctx, call_arg.0, call_arg.1)?; @@ -1043,6 +1136,7 @@ impl Program<'_> { name: String, // Normalized function parameters, modifiers are not applied parameters: Vec>, + depth_set: BitSet, qualifiers: Vec, meta: SourceMetadata, ) -> Result, ErrorKind> { @@ -1089,6 +1183,7 @@ impl Program<'_> { decl.defined = true; decl.qualifiers = qualifiers; + decl.depth_set = depth_set; *self.module.functions.get_mut(decl.handle) = function; return Ok(decl.handle); } @@ -1101,6 +1196,7 @@ impl Program<'_> { handle, defined: true, void, + depth_set, }); handle }) @@ -1153,6 +1249,7 @@ impl Program<'_> { handle, defined: false, void, + depth_set: BitSet::new(), }); Ok(()) diff --git a/src/front/glsl/parser.rs b/src/front/glsl/parser.rs index 3f01e926c4..03f3586818 100644 --- a/src/front/glsl/parser.rs +++ b/src/front/glsl/parser.rs @@ -737,7 +737,9 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> { // parse the body self.parse_compound_statement(&mut context, &mut body)?; - let Context { arg_use, .. } = context; + let Context { + arg_use, depth_set, .. + } = context; let handle = self.program.add_function( Function { name: Some(name.clone()), @@ -750,6 +752,7 @@ impl<'source, 'program, 'options> Parser<'source, 'program, 'options> { }, name, parameters, + depth_set, qualifiers, meta, )?;