|
@@ -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;
|
|
|
}
|