Răsfoiți Sursa

review buffer bytes stride with lowp and remove extra buffer object. changed uploadBytes.bufPos to be per-byte (was not used?)

Nicolas Cannasse 2 ani în urmă
părinte
comite
d247841350
6 a modificat fișierele cu 79 adăugiri și 76 ștergeri
  1. 7 4
      h3d/Buffer.hx
  2. 13 15
      h3d/impl/DX12Driver.hx
  3. 29 29
      h3d/impl/DirectXDriver.hx
  4. 8 8
      h3d/impl/Driver.hx
  5. 18 19
      h3d/impl/GlDriver.hx
  6. 4 1
      h3d/impl/MemoryManager.hx

+ 7 - 4
h3d/Buffer.hx

@@ -23,9 +23,12 @@ class Buffer {
 	var allocPos : hxd.impl.AllocPos;
 	var allocNext : Buffer;
 	#end
+	#if multidriver
+	var driver : h3d.impl.Driver;
+	#end
 
 	var mem : h3d.impl.MemoryManager;
-	var vbuf : h3d.impl.Driver.GPUBuffer;
+	@:allow(h3d.impl.Driver) var vbuf : h3d.impl.Driver.GPUBuffer;
 	public var vertices(default,null) : Int;
 	public var format(default,null) : hxd.BufferFormat;
 	public var flags(default, null) : haxe.EnumFlags<BufferFlag>;
@@ -65,19 +68,19 @@ class Buffer {
 			throw "Invalid vertices count";
 		if( format.hasLowPrecision )
 			throw "Can't upload floats on low precision buffer";
-		mem.driver.uploadBufferData(vbuf, startVertice, vertices, buf, bufPos);
+		mem.driver.uploadBufferData(this, startVertice, vertices, buf, bufPos);
 	}
 
 	public function uploadBytes( data : haxe.io.Bytes, dataPos : Int, vertices : Int ) {
 		if( vertices < 0 || vertices > this.vertices )
 			throw "Invalid vertices count";
-		mem.driver.uploadBufferBytes(vbuf, 0, vertices, data, dataPos);
+		mem.driver.uploadBufferBytes(this, 0, vertices, data, dataPos);
 	}
 
 	public function readBytes( bytes : haxe.io.Bytes, bytesPosition : Int, vertices : Int,  startVertice : Int = 0 ) {
 		if( startVertice < 0 || vertices < 0 || startVertice + vertices > this.vertices )
 			throw "Invalid vertices count";
-		mem.driver.readBufferBytes(vbuf, startVertice, vertices, bytes, bytesPosition);
+		mem.driver.readBufferBytes(this, startVertice, vertices, bytes, bytesPosition);
 	}
 
 	public static function ofFloats( v : hxd.FloatBuffer, format : hxd.BufferFormat, ?flags ) {

+ 13 - 15
h3d/impl/DX12Driver.hx

@@ -261,7 +261,6 @@ class IndexBufferData extends BufferData {
 
 class VertexBufferData extends BufferData {
 	public var view : dx.Dx12.VertexBufferView;
-	public var stride : Int;
 	public var size : Int;
 }
 
@@ -1047,7 +1046,6 @@ class DX12Driver extends h3d.impl.Driver {
 			view.strideInBytes = m.format.strideBytes;
 			buf.view = view;
 		}
-		buf.stride = m.format.strideBytes;
 		buf.size = bufSize;
 		buf.uploaded = m.flags.has(Dynamic);
 		return buf;
@@ -1082,8 +1080,8 @@ class DX12Driver extends h3d.impl.Driver {
 		frame.commandList.resourceBarrier(b);
 	}
 
-	override function disposeBuffer(v:GPUBuffer) {
-		disposeResource(v);
+	override function disposeBuffer(v:Buffer) {
+		disposeResource(v.vbuf);
 	}
 
 	override function disposeIndexes(v:IndexBuffer) {
@@ -1125,17 +1123,17 @@ class DX12Driver extends h3d.impl.Driver {
 		transition(i, INDEX_BUFFER);
 	}
 
-	override function uploadBufferData(v:GPUBuffer, startVertex:Int, vertexCount:Int, buf:hxd.FloatBuffer, bufPos:Int) {
+	override function uploadBufferData(b:Buffer, startVertex:Int, vertexCount:Int, buf:hxd.FloatBuffer, bufPos:Int) {
 		var data = hl.Bytes.getArray(buf.getNative()).offset(bufPos<<2);
-		transition(v, COPY_DEST);
-		updateBuffer(v, data, startVertex * v.stride, vertexCount * v.stride);
-		transition(v, VERTEX_AND_CONSTANT_BUFFER);
+		transition(b.vbuf, COPY_DEST);
+		updateBuffer(b.vbuf, data, startVertex * b.format.strideBytes, vertexCount * b.format.strideBytes);
+		transition(b.vbuf, VERTEX_AND_CONSTANT_BUFFER);
 	}
 
-	override function uploadBufferBytes(v:GPUBuffer, startVertex:Int, vertexCount:Int, buf:haxe.io.Bytes, bufPos:Int) {
-		transition(v, COPY_DEST);
-		updateBuffer(v, @:privateAccess buf.b.offset(bufPos << 2), startVertex * v.stride, vertexCount * v.stride);
-		transition(v, VERTEX_AND_CONSTANT_BUFFER);
+	override function uploadBufferBytes(b:Buffer, startVertex:Int, vertexCount:Int, buf:haxe.io.Bytes, bufPos:Int) {
+		transition(b.vbuf, COPY_DEST);
+		updateBuffer(b.vbuf, @:privateAccess buf.b.offset(bufPos), startVertex * b.format.strideBytes, vertexCount * b.format.strideBytes);
+		transition(b.vbuf, VERTEX_AND_CONSTANT_BUFFER);
 	}
 
 	// ------------ TEXTURES -------
@@ -1463,7 +1461,7 @@ class DX12Driver extends h3d.impl.Driver {
 				for( i in 0...shader.bufferCount ) {
 					var srv = frame.shaderResourceViews.alloc(1);
 					var b = buf.buffers[i];
-					var cbv = @:privateAccess b.vbuf;
+					var cbv = b.vbuf;
 					if( cbv.view != null )
 						throw "Buffer was allocated without UniformBuffer flag";
 					transition(cbv, VERTEX_AND_CONSTANT_BUFFER);
@@ -1511,9 +1509,9 @@ class DX12Driver extends h3d.impl.Driver {
 
 	override function selectBuffer(buffer:Buffer) {
 		var views = tmp.vertexViews;
-		var bview = @:privateAccess buffer.vbuf.view;
+		var bview = buffer.vbuf.view;
 		var map = buffer.format.resolveMapping(currentShader.format);
-		var vbuf = @:privateAccess buffer.vbuf;
+		var vbuf = buffer.vbuf;
 		for( i in 0...currentShader.inputCount ) {
 			var v = views[i];
 			var inf = map[i];

+ 29 - 29
h3d/impl/DirectXDriver.hx

@@ -321,10 +321,9 @@ class DirectXDriver extends h3d.impl.Driver {
 
 	override function allocBuffer(b:Buffer):GPUBuffer {
 		var size = b.getMemSize();
-		var uniform = b.flags.has(UniformBuffer);
-		var res = uniform ? dx.Driver.createBuffer(size, Dynamic, ConstantBuffer, CpuWrite, None, 0, null) : dx.Driver.createBuffer(size, Default, VertexBuffer, None, None, 0, null);
+		var res = b.flags.has(UniformBuffer) ? dx.Driver.createBuffer(size, Dynamic, ConstantBuffer, CpuWrite, None, 0, null) : dx.Driver.createBuffer(size, Default, VertexBuffer, None, None, 0, null);
 		if( res == null ) return null;
-		return { res : res, count : b.vertices, stride : b.format.stride, uniform : uniform };
+		return res;
 	}
 
 	override function allocIndexes( count : Int, is32 : Bool ) : IndexBuffer {
@@ -461,8 +460,8 @@ class DirectXDriver extends h3d.impl.Driver {
 					rt.release();
 	}
 
-	override function disposeBuffer(b:GPUBuffer) {
-		b.res.release();
+	override function disposeBuffer(b:Buffer) {
+		b.vbuf.release();
 	}
 
 	override function disposeIndexes(i:IndexBuffer) {
@@ -495,31 +494,31 @@ class DirectXDriver extends h3d.impl.Driver {
 		updateBuffer(i.res, @:privateAccess buf.b.offset(bufPos << i.bits), startIndice << i.bits, indiceCount << i.bits);
 	}
 
-	override function uploadBufferData(b:GPUBuffer, startVertex:Int, vertexCount:Int, buf:hxd.FloatBuffer, bufPos:Int) {
+	override function uploadBufferData(b:Buffer, startVertex:Int, vertexCount:Int, buf:hxd.FloatBuffer, bufPos:Int) {
 		if( hasDeviceError ) return;
 		var data = hl.Bytes.getArray(buf.getNative()).offset(bufPos<<2);
-		if( b.uniform ) {
+		if( b.flags.has(UniformBuffer) ) {
 			if( startVertex != 0 ) throw "assert";
-			var ptr = b.res.map(0, WriteDiscard, true, null);
+			var ptr = b.vbuf.map(0, WriteDiscard, true, null);
 			if( ptr == null ) throw "Can't map buffer";
-			ptr.blit(0, data, 0, vertexCount * b.stride << 2);
-			b.res.unmap(0);
+			ptr.blit(0, data, 0, vertexCount * b.format.strideBytes);
+			b.vbuf.unmap(0);
 			return;
 		}
-		updateBuffer(b.res, data, startVertex * b.stride << 2, vertexCount * b.stride << 2);
+		updateBuffer(b.vbuf, data, startVertex * b.format.strideBytes, vertexCount * b.format.strideBytes);
 	}
 
-	override function uploadBufferBytes(v:GPUBuffer, startVertex:Int, vertexCount:Int, buf:haxe.io.Bytes, bufPos:Int) {
+	override function uploadBufferBytes(b:Buffer, startVertex:Int, vertexCount:Int, buf:haxe.io.Bytes, bufPos:Int) {
 		if( hasDeviceError ) return;
-		if( v.uniform ) {
+		if( b.flags.has(UniformBuffer) ) {
 			if( startVertex != 0 ) throw "assert";
-			var ptr = v.res.map(0, WriteDiscard, true, null);
+			var ptr = b.vbuf.map(0, WriteDiscard, true, null);
 			if( ptr == null ) throw "Can't map buffer";
-			ptr.blit(0, buf, 0, vertexCount * v.stride << 2);
-			v.res.unmap(0);
+			ptr.blit(0, buf, 0, vertexCount * b.format.strideBytes);
+			b.vbuf.unmap(0);
 			return;
 		}
-		updateBuffer(v.res, @:privateAccess buf.b.offset(bufPos << 2), startVertex * v.stride << 2, vertexCount * v.stride << 2);
+		updateBuffer(b.vbuf, @:privateAccess buf.b.offset(bufPos), startVertex * b.format.strideBytes, vertexCount * b.format.strideBytes);
 	}
 
 	override function readIndexBytes(v:IndexBuffer, startIndice:Int, indiceCount:Int, buf:haxe.io.Bytes, bufPos:Int) {
@@ -537,17 +536,18 @@ class DirectXDriver extends h3d.impl.Driver {
 		tmp.release();
 	}
 
-	override function readBufferBytes(b:GPUBuffer, startVertex:Int, vertexCount:Int, buf:haxe.io.Bytes, bufPos:Int) {
-		var tmp = dx.Driver.createBuffer(vertexCount * b.stride * 4, Staging, None, CpuRead | CpuWrite, None, 0, null);
-		box.left = startVertex * b.stride * 4;
+	override function readBufferBytes(b:Buffer, startVertex:Int, vertexCount:Int, buf:haxe.io.Bytes, bufPos:Int) {
+		var stride = b.format.strideBytes;
+		var tmp = dx.Driver.createBuffer(vertexCount * stride, Staging, None, CpuRead | CpuWrite, None, 0, null);
+		box.left = startVertex * stride;
 		box.top = 0;
 		box.front = 0;
-		box.right = (startVertex + vertexCount) * 4 * b.stride;
+		box.right = (startVertex + vertexCount) * stride;
 		box.bottom = 1;
 		box.back = 1;
-		tmp.copySubresourceRegion(0, 0, 0, 0, b.res, 0, box);
+		tmp.copySubresourceRegion(0, 0, 0, 0, b.vbuf, 0, box);
 		var ptr = tmp.map(0, Read, true, null);
-		@:privateAccess buf.b.blit(bufPos, ptr, 0, vertexCount * b.stride * 4);
+		@:privateAccess buf.b.blit(bufPos, ptr, 0, vertexCount * stride);
 		tmp.unmap(0);
 		tmp.release();
 	}
@@ -1182,13 +1182,13 @@ class DirectXDriver extends h3d.impl.Driver {
 			currentLayout = layout;
 		}
 		var map = buffer.format.resolveMapping(currentShader.format);
-		var vbuf = @:privateAccess buffer.vbuf;
+		var vbuf = buffer.vbuf;
 		var start = -1, max = -1;
 		var stride = buffer.format.strideBytes;
 		for( i in 0...map.length ) {
 			var inf = map[i];
-			if( currentVBuffers[i] != vbuf.res || offsets[i] != inf.offset || strides[i] != stride ) {
-				currentVBuffers[i] = vbuf.res;
+			if( currentVBuffers[i] != vbuf || offsets[i] != inf.offset || strides[i] != stride ) {
+				currentVBuffers[i] = vbuf;
 				strides[i] = stride;
 				offsets[i] = inf.offset;
 				if( start < 0 ) start = i;
@@ -1215,8 +1215,8 @@ class DirectXDriver extends h3d.impl.Driver {
 		for( i in 0...map.length ) {
 			var inf = map[i];
 			var buf = buffers[inf.bufferIndex];
-			if( currentVBuffers[i] != @:privateAccess buf.vbuf.res || offsets[i] != inf.offset || strides[i] != buf.format.strideBytes ) {
-				currentVBuffers[i] = @:privateAccess buf.vbuf.res;
+			if( currentVBuffers[i] != buf.vbuf || offsets[i] != inf.offset || strides[i] != buf.format.strideBytes ) {
+				currentVBuffers[i] = buf.vbuf;
 				strides[i] = buf.format.strideBytes;
 				offsets[i] = inf.offset;
 				if( start < 0 ) start = i;
@@ -1281,7 +1281,7 @@ class DirectXDriver extends h3d.impl.Driver {
 			var first = -1;
 			var max = -1;
 			for( i in 0...shader.bufferCount ) {
-				var buf = @:privateAccess buffers.buffers[i].vbuf.res;
+				var buf = buffers.buffers[i].vbuf;
 				var tid = i + 2;
 				if( buf != state.buffers[tid] ) {
 					state.buffers[tid] = buf;

+ 8 - 8
h3d/impl/Driver.hx

@@ -8,19 +8,19 @@ typedef DepthBuffer = {};
 typedef Query = {};
 #elseif js
 typedef IndexBuffer = { b : js.html.webgl.Buffer, is32 : Bool };
-typedef GPUBuffer = { b : js.html.webgl.Buffer, stride : Int #if multidriver, driver : Driver #end };
+typedef GPUBuffer = js.html.webgl.Buffer;
 typedef Texture = { t : js.html.webgl.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int, bias : Float, bind : Int #if multidriver, driver : Driver #end };
 typedef DepthBuffer = { r : js.html.webgl.Renderbuffer #if multidriver, driver : Driver #end };
 typedef Query = {};
 #elseif hlsdl
 typedef IndexBuffer = { b : sdl.GL.Buffer, is32 : Bool };
-typedef GPUBuffer = { b : sdl.GL.Buffer, stride : Int };
+typedef GPUBuffer = sdl.GL.Buffer;
 typedef Texture = { t : sdl.GL.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int, bind : Int, bias : Float };
 typedef DepthBuffer = { r : sdl.GL.Renderbuffer };
 typedef Query = { q : sdl.GL.Query, kind : QueryKind };
 #elseif usegl
 typedef IndexBuffer = { b : haxe.GLTypes.Buffer, is32 : Bool };
-typedef GPUBuffer = { b : haxe.GLTypes.Buffer, stride : Int };
+typedef GPUBuffer = haxe.GLTypes.Buffer;
 typedef Texture = { t : haxe.GLTypes.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int, bind : Int, bias : Float };
 typedef DepthBuffer = { r : haxe.GLTypes.Renderbuffer };
 typedef Query = { q : haxe.GLTypes.Query, kind : QueryKind };
@@ -32,7 +32,7 @@ typedef DepthBuffer = h3d.impl.DX12Driver.DepthBufferData;
 typedef Query = h3d.impl.DX12Driver.QueryData;
 #elseif hldx
 typedef IndexBuffer = { res : dx.Resource, count : Int, bits : Int };
-typedef GPUBuffer = { res : dx.Resource, count : Int, stride : Int, uniform : Bool };
+typedef GPUBuffer = dx.Resource;
 typedef Texture = { res : dx.Resource, view : dx.Driver.ShaderResourceView, rt : Array<dx.Driver.RenderTargetView>, mips : Int };
 typedef DepthBuffer = { res : dx.Resource, view : dx.Driver.DepthStencilView };
 typedef Query = {};
@@ -252,7 +252,7 @@ class Driver {
 	public function disposeIndexes( i : IndexBuffer ) {
 	}
 
-	public function disposeBuffer( b : GPUBuffer ) {
+	public function disposeBuffer( b : Buffer ) {
 	}
 
 	public function disposeInstanceBuffer( b : h3d.impl.InstanceBuffer ) {
@@ -264,10 +264,10 @@ class Driver {
 	public function uploadIndexBytes( i : IndexBuffer, startIndice : Int, indiceCount : Int, buf : haxe.io.Bytes , bufPos : Int ) {
 	}
 
-	public function uploadBufferData( b : GPUBuffer, startVertex : Int, vertexCount : Int, buf : hxd.FloatBuffer, bufPos : Int ) {
+	public function uploadBufferData( b : Buffer, startVertex : Int, vertexCount : Int, buf : hxd.FloatBuffer, bufPos : Int ) {
 	}
 
-	public function uploadBufferBytes( b : GPUBuffer, startVertex : Int, vertexCount : Int, buf : haxe.io.Bytes, bufPos : Int ) {
+	public function uploadBufferBytes( b : Buffer, startVertex : Int, vertexCount : Int, buf : haxe.io.Bytes, bufPos : Int ) {
 	}
 
 	public function uploadTextureBitmap( t : h3d.mat.Texture, bmp : hxd.BitmapData, mipLevel : Int, side : Int ) {
@@ -276,7 +276,7 @@ class Driver {
 	public function uploadTexturePixels( t : h3d.mat.Texture, pixels : hxd.Pixels, mipLevel : Int, side : Int ) {
 	}
 
-	public function readBufferBytes( v : GPUBuffer, startVertex : Int, vertexCount : Int, buf : haxe.io.Bytes, bufPos : Int ) {
+	public function readBufferBytes( b : Buffer, startVertex : Int, vertexCount : Int, buf : haxe.io.Bytes, bufPos : Int ) {
 		throw "Driver does not allow to read vertex bytes";
 	}
 

+ 18 - 19
h3d/impl/GlDriver.hx

@@ -508,7 +508,7 @@ class GlDriver extends Driver {
 				if( !s.vertex && curShader.vertex.buffers != null )
 					start = curShader.vertex.buffers.length;
 				for( i in 0...s.buffers.length )
-					gl.bindBufferBase(GL.UNIFORM_BUFFER, i + start, @:privateAccess buf.buffers[i].vbuf.b);
+					gl.bindBufferBase(GL.UNIFORM_BUFFER, i + start, buf.buffers[i].vbuf);
 			}
 		case Textures:
 			var tcount = s.textures.length;
@@ -1015,7 +1015,7 @@ class GlDriver extends Driver {
 			gl.deleteBuffer(vb);
 			return null;
 		}
-		return { b : vb, stride : b.format.stride #if multidriver, driver : this #end };
+		return vb;
 	}
 
 	override function allocIndexes( count : Int, is32 : Bool ) : IndexBuffer {
@@ -1052,8 +1052,8 @@ class GlDriver extends Driver {
 		gl.deleteBuffer(i.b);
 	}
 
-	override function disposeBuffer( b : GPUBuffer ) {
-		gl.deleteBuffer(b.b);
+	override function disposeBuffer( b : h3d.Buffer ) {
+		gl.deleteBuffer(b.vbuf);
 	}
 
 	override function generateMipMaps( t : h3d.mat.Texture ) {
@@ -1198,28 +1198,28 @@ class GlDriver extends Driver {
 		restoreBind();
 	}
 
-	override function uploadBufferData( b : GPUBuffer, startVertex : Int, vertexCount : Int, buf : hxd.FloatBuffer, bufPos : Int ) {
-		var stride : Int = b.stride;
-		gl.bindBuffer(GL.ARRAY_BUFFER, b.b);
+	override function uploadBufferData( b : h3d.Buffer, startVertex : Int, vertexCount : Int, buf : hxd.FloatBuffer, bufPos : Int ) {
+		var stride = b.format.strideBytes;
+		gl.bindBuffer(GL.ARRAY_BUFFER, b.vbuf);
 		#if hl
 		var data = #if hl hl.Bytes.getArray(buf.getNative()) #else buf.getNative() #end;
-		gl.bufferSubData(GL.ARRAY_BUFFER, startVertex * stride * 4, streamData(data,bufPos * 4,vertexCount * stride * 4), bufPos * 4 * STREAM_POS, vertexCount * stride * 4);
+		gl.bufferSubData(GL.ARRAY_BUFFER, startVertex * stride, streamData(data,bufPos * 4,vertexCount * stride), bufPos * 4 * STREAM_POS, vertexCount * stride);
 		#else
 		var buf : Float32Array = buf.getNative();
 		var sub = new Float32Array(buf.buffer, bufPos * 4, vertexCount * stride);
-		gl.bufferSubData(GL.ARRAY_BUFFER, startVertex * stride * 4, sub);
+		gl.bufferSubData(GL.ARRAY_BUFFER, startVertex * stride, sub);
 		#end
 		gl.bindBuffer(GL.ARRAY_BUFFER, null);
 	}
 
-	override function uploadBufferBytes( b : GPUBuffer, startVertex : Int, vertexCount : Int, buf : haxe.io.Bytes, bufPos : Int ) {
-		var stride : Int = b.stride;
-		gl.bindBuffer(GL.ARRAY_BUFFER, b.b);
+	override function uploadBufferBytes( b : h3d.Buffer, startVertex : Int, vertexCount : Int, buf : haxe.io.Bytes, bufPos : Int ) {
+		var stride = b.format.strideBytes;
+		gl.bindBuffer(GL.ARRAY_BUFFER, b.vbuf);
 		#if hl
-		gl.bufferSubData(GL.ARRAY_BUFFER, startVertex * stride * 4, streamData(buf.getData(),bufPos * 4,vertexCount * stride * 4), bufPos * 4 * STREAM_POS, vertexCount * stride * 4);
+		gl.bufferSubData(GL.ARRAY_BUFFER, startVertex * stride, streamData(buf.getData(),bufPos,vertexCount * stride), bufPos * STREAM_POS, vertexCount * stride);
 		#else
-		var sub = new Uint8Array(buf.getData(), bufPos * 4, vertexCount * stride * 4);
-		gl.bufferSubData(GL.ARRAY_BUFFER, startVertex * stride * 4, sub);
+		var sub = new Uint8Array(buf.getData(), bufPos, vertexCount * stride);
+		gl.bufferSubData(GL.ARRAY_BUFFER, startVertex * stride, sub);
 		#end
 		gl.bindBuffer(GL.ARRAY_BUFFER, null);
 	}
@@ -1265,12 +1265,11 @@ class GlDriver extends Driver {
 
 		if( curShader == null )
 			throw "No shader selected";
-		var m = @:privateAccess b.vbuf;
 		#if multidriver
-		if( m.driver != this )
+		if( @:privateAccess b.driver != this )
 			throw "Invalid buffer context";
 		#end
-		gl.bindBuffer(GL.ARRAY_BUFFER, m.b);
+		gl.bindBuffer(GL.ARRAY_BUFFER, b.vbuf);
 		curBuffer = b;
 
 		var strideBytes = b.format.strideBytes;
@@ -1294,7 +1293,7 @@ class GlDriver extends Driver {
 			var inf = map[i];
 			var b = buffers[inf.bufferIndex];
 			if( curBuffer != b ) {
-				gl.bindBuffer(GL.ARRAY_BUFFER, @:privateAccess b.vbuf.b);
+				gl.bindBuffer(GL.ARRAY_BUFFER, b.vbuf);
 				curBuffer = b;
 			}
 			var norm = false;

+ 4 - 1
h3d/impl/MemoryManager.hx

@@ -104,9 +104,12 @@ class MemoryManager {
 
 	function freeBuffer( b : Buffer ) {
 		if( b.vbuf == null ) return;
-		driver.disposeBuffer(b.vbuf);
+		driver.disposeBuffer(b);
 		b.vbuf = null;
 		b.mem = null;
+		#if multidriver
+		b.driver = null;
+		#end
 		usedMemory -= b.getMemSize();
 		buffers.remove(b);
 	}