Refactor image sampling arguments, add textureLoad support to WGSL

This commit is contained in:
Dzmitry Malyshau
2020-09-18 09:57:12 -04:00
parent 0aa91927b2
commit d25ab1b1e8
5 changed files with 64 additions and 46 deletions

View File

@@ -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!(),

View File

@@ -515,16 +515,27 @@ impl<W: Write> Writer<W> {
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<W: Write> Writer<W> {
}
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<W: Write> Writer<W> {
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 {

View File

@@ -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,
}
}

View File

@@ -542,6 +542,7 @@ pub enum FunctionOrigin {
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
pub enum SampleLevel {
Auto,
Zero,
Exact(Handle<Expression>),
Bias(Handle<Expression>),
}
@@ -588,8 +589,10 @@ pub enum Expression {
ImageLoad {
image: Handle<Expression>,
coordinate: Handle<Expression>,
/// This is either LOD index, or sample index, based on the image class.
index: Handle<Expression>,
/// For storage images, this is None.
/// For sampled images, this is the Some(Level).
/// For multisampled images, this is Some(Sample).
index: Option<Handle<Expression>>,
},
/// Apply an unary operator.
Unary {

View File

@@ -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);