Basic image query support in SPV and WGSL frontends

This commit is contained in:
Dzmitry Malyshau
2021-02-05 10:27:01 -05:00
committed by Dzmitry Malyshau
parent 50f0ad6249
commit b1fa7471d2
4 changed files with 149 additions and 1 deletions

View File

@@ -351,6 +351,8 @@ impl<W: Write> Writer<W> {
// so a conversion is needed.
crate::Expression::ImageQuery { image, query } => match query {
crate::ImageQuery::Size { level } => {
//Note: MSL only has separate width/height/depth queries,
// so compose the result of them.
let dim = match *self.typifier.get(image, &context.module.types) {
crate::TypeInner::Image { dim, .. } => dim,
ref other => unreachable!("Unexpected type {:?}", other),

View File

@@ -1113,6 +1113,90 @@ impl<I: Iterator<Item = u32>> Parser<I> {
},
);
}
Op::ImageQuerySize => {
inst.expect(4)?;
let result_type_id = self.next()?;
let result_id = self.next()?;
let image_id = self.next()?;
//TODO: handle arrays and cubes
let image_lexp = self.lookup_expression.lookup(image_id)?.clone();
let expr = crate::Expression::ImageQuery {
image: image_lexp.handle,
query: crate::ImageQuery::Size { level: None },
};
self.lookup_expression.insert(
result_id,
LookupExpression {
handle: expressions.append(expr),
type_id: result_type_id,
},
);
}
Op::ImageQuerySizeLod => {
inst.expect(5)?;
let result_type_id = self.next()?;
let result_id = self.next()?;
let image_id = self.next()?;
let level_id = self.next()?;
//TODO: handle arrays and cubes
let image_lexp = self.lookup_expression.lookup(image_id)?.clone();
let level_lexp = self.lookup_expression.lookup(level_id)?.clone();
let expr = crate::Expression::ImageQuery {
image: image_lexp.handle,
query: crate::ImageQuery::Size {
level: Some(level_lexp.handle),
},
};
self.lookup_expression.insert(
result_id,
LookupExpression {
handle: expressions.append(expr),
type_id: result_type_id,
},
);
}
Op::ImageQueryLevels => {
let result_type_id = self.next()?;
let result_id = self.next()?;
let image_id = self.next()?;
let image_lexp = self.lookup_expression.lookup(image_id)?.clone();
let expr = crate::Expression::ImageQuery {
image: image_lexp.handle,
query: crate::ImageQuery::NumLevels,
};
self.lookup_expression.insert(
result_id,
LookupExpression {
handle: expressions.append(expr),
type_id: result_type_id,
},
);
}
Op::ImageQuerySamples => {
let result_type_id = self.next()?;
let result_id = self.next()?;
let image_id = self.next()?;
let image_lexp = self.lookup_expression.lookup(image_id)?.clone();
let expr = crate::Expression::ImageQuery {
image: image_lexp.handle,
query: crate::ImageQuery::NumSamples,
};
self.lookup_expression.insert(
result_id,
LookupExpression {
handle: expressions.append(expr),
type_id: result_type_id,
},
);
}
Op::Select => {
inst.expect(6)?;
let result_type_id = self.next()?;

View File

@@ -604,6 +604,52 @@ impl Parser {
index,
})
}
"textureDimensions" => {
lexer.expect(Token::Paren('('))?;
let image_name = lexer.next_ident()?;
let image = ctx.lookup_ident.lookup(image_name)?;
let level = if lexer.skip(Token::Separator(',')) {
let expr = self.parse_general_expression(lexer, ctx.reborrow())?;
Some(expr)
} else {
None
};
lexer.expect(Token::Paren(')'))?;
Some(crate::Expression::ImageQuery {
image,
query: crate::ImageQuery::Size { level },
})
}
"textureNumLevels" => {
lexer.expect(Token::Paren('('))?;
let image_name = lexer.next_ident()?;
let image = ctx.lookup_ident.lookup(image_name)?;
lexer.expect(Token::Paren(')'))?;
Some(crate::Expression::ImageQuery {
image,
query: crate::ImageQuery::NumLevels,
})
}
"textureNumLayers" => {
lexer.expect(Token::Paren('('))?;
let image_name = lexer.next_ident()?;
let image = ctx.lookup_ident.lookup(image_name)?;
lexer.expect(Token::Paren(')'))?;
Some(crate::Expression::ImageQuery {
image,
query: crate::ImageQuery::NumLayers,
})
}
"textureNumSamples" => {
lexer.expect(Token::Paren('('))?;
let image_name = lexer.next_ident()?;
let image = ctx.lookup_ident.lookup(image_name)?;
lexer.expect(Token::Paren(')'))?;
Some(crate::Expression::ImageQuery {
image,
query: crate::ImageQuery::NumSamples,
})
}
_ => {
match ctx.functions.iter().find(|(_, fun)| match fun.name {
Some(ref string) => string == name,

View File

@@ -155,7 +155,7 @@ fn parse_texture_load() {
"
var t: texture_multisampled_2d_array<i32>;
fn foo() {
const r: vec4<i32> = textureLoad(t, vec2<i32>(10, 20), 2, 3);
const r: vec4<i32> = textureLoad(t, vec2<i32>(10, 20), 2, 3);
}
",
)
@@ -171,6 +171,22 @@ fn parse_texture_load() {
.unwrap();
}
#[test]
fn parse_texture_query() {
parse_str(
"
var t: texture_multisampled_2d_array<f32>;
fn foo() {
var dim: vec2<i32> = textureDimensions(t);
dim = textureDimensions(t, 0);
const layers: i32 = textureNumLayers(t);
const samples: i32 = textureNumSamples(t);
}
",
)
.unwrap();
}
#[test]
fn parse_postfix() {
parse_str("fn foo() { const x: f32 = vec4<f32>(1.0, 2.0, 3.0, 4.0).xyz.rgbr.aaaa.wz.g; }")