From 48320db507bd9362aa9009dabfb3bbe01f4cfa26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Capucho?= Date: Wed, 2 Mar 2022 21:43:41 +0000 Subject: [PATCH] glsl-in: Fix matrix by matrix division --- src/front/glsl/context.rs | 59 ++++++++++++++++++++++++++-- tests/in/glsl/expressions.frag | 1 + tests/out/wgsl/expressions-frag.wgsl | 29 ++++++++------ 3 files changed, 73 insertions(+), 16 deletions(-) diff --git a/src/front/glsl/context.rs b/src/front/glsl/context.rs index ce00a3b181..ed6b2bc5d6 100644 --- a/src/front/glsl/context.rs +++ b/src/front/glsl/context.rs @@ -583,16 +583,19 @@ impl Context { &TypeInner::Matrix { columns: left_columns, rows: left_rows, - .. + width: left_width, }, &TypeInner::Matrix { columns: right_columns, rows: right_rows, - .. + width: right_width, }, ) => { // Check that the two arguments have the same dimensions - if left_columns != right_columns || left_rows != right_rows { + if left_columns != right_columns + || left_rows != right_rows + || left_width != right_width + { parser.errors.push(Error { kind: ErrorKind::SemanticError( format!( @@ -606,6 +609,56 @@ impl Context { } match op { + BinaryOperator::Divide => { + // Naga IR doesn't support matrix division so we need to + // divide the columns individually and reassemble the matrix + let mut components = Vec::with_capacity(left_columns as usize); + + for index in 0..left_columns as u32 { + // Get the column vectors + let left_vector = self.add_expression( + Expression::AccessIndex { base: left, index }, + meta, + body, + ); + let right_vector = self.add_expression( + Expression::AccessIndex { base: right, index }, + meta, + body, + ); + + // Divide the vectors + let column = self.expressions.append( + Expression::Binary { + op, + left: left_vector, + right: right_vector, + }, + meta, + ); + + components.push(column) + } + + // Rebuild the matrix from the divided vectors + self.expressions.append( + Expression::Compose { + ty: parser.module.types.insert( + Type { + name: None, + inner: TypeInner::Matrix { + columns: left_columns, + rows: left_rows, + width: left_width, + }, + }, + Span::default(), + ), + components, + }, + meta, + ) + } BinaryOperator::Equal | BinaryOperator::NotEqual => { // Naga IR doesn't support matrix comparisons so we need to // compare the columns individually and then fold them together diff --git a/tests/in/glsl/expressions.frag b/tests/in/glsl/expressions.frag index 37e9fe78c2..29fb290099 100644 --- a/tests/in/glsl/expressions.frag +++ b/tests/in/glsl/expressions.frag @@ -65,6 +65,7 @@ void testBinOpUintUVec(uint a, uvec4 b) { void testBinOpMatMat(mat3 a, mat3 b) { mat3 v; bool c; + v = a / b; v = a * b; v = a + b; v = a - b; diff --git a/tests/out/wgsl/expressions-frag.wgsl b/tests/out/wgsl/expressions-frag.wgsl index e9c5fdb166..e7a77ff74f 100644 --- a/tests/out/wgsl/expressions-frag.wgsl +++ b/tests/out/wgsl/expressions-frag.wgsl @@ -189,19 +189,22 @@ fn testBinOpMatMat(a_12: mat3x3, b_12: mat3x3) { b_13 = b_12; let _e6 = a_13; let _e7 = b_13; - v_6 = (_e6 * _e7); - let _e9 = a_13; - let _e10 = b_13; - v_6 = (_e9 + _e10); - let _e12 = a_13; - let _e13 = b_13; - v_6 = (_e12 - _e13); - let _e15 = a_13; - let _e16 = b_13; - c = (all((_e15[2] == _e16[2])) && (all((_e15[1] == _e16[1])) && all((_e15[0] == _e16[0])))); - let _e31 = a_13; - let _e32 = b_13; - c = (any((_e31[2] != _e32[2])) || (any((_e31[1] != _e32[1])) || any((_e31[0] != _e32[0])))); + v_6 = mat3x3((_e6[0] / _e7[0]), (_e6[1] / _e7[1]), (_e6[2] / _e7[2])); + let _e18 = a_13; + let _e19 = b_13; + v_6 = (_e18 * _e19); + let _e21 = a_13; + let _e22 = b_13; + v_6 = (_e21 + _e22); + let _e24 = a_13; + let _e25 = b_13; + v_6 = (_e24 - _e25); + let _e27 = a_13; + let _e28 = b_13; + c = (all((_e27[2] == _e28[2])) && (all((_e27[1] == _e28[1])) && all((_e27[0] == _e28[0])))); + let _e43 = a_13; + let _e44 = b_13; + c = (any((_e43[2] != _e44[2])) || (any((_e43[1] != _e44[1])) || any((_e43[0] != _e44[0])))); return; }