Browse Source

added final var in shader declaration and static const in hlslout

Nicolas Cannasse 1 năm trước cách đây
mục cha
commit
897e04165d

+ 1 - 0
hxsl/Ast.hx

@@ -91,6 +91,7 @@ enum VarQualifier {
 	Doc( s : String );
 	Doc( s : String );
 	Borrow( source : String );
 	Borrow( source : String );
 	Sampler( name : String );
 	Sampler( name : String );
+	Final;
 }
 }
 
 
 enum Prec {
 enum Prec {

+ 6 - 1
hxsl/Checker.hx

@@ -364,7 +364,9 @@ class Checker {
 		switch( e.e ) {
 		switch( e.e ) {
 		case TVar(v):
 		case TVar(v):
 			switch( v.kind ) {
 			switch( v.kind ) {
-			case Local, Var, Output:
+			case Var, Output:
+				return;
+			case Local if( v.qualifiers == null || v.qualifiers.indexOf(Final) < 0 ):
 				return;
 				return;
 			case Param if( v.type.match(TBuffer(_,_,RW)) ):
 			case Param if( v.type.match(TBuffer(_,_,RW)) ):
 				return;
 				return;
@@ -749,6 +751,8 @@ class Checker {
 					continue;
 					continue;
 				if( einit != null )
 				if( einit != null )
 					inits.push({ v : v, e : einit });
 					inits.push({ v : v, e : einit });
+				else if( v.qualifiers != null && v.qualifiers.indexOf(Final) >= 0 )
+					error("Final variable needs initializer", e.pos);
 				vars.set(v.name, v);
 				vars.set(v.name, v);
 			}
 			}
 		case ECall( { expr : EIdent("import") }, [e]):
 		case ECall( { expr : EIdent("import") }, [e]):
@@ -834,6 +838,7 @@ class Checker {
 						p = p.parent;
 						p = p.parent;
 					}
 					}
 					if( tv.kind != Global && tv.kind != Param ) error("@const only allowed on parameter or global", pos);
 					if( tv.kind != Global && tv.kind != Param ) error("@const only allowed on parameter or global", pos);
+				case Final: if( tv.kind != Local ) error("final only allowed on local", pos);
 				case PerObject: if( tv.kind != Global ) error("@perObject only allowed on global", pos);
 				case PerObject: if( tv.kind != Global ) error("@perObject only allowed on global", pos);
 				case PerInstance(_): if( tv.kind != Input && tv.kind != Param && (tv.kind != Global || v.qualifiers.indexOf(PerObject) < 0) ) error("@perInstance only allowed on input/param", pos);
 				case PerInstance(_): if( tv.kind != Input && tv.kind != Param && (tv.kind != Global || v.qualifiers.indexOf(PerObject) < 0) ) error("@perInstance only allowed on input/param", pos);
 				case Nullable: if( tv.kind != Param ) error("@nullable only allowed on parameter or global", pos);
 				case Nullable: if( tv.kind != Param ) error("@nullable only allowed on parameter or global", pos);

+ 39 - 1
hxsl/HlslOut.hx

@@ -96,6 +96,7 @@ class HlslOut {
 	var SV_InstanceID = "SV_InstanceID";
 	var SV_InstanceID = "SV_InstanceID";
 	var SV_IsFrontFace = "SV_IsFrontFace";
 	var SV_IsFrontFace = "SV_IsFrontFace";
 	var STATIC = "static ";
 	var STATIC = "static ";
+	var CONST = "const ";
 	var buf : StringBuf;
 	var buf : StringBuf;
 	var exprIds = 0;
 	var exprIds = 0;
 	var exprValues : Array<String>;
 	var exprValues : Array<String>;
@@ -467,7 +468,10 @@ class HlslOut {
 				add(i);
 				add(i);
 				add("] = ");
 				add("] = ");
 				addExpr(el[i], tabs);
 				addExpr(el[i], tabs);
-				newLine(el[i]);
+				if( i < el.length - 1 ) {
+					newLine(el[i]);
+					add(tabs);
+				}
 			}
 			}
 		case TBinop(OpAssign,evar = { e : TVar(_) },{ e : TArrayDecl(el) }):
 		case TBinop(OpAssign,evar = { e : TVar(_) },{ e : TArrayDecl(el) }):
 			for( i in 0...el.length ) {
 			for( i in 0...el.length ) {
@@ -476,6 +480,10 @@ class HlslOut {
 				add(i);
 				add(i);
 				add("] = ");
 				add("] = ");
 				addExpr(el[i], tabs);
 				addExpr(el[i], tabs);
+				if( i < el.length - 1 ) {
+					newLine(el[i]);
+					add(tabs);
+				}
 			}
 			}
 		case TArrayDecl(el):
 		case TArrayDecl(el):
 			add("{");
 			add("{");
@@ -828,8 +836,32 @@ class HlslOut {
 		add("\n");
 		add("\n");
 		for( v in s.vars )
 		for( v in s.vars )
 			if( v.kind == Local ) {
 			if( v.kind == Local ) {
+				var isConst = v.qualifiers != null && v.qualifiers.indexOf(Final) >= 0;
 				add(STATIC);
 				add(STATIC);
+				if( isConst )
+					add(CONST);
 				addVar(v);
 				addVar(v);
+				if( isConst ) {
+					var found = null;
+					for( f in s.funs ) {
+						switch( f.expr.e ) {
+						case TBlock(el):
+							for( e in el ) {
+								switch( e.e ) {
+								case TBinop(OpAssign, { e : TVar(v2) }, einit) if( v2 == v ):
+									found = einit;
+									break;
+								default:
+								}
+							}
+						default:
+						}
+					}
+					if( found == null )
+						throw "Constant variable "+v.name+" is missing initializer";
+					add(" = ");
+					addExpr(found,"");
+				}
 				add(";\n");
 				add(";\n");
 			}
 			}
 		add("\n");
 		add("\n");
@@ -845,6 +877,12 @@ class HlslOut {
 		switch( expr.e ) {
 		switch( expr.e ) {
 		case TBlock(el):
 		case TBlock(el):
 			for( e in el ) {
 			for( e in el ) {
+				switch( e.e ) {
+				case TBinop(OpAssign,evar = { e : TVar(v) },_) if( v.qualifiers != null && v.qualifiers.indexOf(Final) >= 0 ):
+					// ignore (is a static const)
+					continue;
+				default:
+				}
 				add("\t");
 				add("\t");
 				addExpr(e, "\t");
 				addExpr(e, "\t");
 				newLine(e);
 				newLine(e);

+ 1 - 1
hxsl/MacroParser.hx

@@ -188,7 +188,7 @@ class MacroParser {
 					expr : v.expr == null ? null : parseExpr(v.expr),
 					expr : v.expr == null ? null : parseExpr(v.expr),
 					type : v.type == null ? null : parseType(v.type, e.pos),
 					type : v.type == null ? null : parseType(v.type, e.pos),
 					kind : null,
 					kind : null,
-					qualifiers : [],
+					qualifiers : v.isFinal ? [Final] : [],
 				}
 				}
 			}]);
 			}]);
 		case EFunction(FNamed(name,_),f) if( f.expr != null ):
 		case EFunction(FNamed(name,_),f) if( f.expr != null ):

+ 1 - 0
hxsl/Printer.hx

@@ -64,6 +64,7 @@ class Printer {
 				case Doc(s): "doc(\"" + StringTools.replace(s, '"', '\\"') + "\")";
 				case Doc(s): "doc(\"" + StringTools.replace(s, '"', '\\"') + "\")";
 				case Borrow(s): "borrow(" + s + ")";
 				case Borrow(s): "borrow(" + s + ")";
 				case Sampler(s): "sampler("+ s + ")";
 				case Sampler(s): "sampler("+ s + ")";
+				case Final: "final";
 				}) + " ");
 				}) + " ");
 		}
 		}
 		if( v.kind != defKind )
 		if( v.kind != defKind )

