From d25ab1b1e8cd649579aca2efb00a8a6141974758 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Fri, 18 Sep 2020 09:57:12 -0400 Subject: [PATCH] Refactor image sampling arguments, add textureLoad support to WGSL --- src/back/glsl.rs | 20 +++++++++--------- src/back/msl.rs | 47 ++++++++++++++++--------------------------- src/front/wgsl/mod.rs | 30 ++++++++++++++++++++++++++- src/lib.rs | 7 +++++-- src/proc/interface.rs | 6 ++++-- 5 files changed, 64 insertions(+), 46 deletions(-) diff --git a/src/back/glsl.rs b/src/back/glsl.rs index 135675129a..4443c3dbd1 100644 --- a/src/back/glsl.rs +++ b/src/back/glsl.rs @@ -779,6 +779,9 @@ fn write_expression<'a, 'b>( //TODO: handle MS Cow::Owned(match level { crate::SampleLevel::Auto => format!("texture({},{})", image_expr, coordinate_expr), + crate::SampleLevel::Zero => { + format!("textureLod({},{},0)", image_expr, coordinate_expr) + } crate::SampleLevel::Exact(expr) => { let level_expr = write_expression(&builder.expressions[expr], module, builder)?; format!( @@ -822,17 +825,12 @@ fn write_expression<'a, 'b>( image_expr, ); - if !multi { - format!("texelFetch({},{})", sampler_constructor, coordinate_expr) - } else { - let index_expr = - write_expression(&builder.expressions[index], module, builder)?; - - format!( - "texelFetch({},{},{})", - sampler_constructor, coordinate_expr, index_expr - ) - } + let index_expr = + write_expression(&builder.expressions[index.unwrap()], module, builder)?; + format!( + "texelFetch({},{},{})", + sampler_constructor, coordinate_expr, index_expr + ) } ImageClass::Storage(_) => format!("imageLoad({},{})", image_expr, coordinate_expr), ImageClass::Depth => todo!(), diff --git a/src/back/msl.rs b/src/back/msl.rs index 2910089ea0..618d258c6b 100644 --- a/src/back/msl.rs +++ b/src/back/msl.rs @@ -515,16 +515,27 @@ impl Writer { sampler, coordinate, level, - depth_ref: None, + depth_ref, } => { + let op = match depth_ref { + Some(_) => "sample_compare", + None => "sample", + }; //TODO: handle arrayed images self.put_expression(image, function, module)?; - write!(self.out, ".sample(")?; + write!(self.out, ".{}(", op)?; self.put_expression(sampler, function, module)?; write!(self.out, ", ")?; self.put_expression(coordinate, function, module)?; + if let Some(dref) = depth_ref { + write!(self.out, ", ")?; + self.put_expression(dref, function, module)?; + } match level { crate::SampleLevel::Auto => {} + crate::SampleLevel::Zero => { + write!(self.out, ", level(0)")?; + } crate::SampleLevel::Exact(h) => { write!(self.out, ", level(")?; self.put_expression(h, function, module)?; @@ -538,32 +549,6 @@ impl Writer { } write!(self.out, ")")?; } - crate::Expression::ImageSample { - image, - sampler, - coordinate, - level, - depth_ref: Some(dref), - } => { - //TODO: handle arrayed images - self.put_expression(image, function, module)?; - write!(self.out, ".sample_compare(")?; - self.put_expression(sampler, function, module)?; - write!(self.out, ", ")?; - self.put_expression(coordinate, function, module)?; - write!(self.out, ", ")?; - self.put_expression(dref, function, module)?; - match level { - crate::SampleLevel::Auto => {} - crate::SampleLevel::Exact(h) => { - write!(self.out, ", level(")?; - self.put_expression(h, function, module)?; - write!(self.out, ")")?; - } - crate::SampleLevel::Bias(_) => return Err(Error::UnexpectedSampleLevel(level)), - } - write!(self.out, ")")?; - } crate::Expression::ImageLoad { image, coordinate, @@ -573,8 +558,10 @@ impl Writer { self.put_expression(image, function, module)?; write!(self.out, ".read(")?; self.put_expression(coordinate, function, module)?; - write!(self.out, ", ")?; - self.put_expression(index, function, module)?; + if let Some(index) = index { + write!(self.out, ", ")?; + self.put_expression(index, function, module)?; + } write!(self.out, ")")?; } crate::Expression::Call { diff --git a/src/front/wgsl/mod.rs b/src/front/wgsl/mod.rs index 102ea0ca65..61f2330e37 100644 --- a/src/front/wgsl/mod.rs +++ b/src/front/wgsl/mod.rs @@ -760,10 +760,38 @@ impl Parser { image: ctx.lookup_ident.lookup(image_name)?, sampler: ctx.lookup_ident.lookup(sampler_name)?, coordinate, - level: crate::SampleLevel::Auto, //TODO: create a constant expression for 0? + level: crate::SampleLevel::Zero, depth_ref: Some(reference), }) } + "textureLoad" => { + lexer.expect(Token::Paren('('))?; + let image_name = lexer.next_ident()?; + let image = ctx.lookup_ident.lookup(image_name)?; + lexer.expect(Token::Separator(','))?; + let coordinate = + self.parse_primary_expression(lexer, ctx.reborrow())?; + let is_storage = match *ctx.resolve_type(image)? { + crate::TypeInner::Image { + class: crate::ImageClass::Storage(_), + .. + } => true, + _ => false, + }; + let index = if is_storage { + None + } else { + lexer.expect(Token::Separator(','))?; + let index_name = lexer.next_ident()?; + Some(ctx.lookup_ident.lookup(index_name)?) + }; + lexer.expect(Token::Paren(')'))?; + Some(crate::Expression::ImageLoad { + image, + coordinate, + index, + }) + } _ => None, } } diff --git a/src/lib.rs b/src/lib.rs index e1e884edb8..c54d057e88 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -542,6 +542,7 @@ pub enum FunctionOrigin { #[cfg_attr(feature = "deserialize", derive(Deserialize))] pub enum SampleLevel { Auto, + Zero, Exact(Handle), Bias(Handle), } @@ -588,8 +589,10 @@ pub enum Expression { ImageLoad { image: Handle, coordinate: Handle, - /// This is either LOD index, or sample index, based on the image class. - index: Handle, + /// For storage images, this is None. + /// For sampled images, this is the Some(Level). + /// For multisampled images, this is Some(Sample). + index: Option>, }, /// Apply an unary operator. Unary { diff --git a/src/proc/interface.rs b/src/proc/interface.rs index 102da6e6a3..ce117c56fe 100644 --- a/src/proc/interface.rs +++ b/src/proc/interface.rs @@ -51,7 +51,7 @@ where self.traverse_expr(sampler); self.traverse_expr(coordinate); match level { - crate::SampleLevel::Auto => (), + crate::SampleLevel::Auto | crate::SampleLevel::Zero => (), crate::SampleLevel::Exact(h) | crate::SampleLevel::Bias(h) => { self.traverse_expr(h) } @@ -67,7 +67,9 @@ where } => { self.traverse_expr(image); self.traverse_expr(coordinate); - self.traverse_expr(index); + if let Some(index) = index { + self.traverse_expr(index); + } } E::Unary { expr, .. } => { self.traverse_expr(expr);