mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
internal/shader: reland: bug fix: stricter type checks for the built-in cast-like functions
Closes #2712
This commit is contained in:
parent
be2123f7fd
commit
88be4c5b7c
@ -197,15 +197,19 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
t = lhst
|
||||
case op2 == shaderir.MatrixMul && lhst.Main == shaderir.Float && rhst.IsMatrix():
|
||||
t = rhst
|
||||
case op2 == shaderir.MatrixMul && lhst.IsVector() && rhst.IsMatrix():
|
||||
case op2 == shaderir.MatrixMul && lhst.IsFloatVector() && rhst.IsMatrix():
|
||||
t = lhst
|
||||
case op2 == shaderir.MatrixMul && lhst.IsMatrix() && rhst.Main == shaderir.Float:
|
||||
t = lhst
|
||||
case op2 == shaderir.MatrixMul && lhst.IsMatrix() && rhst.IsVector():
|
||||
case op2 == shaderir.MatrixMul && lhst.IsMatrix() && rhst.IsFloatVector():
|
||||
t = rhst
|
||||
case (lhst.Main == shaderir.Float || lhst.Main == shaderir.Int) && rhst.IsVector():
|
||||
case lhst.Main == shaderir.Float && rhst.IsFloatVector():
|
||||
t = rhst
|
||||
case lhst.IsVector() && (rhst.Main == shaderir.Float || rhst.Main == shaderir.Int):
|
||||
case lhst.Main == shaderir.Int && rhst.IsIntVector():
|
||||
t = rhst
|
||||
case lhst.IsFloatVector() && rhst.Main == shaderir.Float:
|
||||
t = lhst
|
||||
case lhst.IsIntVector() && rhst.Main == shaderir.Int:
|
||||
t = lhst
|
||||
default:
|
||||
panic(fmt.Sprintf("shaderir: invalid expression: %s %s %s", lhst.String(), e.Op, rhst.String()))
|
||||
@ -291,31 +295,37 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
}
|
||||
case shaderir.IntF:
|
||||
if len(args) == 1 && args[0].Const != nil {
|
||||
if !canTruncateToInteger(args[0].Const) {
|
||||
// For constants, a cast-like function doesn't work as a cast.
|
||||
// For example, `int(1.1)` is invalid.
|
||||
v := gconstant.ToInt(args[0].Const)
|
||||
if v.Kind() == gconstant.Unknown {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type int", args[0].Const.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
return []shaderir.Expr{
|
||||
{
|
||||
Type: shaderir.NumberExpr,
|
||||
Const: gconstant.ToInt(args[0].Const),
|
||||
Const: v,
|
||||
ConstType: shaderir.ConstTypeInt,
|
||||
},
|
||||
}, []shaderir.Type{{Main: shaderir.Int}}, stmts, true
|
||||
}
|
||||
case shaderir.FloatF:
|
||||
if len(args) == 1 && args[0].Const != nil {
|
||||
if gconstant.ToFloat(args[0].Const).Kind() != gconstant.Unknown {
|
||||
v := gconstant.ToFloat(args[0].Const)
|
||||
if v.Kind() == gconstant.Unknown {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type float", args[0].Const.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
return []shaderir.Expr{
|
||||
{
|
||||
Type: shaderir.NumberExpr,
|
||||
Const: gconstant.ToFloat(args[0].Const),
|
||||
Const: v,
|
||||
ConstType: shaderir.ConstTypeFloat,
|
||||
},
|
||||
}, []shaderir.Type{{Main: shaderir.Float}}, stmts, true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process the expression as a regular function call.
|
||||
var t shaderir.Type
|
||||
@ -357,19 +367,19 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
}
|
||||
t = shaderir.Type{Main: shaderir.Vec4}
|
||||
case shaderir.IVec2F:
|
||||
if err := checkArgsForVec2BuiltinFunc(args, argts); err != nil {
|
||||
if err := checkArgsForIVec2BuiltinFunc(args, argts); err != nil {
|
||||
cs.addError(e.Pos(), err.Error())
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
t = shaderir.Type{Main: shaderir.IVec2}
|
||||
case shaderir.IVec3F:
|
||||
if err := checkArgsForVec3BuiltinFunc(args, argts); err != nil {
|
||||
if err := checkArgsForIVec3BuiltinFunc(args, argts); err != nil {
|
||||
cs.addError(e.Pos(), err.Error())
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
t = shaderir.Type{Main: shaderir.IVec3}
|
||||
case shaderir.IVec4F:
|
||||
if err := checkArgsForVec4BuiltinFunc(args, argts); err != nil {
|
||||
if err := checkArgsForIVec4BuiltinFunc(args, argts); err != nil {
|
||||
cs.addError(e.Pos(), err.Error())
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
|
||||
(lts[0].Main == shaderir.Vec3 && rts[0].Main == shaderir.Mat3) ||
|
||||
(lts[0].Main == shaderir.Vec4 && rts[0].Main == shaderir.Mat4)) {
|
||||
// OK
|
||||
} else if (op == shaderir.MatrixMul || op == shaderir.ComponentWiseMul || lts[0].IsVector()) &&
|
||||
} else if (op == shaderir.MatrixMul || op == shaderir.ComponentWiseMul || lts[0].IsFloatVector()) &&
|
||||
(rts[0].Main == shaderir.Float ||
|
||||
(rhs[0].Const != nil &&
|
||||
rhs[0].ConstType != shaderir.ConstTypeInt &&
|
||||
|
@ -586,7 +586,8 @@ func TestSyntaxDuplicatedVarsAndConstants(t *testing.T) {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
var a = 0
|
||||
const a = 0
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}
|
||||
`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
@ -597,7 +598,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
const a = 0
|
||||
var a = 0
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}
|
||||
`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
@ -608,7 +610,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
const a = 0
|
||||
const a = 0
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}
|
||||
`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
@ -734,7 +737,8 @@ func TestSyntaxOperatorMod(t *testing.T) {
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 2.0 % 0.5
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
@ -743,7 +747,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
// If both are constants, both must be an integer!
|
||||
a := 2.0 % 1.0
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
@ -752,7 +757,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := int(2) % 0.5
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
@ -761,7 +767,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := int(2) % 1.0
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -771,7 +778,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 2.0
|
||||
b := 0.5
|
||||
return vec4(a % b)
|
||||
_ = a % b
|
||||
return vec4(0)
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
@ -781,7 +789,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 2
|
||||
b := 0.5
|
||||
return vec4(a % b)
|
||||
_ = a % b
|
||||
return vec4(0)
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
@ -791,7 +800,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 2.5
|
||||
b := 1
|
||||
return vec4(a % b)
|
||||
_ = a % b
|
||||
return vec4(0)
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
@ -801,7 +811,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 2
|
||||
b := 1
|
||||
return vec4(a % b)
|
||||
_ = a % b
|
||||
return vec4(0)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -810,7 +821,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 2
|
||||
return vec4(a % 1)
|
||||
_ = a % 1
|
||||
return vec4(0)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -820,7 +832,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
// If only one of two is a consntant, the constant can be a float.
|
||||
a := 2
|
||||
return vec4(a % 1.0)
|
||||
_ = a % 1.0
|
||||
return vec4(0)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -829,7 +842,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 1
|
||||
return vec4(2 % a)
|
||||
_ = 2 % a
|
||||
return vec4(0)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -839,7 +853,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
// If only one of two is a consntant, the constant can be a float.
|
||||
a := 1
|
||||
return vec4(2.0 % a)
|
||||
_ = 2.0 % a
|
||||
return vec4(0)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -849,7 +864,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 2
|
||||
a %= 1
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -859,7 +875,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 2
|
||||
a %= 1.0
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -869,7 +886,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 2
|
||||
a %= 0.5
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
@ -879,7 +897,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 2.0
|
||||
a %= 1
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
@ -891,7 +910,8 @@ func TestSyntaxOperatorAssign(t *testing.T) {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 1.0
|
||||
a += 2
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -901,7 +921,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 1.0
|
||||
a += 2.0
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -911,7 +932,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 1.0
|
||||
a += 2.1
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -921,7 +943,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 1
|
||||
a += 2
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -931,7 +954,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 1
|
||||
a += 2.0
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -941,7 +965,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := 1
|
||||
a += 2.1
|
||||
return vec4(a)
|
||||
_ = a
|
||||
return vec4(0)
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
@ -1617,7 +1642,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
|
||||
{stmt: "a := vec2(1); _ = a", err: false},
|
||||
{stmt: "a := vec2(1.0); _ = a", err: false},
|
||||
{stmt: "i := 1; a := vec2(i); _ = a", err: false},
|
||||
{stmt: "i := 1; a := vec2(i); _ = a", err: true},
|
||||
{stmt: "i := 1.0; a := vec2(i); _ = a", err: false},
|
||||
{stmt: "a := vec2(vec2(1)); _ = a", err: false},
|
||||
{stmt: "a := vec2(vec3(1)); _ = a", err: true},
|
||||
@ -1627,7 +1652,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
{stmt: "a := vec2(1, 1); _ = a", err: false},
|
||||
{stmt: "a := vec2(1.0, 1.0); _ = a", err: false},
|
||||
{stmt: "a := vec2(1.1, 1.1); _ = a", err: false},
|
||||
{stmt: "i := 1; a := vec2(i, i); _ = a", err: false},
|
||||
{stmt: "i := 1; a := vec2(i, i); _ = a", err: true},
|
||||
{stmt: "i := 1.0; a := vec2(i, i); _ = a", err: false},
|
||||
{stmt: "a := vec2(vec2(1), 1); _ = a", err: true},
|
||||
{stmt: "a := vec2(1, vec2(1)); _ = a", err: true},
|
||||
@ -1637,7 +1662,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
{stmt: "a := vec3(1); _ = a", err: false},
|
||||
{stmt: "a := vec3(1.0); _ = a", err: false},
|
||||
{stmt: "a := vec3(1.1); _ = a", err: false},
|
||||
{stmt: "i := 1; a := vec3(i); _ = a", err: false},
|
||||
{stmt: "i := 1; a := vec3(i); _ = a", err: true},
|
||||
{stmt: "i := 1.0; a := vec3(i); _ = a", err: false},
|
||||
{stmt: "a := vec3(vec3(1)); _ = a", err: false},
|
||||
{stmt: "a := vec3(vec2(1)); _ = a", err: true},
|
||||
@ -1649,12 +1674,12 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
{stmt: "a := vec3(1, 1, 1); _ = a", err: false},
|
||||
{stmt: "a := vec3(1.0, 1.0, 1.0); _ = a", err: false},
|
||||
{stmt: "a := vec3(1.1, 1.1, 1.1); _ = a", err: false},
|
||||
{stmt: "i := 1; a := vec3(i, i, i); _ = a", err: false},
|
||||
{stmt: "i := 1; a := vec3(i, i, i); _ = a", err: true},
|
||||
{stmt: "i := 1.0; a := vec3(i, i, i); _ = a", err: false},
|
||||
{stmt: "a := vec3(vec2(1), 1); _ = a", err: false},
|
||||
{stmt: "a := vec3(1, vec2(1)); _ = a", err: false},
|
||||
{stmt: "a := vec3(ivec2(1), 1); _ = a", err: false},
|
||||
{stmt: "a := vec3(1, ivec2(1)); _ = a", err: false},
|
||||
{stmt: "a := vec3(ivec2(1), 1); _ = a", err: true},
|
||||
{stmt: "a := vec3(1, ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := vec3(vec3(1), 1); _ = a", err: true},
|
||||
{stmt: "a := vec3(1, vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := vec3(vec3(1), vec3(1), vec3(1)); _ = a", err: true},
|
||||
@ -1662,7 +1687,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
|
||||
{stmt: "a := vec4(1); _ = a", err: false},
|
||||
{stmt: "a := vec4(1.0); _ = a", err: false},
|
||||
{stmt: "i := 1; a := vec4(i); _ = a", err: false},
|
||||
{stmt: "i := 1; a := vec4(i); _ = a", err: true},
|
||||
{stmt: "i := 1.0; a := vec4(i); _ = a", err: false},
|
||||
{stmt: "a := vec4(vec4(1)); _ = a", err: false},
|
||||
{stmt: "a := vec4(vec2(1)); _ = a", err: true},
|
||||
@ -1674,19 +1699,19 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
{stmt: "a := vec4(1, 1, 1, 1); _ = a", err: false},
|
||||
{stmt: "a := vec4(1.0, 1.0, 1.0, 1.0); _ = a", err: false},
|
||||
{stmt: "a := vec4(1.1, 1.1, 1.1, 1.1); _ = a", err: false},
|
||||
{stmt: "i := 1; a := vec4(i, i, i, i); _ = a", err: false},
|
||||
{stmt: "i := 1; a := vec4(i, i, i, i); _ = a", err: true},
|
||||
{stmt: "i := 1.0; a := vec4(i, i, i, i); _ = a", err: false},
|
||||
{stmt: "a := vec4(vec2(1), 1, 1); _ = a", err: false},
|
||||
{stmt: "a := vec4(1, vec2(1), 1); _ = a", err: false},
|
||||
{stmt: "a := vec4(ivec2(1), 1, 1); _ = a", err: false},
|
||||
{stmt: "a := vec4(1, ivec2(1), 1); _ = a", err: false},
|
||||
{stmt: "a := vec4(ivec2(1), 1, 1); _ = a", err: true},
|
||||
{stmt: "a := vec4(1, ivec2(1), 1); _ = a", err: true},
|
||||
{stmt: "a := vec4(1, 1, vec2(1)); _ = a", err: false},
|
||||
{stmt: "a := vec4(vec2(1), vec2(1)); _ = a", err: false},
|
||||
{stmt: "a := vec4(ivec2(1), ivec2(1)); _ = a", err: false},
|
||||
{stmt: "a := vec4(ivec2(1), ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := vec4(vec3(1), 1); _ = a", err: false},
|
||||
{stmt: "a := vec4(1, vec3(1)); _ = a", err: false},
|
||||
{stmt: "a := vec4(ivec3(1), 1); _ = a", err: false},
|
||||
{stmt: "a := vec4(1, ivec3(1)); _ = a", err: false},
|
||||
{stmt: "a := vec4(ivec3(1), 1); _ = a", err: true},
|
||||
{stmt: "a := vec4(1, ivec3(1)); _ = a", err: true},
|
||||
{stmt: "a := vec4(vec4(1), 1); _ = a", err: true},
|
||||
{stmt: "a := vec4(1, vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := vec4(vec4(1), vec4(1), vec4(1), vec4(1)); _ = a", err: true},
|
||||
@ -1695,7 +1720,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
{stmt: "a := ivec2(1); _ = a", err: false},
|
||||
{stmt: "a := ivec2(1.0); _ = a", err: false},
|
||||
{stmt: "i := 1; a := ivec2(i); _ = a", err: false},
|
||||
{stmt: "i := 1.0; a := ivec2(i); _ = a", err: false},
|
||||
{stmt: "i := 1.0; a := ivec2(i); _ = a", err: true},
|
||||
{stmt: "a := ivec2(vec2(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec2(vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec2(ivec2(1)); _ = a", err: false},
|
||||
@ -1704,7 +1729,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
{stmt: "a := ivec2(1, 1); _ = a", err: false},
|
||||
{stmt: "a := ivec2(1.0, 1.0); _ = a", err: false},
|
||||
{stmt: "i := 1; a := ivec2(i, i); _ = a", err: false},
|
||||
{stmt: "i := 1.0; a := ivec2(i, i); _ = a", err: false},
|
||||
{stmt: "i := 1.0; a := ivec2(i, i); _ = a", err: true},
|
||||
{stmt: "a := ivec2(vec2(1), 1); _ = a", err: true},
|
||||
{stmt: "a := ivec2(1, vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec2(ivec2(1), 1); _ = a", err: true},
|
||||
@ -1714,9 +1739,9 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
|
||||
{stmt: "a := ivec3(1); _ = a", err: false},
|
||||
{stmt: "a := ivec3(1.0); _ = a", err: false},
|
||||
{stmt: "a := ivec3(1.1); _ = a", err: false},
|
||||
{stmt: "a := ivec3(1.1); _ = a", err: true},
|
||||
{stmt: "i := 1; a := ivec3(i); _ = a", err: false},
|
||||
{stmt: "i := 1.0; a := ivec3(i); _ = a", err: false},
|
||||
{stmt: "i := 1.0; a := ivec3(i); _ = a", err: true},
|
||||
{stmt: "a := ivec3(vec3(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec3(vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec3(vec4(1)); _ = a", err: true},
|
||||
@ -1726,11 +1751,11 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
|
||||
{stmt: "a := ivec3(1, 1, 1); _ = a", err: false},
|
||||
{stmt: "a := ivec3(1.0, 1.0, 1.0); _ = a", err: false},
|
||||
{stmt: "a := ivec3(1.1, 1.1, 1.1); _ = a", err: false},
|
||||
{stmt: "a := ivec3(1.1, 1.1, 1.1); _ = a", err: true},
|
||||
{stmt: "i := 1; a := ivec3(i, i, i); _ = a", err: false},
|
||||
{stmt: "i := 1.0; a := ivec3(i, i, i); _ = a", err: false},
|
||||
{stmt: "a := ivec3(vec2(1), 1); _ = a", err: false},
|
||||
{stmt: "a := ivec3(1, vec2(1)); _ = a", err: false},
|
||||
{stmt: "i := 1.0; a := ivec3(i, i, i); _ = a", err: true},
|
||||
{stmt: "a := ivec3(vec2(1), 1); _ = a", err: true},
|
||||
{stmt: "a := ivec3(1, vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec3(ivec2(1), 1); _ = a", err: false},
|
||||
{stmt: "a := ivec3(1, ivec2(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec3(vec3(1), 1); _ = a", err: true},
|
||||
@ -1741,7 +1766,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
{stmt: "a := ivec4(1); _ = a", err: false},
|
||||
{stmt: "a := ivec4(1.0); _ = a", err: false},
|
||||
{stmt: "i := 1; a := ivec4(i); _ = a", err: false},
|
||||
{stmt: "i := 1.0; a := ivec4(i); _ = a", err: false},
|
||||
{stmt: "i := 1.0; a := ivec4(i); _ = a", err: true},
|
||||
{stmt: "a := ivec4(vec4(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec4(vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec4(vec3(1)); _ = a", err: true},
|
||||
@ -1751,19 +1776,19 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
|
||||
{stmt: "a := ivec4(1, 1, 1, 1); _ = a", err: false},
|
||||
{stmt: "a := ivec4(1.0, 1.0, 1.0, 1.0); _ = a", err: false},
|
||||
{stmt: "a := ivec4(1.1, 1.1, 1.1, 1.1); _ = a", err: false},
|
||||
{stmt: "a := ivec4(1.1, 1.1, 1.1, 1.1); _ = a", err: true},
|
||||
{stmt: "i := 1; a := ivec4(i, i, i, i); _ = a", err: false},
|
||||
{stmt: "i := 1.0; a := ivec4(i, i, i, i); _ = a", err: false},
|
||||
{stmt: "a := ivec4(vec2(1), 1, 1); _ = a", err: false},
|
||||
{stmt: "a := ivec4(1, vec2(1), 1); _ = a", err: false},
|
||||
{stmt: "a := ivec4(1, 1, vec2(1)); _ = a", err: false},
|
||||
{stmt: "i := 1.0; a := ivec4(i, i, i, i); _ = a", err: true},
|
||||
{stmt: "a := ivec4(vec2(1), 1, 1); _ = a", err: true},
|
||||
{stmt: "a := ivec4(1, vec2(1), 1); _ = a", err: true},
|
||||
{stmt: "a := ivec4(1, 1, vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec4(ivec2(1), 1, 1); _ = a", err: false},
|
||||
{stmt: "a := ivec4(1, ivec2(1), 1); _ = a", err: false},
|
||||
{stmt: "a := ivec4(1, 1, ivec2(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec4(vec2(1), vec2(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec4(vec2(1), vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec4(ivec2(1), ivec2(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec4(vec3(1), 1); _ = a", err: false},
|
||||
{stmt: "a := ivec4(1, vec3(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec4(vec3(1), 1); _ = a", err: true},
|
||||
{stmt: "a := ivec4(1, vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec4(ivec3(1), 1); _ = a", err: false},
|
||||
{stmt: "a := ivec4(1, ivec3(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec4(vec4(1), 1); _ = a", err: true},
|
||||
@ -1773,7 +1798,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
|
||||
{stmt: "a := mat2(1); _ = a", err: false},
|
||||
{stmt: "a := mat2(1.0); _ = a", err: false},
|
||||
{stmt: "i := 1; a := mat2(i); _ = a", err: false},
|
||||
{stmt: "i := 1; a := mat2(i); _ = a", err: true},
|
||||
{stmt: "i := 1.0; a := mat2(i); _ = a", err: false},
|
||||
{stmt: "a := mat2(mat2(1)); _ = a", err: false},
|
||||
{stmt: "a := mat2(vec2(1)); _ = a", err: true},
|
||||
@ -1782,7 +1807,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
{stmt: "a := mat2(mat4(1)); _ = a", err: true},
|
||||
|
||||
{stmt: "a := mat2(vec2(1), vec2(1)); _ = a", err: false},
|
||||
{stmt: "a := mat2(ivec2(1), ivec2(1)); _ = a", err: false},
|
||||
{stmt: "a := mat2(ivec2(1), ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := mat2(1, 1); _ = a", err: true},
|
||||
{stmt: "a := mat2(1, vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := mat2(vec2(1), vec3(1)); _ = a", err: true},
|
||||
@ -1790,7 +1815,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
|
||||
{stmt: "a := mat2(1, 1, 1, 1); _ = a", err: false},
|
||||
{stmt: "a := mat2(1.0, 1.0, 1.0, 1.0); _ = a", err: false},
|
||||
{stmt: "i := 1; a := mat2(i, i, i, i); _ = a", err: false},
|
||||
{stmt: "i := 1; a := mat2(i, i, i, i); _ = a", err: true},
|
||||
{stmt: "i := 1.0; a := mat2(i, i, i, i); _ = a", err: false},
|
||||
{stmt: "a := mat2(vec2(1), vec2(1), vec2(1), vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := mat2(1, 1, 1, vec2(1)); _ = a", err: true},
|
||||
@ -1801,7 +1826,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
|
||||
{stmt: "a := mat3(1); _ = a", err: false},
|
||||
{stmt: "a := mat3(1.0); _ = a", err: false},
|
||||
{stmt: "i := 1; a := mat3(i); _ = a", err: false},
|
||||
{stmt: "i := 1; a := mat3(i); _ = a", err: true},
|
||||
{stmt: "i := 1.0; a := mat3(i); _ = a", err: false},
|
||||
{stmt: "a := mat3(mat3(1)); _ = a", err: false},
|
||||
{stmt: "a := mat3(vec2(1)); _ = a", err: true},
|
||||
@ -1810,7 +1835,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
{stmt: "a := mat3(mat4(1)); _ = a", err: true},
|
||||
|
||||
{stmt: "a := mat3(vec3(1), vec3(1), vec3(1)); _ = a", err: false},
|
||||
{stmt: "a := mat3(ivec3(1), ivec3(1), ivec3(1)); _ = a", err: false},
|
||||
{stmt: "a := mat3(ivec3(1), ivec3(1), ivec3(1)); _ = a", err: true},
|
||||
{stmt: "a := mat3(1, 1, 1); _ = a", err: true},
|
||||
{stmt: "a := mat3(1, 1, vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := mat3(vec3(1), vec3(1), vec4(1)); _ = a", err: true},
|
||||
@ -1818,7 +1843,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
|
||||
{stmt: "a := mat3(1, 1, 1, 1, 1, 1, 1, 1, 1); _ = a", err: false},
|
||||
{stmt: "a := mat3(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0); _ = a", err: false},
|
||||
{stmt: "i := 1; a := mat3(i, i, i, i, i, i, i, i, i); _ = a", err: false},
|
||||
{stmt: "i := 1; a := mat3(i, i, i, i, i, i, i, i, i); _ = a", err: true},
|
||||
{stmt: "i := 1.0; a := mat3(i, i, i, i, i, i, i, i, i); _ = a", err: false},
|
||||
{stmt: "a := mat3(vec3(1), vec3(1), vec3(1), vec3(1), vec3(1), vec3(1), vec3(1), vec3(1), vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := mat3(1, 1, 1, 1, 1, 1, 1, 1, vec2(1)); _ = a", err: true},
|
||||
@ -1829,7 +1854,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
|
||||
{stmt: "a := mat4(1); _ = a", err: false},
|
||||
{stmt: "a := mat4(1.0); _ = a", err: false},
|
||||
{stmt: "i := 1; a := mat4(i); _ = a", err: false},
|
||||
{stmt: "i := 1; a := mat4(i); _ = a", err: true},
|
||||
{stmt: "i := 1.0; a := mat4(i); _ = a", err: false},
|
||||
{stmt: "a := mat4(mat4(1)); _ = a", err: false},
|
||||
{stmt: "a := mat4(vec2(1)); _ = a", err: true},
|
||||
@ -1838,7 +1863,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
{stmt: "a := mat4(mat3(1)); _ = a", err: true},
|
||||
|
||||
{stmt: "a := mat4(vec4(1), vec4(1), vec4(1), vec4(1)); _ = a", err: false},
|
||||
{stmt: "a := mat4(ivec4(1), ivec4(1), ivec4(1), ivec4(1)); _ = a", err: false},
|
||||
{stmt: "a := mat4(ivec4(1), ivec4(1), ivec4(1), ivec4(1)); _ = a", err: true},
|
||||
{stmt: "a := mat4(1, 1, 1, 1); _ = a", err: true},
|
||||
{stmt: "a := mat4(1, 1, 1, vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := mat4(vec4(1), vec4(1), vec4(1), vec2(1)); _ = a", err: true},
|
||||
@ -1846,7 +1871,7 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
|
||||
{stmt: "a := mat4(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); _ = a", err: false},
|
||||
{stmt: "a := mat4(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0); _ = a", err: false},
|
||||
{stmt: "i := 1; a := mat4(i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i); _ = a", err: false},
|
||||
{stmt: "i := 1; a := mat4(i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i); _ = a", err: true},
|
||||
{stmt: "i := 1.0; a := mat4(i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i); _ = a", err: false},
|
||||
{stmt: "a := mat4(vec4(1), vec4(1), vec4(1), vec4(1), vec4(1), vec4(1), vec4(1), vec4(1), vec4(1), vec4(1), vec4(1), vec4(1), vec4(1), vec4(1), vec4(1), vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := mat4(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, vec2(1)); _ = a", err: true},
|
||||
@ -3341,3 +3366,40 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Issue #2712
|
||||
func TestSyntaxCast(t *testing.T) {
|
||||
cases := []struct {
|
||||
stmt string
|
||||
err bool
|
||||
}{
|
||||
{stmt: "a := int(1); _ = a", err: false},
|
||||
{stmt: "a := int(1.0); _ = a", err: false},
|
||||
{stmt: "a := int(1.1); _ = a", err: true},
|
||||
{stmt: "a := float(1); _ = a", err: false},
|
||||
{stmt: "a := float(1.0); _ = a", err: false},
|
||||
{stmt: "a := float(1.1); _ = a", err: false},
|
||||
{stmt: "a := 1; _ = int(a)", err: false},
|
||||
{stmt: "a := 1.0; _ = int(a)", err: false},
|
||||
{stmt: "a := 1.1; _ = int(a)", err: false},
|
||||
{stmt: "a := 1; _ = float(a)", err: false},
|
||||
{stmt: "a := 1.0; _ = float(a)", err: false},
|
||||
{stmt: "a := 1.1; _ = float(a)", err: false},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
stmt := c.stmt
|
||||
src := fmt.Sprintf(`package main
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
%s
|
||||
return position
|
||||
}`, stmt)
|
||||
_, err := compileToIR([]byte(src))
|
||||
if err == nil && c.err {
|
||||
t.Errorf("%s must return an error but does not", stmt)
|
||||
} else if err != nil && !c.err {
|
||||
t.Errorf("%s must not return nil but returned %v", stmt, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2
internal/shader/testdata/blocks2.expected.vs
vendored
2
internal/shader/testdata/blocks2.expected.vs
vendored
@ -6,7 +6,7 @@ vec2 F0(void) {
|
||||
{
|
||||
int l1 = 0;
|
||||
l1 = 0;
|
||||
return vec2(l1);
|
||||
return vec2(float(l1));
|
||||
}
|
||||
return vec2(1.0);
|
||||
}
|
||||
|
2
internal/shader/testdata/blocks2.go
vendored
2
internal/shader/testdata/blocks2.go
vendored
@ -4,7 +4,7 @@ func Foo() vec2 {
|
||||
x := true
|
||||
{
|
||||
x := 0
|
||||
return vec2(x)
|
||||
return vec2(float(x))
|
||||
}
|
||||
_ = x
|
||||
return vec2(1)
|
||||
|
2
internal/shader/testdata/for5.expected.fs
vendored
2
internal/shader/testdata/for5.expected.fs
vendored
@ -25,7 +25,7 @@ vec4 F1(in vec4 l0) {
|
||||
}
|
||||
l3 = 0;
|
||||
l1 = (l1) + (l3);
|
||||
return vec4(l1);
|
||||
return vec4(float(l1));
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
|
2
internal/shader/testdata/for5.expected.vs
vendored
2
internal/shader/testdata/for5.expected.vs
vendored
@ -25,6 +25,6 @@ void main(void) {
|
||||
}
|
||||
l2 = 0;
|
||||
l0 = (l0) + (l2);
|
||||
gl_Position = vec4(l0);
|
||||
gl_Position = vec4(float(l0));
|
||||
return;
|
||||
}
|
||||
|
4
internal/shader/testdata/for5.go
vendored
4
internal/shader/testdata/for5.go
vendored
@ -22,7 +22,7 @@ func Vertex(pos vec2) vec4 {
|
||||
}
|
||||
y := 0
|
||||
sum += y
|
||||
return vec4(sum)
|
||||
return vec4(float(sum))
|
||||
}
|
||||
|
||||
func Fragment(pos vec4) vec4 {
|
||||
@ -37,5 +37,5 @@ func Fragment(pos vec4) vec4 {
|
||||
}
|
||||
y := 0
|
||||
sum += y
|
||||
return vec4(sum)
|
||||
return vec4(float(sum))
|
||||
}
|
||||
|
2
internal/shader/testdata/inc.expected.vs
vendored
2
internal/shader/testdata/inc.expected.vs
vendored
@ -7,5 +7,5 @@ vec2 F0(void) {
|
||||
l0 = (l0) + (1);
|
||||
l1 = 1;
|
||||
l1 = (l1) - (1);
|
||||
return vec2(l0, l1);
|
||||
return vec2(float(l0), float(l1));
|
||||
}
|
||||
|
2
internal/shader/testdata/inc.go
vendored
2
internal/shader/testdata/inc.go
vendored
@ -5,5 +5,5 @@ func Foo() vec2 {
|
||||
l0++
|
||||
l1 := 1
|
||||
l1--
|
||||
return vec2(l0, l1)
|
||||
return vec2(float(l0), float(l1))
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ vec4 F0(void) {
|
||||
l1 = 2.5000000000e+00;
|
||||
l2 = 2.5000000000e+00;
|
||||
l3 = 2.5000000000e+00;
|
||||
return vec4(l0, l1, l2, l3);
|
||||
return vec4(float(l0), l1, l2, l3);
|
||||
}
|
||||
|
||||
vec4 F1(void) {
|
||||
@ -23,7 +23,7 @@ vec4 F1(void) {
|
||||
l1 = 2.5000000000e+00;
|
||||
l2 = 2.5000000000e+00;
|
||||
l3 = 2.5000000000e+00;
|
||||
return vec4(l0, l1, l2, l3);
|
||||
return vec4(float(l0), l1, l2, l3);
|
||||
}
|
||||
|
||||
vec4 F2(void) {
|
||||
@ -35,5 +35,5 @@ vec4 F2(void) {
|
||||
l1 = 2.5000000000e+00;
|
||||
l2 = 2.5000000000e+00;
|
||||
l3 = 2.5000000000e+00;
|
||||
return vec4(l0, l1, l2, l3);
|
||||
return vec4(float(l0), l1, l2, l3);
|
||||
}
|
||||
|
6
internal/shader/testdata/number_binary.go
vendored
6
internal/shader/testdata/number_binary.go
vendored
@ -5,7 +5,7 @@ func Foo1() vec4 {
|
||||
x1 := 5.0 / 2
|
||||
x2 := 5 / 2.0
|
||||
x3 := 5.0 / 2.0
|
||||
return vec4(x0, x1, x2, x3)
|
||||
return vec4(float(x0), x1, x2, x3)
|
||||
}
|
||||
|
||||
func Foo2() vec4 {
|
||||
@ -13,10 +13,10 @@ func Foo2() vec4 {
|
||||
var x1 = 5.0 / 2
|
||||
var x2 = 5 / 2.0
|
||||
var x3 = 5.0 / 2.0
|
||||
return vec4(x0, x1, x2, x3)
|
||||
return vec4(float(x0), x1, x2, x3)
|
||||
}
|
||||
|
||||
func Foo3() vec4 {
|
||||
var x0, x1, x2, x3 = 5 / 2, 5.0 / 2, 5 / 2.0, 5.0 / 2.0
|
||||
return vec4(x0, x1, x2, x3)
|
||||
return vec4(float(x0), x1, x2, x3)
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ vec4 F0(void) {
|
||||
l5 = -5.0;
|
||||
l6 = -5.0;
|
||||
l7 = 5.0;
|
||||
return (vec4(l0, l1, l2, l3)) + (vec4(l4, l5, l6, l7));
|
||||
return (vec4(float(l0), float(l1), float(l2), float(l3))) + (vec4(l4, l5, l6, l7));
|
||||
}
|
||||
|
||||
vec4 F1(void) {
|
||||
@ -38,5 +38,5 @@ vec4 F1(void) {
|
||||
l5 = -5.0;
|
||||
l6 = -5.0;
|
||||
l7 = 5.0;
|
||||
return (vec4(l0, l1, l2, l3)) + (vec4(l4, l5, l6, l7));
|
||||
return (vec4(float(l0), float(l1), float(l2), float(l3))) + (vec4(l4, l5, l6, l7));
|
||||
}
|
||||
|
4
internal/shader/testdata/number_unary.go
vendored
4
internal/shader/testdata/number_unary.go
vendored
@ -9,7 +9,7 @@ func Foo1() vec4 {
|
||||
x5 := +(-5.0)
|
||||
x6 := -(+5.0)
|
||||
x7 := -(-5.0)
|
||||
return vec4(x0, x1, x2, x3) + vec4(x4, x5, x6, x7)
|
||||
return vec4(float(x0), float(x1), float(x2), float(x3)) + vec4(x4, x5, x6, x7)
|
||||
}
|
||||
|
||||
func Foo2() vec4 {
|
||||
@ -21,5 +21,5 @@ func Foo2() vec4 {
|
||||
var x5 = +(-5.0)
|
||||
var x6 = -(+5.0)
|
||||
var x7 = -(-5.0)
|
||||
return vec4(x0, x1, x2, x3) + vec4(x4, x5, x6, x7)
|
||||
return vec4(float(x0), float(x1), float(x2), float(x3)) + vec4(x4, x5, x6, x7)
|
||||
}
|
||||
|
@ -106,19 +106,37 @@ func (cs *compileState) parseType(block *block, fname string, expr ast.Expr) (sh
|
||||
}
|
||||
}
|
||||
|
||||
func canBeFloatImplicitly(expr shaderir.Expr, t shaderir.Type) bool {
|
||||
if expr.Const != nil && canTruncateToFloat(expr.Const) {
|
||||
func isFloat(expr shaderir.Expr, t shaderir.Type) bool {
|
||||
if expr.Const != nil {
|
||||
if t.Main == shaderir.Float {
|
||||
return true
|
||||
}
|
||||
if canTruncateToFloat(expr.Const) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// canBeFloatImplicitly is used for a cast-like functions like float() or vec2().
|
||||
// A non-constant integer value is acceptable.
|
||||
if t.Main == shaderir.Int {
|
||||
if t.Main == shaderir.Float {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isInt(expr shaderir.Expr, t shaderir.Type) bool {
|
||||
if expr.Const != nil {
|
||||
if t.Main == shaderir.Float {
|
||||
return true
|
||||
}
|
||||
if canTruncateToInteger(expr.Const) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if t.Main == shaderir.Int {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@ -150,7 +168,7 @@ func checkArgsForIntBuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) err
|
||||
if argts[0].Main == shaderir.Int || argts[0].Main == shaderir.Float {
|
||||
return nil
|
||||
}
|
||||
if args[0].Const != nil && canTruncateToInteger(args[0].Const) {
|
||||
if args[0].Const != nil && gconstant.ToInt(args[0].Const).Kind() != gconstant.Unknown {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid arguments for int: (%s)", argts[0].String())
|
||||
@ -164,7 +182,10 @@ func checkArgsForFloatBuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) e
|
||||
if len(args) != 1 {
|
||||
return fmt.Errorf("number of float's arguments must be 1 but %d", len(args))
|
||||
}
|
||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
||||
if argts[0].Main == shaderir.Int || argts[0].Main == shaderir.Float {
|
||||
return nil
|
||||
}
|
||||
if args[0].Const != nil && gconstant.ToFloat(args[0].Const).Kind() != gconstant.Unknown {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid arguments for float: (%s)", argts[0].String())
|
||||
@ -177,14 +198,15 @@ func checkArgsForVec2BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
||||
|
||||
switch len(args) {
|
||||
case 1:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
||||
if isFloat(args[0], argts[0]) {
|
||||
return nil
|
||||
}
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 {
|
||||
// Allow any vectors to perform a cast-like function.
|
||||
if (argts[0].IsFloatVector() || argts[0].IsIntVector()) && argts[0].VectorElementCount() == 2 {
|
||||
return nil
|
||||
}
|
||||
case 2:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && canBeFloatImplicitly(args[1], argts[1]) {
|
||||
if isFloat(args[0], argts[0]) && isFloat(args[1], argts[1]) {
|
||||
return nil
|
||||
}
|
||||
default:
|
||||
@ -205,21 +227,22 @@ func checkArgsForVec3BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
||||
|
||||
switch len(args) {
|
||||
case 1:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
||||
if isFloat(args[0], argts[0]) {
|
||||
return nil
|
||||
}
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 3 {
|
||||
// Allow any vectors to perform a cast-like function.
|
||||
if (argts[0].IsFloatVector() || argts[0].IsIntVector()) && argts[0].VectorElementCount() == 3 {
|
||||
return nil
|
||||
}
|
||||
case 2:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && argts[1].IsVector() && argts[1].VectorElementCount() == 2 {
|
||||
if isFloat(args[0], argts[0]) && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 2 {
|
||||
return nil
|
||||
}
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 && canBeFloatImplicitly(args[1], argts[1]) {
|
||||
if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 2 && isFloat(args[1], argts[1]) {
|
||||
return nil
|
||||
}
|
||||
case 3:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && canBeFloatImplicitly(args[1], argts[1]) && canBeFloatImplicitly(args[2], argts[2]) {
|
||||
if isFloat(args[0], argts[0]) && isFloat(args[1], argts[1]) && isFloat(args[2], argts[2]) {
|
||||
return nil
|
||||
}
|
||||
default:
|
||||
@ -240,34 +263,35 @@ func checkArgsForVec4BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
||||
|
||||
switch len(args) {
|
||||
case 1:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
||||
if isFloat(args[0], argts[0]) {
|
||||
return nil
|
||||
}
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 4 {
|
||||
// Allow any vectors to perform a cast-like function.
|
||||
if (argts[0].IsFloatVector() || argts[0].IsIntVector()) && argts[0].VectorElementCount() == 4 {
|
||||
return nil
|
||||
}
|
||||
case 2:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && argts[1].IsVector() && argts[1].VectorElementCount() == 3 {
|
||||
if isFloat(args[0], argts[0]) && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 3 {
|
||||
return nil
|
||||
}
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 && argts[1].IsVector() && argts[1].VectorElementCount() == 2 {
|
||||
if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 2 && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 2 {
|
||||
return nil
|
||||
}
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 3 && canBeFloatImplicitly(args[1], argts[1]) {
|
||||
if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 3 && isFloat(args[1], argts[1]) {
|
||||
return nil
|
||||
}
|
||||
case 3:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && canBeFloatImplicitly(args[1], argts[1]) && argts[2].IsVector() && argts[2].VectorElementCount() == 2 {
|
||||
if isFloat(args[0], argts[0]) && isFloat(args[1], argts[1]) && argts[2].IsFloatVector() && argts[2].VectorElementCount() == 2 {
|
||||
return nil
|
||||
}
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && argts[1].IsVector() && argts[1].VectorElementCount() == 2 && canBeFloatImplicitly(args[2], argts[2]) {
|
||||
if isFloat(args[0], argts[0]) && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 2 && isFloat(args[2], argts[2]) {
|
||||
return nil
|
||||
}
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 && canBeFloatImplicitly(args[1], argts[1]) && canBeFloatImplicitly(args[2], argts[2]) {
|
||||
if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 2 && isFloat(args[1], argts[1]) && isFloat(args[2], argts[2]) {
|
||||
return nil
|
||||
}
|
||||
case 4:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && canBeFloatImplicitly(args[1], argts[1]) && canBeFloatImplicitly(args[2], argts[2]) && canBeFloatImplicitly(args[3], argts[3]) {
|
||||
if isFloat(args[0], argts[0]) && isFloat(args[1], argts[1]) && isFloat(args[2], argts[2]) && isFloat(args[3], argts[3]) {
|
||||
return nil
|
||||
}
|
||||
default:
|
||||
@ -281,6 +305,120 @@ func checkArgsForVec4BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
||||
return fmt.Errorf("invalid arguments for vec4: (%s)", strings.Join(str, ", "))
|
||||
}
|
||||
|
||||
func checkArgsForIVec2BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
|
||||
if len(args) != len(argts) {
|
||||
return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
|
||||
}
|
||||
|
||||
switch len(args) {
|
||||
case 1:
|
||||
if isInt(args[0], argts[0]) {
|
||||
return nil
|
||||
}
|
||||
// Allow any vectors to perform a cast-like function.
|
||||
if (argts[0].IsFloatVector() || argts[0].IsIntVector()) && argts[0].VectorElementCount() == 2 {
|
||||
return nil
|
||||
}
|
||||
case 2:
|
||||
if isInt(args[0], argts[0]) && isInt(args[1], argts[1]) {
|
||||
return nil
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("invalid number of arguments for vec2")
|
||||
}
|
||||
|
||||
var str []string
|
||||
for _, t := range argts {
|
||||
str = append(str, t.String())
|
||||
}
|
||||
return fmt.Errorf("invalid arguments for ivec2: (%s)", strings.Join(str, ", "))
|
||||
}
|
||||
|
||||
func checkArgsForIVec3BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
|
||||
if len(args) != len(argts) {
|
||||
return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
|
||||
}
|
||||
|
||||
switch len(args) {
|
||||
case 1:
|
||||
if isInt(args[0], argts[0]) {
|
||||
return nil
|
||||
}
|
||||
// Allow any vectors to perform a cast-like function.
|
||||
if (argts[0].IsFloatVector() || argts[0].IsIntVector()) && argts[0].VectorElementCount() == 3 {
|
||||
return nil
|
||||
}
|
||||
case 2:
|
||||
if isInt(args[0], argts[0]) && argts[1].IsIntVector() && argts[1].VectorElementCount() == 2 {
|
||||
return nil
|
||||
}
|
||||
if argts[0].IsIntVector() && argts[0].VectorElementCount() == 2 && isInt(args[1], argts[1]) {
|
||||
return nil
|
||||
}
|
||||
case 3:
|
||||
if isInt(args[0], argts[0]) && isInt(args[1], argts[1]) && isInt(args[2], argts[2]) {
|
||||
return nil
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("invalid number of arguments for vec3")
|
||||
}
|
||||
|
||||
var str []string
|
||||
for _, t := range argts {
|
||||
str = append(str, t.String())
|
||||
}
|
||||
return fmt.Errorf("invalid arguments for ivec3: (%s)", strings.Join(str, ", "))
|
||||
}
|
||||
|
||||
func checkArgsForIVec4BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
|
||||
if len(args) != len(argts) {
|
||||
return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
|
||||
}
|
||||
|
||||
switch len(args) {
|
||||
case 1:
|
||||
if isInt(args[0], argts[0]) {
|
||||
return nil
|
||||
}
|
||||
// Allow any vectors to perform a cast-like function.
|
||||
if (argts[0].IsFloatVector() || argts[0].IsIntVector()) && argts[0].VectorElementCount() == 4 {
|
||||
return nil
|
||||
}
|
||||
case 2:
|
||||
if isInt(args[0], argts[0]) && argts[1].IsIntVector() && argts[1].VectorElementCount() == 3 {
|
||||
return nil
|
||||
}
|
||||
if argts[0].IsIntVector() && argts[0].VectorElementCount() == 2 && argts[1].IsIntVector() && argts[1].VectorElementCount() == 2 {
|
||||
return nil
|
||||
}
|
||||
if argts[0].IsIntVector() && argts[0].VectorElementCount() == 3 && isInt(args[1], argts[1]) {
|
||||
return nil
|
||||
}
|
||||
case 3:
|
||||
if isInt(args[0], argts[0]) && isInt(args[1], argts[1]) && argts[2].IsIntVector() && argts[2].VectorElementCount() == 2 {
|
||||
return nil
|
||||
}
|
||||
if isInt(args[0], argts[0]) && argts[1].IsIntVector() && argts[1].VectorElementCount() == 2 && isInt(args[2], argts[2]) {
|
||||
return nil
|
||||
}
|
||||
if argts[0].IsIntVector() && argts[0].VectorElementCount() == 2 && isInt(args[1], argts[1]) && isInt(args[2], argts[2]) {
|
||||
return nil
|
||||
}
|
||||
case 4:
|
||||
if isInt(args[0], argts[0]) && isInt(args[1], argts[1]) && isInt(args[2], argts[2]) && isInt(args[3], argts[3]) {
|
||||
return nil
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("invalid number of arguments for vec4")
|
||||
}
|
||||
|
||||
var str []string
|
||||
for _, t := range argts {
|
||||
str = append(str, t.String())
|
||||
}
|
||||
return fmt.Errorf("invalid arguments for ivec4: (%s)", strings.Join(str, ", "))
|
||||
}
|
||||
|
||||
func checkArgsForMat2BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
|
||||
if len(args) != len(argts) {
|
||||
return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
|
||||
@ -288,20 +426,20 @@ func checkArgsForMat2BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
||||
|
||||
switch len(args) {
|
||||
case 1:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
||||
if isFloat(args[0], argts[0]) {
|
||||
return nil
|
||||
}
|
||||
if argts[0].Main == shaderir.Mat2 {
|
||||
return nil
|
||||
}
|
||||
case 2:
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 && argts[1].IsVector() && argts[1].VectorElementCount() == 2 {
|
||||
if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 2 && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 2 {
|
||||
return nil
|
||||
}
|
||||
case 4:
|
||||
ok := true
|
||||
for i := range argts {
|
||||
if !canBeFloatImplicitly(args[i], argts[i]) {
|
||||
if !isFloat(args[i], argts[i]) {
|
||||
ok = false
|
||||
break
|
||||
}
|
||||
@ -327,22 +465,22 @@ func checkArgsForMat3BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
||||
|
||||
switch len(args) {
|
||||
case 1:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
||||
if isFloat(args[0], argts[0]) {
|
||||
return nil
|
||||
}
|
||||
if argts[0].Main == shaderir.Mat3 {
|
||||
return nil
|
||||
}
|
||||
case 3:
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 3 &&
|
||||
argts[1].IsVector() && argts[1].VectorElementCount() == 3 &&
|
||||
argts[2].IsVector() && argts[2].VectorElementCount() == 3 {
|
||||
if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 3 &&
|
||||
argts[1].IsFloatVector() && argts[1].VectorElementCount() == 3 &&
|
||||
argts[2].IsFloatVector() && argts[2].VectorElementCount() == 3 {
|
||||
return nil
|
||||
}
|
||||
case 9:
|
||||
ok := true
|
||||
for i := range argts {
|
||||
if !canBeFloatImplicitly(args[i], argts[i]) {
|
||||
if !isFloat(args[i], argts[i]) {
|
||||
ok = false
|
||||
break
|
||||
}
|
||||
@ -368,23 +506,23 @@ func checkArgsForMat4BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
||||
|
||||
switch len(args) {
|
||||
case 1:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
||||
if isFloat(args[0], argts[0]) {
|
||||
return nil
|
||||
}
|
||||
if argts[0].Main == shaderir.Mat4 {
|
||||
return nil
|
||||
}
|
||||
case 4:
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 4 &&
|
||||
argts[1].IsVector() && argts[1].VectorElementCount() == 4 &&
|
||||
argts[2].IsVector() && argts[2].VectorElementCount() == 4 &&
|
||||
argts[3].IsVector() && argts[3].VectorElementCount() == 4 {
|
||||
if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 4 &&
|
||||
argts[1].IsFloatVector() && argts[1].VectorElementCount() == 4 &&
|
||||
argts[2].IsFloatVector() && argts[2].VectorElementCount() == 4 &&
|
||||
argts[3].IsFloatVector() && argts[3].VectorElementCount() == 4 {
|
||||
return nil
|
||||
}
|
||||
case 16:
|
||||
ok := true
|
||||
for i := range argts {
|
||||
if !canBeFloatImplicitly(args[i], argts[i]) {
|
||||
if !isFloat(args[i], argts[i]) {
|
||||
ok = false
|
||||
break
|
||||
}
|
||||
|
@ -39,10 +39,10 @@ func ResolveUntypedConstsForBinaryOp(lhs, rhs constant.Value, lhst, rhst Type) (
|
||||
}
|
||||
|
||||
if lhst.Main == None {
|
||||
if (rhst.Main == Float || rhst.isFloatVector() || rhst.IsMatrix()) && constant.ToFloat(lhs).Kind() != constant.Unknown {
|
||||
if (rhst.Main == Float || rhst.IsFloatVector() || rhst.IsMatrix()) && constant.ToFloat(lhs).Kind() != constant.Unknown {
|
||||
return constant.ToFloat(lhs), rhs, true
|
||||
}
|
||||
if (rhst.Main == Int || rhst.isIntVector()) && constant.ToInt(lhs).Kind() != constant.Unknown {
|
||||
if (rhst.Main == Int || rhst.IsIntVector()) && constant.ToInt(lhs).Kind() != constant.Unknown {
|
||||
return constant.ToInt(lhs), rhs, true
|
||||
}
|
||||
if rhst.Main == Bool && lhs.Kind() == constant.Bool {
|
||||
@ -52,10 +52,10 @@ func ResolveUntypedConstsForBinaryOp(lhs, rhs constant.Value, lhst, rhst Type) (
|
||||
}
|
||||
|
||||
if rhst.Main == None {
|
||||
if (lhst.Main == Float || lhst.isFloatVector() || lhst.IsMatrix()) && constant.ToFloat(rhs).Kind() != constant.Unknown {
|
||||
if (lhst.Main == Float || lhst.IsFloatVector() || lhst.IsMatrix()) && constant.ToFloat(rhs).Kind() != constant.Unknown {
|
||||
return lhs, constant.ToFloat(rhs), true
|
||||
}
|
||||
if (lhst.Main == Int || lhst.isIntVector()) && constant.ToInt(rhs).Kind() != constant.Unknown {
|
||||
if (lhst.Main == Int || lhst.IsIntVector()) && constant.ToInt(rhs).Kind() != constant.Unknown {
|
||||
return lhs, constant.ToInt(rhs), true
|
||||
}
|
||||
if lhst.Main == Bool && rhs.Kind() == constant.Bool {
|
||||
@ -97,7 +97,7 @@ func AreValidTypesForBinaryOp(op Op, lhs, rhs *Expr, lhst, rhst Type) bool {
|
||||
}
|
||||
|
||||
if op == VectorEqualOp || op == VectorNotEqualOp {
|
||||
return lhst.IsVector() && rhst.IsVector() && lhst.Equal(&rhst)
|
||||
return (lhst.IsFloatVector() || lhst.IsIntVector()) && (rhst.IsFloatVector() || lhst.IsIntVector()) && lhst.Equal(&rhst)
|
||||
}
|
||||
|
||||
// Comparing matrices are forbidden (#2187).
|
||||
@ -122,7 +122,7 @@ func AreValidTypesForBinaryOp(op Op, lhs, rhs *Expr, lhst, rhst Type) bool {
|
||||
if lhst.Main == IVec4 && rhst.Main == IVec4 {
|
||||
return true
|
||||
}
|
||||
return (lhst.Main == Int || lhst.isIntVector()) && rhst.Main == Int
|
||||
return (lhst.Main == Int || lhst.IsIntVector()) && rhst.Main == Int
|
||||
}
|
||||
|
||||
if lhst.Equal(&rhst) {
|
||||
@ -164,16 +164,16 @@ func AreValidTypesForBinaryOp(op Op, lhs, rhs *Expr, lhst, rhst Type) bool {
|
||||
// fallback
|
||||
}
|
||||
|
||||
if lhst.isFloatVector() && rhst.Main == Float {
|
||||
if lhst.IsFloatVector() && rhst.Main == Float {
|
||||
return true
|
||||
}
|
||||
if rhst.isFloatVector() && lhst.Main == Float {
|
||||
if rhst.IsFloatVector() && lhst.Main == Float {
|
||||
return true
|
||||
}
|
||||
if lhst.isIntVector() && rhst.Main == Int {
|
||||
if lhst.IsIntVector() && rhst.Main == Int {
|
||||
return true
|
||||
}
|
||||
if rhst.isIntVector() && lhst.Main == Int {
|
||||
if rhst.IsIntVector() && lhst.Main == Int {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -205,12 +205,12 @@ func OpFromToken(t token.Token, lhs, rhs Type) (Op, bool) {
|
||||
case token.GEQ:
|
||||
return GreaterThanEqualOp, true
|
||||
case token.EQL:
|
||||
if lhs.IsVector() || rhs.IsVector() {
|
||||
if lhs.IsFloatVector() || lhs.IsIntVector() || rhs.IsFloatVector() || rhs.IsIntVector() {
|
||||
return VectorEqualOp, true
|
||||
}
|
||||
return EqualOp, true
|
||||
case token.NEQ:
|
||||
if lhs.IsVector() || rhs.IsVector() {
|
||||
if lhs.IsFloatVector() || lhs.IsIntVector() || rhs.IsFloatVector() || rhs.IsIntVector() {
|
||||
return VectorNotEqualOp, true
|
||||
}
|
||||
return NotEqualOp, true
|
||||
|
@ -118,15 +118,7 @@ func (t *Type) Uint32Count() int {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Type) IsVector() bool {
|
||||
switch t.Main {
|
||||
case Vec2, Vec3, Vec4, IVec2, IVec3, IVec4:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *Type) isFloatVector() bool {
|
||||
func (t *Type) IsFloatVector() bool {
|
||||
switch t.Main {
|
||||
case Vec2, Vec3, Vec4:
|
||||
return true
|
||||
@ -134,7 +126,7 @@ func (t *Type) isFloatVector() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *Type) isIntVector() bool {
|
||||
func (t *Type) IsIntVector() bool {
|
||||
switch t.Main {
|
||||
case IVec2, IVec3, IVec4:
|
||||
return true
|
||||
|
@ -1836,8 +1836,8 @@ package main
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
orig, _ := imageSrcRegionOnTexture()
|
||||
pos := ivec2(3.1, 4.2)
|
||||
return imageSrc0At(vec2(pos.x, pos.y) + orig)
|
||||
pos := ivec2(3, 4)
|
||||
return imageSrc0At(vec2(pos) + orig)
|
||||
}
|
||||
`))
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user