Browse Source

various fixes

Nicolas Cannasse 3 years ago
parent
commit
ce5d13cb41
1 changed files with 94 additions and 27 deletions
  1. 94 27
      h3d/impl/DX12Driver.hx

+ 94 - 27
h3d/impl/DX12Driver.hx

@@ -28,6 +28,35 @@ class TempBuffer {
 	}
 }
 
+class ManagedHeapArray {
+
+	var heaps : Array<ManagedHeap>;
+	var type : DescriptorHeapType;
+	var size : Int;
+	var cursor : Int;
+
+	public function new(type,size) {
+		this.type = type;
+		this.size = size;
+		heaps = [];
+	}
+
+	public function reset() {
+		cursor = 0;
+	}
+
+	public function next() {
+		var h = heaps[cursor++];
+		if( h == null ) {
+			h = new ManagedHeap(type, size);
+			heaps.push(h);
+		} else
+			h.clear();
+		return h;
+	}
+
+}
+
 class DxFrame {
 	public var backBuffer : ResourceData;
 	public var depthBuffer : GpuResource;
@@ -37,6 +66,8 @@ class DxFrame {
 	public var toRelease : Array<Resource> = [];
 	public var shaderResourceViews : ManagedHeap;
 	public var samplerViews : ManagedHeap;
+	public var shaderResourceCache : ManagedHeapArray;
+	public var samplerCache : ManagedHeapArray;
 	public var availableBuffers : TempBuffer;
 	public var usedBuffers : TempBuffer;
 	public function new() {
@@ -161,8 +192,14 @@ class ManagedHeap {
 	}
 
 	public function alloc( count : Int ) {
-		if( cursor >= limit && cursor + count > size )
+		if( cursor >= limit && cursor + count > size ) {
 			cursor = 0;
+			if( limit == 0 ) {
+				var prev = heap;
+				allocHeap((size * 3) >> 1);
+				onFree(prev);
+			}
+		}
 		if( cursor < limit && cursor + count >= limit ) {
 			var prev = heap;
 			allocHeap((size * 3) >> 1);
@@ -175,7 +212,7 @@ class ManagedHeap {
 
 	inline function get_available() {
 		var d = limit - cursor;
-		return d <= 0 ? size - d : d;
+		return d <= 0 ? size + d : d;
 	}
 
 	public inline function grow( onFree ) {
@@ -290,7 +327,9 @@ class DX12Driver extends h3d.impl.Driver {
 	var rtHeight : Int;
 	var frameCount : Int;
 
-	static var BUFFER_COUNT = 2;
+	public static var INITIAL_RT_COUNT = 1024;
+	public static var BUFFER_COUNT = 2;
+	public static var DEVICE_NAME = null;
 	public static var DEBUG = false;
 
 	public function new() {
@@ -314,7 +353,7 @@ class DX12Driver extends h3d.impl.Driver {
 	function reset() {
 		var flags = new DriverInitFlags();
 		if( DEBUG ) flags.set(DriverInitFlag.DEBUG);
-		driver = Driver.create(window, flags);
+		driver = Driver.create(window, flags, DEVICE_NAME);
 		frames = [];
 		for(i in 0...BUFFER_COUNT) {
 			var f = new DxFrame();
@@ -322,16 +361,16 @@ class DX12Driver extends h3d.impl.Driver {
 			f.allocator = new CommandAllocator(DIRECT);
 			f.commandList = new CommandList(DIRECT, f.allocator, null);
 			f.commandList.close();
-			f.shaderResourceViews = new ManagedHeap(CBV_SRV_UAV, 1024);
-			f.samplerViews = new ManagedHeap(SAMPLER, 1024);
+			f.shaderResourceCache = new ManagedHeapArray(CBV_SRV_UAV, 1024);
+			f.samplerCache = new ManagedHeapArray(SAMPLER, 1024);
 			frames.push(f);
 		}
 		fence = new Fence(0, NONE);
 		fenceEvent = new WaitEvent(false);
 		tmp = new TempObjects();
 
-		renderTargetViews = new ManagedHeap(RTV);
-		depthStenciViews = new ManagedHeap(DSV);
+		renderTargetViews = new ManagedHeap(RTV, INITIAL_RT_COUNT);
+		depthStenciViews = new ManagedHeap(DSV, INITIAL_RT_COUNT);
 		renderTargetViews.onFree = function(prev) frame.toRelease.push(prev);
 		depthStenciViews.onFree = function(prev) frame.toRelease.push(prev);
 		defaultDepth = new h3d.mat.DepthBuffer(0,0, Depth24Stencil8);
@@ -375,13 +414,16 @@ class DX12Driver extends h3d.impl.Driver {
 
 		setRenderTarget(null);
 
+
+		frame.shaderResourceCache.reset();
+		frame.samplerCache.reset();
+		frame.shaderResourceViews = frame.shaderResourceCache.next();
+		frame.samplerViews = frame.samplerCache.next();
+
 		var arr = tmp.descriptors2;
 		arr[0] = @:privateAccess frame.shaderResourceViews.heap;
 		arr[1] = @:privateAccess frame.samplerViews.heap;
 		frame.commandList.setDescriptorHeaps(arr);
-
-		frame.shaderResourceViews.clear();
-		frame.samplerViews.clear();
 	}
 
 	override function clear(?color:Vector, ?depth:Float, ?stencil:Int) {
@@ -424,6 +466,8 @@ class DX12Driver extends h3d.impl.Driver {
 
 		currentWidth = rtWidth = width;
 		currentHeight = rtHeight = height;
+		@:privateAccess defaultDepth.width = width;
+		@:privateAccess defaultDepth.height = height;
 
 		if( frame != null )
 			frame.commandList.close();
@@ -483,6 +527,7 @@ class DX12Driver extends h3d.impl.Driver {
 
 	override function getDriverName(details:Bool) {
 		var desc = "DX12";
+		if( details ) desc += " "+Driver.getDeviceName();
 		return desc;
 	}
 
@@ -528,6 +573,12 @@ class DX12Driver extends h3d.impl.Driver {
 			depthEnabled = false;
 			return null;
 		}
+		if( tex != null ) {
+			var w = tex.depthBuffer.width;
+			var h = tex.depthBuffer.height;
+			if( w != tex.width || h != tex.height )
+				throw "Depth size mismatch";
+		}
 		var depthView = depthStenciViews.alloc(1);
 		Driver.createDepthStencilView(tex == null || tex.depthBuffer == defaultDepth ? frame.depthBuffer : @:privateAccess tex.depthBuffer.b.res, null, depthView);
 		var depths = tmp.depthStencils;
@@ -559,11 +610,12 @@ class DX12Driver extends h3d.impl.Driver {
 		if( tex != null ) transition(tex.t, RENDER_TARGET);
 
 		var texView = renderTargetViews.alloc(1);
+		var isArr = tex != null && (tex.flags.has(IsArray) || tex.flags.has(Cube));
 		var desc = null;
-		if( layer != 0 || mipLevel != 0 ) {
+		if( layer != 0 || mipLevel != 0 || isArr ) {
 			desc = tmp.rtvDesc;
 			desc.format = tex.t.format;
-			if( tex.flags.has(IsArray) || tex.flags.has(Cube) ) {
+			if( isArr ) {
 				desc.viewDimension = TEXTURE2DARRAY;
 				desc.mipSlice = mipLevel;
 				desc.firstArraySlice = layer;
@@ -965,15 +1017,18 @@ class DX12Driver extends h3d.impl.Driver {
 	override function allocVertexes( m : ManagedBuffer ) : VertexBuffer {
 		var buf = new VertexBufferData();
 		var size = (m.size * m.stride) << 2;
+		var bufSize = m.flags.has(UniformBuffer) ? calcCBVSize(size) : size;
 		buf.state = COPY_DEST;
-		buf.res = allocBuffer(size, DEFAULT, COPY_DEST);
-		var view = new VertexBufferView();
-		view.bufferLocation = buf.res.getGpuVirtualAddress();
-		view.sizeInBytes = size;
-		view.strideInBytes = m.stride << 2;
-		buf.view = view;
+		buf.res = allocBuffer(bufSize, DEFAULT, COPY_DEST);
+		if( !m.flags.has(UniformBuffer) ) {
+			var view = new VertexBufferView();
+			view.bufferLocation = buf.res.getGpuVirtualAddress();
+			view.sizeInBytes = size;
+			view.strideInBytes = m.stride << 2;
+			buf.view = view;
+		}
 		buf.stride = m.stride;
-		buf.size = size;
+		buf.size = bufSize;
 		buf.uploaded = m.flags.has(Dynamic);
 		return buf;
 	}
@@ -1180,6 +1235,10 @@ class DX12Driver extends h3d.impl.Driver {
 
 		var upd = new SubResourceData();
 		var stride = @:privateAccess pixels.stride;
+		switch( t.format ) {
+		case S3TC(n): stride = pixels.width * ((n == 1 || n == 4) ? 2 : 4); // "uncompressed" stride ?
+		default:
+		}
 		upd.data = (pixels.bytes:hl.Bytes).offset(pixels.offset);
 		upd.rowPitch = stride;
 		upd.slicePitch = pixels.dataSize;
@@ -1312,8 +1371,9 @@ class DX12Driver extends h3d.impl.Driver {
 					var srv = frame.shaderResourceViews.alloc(1);
 					var b = buf.buffers[i];
 					var cbv = @:privateAccess b.buffer.vbuf;
+					if( cbv.view != null )
+						throw "Buffer was allocated without UniformBuffer flag";
 					transition(cbv, shader.vertex ? NON_PIXEL_SHADER_RESOURCE : PIXEL_SHADER_RESOURCE);
-
 					var desc = tmp.cbvDesc;
 					desc.bufferLocation = cbv.res.getGpuVirtualAddress();
 					desc.sizeInBytes = cbv.size;
@@ -1522,12 +1582,7 @@ class DX12Driver extends h3d.impl.Driver {
 			frame.commandList.iaSetIndexBuffer(ibuf.view);
 		}
 		frame.commandList.drawIndexedInstanced(ntriangles * 3,1,startIndex,0,0);
-		if( frame.shaderResourceViews.available < 128 || frame.samplerViews.available < 64 ) {
-			var arr = tmp.descriptors2;
-			arr[0] = frame.shaderResourceViews.grow(function(prev) frame.toRelease.push(prev));
-			arr[1] = frame.samplerViews.grow(function(prev) frame.toRelease.push(prev));
-			frame.commandList.setDescriptorHeaps(arr);
-		}
+		flushResources();
 	}
 
 	override function drawInstanced(ibuf:IndexBuffer, commands:InstanceBuffer) {
@@ -1541,6 +1596,18 @@ class DX12Driver extends h3d.impl.Driver {
 		} else {
 			frame.commandList.drawIndexedInstanced(commands.indexCount, commands.commandCount, commands.startIndex, 0, 0);
 		}
+		flushResources();
+	}
+
+	function flushResources() {
+		if( frame.shaderResourceViews.available < 128 || frame.samplerViews.available < 64 ) {
+			frame.shaderResourceViews = frame.shaderResourceCache.next();
+			frame.samplerViews = frame.samplerCache.next();
+			var arr = tmp.descriptors2;
+			arr[0] = @:privateAccess frame.shaderResourceViews.heap;
+			arr[1] = @:privateAccess frame.samplerViews.heap;
+			frame.commandList.setDescriptorHeaps(arr);
+		}
 	}
 
 	function flushFrame() {