Browse Source

remove specific IndexBuffer type, instead use a Buffer variant

Nicolas Cannasse 1 year ago
parent
commit
48ed5a4640

+ 4 - 0
h3d/Buffer.hx

@@ -17,6 +17,10 @@ enum BufferFlag {
 		Can be written
 	**/
 	ReadWriteBuffer;
+	/**
+		Used as index buffer
+	**/
+	IndexBuffer;
 }
 
 @:allow(h3d.impl.MemoryManager)

+ 4 - 4
h3d/Engine.hx

@@ -166,7 +166,7 @@ class Engine {
 			throw "Invalid vertices count";
 		if( drawTri > 0 && selectBuffer(b) ) {
 			// *3 because it's the position in indexes which are always by 3
-			driver.draw(indexes.ibuf, startTri * 3, drawTri);
+			driver.draw(indexes, startTri * 3, drawTri);
 			drawTriangles += drawTri;
 			drawCalls++;
 		}
@@ -180,7 +180,7 @@ class Engine {
 		if( drawTri < 0 ) drawTri = maxTri - startTri;
 		if( drawTri > 0 && selectBuffer(b) ) {
 			// *3 because it's the position in indexes which are always by 3
-			driver.draw(indexes.ibuf, startTri * 3, drawTri);
+			driver.draw(indexes, startTri * 3, drawTri);
 			drawTriangles += drawTri;
 			drawCalls++;
 		}
@@ -196,7 +196,7 @@ class Engine {
 		if( drawTri < 0 ) drawTri = maxTri - startTri;
 		if( drawTri > 0 ) {
 			// render
-			driver.draw(indexes.ibuf, startTri * 3, drawTri);
+			driver.draw(indexes, startTri * 3, drawTri);
 			drawTriangles += drawTri;
 			drawCalls++;
 		}
@@ -206,7 +206,7 @@ class Engine {
 		if( indexes.isDisposed() )
 			return;
 		if( commands.commandCount > 0 ) {
-			driver.drawInstanced(indexes.ibuf, commands);
+			driver.drawInstanced(indexes, commands);
 			drawTriangles += commands.triCount;
 			drawCalls++;
 		}

+ 17 - 39
h3d/Indexes.hx

@@ -1,52 +1,30 @@
 package h3d;
 
-@:allow(h3d.impl.MemoryManager)
-@:allow(h3d.Engine)
-class Indexes {
+@:forward(isDisposed, dispose, uploadBytes)
+abstract Indexes(Buffer) to Buffer {
 
-	var mem : h3d.impl.MemoryManager;
-	var ibuf : h3d.impl.Driver.IndexBuffer;
-	public var is32(default,null) : Bool;
-	public var count(default,null) : Int;
-	#if track_alloc
-	var allocPos : hxd.impl.AllocPos;
-	#end
+	public var count(get,never) : Int;
 
-	public function new(count,is32=false) {
-		this.mem = h3d.Engine.getCurrent().mem;
-		this.count = count;
-		this.is32 = is32;
-		mem.allocIndexes(this);
-		#if track_alloc
-		allocPos = new hxd.impl.AllocPos();
-		#end
+	public function new(count:Int,is32=false) {
+		this = new Buffer(count,is32 ? hxd.BufferFormat.INDEX32 : hxd.BufferFormat.INDEX16, [IndexBuffer]);
 	}
 
-	public function isDisposed() {
-		return ibuf == null;
+	public function uploadIndexes( ibuf : hxd.IndexBuffer, bufPos : Int, indices : Int, startIndice = 0 ) {
+		if( startIndice < 0 || indices < 0 || startIndice + indices > this.vertices )
+			throw "Invalid indices count";
+		if( @:privateAccess this.format.inputs[0].precision != F16 )
+			throw "Can't upload indexes on a 32-bit buffer";
+		if( indices == 0 )
+			return;
+		h3d.Engine.getCurrent().driver.uploadIndexData(this, startIndice, indices, ibuf, bufPos);
 	}
 
-	public function upload( indexes : hxd.IndexBuffer, pos : Int, count : Int, bufferPos = 0 ) {
-		mem.driver.uploadIndexBuffer(this.ibuf, pos, count, indexes, bufferPos);
-	}
-
-	public function uploadBytes( bytes : haxe.io.Bytes, dataPos : Int, indices : Int ) {
-		mem.driver.uploadIndexBytes(this.ibuf, 0, indices, bytes, dataPos);
-	}
-
-	public function readBytes( bytes : haxe.io.Bytes, bytesPosition : Int, indices : Int, startIndice : Int = 0 ) {
-		mem.driver.readIndexBytes(this.ibuf, startIndice, indices, bytes, bytesPosition);
-	}
-
-	public function dispose() {
-		if( ibuf != null )
-			mem.deleteIndexes(this);
-	}
+	inline function get_count() return this.vertices;
 
-	public static function alloc( i : hxd.IndexBuffer, startPos = 0, length = -1 ) {
+	public static function alloc( i : hxd.IndexBuffer, startPos = 0, length = -1 ) : Indexes {
 		if( length < 0 ) length = i.length;
-		var idx = new Indexes( length );
-		idx.upload(i, 0, length);
+		var idx = new Indexes(length);
+		idx.uploadIndexes(i, 0, length);
 		return idx;
 	}
 

+ 22 - 43
h3d/impl/DX12Driver.hx

@@ -256,14 +256,9 @@ class BufferData extends ResourceData {
 	public var uploaded : Bool;
 }
 
-class IndexBufferData extends BufferData {
-	public var view : IndexBufferView;
-	public var count : Int;
-	public var bits : Int;
-}
-
 class VertexBufferData extends BufferData {
 	public var view : dx.Dx12.VertexBufferView;
+	public var iview : dx.Dx12.IndexBufferView;
 	public var size : Int;
 }
 
@@ -327,7 +322,7 @@ class DX12Driver extends h3d.impl.Driver {
 	var currentShader : CompiledShader;
 	var compiledShaders : Map<Int,CompiledShader> = new Map();
 	var compiler : ShaderCompiler;
-	var currentIndex : IndexBuffer;
+	var currentIndex : Buffer;
 
 	var tmp : TempObjects;
 	var currentRenderTargets : Array<h3d.mat.Texture> = [];
@@ -1212,7 +1207,15 @@ class DX12Driver extends h3d.impl.Driver {
 		var bufSize = m.flags.has(UniformBuffer) ? calcCBVSize(size) : size;
 		buf.state = COPY_DEST;
 		buf.res = allocGPU(bufSize, DEFAULT, COMMON);
-		if( !m.flags.has(UniformBuffer) ) {
+		if( m.flags.has(UniformBuffer) ) {
+			// no view
+		} else if( m.flags.has(IndexBuffer) ) {
+			var view = new IndexBufferView();
+			view.bufferLocation = buf.res.getGpuVirtualAddress();
+			view.format = m.format.strideBytes == 4 ? R32_UINT : R16_UINT;
+			view.sizeInBytes = size;
+			buf.iview = view;
+		} else {
 			var view = new VertexBufferView();
 			view.bufferLocation = buf.res.getGpuVirtualAddress();
 			view.sizeInBytes = size;
@@ -1224,21 +1227,6 @@ class DX12Driver extends h3d.impl.Driver {
 		return buf;
 	}
 
-	override function allocIndexes( count : Int, is32 : Bool ) : IndexBuffer {
-		var buf = new IndexBufferData();
-		buf.state = COPY_DEST;
-		buf.count = count;
-		buf.bits = is32?2:1;
-		var size = count << buf.bits;
-		buf.res = allocGPU(size, DEFAULT, COMMON);
-		var view = new IndexBufferView();
-		view.bufferLocation = buf.res.getGpuVirtualAddress();
-		view.format = is32 ? R32_UINT : R16_UINT;
-		view.sizeInBytes = size;
-		buf.view = view;
-		return buf;
-	}
-
 	override function allocInstanceBuffer(b:InstanceBuffer, bytes:haxe.io.Bytes) {
 		var dataSize = b.commandCount * 5 * 4;
 		var buf = allocGPU(dataSize, DEFAULT, COMMON);
@@ -1257,10 +1245,6 @@ class DX12Driver extends h3d.impl.Driver {
 		disposeResource(v.vbuf);
 	}
 
-	override function disposeIndexes(v:IndexBuffer) {
-		disposeResource(v);
-	}
-
 	override function disposeInstanceBuffer(b:InstanceBuffer) {
 		frame.toRelease.push((b.data:GpuResource));
 		// disposeResource(b.data);
@@ -1285,29 +1269,24 @@ class DX12Driver extends h3d.impl.Driver {
 		}
 	}
 
-	override function uploadIndexBuffer(i:IndexBuffer, startIndice:Int, indiceCount:Int, buf:hxd.IndexBuffer, bufPos:Int) {
-		transition(i, COPY_DEST);
-		updateBuffer(i, hl.Bytes.getArray(buf.getNative()).offset(bufPos << i.bits), startIndice << i.bits, indiceCount << i.bits);
-		transition(i, INDEX_BUFFER);
-	}
-
-	override function uploadIndexBytes(i:IndexBuffer, startIndice:Int, indiceCount:Int, buf:haxe.io.Bytes, bufPos:Int) {
-		transition(i, COPY_DEST);
-		updateBuffer(i, @:privateAccess buf.b.offset(bufPos << i.bits), startIndice << i.bits, indiceCount << i.bits);
-		transition(i, INDEX_BUFFER);
+	override function uploadIndexData(i:Buffer, startIndice:Int, indiceCount:Int, buf:hxd.IndexBuffer, bufPos:Int) {
+		var bits = i.format.strideBytes >> 1;
+		transition(i.vbuf, COPY_DEST);
+		updateBuffer(i.vbuf, hl.Bytes.getArray(buf.getNative()).offset(bufPos << bits), startIndice << bits, indiceCount << bits);
+		transition(i.vbuf, INDEX_BUFFER);
 	}
 
 	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(b.vbuf, COPY_DEST);
 		updateBuffer(b.vbuf, data, startVertex * b.format.strideBytes, vertexCount * b.format.strideBytes);
-		transition(b.vbuf, VERTEX_AND_CONSTANT_BUFFER);
+		transition(b.vbuf, b.flags.has(IndexBuffer) ? INDEX_BUFFER : 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);
+		transition(b.vbuf, b.flags.has(IndexBuffer) ? INDEX_BUFFER : VERTEX_AND_CONSTANT_BUFFER);
 	}
 
 	// ------------ TEXTURES -------
@@ -1962,21 +1941,21 @@ class DX12Driver extends h3d.impl.Driver {
 
 	// --- DRAW etc.
 
-	override function draw( ibuf : IndexBuffer, startIndex : Int, ntriangles : Int ) {
+	override function draw( ibuf : Buffer, startIndex : Int, ntriangles : Int ) {
 		flushPipeline();
 		if( currentIndex != ibuf ) {
 			currentIndex = ibuf;
-			frame.commandList.iaSetIndexBuffer(ibuf.view);
+			frame.commandList.iaSetIndexBuffer(ibuf.vbuf.iview);
 		}
 		frame.commandList.drawIndexedInstanced(ntriangles * 3,1,startIndex,0,0);
 		flushResources();
 	}
 
-	override function drawInstanced(ibuf:IndexBuffer, commands:InstanceBuffer) {
+	override function drawInstanced(ibuf:Buffer, commands:InstanceBuffer) {
 		flushPipeline();
 		if( currentIndex != ibuf ) {
 			currentIndex = ibuf;
-			frame.commandList.iaSetIndexBuffer(ibuf.view);
+			frame.commandList.iaSetIndexBuffer(ibuf.vbuf.iview);
 		}
 		if( commands.data != null ) {
 			frame.commandList.executeIndirect(indirectCommand, commands.commandCount, commands.data, 0, null, 0);

+ 10 - 39
h3d/impl/DirectXDriver.hx

@@ -76,7 +76,7 @@ class DirectXDriver extends h3d.impl.Driver {
 	var strides : Array<Int> = [];
 	var offsets : Array<Int> = [];
 	var currentShader : CompiledShader;
-	var currentIndex : IndexBuffer;
+	var currentIndex : h3d.Buffer;
 	var currentDepth : Texture;
 	var currentLayout : Layout;
 	var currentTargets = new hl.NativeArray<RenderTargetView>(16);
@@ -328,18 +328,12 @@ class DirectXDriver extends h3d.impl.Driver {
 
 	override function allocBuffer(b:Buffer):GPUBuffer {
 		var size = b.getMemSize();
-		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);
+		var res = b.flags.has(UniformBuffer) ? dx.Driver.createBuffer(size, Dynamic, ConstantBuffer, CpuWrite, None, 0, null) :
+				dx.Driver.createBuffer(size, Default, b.flags.has(IndexBuffer) ? IndexBuffer : VertexBuffer, None, None, 0, null);
 		if( res == null ) return null;
 		return res;
 	}
 
-	override function allocIndexes( count : Int, is32 : Bool ) : IndexBuffer {
-		var bits = is32 ? 2 : 1;
-		var res = dx.Driver.createBuffer(count << bits, Default, IndexBuffer, None, None, 0, null);
-		if( res == null ) return null;
-		return { res : res, count : count, bits : bits  };
-	}
-
 	override function allocDepthBuffer( b : h3d.mat.Texture ) : Texture {
 		var depthDesc = new Texture2dDesc();
 		depthDesc.width = b.width;
@@ -499,10 +493,6 @@ class DirectXDriver extends h3d.impl.Driver {
 		b.vbuf.release();
 	}
 
-	override function disposeIndexes(i:IndexBuffer) {
-		i.res.release();
-	}
-
 	override function generateMipMaps(texture:h3d.mat.Texture) {
 		if( hasDeviceError ) return;
 		Driver.generateMips(texture.t.view);
@@ -519,14 +509,10 @@ class DirectXDriver extends h3d.impl.Driver {
 		updateResCount++;
 	}
 
-	override function uploadIndexBuffer(i:IndexBuffer, startIndice:Int, indiceCount:Int, buf:hxd.IndexBuffer, bufPos:Int) {
+	override function uploadIndexData(i:Buffer, startIndice:Int, indiceCount:Int, buf:hxd.IndexBuffer, bufPos:Int) {
 		if( hasDeviceError ) return;
-		updateBuffer(i.res, hl.Bytes.getArray(buf.getNative()).offset(bufPos << i.bits), startIndice << i.bits, indiceCount << i.bits);
-	}
-
-	override function uploadIndexBytes(i:IndexBuffer, startIndice:Int, indiceCount:Int, buf:haxe.io.Bytes, bufPos:Int) {
-		if( hasDeviceError ) return;
-		updateBuffer(i.res, @:privateAccess buf.b.offset(bufPos << i.bits), startIndice << i.bits, indiceCount << i.bits);
+		var bits = i.format.strideBytes >> 1;
+		updateBuffer(i.vbuf, hl.Bytes.getArray(buf.getNative()).offset(bufPos << bits), startIndice << bits, indiceCount << bits);
 	}
 
 	override function uploadBufferData(b:Buffer, startVertex:Int, vertexCount:Int, buf:hxd.FloatBuffer, bufPos:Int) {
@@ -556,21 +542,6 @@ class DirectXDriver extends h3d.impl.Driver {
 		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) {
-		var tmp = dx.Driver.createBuffer(indiceCount << v.bits, Staging, None, CpuRead | CpuWrite, None, 0, null);
-		box.left = startIndice << v.bits;
-		box.top = 0;
-		box.front = 0;
-		box.right = (startIndice + indiceCount) << v.bits;
-		box.bottom = 1;
-		box.back = 1;
-		tmp.copySubresourceRegion(0, 0, 0, 0, v.res, 0, box);
-		var ptr = tmp.map(0, Read, true, null);
-		@:privateAccess buf.b.blit(bufPos, ptr, 0, indiceCount << v.bits);
-		tmp.unmap(0);
-		tmp.release();
-	}
-
 	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);
@@ -1409,12 +1380,12 @@ class DirectXDriver extends h3d.impl.Driver {
 		}
 	}
 
-	override function draw(ibuf:IndexBuffer, startIndex:Int, ntriangles:Int) {
+	override function draw(ibuf:Buffer, startIndex:Int, ntriangles:Int) {
 		if( !allowDraw )
 			return;
 		if( currentIndex != ibuf ) {
 			currentIndex = ibuf;
-			dx.Driver.iaSetIndexBuffer(ibuf.res,ibuf.bits == 2,0);
+			dx.Driver.iaSetIndexBuffer(ibuf.vbuf,ibuf.format.strideBytes == 4,0);
 		}
 		dx.Driver.drawIndexed(ntriangles * 3, startIndex, 0);
 	}
@@ -1428,12 +1399,12 @@ class DirectXDriver extends h3d.impl.Driver {
 		b.data = null;
 	}
 
-	override function drawInstanced(ibuf:IndexBuffer, commands:InstanceBuffer) {
+	override function drawInstanced(ibuf:Buffer, commands:InstanceBuffer) {
 		if( !allowDraw )
 			return;
 		if( currentIndex != ibuf ) {
 			currentIndex = ibuf;
-			dx.Driver.iaSetIndexBuffer(ibuf.res,ibuf.bits == 2,0);
+			dx.Driver.iaSetIndexBuffer(ibuf.vbuf,ibuf.format.strideBytes == 4,0);
 		}
 		if( commands.data == null ) {
 			#if( (hldx == "1.8.0") || (hldx == "1.9.0") )

+ 3 - 25
h3d/impl/Driver.hx

@@ -1,42 +1,34 @@
 package h3d.impl;
 
 #if macro
-typedef IndexBuffer = {};
 typedef GPUBuffer = {};
 typedef Texture = {};
 typedef Query = {};
 #elseif js
-typedef IndexBuffer = { b : js.html.webgl.Buffer, is32 : Bool };
 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, startMip : Int };
 typedef Query = {};
 #elseif hlsdl
-typedef IndexBuffer = { b : sdl.GL.Buffer, is32 : Bool };
 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, startMip : Int };
 typedef Query = { q : sdl.GL.Query, kind : QueryKind };
 #elseif usegl
-typedef IndexBuffer = { b : haxe.GLTypes.Buffer, is32 : Bool };
 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, startMip : Int };
 typedef Query = { q : haxe.GLTypes.Query, kind : QueryKind };
 #elseif (hldx && dx12)
-typedef IndexBuffer = DX12Driver.IndexBufferData;
 typedef GPUBuffer = DX12Driver.VertexBufferData;
 typedef Texture = h3d.impl.DX12Driver.TextureData;
 typedef Query = h3d.impl.DX12Driver.QueryData;
 #elseif hldx
-typedef IndexBuffer = { res : dx.Resource, count : Int, bits : Int };
 typedef GPUBuffer = dx.Resource;
 typedef Texture = { res : dx.Resource, view : dx.Driver.ShaderResourceView, ?depthView : dx.Driver.DepthStencilView, ?readOnlyDepthView : dx.Driver.DepthStencilView, rt : Array<dx.Driver.RenderTargetView>, mips : Int, ?views : Array<dx.Driver.ShaderResourceView> };
 typedef Query = {};
 #elseif usesys
-typedef IndexBuffer = haxe.GraphicsDriver.IndexBuffer;
 typedef GPUBuffer = haxe.GraphicsDriver.GPUBuffer;
 typedef Texture = haxe.GraphicsDriver.Texture;
 typedef Query = haxe.GraphicsDriver.Query;
 #else
-typedef IndexBuffer = {};
 typedef GPUBuffer = {};
 typedef Texture = {};
 typedef Query = {};
@@ -196,10 +188,10 @@ class Driver {
 	public function selectMultiBuffers( format : hxd.BufferFormat.MultiFormat, buffers : Array<h3d.Buffer> ) {
 	}
 
-	public function draw( ibuf : IndexBuffer, startIndex : Int, ntriangles : Int ) {
+	public function draw( ibuf : Buffer, startIndex : Int, ntriangles : Int ) {
 	}
 
-	public function drawInstanced( ibuf : IndexBuffer, commands : h3d.impl.InstanceBuffer ) {
+	public function drawInstanced( ibuf : Buffer, commands : h3d.impl.InstanceBuffer ) {
 	}
 
 	public function setRenderZone( x : Int, y : Int, width : Int, height : Int ) {
@@ -238,10 +230,6 @@ class Driver {
 		return null;
 	}
 
-	public function allocIndexes( count : Int, is32 : Bool ) : IndexBuffer {
-		return null;
-	}
-
 	public function allocBuffer( b : h3d.Buffer ) : GPUBuffer {
 		return null;
 	}
@@ -252,19 +240,13 @@ class Driver {
 	public function disposeTexture( t : h3d.mat.Texture ) {
 	}
 
-	public function disposeIndexes( i : IndexBuffer ) {
-	}
-
 	public function disposeBuffer( b : Buffer ) {
 	}
 
 	public function disposeInstanceBuffer( b : h3d.impl.InstanceBuffer ) {
 	}
 
-	public function uploadIndexBuffer( i : IndexBuffer, startIndice : Int, indiceCount : Int, buf : hxd.IndexBuffer, bufPos : Int ) {
-	}
-
-	public function uploadIndexBytes( i : IndexBuffer, startIndice : Int, indiceCount : Int, buf : haxe.io.Bytes , bufPos : Int ) {
+	public function uploadIndexData( i : Buffer, startIndice : Int, indiceCount : Int, buf : hxd.IndexBuffer, bufPos : Int ) {
 	}
 
 	public function uploadBufferData( b : Buffer, startVertex : Int, vertexCount : Int, buf : hxd.FloatBuffer, bufPos : Int ) {
@@ -283,10 +265,6 @@ class Driver {
 		throw "Driver does not allow to read vertex bytes";
 	}
 
-	public function readIndexBytes( v : IndexBuffer, startVertex : Int, vertexCount : Int, buf : haxe.io.Bytes, bufPos : Int ) {
-		throw "Driver does not allow to read index bytes";
-	}
-
 	/**
 		Returns true if we could copy the texture, false otherwise (not supported by driver or mismatch in size/format)
 	**/

+ 24 - 56
h3d/impl/GlDriver.hx

@@ -97,7 +97,7 @@ class GlDriver extends Driver {
 	var maxIdxCurAttribs : Int = 0;
 	var curShader : CompiledProgram;
 	var curBuffer : h3d.Buffer;
-	var curIndexBuffer : IndexBuffer;
+	var curIndexBuffer : h3d.Buffer;
 	var curMatBits : Int = -1;
 	var curStOpBits : Int = -1;
 	var curStMaskBits : Int = -1;
@@ -1069,22 +1069,25 @@ class GlDriver extends Driver {
 	override function allocBuffer( b : h3d.Buffer ) : GPUBuffer {
 		discardError();
 		var vb = gl.createBuffer();
-		gl.bindBuffer(GL.ARRAY_BUFFER, vb);
+		var type = b.flags.has(IndexBuffer) ? GL.ELEMENT_ARRAY_BUFFER : GL.ARRAY_BUFFER;
+		gl.bindBuffer(type, vb);
 		if( b.vertices * b.format.stride == 0 ) throw "assert";
 		#if js
-		gl.bufferData(GL.ARRAY_BUFFER, b.getMemSize(), b.flags.has(Dynamic) ? GL.DYNAMIC_DRAW : GL.STATIC_DRAW);
+		gl.bufferData(type, b.getMemSize(), b.flags.has(Dynamic) ? GL.DYNAMIC_DRAW : GL.STATIC_DRAW);
 		#elseif hl
-		gl.bufferDataSize(GL.ARRAY_BUFFER, b.getMemSize(), b.flags.has(Dynamic) ? GL.DYNAMIC_DRAW : GL.STATIC_DRAW);
+		gl.bufferDataSize(type, b.getMemSize(), b.flags.has(Dynamic) ? GL.DYNAMIC_DRAW : GL.STATIC_DRAW);
 		#else
 		var tmp = new Uint8Array(b.getMemSize());
-		gl.bufferData(GL.ARRAY_BUFFER, tmp, b.flags.has(Dynamic) ? GL.DYNAMIC_DRAW : GL.STATIC_DRAW);
+		gl.bufferData(type, tmp, b.flags.has(Dynamic) ? GL.DYNAMIC_DRAW : GL.STATIC_DRAW);
 		#end
 		#if multidriver
 		@:privateAccess if( b.engine.driver != this )
 			throw "Invalid buffer context";
 		#end
 		var outOfMem = outOfMemoryCheck && gl.getError() == GL.OUT_OF_MEMORY;
-		gl.bindBuffer(GL.ARRAY_BUFFER, null);
+		gl.bindBuffer(type, null);
+		if( b.flags.has(IndexBuffer) )
+			curIndexBuffer = null;
 		if( outOfMem ) {
 			gl.deleteBuffer(vb);
 			return null;
@@ -1092,26 +1095,6 @@ class GlDriver extends Driver {
 		return vb;
 	}
 
-	override function allocIndexes( count : Int, is32 : Bool ) : IndexBuffer {
-		discardError();
-		var b = gl.createBuffer();
-		var size = is32 ? 4 : 2;
-		gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, b);
-		#if js
-		gl.bufferData(GL.ELEMENT_ARRAY_BUFFER, count * size, GL.STATIC_DRAW);
-		#elseif hl
-		gl.bufferDataSize(GL.ELEMENT_ARRAY_BUFFER, count * size, GL.STATIC_DRAW);
-		#end
-		var outOfMem = outOfMemoryCheck && gl.getError() == GL.OUT_OF_MEMORY;
-		gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, null);
-		curIndexBuffer = null;
-		if( outOfMem ) {
-			gl.deleteBuffer(b);
-			return null;
-		}
-		return { b : b, is32 : is32 };
-	}
-
 	override function disposeTexture( t : h3d.mat.Texture ) {
 		var tt = t.t;
 		if( tt == null ) return;
@@ -1122,10 +1105,6 @@ class GlDriver extends Driver {
 		gl.deleteTexture(tt.t);
 	}
 
-	override function disposeIndexes( i : IndexBuffer ) {
-		gl.deleteBuffer(i.b);
-	}
-
 	override function disposeBuffer( b : h3d.Buffer ) {
 		gl.deleteBuffer(b.vbuf);
 	}
@@ -1287,19 +1266,21 @@ class GlDriver extends Driver {
 
 	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);
+		var type = b.flags.has(IndexBuffer) ? GL.ELEMENT_ARRAY_BUFFER : GL.ARRAY_BUFFER;
+		gl.bindBuffer(type, b.vbuf);
 		#if hl
-		gl.bufferSubData(GL.ARRAY_BUFFER, startVertex * stride, streamData(buf.getData(),bufPos,vertexCount * stride), bufPos * STREAM_POS, vertexCount * stride);
+		gl.bufferSubData(type, startVertex * stride, streamData(buf.getData(),bufPos,vertexCount * stride), bufPos * STREAM_POS, vertexCount * stride);
 		#else
 		var sub = new Uint8Array(buf.getData(), bufPos, vertexCount * stride);
-		gl.bufferSubData(GL.ARRAY_BUFFER, startVertex * stride, sub);
+		gl.bufferSubData(type, startVertex * stride, sub);
 		#end
-		gl.bindBuffer(GL.ARRAY_BUFFER, null);
+		gl.bindBuffer(type, null);
+		if( b.flags.has(IndexBuffer) ) curIndexBuffer = null;
 	}
 
-	override function uploadIndexBuffer( i : IndexBuffer, startIndice : Int, indiceCount : Int, buf : hxd.IndexBuffer, bufPos : Int ) {
-		var bits = i.is32 ? 2 : 1;
-		gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, i.b);
+	override function uploadIndexData( i : h3d.Buffer, startIndice : Int, indiceCount : Int, buf : hxd.IndexBuffer, bufPos : Int ) {
+		var bits = i.format.strideBytes >> 1;
+		gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, i.vbuf);
 		#if hl
 		var data = #if hl hl.Bytes.getArray(buf.getNative()) #else buf.getNative() #end;
 		gl.bufferSubData(GL.ELEMENT_ARRAY_BUFFER, startIndice << bits, streamData(data,bufPos << bits,indiceCount << bits), (bufPos << bits) * STREAM_POS, indiceCount << bits);
@@ -1312,19 +1293,6 @@ class GlDriver extends Driver {
 		curIndexBuffer = null;
 	}
 
-	override function uploadIndexBytes( i : IndexBuffer, startIndice : Int, indiceCount : Int, buf : haxe.io.Bytes , bufPos : Int ) {
-		var bits = i.is32 ? 2 : 1;
-		gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, i.b);
-		#if hl
-		gl.bufferSubData(GL.ELEMENT_ARRAY_BUFFER, startIndice << bits, streamData(buf.getData(),bufPos << bits, indiceCount << bits), (bufPos << bits) * STREAM_POS, indiceCount << bits);
-		#else
-		var sub = new Uint8Array(buf.getData(), bufPos << bits, indiceCount << bits);
-		gl.bufferSubData(GL.ELEMENT_ARRAY_BUFFER, startIndice << bits, sub);
-		#end
-		gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, null);
-		curIndexBuffer = null;
-	}
-
 	inline function updateDivisor( a : CompiledAttribute ) {
 		if( currentDivisor[a.index] != a.divisor ) {
 			currentDivisor[a.index] = a.divisor;
@@ -1380,12 +1348,12 @@ class GlDriver extends Driver {
 		}
 	}
 
-	override function draw( ibuf : IndexBuffer, startIndex : Int, ntriangles : Int ) {
+	override function draw( ibuf : h3d.Buffer, startIndex : Int, ntriangles : Int ) {
 		if( ibuf != curIndexBuffer ) {
 			curIndexBuffer = ibuf;
-			gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, ibuf.b);
+			gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, ibuf.vbuf);
 		}
-		if( ibuf.is32 )
+		if( ibuf.format.strideBytes == 4 )
 			gl.drawElements(drawMode, ntriangles * 3, GL.UNSIGNED_INT, startIndex * 4);
 		else
 			gl.drawElements(drawMode, ntriangles * 3, GL.UNSIGNED_SHORT, startIndex * 2);
@@ -1423,13 +1391,13 @@ class GlDriver extends Driver {
 		b.data = null;
 	}
 
-	override function drawInstanced( ibuf : IndexBuffer, commands : InstanceBuffer ) {
+	override function drawInstanced( ibuf : h3d.Buffer, commands : InstanceBuffer ) {
 		if( ibuf != curIndexBuffer ) {
 			curIndexBuffer = ibuf;
-			gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, ibuf.b);
+			gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, ibuf.vbuf);
 		}
 		var kind, size;
-		if( ibuf.is32 ) {
+		if( ibuf.format.strideBytes == 4 ) {
 			kind = GL.UNSIGNED_INT;
 			size = 4;
 		} else {

+ 0 - 23
h3d/impl/MemoryManager.hx

@@ -9,7 +9,6 @@ class MemoryManager {
 	@:allow(h3d)
 	var driver : Driver;
 	var buffers : Array<Buffer>;
-	var indexes : Array<Indexes>;
 	var textures : Array<h3d.mat.Texture>;
 	var depths : Array<h3d.mat.Texture>;
 
@@ -25,7 +24,6 @@ class MemoryManager {
 	}
 
 	public function init() {
-		indexes = new Array();
 		textures = new Array();
 		buffers = new Array();
 		depths = new Array();
@@ -133,24 +131,6 @@ class MemoryManager {
 			usedMemory -= b.getMemSize();
 	}
 
-	// ------------------------------------- INDEXES ------------------------------------------
-
-	@:allow(h3d.Indexes)
-	function deleteIndexes( i : Indexes ) {
-		indexes.remove(i);
-		driver.disposeIndexes(i.ibuf);
-		i.ibuf = null;
-		usedMemory -= i.count * (i.is32 ? 4 : 2);
-	}
-
-	@:allow(h3d.Indexes)
-	function allocIndexes( i : Indexes ) {
-		i.ibuf = driver.allocIndexes(i.count,i.is32);
-		indexes.push(i);
-		usedMemory += i.count * (i.is32 ? 4 : 2);
-	}
-
-
 	// ------------------------------------- TEXTURES ------------------------------------------
 
 	function memSize( t : h3d.mat.Texture ) {
@@ -251,10 +231,7 @@ class MemoryManager {
 			b.dispose();
 		for( b in buffers.copy() )
 			b.dispose();
-		for( i in indexes.copy() )
-			i.dispose();
 		buffers = [];
-		indexes = [];
 		textures = [];
 		usedMemory = 0;
 		texMemory = 0;

+ 0 - 4
h3d/impl/NullDriver.hx

@@ -46,10 +46,6 @@ class NullDriver extends Driver {
 		return cast {};
 	}
 
-	override function allocIndexes( count : Int, is32 : Bool ) : IndexBuffer {
-		return cast {};
-	}
-
 	override function allocBuffer( b : Buffer ) : GPUBuffer {
 		return cast {};
 	}

+ 1 - 1
h3d/prim/DynamicPrimitive.hx

@@ -64,7 +64,7 @@ class DynamicPrimitive extends Primitive {
 			indexes = alloc.allocIndexBuffer(hxd.Math.imax(minISize, isize));
 
 		buffer.uploadFloats(vbuf, 0, vsize);
-		indexes.upload(ibuf, 0, isize);
+		indexes.uploadIndexes(ibuf, 0, isize);
 	}
 
 	override function dispose() {

+ 15 - 0
hxd/BufferFormat.hx

@@ -225,6 +225,9 @@ class BufferFormat {
 	public static var POS3D_NORMAL_UV_RGBA(get,null) : BufferFormat;
 	public static var VEC4_DATA(get,null) : BufferFormat;
 
+	public static var INDEX16(get,null) : BufferFormat;
+	public static var INDEX32(get,null) : BufferFormat;
+
 	static inline function get_H2D() return XY_UV_RGBA;
 	static function get_XY_UV_RGBA() {
 		if( XY_UV_RGBA == null ) XY_UV_RGBA = make([{ name : "position", type : DVec2 },{ name : "uv", type : DVec2 },{ name : "color", type : DVec4 }]);
@@ -259,6 +262,18 @@ class BufferFormat {
 		return VEC4_DATA;
 	}
 
+	static function get_INDEX16() {
+		if( INDEX16 == null ) {
+			INDEX16 = hxd.BufferFormat.make([{ name : "index", type : DFloat, precision: F16 }]);
+			INDEX16.strideBytes = 2; // fix ! not subject to vertex buffer alignment !
+		}
+		return INDEX16;
+	}
+	static function get_INDEX32() {
+		if( INDEX32 == null ) INDEX32 = hxd.BufferFormat.make([{ name : "index", type : DFloat, precision: F32 }]);
+		return INDEX32;
+	}
+
 	static var ALL_FORMATS = new Map<String,Array<BufferFormat>>();
 	public static function make( inputs : Array<BufferInput> ) {
 		var names = [];

+ 1 - 1
hxd/impl/Allocator.hx

@@ -47,7 +47,7 @@ class Allocator {
 	public function ofIndexes( ib: hxd.IndexBuffer, length = -1) {
 		if( length < 0 && ib != null ) length = ib.length;
 		var idx = allocIndexBuffer( length );
-		idx.upload(ib, 0, length);
+		idx.uploadIndexes(ib, 0, length);
 		return idx;
 	}