+ 2 - 1
hxsl/Serializer.hx

@@ -191,7 +191,7 @@ class Serializer {
 			for( q in v.qualifiers ) {
 			for( q in v.qualifiers ) {
 				out.addByte(q.getIndex());
 				out.addByte(q.getIndex());
 				switch (q) {
 				switch (q) {
-				case Private, Nullable, PerObject, Shared, Ignore:
+				case Private, Nullable, PerObject, Shared, Ignore, Final:
 				case Const(max): out.addInt32(max == null ? 0 : max);
 				case Const(max): out.addInt32(max == null ? 0 : max);
 				case Name(n): writeString(n);
 				case Name(n): writeString(n);
 				case Precision(p): out.addByte(p.getIndex());
 				case Precision(p): out.addByte(p.getIndex());
@@ -416,6 +416,7 @@ class Serializer {
 				case 10: Doc(readString());
 				case 10: Doc(readString());
 				case 11: Borrow(readString());
 				case 11: Borrow(readString());
 				case 12: Sampler(readString());
 				case 12: Sampler(readString());
+				case 13: Final;
 				default: throw "assert";
 				default: throw "assert";
 				}
 				}
 				v.qualifiers.push(q);
 				v.qualifiers.push(q);

+ 2 - 0
hxsl/Splitter.hx

@@ -244,6 +244,8 @@ class Splitter {
 						kind : v.kind,
 						kind : v.kind,
 						type : v.type,
 						type : v.type,
 					};
 					};
+					if( v.qualifiers != null && v.qualifiers.indexOf(Final) >= 0 )
+						nv.qualifiers = [Final];
 					uniqueName(nv);
 					uniqueName(nv);
 				}
 				}
 				varMap.set(v,nv);
 				varMap.set(v,nv);