mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-09-21 22:02:23 +02:00
internal/shader: bug fix: forbid mat + float
mat + float doesn't work on Metal.
This commit is contained in:
parent
99f003a17a
commit
2e5b4954f3
@ -150,6 +150,13 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr, markLocalVariable
|
|||||||
// TODO: Check types of the operands.
|
// TODO: Check types of the operands.
|
||||||
t = shaderir.Type{Main: shaderir.Bool}
|
t = shaderir.Type{Main: shaderir.Bool}
|
||||||
case lhs[0].Type == shaderir.NumberExpr && rhs[0].Type != shaderir.NumberExpr:
|
case lhs[0].Type == shaderir.NumberExpr && rhs[0].Type != shaderir.NumberExpr:
|
||||||
|
switch rhst.Main {
|
||||||
|
case shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
||||||
|
if op != shaderir.Mul {
|
||||||
|
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), e.Op, rhst.String()))
|
||||||
|
return nil, nil, nil, false
|
||||||
|
}
|
||||||
|
}
|
||||||
if rhst.Main == shaderir.Int {
|
if rhst.Main == shaderir.Int {
|
||||||
if !canTruncateToInteger(lhs[0].Const) {
|
if !canTruncateToInteger(lhs[0].Const) {
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("constant %s truncated to integer", lhs[0].Const.String()))
|
cs.addError(e.Pos(), fmt.Sprintf("constant %s truncated to integer", lhs[0].Const.String()))
|
||||||
@ -159,6 +166,13 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr, markLocalVariable
|
|||||||
}
|
}
|
||||||
t = rhst
|
t = rhst
|
||||||
case lhs[0].Type != shaderir.NumberExpr && rhs[0].Type == shaderir.NumberExpr:
|
case lhs[0].Type != shaderir.NumberExpr && rhs[0].Type == shaderir.NumberExpr:
|
||||||
|
switch lhst.Main {
|
||||||
|
case shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
||||||
|
if op != shaderir.Mul && op != shaderir.Div {
|
||||||
|
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), e.Op, rhst.String()))
|
||||||
|
return nil, nil, nil, false
|
||||||
|
}
|
||||||
|
}
|
||||||
if lhst.Main == shaderir.Int {
|
if lhst.Main == shaderir.Int {
|
||||||
if !canTruncateToInteger(rhs[0].Const) {
|
if !canTruncateToInteger(rhs[0].Const) {
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("constant %s truncated to integer", rhs[0].Const.String()))
|
cs.addError(e.Pos(), fmt.Sprintf("constant %s truncated to integer", rhs[0].Const.String()))
|
||||||
@ -171,15 +185,27 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr, markLocalVariable
|
|||||||
t = lhst
|
t = lhst
|
||||||
case lhst.Main == shaderir.Float:
|
case lhst.Main == shaderir.Float:
|
||||||
switch rhst.Main {
|
switch rhst.Main {
|
||||||
case shaderir.Float, shaderir.Vec2, shaderir.Vec3, shaderir.Vec4, shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
case shaderir.Float, shaderir.Vec2, shaderir.Vec3, shaderir.Vec4:
|
||||||
t = rhst
|
t = rhst
|
||||||
|
case shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
||||||
|
if op != shaderir.Mul {
|
||||||
|
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), e.Op, rhst.String()))
|
||||||
|
return nil, nil, nil, false
|
||||||
|
}
|
||||||
|
t = lhst
|
||||||
default:
|
default:
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), e.Op, rhst.String()))
|
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), e.Op, rhst.String()))
|
||||||
return nil, nil, nil, false
|
return nil, nil, nil, false
|
||||||
}
|
}
|
||||||
case rhst.Main == shaderir.Float:
|
case rhst.Main == shaderir.Float:
|
||||||
switch lhst.Main {
|
switch lhst.Main {
|
||||||
case shaderir.Float, shaderir.Vec2, shaderir.Vec3, shaderir.Vec4, shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
case shaderir.Float, shaderir.Vec2, shaderir.Vec3, shaderir.Vec4:
|
||||||
|
t = lhst
|
||||||
|
case shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
||||||
|
if op != shaderir.Mul && op != shaderir.Div {
|
||||||
|
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), e.Op, rhst.String()))
|
||||||
|
return nil, nil, nil, false
|
||||||
|
}
|
||||||
t = lhst
|
t = lhst
|
||||||
default:
|
default:
|
||||||
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), e.Op, rhst.String()))
|
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), e.Op, rhst.String()))
|
||||||
|
@ -109,7 +109,12 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
|
|||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
case shaderir.Vec2, shaderir.Vec3, shaderir.Vec4, shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
case shaderir.Vec2, shaderir.Vec3, shaderir.Vec4, shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
||||||
if rts[0].Main == shaderir.Float {
|
if (op == shaderir.Mul || op == shaderir.Div) && rts[0].Main == shaderir.Float {
|
||||||
|
// OK
|
||||||
|
} else if (lts[0].Main == shaderir.Vec2 ||
|
||||||
|
lts[0].Main == shaderir.Vec3 ||
|
||||||
|
lts[0].Main == shaderir.Vec4) &&
|
||||||
|
rts[0].Main == shaderir.Float {
|
||||||
// OK
|
// OK
|
||||||
} else if op == shaderir.Mul && ((lts[0].Main == shaderir.Vec2 && rts[0].Main == shaderir.Mat2) ||
|
} else if op == shaderir.Mul && ((lts[0].Main == shaderir.Vec2 && rts[0].Main == shaderir.Mat2) ||
|
||||||
(lts[0].Main == shaderir.Vec3 && rts[0].Main == shaderir.Mat3) ||
|
(lts[0].Main == shaderir.Vec3 && rts[0].Main == shaderir.Mat3) ||
|
||||||
|
@ -1542,6 +1542,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
|||||||
|
|
||||||
// Issue #1971
|
// Issue #1971
|
||||||
func TestShaderOperatorMultiply(t *testing.T) {
|
func TestShaderOperatorMultiply(t *testing.T) {
|
||||||
|
// Note: mat + float is allowed in GLSL but not in Metal.
|
||||||
|
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
stmt string
|
stmt string
|
||||||
err bool
|
err bool
|
||||||
@ -1551,6 +1553,7 @@ func TestShaderOperatorMultiply(t *testing.T) {
|
|||||||
{stmt: "a := 1.0 * vec2(2); _ = a", err: false},
|
{stmt: "a := 1.0 * vec2(2); _ = a", err: false},
|
||||||
{stmt: "a := 1 + vec2(2); _ = a", err: false},
|
{stmt: "a := 1 + vec2(2); _ = a", err: false},
|
||||||
{stmt: "a := int(1) + vec2(2); _ = a", err: true},
|
{stmt: "a := int(1) + vec2(2); _ = a", err: true},
|
||||||
|
{stmt: "a := 1.0 / vec2(2); _ = a", err: false},
|
||||||
{stmt: "a := 1.0 + vec2(2); _ = a", err: false},
|
{stmt: "a := 1.0 + vec2(2); _ = a", err: false},
|
||||||
{stmt: "a := 1 * vec3(2); _ = a", err: false},
|
{stmt: "a := 1 * vec3(2); _ = a", err: false},
|
||||||
{stmt: "a := 1.0 * vec3(2); _ = a", err: false},
|
{stmt: "a := 1.0 * vec3(2); _ = a", err: false},
|
||||||
@ -1558,12 +1561,18 @@ func TestShaderOperatorMultiply(t *testing.T) {
|
|||||||
{stmt: "a := 1.0 * vec4(2); _ = a", err: false},
|
{stmt: "a := 1.0 * vec4(2); _ = a", err: false},
|
||||||
{stmt: "a := 1 * mat2(2); _ = a", err: false},
|
{stmt: "a := 1 * mat2(2); _ = a", err: false},
|
||||||
{stmt: "a := 1.0 * mat2(2); _ = a", err: false},
|
{stmt: "a := 1.0 * mat2(2); _ = a", err: false},
|
||||||
|
{stmt: "a := float(1.0) / mat2(2); _ = a", err: true},
|
||||||
|
{stmt: "a := 1.0 / mat2(2); _ = a", err: true},
|
||||||
|
{stmt: "a := float(1.0) + mat2(2); _ = a", err: true},
|
||||||
|
{stmt: "a := 1.0 + mat2(2); _ = a", err: true},
|
||||||
{stmt: "a := 1 * mat3(2); _ = a", err: false},
|
{stmt: "a := 1 * mat3(2); _ = a", err: false},
|
||||||
{stmt: "a := 1.0 * mat3(2); _ = a", err: false},
|
{stmt: "a := 1.0 * mat3(2); _ = a", err: false},
|
||||||
{stmt: "a := 1 * mat4(2); _ = a", err: false},
|
{stmt: "a := 1 * mat4(2); _ = a", err: false},
|
||||||
{stmt: "a := 1.0 * mat4(2); _ = a", err: false},
|
{stmt: "a := 1.0 * mat4(2); _ = a", err: false},
|
||||||
{stmt: "a := vec2(1) * 2; _ = a", err: false},
|
{stmt: "a := vec2(1) * 2; _ = a", err: false},
|
||||||
{stmt: "a := vec2(1) * 2.0; _ = a", err: false},
|
{stmt: "a := vec2(1) * 2.0; _ = a", err: false},
|
||||||
|
{stmt: "a := vec2(1) / 2.0; _ = a", err: false},
|
||||||
|
{stmt: "a := vec2(1) + 2.0; _ = a", err: false},
|
||||||
{stmt: "a := vec2(1) * int(2); _ = a", err: true},
|
{stmt: "a := vec2(1) * int(2); _ = a", err: true},
|
||||||
{stmt: "a := vec2(1) * vec2(2); _ = a", err: false},
|
{stmt: "a := vec2(1) * vec2(2); _ = a", err: false},
|
||||||
{stmt: "a := vec2(1) + vec2(2); _ = a", err: false},
|
{stmt: "a := vec2(1) + vec2(2); _ = a", err: false},
|
||||||
@ -1575,8 +1584,11 @@ func TestShaderOperatorMultiply(t *testing.T) {
|
|||||||
{stmt: "a := vec2(1) * mat4(2); _ = a", err: true},
|
{stmt: "a := vec2(1) * mat4(2); _ = a", err: true},
|
||||||
{stmt: "a := mat2(1) * 2; _ = a", err: false},
|
{stmt: "a := mat2(1) * 2; _ = a", err: false},
|
||||||
{stmt: "a := mat2(1) * 2.0; _ = a", err: false},
|
{stmt: "a := mat2(1) * 2.0; _ = a", err: false},
|
||||||
|
{stmt: "a := mat2(1) / 2.0; _ = a", err: false},
|
||||||
|
{stmt: "a := mat2(1) / float(2); _ = a", err: false},
|
||||||
{stmt: "a := mat2(1) * int(2); _ = a", err: true},
|
{stmt: "a := mat2(1) * int(2); _ = a", err: true},
|
||||||
{stmt: "a := mat2(1) + 2.0; _ = a", err: false},
|
{stmt: "a := mat2(1) + 2.0; _ = a", err: true},
|
||||||
|
{stmt: "a := mat2(1) + float(2); _ = a", err: true},
|
||||||
{stmt: "a := mat2(1) * vec2(2); _ = a", err: false},
|
{stmt: "a := mat2(1) * vec2(2); _ = a", err: false},
|
||||||
{stmt: "a := mat2(1) + vec2(2); _ = a", err: true},
|
{stmt: "a := mat2(1) + vec2(2); _ = a", err: true},
|
||||||
{stmt: "a := mat2(1) * vec3(2); _ = a", err: true},
|
{stmt: "a := mat2(1) * vec3(2); _ = a", err: true},
|
||||||
@ -1618,7 +1630,11 @@ func TestShaderOperatorMultiplyAssign(t *testing.T) {
|
|||||||
{stmt: "a := 1.0; a *= mat4(2)", err: true},
|
{stmt: "a := 1.0; a *= mat4(2)", err: true},
|
||||||
{stmt: "a := vec2(1); a *= 2", err: false},
|
{stmt: "a := vec2(1); a *= 2", err: false},
|
||||||
{stmt: "a := vec2(1); a *= 2.0", err: false},
|
{stmt: "a := vec2(1); a *= 2.0", err: false},
|
||||||
|
{stmt: "a := vec2(1); a /= 2.0", err: false},
|
||||||
|
{stmt: "a := vec2(1); a += 2.0", err: false},
|
||||||
{stmt: "a := vec2(1); a *= int(2)", err: true},
|
{stmt: "a := vec2(1); a *= int(2)", err: true},
|
||||||
|
{stmt: "a := vec2(1); a *= float(2)", err: false},
|
||||||
|
{stmt: "a := vec2(1); a /= float(2)", err: false},
|
||||||
{stmt: "a := vec2(1); a *= vec2(2)", err: false},
|
{stmt: "a := vec2(1); a *= vec2(2)", err: false},
|
||||||
{stmt: "a := vec2(1); a += vec2(2)", err: false},
|
{stmt: "a := vec2(1); a += vec2(2)", err: false},
|
||||||
{stmt: "a := vec2(1); a *= vec3(2)", err: true},
|
{stmt: "a := vec2(1); a *= vec3(2)", err: true},
|
||||||
@ -1629,7 +1645,11 @@ func TestShaderOperatorMultiplyAssign(t *testing.T) {
|
|||||||
{stmt: "a := vec2(1); a *= mat4(2)", err: true},
|
{stmt: "a := vec2(1); a *= mat4(2)", err: true},
|
||||||
{stmt: "a := mat2(1); a *= 2", err: false},
|
{stmt: "a := mat2(1); a *= 2", err: false},
|
||||||
{stmt: "a := mat2(1); a *= 2.0", err: false},
|
{stmt: "a := mat2(1); a *= 2.0", err: false},
|
||||||
|
{stmt: "a := mat2(1); a /= 2.0", err: false},
|
||||||
|
{stmt: "a := mat2(1); a += 2.0", err: true},
|
||||||
{stmt: "a := mat2(1); a *= int(2)", err: true},
|
{stmt: "a := mat2(1); a *= int(2)", err: true},
|
||||||
|
{stmt: "a := mat2(1); a *= float(2)", err: false},
|
||||||
|
{stmt: "a := mat2(1); a /= float(2)", err: false},
|
||||||
{stmt: "a := mat2(1); a *= vec2(2)", err: true},
|
{stmt: "a := mat2(1); a *= vec2(2)", err: true},
|
||||||
{stmt: "a := mat2(1); a += vec2(2)", err: true},
|
{stmt: "a := mat2(1); a += vec2(2)", err: true},
|
||||||
{stmt: "a := mat2(1); a *= vec3(2)", err: true},
|
{stmt: "a := mat2(1); a *= vec3(2)", err: true},
|
||||||
|
Loading…
Reference in New Issue
Block a user