瀏覽代碼

move globals from ShaderManager to RenderContext (shared by default)

Nicolas Cannasse 1 年之前
父節點
當前提交
471f947c78

+ 1 - 1
h2d/Drawable.hx

@@ -146,7 +146,7 @@ class Drawable extends Object {
 	public function getDebugShaderCode( toHxsl = true ) {
 		var shader = @:privateAccess {
 			var ctx = getScene().ctx;
-			ctx.manager.compileShaders(new hxsl.ShaderList(ctx.baseShader,shaders));
+			ctx.manager.compileShaders(ctx.globals, new hxsl.ShaderList(ctx.baseShader,shaders));
 		}
 		if( toHxsl ) {
 			var toString = hxsl.Printer.shaderToString.bind(_, true);

+ 9 - 8
h2d/RenderContext.hx

@@ -173,12 +173,12 @@ class RenderContext extends h3d.impl.RenderContext {
 		viewD = scene.viewportD;
 		viewX = scene.viewportX;
 		viewY = scene.viewportY;
-
+		setCurrent();
 		targetFlipY = engine.driver.hasFeature(BottomLeftCoords) ? -1 : 1;
 		baseFlipY = engine.getCurrentTarget() != null ? targetFlipY : 1;
 		inFilter = null;
-		manager.globals.set("time", time);
-		manager.globals.set("global.time", time);
+		globals.set("time", time);
+		globals.set("global.time", time);
 		baseShader.pixelAlign = false;
 		baseShader.halfPixelInverse.set(0.5 / engine.width, 0.5 / engine.height);
 		baseShader.viewportA.set(scene.viewportA, 0, scene.viewportX);
@@ -210,12 +210,12 @@ class RenderContext extends h3d.impl.RenderContext {
 
 	function initShaders( shaders ) {
 		currentShaders = shaders;
-		compiledShader = manager.compileShaders(shaders);
+		compiledShader = manager.compileShaders(globals, shaders);
 		if( buffers == null )
 			buffers = new h3d.shader.Buffers(compiledShader);
 		else
 			buffers.grow(compiledShader);
-		manager.fillGlobals(buffers, compiledShader);
+		manager.fillGlobals(globals, buffers, compiledShader);
 		engine.selectShader(compiledShader);
 		engine.uploadShaderBuffers(buffers, Globals);
 	}
@@ -230,6 +230,7 @@ class RenderContext extends h3d.impl.RenderContext {
 		texture = null;
 		currentObj = null;
 		baseShaderList.next = null;
+		clearCurrent();
 		if ( targetsStackIndex != 0 ) throw "Missing popTarget()";
 		if ( cameraStackIndex != 0 ) throw "Missing popCamera()";
 	}
@@ -611,7 +612,7 @@ class RenderContext extends h3d.impl.RenderContext {
 					pass.blendSrc = One;
 			}
 		}
-		manager.fillParams(buffers, compiledShader, currentShaders);
+		manager.fillParams(globals, buffers, compiledShader, currentShaders);
 		engine.selectMaterial(pass);
 		engine.uploadShaderBuffers(buffers, Params);
 		engine.uploadShaderBuffers(buffers, Textures);
@@ -773,7 +774,7 @@ class RenderContext extends h3d.impl.RenderContext {
 			var prevInst = @:privateAccess t.instance;
 			if( s != t )
 				paramsChanged = true;
-			s.updateConstants(manager.globals);
+			s.updateConstants(globals);
 			if( @:privateAccess s.instance != prevInst )
 				shaderChanged = true;
 		}
@@ -784,7 +785,7 @@ class RenderContext extends h3d.impl.RenderContext {
 			baseShader.hasUVPos = hasUVPos;
 			baseShader.isRelative = isRelative;
 			baseShader.killAlpha = killAlpha;
-			baseShader.updateConstants(manager.globals);
+			baseShader.updateConstants(globals);
 			baseShaderList.next = obj.shaders;
 			initShaders(baseShaderList);
 		} else if( paramsChanged ) {

+ 3 - 0
h2d/Scene.hx

@@ -739,6 +739,7 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 		var inRender = @:privateAccess ctx.engine.inRender;
 		ctx.engine.backgroundColor = null; // prevent clear bg
 		ctx.globalAlpha = alpha;
+		var prevCtx = h3d.impl.RenderContext.get();
 		if( !inRender ) { // don't reset current tex stack
 			ctx.engine.begin();
 			ctx.begin();
@@ -754,6 +755,8 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 			ctx.end();
 			ctx.engine.end();
 		}
+		if( prevCtx != null )
+			prevCtx.setCurrent();
 	}
 
 	/**

+ 21 - 1
h3d/impl/RenderContext.hx

@@ -7,16 +7,36 @@ class RenderContext {
 	public var elapsedTime : Float;
 	public var frame : Int;
 	public var textures : h3d.impl.TextureCache;
+	public var globals : hxsl.Globals;
 
 	function new() {
 		engine = h3d.Engine.getCurrent();
 		frame = 0;
 		time = 0.;
 		elapsedTime = 1. / hxd.System.getDefaultFrameRate();
-		textures = new h3d.impl.TextureCache(this);
+		textures = new h3d.impl.TextureCache();
+		globals = new hxsl.Globals();
+	}
+
+	public function setCurrent() {
+		inst = this;
+	}
+
+	public function clearCurrent() {
+		if( inst == this )
+			inst = null;
+		else
+			throw "Context has changed";
 	}
 
 	public function dispose() {
 		textures.dispose();
 	}
+
+	static var inst : RenderContext;
+	public static function get() return inst;
+	public static inline function getType<T:RenderContext>( cl : Class<h3d.impl.RenderContext> ) {
+		return Std.downcast(inst, cl);
+	}
+
 }

+ 1 - 3
h3d/impl/TextureCache.hx

@@ -5,11 +5,9 @@ class TextureCache {
 	var cache : Array<h3d.mat.Texture>;
 	var position : Int = 0;
 	var defaultDepthBuffer : h3d.mat.Texture;
-	var ctx : h3d.impl.RenderContext;
 	public var defaultFormat : hxd.PixelFormat;
 
-	public function new(ctx) {
-		this.ctx = ctx;
+	public function new() {
 		cache = [];
 		var engine = h3d.Engine.getCurrent();
 		defaultFormat = h3d.mat.Texture.nativeFormat;

+ 6 - 8
h3d/pass/Default.hx

@@ -8,7 +8,7 @@ class Default extends Base {
 	var globals(get, never) : hxsl.Globals;
 	var defaultSort = new SortByMaterial().sort;
 
-	inline function get_globals() return manager.globals;
+	inline function get_globals() return ctx.globals;
 
 	@global("camera.view") var cameraView : h3d.Matrix = ctx.camera.mcam;
 	@global("camera.zNear") var cameraNear : Float = ctx.camera.zNear;
@@ -43,7 +43,7 @@ class Default extends Base {
 		var o = @:privateAccess new h3d.pass.PassObject();
 		o.pass = p;
 		setupShaders(new h3d.pass.PassList(o));
-		return manager.compileShaders(o.shaders, p.batchMode ? Batch : Default);
+		return manager.compileShaders(ctx.globals, o.shaders, p.batchMode ? Batch : Default);
 	}
 
 	function processShaders( p : h3d.pass.PassObject, shaders : hxsl.ShaderList ) {
@@ -68,13 +68,13 @@ class Default extends Base {
 				}
 				shaders = ctx.lightSystem.computeLight(p.obj, shaders);
 			}
-			p.shader = manager.compileShaders(shaders, p.pass.batchMode ? Batch : Default);
+			p.shader = manager.compileShaders(ctx.globals, shaders, p.pass.batchMode ? Batch : Default);
 			p.shaders = shaders;
 			var t = p.shader.fragment.textures;
 			if( t == null || t.type.match(TArray(_)) )
 				p.texture = 0;
 			else {
-				var t : h3d.mat.Texture = manager.getParamValue(t, shaders, true);
+				var t : h3d.mat.Texture = manager.getParamValue(ctx.globals, t, shaders, true);
 				p.texture = t == null ? 0 : t.id;
 			}
 		}
@@ -97,8 +97,6 @@ class Default extends Base {
 		if( passes.isEmpty() )
 			return;
 		#if sceneprof h3d.impl.SceneProf.begin("draw", ctx.frame); #end
-		for( g in ctx.sharedGlobals )
-			globals.fastSet(g.gid, g.value);
 		setGlobals();
 		setupShaders(passes);
 		if( sort == null )
@@ -128,11 +126,11 @@ class Default extends Base {
 					buf = ctx.shaderBuffers = new h3d.shader.Buffers(p.shader);
 				else
 					buf.grow(p.shader);
-				manager.fillGlobals(buf, p.shader);
+				manager.fillGlobals(ctx.globals, buf, p.shader);
 				ctx.engine.uploadShaderBuffers(buf, Globals);
 			}
 			if( !p.pass.dynamicParameters ) {
-				manager.fillParams(buf, p.shader, p.shaders);
+				manager.fillParams(ctx.globals, buf, p.shader, p.shaders);
 				ctx.engine.uploadShaderBuffers(buf, Params);
 				ctx.engine.uploadShaderBuffers(buf, Textures);
 				ctx.engine.uploadShaderBuffers(buf, Buffers);

+ 5 - 5
h3d/pass/DefaultShadowMap.hx

@@ -26,11 +26,11 @@ class DefaultShadowMap extends DirShadowMap {
 
 	override function draw( passes, ?sort ) {
 		super.draw(passes, sort);
-		ctx.setGlobalID(shadowMapId, { texture : dshader.shadowMap, channel : format == h3d.mat.Texture.nativeFormat ? hxsl.Channel.PackedFloat : hxsl.Channel.R });
-		ctx.setGlobalID(shadowProjId, getShadowProj());
-		ctx.setGlobalID(shadowColorId, color);
-		ctx.setGlobalID(shadowPowerId, power);
-		ctx.setGlobalID(shadowBiasId, bias);
+		ctx.globals.fastSet(shadowMapId, { texture : dshader.shadowMap, channel : format == h3d.mat.Texture.nativeFormat ? hxsl.Channel.PackedFloat : hxsl.Channel.R });
+		ctx.globals.fastSet(shadowProjId, getShadowProj());
+		ctx.globals.fastSet(shadowColorId, color);
+		ctx.globals.fastSet(shadowPowerId, power);
+		ctx.globals.fastSet(shadowBiasId, bias);
 	}
 
 }

+ 5 - 8
h3d/pass/ScreenFx.hx

@@ -27,11 +27,6 @@ class ScreenFx<T:h3d.shader.ScreenShader> {
 		h3d.pass.Copy.run(src,dst);
 	}
 
-	public function setGlobals( ctx :  h3d.scene.RenderContext ) {
-		for( g in @:privateAccess ctx.sharedGlobals )
-			manager.globals.fastSet(g.gid, g.value);
-	}
-
 	public inline function addShader<T:hxsl.Shader>(s:T) {
 		return pass.addShader(s);
 	}
@@ -49,15 +44,17 @@ class ScreenFx<T:h3d.shader.ScreenShader> {
 			primitive = h3d.prim.Plane2D.get();
 		shader.flipY = engine.driver.hasFeature(BottomLeftCoords) && engine.getCurrentTarget() != null ? -1 : 1;
 		var shaders = @:privateAccess pass.shaders;
-		var rts = manager.compileShaders(shaders);
+		var ctx = h3d.impl.RenderContext.get();
+		var globals = ctx == null ? new hxsl.Globals() : ctx.globals;
+		var rts = manager.compileShaders(globals, shaders);
 		engine.selectMaterial(pass);
 		engine.selectShader(rts);
 		if( buffers == null )
 			buffers = new h3d.shader.Buffers(rts);
 		else
 			buffers.grow(rts);
-		manager.fillGlobals(buffers, rts);
-		manager.fillParams(buffers, rts, shaders);
+		manager.fillGlobals(globals, buffers, rts);
+		manager.fillParams(globals, buffers, rts, shaders);
 		engine.uploadShaderBuffers(buffers, Globals);
 		engine.uploadShaderBuffers(buffers, Params);
 		engine.uploadShaderBuffers(buffers, Textures);

+ 4 - 6
h3d/pass/ShaderManager.hx

@@ -4,13 +4,11 @@ class ShaderManager {
 
 	public static var STRICT = true;
 
-	public var globals : hxsl.Globals;
 	var shaderCache : hxsl.Cache;
 	var currentOutput : hxsl.ShaderList;
 
 	public function new(?output:Array<hxsl.Output>) {
 		shaderCache = hxsl.Cache.get();
-		globals = new hxsl.Globals();
 		currentOutput = new hxsl.ShaderList(null);
 		setOutput(output);
 	}
@@ -170,7 +168,7 @@ class ShaderManager {
 		#end
 	}
 
-	public inline function getParamValue( p : hxsl.RuntimeShader.AllocParam, shaders : hxsl.ShaderList, opt = false ) : Dynamic {
+	public inline function getParamValue( globals : hxsl.Globals, 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);
@@ -186,7 +184,7 @@ class ShaderManager {
 		return v;
 	}
 
-	public function fillGlobals( buf : h3d.shader.Buffers, s : hxsl.RuntimeShader ) {
+	public function fillGlobals( globals : hxsl.Globals, 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);
@@ -202,7 +200,7 @@ class ShaderManager {
 		fill(buf.fragment, s.fragment);
 	}
 
-	public function fillParams( buf : h3d.shader.Buffers, s : hxsl.RuntimeShader, shaders : hxsl.ShaderList ) {
+	public function fillParams( globals : hxsl.Globals, buf : h3d.shader.Buffers, s : hxsl.RuntimeShader, shaders : hxsl.ShaderList ) {
 		var curInstance = -1;
 		var curInstanceValue = null;
 		inline function getInstance( index : Int ) {
@@ -270,7 +268,7 @@ class ShaderManager {
 		fill(buf.fragment, s.fragment);
 	}
 
-	public function compileShaders( shaders : hxsl.ShaderList, mode : hxsl.Linker.LinkMode = Default ) {
+	public function compileShaders( globals : hxsl.Globals, shaders : hxsl.ShaderList, mode : hxsl.Linker.LinkMode = Default ) {
 		globals.resetChannels();
 		for( s in shaders ) s.updateConstants(globals);
 		currentOutput.next = shaders;

+ 1 - 1
h3d/scene/MeshBatch.hx

@@ -121,7 +121,7 @@ class MeshBatch extends MultiMaterial {
 
 				var manager = cast(ctx,h3d.pass.Default).manager;
 				var shaders = p.getShadersRec();
-				var rt = manager.compileShaders(shaders, Default);
+				var rt = manager.compileShaders(scene.ctx.globals, shaders, Default);
 				var shader = manager.shaderCache.makeBatchShader(rt, shaders, instancedParams);
 
 				var b = new BatchData();

+ 7 - 21
h3d/scene/RenderContext.hx

@@ -17,7 +17,6 @@ class RenderContext extends h3d.impl.RenderContext {
 	public var pbrLightPass : h3d.mat.Pass;
 	public var computingStatic : Bool;
 
-	var sharedGlobals : Array<SharedGlobal>;
 	public var lightSystem : h3d.scene.LightSystem;
 	public var extraShaders : hxsl.ShaderList;
 	public var visibleFlag : Bool;
@@ -52,7 +51,6 @@ class RenderContext extends h3d.impl.RenderContext {
 	}
 
 	public function start() {
-		sharedGlobals = [];
 		lights = null;
 		drawPass = null;
 		passes = [];
@@ -61,6 +59,7 @@ class RenderContext extends h3d.impl.RenderContext {
 		visibleFlag = true;
 		time += elapsedTime;
 		frame++;
+		setCurrent();
 	}
 
 	public inline function nextPass() {
@@ -68,25 +67,11 @@ class RenderContext extends h3d.impl.RenderContext {
 		drawPass = null;
 	}
 
-	public function getGlobal( name : String ) : Dynamic {
-		var id = hxsl.Globals.allocID(name);
-		for( g in sharedGlobals )
-			if( g.gid == id )
-				return g.value;
-		return null;
+	public inline function getGlobal(name) {
+		return globals.get(name);
 	}
-
-	public inline function setGlobal( name : String, value : Dynamic ) {
-		setGlobalID(hxsl.Globals.allocID(name), value);
-	}
-
-	public function setGlobalID( gid : Int, value : Dynamic ) {
-		for( g in sharedGlobals )
-			if( g.gid == gid ) {
-				g.value = value;
-				return;
-			}
-		sharedGlobals.push(new SharedGlobal(gid, value));
+	public inline function setGlobal(name,v:Dynamic) {
+		globals.set(name, v);
 	}
 
 	public function emitPass( pass : h3d.mat.Pass, obj : h3d.scene.Object ) @:privateAccess {
@@ -125,7 +110,7 @@ class RenderContext extends h3d.impl.RenderContext {
 	}
 
 	public function uploadParams() {
-		currentManager.fillParams(shaderBuffers, drawPass.shader, drawPass.shaders);
+		currentManager.fillParams(globals, shaderBuffers, drawPass.shader, drawPass.shaders);
 		engine.uploadShaderBuffers(shaderBuffers, Params);
 		engine.uploadShaderBuffers(shaderBuffers, Textures);
 		engine.uploadShaderBuffers(shaderBuffers, Buffers);
@@ -155,6 +140,7 @@ class RenderContext extends h3d.impl.RenderContext {
 		}
 		passes = [];
 		lights = null;
+		clearCurrent();
 	}
 
 }

+ 2 - 2
h3d/scene/fwd/Renderer.hx

@@ -20,7 +20,7 @@ class DepthPass extends h3d.pass.Default {
 		ctx.engine.clear(enableSky ? 0 : 0xFF0000, 1);
 		super.draw(passes, sort);
 		ctx.engine.popTarget();
-		ctx.setGlobalID(depthMapId, { texture : texture });
+		ctx.globals.fastSet(depthMapId, { texture : texture });
 	}
 
 }
@@ -44,7 +44,7 @@ class NormalPass extends h3d.pass.Default {
 		ctx.engine.clear(0x808080, 1);
 		super.draw(passes, sort);
 		ctx.engine.popTarget();
-		ctx.setGlobalID(normalMapId, texture);
+		ctx.globals.fastSet(normalMapId, texture);
 	}
 
 }