program.go (7335B)
1 // Copyright 2020 The Ebiten Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package shaderir offers intermediate representation for shader programs. 16 package shaderir 17 18 import ( 19 "go/constant" 20 "go/token" 21 "strings" 22 ) 23 24 type Program struct { 25 UniformNames []string 26 Uniforms []Type 27 TextureNum int 28 Attributes []Type 29 Varyings []Type 30 Funcs []Func 31 VertexFunc VertexFunc 32 FragmentFunc FragmentFunc 33 } 34 35 type Func struct { 36 Index int 37 InParams []Type 38 OutParams []Type 39 Return Type 40 Block *Block 41 } 42 43 // VertexFunc takes pseudo params, and the number if len(attributes) + len(varyings) + 1. 44 // If 0 <= index < len(attributes), the params are in-params and represent attribute variables. 45 // If index == len(attributes), the param is an out-param and repesents the position in vec4 (gl_Position in GLSL) 46 // If len(attributes) + 1 <= index < len(attributes) + len(varyings) + 1, the params are out-params and represent 47 // varying variables. 48 type VertexFunc struct { 49 Block *Block 50 } 51 52 // FragmentFunc takes pseudo params, and the number is len(varyings) + 2. 53 // If index == 0, the param represents the coordinate of the fragment (gl_FragCoord in GLSL). 54 // If index == len(varyings), the param represents (index-1)th verying variable. 55 // If index == len(varyings)+1, the param is an out-param representing the color of the pixel (gl_FragColor in GLSL). 56 type FragmentFunc struct { 57 Block *Block 58 } 59 60 type Block struct { 61 LocalVars []Type 62 LocalVarIndexOffset int 63 Stmts []Stmt 64 } 65 66 type Stmt struct { 67 Type StmtType 68 Exprs []Expr 69 Blocks []*Block 70 ForVarType Type 71 ForVarIndex int 72 ForInit constant.Value 73 ForEnd constant.Value 74 ForOp Op 75 ForDelta constant.Value 76 InitIndex int 77 } 78 79 type StmtType int 80 81 const ( 82 ExprStmt StmtType = iota 83 BlockStmt 84 Assign 85 Init 86 If 87 For 88 Continue 89 Break 90 Return 91 Discard 92 ) 93 94 type ConstType int 95 96 const ( 97 ConstTypeNone ConstType = iota 98 ConstTypeBool 99 ConstTypeInt 100 ConstTypeFloat 101 ) 102 103 type Expr struct { 104 Type ExprType 105 Exprs []Expr 106 Const constant.Value 107 ConstType ConstType 108 BuiltinFunc BuiltinFunc 109 Swizzling string 110 Index int 111 Op Op 112 } 113 114 type ExprType int 115 116 const ( 117 Blank ExprType = iota 118 NumberExpr 119 UniformVariable 120 TextureVariable 121 LocalVariable 122 StructMember 123 BuiltinFuncExpr 124 SwizzlingExpr 125 FunctionExpr 126 Unary 127 Binary 128 Selection 129 Call 130 FieldSelector 131 Index 132 ) 133 134 type Op string 135 136 const ( 137 Add Op = "+" 138 Sub Op = "-" 139 NotOp Op = "!" 140 Mul Op = "*" 141 Div Op = "/" 142 ModOp Op = "%" 143 LeftShift Op = "<<" 144 RightShift Op = ">>" 145 LessThanOp Op = "<" 146 LessThanEqualOp Op = "<=" 147 GreaterThanOp Op = ">" 148 GreaterThanEqualOp Op = ">=" 149 EqualOp Op = "==" 150 NotEqualOp Op = "!=" 151 And Op = "&" 152 Xor Op = "^" 153 Or Op = "|" 154 AndAnd Op = "&&" 155 OrOr Op = "||" 156 ) 157 158 func OpFromToken(t token.Token) (Op, bool) { 159 switch t { 160 case token.ADD: 161 return Add, true 162 case token.SUB: 163 return Sub, true 164 case token.NOT: 165 return NotOp, true 166 case token.MUL: 167 return Mul, true 168 case token.QUO: 169 return Div, true 170 case token.REM: 171 return ModOp, true 172 case token.SHL: 173 return LeftShift, true 174 case token.SHR: 175 return RightShift, true 176 case token.LSS: 177 return LessThanOp, true 178 case token.LEQ: 179 return LessThanEqualOp, true 180 case token.GTR: 181 return GreaterThanOp, true 182 case token.GEQ: 183 return GreaterThanEqualOp, true 184 case token.EQL: 185 return EqualOp, true 186 case token.NEQ: 187 return NotEqualOp, true 188 case token.AND: 189 return And, true 190 case token.XOR: 191 return Xor, true 192 case token.OR: 193 return Or, true 194 case token.LAND: 195 return AndAnd, true 196 case token.LOR: 197 return OrOr, true 198 } 199 return "", false 200 } 201 202 type BuiltinFunc string 203 204 const ( 205 Len BuiltinFunc = "len" 206 BoolF BuiltinFunc = "bool" 207 IntF BuiltinFunc = "int" 208 FloatF BuiltinFunc = "float" 209 Vec2F BuiltinFunc = "vec2" 210 Vec3F BuiltinFunc = "vec3" 211 Vec4F BuiltinFunc = "vec4" 212 Mat2F BuiltinFunc = "mat2" 213 Mat3F BuiltinFunc = "mat3" 214 Mat4F BuiltinFunc = "mat4" 215 Radians BuiltinFunc = "radians" 216 Degrees BuiltinFunc = "degrees" 217 Sin BuiltinFunc = "sin" 218 Cos BuiltinFunc = "cos" 219 Tan BuiltinFunc = "tan" 220 Asin BuiltinFunc = "asin" 221 Acos BuiltinFunc = "acos" 222 Atan BuiltinFunc = "atan" 223 Atan2 BuiltinFunc = "atan2" 224 Pow BuiltinFunc = "pow" 225 Exp BuiltinFunc = "exp" 226 Log BuiltinFunc = "log" 227 Exp2 BuiltinFunc = "exp2" 228 Log2 BuiltinFunc = "log2" 229 Sqrt BuiltinFunc = "sqrt" 230 Inversesqrt BuiltinFunc = "inversesqrt" 231 Abs BuiltinFunc = "abs" 232 Sign BuiltinFunc = "sign" 233 Floor BuiltinFunc = "floor" 234 Ceil BuiltinFunc = "ceil" 235 Fract BuiltinFunc = "fract" 236 Mod BuiltinFunc = "mod" 237 Min BuiltinFunc = "min" 238 Max BuiltinFunc = "max" 239 Clamp BuiltinFunc = "clamp" 240 Mix BuiltinFunc = "mix" 241 Step BuiltinFunc = "step" 242 Smoothstep BuiltinFunc = "smoothstep" 243 Length BuiltinFunc = "length" 244 Distance BuiltinFunc = "distance" 245 Dot BuiltinFunc = "dot" 246 Cross BuiltinFunc = "cross" 247 Normalize BuiltinFunc = "normalize" 248 Faceforward BuiltinFunc = "faceforward" 249 Reflect BuiltinFunc = "reflect" 250 Transpose BuiltinFunc = "transpose" 251 Texture2DF BuiltinFunc = "texture2D" 252 Dfdx BuiltinFunc = "dfdx" 253 Dfdy BuiltinFunc = "dfdy" 254 Fwidth BuiltinFunc = "fwidth" 255 ) 256 257 func ParseBuiltinFunc(str string) (BuiltinFunc, bool) { 258 switch BuiltinFunc(str) { 259 case Len, 260 BoolF, 261 IntF, 262 FloatF, 263 Vec2F, 264 Vec3F, 265 Vec4F, 266 Mat2F, 267 Mat3F, 268 Mat4F, 269 Sin, 270 Cos, 271 Tan, 272 Asin, 273 Acos, 274 Atan, 275 Atan2, 276 Pow, 277 Exp, 278 Log, 279 Exp2, 280 Log2, 281 Sqrt, 282 Inversesqrt, 283 Abs, 284 Sign, 285 Floor, 286 Ceil, 287 Fract, 288 Mod, 289 Min, 290 Max, 291 Clamp, 292 Mix, 293 Step, 294 Smoothstep, 295 Length, 296 Distance, 297 Dot, 298 Cross, 299 Normalize, 300 Faceforward, 301 Reflect, 302 Transpose, 303 Texture2DF, 304 Dfdx, 305 Dfdy, 306 Fwidth: 307 return BuiltinFunc(str), true 308 } 309 return "", false 310 } 311 312 func IsValidSwizzling(s string) bool { 313 if len(s) < 1 || 4 < len(s) { 314 return false 315 } 316 317 const ( 318 xyzw = "xyzw" 319 rgba = "rgba" 320 strq = "strq" 321 ) 322 323 switch { 324 case strings.IndexByte(xyzw, s[0]) >= 0: 325 for _, c := range s { 326 if strings.IndexRune(xyzw, c) == -1 { 327 return false 328 } 329 } 330 return true 331 case strings.IndexByte(rgba, s[0]) >= 0: 332 for _, c := range s { 333 if strings.IndexRune(rgba, c) == -1 { 334 return false 335 } 336 } 337 return true 338 case strings.IndexByte(strq, s[0]) >= 0: 339 for _, c := range s { 340 if strings.IndexRune(strq, c) == -1 { 341 return false 342 } 343 } 344 return true 345 } 346 return false 347 }