type.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  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. package shader
  15. import (
  16. "fmt"
  17. "go/ast"
  18. gconstant "go/constant"
  19. "strings"
  20. "github.com/hajimehoshi/ebiten/v2/internal/shaderir"
  21. )
  22. func (cs *compileState) parseType(block *block, fname string, expr ast.Expr) (shaderir.Type, bool) {
  23. switch t := expr.(type) {
  24. case *ast.Ident:
  25. switch t.Name {
  26. case "bool":
  27. return shaderir.Type{Main: shaderir.Bool}, true
  28. case "int":
  29. return shaderir.Type{Main: shaderir.Int}, true
  30. case "float":
  31. return shaderir.Type{Main: shaderir.Float}, true
  32. case "vec2":
  33. return shaderir.Type{Main: shaderir.Vec2}, true
  34. case "vec3":
  35. return shaderir.Type{Main: shaderir.Vec3}, true
  36. case "vec4":
  37. return shaderir.Type{Main: shaderir.Vec4}, true
  38. case "ivec2":
  39. return shaderir.Type{Main: shaderir.IVec2}, true
  40. case "ivec3":
  41. return shaderir.Type{Main: shaderir.IVec3}, true
  42. case "ivec4":
  43. return shaderir.Type{Main: shaderir.IVec4}, true
  44. case "mat2":
  45. return shaderir.Type{Main: shaderir.Mat2}, true
  46. case "mat3":
  47. return shaderir.Type{Main: shaderir.Mat3}, true
  48. case "mat4":
  49. return shaderir.Type{Main: shaderir.Mat4}, true
  50. default:
  51. cs.addError(t.Pos(), fmt.Sprintf("unexpected type: %s", t.Name))
  52. return shaderir.Type{}, false
  53. }
  54. case *ast.ArrayType:
  55. if t.Len == nil {
  56. cs.addError(t.Pos(), "array length must be specified")
  57. return shaderir.Type{}, false
  58. }
  59. var length int
  60. if _, ok := t.Len.(*ast.Ellipsis); ok {
  61. length = -1 // Determine the length later.
  62. } else {
  63. exprs, _, _, ok := cs.parseExpr(block, fname, t.Len, true)
  64. if !ok {
  65. return shaderir.Type{}, false
  66. }
  67. if len(exprs) != 1 {
  68. cs.addError(t.Pos(), "invalid length of array")
  69. return shaderir.Type{}, false
  70. }
  71. if exprs[0].Type != shaderir.NumberExpr {
  72. cs.addError(t.Pos(), "length of array must be a constant number")
  73. return shaderir.Type{}, false
  74. }
  75. l, ok := gconstant.Int64Val(exprs[0].Const)
  76. if !ok {
  77. cs.addError(t.Pos(), "length of array must be an integer")
  78. return shaderir.Type{}, false
  79. }
  80. length = int(l)
  81. }
  82. elm, ok := cs.parseType(block, fname, t.Elt)
  83. if !ok {
  84. return shaderir.Type{}, false
  85. }
  86. if elm.Main == shaderir.Array {
  87. cs.addError(t.Pos(), "array of array is forbidden")
  88. return shaderir.Type{}, false
  89. }
  90. return shaderir.Type{
  91. Main: shaderir.Array,
  92. Sub: []shaderir.Type{elm},
  93. Length: length,
  94. }, true
  95. case *ast.StructType:
  96. cs.addError(t.Pos(), "struct is not implemented")
  97. return shaderir.Type{}, false
  98. default:
  99. cs.addError(t.Pos(), fmt.Sprintf("unepxected type: %v", t))
  100. return shaderir.Type{}, false
  101. }
  102. }
  103. func isFloat(expr shaderir.Expr, t shaderir.Type) bool {
  104. if expr.Const != nil {
  105. if t.Main == shaderir.Float {
  106. return true
  107. }
  108. if canTruncateToFloat(expr.Const) {
  109. return true
  110. }
  111. return false
  112. }
  113. if t.Main == shaderir.Float {
  114. return true
  115. }
  116. return false
  117. }
  118. func isInt(expr shaderir.Expr, t shaderir.Type) bool {
  119. if expr.Const != nil {
  120. if t.Main == shaderir.Float {
  121. return true
  122. }
  123. if canTruncateToInteger(expr.Const) {
  124. return true
  125. }
  126. return false
  127. }
  128. if t.Main == shaderir.Int {
  129. return true
  130. }
  131. return false
  132. }
  133. func checkArgsForBoolBuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
  134. if len(args) != len(argts) {
  135. return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
  136. }
  137. if len(args) != 1 {
  138. return fmt.Errorf("number of bool's arguments must be 1 but %d", len(args))
  139. }
  140. if argts[0].Main == shaderir.Bool {
  141. return nil
  142. }
  143. if args[0].Const != nil && args[0].Const.Kind() == gconstant.Bool {
  144. return nil
  145. }
  146. return fmt.Errorf("invalid arguments for bool: (%s)", argts[0].String())
  147. }
  148. func checkArgsForIntBuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
  149. if len(args) != len(argts) {
  150. return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
  151. }
  152. if len(args) != 1 {
  153. return fmt.Errorf("number of int's arguments must be 1 but %d", len(args))
  154. }
  155. if argts[0].Main == shaderir.Int || argts[0].Main == shaderir.Float {
  156. return nil
  157. }
  158. if args[0].Const != nil && gconstant.ToInt(args[0].Const).Kind() != gconstant.Unknown {
  159. return nil
  160. }
  161. return fmt.Errorf("invalid arguments for int: (%s)", argts[0].String())
  162. }
  163. func checkArgsForFloatBuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
  164. if len(args) != len(argts) {
  165. return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
  166. }
  167. if len(args) != 1 {
  168. return fmt.Errorf("number of float's arguments must be 1 but %d", len(args))
  169. }
  170. if argts[0].Main == shaderir.Int || argts[0].Main == shaderir.Float {
  171. return nil
  172. }
  173. if args[0].Const != nil && gconstant.ToFloat(args[0].Const).Kind() != gconstant.Unknown {
  174. return nil
  175. }
  176. return fmt.Errorf("invalid arguments for float: (%s)", argts[0].String())
  177. }
  178. func checkArgsForVec2BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
  179. if len(args) != len(argts) {
  180. return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
  181. }
  182. switch len(args) {
  183. case 1:
  184. if isFloat(args[0], argts[0]) {
  185. return nil
  186. }
  187. // Allow any vectors to perform a cast-like function.
  188. if (argts[0].IsFloatVector() || argts[0].IsIntVector()) && argts[0].VectorElementCount() == 2 {
  189. return nil
  190. }
  191. case 2:
  192. if isFloat(args[0], argts[0]) && isFloat(args[1], argts[1]) {
  193. return nil
  194. }
  195. default:
  196. return fmt.Errorf("invalid number of arguments for vec2")
  197. }
  198. var str []string
  199. for _, t := range argts {
  200. str = append(str, t.String())
  201. }
  202. return fmt.Errorf("invalid arguments for vec2: (%s)", strings.Join(str, ", "))
  203. }
  204. func checkArgsForVec3BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
  205. if len(args) != len(argts) {
  206. return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
  207. }
  208. switch len(args) {
  209. case 1:
  210. if isFloat(args[0], argts[0]) {
  211. return nil
  212. }
  213. // Allow any vectors to perform a cast-like function.
  214. if (argts[0].IsFloatVector() || argts[0].IsIntVector()) && argts[0].VectorElementCount() == 3 {
  215. return nil
  216. }
  217. case 2:
  218. if isFloat(args[0], argts[0]) && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 2 {
  219. return nil
  220. }
  221. if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 2 && isFloat(args[1], argts[1]) {
  222. return nil
  223. }
  224. case 3:
  225. if isFloat(args[0], argts[0]) && isFloat(args[1], argts[1]) && isFloat(args[2], argts[2]) {
  226. return nil
  227. }
  228. default:
  229. return fmt.Errorf("invalid number of arguments for vec3")
  230. }
  231. var str []string
  232. for _, t := range argts {
  233. str = append(str, t.String())
  234. }
  235. return fmt.Errorf("invalid arguments for vec3: (%s)", strings.Join(str, ", "))
  236. }
  237. func checkArgsForVec4BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
  238. if len(args) != len(argts) {
  239. return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
  240. }
  241. switch len(args) {
  242. case 1:
  243. if isFloat(args[0], argts[0]) {
  244. return nil
  245. }
  246. // Allow any vectors to perform a cast-like function.
  247. if (argts[0].IsFloatVector() || argts[0].IsIntVector()) && argts[0].VectorElementCount() == 4 {
  248. return nil
  249. }
  250. case 2:
  251. if isFloat(args[0], argts[0]) && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 3 {
  252. return nil
  253. }
  254. if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 2 && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 2 {
  255. return nil
  256. }
  257. if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 3 && isFloat(args[1], argts[1]) {
  258. return nil
  259. }
  260. case 3:
  261. if isFloat(args[0], argts[0]) && isFloat(args[1], argts[1]) && argts[2].IsFloatVector() && argts[2].VectorElementCount() == 2 {
  262. return nil
  263. }
  264. if isFloat(args[0], argts[0]) && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 2 && isFloat(args[2], argts[2]) {
  265. return nil
  266. }
  267. if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 2 && isFloat(args[1], argts[1]) && isFloat(args[2], argts[2]) {
  268. return nil
  269. }
  270. case 4:
  271. if isFloat(args[0], argts[0]) && isFloat(args[1], argts[1]) && isFloat(args[2], argts[2]) && isFloat(args[3], argts[3]) {
  272. return nil
  273. }
  274. default:
  275. return fmt.Errorf("invalid number of arguments for vec4")
  276. }
  277. var str []string
  278. for _, t := range argts {
  279. str = append(str, t.String())
  280. }
  281. return fmt.Errorf("invalid arguments for vec4: (%s)", strings.Join(str, ", "))
  282. }
  283. func checkArgsForIVec2BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
  284. if len(args) != len(argts) {
  285. return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
  286. }
  287. switch len(args) {
  288. case 1:
  289. if isInt(args[0], argts[0]) {
  290. return nil
  291. }
  292. // Allow any vectors to perform a cast-like function.
  293. if (argts[0].IsFloatVector() || argts[0].IsIntVector()) && argts[0].VectorElementCount() == 2 {
  294. return nil
  295. }
  296. case 2:
  297. if isInt(args[0], argts[0]) && isInt(args[1], argts[1]) {
  298. return nil
  299. }
  300. default:
  301. return fmt.Errorf("invalid number of arguments for vec2")
  302. }
  303. var str []string
  304. for _, t := range argts {
  305. str = append(str, t.String())
  306. }
  307. return fmt.Errorf("invalid arguments for ivec2: (%s)", strings.Join(str, ", "))
  308. }
  309. func checkArgsForIVec3BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
  310. if len(args) != len(argts) {
  311. return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
  312. }
  313. switch len(args) {
  314. case 1:
  315. if isInt(args[0], argts[0]) {
  316. return nil
  317. }
  318. // Allow any vectors to perform a cast-like function.
  319. if (argts[0].IsFloatVector() || argts[0].IsIntVector()) && argts[0].VectorElementCount() == 3 {
  320. return nil
  321. }
  322. case 2:
  323. if isInt(args[0], argts[0]) && argts[1].IsIntVector() && argts[1].VectorElementCount() == 2 {
  324. return nil
  325. }
  326. if argts[0].IsIntVector() && argts[0].VectorElementCount() == 2 && isInt(args[1], argts[1]) {
  327. return nil
  328. }
  329. case 3:
  330. if isInt(args[0], argts[0]) && isInt(args[1], argts[1]) && isInt(args[2], argts[2]) {
  331. return nil
  332. }
  333. default:
  334. return fmt.Errorf("invalid number of arguments for vec3")
  335. }
  336. var str []string
  337. for _, t := range argts {
  338. str = append(str, t.String())
  339. }
  340. return fmt.Errorf("invalid arguments for ivec3: (%s)", strings.Join(str, ", "))
  341. }
  342. func checkArgsForIVec4BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
  343. if len(args) != len(argts) {
  344. return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
  345. }
  346. switch len(args) {
  347. case 1:
  348. if isInt(args[0], argts[0]) {
  349. return nil
  350. }
  351. // Allow any vectors to perform a cast-like function.
  352. if (argts[0].IsFloatVector() || argts[0].IsIntVector()) && argts[0].VectorElementCount() == 4 {
  353. return nil
  354. }
  355. case 2:
  356. if isInt(args[0], argts[0]) && argts[1].IsIntVector() && argts[1].VectorElementCount() == 3 {
  357. return nil
  358. }
  359. if argts[0].IsIntVector() && argts[0].VectorElementCount() == 2 && argts[1].IsIntVector() && argts[1].VectorElementCount() == 2 {
  360. return nil
  361. }
  362. if argts[0].IsIntVector() && argts[0].VectorElementCount() == 3 && isInt(args[1], argts[1]) {
  363. return nil
  364. }
  365. case 3:
  366. if isInt(args[0], argts[0]) && isInt(args[1], argts[1]) && argts[2].IsIntVector() && argts[2].VectorElementCount() == 2 {
  367. return nil
  368. }
  369. if isInt(args[0], argts[0]) && argts[1].IsIntVector() && argts[1].VectorElementCount() == 2 && isInt(args[2], argts[2]) {
  370. return nil
  371. }
  372. if argts[0].IsIntVector() && argts[0].VectorElementCount() == 2 && isInt(args[1], argts[1]) && isInt(args[2], argts[2]) {
  373. return nil
  374. }
  375. case 4:
  376. if isInt(args[0], argts[0]) && isInt(args[1], argts[1]) && isInt(args[2], argts[2]) && isInt(args[3], argts[3]) {
  377. return nil
  378. }
  379. default:
  380. return fmt.Errorf("invalid number of arguments for vec4")
  381. }
  382. var str []string
  383. for _, t := range argts {
  384. str = append(str, t.String())
  385. }
  386. return fmt.Errorf("invalid arguments for ivec4: (%s)", strings.Join(str, ", "))
  387. }
  388. func checkArgsForMat2BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
  389. if len(args) != len(argts) {
  390. return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
  391. }
  392. switch len(args) {
  393. case 1:
  394. if isFloat(args[0], argts[0]) {
  395. return nil
  396. }
  397. if argts[0].Main == shaderir.Mat2 {
  398. return nil
  399. }
  400. case 2:
  401. if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 2 && argts[1].IsFloatVector() && argts[1].VectorElementCount() == 2 {
  402. return nil
  403. }
  404. case 4:
  405. ok := true
  406. for i := range argts {
  407. if !isFloat(args[i], argts[i]) {
  408. ok = false
  409. break
  410. }
  411. }
  412. if ok {
  413. return nil
  414. }
  415. default:
  416. return fmt.Errorf("invalid number of arguments for mat2")
  417. }
  418. var str []string
  419. for _, t := range argts {
  420. str = append(str, t.String())
  421. }
  422. return fmt.Errorf("invalid arguments for mat2: (%s)", strings.Join(str, ", "))
  423. }
  424. func checkArgsForMat3BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
  425. if len(args) != len(argts) {
  426. return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
  427. }
  428. switch len(args) {
  429. case 1:
  430. if isFloat(args[0], argts[0]) {
  431. return nil
  432. }
  433. if argts[0].Main == shaderir.Mat3 {
  434. return nil
  435. }
  436. case 3:
  437. if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 3 &&
  438. argts[1].IsFloatVector() && argts[1].VectorElementCount() == 3 &&
  439. argts[2].IsFloatVector() && argts[2].VectorElementCount() == 3 {
  440. return nil
  441. }
  442. case 9:
  443. ok := true
  444. for i := range argts {
  445. if !isFloat(args[i], argts[i]) {
  446. ok = false
  447. break
  448. }
  449. }
  450. if ok {
  451. return nil
  452. }
  453. default:
  454. return fmt.Errorf("invalid number of arguments for mat3")
  455. }
  456. var str []string
  457. for _, t := range argts {
  458. str = append(str, t.String())
  459. }
  460. return fmt.Errorf("invalid arguments for mat3: (%s)", strings.Join(str, ", "))
  461. }
  462. func checkArgsForMat4BuiltinFunc(args []shaderir.Expr, argts []shaderir.Type) error {
  463. if len(args) != len(argts) {
  464. return fmt.Errorf("the number of arguments and types doesn't match: %d vs %d", len(args), len(argts))
  465. }
  466. switch len(args) {
  467. case 1:
  468. if isFloat(args[0], argts[0]) {
  469. return nil
  470. }
  471. if argts[0].Main == shaderir.Mat4 {
  472. return nil
  473. }
  474. case 4:
  475. if argts[0].IsFloatVector() && argts[0].VectorElementCount() == 4 &&
  476. argts[1].IsFloatVector() && argts[1].VectorElementCount() == 4 &&
  477. argts[2].IsFloatVector() && argts[2].VectorElementCount() == 4 &&
  478. argts[3].IsFloatVector() && argts[3].VectorElementCount() == 4 {
  479. return nil
  480. }
  481. case 16:
  482. ok := true
  483. for i := range argts {
  484. if !isFloat(args[i], argts[i]) {
  485. ok = false
  486. break
  487. }
  488. }
  489. if ok {
  490. return nil
  491. }
  492. default:
  493. return fmt.Errorf("invalid number of arguments for mat4")
  494. }
  495. var str []string
  496. for _, t := range argts {
  497. str = append(str, t.String())
  498. }
  499. return fmt.Errorf("invalid arguments for mat4: (%s)", strings.Join(str, ", "))
  500. }