|
@@ -2,15 +2,11 @@ package h3d.pass;
|
|
|
|
|
|
class ShaderManager {
|
|
class ShaderManager {
|
|
|
|
|
|
- public static var STRICT = true;
|
|
|
|
-
|
|
|
|
- public var globals : hxsl.Globals;
|
|
|
|
var shaderCache : hxsl.Cache;
|
|
var shaderCache : hxsl.Cache;
|
|
var currentOutput : hxsl.ShaderList;
|
|
var currentOutput : hxsl.ShaderList;
|
|
|
|
|
|
public function new(?output:Array<hxsl.Output>) {
|
|
public function new(?output:Array<hxsl.Output>) {
|
|
shaderCache = hxsl.Cache.get();
|
|
shaderCache = hxsl.Cache.get();
|
|
- globals = new hxsl.Globals();
|
|
|
|
currentOutput = new hxsl.ShaderList(null);
|
|
currentOutput = new hxsl.ShaderList(null);
|
|
setOutput(output);
|
|
setOutput(output);
|
|
}
|
|
}
|
|
@@ -20,257 +16,7 @@ class ShaderManager {
|
|
currentOutput.s = shaderCache.getLinkShader(output);
|
|
currentOutput.s = shaderCache.getLinkShader(output);
|
|
}
|
|
}
|
|
|
|
|
|
- @:noDebug
|
|
|
|
- function fillRec( v : Dynamic, type : hxsl.Ast.Type, out : #if hl hl.BytesAccess<hl.F32> #else h3d.shader.Buffers.ShaderBufferData #end, pos : Int ) {
|
|
|
|
- switch( type ) {
|
|
|
|
- case TInt:
|
|
|
|
- out[pos] = v;
|
|
|
|
- return 1;
|
|
|
|
- case TFloat:
|
|
|
|
- out[pos] = v;
|
|
|
|
- return 1;
|
|
|
|
- case TVec(4, _):
|
|
|
|
- var v : hxsl.Types.Vec4 = v;
|
|
|
|
- out[pos++] = v.x;
|
|
|
|
- out[pos++] = v.y;
|
|
|
|
- out[pos++] = v.z;
|
|
|
|
- out[pos++] = v.w;
|
|
|
|
- return 4;
|
|
|
|
- case TVec(n, _):
|
|
|
|
- var v : hxsl.Types.Vec = v;
|
|
|
|
- out[pos++] = v.x;
|
|
|
|
- out[pos++] = v.y;
|
|
|
|
- if( n == 3 )
|
|
|
|
- out[pos++] = v.z;
|
|
|
|
- return n;
|
|
|
|
- case TMat4:
|
|
|
|
- var m : h3d.Matrix = v;
|
|
|
|
- out[pos++] = m._11;
|
|
|
|
- out[pos++] = m._21;
|
|
|
|
- out[pos++] = m._31;
|
|
|
|
- out[pos++] = m._41;
|
|
|
|
- out[pos++] = m._12;
|
|
|
|
- out[pos++] = m._22;
|
|
|
|
- out[pos++] = m._32;
|
|
|
|
- out[pos++] = m._42;
|
|
|
|
- out[pos++] = m._13;
|
|
|
|
- out[pos++] = m._23;
|
|
|
|
- out[pos++] = m._33;
|
|
|
|
- out[pos++] = m._43;
|
|
|
|
- out[pos++] = m._14;
|
|
|
|
- out[pos++] = m._24;
|
|
|
|
- out[pos++] = m._34;
|
|
|
|
- out[pos++] = m._44;
|
|
|
|
- return 16;
|
|
|
|
- case TMat3x4:
|
|
|
|
- var m : h3d.Matrix = v;
|
|
|
|
- out[pos++] = m._11;
|
|
|
|
- out[pos++] = m._21;
|
|
|
|
- out[pos++] = m._31;
|
|
|
|
- out[pos++] = m._41;
|
|
|
|
- out[pos++] = m._12;
|
|
|
|
- out[pos++] = m._22;
|
|
|
|
- out[pos++] = m._32;
|
|
|
|
- out[pos++] = m._42;
|
|
|
|
- out[pos++] = m._13;
|
|
|
|
- out[pos++] = m._23;
|
|
|
|
- out[pos++] = m._33;
|
|
|
|
- out[pos++] = m._43;
|
|
|
|
- return 12;
|
|
|
|
- case TMat3:
|
|
|
|
- var m : h3d.Matrix = v;
|
|
|
|
- out[pos++] = m._11;
|
|
|
|
- out[pos++] = m._21;
|
|
|
|
- out[pos++] = m._31;
|
|
|
|
- out[pos++] = 0;
|
|
|
|
- out[pos++] = m._12;
|
|
|
|
- out[pos++] = m._22;
|
|
|
|
- out[pos++] = m._32;
|
|
|
|
- out[pos++] = 0;
|
|
|
|
- out[pos++] = m._13;
|
|
|
|
- out[pos++] = m._23;
|
|
|
|
- out[pos++] = m._33;
|
|
|
|
- out[pos++] = 0;
|
|
|
|
- return 12;
|
|
|
|
- case TArray(TVec(4,VFloat), SConst(len)):
|
|
|
|
- var v : Array<h3d.Vector4> = v;
|
|
|
|
- for( i in 0...len ) {
|
|
|
|
- var n = v[i];
|
|
|
|
- if( n == null ) break;
|
|
|
|
- out[pos++] = n.x;
|
|
|
|
- out[pos++] = n.y;
|
|
|
|
- out[pos++] = n.z;
|
|
|
|
- out[pos++] = n.w;
|
|
|
|
- }
|
|
|
|
- return len * 4;
|
|
|
|
- case TArray(TMat3x4, SConst(len)):
|
|
|
|
- var v : Array<h3d.Matrix> = v;
|
|
|
|
- for( i in 0...len ) {
|
|
|
|
- var m = v[i];
|
|
|
|
- if( m == null ) break;
|
|
|
|
- out[pos++] = m._11;
|
|
|
|
- out[pos++] = m._21;
|
|
|
|
- out[pos++] = m._31;
|
|
|
|
- out[pos++] = m._41;
|
|
|
|
- out[pos++] = m._12;
|
|
|
|
- out[pos++] = m._22;
|
|
|
|
- out[pos++] = m._32;
|
|
|
|
- out[pos++] = m._42;
|
|
|
|
- out[pos++] = m._13;
|
|
|
|
- out[pos++] = m._23;
|
|
|
|
- out[pos++] = m._33;
|
|
|
|
- out[pos++] = m._43;
|
|
|
|
- }
|
|
|
|
- return len * 12;
|
|
|
|
- case TArray(TFloat, SConst(len)):
|
|
|
|
- var v : Array<Float> = v;
|
|
|
|
- var size = 0;
|
|
|
|
- var count = v.length < len ? v.length : len;
|
|
|
|
- for( i in 0...count )
|
|
|
|
- out[pos++] = v[i];
|
|
|
|
- return len;
|
|
|
|
- case TArray(t, SConst(len)):
|
|
|
|
- var v : Array<Dynamic> = v;
|
|
|
|
- var size = 0;
|
|
|
|
- for( i in 0...len ) {
|
|
|
|
- var n = v[i];
|
|
|
|
- if( n == null ) break;
|
|
|
|
- size = fillRec(n, t, out, pos);
|
|
|
|
- pos += size;
|
|
|
|
- }
|
|
|
|
- return len * size;
|
|
|
|
- case TStruct(vl):
|
|
|
|
- var tot = 0;
|
|
|
|
- for( vv in vl )
|
|
|
|
- tot += fillRec(Reflect.field(v, vv.name), vv.type, out, pos + tot);
|
|
|
|
- return tot;
|
|
|
|
- default:
|
|
|
|
- throw "assert " + type;
|
|
|
|
- }
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function shaderInfo( shaders : hxsl.ShaderList, path : String ) {
|
|
|
|
- var name = path.split(".").pop();
|
|
|
|
- while( shaders != null ) {
|
|
|
|
- var inst = @:privateAccess shaders.s.instance;
|
|
|
|
- for( v in inst.shader.vars )
|
|
|
|
- if( v.name == name )
|
|
|
|
- return shaders.s.toString();
|
|
|
|
- shaders = shaders.next;
|
|
|
|
- }
|
|
|
|
- return "(not found)";
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- inline function getPtr( data : h3d.shader.Buffers.ShaderBufferData ) {
|
|
|
|
- #if hl
|
|
|
|
- return (hl.Bytes.getArray((cast data : Array<Single>)) : hl.BytesAccess<hl.F32>);
|
|
|
|
- #else
|
|
|
|
- return data;
|
|
|
|
- #end
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public inline function getParamValue( p : hxsl.RuntimeShader.AllocParam, shaders : hxsl.ShaderList, opt = false ) : Dynamic {
|
|
|
|
- if( p.perObjectGlobal != null ) {
|
|
|
|
- var v : Dynamic = globals.fastGet(p.perObjectGlobal.gid);
|
|
|
|
- if( v == null ) throw "Missing global value " + p.perObjectGlobal.path+" for shader "+shaderInfo(shaders,p.perObjectGlobal.path);
|
|
|
|
- if( p.type.match(TChannel(_)) )
|
|
|
|
- return v.texture;
|
|
|
|
- return v;
|
|
|
|
- }
|
|
|
|
- var si = shaders;
|
|
|
|
- var n = p.instance;
|
|
|
|
- while( --n > 0 ) si = si.next;
|
|
|
|
- var v = si.s.getParamValue(p.index);
|
|
|
|
- if( v == null && !opt ) throw "Missing param value " + si.s + "." + p.name;
|
|
|
|
- return v;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public function fillGlobals( buf : h3d.shader.Buffers, s : hxsl.RuntimeShader ) {
|
|
|
|
- inline function fill(buf:h3d.shader.Buffers.ShaderBuffers, s:hxsl.RuntimeShader.RuntimeShaderData) {
|
|
|
|
- var g = s.globals;
|
|
|
|
- var ptr = getPtr(buf.globals);
|
|
|
|
- while( g != null ) {
|
|
|
|
- var v = globals.fastGet(g.gid);
|
|
|
|
- if( v == null )
|
|
|
|
- throw "Missing global value " + g.path;
|
|
|
|
- fillRec(v, g.type, ptr, g.pos);
|
|
|
|
- g = g.next;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- fill(buf.vertex, s.vertex);
|
|
|
|
- fill(buf.fragment, s.fragment);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public function fillParams( buf : h3d.shader.Buffers, s : hxsl.RuntimeShader, shaders : hxsl.ShaderList ) {
|
|
|
|
- var curInstance = -1;
|
|
|
|
- var curInstanceValue = null;
|
|
|
|
- inline function getInstance( index : Int ) {
|
|
|
|
- if( curInstance == index )
|
|
|
|
- return curInstanceValue;
|
|
|
|
- var si = shaders;
|
|
|
|
- curInstance = index;
|
|
|
|
- while( --index > 0 ) si = si.next;
|
|
|
|
- curInstanceValue = si.s;
|
|
|
|
- return curInstanceValue;
|
|
|
|
- }
|
|
|
|
- inline function getParamValue( p : hxsl.RuntimeShader.AllocParam, shaders : hxsl.ShaderList, opt = false ) : Dynamic {
|
|
|
|
- if( p.perObjectGlobal != null ) {
|
|
|
|
- var v : Dynamic = globals.fastGet(p.perObjectGlobal.gid);
|
|
|
|
- if( v == null ) throw "Missing global value " + p.perObjectGlobal.path+" for shader "+shaderInfo(shaders,p.perObjectGlobal.path);
|
|
|
|
- if( p.type.match(TChannel(_)) )
|
|
|
|
- return v.texture;
|
|
|
|
- return v;
|
|
|
|
- }
|
|
|
|
- var v = getInstance(p.instance).getParamValue(p.index);
|
|
|
|
- if( v == null && !opt ) throw "Missing param value " + shaders.s + "." + p.name;
|
|
|
|
- return v;
|
|
|
|
- }
|
|
|
|
- inline function fill(buf:h3d.shader.Buffers.ShaderBuffers, s:hxsl.RuntimeShader.RuntimeShaderData) {
|
|
|
|
- var p = s.params;
|
|
|
|
- var ptr = getPtr(buf.params);
|
|
|
|
- while( p != null ) {
|
|
|
|
- var v : Dynamic;
|
|
|
|
- if( p.perObjectGlobal == null ) {
|
|
|
|
- if( p.type == TFloat ) {
|
|
|
|
- var i = getInstance(p.instance);
|
|
|
|
- ptr[p.pos] = i.getParamFloatValue(p.index);
|
|
|
|
- p = p.next;
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- v = getInstance(p.instance).getParamValue(p.index);
|
|
|
|
- if( v == null ) throw "Missing param value " + curInstanceValue + "." + p.name;
|
|
|
|
- } else
|
|
|
|
- v = getParamValue(p, shaders);
|
|
|
|
- fillRec(v, p.type, ptr, p.pos);
|
|
|
|
- p = p.next;
|
|
|
|
- }
|
|
|
|
- var tid = 0;
|
|
|
|
- var p = s.textures;
|
|
|
|
- while( p != null ) {
|
|
|
|
- var t : Dynamic = getParamValue(p, shaders, !STRICT);
|
|
|
|
- if( p.pos < 0 ) {
|
|
|
|
- // is array !
|
|
|
|
- var arr : Array<h3d.mat.Texture> = t;
|
|
|
|
- for( i in 0...-p.pos )
|
|
|
|
- buf.tex[tid++] = arr[i];
|
|
|
|
- } else
|
|
|
|
- buf.tex[tid++] = t;
|
|
|
|
- p = p.next;
|
|
|
|
- }
|
|
|
|
- var p = s.buffers;
|
|
|
|
- var bid = 0;
|
|
|
|
- while( p != null ) {
|
|
|
|
- var b : h3d.Buffer = getParamValue(p, shaders, !STRICT);
|
|
|
|
- buf.buffers[bid++] = b;
|
|
|
|
- p = p.next;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- fill(buf.vertex, s.vertex);
|
|
|
|
- fill(buf.fragment, s.fragment);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public function compileShaders( shaders : hxsl.ShaderList, mode : hxsl.RuntimeShader.LinkMode = Default ) {
|
|
|
|
|
|
+ public function compileShaders( globals : hxsl.Globals, shaders : hxsl.ShaderList, mode : hxsl.RuntimeShader.LinkMode = Default ) {
|
|
globals.resetChannels();
|
|
globals.resetChannels();
|
|
for( s in shaders ) s.updateConstants(globals);
|
|
for( s in shaders ) s.updateConstants(globals);
|
|
currentOutput.next = shaders;
|
|
currentOutput.next = shaders;
|