Ast.hx 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. package hxsl;
  2. enum BufferKind {
  3. Uniform;
  4. Storage;
  5. RW;
  6. Partial;
  7. StoragePartial;
  8. RWPartial;
  9. }
  10. enum TexDimension {
  11. T1D;
  12. T2D;
  13. T3D;
  14. TCube;
  15. }
  16. enum Type {
  17. TVoid;
  18. TInt;
  19. TBool;
  20. TFloat;
  21. TString;
  22. TVec( size : Int, t : VecType );
  23. TMat3;
  24. TMat4;
  25. TMat3x4;
  26. TBytes( size : Int );
  27. TSampler( dim : TexDimension, isArray : Bool );
  28. TRWTexture( dim : TexDimension, isArray : Bool, channels : Int );
  29. TMat2;
  30. TStruct( vl : Array<TVar> );
  31. TFun( variants : Array<FunType> );
  32. TArray( t : Type, size : SizeDecl );
  33. TBuffer( t : Type, size : SizeDecl, kind : BufferKind );
  34. TChannel( size : Int );
  35. }
  36. enum VecType {
  37. VInt;
  38. VFloat;
  39. VBool;
  40. }
  41. enum SizeDecl {
  42. SConst( v : Int );
  43. SVar( v : TVar );
  44. }
  45. typedef FunType = { args : Array<{ name : String, type : Type }>, ret : Type };
  46. class Error {
  47. public var msg : String;
  48. public var pos : Position;
  49. public function new( msg, pos ) {
  50. this.msg = msg;
  51. this.pos = pos;
  52. }
  53. public function toString() {
  54. return "Error(" + msg + ")@" + pos;
  55. }
  56. public static function t( msg : String, pos : Position ) : Dynamic {
  57. throw new Error(msg, pos);
  58. return null;
  59. }
  60. }
  61. typedef Position = haxe.macro.Expr.Position;
  62. typedef Expr = { expr : ExprDef, pos : Position };
  63. typedef Binop = haxe.macro.Expr.Binop;
  64. typedef Unop = haxe.macro.Expr.Unop;
  65. enum VarKind {
  66. Global;
  67. Input;
  68. Param;
  69. Var;
  70. Local;
  71. Output;
  72. Function;
  73. }
  74. enum VarQualifier {
  75. Const( ?max : Int );
  76. Private;
  77. Nullable;
  78. PerObject;
  79. Name( n : String );
  80. Shared;
  81. Precision( p : Prec );
  82. Range( min : Float, max : Float );
  83. Ignore; // the variable is ignored in reflection (inspector)
  84. PerInstance( v : Int );
  85. Doc( s : String );
  86. Borrow( source : String );
  87. Sampler( name : String );
  88. Final;
  89. Flat;
  90. }
  91. enum Prec {
  92. Low;
  93. Medium;
  94. High;
  95. }
  96. typedef VarDecl = {
  97. var name : String;
  98. var type : Null<Type>;
  99. var kind : Null<VarKind>;
  100. var qualifiers : Array<VarQualifier>;
  101. var expr : Null<Expr>;
  102. }
  103. typedef FunDecl = {
  104. var name : String;
  105. var args : Array<VarDecl>;
  106. var ret : Null<Type>;
  107. var expr : Expr;
  108. }
  109. enum Const {
  110. CNull;
  111. CBool( b : Bool );
  112. CInt( v : Int );
  113. CFloat( v : Float );
  114. CString( v : String );
  115. }
  116. enum ExprDef {
  117. EConst( c : Const );
  118. EIdent( i : String );
  119. EParenthesis( e : Expr );
  120. EField( e : Expr, f : String );
  121. EBinop( op : Binop, e1 : Expr, e2 : Expr );
  122. EUnop( op : Unop, e1 : Expr );
  123. ECall( e : Expr, args : Array<Expr> );
  124. EBlock( el : Array<Expr> );
  125. EVars( v : Array<VarDecl> );
  126. EFunction( f : FunDecl );
  127. EIf( econd : Expr, eif : Expr, eelse : Null<Expr> );
  128. EDiscard;
  129. EFor( v : String, loop : Expr, block : Expr );
  130. EReturn( ?e : Expr );
  131. EBreak;
  132. EContinue;
  133. EArray( e : Expr, eindex : Expr );
  134. EArrayDecl( el : Array<Expr> );
  135. ESwitch( e : Expr, cases : Array<{ values : Array<Expr>, expr:Expr }>, def : Null<Expr> );
  136. EWhile( cond : Expr, loop : Expr, normalWhile : Bool );
  137. EMeta( name : String, args : Array<Expr>, e : Expr );
  138. }
  139. enum TExprDef {
  140. TConst( c : Const );
  141. TVar( v : TVar );
  142. TGlobal( g : TGlobal );
  143. TParenthesis( e : TExpr );
  144. TBlock( el : Array<TExpr> );
  145. TBinop( op : Binop, e1 : TExpr, e2 : TExpr );
  146. TUnop( op : Unop, e1 : TExpr );
  147. TVarDecl( v : TVar, ?init : TExpr );
  148. TCall( e : TExpr, args : Array<TExpr> );
  149. TSwiz( e : TExpr, regs : Array<Component> );
  150. TIf( econd : TExpr, eif : TExpr, eelse : Null<TExpr> );
  151. TDiscard;
  152. TReturn( ?e : TExpr );
  153. TFor( v : TVar, it : TExpr, loop : TExpr );
  154. TContinue;
  155. TBreak;
  156. TArray( e : TExpr, index : TExpr );
  157. TArrayDecl( el : Array<TExpr> );
  158. TSwitch( e : TExpr, cases : Array<{ values : Array<TExpr>, expr:TExpr }>, def : Null<TExpr> );
  159. TWhile( e : TExpr, loop : TExpr, normalWhile : Bool );
  160. TMeta( m : String, args : Array<Const>, e : TExpr );
  161. TField( e : TExpr, name : String );
  162. TSyntax(target : String, code : String, args : Array<SyntaxArg> ); // target = "code" should be treated as "insert regardless of target"
  163. }
  164. typedef TVar = {
  165. var id : Int;
  166. var name : String;
  167. var type : Type;
  168. var kind : VarKind;
  169. @:optional var parent : TVar;
  170. @:optional var qualifiers : Null<Array<VarQualifier>>;
  171. }
  172. typedef TFunction = {
  173. var kind : FunctionKind;
  174. var ref : TVar;
  175. var args : Array<TVar>;
  176. var ret : Type;
  177. var expr : TExpr;
  178. }
  179. enum FunctionKind {
  180. Vertex;
  181. Fragment;
  182. Init;
  183. Helper;
  184. Main;
  185. }
  186. enum TGlobal {
  187. Radians;
  188. Degrees;
  189. Sin;
  190. Cos;
  191. Tan;
  192. Asin;
  193. Acos;
  194. Atan;
  195. Pow;
  196. Exp;
  197. Log;
  198. Exp2;
  199. Log2;
  200. Sqrt;
  201. Inversesqrt;
  202. Abs;
  203. Sign;
  204. Floor;
  205. Ceil;
  206. Fract;
  207. Mod;
  208. Min;
  209. Max;
  210. Clamp;
  211. Mix;
  212. InvLerp;
  213. Step;
  214. Smoothstep;
  215. Length;
  216. Distance;
  217. Dot;
  218. Cross;
  219. Normalize;
  220. //Faceforward;
  221. LReflect;
  222. //Refract;
  223. //MatrixCompMult;
  224. //Any;
  225. //All;
  226. Texture;
  227. TextureLod;
  228. Texel;
  229. TextureSize;
  230. // ...other texture* operations
  231. // constructors
  232. ToInt;
  233. ToFloat;
  234. ToBool;
  235. Vec2;
  236. Vec3;
  237. Vec4;
  238. IVec2;
  239. IVec3;
  240. IVec4;
  241. BVec2;
  242. BVec3;
  243. BVec4;
  244. Mat2;
  245. Mat3;
  246. Mat4;
  247. // extra (not in GLSL ES)
  248. Mat3x4;
  249. Saturate;
  250. Pack;
  251. Unpack;
  252. PackNormal;
  253. UnpackNormal;
  254. ScreenToUv;
  255. UvToScreen;
  256. // extensions
  257. DFdx;
  258. DFdy;
  259. Fwidth;
  260. // debug / internal
  261. ChannelRead;
  262. ChannelReadLod;
  263. ChannelFetch;
  264. ChannelTextureSize;
  265. Trace;
  266. // instancing
  267. VertexID;
  268. InstanceID;
  269. // gl globals
  270. FragCoord;
  271. FrontFacing;
  272. // bit casting
  273. FloatBitsToInt;
  274. FloatBitsToUint;
  275. IntBitsToFloat;
  276. UintBitsToFloat;
  277. RoundEven;
  278. // compute
  279. SetLayout;
  280. ImageStore;
  281. ComputeVar_GlobalInvocation;
  282. ComputeVar_LocalInvocation;
  283. ComputeVar_WorkGroup;
  284. ComputeVar_LocalInvocationIndex;
  285. //ComputeVar_NumWorkGroups - no DirectX support
  286. //ComputeVar_WorkGroupSize - no DirectX support
  287. AtomicAdd;
  288. GroupMemoryBarrier;
  289. UnpackSnorm4x8;
  290. UnpackUnorm4x8;
  291. Transpose;
  292. }
  293. enum SyntaxArgAccess {
  294. Read;
  295. Write;
  296. ReadWrite;
  297. }
  298. typedef SyntaxArg = {
  299. e: TExpr,
  300. access: SyntaxArgAccess,
  301. }
  302. enum Component {
  303. X;
  304. Y;
  305. Z;
  306. W;
  307. }
  308. typedef TExpr = { e : TExprDef, t : Type, p : Position }
  309. typedef ShaderData = {
  310. var name : String;
  311. var vars : Array<TVar>;
  312. var funs : Array<TFunction>;
  313. }
  314. class Tools {
  315. static var UID = 0;
  316. public static var SWIZ = Component.createAll();
  317. public static var MAX_CHANNELS_BITS = 3;
  318. public static var MAX_PARTIAL_MAPPINGS_BITS = 7;
  319. public static function allocVarId() {
  320. // in order to prevent compile time ids to conflict with runtime allocated ones
  321. // let's use negative numbers for compile time ones
  322. #if macro
  323. return --UID;
  324. #else
  325. return ++UID;
  326. #end
  327. }
  328. public static function getTexUVSize( dim : TexDimension, arr = false ) {
  329. var size = switch( dim ) {
  330. case T1D: 1;
  331. case T2D: 2;
  332. case T3D, TCube: 3;
  333. }
  334. if( arr ) size++;
  335. return size;
  336. }
  337. public static function getDimSize( dim : TexDimension, arr = false ) {
  338. var size = switch( dim ){
  339. case T1D: 1;
  340. case T2D, TCube: 2;
  341. case T3D: 3;
  342. }
  343. if( arr ) size++;
  344. return size;
  345. }
  346. public static function getName( v : TVar ) {
  347. if( v.qualifiers == null )
  348. return v.name;
  349. for( q in v.qualifiers )
  350. switch( q ) {
  351. case Name(n): return n;
  352. default:
  353. }
  354. return v.name;
  355. }
  356. public static function getDoc( v : TVar ) {
  357. if ( v.qualifiers == null )
  358. return null;
  359. for ( q in v.qualifiers )
  360. switch ( q ) {
  361. case Doc(s): return s;
  362. default:
  363. }
  364. return null;
  365. }
  366. public static function getConstBits( v : TVar ) {
  367. switch( v.type ) {
  368. case TBool:
  369. return 1;
  370. case TInt:
  371. for( q in v.qualifiers )
  372. switch( q ) {
  373. case Const(n):
  374. if( n != null ) {
  375. var bits = 0;
  376. while( n >= 1 << bits )
  377. bits++;
  378. return bits;
  379. }
  380. return 8;
  381. default:
  382. }
  383. case TChannel(_):
  384. return 3 + MAX_CHANNELS_BITS;
  385. case TBuffer(_, _, Partial|StoragePartial|RWPartial):
  386. return MAX_PARTIAL_MAPPINGS_BITS;
  387. default:
  388. }
  389. return 0;
  390. }
  391. public static function isConst( v : TVar ) {
  392. if( v.type.match(TChannel(_)|TBuffer(_,_,Partial|StoragePartial|RWPartial)) )
  393. return true;
  394. if( v.qualifiers != null )
  395. for( q in v.qualifiers )
  396. switch( q ) {
  397. case Const(_): return true;
  398. default:
  399. }
  400. return false;
  401. }
  402. public static function isStruct( v : TVar ) {
  403. return switch( v.type ) { case TStruct(_): true; default: false; }
  404. }
  405. public static function isArray( v : TVar ) {
  406. return switch( v.type ) { case TArray(_): true; default: false; }
  407. }
  408. public static function hasQualifier( v : TVar, q ) {
  409. if( v.qualifiers != null )
  410. for( q2 in v.qualifiers )
  411. if( q2 == q )
  412. return true;
  413. return false;
  414. }
  415. public static function hasBorrowQualifier( v : TVar, path : String ) {
  416. if ( v.qualifiers != null )
  417. for( q in v.qualifiers )
  418. switch (q) {
  419. case Borrow(s): return path == s;
  420. default:
  421. }
  422. return false;
  423. }
  424. public static function isTexture( t : Type ) {
  425. return switch( t ) {
  426. case TSampler(_), TChannel(_), TRWTexture(_):
  427. true;
  428. default:
  429. false;
  430. }
  431. }
  432. public static function toString( t : Type ) {
  433. return switch( t ) {
  434. case TVec(size, t):
  435. var prefix = switch( t ) {
  436. case VFloat: "";
  437. case VInt: "i";
  438. case VBool: "b";
  439. }
  440. prefix + "vec" + size;
  441. case TStruct(vl):"{" + [for( v in vl ) v.name + " : " + toString(v.type)].join(",") + "}";
  442. case TArray(t, s): toString(t) + "[" + (switch( s ) { case SConst(i): "" + i; case SVar(v): v.name; } ) + "]";
  443. case TBuffer(t, s, k):
  444. var prefix = switch( k ) {
  445. case Uniform: "Buffer";
  446. case Storage: "StorageBuffer";
  447. case RW: "RWBuffer";
  448. case Partial: "PartialBuffer";
  449. case StoragePartial: "StoragePartialBuffer";
  450. case RWPartial: "RWPartialBuffer";
  451. };
  452. prefix+" "+toString(t) + "[" + (switch( s ) { case SConst(i): "" + i; case SVar(v): v.name; } ) + "]";
  453. case TBytes(n): "Bytes" + n;
  454. case TSampler(dim, arr):
  455. "Sampler"+dim.getName().substr(1)+(arr ? "Array":"");
  456. case TRWTexture(dim, arr,dims):
  457. "RWTexture"+dim.getName().substr(1)+(arr ? "Array":"")+"<"+(dims == 1 ? "Float" : "Vec"+dims)+">";
  458. default: t.getName().substr(1);
  459. }
  460. }
  461. public static function toType( t : VecType ) {
  462. return switch( t ) {
  463. case VFloat: TFloat;
  464. case VBool: TBool;
  465. case VInt: TInt;
  466. };
  467. }
  468. public static function hasSideEffect( e : TExpr ) {
  469. switch( e.e ) {
  470. case TParenthesis(e):
  471. return hasSideEffect(e);
  472. case TBlock(el), TArrayDecl(el):
  473. for( e in el )
  474. if( hasSideEffect(e) )
  475. return true;
  476. return false;
  477. case TBinop(OpAssign | OpAssignOp(_), _, _):
  478. return true;
  479. case TBinop(_, e1, e2):
  480. return hasSideEffect(e1) || hasSideEffect(e2);
  481. case TUnop(_, e1):
  482. return hasSideEffect(e1);
  483. case TSwiz(e, _):
  484. return hasSideEffect(e);
  485. case TIf(econd, eif, eelse):
  486. return hasSideEffect(econd) || hasSideEffect(eif) || (eelse != null && hasSideEffect(eelse));
  487. case TFor(_, it, loop):
  488. return hasSideEffect(it) || hasSideEffect(loop);
  489. case TArray(e, index):
  490. return hasSideEffect(e) || hasSideEffect(index);
  491. case TConst(_), TVar(_), TGlobal(_):
  492. return false;
  493. case TCall({ e : TGlobal(SetLayout) },_):
  494. return true;
  495. case TCall(e, pl):
  496. switch( e.e ) {
  497. case TGlobal( ImageStore | AtomicAdd | GroupMemoryBarrier ):
  498. return true;
  499. case TGlobal(g):
  500. default:
  501. return true;
  502. }
  503. for( p in pl )
  504. if( hasSideEffect(p) )
  505. return true;
  506. return false;
  507. case TVarDecl(_), TDiscard, TContinue, TBreak, TReturn(_), TSyntax(_, _, _):
  508. return true;
  509. case TSwitch(e, cases, def):
  510. for( c in cases ) {
  511. for( v in c.values ) if( hasSideEffect(v) ) return true;
  512. if( hasSideEffect(c.expr) ) return true;
  513. }
  514. return hasSideEffect(e) || (def != null && hasSideEffect(def));
  515. case TWhile(e, loop, _):
  516. return hasSideEffect(e) || hasSideEffect(loop);
  517. case TMeta(_, _, e):
  518. return hasSideEffect(e);
  519. case TField(e,_):
  520. return hasSideEffect(e);
  521. }
  522. }
  523. public static function iter( e : TExpr, f : TExpr -> Void ) {
  524. switch( e.e ) {
  525. case TParenthesis(e): f(e);
  526. case TBlock(el): for( e in el ) f(e);
  527. case TBinop(_, e1, e2): f(e1); f(e2);
  528. case TUnop(_, e1): f(e1);
  529. case TVarDecl(_,init): if( init != null ) f(init);
  530. case TCall(e, args): f(e); for( a in args ) f(a);
  531. case TSwiz(e, _): f(e);
  532. case TIf(econd, eif, eelse): f(econd); f(eif); if( eelse != null ) f(eelse);
  533. case TReturn(e): if( e != null ) f(e);
  534. case TFor(_, it, loop): f(it); f(loop);
  535. case TArray(e, index): f(e); f(index);
  536. case TArrayDecl(el): for( e in el ) f(e);
  537. case TSwitch(e, cases, def):
  538. f(e);
  539. for( c in cases ) {
  540. for( v in c.values ) f(v);
  541. f(c.expr);
  542. }
  543. if( def != null ) f(def);
  544. case TWhile(e, loop, _):
  545. f(e);
  546. f(loop);
  547. case TConst(_), TVar(_), TGlobal(_), TDiscard, TContinue, TBreak:
  548. case TMeta(_, _, e): f(e);
  549. case TField(e, _): f(e);
  550. case TSyntax(_, _, args): for (arg in args) f(arg.e);
  551. }
  552. }
  553. public static function map( e : TExpr, f : TExpr -> TExpr ) : TExpr {
  554. var ed = switch( e.e ) {
  555. case TParenthesis(e): TParenthesis(f(e));
  556. case TBlock(el): TBlock([for( e in el ) f(e)]);
  557. case TBinop(op, e1, e2): TBinop(op, f(e1), f(e2));
  558. case TUnop(op, e1): TUnop(op, f(e1));
  559. case TVarDecl(v,init): TVarDecl(v, if( init != null ) f(init) else null);
  560. case TCall(e, args): TCall(f(e),[for( a in args ) f(a)]);
  561. case TSwiz(e, c): TSwiz(f(e), c);
  562. case TIf(econd, eif, eelse): TIf(f(econd),f(eif),if( eelse != null ) f(eelse) else null);
  563. case TReturn(e): TReturn(if( e != null ) f(e) else null);
  564. case TFor(v, it, loop): TFor(v, f(it), f(loop));
  565. case TArray(e, index): TArray(f(e), f(index));
  566. case TArrayDecl(el): TArrayDecl([for( e in el ) f(e)]);
  567. case TSwitch(e, cases, def): TSwitch(f(e), [for( c in cases ) { values : [for( v in c.values ) f(v)], expr : f(c.expr) }], def == null ? null : f(def));
  568. case TWhile(e, loop, normalWhile): TWhile(f(e), f(loop), normalWhile);
  569. case TConst(_), TVar(_), TGlobal(_), TDiscard, TContinue, TBreak: e.e;
  570. case TMeta(m, args, e): TMeta(m, args, f(e)); // don't map args
  571. case TField(e, name): TField(f(e), name);
  572. case TSyntax(target, code, args): TSyntax(target, code, [for (arg in args) ({ e : f(arg.e), access : arg.access })]);
  573. }
  574. return { e : ed, t : e.t, p : e.p };
  575. }
  576. public static function size( t : Type ) {
  577. return switch( t ) {
  578. case TVoid: 0;
  579. case TFloat, TInt: 1;
  580. case TVec(n, _), TChannel(n): n;
  581. case TStruct(vl):
  582. var s = 0;
  583. for( v in vl ) s += size(v.type);
  584. return s;
  585. case TMat2: 4;
  586. case TMat3: 9;
  587. case TMat4: 16;
  588. case TMat3x4: 12;
  589. case TBytes(s): s;
  590. case TBool, TString, TSampler(_), TRWTexture(_), TFun(_): 0;
  591. case TArray(t, SConst(v)), TBuffer(t, SConst(v),_): size(t) * v;
  592. case TArray(_, SVar(_)), TBuffer(_): 0;
  593. }
  594. }
  595. #if !macro
  596. public static function evalConst( e : TExpr ) : Dynamic {
  597. return switch( e.e ) {
  598. case TConst(c):
  599. switch( c ) {
  600. case CNull: null;
  601. case CBool(b): b;
  602. case CInt(i): i;
  603. case CFloat(f): f;
  604. case CString(s): s;
  605. }
  606. case TCall({ e : TGlobal(Vec4) }, args):
  607. var vals = [for( a in args ) evalConst(a)];
  608. if( vals.length == 1 )
  609. return new Types.Vec4(vals[0], vals[0], vals[0], vals[0]);
  610. return new Types.Vec4(vals[0], vals[1], vals[2], vals[3]);
  611. case TCall({ e : TGlobal(Vec2 | Vec3) }, args):
  612. var vals = [for( a in args ) evalConst(a)];
  613. if( vals.length == 1 )
  614. return new Types.Vec(vals[0], vals[0], vals[0]);
  615. return new Types.Vec(vals[0], vals[1], vals[2]);
  616. default:
  617. throw "Unhandled constant init " + Printer.toString(e);
  618. }
  619. }
  620. #end
  621. }
  622. class Tools2 {
  623. public static function toString( g : TGlobal ) {
  624. var n = g.getName();
  625. return n.charAt(0).toLowerCase() + n.substr(1);
  626. }
  627. }
  628. class Tools3 {
  629. public static function toString( s : ShaderData ) {
  630. return Printer.shaderToString(s);
  631. }
  632. }
  633. class Tools4 {
  634. public static function toString( e : TExpr ) {
  635. return Printer.toString(e);
  636. }
  637. }