mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
internal/shader: introduce integer vectors (ivec2, ivec3, ivec4)
Closes #1911
This commit is contained in:
parent
f09c4a624e
commit
0b9cbaa1ed
@ -1739,19 +1739,19 @@ func (s *Shader) flattenUniforms(uniforms [][]uint32) []uint32 {
|
||||
} else {
|
||||
fs = append(fs, 0)
|
||||
}
|
||||
case shaderir.Vec2:
|
||||
case shaderir.Vec2, shaderir.IVec2:
|
||||
if u != nil {
|
||||
fs = append(fs, u...)
|
||||
} else {
|
||||
fs = append(fs, 0, 0)
|
||||
}
|
||||
case shaderir.Vec3:
|
||||
case shaderir.Vec3, shaderir.IVec3:
|
||||
if u != nil {
|
||||
fs = append(fs, u...)
|
||||
} else {
|
||||
fs = append(fs, 0, 0, 0)
|
||||
}
|
||||
case shaderir.Vec4:
|
||||
case shaderir.Vec4, shaderir.IVec4:
|
||||
if u != nil {
|
||||
fs = append(fs, u...)
|
||||
} else {
|
||||
@ -1824,7 +1824,7 @@ func (s *Shader) flattenUniforms(uniforms [][]uint32) []uint32 {
|
||||
} else {
|
||||
fs = append(fs, make([]uint32, (t.Length-1)*4+1)...)
|
||||
}
|
||||
case shaderir.Vec2:
|
||||
case shaderir.Vec2, shaderir.IVec2:
|
||||
if u != nil {
|
||||
for j := 0; j < t.Length; j++ {
|
||||
fs = append(fs, u[2*j:2*(j+1)]...)
|
||||
@ -1835,7 +1835,7 @@ func (s *Shader) flattenUniforms(uniforms [][]uint32) []uint32 {
|
||||
} else {
|
||||
fs = append(fs, make([]uint32, (t.Length-1)*4+2)...)
|
||||
}
|
||||
case shaderir.Vec3:
|
||||
case shaderir.Vec3, shaderir.IVec3:
|
||||
if u != nil {
|
||||
for j := 0; j < t.Length; j++ {
|
||||
fs = append(fs, u[3*j:3*(j+1)]...)
|
||||
@ -1846,7 +1846,7 @@ func (s *Shader) flattenUniforms(uniforms [][]uint32) []uint32 {
|
||||
} else {
|
||||
fs = append(fs, make([]uint32, (t.Length-1)*4+3)...)
|
||||
}
|
||||
case shaderir.Vec4:
|
||||
case shaderir.Vec4, shaderir.IVec4:
|
||||
if u != nil {
|
||||
fs = append(fs, u...)
|
||||
} else {
|
||||
|
@ -576,7 +576,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
|
||||
|
||||
t := g.shaders[shaderID].ir.Uniforms[i]
|
||||
switch t.Main {
|
||||
case shaderir.Vec3:
|
||||
case shaderir.Vec3, shaderir.IVec3:
|
||||
// float3 requires 16-byte alignment (#2463).
|
||||
v1 := make([]uint32, 4)
|
||||
copy(v1[0:3], v[0:3])
|
||||
@ -590,7 +590,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
|
||||
uniformVars[i] = v1
|
||||
case shaderir.Array:
|
||||
switch t.Sub[0].Main {
|
||||
case shaderir.Vec3:
|
||||
case shaderir.Vec3, shaderir.IVec3:
|
||||
v1 := make([]uint32, t.Length*4)
|
||||
for j := 0; j < t.Length; j++ {
|
||||
offset0 := j * 3
|
||||
|
@ -470,6 +470,12 @@ func (c *context) uniforms(p program, location string, v []uint32, typ shaderir.
|
||||
c.ctx.Uniform3fv(int32(l), uint32sToFloat32s(v))
|
||||
case shaderir.Vec4:
|
||||
c.ctx.Uniform4fv(int32(l), uint32sToFloat32s(v))
|
||||
case shaderir.IVec2:
|
||||
c.ctx.Uniform2iv(int32(l), uint32sToInt32s(v))
|
||||
case shaderir.IVec3:
|
||||
c.ctx.Uniform3iv(int32(l), uint32sToInt32s(v))
|
||||
case shaderir.IVec4:
|
||||
c.ctx.Uniform4iv(int32(l), uint32sToInt32s(v))
|
||||
case shaderir.Mat2:
|
||||
c.ctx.UniformMatrix2fv(int32(l), uint32sToFloat32s(v))
|
||||
case shaderir.Mat3:
|
||||
|
@ -99,8 +99,11 @@ package gl
|
||||
// typedef void (APIENTRYP GPUNIFORM1I)(GLint location, GLint v0);
|
||||
// typedef void (APIENTRYP GPUNIFORM1IV)(GLint location, GLsizei count, const GLint * value);
|
||||
// typedef void (APIENTRYP GPUNIFORM2FV)(GLint location, GLsizei count, const GLfloat * value);
|
||||
// typedef void (APIENTRYP GPUNIFORM2IV)(GLint location, GLsizei count, const GLint * value);
|
||||
// typedef void (APIENTRYP GPUNIFORM3FV)(GLint location, GLsizei count, const GLfloat * value);
|
||||
// typedef void (APIENTRYP GPUNIFORM3IV)(GLint location, GLsizei count, const GLint * value);
|
||||
// typedef void (APIENTRYP GPUNIFORM4FV)(GLint location, GLsizei count, const GLfloat * value);
|
||||
// typedef void (APIENTRYP GPUNIFORM4IV)(GLint location, GLsizei count, const GLint * value);
|
||||
// typedef void (APIENTRYP GPUNIFORMMATRIX2FV)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
|
||||
// typedef void (APIENTRYP GPUNIFORMMATRIX3FV)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
|
||||
// typedef void (APIENTRYP GPUNIFORMMATRIX4FV)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
|
||||
@ -291,12 +294,21 @@ package gl
|
||||
// static void glowUniform2fv(GPUNIFORM2FV fnptr, GLint location, GLsizei count, const GLfloat * value) {
|
||||
// (*fnptr)(location, count, value);
|
||||
// }
|
||||
// static void glowUniform2iv(GPUNIFORM2IV fnptr, GLint location, GLsizei count, const GLint * value) {
|
||||
// (*fnptr)(location, count, value);
|
||||
// }
|
||||
// static void glowUniform3fv(GPUNIFORM3FV fnptr, GLint location, GLsizei count, const GLfloat * value) {
|
||||
// (*fnptr)(location, count, value);
|
||||
// }
|
||||
// static void glowUniform3iv(GPUNIFORM3IV fnptr, GLint location, GLsizei count, const GLint * value) {
|
||||
// (*fnptr)(location, count, value);
|
||||
// }
|
||||
// static void glowUniform4fv(GPUNIFORM4FV fnptr, GLint location, GLsizei count, const GLfloat * value) {
|
||||
// (*fnptr)(location, count, value);
|
||||
// }
|
||||
// static void glowUniform4iv(GPUNIFORM4IV fnptr, GLint location, GLsizei count, const GLint * value) {
|
||||
// (*fnptr)(location, count, value);
|
||||
// }
|
||||
// static void glowUniformMatrix2fv(GPUNIFORMMATRIX2FV fnptr, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) {
|
||||
// (*fnptr)(location, count, transpose, value);
|
||||
// }
|
||||
@ -385,8 +397,11 @@ type defaultContext struct {
|
||||
gpUniform1i C.GPUNIFORM1I
|
||||
gpUniform1iv C.GPUNIFORM1IV
|
||||
gpUniform2fv C.GPUNIFORM2FV
|
||||
gpUniform2iv C.GPUNIFORM2IV
|
||||
gpUniform3fv C.GPUNIFORM3FV
|
||||
gpUniform3iv C.GPUNIFORM3IV
|
||||
gpUniform4fv C.GPUNIFORM4FV
|
||||
gpUniform4iv C.GPUNIFORM4IV
|
||||
gpUniformMatrix2fv C.GPUNIFORMMATRIX2FV
|
||||
gpUniformMatrix3fv C.GPUNIFORMMATRIX3FV
|
||||
gpUniformMatrix4fv C.GPUNIFORMMATRIX4FV
|
||||
@ -705,16 +720,31 @@ func (c *defaultContext) Uniform2fv(location int32, value []float32) {
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform2iv(location int32, value []int32) {
|
||||
C.glowUniform2iv(c.gpUniform2iv, (C.GLint)(location), (C.GLsizei)(len(value)/2), (*C.GLint)(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform3fv(location int32, value []float32) {
|
||||
C.glowUniform3fv(c.gpUniform3fv, (C.GLint)(location), (C.GLsizei)(len(value)/3), (*C.GLfloat)(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform3iv(location int32, value []int32) {
|
||||
C.glowUniform3iv(c.gpUniform3iv, (C.GLint)(location), (C.GLsizei)(len(value)/3), (*C.GLint)(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform4fv(location int32, value []float32) {
|
||||
C.glowUniform4fv(c.gpUniform4fv, (C.GLint)(location), (C.GLsizei)(len(value)/4), (*C.GLfloat)(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform4iv(location int32, value []int32) {
|
||||
C.glowUniform4iv(c.gpUniform4iv, (C.GLint)(location), (C.GLsizei)(len(value)/4), (*C.GLint)(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) UniformMatrix2fv(location int32, value []float32) {
|
||||
C.glowUniformMatrix2fv(c.gpUniformMatrix2fv, (C.GLint)(location), (C.GLsizei)(len(value)/4), 0, (*C.GLfloat)(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
@ -951,14 +981,26 @@ func (c *defaultContext) LoadFunctions() error {
|
||||
if c.gpUniform2fv == nil {
|
||||
return errors.New("gl: glUniform2fv is missing")
|
||||
}
|
||||
c.gpUniform2iv = (C.GPUNIFORM2IV)(c.getProcAddress("glUniform2iv"))
|
||||
if c.gpUniform2iv == nil {
|
||||
return errors.New("gl: glUniform2iv is missing")
|
||||
}
|
||||
c.gpUniform3fv = (C.GPUNIFORM3FV)(c.getProcAddress("glUniform3fv"))
|
||||
if c.gpUniform3fv == nil {
|
||||
return errors.New("gl: glUniform3fv is missing")
|
||||
}
|
||||
c.gpUniform3iv = (C.GPUNIFORM3IV)(c.getProcAddress("glUniform3iv"))
|
||||
if c.gpUniform3iv == nil {
|
||||
return errors.New("gl: glUniform3iv is missing")
|
||||
}
|
||||
c.gpUniform4fv = (C.GPUNIFORM4FV)(c.getProcAddress("glUniform4fv"))
|
||||
if c.gpUniform4fv == nil {
|
||||
return errors.New("gl: glUniform4fv is missing")
|
||||
}
|
||||
c.gpUniform4iv = (C.GPUNIFORM4IV)(c.getProcAddress("glUniform4iv"))
|
||||
if c.gpUniform4iv == nil {
|
||||
return errors.New("gl: glUniform4iv is missing")
|
||||
}
|
||||
c.gpUniformMatrix2fv = (C.GPUNIFORMMATRIX2FV)(c.getProcAddress("glUniformMatrix2fv"))
|
||||
if c.gpUniformMatrix2fv == nil {
|
||||
return errors.New("gl: glUniformMatrix2fv is missing")
|
||||
|
@ -84,8 +84,11 @@ type defaultContext struct {
|
||||
fnUniform1i js.Value
|
||||
fnUniform1iv js.Value
|
||||
fnUniform2fv js.Value
|
||||
fnUniform2iv js.Value
|
||||
fnUniform3fv js.Value
|
||||
fnUniform3iv js.Value
|
||||
fnUniform4fv js.Value
|
||||
fnUniform4iv js.Value
|
||||
fnUniformMatrix2fv js.Value
|
||||
fnUniformMatrix3fv js.Value
|
||||
fnUniformMatrix4fv js.Value
|
||||
@ -210,8 +213,11 @@ func NewDefaultContext(v js.Value) (Context, error) {
|
||||
fnUniform1i: v.Get("uniform1i").Call("bind", v),
|
||||
fnUniform1iv: v.Get("uniform1iv").Call("bind", v),
|
||||
fnUniform2fv: v.Get("uniform2fv").Call("bind", v),
|
||||
fnUniform2iv: v.Get("uniform2iv").Call("bind", v),
|
||||
fnUniform3fv: v.Get("uniform3fv").Call("bind", v),
|
||||
fnUniform3iv: v.Get("uniform3iv").Call("bind", v),
|
||||
fnUniform4fv: v.Get("uniform4fv").Call("bind", v),
|
||||
fnUniform4iv: v.Get("uniform4iv").Call("bind", v),
|
||||
fnUniformMatrix2fv: v.Get("uniformMatrix2fv").Call("bind", v),
|
||||
fnUniformMatrix3fv: v.Get("uniformMatrix3fv").Call("bind", v),
|
||||
fnUniformMatrix4fv: v.Get("uniformMatrix4fv").Call("bind", v),
|
||||
@ -582,6 +588,16 @@ func (c *defaultContext) Uniform2fv(location int32, value []float32) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform2iv(location int32, value []int32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryInt32Array(len(value), value)
|
||||
if c.webGL2 {
|
||||
c.fnUniform2iv.Invoke(l, arr, 0, len(value))
|
||||
} else {
|
||||
c.fnUniform2iv.Invoke(l, arr.Call("subarray", 0, len(value)))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform3fv(location int32, value []float32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryFloat32Array(len(value), value)
|
||||
@ -592,6 +608,16 @@ func (c *defaultContext) Uniform3fv(location int32, value []float32) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform3iv(location int32, value []int32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryInt32Array(len(value), value)
|
||||
if c.webGL2 {
|
||||
c.fnUniform3iv.Invoke(l, arr, 0, len(value))
|
||||
} else {
|
||||
c.fnUniform3iv.Invoke(l, arr.Call("subarray", 0, len(value)))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform4fv(location int32, value []float32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryFloat32Array(len(value), value)
|
||||
@ -602,6 +628,16 @@ func (c *defaultContext) Uniform4fv(location int32, value []float32) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform4iv(location int32, value []int32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryInt32Array(len(value), value)
|
||||
if c.webGL2 {
|
||||
c.fnUniform4iv.Invoke(l, arr, 0, len(value))
|
||||
} else {
|
||||
c.fnUniform4iv.Invoke(l, arr.Call("subarray", 0, len(value)))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *defaultContext) UniformMatrix2fv(location int32, value []float32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryFloat32Array(len(value), value)
|
||||
|
@ -86,8 +86,11 @@ type defaultContext struct {
|
||||
gpUniform1i uintptr
|
||||
gpUniform1iv uintptr
|
||||
gpUniform2fv uintptr
|
||||
gpUniform2iv uintptr
|
||||
gpUniform3fv uintptr
|
||||
gpUniform3iv uintptr
|
||||
gpUniform4fv uintptr
|
||||
gpUniform4iv uintptr
|
||||
gpUniformMatrix2fv uintptr
|
||||
gpUniformMatrix3fv uintptr
|
||||
gpUniformMatrix4fv uintptr
|
||||
@ -406,16 +409,31 @@ func (c *defaultContext) Uniform2fv(location int32, value []float32) {
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform2iv(location int32, value []int32) {
|
||||
purego.SyscallN(c.gpUniform2iv, uintptr(location), uintptr(len(value)/2), uintptr(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform3fv(location int32, value []float32) {
|
||||
purego.SyscallN(c.gpUniform3fv, uintptr(location), uintptr(len(value)/3), uintptr(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform3iv(location int32, value []int32) {
|
||||
purego.SyscallN(c.gpUniform3iv, uintptr(location), uintptr(len(value)/3), uintptr(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform4fv(location int32, value []float32) {
|
||||
purego.SyscallN(c.gpUniform4fv, uintptr(location), uintptr(len(value)/4), uintptr(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform4iv(location int32, value []int32) {
|
||||
purego.SyscallN(c.gpUniform4iv, uintptr(location), uintptr(len(value)/4), uintptr(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) UniformMatrix2fv(location int32, value []float32) {
|
||||
purego.SyscallN(c.gpUniformMatrix2fv, uintptr(location), uintptr(len(value)/4), 0, uintptr(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
@ -652,14 +670,26 @@ func (c *defaultContext) LoadFunctions() error {
|
||||
if c.gpUniform2fv == 0 {
|
||||
return errors.New("gl: glUniform2fv is missing")
|
||||
}
|
||||
c.gpUniform2iv = c.getProcAddress("glUniform2iv")
|
||||
if c.gpUniform2iv == 0 {
|
||||
return errors.New("gl: glUniform2iv is missing")
|
||||
}
|
||||
c.gpUniform3fv = c.getProcAddress("glUniform3fv")
|
||||
if c.gpUniform3fv == 0 {
|
||||
return errors.New("gl: glUniform3fv is missing")
|
||||
}
|
||||
c.gpUniform3iv = c.getProcAddress("glUniform3iv")
|
||||
if c.gpUniform3iv == 0 {
|
||||
return errors.New("gl: glUniform3iv is missing")
|
||||
}
|
||||
c.gpUniform4fv = c.getProcAddress("glUniform4fv")
|
||||
if c.gpUniform4fv == 0 {
|
||||
return errors.New("gl: glUniform4fv is missing")
|
||||
}
|
||||
c.gpUniform4iv = c.getProcAddress("glUniform4iv")
|
||||
if c.gpUniform4iv == 0 {
|
||||
return errors.New("gl: glUniform4iv is missing")
|
||||
}
|
||||
c.gpUniformMatrix2fv = c.getProcAddress("glUniformMatrix2fv")
|
||||
if c.gpUniformMatrix2fv == 0 {
|
||||
return errors.New("gl: glUniformMatrix2fv is missing")
|
||||
|
@ -287,14 +287,26 @@ func (g *gomobileContext) Uniform2fv(location int32, value []float32) {
|
||||
g.ctx.Uniform2fv(gl.Uniform{Value: location}, value)
|
||||
}
|
||||
|
||||
func (g *gomobileContext) Uniform2iv(location int32, value []int32) {
|
||||
g.ctx.Uniform2iv(gl.Uniform{Value: location}, value)
|
||||
}
|
||||
|
||||
func (g *gomobileContext) Uniform3fv(location int32, value []float32) {
|
||||
g.ctx.Uniform3fv(gl.Uniform{Value: location}, value)
|
||||
}
|
||||
|
||||
func (g *gomobileContext) Uniform3iv(location int32, value []int32) {
|
||||
g.ctx.Uniform3iv(gl.Uniform{Value: location}, value)
|
||||
}
|
||||
|
||||
func (g *gomobileContext) Uniform4fv(location int32, value []float32) {
|
||||
g.ctx.Uniform4fv(gl.Uniform{Value: location}, value)
|
||||
}
|
||||
|
||||
func (g *gomobileContext) Uniform4iv(location int32, value []int32) {
|
||||
g.ctx.Uniform4iv(gl.Uniform{Value: location}, value)
|
||||
}
|
||||
|
||||
func (g *gomobileContext) UniformMatrix2fv(location int32, value []float32) {
|
||||
g.ctx.UniformMatrix2fv(gl.Uniform{Value: location}, value)
|
||||
}
|
||||
|
@ -83,8 +83,11 @@ type Context interface {
|
||||
Uniform1i(location int32, v0 int32)
|
||||
Uniform1iv(location int32, value []int32)
|
||||
Uniform2fv(location int32, value []float32)
|
||||
Uniform2iv(location int32, value []int32)
|
||||
Uniform3fv(location int32, value []float32)
|
||||
Uniform3iv(location int32, value []int32)
|
||||
Uniform4fv(location int32, value []float32)
|
||||
Uniform4iv(location int32, value []int32)
|
||||
UniformMatrix2fv(location int32, value []float32)
|
||||
UniformMatrix3fv(location int32, value []float32)
|
||||
UniformMatrix4fv(location int32, value []float32)
|
||||
|
@ -54,6 +54,34 @@ func isModAvailableForConsts(lhs, rhs *shaderir.Expr) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func isValidForModOp(lhs, rhs *shaderir.Expr, lhst, rhst shaderir.Type) bool {
|
||||
isInt := func(s *shaderir.Expr, t shaderir.Type) bool {
|
||||
if t.Main == shaderir.Int {
|
||||
return true
|
||||
}
|
||||
if s.Const == nil {
|
||||
return false
|
||||
}
|
||||
if s.ConstType == shaderir.ConstTypeInt {
|
||||
return true
|
||||
}
|
||||
if canTruncateToInteger(s.Const) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if isInt(lhs, lhst) {
|
||||
return isInt(rhs, rhst)
|
||||
}
|
||||
|
||||
if lhst.Main == shaderir.IVec2 || lhst.Main == shaderir.IVec3 || lhst.Main == shaderir.IVec4 {
|
||||
return lhst.Equal(&rhst) || isInt(rhs, rhst)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func canApplyBinaryOp(lhs, rhs *shaderir.Expr, lhst, rhst shaderir.Type, op shaderir.Op) bool {
|
||||
if op == shaderir.AndAnd || op == shaderir.OrOr {
|
||||
return lhst.Main == shaderir.Bool && rhst.Main == shaderir.Bool
|
||||
@ -289,6 +317,11 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), e.Op, rhst.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
case shaderir.IVec2, shaderir.IVec3, shaderir.IVec4:
|
||||
if !canTruncateToInteger(lhs[0].Const) {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), e.Op, rhst.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
case shaderir.Int:
|
||||
if !canTruncateToInteger(lhs[0].Const) {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("constant %s truncated to integer", lhs[0].Const.String()))
|
||||
@ -310,6 +343,11 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), e.Op, rhst.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
case shaderir.IVec2, shaderir.IVec3, shaderir.IVec4:
|
||||
if !canTruncateToInteger(rhs[0].Const) {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("types don't match: %s %s %s", lhst.String(), e.Op, rhst.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
case shaderir.Int:
|
||||
if !canTruncateToInteger(rhs[0].Const) {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("constant %s truncated to integer", rhs[0].Const.String()))
|
||||
@ -368,9 +406,7 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
|
||||
// For `%`, both types must be deducible to integers.
|
||||
if op == shaderir.ModOp {
|
||||
// TODO: What about ivec?
|
||||
if lhst.Main != shaderir.Int && (lhs[0].ConstType == shaderir.ConstTypeNone || !canTruncateToInteger(lhs[0].Const)) ||
|
||||
rhst.Main != shaderir.Int && (rhs[0].ConstType == shaderir.ConstTypeNone || !canTruncateToInteger(rhs[0].Const)) {
|
||||
if !isValidForModOp(&lhs[0], &rhs[0], lhst, rhst) {
|
||||
var wrongType shaderir.Type
|
||||
if lhst.Main != shaderir.Int {
|
||||
wrongType = lhst
|
||||
@ -527,6 +563,24 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
t = shaderir.Type{Main: shaderir.Vec4}
|
||||
case shaderir.IVec2F:
|
||||
if err := checkArgsForVec2BuiltinFunc(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 {
|
||||
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 {
|
||||
cs.addError(e.Pos(), err.Error())
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
t = shaderir.Type{Main: shaderir.IVec4}
|
||||
case shaderir.Mat2F:
|
||||
if err := checkArgsForMat2BuiltinFunc(args, argts); err != nil {
|
||||
cs.addError(e.Pos(), err.Error())
|
||||
@ -901,16 +955,31 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
}
|
||||
|
||||
var t shaderir.Type
|
||||
switch len(e.Sel.Name) {
|
||||
case 1:
|
||||
t.Main = shaderir.Float
|
||||
case 2:
|
||||
t.Main = shaderir.Vec2
|
||||
case 3:
|
||||
t.Main = shaderir.Vec3
|
||||
case 4:
|
||||
t.Main = shaderir.Vec4
|
||||
default:
|
||||
switch types[0].Main {
|
||||
case shaderir.Vec2, shaderir.Vec3, shaderir.Vec4:
|
||||
switch len(e.Sel.Name) {
|
||||
case 1:
|
||||
t.Main = shaderir.Float
|
||||
case 2:
|
||||
t.Main = shaderir.Vec2
|
||||
case 3:
|
||||
t.Main = shaderir.Vec3
|
||||
case 4:
|
||||
t.Main = shaderir.Vec4
|
||||
}
|
||||
case shaderir.IVec2, shaderir.IVec3, shaderir.IVec4:
|
||||
switch len(e.Sel.Name) {
|
||||
case 1:
|
||||
t.Main = shaderir.Int
|
||||
case 2:
|
||||
t.Main = shaderir.IVec2
|
||||
case 3:
|
||||
t.Main = shaderir.IVec3
|
||||
case 4:
|
||||
t.Main = shaderir.IVec4
|
||||
}
|
||||
}
|
||||
if t.Equal(&shaderir.Type{}) {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("unexpected swizzling: %s", e.Sel.Name))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
@ -1064,6 +1133,8 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
switch t.Main {
|
||||
case shaderir.Vec2, shaderir.Vec3, shaderir.Vec4:
|
||||
typ = shaderir.Type{Main: shaderir.Float}
|
||||
case shaderir.IVec2, shaderir.IVec3, shaderir.IVec4:
|
||||
typ = shaderir.Type{Main: shaderir.Int}
|
||||
case shaderir.Mat2:
|
||||
typ = shaderir.Type{Main: shaderir.Vec2}
|
||||
case shaderir.Mat3:
|
||||
@ -1099,11 +1170,11 @@ func isValidSwizzling(swizzling string, t shaderir.Type) bool {
|
||||
}
|
||||
|
||||
switch t.Main {
|
||||
case shaderir.Vec2:
|
||||
case shaderir.Vec2, shaderir.IVec2:
|
||||
return !strings.ContainsAny(swizzling, "zwbarq")
|
||||
case shaderir.Vec3:
|
||||
case shaderir.Vec3, shaderir.IVec3:
|
||||
return !strings.ContainsAny(swizzling, "waq")
|
||||
case shaderir.Vec4:
|
||||
case shaderir.Vec4, shaderir.IVec4:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
@ -104,9 +104,15 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
|
||||
}
|
||||
} else {
|
||||
switch lts[0].Main {
|
||||
case shaderir.Int:
|
||||
if !cs.forceToInt(stmt, &rhs[0]) {
|
||||
return nil, false
|
||||
case shaderir.Int, shaderir.IVec2, shaderir.IVec3, shaderir.IVec4:
|
||||
if rts[0].Main != shaderir.Int {
|
||||
if !rts[0].Equal(&shaderir.Type{}) {
|
||||
cs.addError(stmt.Pos(), fmt.Sprintf("invalid operation: mismatched types %s and %s", lts[0].String(), rts[0].String()))
|
||||
return nil, false
|
||||
}
|
||||
if !cs.forceToInt(stmt, &rhs[0]) {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
case shaderir.Float:
|
||||
if rhs[0].Const != nil &&
|
||||
@ -151,7 +157,7 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
|
||||
}
|
||||
}
|
||||
|
||||
if op == shaderir.ModOp && lts[0].Main != shaderir.Int {
|
||||
if op == shaderir.ModOp && lts[0].Main != shaderir.Int && lts[0].Main != shaderir.IVec2 && lts[0].Main != shaderir.IVec3 && lts[0].Main != shaderir.IVec4 {
|
||||
cs.addError(stmt.Pos(), fmt.Sprintf("invalid operation: operator %% not defined on %s", lts[0].String()))
|
||||
return nil, false
|
||||
}
|
||||
|
@ -974,6 +974,14 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := ivec2(1) + 2
|
||||
return vec4(a.xxyy)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
@ -983,6 +991,14 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := ivec2(1) + 2.1
|
||||
return vec4(a.xxyy)
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
@ -992,6 +1008,14 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := ivec2(1) % 2
|
||||
return vec4(a.xxyy)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
@ -1001,6 +1025,14 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := ivec2(1) % 2.1
|
||||
return vec4(a.xxyy)
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
@ -1011,6 +1043,15 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := ivec2(1)
|
||||
a += 2
|
||||
return vec4(a.xxyy)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
@ -1021,6 +1062,15 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := ivec2(1)
|
||||
a += 2.1
|
||||
return vec4(a.xxyy)
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
@ -1031,6 +1081,15 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := ivec2(1)
|
||||
a %= 2
|
||||
return vec4(a.xxyy)
|
||||
}`)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
@ -1038,6 +1097,15 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := vec2(1)
|
||||
a %= 2.1
|
||||
return a.xxyy
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
if _, err := compileToIR([]byte(`package main
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
a := ivec2(1)
|
||||
a %= 2.1
|
||||
return vec4(a.xxyy)
|
||||
}`)); err == nil {
|
||||
t.Errorf("error must be non-nil but was nil")
|
||||
}
|
||||
@ -1054,14 +1122,37 @@ func TestSyntaxOperatorMultiply(t *testing.T) {
|
||||
{stmt: "a := 1 * vec2(2); _ = a", err: false},
|
||||
{stmt: "a := int(1) * vec2(2); _ = a", err: true},
|
||||
{stmt: "a := 1.0 * vec2(2); _ = a", err: false},
|
||||
{stmt: "a := 1.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 := 1.0 / vec2(2); _ = a", err: false},
|
||||
{stmt: "a := 1.1 / vec2(2); _ = a", err: false},
|
||||
{stmt: "a := 1.0 + vec2(2); _ = a", err: false},
|
||||
{stmt: "a := 1.1 + vec2(2); _ = a", err: false},
|
||||
{stmt: "a := 1 * vec3(2); _ = a", err: false},
|
||||
{stmt: "a := 1.0 * vec3(2); _ = a", err: false},
|
||||
{stmt: "a := 1.1 * vec3(2); _ = a", err: false},
|
||||
{stmt: "a := 1 * vec4(2); _ = a", err: false},
|
||||
{stmt: "a := 1.0 * vec4(2); _ = a", err: false},
|
||||
{stmt: "a := 1.1 * vec4(2); _ = a", err: false},
|
||||
|
||||
{stmt: "a := 1 * ivec2(2); _ = a", err: false},
|
||||
{stmt: "a := int(1) * ivec2(2); _ = a", err: false},
|
||||
{stmt: "a := 1.0 * ivec2(2); _ = a", err: false},
|
||||
{stmt: "a := 1.1 * ivec2(2); _ = a", err: true},
|
||||
{stmt: "a := 1 + ivec2(2); _ = a", err: false},
|
||||
{stmt: "a := int(1) + ivec2(2); _ = a", err: false},
|
||||
{stmt: "a := 1.0 / ivec2(2); _ = a", err: false},
|
||||
{stmt: "a := 1.1 / ivec2(2); _ = a", err: true},
|
||||
{stmt: "a := 1.0 + ivec2(2); _ = a", err: false},
|
||||
{stmt: "a := 1.1 + ivec2(2); _ = a", err: true},
|
||||
{stmt: "a := 1 * ivec3(2); _ = a", err: false},
|
||||
{stmt: "a := 1.0 * ivec3(2); _ = a", err: false},
|
||||
{stmt: "a := 1.1 * ivec3(2); _ = a", err: true},
|
||||
{stmt: "a := 1 * ivec4(2); _ = a", err: false},
|
||||
{stmt: "a := 1.0 * ivec4(2); _ = a", err: false},
|
||||
{stmt: "a := 1.1 * ivec4(2); _ = a", err: true},
|
||||
|
||||
{stmt: "a := 1 * mat2(2); _ = a", err: false},
|
||||
{stmt: "a := 1.0 * mat2(2); _ = a", err: false},
|
||||
{stmt: "a := float(1.0) / mat2(2); _ = a", err: true},
|
||||
@ -1072,30 +1163,67 @@ func TestSyntaxOperatorMultiply(t *testing.T) {
|
||||
{stmt: "a := 1.0 * mat3(2); _ = a", err: false},
|
||||
{stmt: "a := 1 * 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.0; _ = a", err: false},
|
||||
{stmt: "a := vec2(1) * 2.1; _ = a", err: false},
|
||||
{stmt: "a := vec2(1) / 2.0; _ = a", err: false},
|
||||
{stmt: "a := vec2(1) / 2.1; _ = a", err: false},
|
||||
{stmt: "a := vec2(1) + 2.0; _ = a", err: false},
|
||||
{stmt: "a := vec2(1) + 2.1; _ = a", err: false},
|
||||
{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) * vec3(2); _ = a", err: true},
|
||||
{stmt: "a := vec2(1) * vec4(2); _ = a", err: true},
|
||||
{stmt: "a := vec2(1) * ivec2(2); _ = a", err: true},
|
||||
{stmt: "a := vec2(1) + ivec2(2); _ = a", err: true},
|
||||
{stmt: "a := vec2(1) * ivec3(2); _ = a", err: true},
|
||||
{stmt: "a := vec2(1) * ivec4(2); _ = a", err: true},
|
||||
{stmt: "a := vec2(1) * mat2(2); _ = a", err: false},
|
||||
{stmt: "a := vec2(1) + mat2(2); _ = a", err: true},
|
||||
{stmt: "a := vec2(1) * mat3(2); _ = a", err: true},
|
||||
{stmt: "a := vec2(1) * mat4(2); _ = a", err: true},
|
||||
|
||||
{stmt: "a := ivec2(1) * 2; _ = a", err: false},
|
||||
{stmt: "a := ivec2(1) * 2.0; _ = a", err: false},
|
||||
{stmt: "a := ivec2(1) * 2.1; _ = a", err: true},
|
||||
{stmt: "a := ivec2(1) / 2.0; _ = a", err: false},
|
||||
{stmt: "a := ivec2(1) / 2.1; _ = a", err: true},
|
||||
{stmt: "a := ivec2(1) + 2.0; _ = a", err: false},
|
||||
{stmt: "a := ivec2(1) + 2.1; _ = a", err: true},
|
||||
{stmt: "a := ivec2(1) * int(2); _ = a", err: false},
|
||||
{stmt: "a := ivec2(1) * vec2(2); _ = a", err: true},
|
||||
{stmt: "a := ivec2(1) + vec2(2); _ = a", err: true},
|
||||
{stmt: "a := ivec2(1) * vec3(2); _ = a", err: true},
|
||||
{stmt: "a := ivec2(1) * vec4(2); _ = a", err: true},
|
||||
{stmt: "a := ivec2(1) * ivec2(2); _ = a", err: false},
|
||||
{stmt: "a := ivec2(1) + ivec2(2); _ = a", err: false},
|
||||
{stmt: "a := ivec2(1) * ivec3(2); _ = a", err: true},
|
||||
{stmt: "a := ivec2(1) * ivec4(2); _ = a", err: true},
|
||||
{stmt: "a := ivec2(1) * mat2(2); _ = a", err: true},
|
||||
{stmt: "a := ivec2(1) + mat2(2); _ = a", err: true},
|
||||
{stmt: "a := ivec2(1) * mat3(2); _ = a", err: true},
|
||||
{stmt: "a := ivec2(1) * mat4(2); _ = a", err: true},
|
||||
|
||||
{stmt: "a := mat2(1) * 2; _ = a", err: false},
|
||||
{stmt: "a := mat2(1) * 2.0; _ = a", err: false},
|
||||
{stmt: "a := mat2(1) * 2.1; _ = a", err: false},
|
||||
{stmt: "a := mat2(1) / 2.0; _ = a", err: false},
|
||||
{stmt: "a := mat2(1) / 2.1; _ = 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) + 2.0; _ = a", err: true},
|
||||
{stmt: "a := mat2(1) + 2.1; _ = 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: true},
|
||||
{stmt: "a := mat2(1) * vec3(2); _ = a", err: true},
|
||||
{stmt: "a := mat2(1) * vec4(2); _ = a", err: true},
|
||||
{stmt: "a := mat2(1) * ivec2(2); _ = a", err: true},
|
||||
{stmt: "a := mat2(1) + ivec2(2); _ = a", err: true},
|
||||
{stmt: "a := mat2(1) * ivec3(2); _ = a", err: true},
|
||||
{stmt: "a := mat2(1) * ivec4(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},
|
||||
@ -1117,6 +1245,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
// Issue #1971
|
||||
func TestSyntaxOperatorMultiplyAssign(t *testing.T) {
|
||||
cases := []struct {
|
||||
@ -1135,6 +1265,9 @@ func TestSyntaxOperatorMultiplyAssign(t *testing.T) {
|
||||
{stmt: "a := 1.0; a *= vec2(2)", err: true},
|
||||
{stmt: "a := 1.0; a *= vec3(2)", err: true},
|
||||
{stmt: "a := 1.0; a *= vec4(2)", err: true},
|
||||
{stmt: "a := 1.0; a *= ivec2(2)", err: true},
|
||||
{stmt: "a := 1.0; a *= ivec3(2)", err: true},
|
||||
{stmt: "a := 1.0; a *= ivec4(2)", err: true},
|
||||
{stmt: "a := 1.0; a *= mat2(2)", err: true},
|
||||
{stmt: "a := 1.0; a *= mat3(2)", err: true},
|
||||
{stmt: "a := 1.0; a *= mat4(2)", err: true},
|
||||
@ -1156,12 +1289,43 @@ func TestSyntaxOperatorMultiplyAssign(t *testing.T) {
|
||||
{stmt: "a := vec2(1); a += vec2(2)", err: false},
|
||||
{stmt: "a := vec2(1); a *= vec3(2)", err: true},
|
||||
{stmt: "a := vec2(1); a *= vec4(2)", err: true},
|
||||
{stmt: "a := vec2(1); a *= ivec2(2)", err: true},
|
||||
{stmt: "a := vec2(1); a += ivec2(2)", err: true},
|
||||
{stmt: "a := vec2(1); a *= ivec3(2)", err: true},
|
||||
{stmt: "a := vec2(1); a *= ivec4(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 := ivec2(1); a *= 2", err: false},
|
||||
{stmt: "a := ivec2(1); a *= 2.0", err: false},
|
||||
{stmt: "const c = 2; a := ivec2(1); a *= c", err: false},
|
||||
{stmt: "const c = 2.0; a := ivec2(1); a *= c", err: false},
|
||||
{stmt: "const c int = 2; a := ivec2(1); a *= c", err: false},
|
||||
{stmt: "const c int = 2.0; a := ivec2(1); a *= c", err: false},
|
||||
{stmt: "const c float = 2; a := ivec2(1); a *= c", err: true},
|
||||
{stmt: "const c float = 2.0; a := ivec2(1); a *= c", err: true},
|
||||
{stmt: "a := ivec2(1); a /= 2.0", err: false},
|
||||
{stmt: "a := ivec2(1); a += 2.0", err: false},
|
||||
{stmt: "a := ivec2(1); a *= int(2)", err: false},
|
||||
{stmt: "a := ivec2(1); a *= float(2)", err: true},
|
||||
{stmt: "a := ivec2(1); a /= float(2)", err: true},
|
||||
{stmt: "a := ivec2(1); a *= vec2(2)", err: true},
|
||||
{stmt: "a := ivec2(1); a += vec2(2)", err: true},
|
||||
{stmt: "a := ivec2(1); a *= vec3(2)", err: true},
|
||||
{stmt: "a := ivec2(1); a *= vec4(2)", err: true},
|
||||
{stmt: "a := ivec2(1); a *= ivec2(2)", err: false},
|
||||
{stmt: "a := ivec2(1); a += ivec2(2)", err: false},
|
||||
{stmt: "a := ivec2(1); a *= ivec3(2)", err: true},
|
||||
{stmt: "a := ivec2(1); a *= ivec4(2)", err: true},
|
||||
{stmt: "a := ivec2(1); a *= mat2(2)", err: true},
|
||||
{stmt: "a := ivec2(1); a += mat2(2)", err: true},
|
||||
{stmt: "a := ivec2(1); a /= mat2(2)", err: true},
|
||||
{stmt: "a := ivec2(1); a *= mat3(2)", err: true},
|
||||
{stmt: "a := ivec2(1); a *= mat4(2)", err: true},
|
||||
|
||||
{stmt: "a := mat2(1); a *= 2", err: false},
|
||||
{stmt: "a := mat2(1); a *= 2.0", err: false},
|
||||
{stmt: "const c = 2; a := mat2(1); a *= c", err: false},
|
||||
@ -1179,6 +1343,10 @@ func TestSyntaxOperatorMultiplyAssign(t *testing.T) {
|
||||
{stmt: "a := mat2(1); a += vec2(2)", err: true},
|
||||
{stmt: "a := mat2(1); a *= vec3(2)", err: true},
|
||||
{stmt: "a := mat2(1); a *= vec4(2)", err: true},
|
||||
{stmt: "a := mat2(1); a *= ivec2(2)", err: true},
|
||||
{stmt: "a := mat2(1); a += ivec2(2)", err: true},
|
||||
{stmt: "a := mat2(1); a *= ivec3(2)", err: true},
|
||||
{stmt: "a := mat2(1); a *= ivec4(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},
|
||||
@ -1437,9 +1605,12 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
{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},
|
||||
{stmt: "a := vec2(ivec2(1)); _ = a", err: false},
|
||||
{stmt: "a := vec2(ivec3(1)); _ = a", err: true},
|
||||
|
||||
{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.0; a := vec2(i, i); _ = a", err: false},
|
||||
{stmt: "a := vec2(vec2(1), 1); _ = a", err: true},
|
||||
@ -1449,18 +1620,25 @@ 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.0; a := vec3(i); _ = a", err: false},
|
||||
{stmt: "a := vec3(vec3(1)); _ = a", err: false},
|
||||
{stmt: "a := vec3(vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := vec3(vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := vec3(ivec3(1)); _ = a", err: false},
|
||||
{stmt: "a := vec3(ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := vec3(ivec4(1)); _ = a", err: true},
|
||||
|
||||
{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.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(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},
|
||||
@ -1473,32 +1651,122 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
{stmt: "a := vec4(vec4(1)); _ = a", err: false},
|
||||
{stmt: "a := vec4(vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := vec4(vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := vec4(ivec4(1)); _ = a", err: false},
|
||||
{stmt: "a := vec4(ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := vec4(ivec3(1)); _ = a", err: true},
|
||||
|
||||
{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.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(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(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(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},
|
||||
{stmt: "a := vec4(1, 1, 1, 1, 1); _ = a", err: true},
|
||||
|
||||
{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: "a := ivec2(vec2(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec2(vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec2(ivec2(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec2(ivec3(1)); _ = a", err: true},
|
||||
|
||||
{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: "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},
|
||||
{stmt: "a := ivec2(1, ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec2(ivec2(1), ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec2(1, 1, 1); _ = a", err: true},
|
||||
|
||||
{stmt: "a := ivec3(1); _ = a", err: false},
|
||||
{stmt: "a := ivec3(1.0); _ = a", err: false},
|
||||
{stmt: "a := ivec3(1.1); _ = a", err: false},
|
||||
{stmt: "i := 1; a := ivec3(i); _ = a", err: false},
|
||||
{stmt: "i := 1.0; a := ivec3(i); _ = a", err: false},
|
||||
{stmt: "a := ivec3(vec3(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec3(vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec3(vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec3(ivec3(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec3(ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec3(ivec4(1)); _ = a", err: true},
|
||||
|
||||
{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: "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: "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},
|
||||
{stmt: "a := ivec3(1, vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec3(vec3(1), vec3(1), vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec3(1, 1, 1, 1); _ = a", err: true},
|
||||
|
||||
{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: "a := ivec4(vec4(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec4(vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec4(vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec4(ivec4(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec4(ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec4(ivec3(1)); _ = a", err: true},
|
||||
|
||||
{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: "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: "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(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(ivec3(1), 1); _ = a", err: false},
|
||||
{stmt: "a := ivec4(1, ivec3(1)); _ = a", err: false},
|
||||
{stmt: "a := ivec4(vec4(1), 1); _ = a", err: true},
|
||||
{stmt: "a := ivec4(1, vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec4(vec4(1), vec4(1), vec4(1), vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := ivec4(1, 1, 1, 1, 1); _ = a", err: true},
|
||||
|
||||
{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.0; a := mat2(i); _ = a", err: false},
|
||||
{stmt: "a := mat2(mat2(1)); _ = a", err: false},
|
||||
{stmt: "a := mat2(vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := mat2(ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := mat2(mat3(1)); _ = a", err: true},
|
||||
{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(1, 1); _ = a", err: true},
|
||||
{stmt: "a := mat2(1, vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := mat2(vec2(1), vec3(1)); _ = a", err: true},
|
||||
@ -1521,10 +1789,12 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
{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},
|
||||
{stmt: "a := mat3(ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := mat3(mat2(1)); _ = a", err: true},
|
||||
{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(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},
|
||||
@ -1547,10 +1817,12 @@ func TestSyntaxConstructorFuncType(t *testing.T) {
|
||||
{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},
|
||||
{stmt: "a := mat4(ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := mat4(mat2(1)); _ = a", err: true},
|
||||
{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(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},
|
||||
@ -1636,6 +1908,9 @@ func TestSyntaxBuiltinFuncSingleArgType(t *testing.T) {
|
||||
{stmt: "a := {{.Func}}(vec2(1)); _ = a", err: false},
|
||||
{stmt: "a := {{.Func}}(vec3(1)); _ = a", err: false},
|
||||
{stmt: "a := {{.Func}}(vec4(1)); _ = a", err: false},
|
||||
{stmt: "a := {{.Func}}(ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(ivec3(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(ivec4(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(mat2(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(mat3(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(mat4(1)); _ = a", err: true},
|
||||
@ -1714,6 +1989,8 @@ func TestSyntaxBuiltinFuncDoubleArgsType(t *testing.T) {
|
||||
{stmt: "a := {{.Func}}(vec4(1), vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(vec4(1), vec4(1)); _ = a", err: false},
|
||||
{stmt: "a := {{.Func}}(mat2(1), mat2(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(ivec2(1), 1); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(ivec2(1), ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(1, 1, 1); _ = a", err: true},
|
||||
}
|
||||
|
||||
@ -1759,6 +2036,9 @@ func TestSyntaxBuiltinFuncDoubleArgsType2(t *testing.T) {
|
||||
{stmt: "a := {{.Func}}(1, vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(1, vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(1, vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(1, ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(1, ivec3(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(1, ivec4(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(vec2(1), 1); _ = a", err: false}, // The second argument can be a scalar.
|
||||
{stmt: "a := {{.Func}}(vec2(1), vec2(1)); _ = a", err: false},
|
||||
{stmt: "a := {{.Func}}(vec2(1), vec3(1)); _ = a", err: true},
|
||||
@ -1772,6 +2052,8 @@ func TestSyntaxBuiltinFuncDoubleArgsType2(t *testing.T) {
|
||||
{stmt: "a := {{.Func}}(vec4(1), vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(vec4(1), vec4(1)); _ = a", err: false},
|
||||
{stmt: "a := {{.Func}}(mat2(1), mat2(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(ivec2(1), 1); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(ivec2(1), ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(1, 1, 1); _ = a", err: true},
|
||||
}
|
||||
|
||||
@ -1815,6 +2097,9 @@ func TestSyntaxBuiltinFuncStepType(t *testing.T) {
|
||||
{stmt: "a := step(1, vec2(1)); _ = a", err: false}, // The first argument can be a scalar.
|
||||
{stmt: "a := step(1, vec3(1)); _ = a", err: false}, // The first argument can be a scalar.
|
||||
{stmt: "a := step(1, vec4(1)); _ = a", err: false}, // The first argument can be a scalar.
|
||||
{stmt: "a := step(1, ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := step(1, ivec3(1)); _ = a", err: true},
|
||||
{stmt: "a := step(1, ivec4(1)); _ = a", err: true},
|
||||
{stmt: "a := step(vec2(1), 1); _ = a", err: true},
|
||||
{stmt: "a := step(vec2(1), vec2(1)); _ = a", err: false},
|
||||
{stmt: "a := step(vec2(1), vec3(1)); _ = a", err: true},
|
||||
@ -1828,6 +2113,7 @@ func TestSyntaxBuiltinFuncStepType(t *testing.T) {
|
||||
{stmt: "a := step(vec4(1), vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := step(vec4(1), vec4(1)); _ = a", err: false},
|
||||
{stmt: "a := step(mat2(1), mat2(1)); _ = a", err: true},
|
||||
{stmt: "a := step(ivec2(1), ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := step(1, 1, 1); _ = a", err: true},
|
||||
}
|
||||
|
||||
@ -1879,7 +2165,7 @@ func TestSyntaxBuiltinFuncTripleArgsType(t *testing.T) {
|
||||
{stmt: "a := {{.Func}}(vec4(1), 1, vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(vec4(1), vec4(1), 1); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(vec4(1), vec4(1), vec4(1)); _ = a", err: false},
|
||||
{stmt: "a := {{.Func}}(1, 1, 1, 1); _ = a", err: true},
|
||||
{stmt: "a := {{.Func}}(ivec2(1), ivec2(1), ivec2(1)); _ = a", err: true},
|
||||
}
|
||||
|
||||
funcs := []string{
|
||||
@ -1935,6 +2221,7 @@ func TestSyntaxBuiltinFuncClampType(t *testing.T) {
|
||||
{stmt: "a := clamp(vec4(1), 1, vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := clamp(vec4(1), vec4(1), 1); _ = a", err: true},
|
||||
{stmt: "a := clamp(vec4(1), vec4(1), vec4(1)); _ = a", err: false},
|
||||
{stmt: "a := clamp(ivec2(1), 1, 1); _ = a", err: true},
|
||||
{stmt: "a := clamp(1, 1, 1, 1); _ = a", err: true},
|
||||
}
|
||||
|
||||
@ -1986,6 +2273,8 @@ func TestSyntaxBuiltinFuncMixType(t *testing.T) {
|
||||
{stmt: "a := mix(vec4(1), 1, vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := mix(vec4(1), vec4(1), 1); _ = a", err: false}, // The thrid argument can be a float.
|
||||
{stmt: "a := mix(vec4(1), vec4(1), vec4(1)); _ = a", err: false},
|
||||
{stmt: "a := mix(ivec2(1), ivec2(1), 1); _ = a", err: true},
|
||||
{stmt: "a := mix(ivec2(1), ivec2(1), ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := mix(1, 1, 1, 1); _ = a", err: true},
|
||||
}
|
||||
|
||||
@ -2039,6 +2328,9 @@ func TestSyntaxBuiltinFuncSmoothstepType(t *testing.T) {
|
||||
{stmt: "a := smoothstep(vec4(1), 1, vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := smoothstep(vec4(1), vec4(1), 1); _ = a", err: true},
|
||||
{stmt: "a := smoothstep(vec4(1), vec4(1), vec4(1)); _ = a", err: false},
|
||||
{stmt: "a := smoothstep(ivec2(1), 1, 1); _ = a", err: true},
|
||||
{stmt: "a := smoothstep(1, ivec2(1), 1); _ = a", err: true},
|
||||
{stmt: "a := smoothstep(1, 1, ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := smoothstep(1, 1, 1, 1); _ = a", err: true},
|
||||
}
|
||||
|
||||
@ -2090,6 +2382,7 @@ func TestSyntaxBuiltinFuncRefractType(t *testing.T) {
|
||||
{stmt: "a := refract(vec4(1), 1, vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := refract(vec4(1), vec4(1), 1); _ = a", err: false}, // The third argument must be a float.
|
||||
{stmt: "a := refract(vec4(1), vec4(1), vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := refract(ivec2(1), ivec2(1), 1); _ = a", err: true},
|
||||
{stmt: "a := refract(1, 1, 1, 1); _ = a", err: true},
|
||||
}
|
||||
|
||||
@ -2139,6 +2432,7 @@ func TestSyntaxBuiltinFuncCrossType(t *testing.T) {
|
||||
{stmt: "a := cross(vec4(1), vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := cross(vec4(1), vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := cross(mat2(1), mat2(1)); _ = a", err: true},
|
||||
{stmt: "a := cross(ivec3(1), ivec3(1)); _ = a", err: true},
|
||||
{stmt: "a := cross(1, 1, 1); _ = a", err: true},
|
||||
}
|
||||
|
||||
@ -2173,6 +2467,9 @@ func TestSyntaxBuiltinFuncTransposeType(t *testing.T) {
|
||||
{stmt: "a := transpose(vec2(1)); _ = a", err: true},
|
||||
{stmt: "a := transpose(vec3(1)); _ = a", err: true},
|
||||
{stmt: "a := transpose(vec4(1)); _ = a", err: true},
|
||||
{stmt: "a := transpose(ivec2(1)); _ = a", err: true},
|
||||
{stmt: "a := transpose(ivec3(1)); _ = a", err: true},
|
||||
{stmt: "a := transpose(ivec4(1)); _ = a", err: true},
|
||||
{stmt: "a := transpose(mat2(1)); _ = a", err: false},
|
||||
{stmt: "a := transpose(mat3(1)); _ = a", err: false},
|
||||
{stmt: "a := transpose(mat4(1)); _ = a", err: false},
|
||||
@ -2220,6 +2517,8 @@ func TestSyntaxEqual(t *testing.T) {
|
||||
{stmt: "a, b := false, 1.1; _ = a != b", err: true},
|
||||
{stmt: "a, b := false, vec2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := false, vec2(1); _ = a != b", err: true},
|
||||
{stmt: "a, b := false, ivec2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := false, ivec2(1); _ = a != b", err: true},
|
||||
{stmt: "a, b := false, mat2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := false, mat2(1); _ = a != b", err: true},
|
||||
|
||||
@ -2241,6 +2540,8 @@ func TestSyntaxEqual(t *testing.T) {
|
||||
{stmt: "a, b := 1, 1.1; _ = a != b", err: true},
|
||||
{stmt: "a, b := 1, vec2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := 1, vec2(1); _ = a != b", err: true},
|
||||
{stmt: "a, b := 1, ivec2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := 1, ivec2(1); _ = a != b", err: true},
|
||||
{stmt: "a, b := 1, mat2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := 1, mat2(1); _ = a != b", err: true},
|
||||
|
||||
@ -2262,6 +2563,8 @@ func TestSyntaxEqual(t *testing.T) {
|
||||
{stmt: "a, b := 1.0, 1.1; _ = a != b", err: false},
|
||||
{stmt: "a, b := 1.0, vec2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := 1.0, vec2(1); _ = a != b", err: true},
|
||||
{stmt: "a, b := 1.0, ivec2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := 1.0, ivec2(1); _ = a != b", err: true},
|
||||
{stmt: "a, b := 1.0, mat2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := 1.0, mat2(1); _ = a != b", err: true},
|
||||
|
||||
@ -2283,6 +2586,8 @@ func TestSyntaxEqual(t *testing.T) {
|
||||
{stmt: "a, b := 1.1, 1.1; _ = a != b", err: false},
|
||||
{stmt: "a, b := 1.1, vec2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := 1.1, vec2(1); _ = a != b", err: true},
|
||||
{stmt: "a, b := 1.1, ivec2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := 1.1, ivec2(1); _ = a != b", err: true},
|
||||
{stmt: "a, b := 1.1, mat2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := 1.1, mat2(1); _ = a != b", err: true},
|
||||
|
||||
@ -2304,9 +2609,34 @@ func TestSyntaxEqual(t *testing.T) {
|
||||
{stmt: "a, b := vec2(1), 1.1; _ = a != b", err: true},
|
||||
{stmt: "a, b := vec2(1), vec2(1); _ = a == b", err: false},
|
||||
{stmt: "a, b := vec2(1), vec2(1); _ = a != b", err: false},
|
||||
{stmt: "a, b := vec2(1), ivec2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := vec2(1), ivec2(1); _ = a != b", err: true},
|
||||
{stmt: "a, b := vec2(1), mat2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := vec2(1), mat2(1); _ = a != b", err: true},
|
||||
|
||||
{stmt: "_ = ivec2(1) == true", err: true},
|
||||
{stmt: "_ = ivec2(1) != true", err: true},
|
||||
{stmt: "_ = ivec2(1) == 1", err: true},
|
||||
{stmt: "_ = ivec2(1) != 1", err: true},
|
||||
{stmt: "_ = ivec2(1) == 1.0", err: true},
|
||||
{stmt: "_ = ivec2(1) != 1.0", err: true},
|
||||
{stmt: "_ = ivec2(1) == 1.1", err: true},
|
||||
{stmt: "_ = ivec2(1) != 1.1", err: true},
|
||||
{stmt: "a, b := ivec2(1), true; _ = a == b", err: true},
|
||||
{stmt: "a, b := ivec2(1), true; _ = a != b", err: true},
|
||||
{stmt: "a, b := ivec2(1), 1; _ = a == b", err: true},
|
||||
{stmt: "a, b := ivec2(1), 1; _ = a != b", err: true},
|
||||
{stmt: "a, b := ivec2(1), 1.0; _ = a == b", err: true},
|
||||
{stmt: "a, b := ivec2(1), 1.0; _ = a != b", err: true},
|
||||
{stmt: "a, b := ivec2(1), 1.1; _ = a == b", err: true},
|
||||
{stmt: "a, b := ivec2(1), 1.1; _ = a != b", err: true},
|
||||
{stmt: "a, b := ivec2(1), vec2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := ivec2(1), vec2(1); _ = a != b", err: true},
|
||||
{stmt: "a, b := ivec2(1), ivec2(1); _ = a == b", err: false},
|
||||
{stmt: "a, b := ivec2(1), ivec2(1); _ = a != b", err: false},
|
||||
{stmt: "a, b := ivec2(1), mat2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := ivec2(1), mat2(1); _ = a != b", err: true},
|
||||
|
||||
{stmt: "_ = mat2(1) == true", err: true},
|
||||
{stmt: "_ = mat2(1) != true", err: true},
|
||||
{stmt: "_ = mat2(1) == 1", err: true},
|
||||
@ -2325,6 +2655,8 @@ func TestSyntaxEqual(t *testing.T) {
|
||||
{stmt: "a, b := mat2(1), 1.1; _ = a != b", err: true},
|
||||
{stmt: "a, b := mat2(1), vec2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := mat2(1), vec2(1); _ = a != b", err: true},
|
||||
{stmt: "a, b := mat2(1), ivec2(1); _ = a == b", err: true},
|
||||
{stmt: "a, b := mat2(1), ivec2(1); _ = a != b", err: true},
|
||||
{stmt: "a, b := mat2(1), mat2(1); _ = a == b", err: true}, // Comparing matrices are not allowed.
|
||||
{stmt: "a, b := mat2(1), mat2(1); _ = a != b", err: true}, // Comparing matrices are not allowed.
|
||||
|
||||
@ -2346,6 +2678,8 @@ func TestSyntaxEqual(t *testing.T) {
|
||||
{stmt: "a, b := false, 1.1; _ = a || b", err: true},
|
||||
{stmt: "a, b := false, vec2(1); _ = a && b", err: true},
|
||||
{stmt: "a, b := false, vec2(1); _ = a || b", err: true},
|
||||
{stmt: "a, b := false, ivec2(1); _ = a && b", err: true},
|
||||
{stmt: "a, b := false, ivec2(1); _ = a || b", err: true},
|
||||
{stmt: "a, b := false, mat2(1); _ = a && b", err: true},
|
||||
{stmt: "a, b := false, mat2(1); _ = a || b", err: true},
|
||||
|
||||
@ -2367,6 +2701,8 @@ func TestSyntaxEqual(t *testing.T) {
|
||||
{stmt: "a, b := 1.0, 1.1; _ = a || b", err: true},
|
||||
{stmt: "a, b := 1.0, vec2(1); _ = a && b", err: true},
|
||||
{stmt: "a, b := 1.0, vec2(1); _ = a || b", err: true},
|
||||
{stmt: "a, b := 1.0, ivec2(1); _ = a && b", err: true},
|
||||
{stmt: "a, b := 1.0, ivec2(1); _ = a || b", err: true},
|
||||
{stmt: "a, b := 1.0, mat2(1); _ = a && b", err: true},
|
||||
{stmt: "a, b := 1.0, mat2(1); _ = a || b", err: true},
|
||||
}
|
||||
@ -2453,6 +2789,39 @@ func TestSwizzling(t *testing.T) {
|
||||
{stmt: "var a vec4; var b vec3 = a.xyy; _ = b", err: false},
|
||||
{stmt: "var a vec4; var b vec3 = a.xyz; _ = b", err: false},
|
||||
{stmt: "var a vec4; var b vec4 = a.xyzw; _ = b", err: false},
|
||||
|
||||
{stmt: "var a ivec2; var b int = a.x; _ = b", err: false},
|
||||
{stmt: "var a ivec2; var b int = a.y; _ = b", err: false},
|
||||
{stmt: "var a ivec2; var b int = a.z; _ = b", err: true},
|
||||
{stmt: "var a ivec2; var b int = a.w; _ = b", err: true},
|
||||
{stmt: "var a ivec2; var b ivec2 = a.xy; _ = b", err: false},
|
||||
{stmt: "var a ivec2; var b ivec3 = a.xyz; _ = b", err: true},
|
||||
{stmt: "var a ivec2; var b ivec3 = a.xyw; _ = b", err: true},
|
||||
{stmt: "var a ivec2; var b ivec3 = a.xyy; _ = b", err: false},
|
||||
{stmt: "var a ivec2; var b ivec3 = a.xyz; _ = b", err: true},
|
||||
{stmt: "var a ivec2; var b ivec4 = a.xyzw; _ = b", err: true},
|
||||
|
||||
{stmt: "var a ivec3; var b int = a.x; _ = b", err: false},
|
||||
{stmt: "var a ivec3; var b int = a.y; _ = b", err: false},
|
||||
{stmt: "var a ivec3; var b int = a.z; _ = b", err: false},
|
||||
{stmt: "var a ivec3; var b int = a.w; _ = b", err: true},
|
||||
{stmt: "var a ivec3; var b ivec2 = a.xy; _ = b", err: false},
|
||||
{stmt: "var a ivec3; var b ivec3 = a.xyz; _ = b", err: false},
|
||||
{stmt: "var a ivec3; var b ivec3 = a.xyw; _ = b", err: true},
|
||||
{stmt: "var a ivec3; var b ivec3 = a.xyy; _ = b", err: false},
|
||||
{stmt: "var a ivec3; var b ivec3 = a.xyz; _ = b", err: false},
|
||||
{stmt: "var a ivec3; var b ivec4 = a.xyzw; _ = b", err: true},
|
||||
|
||||
{stmt: "var a ivec4; var b int = a.x; _ = b", err: false},
|
||||
{stmt: "var a ivec4; var b int = a.y; _ = b", err: false},
|
||||
{stmt: "var a ivec4; var b int = a.z; _ = b", err: false},
|
||||
{stmt: "var a ivec4; var b int = a.w; _ = b", err: false},
|
||||
{stmt: "var a ivec4; var b ivec2 = a.xy; _ = b", err: false},
|
||||
{stmt: "var a ivec4; var b ivec3 = a.xyz; _ = b", err: false},
|
||||
{stmt: "var a ivec4; var b ivec3 = a.xyw; _ = b", err: false},
|
||||
{stmt: "var a ivec4; var b ivec3 = a.xyy; _ = b", err: false},
|
||||
{stmt: "var a ivec4; var b ivec3 = a.xyz; _ = b", err: false},
|
||||
{stmt: "var a ivec4; var b ivec4 = a.xyzw; _ = b", err: false},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
@ -2482,84 +2851,105 @@ func TestConstType(t *testing.T) {
|
||||
{stmt: "const a int = false", err: true},
|
||||
{stmt: "const a float = false", err: true},
|
||||
{stmt: "const a vec2 = false", err: true},
|
||||
{stmt: "const a ivec2 = false", err: true},
|
||||
|
||||
{stmt: "const a = bool(false)", err: false},
|
||||
{stmt: "const a bool = bool(false)", err: false},
|
||||
{stmt: "const a int = bool(false)", err: true},
|
||||
{stmt: "const a float = bool(false)", err: true},
|
||||
{stmt: "const a vec2 = bool(false)", err: true},
|
||||
{stmt: "const a ivec2 = bool(false)", err: true},
|
||||
|
||||
{stmt: "const a = int(false)", err: true},
|
||||
{stmt: "const a bool = int(false)", err: true},
|
||||
{stmt: "const a int = int(false)", err: true},
|
||||
{stmt: "const a float = int(false)", err: true},
|
||||
{stmt: "const a vec2 = int(false)", err: true},
|
||||
{stmt: "const a ivec2 = int(false)", err: true},
|
||||
|
||||
{stmt: "const a = float(false)", err: true},
|
||||
{stmt: "const a bool = float(false)", err: true},
|
||||
{stmt: "const a int = float(false)", err: true},
|
||||
{stmt: "const a float = float(false)", err: true},
|
||||
{stmt: "const a vec2 = float(false)", err: true},
|
||||
{stmt: "const a ivec2 = float(false)", err: true},
|
||||
|
||||
{stmt: "const a = 1", err: false},
|
||||
{stmt: "const a bool = 1", err: true},
|
||||
{stmt: "const a int = 1", err: false},
|
||||
{stmt: "const a float = 1", err: false},
|
||||
{stmt: "const a vec2 = 1", err: true},
|
||||
{stmt: "const a ivec2 = 1", err: true},
|
||||
|
||||
{stmt: "const a = int(1)", err: false},
|
||||
{stmt: "const a bool = int(1)", err: true},
|
||||
{stmt: "const a int = int(1)", err: false},
|
||||
{stmt: "const a float = int(1)", err: true},
|
||||
{stmt: "const a vec2 = int(1)", err: true},
|
||||
{stmt: "const a ivec2 = int(1)", err: true},
|
||||
|
||||
{stmt: "const a = float(1)", err: false},
|
||||
{stmt: "const a bool = float(1)", err: true},
|
||||
{stmt: "const a int = float(1)", err: true},
|
||||
{stmt: "const a float = float(1)", err: false},
|
||||
{stmt: "const a vec2 = float(1)", err: true},
|
||||
{stmt: "const a ivec2 = float(1)", err: true},
|
||||
|
||||
{stmt: "const a = 1.0", err: false},
|
||||
{stmt: "const a bool = 1.0", err: true},
|
||||
{stmt: "const a int = 1.0", err: false},
|
||||
{stmt: "const a float = 1.0", err: false},
|
||||
{stmt: "const a vec2 = 1.0", err: true},
|
||||
{stmt: "const a ivec2 = 1.0", err: true},
|
||||
|
||||
{stmt: "const a = int(1.0)", err: false},
|
||||
{stmt: "const a bool = int(1.0)", err: true},
|
||||
{stmt: "const a int = int(1.0)", err: false},
|
||||
{stmt: "const a float = int(1.0)", err: true},
|
||||
{stmt: "const a vec2 = int(1.0)", err: true},
|
||||
{stmt: "const a ivec2 = int(1.0)", err: true},
|
||||
|
||||
{stmt: "const a = float(1.0)", err: false},
|
||||
{stmt: "const a bool = float(1.0)", err: true},
|
||||
{stmt: "const a int = float(1.0)", err: true},
|
||||
{stmt: "const a float = float(1.0)", err: false},
|
||||
{stmt: "const a vec2 = float(1.0)", err: true},
|
||||
{stmt: "const a ivec2 = float(1.0)", err: true},
|
||||
|
||||
{stmt: "const a = 1.1", err: false},
|
||||
{stmt: "const a bool = 1.1", err: true},
|
||||
{stmt: "const a int = 1.1", err: true},
|
||||
{stmt: "const a float = 1.1", err: false},
|
||||
{stmt: "const a vec2 = 1.1", err: true},
|
||||
{stmt: "const a ivec2 = 1.1", err: true},
|
||||
|
||||
{stmt: "const a = int(1.1)", err: true},
|
||||
{stmt: "const a bool = int(1.1)", err: true},
|
||||
{stmt: "const a int = int(1.1)", err: true},
|
||||
{stmt: "const a float = int(1.1)", err: true},
|
||||
{stmt: "const a vec2 = int(1.1)", err: true},
|
||||
{stmt: "const a ivec2 = int(1.1)", err: true},
|
||||
|
||||
{stmt: "const a = float(1.1)", err: false},
|
||||
{stmt: "const a bool = float(1.1)", err: true},
|
||||
{stmt: "const a int = float(1.1)", err: true},
|
||||
{stmt: "const a float = float(1.1)", err: false},
|
||||
{stmt: "const a vec2 = float(1.1)", err: true},
|
||||
{stmt: "const a ivec2 = float(1.1)", err: true},
|
||||
|
||||
{stmt: "const a = vec2(0)", err: true},
|
||||
{stmt: "const a bool = vec2(0)", err: true},
|
||||
{stmt: "const a int = vec2(0)", err: true},
|
||||
{stmt: "const a float = vec2(0)", err: true},
|
||||
{stmt: "const a vec2 = vec2(0)", err: true},
|
||||
{stmt: "const a ivec2 = vec2(0)", err: true},
|
||||
|
||||
{stmt: "const a = ivec2(0)", err: true},
|
||||
{stmt: "const a bool = ivec2(0)", err: true},
|
||||
{stmt: "const a int = ivec2(0)", err: true},
|
||||
{stmt: "const a float = ivec2(0)", err: true},
|
||||
{stmt: "const a vec2 = ivec2(0)", err: true},
|
||||
{stmt: "const a ivec2 = ivec2(0)", err: true},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
|
@ -39,6 +39,12 @@ func (cs *compileState) parseType(block *block, fname string, expr ast.Expr) (sh
|
||||
return shaderir.Type{Main: shaderir.Vec3}, true
|
||||
case "vec4":
|
||||
return shaderir.Type{Main: shaderir.Vec4}, true
|
||||
case "ivec2":
|
||||
return shaderir.Type{Main: shaderir.IVec2}, true
|
||||
case "ivec3":
|
||||
return shaderir.Type{Main: shaderir.IVec3}, true
|
||||
case "ivec4":
|
||||
return shaderir.Type{Main: shaderir.IVec4}, true
|
||||
case "mat2":
|
||||
return shaderir.Type{Main: shaderir.Mat2}, true
|
||||
case "mat3":
|
||||
@ -177,7 +183,7 @@ func checkArgsForVec2BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
||||
return nil
|
||||
}
|
||||
if argts[0].Main == shaderir.Vec2 {
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 {
|
||||
return nil
|
||||
}
|
||||
case 2:
|
||||
@ -205,14 +211,14 @@ func checkArgsForVec3BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
||||
return nil
|
||||
}
|
||||
if argts[0].Main == shaderir.Vec3 {
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 3 {
|
||||
return nil
|
||||
}
|
||||
case 2:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && argts[1].Main == shaderir.Vec2 {
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && argts[1].IsVector() && argts[1].VectorElementCount() == 2 {
|
||||
return nil
|
||||
}
|
||||
if argts[0].Main == shaderir.Vec2 && canBeFloatImplicitly(args[1], argts[1]) {
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 && canBeFloatImplicitly(args[1], argts[1]) {
|
||||
return nil
|
||||
}
|
||||
case 3:
|
||||
@ -240,27 +246,27 @@ func checkArgsForVec4BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
||||
if canBeFloatImplicitly(args[0], argts[0]) {
|
||||
return nil
|
||||
}
|
||||
if argts[0].Main == shaderir.Vec4 {
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 4 {
|
||||
return nil
|
||||
}
|
||||
case 2:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && argts[1].Main == shaderir.Vec3 {
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && argts[1].IsVector() && argts[1].VectorElementCount() == 3 {
|
||||
return nil
|
||||
}
|
||||
if argts[0].Main == shaderir.Vec2 && argts[1].Main == shaderir.Vec2 {
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 && argts[1].IsVector() && argts[1].VectorElementCount() == 2 {
|
||||
return nil
|
||||
}
|
||||
if argts[0].Main == shaderir.Vec3 && canBeFloatImplicitly(args[1], argts[1]) {
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 3 && canBeFloatImplicitly(args[1], argts[1]) {
|
||||
return nil
|
||||
}
|
||||
case 3:
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && canBeFloatImplicitly(args[1], argts[1]) && argts[2].Main == shaderir.Vec2 {
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && canBeFloatImplicitly(args[1], argts[1]) && argts[2].IsVector() && argts[2].VectorElementCount() == 2 {
|
||||
return nil
|
||||
}
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && argts[1].Main == shaderir.Vec2 && canBeFloatImplicitly(args[2], argts[2]) {
|
||||
if canBeFloatImplicitly(args[0], argts[0]) && argts[1].IsVector() && argts[1].VectorElementCount() == 2 && canBeFloatImplicitly(args[2], argts[2]) {
|
||||
return nil
|
||||
}
|
||||
if argts[0].Main == shaderir.Vec2 && canBeFloatImplicitly(args[1], argts[1]) && canBeFloatImplicitly(args[2], argts[2]) {
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 && canBeFloatImplicitly(args[1], argts[1]) && canBeFloatImplicitly(args[2], argts[2]) {
|
||||
return nil
|
||||
}
|
||||
case 4:
|
||||
@ -292,7 +298,7 @@ func checkArgsForMat2BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
||||
return nil
|
||||
}
|
||||
case 2:
|
||||
if argts[0].Main == shaderir.Vec2 && argts[1].Main == shaderir.Vec2 {
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 2 && argts[1].IsVector() && argts[1].VectorElementCount() == 2 {
|
||||
return nil
|
||||
}
|
||||
case 4:
|
||||
@ -331,7 +337,9 @@ func checkArgsForMat3BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
||||
return nil
|
||||
}
|
||||
case 3:
|
||||
if argts[0].Main == shaderir.Vec3 && argts[1].Main == shaderir.Vec3 && argts[2].Main == shaderir.Vec3 {
|
||||
if argts[0].IsVector() && argts[0].VectorElementCount() == 3 &&
|
||||
argts[1].IsVector() && argts[1].VectorElementCount() == 3 &&
|
||||
argts[2].IsVector() && argts[2].VectorElementCount() == 3 {
|
||||
return nil
|
||||
}
|
||||
case 9:
|
||||
@ -370,7 +378,10 @@ func checkArgsForMat4BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) er
|
||||
return nil
|
||||
}
|
||||
case 4:
|
||||
if argts[0].Main == shaderir.Vec4 && argts[1].Main == shaderir.Vec4 && argts[2].Main == shaderir.Vec4 && argts[3].Main == shaderir.Vec4 {
|
||||
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 {
|
||||
return nil
|
||||
}
|
||||
case 16:
|
||||
|
@ -164,7 +164,7 @@ func Compile(p *shaderir.Program, version GLSLVersion) (vertexShader, fragmentSh
|
||||
}
|
||||
str := fmt.Sprintf("U%d[%d]", i, t.Length-1)
|
||||
switch t.Sub[0].Main {
|
||||
case shaderir.Vec2, shaderir.Vec3, shaderir.Vec4:
|
||||
case shaderir.Vec2, shaderir.Vec3, shaderir.Vec4, shaderir.IVec2, shaderir.IVec3, shaderir.IVec4:
|
||||
str += ".x"
|
||||
case shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
||||
str += "[0][0]"
|
||||
@ -325,7 +325,9 @@ func (c *compileContext) varInit(p *shaderir.Program, t *shaderir.Type) string {
|
||||
return "false"
|
||||
case shaderir.Int:
|
||||
return "0"
|
||||
case shaderir.Float, shaderir.Vec2, shaderir.Vec3, shaderir.Vec4, shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
||||
case shaderir.Float, shaderir.Vec2, shaderir.Vec3, shaderir.Vec4,
|
||||
shaderir.IVec2, shaderir.IVec3, shaderir.IVec4,
|
||||
shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
||||
return fmt.Sprintf("%s(0)", basicTypeString(t.Main))
|
||||
default:
|
||||
t0, t1 := c.typ(p, t)
|
||||
|
@ -92,6 +92,12 @@ func basicTypeString(t shaderir.BasicType) string {
|
||||
return "vec3"
|
||||
case shaderir.Vec4:
|
||||
return "vec4"
|
||||
case shaderir.IVec2:
|
||||
return "ivec2"
|
||||
case shaderir.IVec3:
|
||||
return "ivec3"
|
||||
case shaderir.IVec4:
|
||||
return "ivec4"
|
||||
case shaderir.Mat2:
|
||||
return "mat2"
|
||||
case shaderir.Mat3:
|
||||
|
@ -215,7 +215,7 @@ func (c *compileContext) varInit(p *shaderir.Program, t *shaderir.Type) string {
|
||||
panic("not implemented")
|
||||
case shaderir.Bool:
|
||||
return "false"
|
||||
case shaderir.Int:
|
||||
case shaderir.Int, shaderir.IVec2, shaderir.IVec3, shaderir.IVec4:
|
||||
return "0"
|
||||
case shaderir.Float, shaderir.Vec2, shaderir.Vec3, shaderir.Vec4, shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
||||
return "0.0"
|
||||
@ -404,7 +404,7 @@ func (c *compileContext) block(p *shaderir.Program, topBlock, block *shaderir.Bl
|
||||
}
|
||||
if callee.Type == shaderir.BuiltinFuncExpr {
|
||||
switch callee.BuiltinFunc {
|
||||
case shaderir.Vec2F, shaderir.Vec3F, shaderir.Vec4F:
|
||||
case shaderir.Vec2F, shaderir.Vec3F, shaderir.Vec4F, shaderir.IVec2F, shaderir.IVec3F, shaderir.IVec4F:
|
||||
if len(args) == 1 {
|
||||
// Use casting. For example, `float4(1)` doesn't work.
|
||||
return fmt.Sprintf("(%s)(%s)", expr(&e.Exprs[0]), args[0])
|
||||
|
@ -46,19 +46,19 @@ func calculateMemoryOffsets(uniforms []shaderir.Type) []int {
|
||||
case shaderir.Int:
|
||||
offsets = append(offsets, head)
|
||||
head += 4
|
||||
case shaderir.Vec2:
|
||||
case shaderir.Vec2, shaderir.IVec2:
|
||||
if head%boundaryInBytes >= 4*3 {
|
||||
head = align(head)
|
||||
}
|
||||
offsets = append(offsets, head)
|
||||
head += 4 * 2
|
||||
case shaderir.Vec3:
|
||||
case shaderir.Vec3, shaderir.IVec3:
|
||||
if head%boundaryInBytes >= 4*2 {
|
||||
head = align(head)
|
||||
}
|
||||
offsets = append(offsets, head)
|
||||
head += 4 * 3
|
||||
case shaderir.Vec4:
|
||||
case shaderir.Vec4, shaderir.IVec4:
|
||||
if head%boundaryInBytes >= 4*1 {
|
||||
head = align(head)
|
||||
}
|
||||
|
@ -92,6 +92,12 @@ func basicTypeString(t shaderir.BasicType) string {
|
||||
return "float3"
|
||||
case shaderir.Vec4:
|
||||
return "float4"
|
||||
case shaderir.IVec2:
|
||||
return "int2"
|
||||
case shaderir.IVec3:
|
||||
return "int3"
|
||||
case shaderir.IVec4:
|
||||
return "int4"
|
||||
case shaderir.Mat2:
|
||||
return "float2x2"
|
||||
case shaderir.Mat3:
|
||||
@ -115,6 +121,12 @@ func (c *compileContext) builtinFuncString(f shaderir.BuiltinFunc) string {
|
||||
return "float3"
|
||||
case shaderir.Vec4F:
|
||||
return "float4"
|
||||
case shaderir.IVec2F:
|
||||
return "int2"
|
||||
case shaderir.IVec3F:
|
||||
return "int3"
|
||||
case shaderir.IVec4F:
|
||||
return "int4"
|
||||
case shaderir.Mat2F:
|
||||
return "float2x2"
|
||||
case shaderir.Mat3F:
|
||||
|
@ -203,7 +203,9 @@ func (c *compileContext) varInit(p *shaderir.Program, t *shaderir.Type) string {
|
||||
return "false"
|
||||
case shaderir.Int:
|
||||
return "0"
|
||||
case shaderir.Float, shaderir.Vec2, shaderir.Vec3, shaderir.Vec4, shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
||||
case shaderir.Float, shaderir.Vec2, shaderir.Vec3, shaderir.Vec4,
|
||||
shaderir.IVec2, shaderir.IVec3, shaderir.IVec4,
|
||||
shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
||||
return fmt.Sprintf("%s(0)", basicTypeString(t.Main))
|
||||
default:
|
||||
t := c.typ(p, t)
|
||||
|
@ -100,6 +100,12 @@ func basicTypeString(t shaderir.BasicType) string {
|
||||
return "float3"
|
||||
case shaderir.Vec4:
|
||||
return "float4"
|
||||
case shaderir.IVec2:
|
||||
return "int2"
|
||||
case shaderir.IVec3:
|
||||
return "int3"
|
||||
case shaderir.IVec4:
|
||||
return "int4"
|
||||
case shaderir.Mat2:
|
||||
return "float2x2"
|
||||
case shaderir.Mat3:
|
||||
@ -129,6 +135,12 @@ func builtinFuncString(f shaderir.BuiltinFunc) string {
|
||||
return "float3"
|
||||
case shaderir.Vec4F:
|
||||
return "float4"
|
||||
case shaderir.IVec2F:
|
||||
return "int2"
|
||||
case shaderir.IVec3F:
|
||||
return "int3"
|
||||
case shaderir.IVec4F:
|
||||
return "int4"
|
||||
case shaderir.Mat2F:
|
||||
return "float2x2"
|
||||
case shaderir.Mat3F:
|
||||
|
@ -224,6 +224,9 @@ const (
|
||||
Vec2F BuiltinFunc = "vec2"
|
||||
Vec3F BuiltinFunc = "vec3"
|
||||
Vec4F BuiltinFunc = "vec4"
|
||||
IVec2F BuiltinFunc = "ivec2"
|
||||
IVec3F BuiltinFunc = "ivec3"
|
||||
IVec4F BuiltinFunc = "ivec4"
|
||||
Mat2F BuiltinFunc = "mat2"
|
||||
Mat3F BuiltinFunc = "mat3"
|
||||
Mat4F BuiltinFunc = "mat4"
|
||||
@ -281,6 +284,9 @@ func ParseBuiltinFunc(str string) (BuiltinFunc, bool) {
|
||||
Vec2F,
|
||||
Vec3F,
|
||||
Vec4F,
|
||||
IVec2F,
|
||||
IVec3F,
|
||||
IVec4F,
|
||||
Mat2F,
|
||||
Mat3F,
|
||||
Mat4F,
|
||||
|
@ -59,6 +59,12 @@ func (t *Type) String() string {
|
||||
return "vec3"
|
||||
case Vec4:
|
||||
return "vec4"
|
||||
case IVec2:
|
||||
return "ivec2"
|
||||
case IVec3:
|
||||
return "ivec3"
|
||||
case IVec4:
|
||||
return "ivec4"
|
||||
case Mat2:
|
||||
return "mat2"
|
||||
case Mat3:
|
||||
@ -93,6 +99,12 @@ func (t *Type) Uint32Count() int {
|
||||
return 3
|
||||
case Vec4:
|
||||
return 4
|
||||
case IVec2:
|
||||
return 2
|
||||
case IVec3:
|
||||
return 3
|
||||
case IVec4:
|
||||
return 4
|
||||
case Mat2:
|
||||
return 4
|
||||
case Mat3:
|
||||
@ -108,12 +120,31 @@ func (t *Type) Uint32Count() int {
|
||||
|
||||
func (t *Type) IsVector() bool {
|
||||
switch t.Main {
|
||||
case Vec2, Vec3, Vec4:
|
||||
case Vec2, Vec3, Vec4, IVec2, IVec3, IVec4:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *Type) VectorElementCount() int {
|
||||
switch t.Main {
|
||||
case Vec2:
|
||||
return 2
|
||||
case Vec3:
|
||||
return 3
|
||||
case Vec4:
|
||||
return 4
|
||||
case IVec2:
|
||||
return 2
|
||||
case IVec3:
|
||||
return 3
|
||||
case IVec4:
|
||||
return 4
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Type) IsMatrix() bool {
|
||||
switch t.Main {
|
||||
case Mat2, Mat3, Mat4:
|
||||
@ -132,6 +163,9 @@ const (
|
||||
Vec2
|
||||
Vec3
|
||||
Vec4
|
||||
IVec2
|
||||
IVec3
|
||||
IVec4
|
||||
Mat2
|
||||
Mat3
|
||||
Mat4
|
||||
|
@ -1293,6 +1293,16 @@ var U [4]int
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
return vec4(float(U[0])/255.0, float(U[1])/255.0, float(U[2])/255.0, float(U[3])/255.0)
|
||||
}
|
||||
`
|
||||
|
||||
const intVec = `package main
|
||||
|
||||
var U0 ivec4
|
||||
var U1 [2]ivec3
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
return vec4(float(U0.x)/255.0, float(U0.y)/255.0, float(U1[0].z)/255.0, float(U1[1].x)/255.0)
|
||||
}
|
||||
`
|
||||
|
||||
testCases := []struct {
|
||||
@ -1382,6 +1392,57 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
Shader: intArray,
|
||||
Want: color.RGBA{0x85, 0xa3, 0x08, 0xd3},
|
||||
},
|
||||
{
|
||||
Name: "0xff,array",
|
||||
Uniforms: map[string]any{
|
||||
"U": [...]int{0xff, 0xff, 0xff, 0xff},
|
||||
},
|
||||
Shader: intArray,
|
||||
Want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
||||
},
|
||||
{
|
||||
Name: "int,array",
|
||||
Uniforms: map[string]any{
|
||||
"U": [...]int16{0x24, 0x3f, 0x6a, 0x88},
|
||||
},
|
||||
Shader: intArray,
|
||||
Want: color.RGBA{0x24, 0x3f, 0x6a, 0x88},
|
||||
},
|
||||
{
|
||||
Name: "uint,array",
|
||||
Uniforms: map[string]any{
|
||||
"U": [...]uint8{0x85, 0xa3, 0x08, 0xd3},
|
||||
},
|
||||
Shader: intArray,
|
||||
Want: color.RGBA{0x85, 0xa3, 0x08, 0xd3},
|
||||
},
|
||||
{
|
||||
Name: "0xff,ivec",
|
||||
Uniforms: map[string]any{
|
||||
"U0": [...]int{0xff, 0xff, 0xff, 0xff},
|
||||
"U1": [...]int{0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
},
|
||||
Shader: intVec,
|
||||
Want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
||||
},
|
||||
{
|
||||
Name: "int,ivec",
|
||||
Uniforms: map[string]any{
|
||||
"U0": [...]int16{0x24, 0x3f, 0x6a, 0x88},
|
||||
"U1": [...]int16{0x85, 0xa3, 0x08, 0xd3, 0x13, 0x19},
|
||||
},
|
||||
Shader: intVec,
|
||||
Want: color.RGBA{0x24, 0x3f, 0x08, 0xd3},
|
||||
},
|
||||
{
|
||||
Name: "uint,ivec",
|
||||
Uniforms: map[string]any{
|
||||
"U0": [...]uint8{0x24, 0x3f, 0x6a, 0x88},
|
||||
"U1": [...]uint8{0x85, 0xa3, 0x08, 0xd3, 0x13, 0x19},
|
||||
},
|
||||
Shader: intVec,
|
||||
Want: color.RGBA{0x24, 0x3f, 0x08, 0xd3},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
@ -1408,7 +1469,7 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
}
|
||||
|
||||
// Issue #2463
|
||||
func TestShaderVec3Array(t *testing.T) {
|
||||
func TestShaderUniformVec3Array(t *testing.T) {
|
||||
const shader = `package main
|
||||
|
||||
var U [4]vec3
|
||||
|
Loading…
Reference in New Issue
Block a user