updated ebiten version from 2.7.9 to 2.9.9
This commit is contained in:
+137
-43
@@ -88,6 +88,10 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
stmts = append(stmts, ss...)
|
||||
if len(ts) == 0 {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("unexpected binary operator: %s", e.Y))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
rhst := ts[0]
|
||||
|
||||
op := e.Op
|
||||
@@ -199,7 +203,7 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
for _, expr := range es {
|
||||
if expr.Type == shaderir.FunctionExpr {
|
||||
if expr.Type == shaderir.FunctionExpr || expr.Type == shaderir.BuiltinFuncExpr {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("function name cannot be an argument: %s", e.Fun))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
@@ -417,6 +421,16 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
finalType = shaderir.Type{Main: shaderir.Vec4}
|
||||
case shaderir.FrontFacing:
|
||||
if len(args) != 0 {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("number of %s's arguments must be 0 but %d", callee.BuiltinFunc, len(args)))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
if fname != cs.fragmentEntry {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("frontfacing is available only in %s", cs.fragmentEntry))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
finalType = shaderir.Type{Main: shaderir.Bool}
|
||||
case shaderir.DiscardF:
|
||||
if len(args) != 0 {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("number of %s's arguments must be 0 but %d", callee.BuiltinFunc, len(args)))
|
||||
@@ -430,7 +444,6 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
Type: shaderir.Discard,
|
||||
})
|
||||
return nil, nil, stmts, true
|
||||
|
||||
case shaderir.Clamp, shaderir.Mix, shaderir.Smoothstep, shaderir.Faceforward, shaderir.Refract:
|
||||
// 3 arguments
|
||||
if len(args) != 3 {
|
||||
@@ -571,22 +584,65 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
finalType = argts[0]
|
||||
}
|
||||
|
||||
case shaderir.Atan2, shaderir.Pow, shaderir.Mod, shaderir.Min, shaderir.Max, shaderir.Step, shaderir.Distance, shaderir.Dot, shaderir.Cross, shaderir.Reflect:
|
||||
// 2 arguments
|
||||
if len(args) != 2 {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("number of %s's arguments must be 2 but %d", callee.BuiltinFunc, len(args)))
|
||||
case shaderir.Min, shaderir.Max:
|
||||
if len(args) < 1 {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("number of %s's arguments must be 1 or more but %d", callee.BuiltinFunc, len(args)))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
|
||||
switch callee.BuiltinFunc {
|
||||
case shaderir.Min, shaderir.Max:
|
||||
var hasVectors bool
|
||||
var hasScalars bool
|
||||
for i := range argts {
|
||||
if argts[i].IsFloatVector() || argts[i].IsIntVector() {
|
||||
hasVectors = true
|
||||
continue
|
||||
}
|
||||
if argts[i].Main == shaderir.Float || argts[i].Main == shaderir.Int || argts[i].Main == shaderir.None {
|
||||
hasScalars = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve the constant values.
|
||||
if hasVectors && hasScalars {
|
||||
// Vector values and scalar values are mixed. Resolve the constant kind based on the first vector argument.
|
||||
if argts[0].IsIntVector() {
|
||||
for i := 1; i < len(args); i++ {
|
||||
if args[i].Const != nil {
|
||||
v := gconstant.ToInt(args[i].Const)
|
||||
if v.Kind() == gconstant.Unknown {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type int", args[i].Const.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
args[i].Const = v
|
||||
argts[i] = shaderir.Type{Main: shaderir.Int}
|
||||
}
|
||||
}
|
||||
} else if argts[0].IsFloatVector() {
|
||||
for i := 1; i < len(args); i++ {
|
||||
if args[i].Const != nil {
|
||||
v := gconstant.ToFloat(args[i].Const)
|
||||
if v.Kind() == gconstant.Unknown {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type float", args[i].Const.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
args[i].Const = v
|
||||
argts[i] = shaderir.Type{Main: shaderir.Float}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as vecN or ivecN value in argument to %s", argts[0].String(), callee.BuiltinFunc))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
} else {
|
||||
// Vector values and scalar values are not mixed. Resolve the constant kind based on all the arguments.
|
||||
if kind, _ := resolveConstKind(args, argts); kind != gconstant.Unknown {
|
||||
switch kind {
|
||||
case gconstant.Int:
|
||||
for i, arg := range args {
|
||||
if arg.Const == nil {
|
||||
if argts[i].Main != shaderir.Int {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("%s's arguments don't match: %s and %s", callee.BuiltinFunc, argts[0].String(), argts[1].String()))
|
||||
cs.addError(e.Pos(), fmt.Sprintf("%s's arguments must all be compatible types but got %s", callee.BuiltinFunc, argts[i].String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
continue
|
||||
@@ -603,7 +659,7 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
for i, arg := range args {
|
||||
if arg.Const == nil {
|
||||
if argts[i].Main != shaderir.Float {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("%s's arguments don't match: %s and %s", callee.BuiltinFunc, argts[0].String(), argts[1].String()))
|
||||
cs.addError(e.Pos(), fmt.Sprintf("%s's arguments must all be compatible types but got %s", callee.BuiltinFunc, argts[i].String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
continue
|
||||
@@ -618,25 +674,45 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if argts[0].IsIntVector() && args[1].Const != nil {
|
||||
v := gconstant.ToInt(args[1].Const)
|
||||
if v.Kind() == gconstant.Unknown {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type int", args[1].Const.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
args[1].Const = v
|
||||
argts[1] = shaderir.Type{Main: shaderir.Int}
|
||||
for i := range args {
|
||||
if argts[i].Main != shaderir.Float && !argts[i].IsFloatVector() && argts[i].Main != shaderir.Int && !argts[i].IsIntVector() {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as float, vecN, int, or ivecN value in argument to %s", argts[i].String(), callee.BuiltinFunc))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
if argts[0].IsFloatVector() && args[1].Const != nil {
|
||||
v := gconstant.ToFloat(args[1].Const)
|
||||
if v.Kind() == gconstant.Unknown {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("cannot convert %s to type float", args[1].Const.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
|
||||
if len(args) > 1 {
|
||||
baseType := argts[0]
|
||||
for i := 1; i < len(args); i++ {
|
||||
if len(args) == 2 {
|
||||
if !baseType.Equal(&argts[i]) {
|
||||
// Only allow vector + scalar (not scalar + vector)
|
||||
if !((baseType.IsFloatVector() && argts[i].Main == shaderir.Float) || (baseType.IsIntVector() && argts[i].Main == shaderir.Int)) {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("invalid arguments %s and %s for %s", baseType.String(), argts[i].String(), callee.BuiltinFunc))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if !baseType.Equal(&argts[i]) {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("all argument types must be the same but got %s and %s for variadic %s", baseType.String(), argts[i].String(), callee.BuiltinFunc))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
}
|
||||
args[1].Const = v
|
||||
argts[1] = shaderir.Type{Main: shaderir.Float}
|
||||
}
|
||||
}
|
||||
|
||||
finalType = argts[0]
|
||||
|
||||
case shaderir.Atan2, shaderir.Pow, shaderir.Mod, shaderir.Step, shaderir.Distance, shaderir.Dot, shaderir.Cross, shaderir.Reflect:
|
||||
// 2 arguments
|
||||
if len(args) != 2 {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("number of %s's arguments must be 2 but %d", callee.BuiltinFunc, len(args)))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
|
||||
switch callee.BuiltinFunc {
|
||||
default:
|
||||
for i := range args {
|
||||
if args[i].Const != nil && argts[i].Main == shaderir.None {
|
||||
@@ -650,17 +726,9 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
}
|
||||
|
||||
for i := range args {
|
||||
switch callee.BuiltinFunc {
|
||||
case shaderir.Min, shaderir.Max:
|
||||
if argts[i].Main != shaderir.Float && !argts[i].IsFloatVector() && argts[i].Main != shaderir.Int && !argts[i].IsIntVector() {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as float, vecN, int, or ivecN value in argument to %s", argts[i].String(), callee.BuiltinFunc))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
default:
|
||||
if argts[i].Main != shaderir.Float && !argts[i].IsFloatVector() {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as float, vec2, vec3, or vec4 value in argument to %s", argts[i].String(), callee.BuiltinFunc))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
if argts[i].Main != shaderir.Float && !argts[i].IsFloatVector() {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("cannot use %s as float, vec2, vec3, or vec4 value in argument to %s", argts[i].String(), callee.BuiltinFunc))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -670,11 +738,6 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
cs.addError(e.Pos(), fmt.Sprintf("the second argument for %s must equal to the first argument %s or float but %s", callee.BuiltinFunc, argts[0].String(), argts[1].String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
case shaderir.Min, shaderir.Max:
|
||||
if !(argts[0].Equal(&argts[1]) || (argts[0].IsFloatVector() && argts[1].Main == shaderir.Float) || (argts[0].IsIntVector() && argts[1].Main == shaderir.Int)) {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("the second argument for %s must equal to the first argument %s or float or int but %s", callee.BuiltinFunc, argts[0].String(), argts[1].String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
case shaderir.Step:
|
||||
if !argts[0].Equal(&argts[1]) && argts[0].Main != shaderir.Float {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("the first argument for %s must equal to the second argument %s or float but %s", callee.BuiltinFunc, argts[1].String(), argts[0].String()))
|
||||
@@ -1034,8 +1097,14 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
cs.addError(e.Pos(), fmt.Sprintf("invalid composite literal type %s", t.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
if t.Main == shaderir.Array && t.Length == -1 {
|
||||
t.Length = len(e.Elts)
|
||||
if t.Main == shaderir.Array {
|
||||
if t.Length == -1 {
|
||||
t.Length = len(e.Elts)
|
||||
} else if t.Length < len(e.Elts) {
|
||||
// KeyValueExpr is not supported yet. Just compare the length.
|
||||
cs.addError(e.Pos(), fmt.Sprintf("too many values in %s literal", t.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
}
|
||||
|
||||
idx := block.totalLocalVariableCount()
|
||||
@@ -1146,6 +1215,31 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar
|
||||
x := exprs[0]
|
||||
t := ts[0]
|
||||
|
||||
// Check the length only when the index is a constant.
|
||||
if idx.Const != nil {
|
||||
var length int
|
||||
switch {
|
||||
case t.Main == shaderir.Array:
|
||||
length = t.Length
|
||||
case t.IsFloatVector() || t.IsIntVector():
|
||||
length = t.VectorElementCount()
|
||||
case t.IsMatrix():
|
||||
length = t.MatrixSize()
|
||||
default:
|
||||
cs.addError(e.Pos(), fmt.Sprintf("index operator cannot be applied to the type %s", t.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
v, ok := gconstant.Int64Val(gconstant.ToInt(idx.Const))
|
||||
if !ok {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("constant %s cannot be used as an index", idx.Const.String()))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
if v < 0 || int(v) >= length {
|
||||
cs.addError(e.Pos(), fmt.Sprintf("index out of range: %d", v))
|
||||
return nil, nil, nil, false
|
||||
}
|
||||
}
|
||||
|
||||
var typ shaderir.Type
|
||||
switch t.Main {
|
||||
case shaderir.Vec2, shaderir.Vec3, shaderir.Vec4:
|
||||
|
||||
+79
-76
@@ -59,8 +59,6 @@ type compileState struct {
|
||||
|
||||
global block
|
||||
|
||||
varyingParsed bool
|
||||
|
||||
errs []string
|
||||
}
|
||||
|
||||
@@ -202,6 +200,7 @@ func Compile(src []byte, vertexEntry, fragmentEntry string, textureCount int) (*
|
||||
fragmentEntry: fragmentEntry,
|
||||
unit: unit,
|
||||
}
|
||||
s.ir.SourceHash = shaderir.CalcSourceHash(src)
|
||||
s.global.ir = &shaderir.Block{}
|
||||
s.parse(f)
|
||||
|
||||
@@ -291,18 +290,17 @@ func (cs *compileState) parse(f *ast.File) {
|
||||
|
||||
// Parse function names so that any other function call the others.
|
||||
// The function data is provisional and will be updated soon.
|
||||
var vertexInParams []variable
|
||||
var vertexOutParams []variable
|
||||
var fragmentInParams []variable
|
||||
var fragmentOutParams []variable
|
||||
var fragmentReturnType shaderir.Type
|
||||
for _, d := range f.Decls {
|
||||
fd, ok := d.(*ast.FuncDecl)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
n := fd.Name.Name
|
||||
if n == cs.vertexEntry {
|
||||
continue
|
||||
}
|
||||
if n == cs.fragmentEntry {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, f := range cs.funcs {
|
||||
if f.name == n {
|
||||
@@ -312,6 +310,19 @@ func (cs *compileState) parse(f *ast.File) {
|
||||
}
|
||||
|
||||
inParams, outParams, ret := cs.parseFuncParams(&cs.global, n, fd)
|
||||
|
||||
if n == cs.vertexEntry {
|
||||
vertexInParams = inParams
|
||||
vertexOutParams = outParams
|
||||
continue
|
||||
}
|
||||
if n == cs.fragmentEntry {
|
||||
fragmentInParams = inParams
|
||||
fragmentOutParams = outParams
|
||||
fragmentReturnType = ret
|
||||
continue
|
||||
}
|
||||
|
||||
var inT, outT []shaderir.Type
|
||||
for _, v := range inParams {
|
||||
inT = append(inT, v.typ)
|
||||
@@ -319,7 +330,6 @@ func (cs *compileState) parse(f *ast.File) {
|
||||
for _, v := range outParams {
|
||||
outT = append(outT, v.typ)
|
||||
}
|
||||
|
||||
cs.funcs = append(cs.funcs, function{
|
||||
name: n,
|
||||
ir: shaderir.Func{
|
||||
@@ -332,6 +342,45 @@ func (cs *compileState) parse(f *ast.File) {
|
||||
})
|
||||
}
|
||||
|
||||
// Check varying variables.
|
||||
// In testings, there might not be vertex and fragment entry points.
|
||||
if len(vertexOutParams) > 0 && len(fragmentInParams) > 0 {
|
||||
for i, p := range vertexOutParams {
|
||||
if len(fragmentInParams) <= i {
|
||||
break
|
||||
}
|
||||
t := fragmentInParams[i].typ
|
||||
if !p.typ.Equal(&t) {
|
||||
name := fragmentInParams[i].name
|
||||
cs.addError(0, fmt.Sprintf("fragment argument %s must be %s but was %s", name, p.typ.String(), t.String()))
|
||||
}
|
||||
}
|
||||
|
||||
// The first out-param is treated as gl_Position in GLSL.
|
||||
if vertexOutParams[0].typ.Main != shaderir.Vec4 {
|
||||
cs.addError(0, "vertex entry point must have at least one returning vec4 value for a position")
|
||||
}
|
||||
if len(fragmentOutParams) != 0 || fragmentReturnType.Main != shaderir.Vec4 {
|
||||
cs.addError(0, "fragment entry point must have one returning vec4 value for a color")
|
||||
}
|
||||
}
|
||||
|
||||
if len(cs.errs) > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Set attribute and varying veraibles.
|
||||
for _, p := range vertexInParams {
|
||||
cs.ir.Attributes = append(cs.ir.Attributes, p.typ)
|
||||
}
|
||||
if len(vertexOutParams) > 0 {
|
||||
// TODO: Check that these params are not arrays or structs
|
||||
// The 0th argument is a special variable for position and is not included in varying variables.
|
||||
for _, p := range vertexOutParams[1:] {
|
||||
cs.ir.Varyings = append(cs.ir.Varyings, p.typ)
|
||||
}
|
||||
}
|
||||
|
||||
// Parse functions.
|
||||
for _, d := range f.Decls {
|
||||
if f, ok := d.(*ast.FuncDecl); ok {
|
||||
@@ -742,7 +791,13 @@ func (cs *compileState) parseFuncParams(block *block, fname string, d *ast.FuncD
|
||||
|
||||
// If there is only one returning value, it is treated as a returning value.
|
||||
// An array cannot be a returning value, especially for HLSL (#2923).
|
||||
if len(out) == 1 && out[0].name == "" && out[0].typ.Main != shaderir.Array {
|
||||
//
|
||||
// For the vertex entry, a parameter (variable) is used as a returning value.
|
||||
// For example, GLSL doesn't treat gl_Position as a returning value.
|
||||
// Thus, the returning value is not set for the vertex entry.
|
||||
// TODO: This can be resolved by having an indirect function like what the fragment entry already does.
|
||||
// See internal/shaderir/glsl.adjustProgram.
|
||||
if len(out) == 1 && out[0].name == "" && out[0].typ.Main != shaderir.Array && fname != cs.vertexEntry {
|
||||
ret = out[0].typ
|
||||
out = nil
|
||||
}
|
||||
@@ -765,77 +820,25 @@ func (cs *compileState) parseFunc(block *block, d *ast.FuncDecl) (function, bool
|
||||
}
|
||||
|
||||
inParams, outParams, returnType := cs.parseFuncParams(block, d.Name.Name, d)
|
||||
|
||||
checkVaryings := func(vs []variable) {
|
||||
if len(cs.ir.Varyings) != len(vs) {
|
||||
cs.addError(d.Pos(), "the number of vertex entry point's returning values and the number of fragment entry point's params must be the same")
|
||||
return
|
||||
if d.Name.Name == cs.fragmentEntry {
|
||||
if len(inParams) == 0 {
|
||||
inParams = append(inParams, variable{
|
||||
name: "_",
|
||||
typ: shaderir.Type{Main: shaderir.Vec4},
|
||||
})
|
||||
}
|
||||
for i, t := range cs.ir.Varyings {
|
||||
if t.Main != vs[i].typ.Main {
|
||||
cs.addError(d.Pos(), "vertex entry point's returning value types and fragment entry point's param types must match")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if block == &cs.global {
|
||||
switch d.Name.Name {
|
||||
case cs.vertexEntry:
|
||||
for _, v := range inParams {
|
||||
cs.ir.Attributes = append(cs.ir.Attributes, v.typ)
|
||||
}
|
||||
|
||||
// For the vertex entry, a parameter (variable) is used as a returning value.
|
||||
// For example, GLSL doesn't treat gl_Position as a returning value.
|
||||
// TODO: This can be resolved by having an indirect function like what the fragment entry already does.
|
||||
// See internal/shaderir/glsl.adjustProgram.
|
||||
if len(outParams) == 0 {
|
||||
outParams = append(outParams, variable{
|
||||
typ: shaderir.Type{Main: shaderir.Vec4},
|
||||
// The 0th inParams is a special variable for position and is not included in varying variables.
|
||||
if diff := len(cs.ir.Varyings) - (len(inParams) - 1); diff > 0 {
|
||||
// inParams is not enough when the vertex shader has more returning values than the fragment shader's arguments.
|
||||
orig := len(inParams) - 1
|
||||
for i := 0; i < diff; i++ {
|
||||
inParams = append(inParams, variable{
|
||||
name: "_",
|
||||
typ: cs.ir.Varyings[orig+i],
|
||||
})
|
||||
}
|
||||
|
||||
// The first out-param is treated as gl_Position in GLSL.
|
||||
if outParams[0].typ.Main != shaderir.Vec4 {
|
||||
cs.addError(d.Pos(), "vertex entry point must have at least one returning vec4 value for a position")
|
||||
return function{}, false
|
||||
}
|
||||
|
||||
if cs.varyingParsed {
|
||||
checkVaryings(outParams[1:])
|
||||
} else {
|
||||
for _, v := range outParams[1:] {
|
||||
// TODO: Check that these params are not arrays or structs
|
||||
cs.ir.Varyings = append(cs.ir.Varyings, v.typ)
|
||||
}
|
||||
}
|
||||
cs.varyingParsed = true
|
||||
case cs.fragmentEntry:
|
||||
if len(inParams) == 0 {
|
||||
cs.addError(d.Pos(), "fragment entry point must have at least one vec4 parameter for a position")
|
||||
return function{}, false
|
||||
}
|
||||
if inParams[0].typ.Main != shaderir.Vec4 {
|
||||
cs.addError(d.Pos(), "fragment entry point must have at least one vec4 parameter for a position")
|
||||
return function{}, false
|
||||
}
|
||||
|
||||
if len(outParams) != 0 || returnType.Main != shaderir.Vec4 {
|
||||
cs.addError(d.Pos(), "fragment entry point must have one returning vec4 value for a color")
|
||||
return function{}, false
|
||||
}
|
||||
|
||||
if cs.varyingParsed {
|
||||
checkVaryings(inParams[1:])
|
||||
} else {
|
||||
for _, v := range inParams[1:] {
|
||||
cs.ir.Varyings = append(cs.ir.Varyings, v.typ)
|
||||
}
|
||||
}
|
||||
cs.varyingParsed = true
|
||||
}
|
||||
}
|
||||
|
||||
b, ok := cs.parseBlock(block, d.Name.Name, d.Body.List, inParams, outParams, returnType, true)
|
||||
if !ok {
|
||||
return function{}, false
|
||||
|
||||
+23
-12
@@ -117,11 +117,12 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
|
||||
if op == shaderir.And || op == shaderir.Or || op == shaderir.Xor || op == shaderir.LeftShift || op == shaderir.RightShift {
|
||||
if lts[0].Main != shaderir.Int && !lts[0].IsIntVector() {
|
||||
cs.addError(stmt.Pos(), fmt.Sprintf("invalid operation: operator %s not defined on %s", stmt.Tok, lts[0].String()))
|
||||
return nil, false
|
||||
}
|
||||
if rts[0].Main != shaderir.Int && !rts[0].IsIntVector() {
|
||||
cs.addError(stmt.Pos(), fmt.Sprintf("invalid operation: operator %s not defined on %s", stmt.Tok, rts[0].String()))
|
||||
return nil, false
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
if lts[0].Main == shaderir.Int && rhs[0].Const != nil {
|
||||
if !cs.forceToInt(stmt, &rhs[0]) {
|
||||
@@ -251,7 +252,7 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
if len(ts) != 1 || ts[0].Main != shaderir.Bool {
|
||||
if len(ts) != 1 {
|
||||
var tss []string
|
||||
for _, t := range ts {
|
||||
tss = append(tss, t.String())
|
||||
@@ -259,6 +260,10 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
|
||||
cs.addError(stmt.Pos(), fmt.Sprintf("if-condition must be bool but: %s", strings.Join(tss, ", ")))
|
||||
return nil, false
|
||||
}
|
||||
if !(ts[0].Main == shaderir.Bool || (ts[0].Main == shaderir.None && exprs[0].Const != nil && exprs[0].Const.Kind() == gconstant.Bool)) {
|
||||
cs.addError(stmt.Pos(), fmt.Sprintf("if-condition must be bool but: %s", ts[0].String()))
|
||||
return nil, false
|
||||
}
|
||||
stmts = append(stmts, ss...)
|
||||
|
||||
var bs []*shaderir.Block
|
||||
@@ -493,6 +498,8 @@ func (cs *compileState) assign(block *block, fname string, pos token.Pos, lhs, r
|
||||
allblank := true
|
||||
|
||||
if len(lhs) == len(rhs) {
|
||||
var localVariablIndicesToAssignLater []int
|
||||
var leftExprsToAssignLater []shaderir.Expr
|
||||
for i, e := range lhs {
|
||||
// Prase RHS first for the order of the statements.
|
||||
r, rts, ss, ok := cs.parseExpr(block, fname, rhs[i], true)
|
||||
@@ -615,19 +622,23 @@ func (cs *compileState) assign(block *block, fname string, pos token.Pos, lhs, r
|
||||
},
|
||||
r[0],
|
||||
},
|
||||
},
|
||||
shaderir.Stmt{
|
||||
Type: shaderir.Assign,
|
||||
Exprs: []shaderir.Expr{
|
||||
l[0],
|
||||
{
|
||||
Type: shaderir.LocalVariable,
|
||||
Index: idx,
|
||||
},
|
||||
},
|
||||
})
|
||||
localVariablIndicesToAssignLater = append(localVariablIndicesToAssignLater, idx)
|
||||
leftExprsToAssignLater = append(leftExprsToAssignLater, l[0])
|
||||
}
|
||||
}
|
||||
for i, idx := range localVariablIndicesToAssignLater {
|
||||
stmts = append(stmts, shaderir.Stmt{
|
||||
Type: shaderir.Assign,
|
||||
Exprs: []shaderir.Expr{
|
||||
leftExprsToAssignLater[i],
|
||||
{
|
||||
Type: shaderir.LocalVariable,
|
||||
Index: idx,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
} else {
|
||||
var ss []shaderir.Stmt
|
||||
var ok bool
|
||||
|
||||
+4
@@ -81,6 +81,10 @@ func (cs *compileState) parseType(block *block, fname string, expr ast.Expr) (sh
|
||||
cs.addError(t.Pos(), "length of array must be an integer")
|
||||
return shaderir.Type{}, false
|
||||
}
|
||||
if l < 0 {
|
||||
cs.addError(t.Pos(), fmt.Sprintf("invalid length array %d", l))
|
||||
return shaderir.Type{}, false
|
||||
}
|
||||
length = int(l)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user