|
@@ -622,18 +622,22 @@ class Cache {
|
|
|
hasOffset.qualifiers = [Const()];
|
|
|
inputOffset.qualifiers = [PerInstance(1)];
|
|
|
|
|
|
+ var useStorage = declVar("Batch_UseStorage",TBool,Param);
|
|
|
var vcount = declVar("Batch_Count",TInt,Param);
|
|
|
- var vbuffer = declVar("Batch_Buffer",TBuffer(TVec(4,VFloat),SVar(vcount),Uniform),Param);
|
|
|
+ var vuniformBuffer = declVar("Batch_Buffer",TBuffer(TVec(4,VFloat),SVar(vcount),Uniform),Param);
|
|
|
+ var vstorageBuffer = declVar("Batch_StorageBuffer",TBuffer(TVec(4,VFloat),SConst(65535),RW),Param);
|
|
|
var voffset = declVar("Batch_Offset", TInt, Local);
|
|
|
- var ebuffer = { e : TVar(vbuffer), p : pos, t : vbuffer.type };
|
|
|
+ var euniformBuffer = { e : TVar(vuniformBuffer), p : pos, t : vuniformBuffer.type };
|
|
|
+ var estorageBuffer = { e : TVar(vstorageBuffer), p : pos, t : vstorageBuffer.type };
|
|
|
var eoffset = { e : TVar(voffset), p : pos, t : voffset.type };
|
|
|
var tvec4 = TVec(4,VFloat);
|
|
|
var countBits = 16;
|
|
|
vcount.qualifiers = [Const(1 << countBits)];
|
|
|
+ useStorage.qualifiers = [Const()];
|
|
|
|
|
|
s.data = {
|
|
|
name : "batchShader_"+id,
|
|
|
- vars : [vcount,hasOffset,vbuffer,voffset,inputOffset],
|
|
|
+ vars : [vcount,hasOffset,useStorage,vuniformBuffer,vstorageBuffer,voffset,inputOffset],
|
|
|
funs : [],
|
|
|
};
|
|
|
|
|
@@ -764,11 +768,11 @@ class Cache {
|
|
|
var parentVars = new Map();
|
|
|
var swiz = [[X],[Y],[Z],[W]];
|
|
|
|
|
|
- function readOffset( index : Int ) : TExpr {
|
|
|
+ function readOffset( ebuffer, index : Int ) : TExpr {
|
|
|
return { e : TArray(ebuffer,{ e : TBinop(OpAdd,eoffset,{ e : TConst(CInt(index)), t : TInt, p : pos }), t : TInt, p : pos }), t : tvec4, p : pos };
|
|
|
}
|
|
|
|
|
|
- function extractVar( v : AllocParam ) {
|
|
|
+ function declareLocalVar( v : AllocParam ) {
|
|
|
var vreal : TVar = declVar(v.name, v.type, Local);
|
|
|
if( v.perObjectGlobal != null ) {
|
|
|
var path = v.perObjectGlobal.path.split(".");
|
|
@@ -791,43 +795,49 @@ class Cache {
|
|
|
}
|
|
|
}
|
|
|
s.data.vars.push(vreal);
|
|
|
+ return vreal;
|
|
|
+ }
|
|
|
+
|
|
|
+ function extractVar( vreal, ebuffer, v : AllocParam ) {
|
|
|
var index = (v.pos>>2);
|
|
|
var extract = switch( v.type ) {
|
|
|
case TMat4:
|
|
|
{ p : pos, t : v.type, e : TCall({ e : TGlobal(Mat4), t : TVoid, p : pos },[
|
|
|
- readOffset(index),
|
|
|
- readOffset(index + 1),
|
|
|
- readOffset(index + 2),
|
|
|
- readOffset(index + 3),
|
|
|
+ readOffset(ebuffer, index),
|
|
|
+ readOffset(ebuffer, index + 1),
|
|
|
+ readOffset(ebuffer, index + 2),
|
|
|
+ readOffset(ebuffer, index + 3),
|
|
|
]) };
|
|
|
case TVec(4,VFloat):
|
|
|
- readOffset(index);
|
|
|
+ readOffset(ebuffer, index);
|
|
|
case TVec(3,VFloat):
|
|
|
- { p : pos, t : v.type, e : TSwiz(readOffset(index),v.pos&3 == 0 ? [X,Y,Z] : [Y,Z,W]) };
|
|
|
+ { p : pos, t : v.type, e : TSwiz(readOffset(ebuffer, index),v.pos&3 == 0 ? [X,Y,Z] : [Y,Z,W]) };
|
|
|
case TVec(2,VFloat):
|
|
|
var swiz = switch( v.pos & 3 ) {
|
|
|
case 0: [X,Y];
|
|
|
case 1: [Y,Z];
|
|
|
default: [Z,W];
|
|
|
}
|
|
|
- { p : pos, t : v.type, e : TSwiz(readOffset(index),swiz) };
|
|
|
+ { p : pos, t : v.type, e : TSwiz(readOffset(ebuffer, index),swiz) };
|
|
|
case TFloat:
|
|
|
- { p : pos, t : v.type, e : TSwiz(readOffset(index),swiz[v.pos&3]) }
|
|
|
+ { p : pos, t : v.type, e : TSwiz(readOffset(ebuffer, index),swiz[v.pos&3]) }
|
|
|
default:
|
|
|
throw "assert";
|
|
|
}
|
|
|
return { p : pos, e : TBinop(OpAssign, { e : TVar(vreal), p : pos, t : v.type }, extract), t : TVoid };
|
|
|
}
|
|
|
|
|
|
- var exprs = [];
|
|
|
+ var exprsUniform = [];
|
|
|
+ var exprsStorage = [];
|
|
|
var stride = used.length;
|
|
|
var p = params;
|
|
|
while( p != null ) {
|
|
|
- exprs.push(extractVar(p));
|
|
|
+ var vreal = declareLocalVar(p);
|
|
|
+ exprsUniform.push(extractVar(vreal, euniformBuffer, p));
|
|
|
+ exprsStorage.push(extractVar(vreal, estorageBuffer, p));
|
|
|
p = p.next;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
var inits = [];
|
|
|
|
|
|
inits.push({
|
|
@@ -853,19 +863,35 @@ class Cache {
|
|
|
e : TBinop(OpAssignOp(OpMult),eoffset,{ e : TConst(CInt(stride)), t : TInt, p : pos }),
|
|
|
});
|
|
|
|
|
|
+ inits.push({
|
|
|
+ p : pos,
|
|
|
+ e : TIf({ e : TVar(useStorage), t : TBool, p : pos },{
|
|
|
+ p : pos,
|
|
|
+ e : TBlock(exprsStorage),
|
|
|
+ t : TVoid,
|
|
|
+ }, {
|
|
|
+ p : pos,
|
|
|
+ e : TBlock(exprsUniform),
|
|
|
+ t : TVoid,
|
|
|
+ }),
|
|
|
+ t : TVoid,
|
|
|
+ });
|
|
|
+
|
|
|
var fv : TVar = declVar("init",TFun([]), Function);
|
|
|
var f : TFunction = {
|
|
|
kind : Init,
|
|
|
ref : fv,
|
|
|
args : [],
|
|
|
ret : TVoid,
|
|
|
- expr : { e : TBlock(inits.concat(exprs)), p : pos, t : TVoid },
|
|
|
+ expr : { e : TBlock(inits), p : pos, t : TVoid },
|
|
|
};
|
|
|
s.data.funs.push(f);
|
|
|
- s.consts = new SharedShader.ShaderConst(vcount,1,countBits+1);
|
|
|
+ s.consts = new SharedShader.ShaderConst(vcount,2,countBits+1);
|
|
|
s.consts.globalId = 0;
|
|
|
s.consts.next = new SharedShader.ShaderConst(hasOffset,0,1);
|
|
|
s.consts.next.globalId = 0;
|
|
|
+ s.consts.next.next = new SharedShader.ShaderConst(useStorage,1,1);
|
|
|
+ s.consts.next.next.globalId = 0;
|
|
|
|
|
|
return { shader : s, params : params, size : stride };
|
|
|
}
|