浏览代码

added TMeta, added @unroll to force loop unroll, eliminateConditionals is now optional

ncannasse 8 年之前
父节点
当前提交
fb65850224
共有 7 个文件被更改,包括 62 次插入14 次删除
  1. 3 3
      h3d/shader/Blur.hx
  2. 7 1
      hxsl/Ast.hx
  3. 8 0
      hxsl/Checker.hx
  4. 15 2
      hxsl/Eval.hx
  5. 1 1
      hxsl/MacroParser.hx
  6. 25 7
      hxsl/Printer.hx
  7. 3 0
      hxsl/SharedShader.hx

+ 3 - 3
h3d/shader/Blur.hx

@@ -27,7 +27,7 @@ class Blur extends ScreenShader {
 				var ccur = texture.get(input.uv);
 				var color = vec4(0, 0, 0, 0);
 				var ncur = unpackNormal(normalTexture.get(input.uv));
-				for( i in -Quality + 1...Quality ) {
+				@unroll for( i in -Quality + 1...Quality ) {
 					var uv = input.uv + pixel * float(i);
 					var c = texture.get(uv);
 					var p = getPosition(uv);
@@ -42,12 +42,12 @@ class Blur extends ScreenShader {
 			}
 			else if( isDepth ) {
 				var val = 0.;
-				for( i in -Quality + 1...Quality )
+				@unroll for( i in -Quality + 1...Quality )
 					val += unpack(texture.get(input.uv + pixel * float(i))) * values[i < 0 ? -i : i];
 				output.color = pack(val.min(0.9999999));
 			} else {
 				var color = vec4(0, 0, 0, 0);
-				for( i in -Quality + 1...Quality )
+				@unroll for( i in -Quality + 1...Quality )
 					color += texture.get(input.uv + pixel * float(i)) * values[i < 0 ? -i : i];
 				output.color = color;
 			}

+ 7 - 1
hxsl/Ast.hx

@@ -130,6 +130,7 @@ enum ExprDef {
 	EArrayDecl( el : Array<Expr> );
 	ESwitch( e : Expr, cases : Array<{ values : Array<Expr>, expr:Expr }>, def : Null<Expr> );
 	EWhile( cond : Expr, loop : Expr, normalWhile : Bool );
+	EMeta( name : String, args : Array<Expr>, e : Expr );
 }
 
 typedef TVar = {
@@ -259,6 +260,7 @@ enum TExprDef {
 	TArrayDecl( el : Array<TExpr> );
 	TSwitch( e : TExpr, cases : Array<{ values : Array<TExpr>, expr:TExpr }>, def : Null<TExpr> );
 	TWhile( e : TExpr, loop : TExpr, normalWhile : Bool );
+	TMeta( m : String, args : Array<Const>, e : TExpr );
 }
 
 typedef TExpr = { e : TExprDef, t : Type, p : Position }
@@ -402,6 +404,8 @@ class Tools {
 			return hasSideEffect(e) || (def != null && hasSideEffect(def));
 		case TWhile(e, loop, _):
 			return hasSideEffect(e) || hasSideEffect(loop);
+		case TMeta(_, _, e):
+			return hasSideEffect(e);
 		}
 	}
 
@@ -429,7 +433,8 @@ class Tools {
 		case TWhile(e, loop, _):
 			f(e);
 			f(loop);
-		case TConst(_),TVar(_),TGlobal(_), TDiscard, TContinue, TBreak:
+		case TConst(_), TVar(_), TGlobal(_), TDiscard, TContinue, TBreak:
+		case TMeta(_, _, e): f(e);
 		}
 	}
 
@@ -450,6 +455,7 @@ class Tools {
 		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));
 		case TWhile(e, loop, normalWhile): TWhile(f(e), f(loop), normalWhile);
 		case TConst(_), TVar(_), TGlobal(_), TDiscard, TContinue, TBreak: e.e;
+		case TMeta(m, args, e): TMeta(m, args, f(e)); // don't map args
 		}
 		return { e : ed, t : e.t, p : e.p };
 	}

+ 8 - 0
hxsl/Checker.hx

@@ -262,6 +262,14 @@ class Checker {
 			case CFloat(_): TFloat;
 			};
 			TConst(c);
+		case EMeta(name, args, e):
+			var e = typeExpr(e, with);
+			type = e.t;
+			TMeta(name, [for( c in args ) switch( c.expr ) {
+				case EConst(c): c;
+				case EIdent(i): CString(i); // convert ident to string
+				default: error("Metadata parameter should be constant", c.pos);
+			}], e);
 		case EBlock(el):
 			var old = saveVars();
 			var el = el.copy(), tl = [];

