Sfoglia il codice sorgente

fixed support for arrays and structs

Nicolas Cannasse 11 anni fa
parent
commit
c35f2a0b9d
1 ha cambiato i file con 54 aggiunte e 38 eliminazioni
  1. 54 38
      hxsl/Flatten.hx

+ 54 - 38
hxsl/Flatten.hx

@@ -7,9 +7,9 @@ private class Alloc {
 	public var size : Int;
 	public var g : TVar;
 	public var v : Null<TVar>;
-	public function new(g, pos, size) {
+	public function new(g, t, pos, size) {
 		this.g = g;
-		this.t = switch( g.type ) { case TVec(_, t): t; default: throw "assert"; };
+		this.t = t;
 		this.pos = pos;
 		this.size = size;
 	}
@@ -47,50 +47,61 @@ class Flatten {
 	}
 	
 	function mapExpr( e : TExpr ) : TExpr {
-		inline function mkInt(v:Int) {
-			return { e : TConst(CInt(v)), t : TInt, p : e.p };
-		}
 		e = switch( e.e ) {
 		case TVar(v):
 			var a = varMap.get(v);
-			inline function access( index : Int ) : TExpr {
-				return { e : TArray({ e : TVar(a.g), t : a.g.type, p : e.p },mkInt((a.pos>>2)+index)), t : TVec(4,a.t), p : e.p }
-			}
 			if( a == null )
 				e
-			else if( a.size <= 4 ) {
-				var k = access(0);
-				if( a.size == 4 ) {
+			else
+				access(a,v.type, e.p);
+		default:
+			e.map(mapExpr);
+		};
+		return optimize(e);
+	}
+	
+	function access( a : Alloc, t : Type, pos : Position ) : TExpr {
+		inline function mkInt(v:Int) {
+			return { e : TConst(CInt(v)), t : TInt, p : pos };
+		}
+		inline function read( index : Int ) : TExpr {
+			return { e : TArray({ e : TVar(a.g), t : a.g.type, p : pos },mkInt((a.pos>>2)+index)), t : TVec(4,a.t), p : pos }
+		}
+		switch( t ) {
+		case TMat4:
+			return { e : TCall( { e : TGlobal(Mat4), t : TFun([]), p : pos }, [
+				read(0),
+				read(1),
+				read(2),
+				read(3),
+			]), t : TMat4, p : pos }
+		case TMat3x4:
+			return { e : TCall( { e : TGlobal(Mat3x4), t : TFun([]), p : pos }, [
+				read(0),
+				read(1),
+				read(2),
+			]), t : TMat3x4, p : pos }
+		case TArray(t, SConst(len)):
+			var stride = Std.int(a.size / len);
+			return { e : TArrayDecl([for( i in 0...len ) access(new Alloc(a.g, a.t, a.pos + stride * i, stride), t, pos)]), t : t, p : pos };
+		default:
+			var size = varSize(t, a.t);
+			if( size <= 4 ) {
+				var k = read(0);
+				if( size == 4 ) {
 					if( a.pos & 3 != 0 ) throw "assert";
-					k;
+					return k;
 				} else {
 					var sw = [];
-					for( i in 0...a.size )
+					for( i in 0...size )
 						sw.push(Tools.SWIZ[i + (a.pos & 3)]);
-					{ e : TSwiz(k, sw), t : v.type, p : e.p };
+					return { e : TSwiz(k, sw), t : t, p : pos };
 				}
-			} else switch( v.type ) {
-			case TMat4:
-				{ e : TCall( { e : TGlobal(Mat4), t : TFun([]), p : e.p }, [
-					access(0),
-					access(1),
-					access(2),
-					access(3),
-				]), t : TMat4, p : e.p }
-			case TMat3x4:
-				{ e : TCall( { e : TGlobal(Mat3x4), t : TFun([]), p : e.p }, [
-					access(0),
-					access(1),
-					access(2),
-				]), t : TMat3x4, p : e.p }
-			default:
-				throw "TODO "+v.type.toString();
 			}
-		default:
-			e.map(mapExpr);
-		};
-		return optimize(e);
+			return Error.t("Access not supported for " + t.toString(), null);
+		}
 	}
+
 	
 	function optimize( e : TExpr ) {
 		switch( e.e ) {
@@ -108,6 +119,8 @@ class Flatten {
 				var emat = switch( e.e ) { case TCall(e, _): e; default: throw "assert"; };
 				return { e : TCall(emat, args), t : e.t, p : e.p };
 			}
+		case TArray( { e : TArrayDecl(el) }, { e : TConst(CInt(i)) } ) if( i >= 0 && i < el.length ):
+			return el[i];
 		default:
 		}
 		return e;
@@ -135,21 +148,21 @@ class Flatten {
 				var free = best.size - size;
 				if( free > 0 ) {
 					var i = Lambda.indexOf(alloc, best);
-					var a = new Alloc(g, best.pos + size, free);
+					var a = new Alloc(g, t, best.pos + size, free);
 					alloc.insert(i + 1, a);
 					best.size = size;
 				}
 				best.v = v;
 				varMap.set(v, best);
 			} else {
-				var a = new Alloc(g, apos, size);
+				var a = new Alloc(g, t, apos, size);
 				apos += size;
 				a.v = v;
 				varMap.set(v, a);
 				alloc.push(a);
 				var pad = (4 - (size % 4)) % 4;
 				if( pad > 0 ) {
-					var a = new Alloc(g, apos, pad);
+					var a = new Alloc(g, t, apos, pad);
 					apos += pad;
 					alloc.push(a);
 				}
@@ -168,7 +181,10 @@ class Flatten {
 		case TMat4 if( t == VFloat ): 16;
 		case TMat3x4 if( t == VFloat ): 12;
 		case TMat3 if( t == VFloat ): 9;
-		case TArray(at, SConst(n)): varSize(at, t) * n;
+		case TArray(at, SConst(n)):
+			var s = varSize(at, t);
+			s += (4 - (s & 3)) & 3;
+			s * n;
 		default:
 			throw v.toString() + " size unknown for type " + t;
 		}