|
@@ -31,6 +31,7 @@ class CacheFile extends Cache {
|
|
var shaders : Map<String,{ shader : SharedShader, version : String }> = new Map();
|
|
var shaders : Map<String,{ shader : SharedShader, version : String }> = new Map();
|
|
var runtimeShaders : Array<RuntimeShader> = [];
|
|
var runtimeShaders : Array<RuntimeShader> = [];
|
|
var linkers : Array<{ shader : Shader, vars : Array<hxsl.Output> }> = [];
|
|
var linkers : Array<{ shader : Shader, vars : Array<hxsl.Output> }> = [];
|
|
|
|
+ var batchers : Array<{ shader : SharedShader, rt : RuntimeShader }> = [];
|
|
|
|
|
|
// sources
|
|
// sources
|
|
var compiledSources : Map<String,{ vertex : String, fragment : String }> = new Map();
|
|
var compiledSources : Map<String,{ vertex : String, fragment : String }> = new Map();
|
|
@@ -69,6 +70,12 @@ class CacheFile extends Cache {
|
|
return shader;
|
|
return shader;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ override function createBatchShader( rt ) {
|
|
|
|
+ var b = super.createBatchShader(rt);
|
|
|
|
+ batchers.push({ rt : rt, shader : b });
|
|
|
|
+ return b;
|
|
|
|
+ }
|
|
|
|
+
|
|
static var HEX = "0123456789abcdef";
|
|
static var HEX = "0123456789abcdef";
|
|
|
|
|
|
function load() {
|
|
function load() {
|
|
@@ -97,7 +104,7 @@ class CacheFile extends Cache {
|
|
} else if( !allowCompile )
|
|
} else if( !allowCompile )
|
|
throw "Missing " + file;
|
|
throw "Missing " + file;
|
|
if( linkCache.linked == null ) {
|
|
if( linkCache.linked == null ) {
|
|
- var rt = link(makeDefaultShader());
|
|
|
|
|
|
+ var rt = link(makeDefaultShader(), false);
|
|
linkCache.linked = rt;
|
|
linkCache.linked = rt;
|
|
if( rt.vertex.code == null || rt.fragment.code == null ) {
|
|
if( rt.vertex.code == null || rt.fragment.code == null ) {
|
|
if( !allowCompile ) throw "Missing default shader code";
|
|
if( !allowCompile ) throw "Missing default shader code";
|
|
@@ -173,6 +180,16 @@ class CacheFile extends Cache {
|
|
linkMap.set(name, shader);
|
|
linkMap.set(name, shader);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ batchers = [];
|
|
|
|
+ var batchMap = new Map();
|
|
|
|
+ while( true ) {
|
|
|
|
+ skip();
|
|
|
|
+ var name = readString();
|
|
|
|
+ if( name == null ) break;
|
|
|
|
+ var rt = readString();
|
|
|
|
+ batchMap.set(name, rt);
|
|
|
|
+ }
|
|
|
|
+
|
|
shaders = new Map();
|
|
shaders = new Map();
|
|
while( true ) {
|
|
while( true ) {
|
|
skip();
|
|
skip();
|
|
@@ -207,8 +224,12 @@ class CacheFile extends Cache {
|
|
var inst = [for( i in 0...f.readByte() ) {
|
|
var inst = [for( i in 0...f.readByte() ) {
|
|
var name = readString();
|
|
var name = readString();
|
|
var shader = shaders.get(name);
|
|
var shader = shaders.get(name);
|
|
- if( shader == null ) missingShader = true;
|
|
|
|
- { shader : shader, bits : readIntHex(), index : f.readByte() };
|
|
|
|
|
|
+ var batch = null;
|
|
|
|
+ if( shader == null ) {
|
|
|
|
+ batch = batchMap.get(name);
|
|
|
|
+ if( batch == null ) missingShader = true;
|
|
|
|
+ }
|
|
|
|
+ { shader : shader, batch : batch, bits : readIntHex(), index : f.readByte() };
|
|
}];
|
|
}];
|
|
var sign = readString();
|
|
var sign = readString();
|
|
if( missingShader ) continue;
|
|
if( missingShader ) continue;
|
|
@@ -219,14 +240,26 @@ class CacheFile extends Cache {
|
|
|
|
|
|
// recompile or load runtime shaders
|
|
// recompile or load runtime shaders
|
|
runtimeShaders = [];
|
|
runtimeShaders = [];
|
|
|
|
+ var rttMap = new Map<String,RuntimeShader>();
|
|
if( recompileRT ) {
|
|
if( recompileRT ) {
|
|
|
|
|
|
for( r in runtimes ) {
|
|
for( r in runtimes ) {
|
|
var shaderList = null;
|
|
var shaderList = null;
|
|
|
|
+ var batchMode = false;
|
|
r.inst.reverse();
|
|
r.inst.reverse();
|
|
for( i in r.inst ) {
|
|
for( i in r.inst ) {
|
|
var s = Type.createEmptyInstance(hxsl.Shader);
|
|
var s = Type.createEmptyInstance(hxsl.Shader);
|
|
@:privateAccess {
|
|
@:privateAccess {
|
|
|
|
+ if( i.shader == null ) {
|
|
|
|
+ var rt = rttMap.get(i.batch);
|
|
|
|
+ if( rt == null ) {
|
|
|
|
+ r = null; // was modified
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ var sh = makeBatchShader(rt);
|
|
|
|
+ i.shader = { version : null, shader : sh.shader };
|
|
|
|
+ batchMode = true;
|
|
|
|
+ }
|
|
s.constBits = i.bits;
|
|
s.constBits = i.bits;
|
|
s.shader = i.shader.shader;
|
|
s.shader = i.shader.shader;
|
|
s.instance = i.shader.shader.getInstance(i.bits);
|
|
s.instance = i.shader.shader.getInstance(i.bits);
|
|
@@ -234,10 +267,12 @@ class CacheFile extends Cache {
|
|
}
|
|
}
|
|
shaderList = new hxsl.ShaderList(s, shaderList);
|
|
shaderList = new hxsl.ShaderList(s, shaderList);
|
|
}
|
|
}
|
|
- var rt = link(shaderList); // will compile + update linkMap
|
|
|
|
|
|
+ if( r == null ) continue;
|
|
|
|
+ var rt = link(shaderList, batchMode); // will compile + update linkMap
|
|
if( rt.spec.signature != r.specSign )
|
|
if( rt.spec.signature != r.specSign )
|
|
throw "assert";
|
|
throw "assert";
|
|
runtimeShaders.push(rt);
|
|
runtimeShaders.push(rt);
|
|
|
|
+ rttMap.set(r.specSign, rt);
|
|
}
|
|
}
|
|
|
|
|
|
} else {
|
|
} else {
|
|
@@ -262,6 +297,16 @@ class CacheFile extends Cache {
|
|
for( i in spec.inst ) {
|
|
for( i in spec.inst ) {
|
|
var s = Type.createEmptyInstance(hxsl.Shader);
|
|
var s = Type.createEmptyInstance(hxsl.Shader);
|
|
@:privateAccess {
|
|
@:privateAccess {
|
|
|
|
+ if( i.shader == null ) {
|
|
|
|
+ var rt = rttMap.get(i.batch);
|
|
|
|
+ if( rt == null ) {
|
|
|
|
+ r = null; // was modified
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ var sh = makeBatchShader(rt);
|
|
|
|
+ i.shader = { version : null, shader : sh.shader };
|
|
|
|
+ r.batchMode = true;
|
|
|
|
+ }
|
|
// pseudo instance
|
|
// pseudo instance
|
|
var scache = i.shader.shader.instanceCache;
|
|
var scache = i.shader.shader.instanceCache;
|
|
var inst = scache.get(i.bits);
|
|
var inst = scache.get(i.bits);
|
|
@@ -276,9 +321,11 @@ class CacheFile extends Cache {
|
|
}
|
|
}
|
|
shaderList = new hxsl.ShaderList(s, shaderList);
|
|
shaderList = new hxsl.ShaderList(s, shaderList);
|
|
}
|
|
}
|
|
|
|
+ if( r == null ) continue;
|
|
addToCache(r, shaderList);
|
|
addToCache(r, shaderList);
|
|
reviveRuntime(r);
|
|
reviveRuntime(r);
|
|
runtimeShaders.push(r);
|
|
runtimeShaders.push(r);
|
|
|
|
+ rttMap.set(spec.specSign, r);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
@@ -411,6 +458,16 @@ class CacheFile extends Cache {
|
|
separator();
|
|
separator();
|
|
writeString(null);
|
|
writeString(null);
|
|
|
|
|
|
|
|
+ // batchers
|
|
|
|
+ batchers.sort(function(l1, l2) return @:privateAccess Reflect.compare(l1.shader.data.name,l2.shader.data.name));
|
|
|
|
+ for( b in batchers ) {
|
|
|
|
+ separator();
|
|
|
|
+ writeString(@:privateAccess b.shader.data.name);
|
|
|
|
+ writeString(@:privateAccess b.rt.spec.signature);
|
|
|
|
+ }
|
|
|
|
+ separator();
|
|
|
|
+ writeString(null);
|
|
|
|
+
|
|
// shaders
|
|
// shaders
|
|
var shaders = [for( s in shaders ) s];
|
|
var shaders = [for( s in shaders ) s];
|
|
shaders.sort(function(s1, s2) return Reflect.compare(s1.version, s2.version));
|
|
shaders.sort(function(s1, s2) return Reflect.compare(s1.version, s2.version));
|
|
@@ -514,12 +571,15 @@ class CacheFile extends Cache {
|
|
rc.paramsSize = r.paramsSize;
|
|
rc.paramsSize = r.paramsSize;
|
|
rc.globalsSize = r.globalsSize;
|
|
rc.globalsSize = r.globalsSize;
|
|
rc.texturesCount = r.texturesCount;
|
|
rc.texturesCount = r.texturesCount;
|
|
|
|
+ rc.bufferCount = r.bufferCount;
|
|
if( r.params != null )
|
|
if( r.params != null )
|
|
rc.params = r.params.clone(true);
|
|
rc.params = r.params.clone(true);
|
|
if( r.globals != null )
|
|
if( r.globals != null )
|
|
rc.globals = r.globals.clone(true);
|
|
rc.globals = r.globals.clone(true);
|
|
if( r.textures != null )
|
|
if( r.textures != null )
|
|
rc.textures = r.textures.clone(true);
|
|
rc.textures = r.textures.clone(true);
|
|
|
|
+ if( r.buffers != null )
|
|
|
|
+ rc.buffers = r.buffers.clone(true);
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -547,11 +607,14 @@ class CacheFile extends Cache {
|
|
}
|
|
}
|
|
rvParam(rd.params);
|
|
rvParam(rd.params);
|
|
rvParam(rd.textures);
|
|
rvParam(rd.textures);
|
|
|
|
+ rvParam(rd.buffers);
|
|
rvGlobal(rd.globals);
|
|
rvGlobal(rd.globals);
|
|
initGlobals(r, rd);
|
|
initGlobals(r, rd);
|
|
}
|
|
}
|
|
|
|
|
|
function sortBySpec( r1 : RuntimeShader, r2 : RuntimeShader ) {
|
|
function sortBySpec( r1 : RuntimeShader, r2 : RuntimeShader ) {
|
|
|
|
+ if( r1.batchMode != r2.batchMode )
|
|
|
|
+ return r1.batchMode ? 1 : -1;
|
|
var minLen = hxd.Math.imin(r1.spec.instances.length, r2.spec.instances.length);
|
|
var minLen = hxd.Math.imin(r1.spec.instances.length, r2.spec.instances.length);
|
|
for( i in 0...minLen ) {
|
|
for( i in 0...minLen ) {
|
|
var i1 = r1.spec.instances[i];
|
|
var i1 = r1.spec.instances[i];
|
|
@@ -581,19 +644,19 @@ class CacheFile extends Cache {
|
|
|
|
|
|
public dynamic function onMissingShader(shaders:hxsl.ShaderList) {
|
|
public dynamic function onMissingShader(shaders:hxsl.ShaderList) {
|
|
log("Missing shader " + [for( s in shaders ) @:privateAccess s.instance.shader.name+":" + s.priority]);
|
|
log("Missing shader " + [for( s in shaders ) @:privateAccess s.instance.shader.name+":" + s.priority]);
|
|
- return link(null); // default fallback
|
|
|
|
|
|
+ return link(null, false); // default fallback
|
|
}
|
|
}
|
|
|
|
|
|
public dynamic function onNewShader(r:RuntimeShader) {
|
|
public dynamic function onNewShader(r:RuntimeShader) {
|
|
log("Compiled " + [for( i in r.spec.instances ) i.shader.data.name+(i.bits == 0 ? "" : ":" + StringTools.hex(i.bits))].join(" "));
|
|
log("Compiled " + [for( i in r.spec.instances ) i.shader.data.name+(i.bits == 0 ? "" : ":" + StringTools.hex(i.bits))].join(" "));
|
|
}
|
|
}
|
|
|
|
|
|
- override function compileRuntimeShader(shaders:hxsl.ShaderList) {
|
|
|
|
|
|
+ override function compileRuntimeShader(shaders:hxsl.ShaderList, batchMode) {
|
|
if( isLoading )
|
|
if( isLoading )
|
|
- return super.compileRuntimeShader(shaders);
|
|
|
|
|
|
+ return super.compileRuntimeShader(shaders, batchMode);
|
|
if( allowCompile ) {
|
|
if( allowCompile ) {
|
|
// was not found in previous cache, let's compile and cache it
|
|
// was not found in previous cache, let's compile and cache it
|
|
- var s = super.compileRuntimeShader(shaders);
|
|
|
|
|
|
+ var s = super.compileRuntimeShader(shaders, batchMode);
|
|
onNewShader(s);
|
|
onNewShader(s);
|
|
waitCount++;
|
|
waitCount++;
|
|
haxe.Timer.delay(function() addNewShader(s), 0);
|
|
haxe.Timer.delay(function() addNewShader(s), 0);
|
|
@@ -612,6 +675,8 @@ class CacheFile extends Cache {
|
|
for( i in s.spec.instances ) {
|
|
for( i in s.spec.instances ) {
|
|
var inst = shaders.get(i.shader.data.name);
|
|
var inst = shaders.get(i.shader.data.name);
|
|
if( inst == null ) {
|
|
if( inst == null ) {
|
|
|
|
+ if( s.batchMode && StringTools.startsWith(i.shader.data.name,"batchShader_") )
|
|
|
|
+ continue;
|
|
var version = getShaderVersion(i.shader);
|
|
var version = getShaderVersion(i.shader);
|
|
inst = { shader : i.shader, version : version };
|
|
inst = { shader : i.shader, version : version };
|
|
shaders.set(i.shader.data.name, inst);
|
|
shaders.set(i.shader.data.name, inst);
|