Przeglądaj źródła

changed MultiBuffer handling : hash name (faster access) and return linked list (no Array allocation)
added NullDriver to disable draw calls

ncannasse 11 lat temu
rodzic
commit
ffef9e7a20

+ 13 - 1
h3d/Engine.hx

@@ -109,6 +109,18 @@ class Engine {
 	public inline function renderQuadBuffer( b : h3d.impl.Buffer, start = 0, max = -1 ) {
 		return renderBuffer(b, mem.quadIndexes, 2, start, max);
 	}
+	
+	public function enableDriver( ?b : Bool ) {
+		if( b == null )
+			b = Std.is(driver, h3d.impl.NullDriver);
+		if( b ) {
+			var d = Std.instance(driver, h3d.impl.NullDriver);
+			if( d != null )
+				driver = d.driver;
+		} else if( !Std.is(driver,h3d.impl.NullDriver) ) {
+			driver = new h3d.impl.NullDriver(driver);
+		}
+	}
 
 	// we use preallocated indexes so all the triangles are stored inside our buffers
 	function renderBuffer( b : h3d.impl.Buffer, indexes : h3d.impl.Indexes, vertPerTri : Int, startTri = 0, drawTri = -1 ) {
@@ -161,7 +173,7 @@ class Engine {
 		}
 	}
 	
-	public function renderMultiBuffers( buffers : Array<h3d.impl.Buffer.BufferOffset>, indexes : h3d.impl.Indexes, startTri = 0, drawTri = -1 ) {
+	public function renderMultiBuffers( buffers : h3d.impl.Buffer.BufferOffset, indexes : h3d.impl.Indexes, startTri = 0, drawTri = -1 ) {
 		var maxTri = Std.int(indexes.count / 3);
 		if( maxTri <= 0 ) return;
 		driver.selectMultiBuffers(buffers);

+ 11 - 0
h3d/impl/Buffer.hx

@@ -65,9 +65,19 @@ class Buffer {
 }
 
 class BufferOffset {
+	public var id : Int;
 	public var b : Buffer;
 	public var offset : Int;
+	
+	/*
+		This is used to return a list of BufferOffset without allocating an array
+	*/
+	public var next : BufferOffset;
+	
+	static var UID = 0;
+	
 	public function new(b, offset) {
+		this.id = UID++;
 		this.b = b;
 		this.offset = offset;
 	}
@@ -76,5 +86,6 @@ class BufferOffset {
 			b.dispose();
 			b = null;
 		}
+		next = null;
 	}
 }

+ 4 - 4
h3d/impl/Driver.hx

@@ -51,14 +51,14 @@ class Driver {
 		return false;
 	}
 	
-	public function selectBuffer( buffer : VertexBuffer ) {
-	}
-	
 	public function getShaderInputNames() : Array<String> {
 		return null;
 	}
 	
-	public function selectMultiBuffers( buffers : Array<Buffer.BufferOffset> ) {
+	public function selectBuffer( buffer : VertexBuffer ) {
+	}
+	
+	public function selectMultiBuffers( buffers : Buffer.BufferOffset ) {
 	}
 	
 	public function draw( ibuf : IndexBuffer, startIndex : Int, ntriangles : Int ) {

+ 120 - 0
h3d/impl/NullDriver.hx

@@ -0,0 +1,120 @@
+package h3d.impl;
+import h3d.impl.Driver;
+
+class NullDriver extends Driver {
+
+	public var driver : Driver;
+	
+	public function new( driver ) {
+		this.driver = driver;
+	}
+	
+	override function isDisposed() {
+		return driver.isDisposed();
+	}
+	
+	override function dispose() {
+		driver.dispose();
+	}
+
+	override function reset() {
+		driver.reset();
+	}
+
+	override function present() {
+		driver.present();
+	}
+
+	override function clear( r : Float, g : Float, b : Float, a : Float ) {
+		driver.clear(r, g, b, a);
+	}
+	
+	override function getDriverName( details : Bool ) {
+		return "Null Driver - " + driver.getDriverName(details);
+	}
+	
+	override function init( onCreate : Bool -> Void, forceSoftware = false ) {
+		driver.init(onCreate, forceSoftware);
+	}
+
+	override function resize( width : Int, height : Int ) {
+		driver.resize(width, height);
+	}
+
+	override function selectMaterial( mbits : Int ) {
+		driver.selectMaterial(mbits);
+	}
+	
+	override function selectShader( shader : Shader ) : Bool {
+		return driver.selectShader(shader);
+	}
+	
+	override function getShaderInputNames() : Array<String> {
+		return driver.getShaderInputNames();
+	}
+	
+	override function isHardware() {
+		return driver.isHardware();
+	}
+	
+	override function setDebug( b : Bool ) {
+		driver.setDebug(b);
+	}
+	
+	override function allocTexture( t : h3d.mat.Texture ) : Texture {
+		return driver.allocTexture(t);
+	}
+
+	override function allocIndexes( count : Int ) : IndexBuffer {
+		return driver.allocIndexes(count);
+	}
+
+	override function allocVertex( count : Int, stride : Int ) : VertexBuffer {
+		return driver.allocVertex(count,stride);
+	}
+	
+	override function disposeTexture( t : Texture ) {
+		driver.disposeTexture(t);
+	}
+	
+	override function disposeIndexes( i : IndexBuffer ) {
+		driver.disposeIndexes(i);
+	}
+	
+	override function disposeVertex( v : VertexBuffer ) {
+		driver.disposeVertex(v);
+	}
+	
+	override function uploadIndexesBuffer( i : IndexBuffer, startIndice : Int, indiceCount : Int, buf : hxd.IndexBuffer, bufPos : Int ) {
+		driver.uploadIndexesBuffer(i, startIndice, indiceCount, buf, bufPos);
+	}
+
+	override function uploadIndexesBytes( i : IndexBuffer, startIndice : Int, indiceCount : Int, buf : haxe.io.Bytes , bufPos : Int ) {
+		driver.uploadIndexesBytes(i, startIndice, indiceCount, buf, bufPos);
+	}
+	
+	override function uploadVertexBuffer( v : VertexBuffer, startVertex : Int, vertexCount : Int, buf : hxd.FloatBuffer, bufPos : Int ) {
+		driver.uploadVertexBuffer(v, startVertex, vertexCount, buf, bufPos);
+	}
+
+	override function uploadVertexBytes( v : VertexBuffer, startVertex : Int, vertexCount : Int, buf : haxe.io.Bytes, bufPos : Int ) {
+		driver.uploadVertexBytes(v, startVertex, vertexCount, buf, bufPos);
+	}
+	
+	override function uploadTextureBitmap( t : h3d.mat.Texture, bmp : hxd.BitmapData, mipLevel : Int, side : Int ) {
+		driver.uploadTextureBitmap(t, bmp, mipLevel, side);
+	}
+
+	override function uploadTexturePixels( t : h3d.mat.Texture, pixels : hxd.Pixels, mipLevel : Int, side : Int ) {
+		driver.uploadTexturePixels(t, pixels, mipLevel, side);
+	}
+
+	/*
+	public function selectBuffer( buffer : VertexBuffer )
+	public function selectMultiBuffers( buffers : Array<Buffer.BufferOffset> )
+	public function draw( ibuf : IndexBuffer, startIndex : Int, ntriangles : Int )
+	public function setRenderZone( x : Int, y : Int, width : Int, height : Int )
+	public function setRenderTarget( tex : Null<Texture>, useDepth : Bool, clearColor : Int )
+	*/
+	
+}

+ 16 - 11
h3d/impl/Stage3dDriver.hx

@@ -41,7 +41,7 @@ class Stage3dDriver extends Driver {
 	var curMatBits : Int;
 	var curShader : hxsl.Shader.ShaderInstance;
 	var curBuffer : VertexBuffer;
-	var curMultiBuffer : Array<h3d.impl.Buffer.BufferOffset>;
+	var curMultiBuffer : Array<Int>;
 	var curAttributes : Int;
 	var curTextures : Array<h3d.mat.Texture>;
 	var curSamplerBits : Array<Int>;
@@ -67,7 +67,7 @@ class Stage3dDriver extends Driver {
 		curMatBits = -1;
 		curShader = null;
 		curBuffer = null;
-		curMultiBuffer = null;
+		curMultiBuffer = [];
 		for( i in 0...curAttributes )
 			ctx.setVertexBufferAt(i, null);
 		curAttributes = 0;
@@ -265,7 +265,7 @@ class Stage3dDriver extends Driver {
 			}
 			// force remapping of vertex buffer
 			curBuffer = null;
-			curMultiBuffer = null;
+			curMultiBuffer[0] = -1;
 			curShader = s;
 		}
 		if( s.varsChanged ) {
@@ -300,7 +300,7 @@ class Stage3dDriver extends Driver {
 		if( v == curBuffer )
 			return;
 		curBuffer = v;
-		curMultiBuffer = null;
+		curMultiBuffer[0] = -1;
 		if( v.stride < curShader.stride )
 			throw "Buffer stride (" + v.stride + ") and shader stride (" + curShader.stride + ") mismatch";
 		if( !v.written )
@@ -322,35 +322,40 @@ class Stage3dDriver extends Driver {
 		return curShader.bufferNames;
 	}
 	
-	override function selectMultiBuffers( buffers : Array<Buffer.BufferOffset> ) {
+	override function selectMultiBuffers( buffers : Buffer.BufferOffset ) {
 		// select the multiple buffers elements
-		var changed = curMultiBuffer == null || curMultiBuffer.length != buffers.length;
-		if( !changed )
-			for( i in 0...curMultiBuffer.length )
-				if( buffers[i] != curMultiBuffer[i] ) {
+		var changed = false;
+		if( !changed ) {
+			var b = buffers;
+			for( i in 0...curAttributes ) {
+				if( b == null || b.id != curMultiBuffer[i] ) {
 					changed = true;
 					break;
 				}
+				b = b.next;
+			}
+		}
 		if( changed ) {
 			var pos = 0, offset = 0;
 			var bits = curShader.bufferFormat;
+			var b = buffers;
 			while( offset < curShader.stride ) {
 				var size = bits & 7;
-				var b = buffers[pos];
 				if( b.b.next != null )
 					throw "Buffer is split";
 				if( !b.b.b.vbuf.written )
 					b.b.b.vbuf.finalize(this);
 				ctx.setVertexBufferAt(pos, b.b.b.vbuf.vbuf, b.offset, FORMAT[size]);
+				curMultiBuffer[pos] = b.id;
 				offset += size == 0 ? 1 : size;
 				bits >>= 3;
 				pos++;
+				b = b.next;
 			}
 			for( i in pos...curAttributes )
 				ctx.setVertexBufferAt(i, null);
 			curAttributes = pos;
 			curBuffer = null;
-			curMultiBuffer = buffers;
 		}
 	}
 	

+ 23 - 7
h3d/prim/MeshPrimitive.hx

@@ -2,18 +2,27 @@ package h3d.prim;
 
 class MeshPrimitive extends Primitive {
 		
-	var bufferCache : Map<String,h3d.impl.Buffer.BufferOffset>;
+	var bufferCache : Map<Int,h3d.impl.Buffer.BufferOffset>;
 	
 	function allocBuffer( engine : h3d.Engine, name : String ) {
 		return null;
 	}
 	
+	// TODO : in HxSL 3, we might instead allocate unique ID per name
+	static inline function hash( name : String ) {
+		var id = 0;
+		for( i in 0...name.length )
+			id = id * 223 + name.charCodeAt(i);
+		return id & 0x0FFFFFFF;
+	}
+	
 	function addBuffer( name : String, buf, offset = 0 ) {
 		if( bufferCache == null )
 			bufferCache = new Map();
-		var old = bufferCache.get(name);
+		var id = hash(name);
+		var old = bufferCache.get(id);
 		if( old != null ) old.dispose();
-		bufferCache.set(name, new h3d.impl.Buffer.BufferOffset(buf, offset));
+		bufferCache.set(id, new h3d.impl.Buffer.BufferOffset(buf, offset));
 	}
 
 	override public function dispose() {
@@ -28,15 +37,22 @@ class MeshPrimitive extends Primitive {
 	function getBuffers( engine : h3d.Engine ) {
 		if( bufferCache == null )
 			bufferCache = new Map();
-		var buffers = [];
+		var buffers = null, prev = null;
 		for( name in engine.driver.getShaderInputNames() ) {
-			var b = bufferCache.get(name);
+			var id = hash(name);
+			var b = bufferCache.get(id);
 			if( b == null ) {
 				b = allocBuffer(engine, name);
 				if( b == null ) throw "Buffer " + name + " is not available";
-				bufferCache.set(name, b);
+				bufferCache.set(id, b);
+			}
+			b.next = null;
+			if( prev == null ) {
+				buffers = prev = b;
+			} else {
+				prev.next = b;
+				prev = b;
 			}
-			buffers.push(b);
 		}
 		return buffers;
 	}

+ 0 - 2
hxd/impl/FastIO.hx

@@ -68,7 +68,6 @@ class FastIntIO extends FastIO<Int> {
 			flush((write < read ? write : (write - read)) * 4);
 			if( !hasNext() )
 				break;
-			var k = 0;
 			for( id in this ) {
 				var x = id & ((1 << bits) - 1);
 				var y = id >>> bits;
@@ -78,7 +77,6 @@ class FastIntIO extends FastIO<Int> {
 				add2d(x - 1, y, bits);
 				add2d(x, y + 1, bits);
 				add2d(x, y - 1, bits);
-				k += 4;
 			}
 		}
 	}