Jelajahi Sumber

Revert "Move GPUMeshBatch command buffer back to MeshBatch (will be uploaded from cpu)."

This reverts commit 67d37044da1d62a2a4dda3e1f87d692e2a35955a.
clementlandrin 5 bulan lalu
induk
melakukan
5042a05bcc
2 mengubah file dengan 66 tambahan dan 55 penghapusan
  1. 55 11
      h3d/scene/GPUMeshBatch.hx
  2. 11 44
      h3d/scene/MeshBatch.hx

+ 55 - 11
h3d/scene/GPUMeshBatch.hx

@@ -5,6 +5,7 @@ import h3d.scene.MeshBatch.MeshBatchPart;
 
 
 class GPUMeshBatch extends MeshBatch {
 class GPUMeshBatch extends MeshBatch {
 
 
+	static var INDIRECT_DRAW_ARGUMENTS_FMT = hxd.BufferFormat.make([{ name : "", type : DVec4 }, { name : "", type : DFloat }]);
 	static var INSTANCE_OFFSETS_FMT = hxd.BufferFormat.make([{ name : "", type : DFloat }]);
 	static var INSTANCE_OFFSETS_FMT = hxd.BufferFormat.make([{ name : "", type : DFloat }]);
 
 
 	var matInfos : h3d.Buffer;
 	var matInfos : h3d.Buffer;
@@ -53,14 +54,6 @@ class GPUMeshBatch extends MeshBatch {
 
 
 	function getLodCount() return gpuLodEnabled ? getPrimitive().lodCount() : 1;
 	function getLodCount() return gpuLodEnabled ? getPrimitive().lodCount() : 1;
 	override function updateHasPrimitiveOffset() meshBatchFlags.set(HasPrimitiveOffset);
 	override function updateHasPrimitiveOffset() meshBatchFlags.set(HasPrimitiveOffset);
-	override function useCommandBuffer() return true;
-	override function useCountBuffer() {
-		#if hlsdl
-		return h3d.impl.GlDriver.hasMultiIndirectCount;
-		#else
-		return true;
-		#end
-	}
 
 
 	override function begin( emitCountTip = -1) {
 	override function begin( emitCountTip = -1) {
 		if ( !gpuLodEnabled && !gpuCullingEnabled )
 		if ( !gpuLodEnabled && !gpuCullingEnabled )
@@ -206,6 +199,30 @@ class GPUMeshBatch extends MeshBatch {
 		materialCount = 0;
 		materialCount = 0;
 	}
 	}
 
 
+	override function onFlushBuffer(p : BatchData, index : Int, count : Int) {
+		var p = cast(p, GPUBatchData);
+		var alloc = hxd.impl.Allocator.get();
+
+		var commandCountAllocated = hxd.Math.imin( hxd.Math.nextPOT( count ), p.maxInstance );
+		if ( p.commandBuffers == null) {
+			p.commandBuffers = [];
+			p.countBuffers = [];
+		}
+		var buf = p.commandBuffers[index];
+		var cbuf = p.countBuffers[index];
+		if ( buf == null ) {
+			buf = alloc.allocBuffer( commandCountAllocated, INDIRECT_DRAW_ARGUMENTS_FMT, UniformReadWrite );
+			cbuf = alloc.allocBuffer( 1, hxd.BufferFormat.VEC4_DATA, UniformReadWrite );
+			p.commandBuffers[index] = buf;
+			p.countBuffers[index] = cbuf;
+		}
+		else if ( buf.vertices < commandCountAllocated ) {
+			alloc.disposeBuffer( buf );
+			buf = alloc.allocBuffer( commandCountAllocated, INDIRECT_DRAW_ARGUMENTS_FMT, UniformReadWrite );
+			p.commandBuffers[index] = buf;
+		}
+	}
+
 	override function onFlushPass(p : BatchData) {
 	override function onFlushPass(p : BatchData) {
 		var p = cast(p, GPUBatchData);
 		var p = cast(p, GPUBatchData);
 		var prim = getPrimitive();
 		var prim = getPrimitive();
@@ -268,7 +285,7 @@ class GPUMeshBatch extends MeshBatch {
 				p.countBuffers[i].uploadBytes(countBytes, 0, 1);
 				p.countBuffers[i].uploadBytes(countBytes, 0, 1);
 				computeShader.countBuffer = p.countBuffers[i];
 				computeShader.countBuffer = p.countBuffers[i];
 				computeShader.startInstanceOffset = emittedCount;
 				computeShader.startInstanceOffset = emittedCount;
-				computeShader.ENABLE_COUNT_BUFFER = useCountBuffer();
+				computeShader.ENABLE_COUNT_BUFFER = isCountBufferAllowed();
 				ctx.computeList(@:privateAccess p.computePass.shaders);
 				ctx.computeList(@:privateAccess p.computePass.shaders);
 				ctx.computeDispatch(count);
 				ctx.computeDispatch(count);
 				emittedCount += count;
 				emittedCount += count;
@@ -276,6 +293,23 @@ class GPUMeshBatch extends MeshBatch {
 		}
 		}
 	}
 	}
 
 
+	override function setPassCommand(p : BatchData, bufferIndex : Int) {
+		super.setPassCommand(p, bufferIndex);
+		var p = cast(p, GPUBatchData);
+		if ( p.commandBuffers != null && p.commandBuffers.length > 0 ) {
+			@:privateAccess instanced.commands.data = p.commandBuffers[bufferIndex].vbuf;
+			@:privateAccess instanced.commands.countBuffer = p.countBuffers[bufferIndex].vbuf;
+		}
+	}
+
+	inline function isCountBufferAllowed() {
+		#if hlsdl
+		return h3d.impl.GlDriver.hasMultiIndirectCount;
+		#else
+		return true;
+		#end
+	}
+
 	override function cleanPasses() {
 	override function cleanPasses() {
 		if ( instanced.commands != null )
 		if ( instanced.commands != null )
 			@:privateAccess instanced.commands.data = null;
 			@:privateAccess instanced.commands.data = null;
@@ -302,10 +336,20 @@ class GPUMeshBatch extends MeshBatch {
 
 
 class GPUBatchData extends BatchData {
 class GPUBatchData extends BatchData {
 	public var computePass : h3d.mat.Pass;
 	public var computePass : h3d.mat.Pass;
+	public var commandBuffers : Array<h3d.Buffer>;
+	public var countBuffers : Array<h3d.Buffer>;
 
 
-	override function clean() {
+	override function clean() {		
 		super.clean();
 		super.clean();
 
 
-		computePass = null;
+		var alloc = hxd.impl.Allocator.get();
+		if ( commandBuffers != null && commandBuffers.length > 0 ) {
+			for ( buf in commandBuffers )
+				alloc.disposeBuffer(buf);
+			commandBuffers.resize(0);
+			for ( buf in countBuffers )
+				alloc.disposeBuffer(buf);
+			countBuffers.resize(0);
+		}
 	}
 	}
 }
 }

+ 11 - 44
h3d/scene/MeshBatch.hx

@@ -19,7 +19,6 @@ class MeshBatch extends MultiMaterial {
 	static var MAX_BUFFER_ELEMENTS = 4096;
 	static var MAX_BUFFER_ELEMENTS = 4096;
 	static var MAX_STORAGE_BUFFER_ELEMENTS = 128 * 1024 * 1024 >> 2;
 	static var MAX_STORAGE_BUFFER_ELEMENTS = 128 * 1024 * 1024 >> 2;
 	static var BATCH_START_FMT = hxd.BufferFormat.make([{ name : "Batch_Start", type : DFloat }]);
 	static var BATCH_START_FMT = hxd.BufferFormat.make([{ name : "Batch_Start", type : DFloat }]);
-	static var INDIRECT_DRAW_ARGUMENTS_FMT = hxd.BufferFormat.make([{ name : "", type : DVec4 }, { name : "", type : DFloat }]);
 
 
 	var instanced : h3d.prim.Instanced;
 	var instanced : h3d.prim.Instanced;
 	var dataPasses : BatchData;
 	var dataPasses : BatchData;
@@ -95,8 +94,6 @@ class MeshBatch extends MultiMaterial {
 	function gpuUpdateEnabled() return meshBatchFlags.has(EnableGpuUpdate);
 	function gpuUpdateEnabled() return meshBatchFlags.has(EnableGpuUpdate);
 	function getMaxElements() return storageBufferEnabled() ? MAX_STORAGE_BUFFER_ELEMENTS : MAX_BUFFER_ELEMENTS;
 	function getMaxElements() return storageBufferEnabled() ? MAX_STORAGE_BUFFER_ELEMENTS : MAX_BUFFER_ELEMENTS;
 	function hasPrimitiveOffset() return meshBatchFlags.has(HasPrimitiveOffset);
 	function hasPrimitiveOffset() return meshBatchFlags.has(HasPrimitiveOffset);
-	function useCommandBuffer() return false;
-	function useCountBuffer() return false;
 
 
 	public function begin( emitCountTip = -1 ) : Int {
 	public function begin( emitCountTip = -1 ) : Int {
 		instanceCount = 0;
 		instanceCount = 0;
@@ -335,26 +332,7 @@ class MeshBatch extends MultiMaterial {
 					}
 					}
 				}
 				}
 
 
-				if ( useCommandBuffer() ) {
-					var commandCountAllocated = hxd.Math.imin( hxd.Math.nextPOT( count ), p.maxInstance );
-					if ( p.commandBuffers == null) {
-						p.commandBuffers = [];
-						if ( useCountBuffer() )
-							p.countBuffers = [];
-					}
-					var buf = p.commandBuffers[index];
-					if ( buf == null ) {
-						buf = alloc.allocBuffer( commandCountAllocated, INDIRECT_DRAW_ARGUMENTS_FMT, UniformReadWrite );
-						p.commandBuffers[index] = buf;
-						if ( useCountBuffer() )
-							p.countBuffers[index] = alloc.allocBuffer( 1, hxd.BufferFormat.VEC4_DATA, UniformReadWrite );
-					}
-					else if ( buf.vertices < commandCountAllocated ) {
-						alloc.disposeBuffer( buf );
-						buf = alloc.allocBuffer( commandCountAllocated, INDIRECT_DRAW_ARGUMENTS_FMT, UniformReadWrite );
-						p.commandBuffers[index] = buf;
-					}
-				}
+				onFlushBuffer(p, index, count);
 
 
 				start += count;
 				start += count;
 				index++;
 				index++;
@@ -384,6 +362,8 @@ class MeshBatch extends MultiMaterial {
 		needUpload = false;
 		needUpload = false;
 	}
 	}
 
 
+	function onFlushBuffer(p : BatchData, index : Int, count : Int) {}
+
 	function onFlushPass(p : BatchData) {}
 	function onFlushPass(p : BatchData) {}
 
 
 	function syncData( batch : BatchData ) {
 	function syncData( batch : BatchData ) {
@@ -503,15 +483,9 @@ class MeshBatch extends MultiMaterial {
 				else
 				else
 					p.shader.Batch_Buffer = p.buffers[bufferIndex];
 					p.shader.Batch_Buffer = p.buffers[bufferIndex];
 
 
-				if( p.instanceBuffers == null ) {
-					var count = hxd.Math.imin( instanceCount - p.maxInstance * bufferIndex, p.maxInstance );
-					instanced.setCommand(p.matIndex, instanced.screenRatioToLod(curScreenRatio), count);
-					if ( useCommandBuffer() ) {
-						@:privateAccess instanced.commands.data = p.commandBuffers[bufferIndex].vbuf;
-						if ( useCountBuffer() )
-							@:privateAccess instanced.commands.countBuffer = p.countBuffers[bufferIndex].vbuf;
-					}
-				} else
+				if( p.instanceBuffers == null )
+					setPassCommand(p, bufferIndex);
+				else
 					instanced.commands = p.instanceBuffers[bufferIndex];
 					instanced.commands = p.instanceBuffers[bufferIndex];
 
 
 				break;
 				break;
@@ -525,6 +499,11 @@ class MeshBatch extends MultiMaterial {
 		ctx.drawPass.index = prev;
 		ctx.drawPass.index = prev;
 	}
 	}
 
 
+	function setPassCommand(p : BatchData, bufferIndex : Int) {
+		var count = hxd.Math.imin( instanceCount - p.maxInstance * bufferIndex, p.maxInstance );
+		instanced.setCommand(p.matIndex, instanced.screenRatioToLod(curScreenRatio), count);
+	}
+
 	override function calcScreenRatio(ctx:RenderContext) {
 	override function calcScreenRatio(ctx:RenderContext) {
 		curScreenRatio = getPrimitive().getBounds().dimension() / ( 2.0 * hxd.Math.max(lodDistance, 0.0001) );
 		curScreenRatio = getPrimitive().getBounds().dimension() / ( 2.0 * hxd.Math.max(lodDistance, 0.0001) );
 	}
 	}
@@ -590,8 +569,6 @@ class BatchData {
 	public var shader : hxsl.BatchShader;
 	public var shader : hxsl.BatchShader;
 	public var shaders : Array<hxsl.Shader>;
 	public var shaders : Array<hxsl.Shader>;
 	public var pass : h3d.mat.Pass;
 	public var pass : h3d.mat.Pass;
-	public var commandBuffers : Array<h3d.Buffer>;
-	public var countBuffers : Array<h3d.Buffer>;
 	public var next : BatchData;
 	public var next : BatchData;
 
 
 	public function new() {
 	public function new() {
@@ -599,16 +576,6 @@ class BatchData {
 
 
 	public function clean() {
 	public function clean() {
 		var alloc = hxd.impl.Allocator.get();
 		var alloc = hxd.impl.Allocator.get();
-		if ( commandBuffers != null ) {
-			for ( buf in commandBuffers )
-				alloc.disposeBuffer(buf);
-			commandBuffers = null;
-		}
-		if ( countBuffers != null ) {
-			for ( buf in countBuffers )
-				alloc.disposeBuffer(buf);
-			countBuffers = null;
-		}
 
 
 		pass.removeShader(shader);
 		pass.removeShader(shader);
 		for( b in buffers )
 		for( b in buffers )