+ 15 - 2
hxsl/Eval.hx

@@ -11,6 +11,7 @@ class Eval {
 	public var varMap : Map<TVar,TVar>;
 	public var inlineCalls : Bool;
 	public var unrollLoops : Bool;
+	public var eliminateConditionals : Bool;
 	var constants : Map<TVar,TExprDef>;
 	var funMap : Map<TVar,TFunction>;
 	var curFun : TFunction;
@@ -360,8 +361,8 @@ class Eval {
 			switch( econd.e ) {
 			case TConst(CBool(b)): b ? evalExpr(eif, isVal).e : eelse == null ? TConst(CNull) : evalExpr(eelse, isVal).e;
 			default:
-				if( isVal && eelse != null )
-					TCall( { e : TGlobal(Mix), t : e.t, p : e.p }, [eelse, eif, { e : TCall( { e : TGlobal(ToFloat), t : TFun([]), p : econd.p }, [econd]), t : TFloat, p : e.p } ]);
+				if( isVal && eelse != null && eliminateConditionals )
+					TCall( { e : TGlobal(Mix), t : e.t, p : e.p }, [evalExpr(eelse,true), evalExpr(eif,true), { e : TCall( { e : TGlobal(ToFloat), t : TFun([]), p : econd.p }, [econd]), t : TFloat, p : e.p } ]);
 				else
 					TIf(econd, evalExpr(eif,isVal), eelse == null ? null : evalExpr(eelse,isVal));
 			}
@@ -428,6 +429,18 @@ class Eval {
 				def.e;
 		case TArrayDecl(el):
 			TArrayDecl([for( e in el ) evalExpr(e)]);
+		case TMeta(name, args, e):
+			var e2;
+			switch( name ) {
+			case "unroll":
+				var old = unrollLoops;
+				unrollLoops = true;
+				e2 = evalExpr(e, isVal);
+				unrollLoops = false;
+			default:
+				e2 = evalExpr(e, isVal);
+			}
+			TMeta(name, args, e2);
 		};
 		return { e : d, t : e.t, p : e.p }
 	}

+ 1 - 1
hxsl/MacroParser.hx

@@ -142,7 +142,7 @@ class MacroParser {
 				case ":import":
 					ECall({ expr : EIdent("import"), pos : m.pos }, [e2]);
 				default:
-					error("Qualifier only supported before 'var'", e.pos);
+					EMeta(m.name, [for( e in m.params ) parseExpr(e)], e2);
 				}
 			}
 		case EVars(vl):

+ 25 - 7
hxsl/Printer.hx

@@ -127,6 +127,16 @@ class Printer {
 
 	static var SWIZ = ["x", "y", "z", "w"];
 
+	function addConst( c : Const ) {
+		add(switch(c) {
+		case CNull: "null";
+		case CBool(b): b;
+		case CInt(i): i;
+		case CFloat(f): f;
+		case CString(s): '"' + s + '"';
+		});
+	}
+
 	function addExpr( e : TExpr, tabs : String ) : Void {
 		switch( e.e ) {
 		case TVar(v):
@@ -242,13 +252,7 @@ class Printer {
 			addExpr(e, tabs);
 			add(")");
 		case TConst(c):
-			add(switch(c) {
-			case CNull: "null";
-			case CBool(b): b;
-			case CInt(i): i;
-			case CFloat(f): f;
-			case CString(s): '"' + s + '"';
-			});
+			addConst(c);
 		case TArrayDecl(el):
 			add("[");
 			var first = true;
@@ -275,7 +279,21 @@ class Printer {
 			addExpr(loop,tabs);
 			tabs = old;
 			add("\n" + tabs + "}");
+		case TMeta(m, args, e):
+			add(m);
+			if( args.length > 0 ) {
+				add("(");
+				var first = true;
+				for( c in args ) {
+					if( first ) first = false else add(", ");
+					addConst(c);
+				}
+				add(")");
+			}
+			add(" ");
+			addExpr(e, tabs);
 		}
+
 	}
 
 	public static function opStr( op : Ast.Binop ) {

+ 3 - 0
hxsl/SharedShader.hx

@@ -69,6 +69,9 @@ class SharedShader {
 			c = c.next;
 		}
 		eval.inlineCalls = true;
+		#if flash
+		eval.eliminateConditionals = true;
+		#end
 		#if (js || flash)
 		eval.unrollLoops = true;
 		#end