diff --git a/internal/shaderir/glsl.go b/internal/shaderir/glsl.go index f24657ed7..0d2822cfe 100644 --- a/internal/shaderir/glsl.go +++ b/internal/shaderir/glsl.go @@ -188,6 +188,8 @@ func (p *Program) glslBlock(b *Block, level int, localVarIndex int) []string { default: return fmt.Sprintf("?(unexpected variable type: %d)", e.Variable.Type) } + case BuiltinFuncExpr: + return string(e.BuiltinFunc) case Ident: return e.Ident case Unary: @@ -205,10 +207,10 @@ func (p *Program) glslBlock(b *Block, level int, localVarIndex int) []string { return fmt.Sprintf("(%s) ? (%s) : (%s)", glslExpr(&e.Exprs[0]), glslExpr(&e.Exprs[1]), glslExpr(&e.Exprs[2])) case Call: var args []string - for _, exp := range e.Exprs { + for _, exp := range e.Exprs[1:] { args = append(args, glslExpr(&exp)) } - return fmt.Sprintf("%s(%s)", e.Ident, strings.Join(args, ", ")) + return fmt.Sprintf("(%s)(%s)", glslExpr(&e.Exprs[0]), strings.Join(args, ", ")) case FieldSelector: return fmt.Sprintf("(%s).%s", glslExpr(&e.Exprs[0]), glslExpr(&e.Exprs[1])) case Index: @@ -256,7 +258,7 @@ func (p *Program) glslBlock(b *Block, level int, localVarIndex int) []string { } var op string switch s.ForOp { - case LessThan, LessEqual, GreaterThan, GreaterEqual, Equal, NotEqual: + case LessThanOp, LessThanEqualOp, GreaterThanOp, GreaterThanEqualOp, EqualOp, NotEqualOp: op = string(s.ForOp) default: op = fmt.Sprintf("?(unexpected op: %s)", string(s.ForOp)) diff --git a/internal/shaderir/ir_test.go b/internal/shaderir/ir_test.go index 9eb7e6d21..a479b59a1 100644 --- a/internal/shaderir/ir_test.go +++ b/internal/shaderir/ir_test.go @@ -91,6 +91,13 @@ func varNameExpr(vt VariableType, index int) Expr { } } +func builtinFuncExpr(f BuiltinFunc) Expr { + return Expr{ + Type: BuiltinFuncExpr, + BuiltinFunc: f, + } +} + func identExpr(ident string) Expr { return Expr{ Type: Ident, @@ -113,11 +120,10 @@ func selectionExpr(cond, a, b Expr) Expr { } } -func callExpr(name string, args ...Expr) Expr { +func callExpr(callee Expr, args ...Expr) Expr { return Expr{ Type: Call, - Ident: name, - Exprs: args, + Exprs: append([]Expr{callee}, args...), } } @@ -388,13 +394,13 @@ varying vec3 V0;`, nil, exprStmt( callExpr( - "F1", + identExpr("F1"), ), ), assignStmt( varNameExpr(Local, 2), callExpr( - "F2", + identExpr("F2"), varNameExpr(Local, 0), varNameExpr(Local, 1), ), @@ -404,8 +410,39 @@ varying vec3 V0;`, }, }, Glsl: `void F0(in float l0, in float l1, out vec2 l2) { - F1(); - l2 = F2(l0, l1); + (F1)(); + l2 = (F2)(l0, l1); +}`, + }, + { + Name: "BuiltinFunc", + Program: Program{ + Funcs: []Func{ + { + Name: "F0", + InParams: []Type{ + {Main: Float}, + {Main: Float}, + }, + OutParams: []Type{ + {Main: Float}, + }, + Block: block( + nil, + assignStmt( + varNameExpr(Local, 2), + callExpr( + builtinFuncExpr(Min), + varNameExpr(Local, 0), + varNameExpr(Local, 1), + ), + ), + ), + }, + }, + }, + Glsl: `void F0(in float l0, in float l1, out float l2) { + l2 = (min)(l0, l1); }`, }, { @@ -454,7 +491,7 @@ varying vec3 V0;`, nil, ifStmt( binaryExpr( - Equal, + EqualOp, varNameExpr(Local, 0), floatExpr(0), ), @@ -503,7 +540,7 @@ varying vec3 V0;`, forStmt( 0, 100, - LessThan, + LessThanOp, 1, block( nil, diff --git a/internal/shaderir/program.go b/internal/shaderir/program.go index 2befe1d4e..f85d5523c 100644 --- a/internal/shaderir/program.go +++ b/internal/shaderir/program.go @@ -83,13 +83,14 @@ const ( ) type Expr struct { - Type ExprType - Exprs []Expr - Variable Variable - Int int32 - Float float32 - Ident string - Op Op + Type ExprType + Exprs []Expr + Variable Variable + Int int32 + Float float32 + BuiltinFunc BuiltinFunc + Ident string + Op Op } type ExprType int @@ -98,6 +99,7 @@ const ( IntExpr ExprType = iota FloatExpr VarName + BuiltinFuncExpr Ident Unary Binary @@ -122,23 +124,75 @@ const ( type Op string const ( - Add Op = "+" - Sub Op = "-" - Neg Op = "!" - Mul Op = "*" - Div Op = "/" - Mod Op = "%" - LeftShift Op = "<<" - RightShift Op = ">>" - LessThan Op = "<" - LessEqual Op = "<=" - GreaterThan Op = ">" - GreaterEqual Op = ">=" - Equal Op = "==" - NotEqual Op = "!=" - And Op = "&" - Xor Op = "^" - Or Op = "|" - AndAnd Op = "&&" - OrOr Op = "||" + Add Op = "+" + Sub Op = "-" + Neg Op = "!" + Mul Op = "*" + Div Op = "/" + ModOp Op = "%" + LeftShift Op = "<<" + RightShift Op = ">>" + LessThanOp Op = "<" + LessThanEqualOp Op = "<=" + GreaterThanOp Op = ">" + GreaterThanEqualOp Op = ">=" + EqualOp Op = "==" + NotEqualOp Op = "!=" + And Op = "&" + Xor Op = "^" + Or Op = "|" + AndAnd Op = "&&" + OrOr Op = "||" +) + +type BuiltinFunc string + +const ( + Radians BuiltinFunc = "radians" + Degrees BuiltinFunc = "degrees" + Sin BuiltinFunc = "sin" + Cos BuiltinFunc = "cos" + Tan BuiltinFunc = "tan" + Asin BuiltinFunc = "asin" + Acos BuiltinFunc = "acos" + Atan BuiltinFunc = "atan" + Pow BuiltinFunc = "pow" + Exp BuiltinFunc = "exp" + Log BuiltinFunc = "log" + Exp2 BuiltinFunc = "exp2" + Log2 BuiltinFunc = "log2" + Sqrt BuiltinFunc = "sqrt" + Inversesqrt BuiltinFunc = "inversesqrt" + Abs BuiltinFunc = "abs" + Sign BuiltinFunc = "sign" + Floor BuiltinFunc = "floor" + Ceil BuiltinFunc = "ceil" + Fract BuiltinFunc = "fract" + Mod BuiltinFunc = "mod" + Min BuiltinFunc = "min" + Max BuiltinFunc = "max" + Clamp BuiltinFunc = "clamp" + Mix BuiltinFunc = "mix" + Step BuiltinFunc = "step" + Smoothstep BuiltinFunc = "smoothstep" + Length BuiltinFunc = "length" + Distance BuiltinFunc = "distance" + Dot BuiltinFunc = "dot" + Cross BuiltinFunc = "cross" + Normalize BuiltinFunc = "normalize" + Faceforward BuiltinFunc = "faceforward" + Reflect BuiltinFunc = "reflect" + MatrixCompMult BuiltinFunc = "matrixCompMult" + OuterProduct BuiltinFunc = "outerProduct" + Transpose BuiltinFunc = "transpose" + LessThan BuiltinFunc = "lessThan" + LessThanEqual BuiltinFunc = "lessThanEqual" + GreaterThan BuiltinFunc = "greaterThan" + GreaterThanEqual BuiltinFunc = "greaterThanEqual" + Equal BuiltinFunc = "equal" + NotEqual BuiltinFunc = "notEqual" + Any BuiltinFunc = "any" + All BuiltinFunc = "all" + Not BuiltinFunc = "not" + Texture2D BuiltinFunc = "texture2D" )