From 84c680c6ed33f65ead5fb9587062478f2eef34f8 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Fri, 21 Jan 2022 03:37:31 +0900 Subject: [PATCH] internal/shader: ban the operator div on a matrix The operator div on a matrix doesn't work on Metal. --- internal/shader/expr.go | 4 ++++ internal/shader/stmt.go | 7 ++++++- shader_test.go | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/internal/shader/expr.go b/internal/shader/expr.go index 459fb04ce..dcce38b86 100644 --- a/internal/shader/expr.go +++ b/internal/shader/expr.go @@ -182,6 +182,10 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr, markLocalVariable } t = lhst case lhst.Equal(&rhst): + if op == shaderir.Div && (rhst.Main == shaderir.Mat2 || rhst.Main == shaderir.Mat3 || rhst.Main == shaderir.Mat4) { + cs.addError(e.Pos(), fmt.Sprintf("invalid operation: operator %s not defined on %s", e.Op, rhst.String())) + return nil, nil, nil, false + } t = lhst case lhst.Main == shaderir.Float: switch rhst.Main { diff --git a/internal/shader/stmt.go b/internal/shader/stmt.go index f87a2821f..b55fb8b51 100644 --- a/internal/shader/stmt.go +++ b/internal/shader/stmt.go @@ -94,7 +94,12 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP } } - if lts[0].Main != rts[0].Main { + if lts[0].Main == rts[0].Main { + if op == shaderir.Div && (rts[0].Main == shaderir.Mat2 || rts[0].Main == shaderir.Mat3 || rts[0].Main == shaderir.Mat4) { + cs.addError(stmt.Pos(), fmt.Sprintf("invalid operation: operator / not defined on %s", rts[0].String())) + return nil, false + } + } else { switch lts[0].Main { case shaderir.Int: if !cs.forceToInt(stmt, &rhs[0]) { diff --git a/shader_test.go b/shader_test.go index c73651f79..43e18b496 100644 --- a/shader_test.go +++ b/shader_test.go @@ -1594,6 +1594,7 @@ func TestShaderOperatorMultiply(t *testing.T) { {stmt: "a := mat2(1) * vec3(2); _ = a", err: true}, {stmt: "a := mat2(1) * vec4(2); _ = a", err: true}, {stmt: "a := mat2(1) * mat2(2); _ = a", err: false}, + {stmt: "a := mat2(1) / mat2(2); _ = a", err: true}, {stmt: "a := mat2(1) * mat3(2); _ = a", err: true}, {stmt: "a := mat2(1) * mat4(2); _ = a", err: true}, } @@ -1641,6 +1642,7 @@ func TestShaderOperatorMultiplyAssign(t *testing.T) { {stmt: "a := vec2(1); a *= vec4(2)", err: true}, {stmt: "a := vec2(1); a *= mat2(2)", err: false}, {stmt: "a := vec2(1); a += mat2(2)", err: true}, + {stmt: "a := vec2(1); a /= mat2(2)", err: true}, {stmt: "a := vec2(1); a *= mat3(2)", err: true}, {stmt: "a := vec2(1); a *= mat4(2)", err: true}, {stmt: "a := mat2(1); a *= 2", err: false}, @@ -1656,6 +1658,7 @@ func TestShaderOperatorMultiplyAssign(t *testing.T) { {stmt: "a := mat2(1); a *= vec4(2)", err: true}, {stmt: "a := mat2(1); a *= mat2(2)", err: false}, {stmt: "a := mat2(1); a += mat2(2)", err: false}, + {stmt: "a := mat2(1); a /= mat2(2)", err: true}, {stmt: "a := mat2(1); a *= mat3(2)", err: true}, {stmt: "a := mat2(1); a *= mat4(2)", err: true}, }