mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[glsl-in] add support for .length() (#2017)
Adds parsing support for methods on the glsl frontend, while `.length` is the only method in the base extensions, there might be more in extensions. Adds support for the `.length` method and tests for it.
This commit is contained in:
@@ -159,6 +159,15 @@ pub enum HirExprKind {
|
||||
/// The target expression
|
||||
expr: Handle<HirExpr>,
|
||||
},
|
||||
/// A method call like `what.something(a, b, c)`
|
||||
Method {
|
||||
/// expression the method call applies to (`what` in the example)
|
||||
expr: Handle<HirExpr>,
|
||||
/// the method name (`something` in the example)
|
||||
name: String,
|
||||
/// the arguments to the method (`a`, `b`, and `c` in the example)
|
||||
args: Vec<Handle<HirExpr>>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Hash, PartialEq, Eq)]
|
||||
|
||||
@@ -1366,6 +1366,67 @@ impl Context {
|
||||
value
|
||||
}
|
||||
}
|
||||
HirExprKind::Method {
|
||||
expr: object,
|
||||
ref name,
|
||||
ref args,
|
||||
} if ExprPos::Lhs != pos => {
|
||||
let args = args
|
||||
.iter()
|
||||
.map(|e| self.lower_expect_inner(stmt, parser, *e, ExprPos::Rhs, body))
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
match name.as_ref() {
|
||||
"length" => {
|
||||
if !args.is_empty() {
|
||||
parser.errors.push(Error {
|
||||
kind: ErrorKind::SemanticError(
|
||||
".length() doesn't take any arguments".into(),
|
||||
),
|
||||
meta,
|
||||
});
|
||||
}
|
||||
let lowered_array =
|
||||
self.lower_expect_inner(stmt, parser, object, pos, body)?.0;
|
||||
let array_type = parser.resolve_type(self, lowered_array, meta)?;
|
||||
|
||||
match *array_type {
|
||||
TypeInner::Array {
|
||||
size: crate::ArraySize::Constant(size),
|
||||
..
|
||||
} => {
|
||||
let mut array_length =
|
||||
self.add_expression(Expression::Constant(size), meta, body);
|
||||
self.forced_conversion(
|
||||
parser,
|
||||
&mut array_length,
|
||||
meta,
|
||||
ScalarKind::Sint,
|
||||
4,
|
||||
)?;
|
||||
array_length
|
||||
}
|
||||
// let the error be handled in type checking if it's not a dynamic array
|
||||
_ => {
|
||||
let mut array_length = self.add_expression(
|
||||
Expression::ArrayLength(lowered_array),
|
||||
meta,
|
||||
body,
|
||||
);
|
||||
self.conversion(&mut array_length, meta, ScalarKind::Sint, 4)?;
|
||||
array_length
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error {
|
||||
kind: ErrorKind::SemanticError(
|
||||
format!("unknown method '{}'", name).into(),
|
||||
),
|
||||
meta,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error {
|
||||
kind: ErrorKind::SemanticError(
|
||||
|
||||
@@ -231,6 +231,24 @@ impl<'source> ParsingContext<'source> {
|
||||
TokenValue::Dot => {
|
||||
let (field, end_meta) = self.expect_ident(parser)?;
|
||||
|
||||
if self.bump_if(parser, TokenValue::LeftParen).is_some() {
|
||||
let args =
|
||||
self.parse_function_call_args(parser, ctx, stmt, body, &mut meta)?;
|
||||
|
||||
base = stmt.hir_exprs.append(
|
||||
HirExpr {
|
||||
kind: HirExprKind::Method {
|
||||
expr: base,
|
||||
name: field,
|
||||
args,
|
||||
},
|
||||
meta,
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
meta.subsume(end_meta);
|
||||
base = stmt.hir_exprs.append(
|
||||
HirExpr {
|
||||
|
||||
@@ -132,6 +132,18 @@ void testMatrixMultiplication(mat4x3 a, mat4x4 b) {
|
||||
mat4x3 c = a * b;
|
||||
}
|
||||
|
||||
layout(std430, binding = 0) buffer a_buf {
|
||||
float a[];
|
||||
};
|
||||
|
||||
void testLength() {
|
||||
int len = a.length();
|
||||
}
|
||||
|
||||
void testConstantLength(float a[4u]) {
|
||||
int len = a.length();
|
||||
}
|
||||
|
||||
out vec4 o_color;
|
||||
void main() {
|
||||
privatePointer(global);
|
||||
|
||||
@@ -2,11 +2,17 @@ struct BST {
|
||||
data: i32,
|
||||
}
|
||||
|
||||
struct a_buf {
|
||||
a: array<f32>,
|
||||
}
|
||||
|
||||
struct FragmentOutput {
|
||||
@location(0) o_color: vec4<f32>,
|
||||
}
|
||||
|
||||
var<private> global: f32;
|
||||
@group(0) @binding(0)
|
||||
var<storage, read_write> global_1: a_buf;
|
||||
var<private> o_color: vec4<f32>;
|
||||
|
||||
fn testBinOpVecFloat(a: vec4<f32>, b: f32) {
|
||||
@@ -369,28 +375,47 @@ fn testMatrixMultiplication(a_22: mat4x3<f32>, b_18: mat4x4<f32>) {
|
||||
return;
|
||||
}
|
||||
|
||||
fn testLength() {
|
||||
var len: i32;
|
||||
|
||||
len = i32(arrayLength((&global_1.a)));
|
||||
return;
|
||||
}
|
||||
|
||||
fn testConstantLength(a_24: array<f32,4u>) {
|
||||
var a_25: array<f32,4u>;
|
||||
var len_1: i32 = 4;
|
||||
|
||||
_ = (&global_1.a);
|
||||
a_25 = a_24;
|
||||
_ = a_25;
|
||||
_ = i32(4u);
|
||||
}
|
||||
|
||||
fn main_1() {
|
||||
var local_5: f32;
|
||||
|
||||
_ = (&global_1.a);
|
||||
_ = global;
|
||||
let _e3 = global;
|
||||
local_5 = _e3;
|
||||
let _e5 = global;
|
||||
local_5 = _e5;
|
||||
privatePointer((&local_5));
|
||||
let _e5 = local_5;
|
||||
global = _e5;
|
||||
let _e6 = o_color;
|
||||
_ = _e6.xyzw;
|
||||
let _e9 = vec4<f32>(1.0);
|
||||
o_color.x = _e9.x;
|
||||
o_color.y = _e9.y;
|
||||
o_color.z = _e9.z;
|
||||
o_color.w = _e9.w;
|
||||
let _e7 = local_5;
|
||||
global = _e7;
|
||||
let _e8 = o_color;
|
||||
_ = _e8.xyzw;
|
||||
let _e11 = vec4<f32>(1.0);
|
||||
o_color.x = _e11.x;
|
||||
o_color.y = _e11.y;
|
||||
o_color.z = _e11.z;
|
||||
o_color.w = _e11.w;
|
||||
return;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn main() -> FragmentOutput {
|
||||
_ = (&global_1.a);
|
||||
main_1();
|
||||
let _e5 = o_color;
|
||||
return FragmentOutput(_e5);
|
||||
let _e7 = o_color;
|
||||
return FragmentOutput(_e7);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user