Explorar o código

fixed texture management, added instance buffer support

Nicolas Cannasse %!s(int64=3) %!d(string=hai) anos
pai
achega
dc95397b34
Modificáronse 1 ficheiros con 79 adicións e 8 borrados
  1. 79 8
      h3d/impl/DX12Driver.hx

+ 79 - 8
h3d/impl/DX12Driver.hx

@@ -89,6 +89,7 @@ class ShaderRegisters {
 	public var textures : Int;
 	public var samplers : Int;
 	public var texturesCount : Int;
+	public var textures2DCount : Int;
 	public function new() {
 	}
 }
@@ -304,6 +305,7 @@ class DX12Driver extends h3d.impl.Driver {
 
 	var renderTargetViews : ManagedHeap;
 	var depthStenciViews : ManagedHeap;
+	var indirectCommand : CommandSignature;
 
 	var currentFrame : Int;
 	var fenceValue : Int64 = 0;
@@ -375,11 +377,19 @@ class DX12Driver extends h3d.impl.Driver {
 		depthStenciViews.onFree = function(prev) frame.toRelease.push(prev);
 		defaultDepth = new h3d.mat.DepthBuffer(0,0, Depth24Stencil8);
 
+		var desc = new CommandSignatureDesc();
+		desc.byteStride = 5 * 4;
+		desc.numArgumentDescs = 1;
+		desc.argumentDescs = new IndirectArgumentDesc();
+		desc.argumentDescs.type = DRAW_INDEXED;
+		indirectCommand = Driver.createCommandSignature(desc,null);
+
 		compiler = new ShaderCompiler();
 		resize(window.width, window.height);
 	}
 
 	function beginFrame() {
+		frameCount = hxd.Timer.frameCount;
 		currentFrame = Driver.getCurrentBackBufferIndex();
 		frame = frames[currentFrame];
 		frame.allocator.reset();
@@ -607,7 +617,10 @@ class DX12Driver extends h3d.impl.Driver {
 
 	override function setRenderTarget(tex:Null<h3d.mat.Texture>, layer:Int = 0, mipLevel:Int = 0) {
 
-		if( tex != null ) transition(tex.t, RENDER_TARGET);
+		if( tex != null ) {
+			if( tex.t == null ) tex.alloc();
+			transition(tex.t, RENDER_TARGET);
+		}
 
 		var texView = renderTargetViews.alloc(1);
 		var isArr = tex != null && (tex.flags.has(IsArray) || tex.flags.has(Cube));
@@ -854,6 +867,15 @@ class DX12Driver extends h3d.impl.Driver {
 				regs.texturesCount = sh.texturesCount;
 				regs.textures = paramsCount;
 
+				var p = sh.textures;
+				while( p != null ) {
+					switch( p.type ) {
+					case TArray( TSampler2D , SConst(n) ): regs.textures2DCount = n;
+					default:
+					}
+					p = p.next;
+				}
+
 				var r = allocDescTable(vis);
 				r.rangeType = SRV;
 				r.baseShaderRegister = 0;
@@ -1048,6 +1070,20 @@ class DX12Driver extends h3d.impl.Driver {
 		return buf;
 	}
 
+	override function allocInstanceBuffer(b:InstanceBuffer, bytes:haxe.io.Bytes) {
+		var dataSize = b.commandCount * 5 * 4;
+		var buf = allocBuffer(dataSize, DEFAULT, COPY_DEST);
+		var tmpBuf = allocDynamicBuffer(bytes, dataSize);
+		frame.commandList.copyBufferRegion(buf, 0, tmpBuf, 0, dataSize);
+		b.data = buf;
+
+		var b = tmp.barrier;
+		b.resource = buf;
+		b.stateBefore = COPY_DEST;
+		b.stateAfter = NON_PIXEL_SHADER_RESOURCE;
+		frame.commandList.resourceBarrier(b);
+	}
+
 	override function disposeVertexes(v:VertexBuffer) {
 		disposeResource(v);
 	}
@@ -1056,6 +1092,11 @@ class DX12Driver extends h3d.impl.Driver {
 		disposeResource(v);
 	}
 
+	override function disposeInstanceBuffer(b:InstanceBuffer) {
+		disposeResource(b.data);
+		b.data = null;
+	}
+
 	function updateBuffer( b : BufferData, bytes : hl.Bytes, startByte : Int, bytesCount : Int ) {
 		var tmpBuf;
 		if( b.uploaded )
@@ -1172,6 +1213,8 @@ class DX12Driver extends h3d.impl.Driver {
 		td.state = isRT ? RENDER_TARGET : COPY_DEST;
 		td.res = Driver.createCommittedResource(tmp.heap, flags, desc, isRT ? RENDER_TARGET : COPY_DEST, clear);
 		td.res.setName(t.name == null ? "Texture#"+t.id : t.name);
+		t.lastFrame = frameCount;
+		t.flags.unset(WasCleared);
 
 		return td;
 	}
@@ -1252,11 +1295,15 @@ class DX12Driver extends h3d.impl.Driver {
 		t.flags.set(WasCleared);
 	}
 
+	override function copyTexture(from:h3d.mat.Texture, to:h3d.mat.Texture):Bool {
+		return false;
+	}
+
 	// ----- PIPELINE UPDATE
 
 	override function uploadShaderBuffers(buffers:h3d.shader.Buffers, which:h3d.shader.Buffers.BufferKind) {
-		uploadBuffers(buffers.vertex, which, currentShader.shader.vertex, currentShader.vertexRegisters);
-		uploadBuffers(buffers.fragment, which, currentShader.shader.fragment, currentShader.fragmentRegisters);
+		uploadBuffers(buffers, buffers.vertex, which, currentShader.shader.vertex, currentShader.vertexRegisters);
+		uploadBuffers(buffers, buffers.fragment, which, currentShader.shader.fragment, currentShader.fragmentRegisters);
 	}
 
 	function calcCBVSize( dataSize : Int ) {
@@ -1300,7 +1347,7 @@ class DX12Driver extends h3d.impl.Driver {
 		return tmpBuf;
 	}
 
-	function uploadBuffers( buf : h3d.shader.Buffers.ShaderBuffers, which:h3d.shader.Buffers.BufferKind, shader : hxsl.RuntimeShader.RuntimeShaderData, regs : ShaderRegisters ) {
+	function uploadBuffers( buffers : h3d.shader.Buffers, buf : h3d.shader.Buffers.ShaderBuffers, which:h3d.shader.Buffers.BufferKind, shader : hxsl.RuntimeShader.RuntimeShaderData, regs : ShaderRegisters ) {
 		switch( which ) {
 		case Params:
 			if( shader.paramsSize > 0 ) {
@@ -1327,8 +1374,32 @@ class DX12Driver extends h3d.impl.Driver {
 				var sampler = frame.samplerViews.alloc(regs.texturesCount);
 				for( i in 0...regs.texturesCount ) {
 					var t = buf.tex[i];
-					if( t.t == null )
+
+					if( t == null || t.isDisposed() ) {
+						if( i < regs.textures2DCount ) {
+							var color = h3d.mat.Defaults.loadingTextureColor;
+							t = h3d.mat.Texture.fromColor(color, (color >>> 24) / 255);
+						} else {
+							t = h3d.mat.Texture.defaultCubeTexture();
+						}
+					}
+					if( t != null && t.t == null && t.realloc != null ) {
+						var s = currentShader;
 						t.alloc();
+						t.realloc();
+						if( hasDeviceError ) return;
+						if( s != currentShader ) {
+							// realloc triggered a shader change !
+							// we need to reset the original shader and reupload everything
+							currentShader = null;
+							selectShader(s.shader);
+							uploadShaderBuffers(buffers,Globals);
+							uploadShaderBuffers(buffers,Params);
+							uploadShaderBuffers(buffers,Textures);
+							return;
+						}
+					}
+
 					var tdesc : ShaderResourceViewDesc;
 					if( t.flags.has(Cube) ) {
 						var desc = tmp.texCubeSRV;
@@ -1344,6 +1415,7 @@ class DX12Driver extends h3d.impl.Driver {
 						desc.format = t.t.format;
 						tdesc = desc;
 					}
+					t.lastFrame = frameCount;
 					transition(t.t, shader.vertex ? NON_PIXEL_SHADER_RESOURCE : PIXEL_SHADER_RESOURCE);
 					Driver.createShaderResourceView(t.t.res, tdesc, srv.offset(i * frame.shaderResourceViews.stride));
 
@@ -1373,7 +1445,7 @@ class DX12Driver extends h3d.impl.Driver {
 					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);
+					transition(cbv, VERTEX_AND_CONSTANT_BUFFER);
 					var desc = tmp.cbvDesc;
 					desc.bufferLocation = cbv.res.getGpuVirtualAddress();
 					desc.sizeInBytes = cbv.size;
@@ -1592,7 +1664,7 @@ class DX12Driver extends h3d.impl.Driver {
 			frame.commandList.iaSetIndexBuffer(ibuf.view);
 		}
 		if( commands.data != null ) {
-			throw "TODO:ExecuteIndirect";
+			frame.commandList.executeIndirect(indirectCommand, commands.commandCount, commands.data, 0, null, 0);
 		} else {
 			frame.commandList.drawIndexedInstanced(commands.indexCount, commands.commandCount, commands.startIndex, 0, 0);
 		}
@@ -1621,7 +1693,6 @@ class DX12Driver extends h3d.impl.Driver {
 
 	override function present() {
 
-		frameCount++;
 		transition(frame.backBuffer, PRESENT);
 		flushFrame();
 		Driver.present(window.vsync);