From ebef176089510bfb3f5c4ad152c3827b38cbd7ee Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sat, 20 Aug 2022 20:50:26 -0700 Subject: [PATCH] Dynamically indirect - Indirect engine now only allocates as much memory as it needs --- .../instancing/indirect/IndirectBuffers.java | 66 +++++++++++++++++-- .../instancing/indirect/IndirectEngine.java | 4 -- .../instancing/indirect/IndirectList.java | 4 +- 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectBuffers.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectBuffers.java index 3fade4ff6..bde48b05a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectBuffers.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectBuffers.java @@ -5,6 +5,7 @@ import static org.lwjgl.opengl.GL46.*; import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.Pointer; +import com.jozufozu.flywheel.backend.memory.FlwMemoryTracker; import com.jozufozu.flywheel.backend.memory.MemoryBlock; public class IndirectBuffers { @@ -43,8 +44,11 @@ public class IndirectBuffers { long batchPtr; long drawPtr; - int maxObjectCount; - int maxDrawCount; + int maxObjectCount = 0; + int maxDrawCount = 0; + + float objectGrowthFactor = 2f; + float drawGrowthFactor = 2f; IndirectBuffers(long objectStride) { this.objectStride = objectStride; @@ -63,10 +67,18 @@ public class IndirectBuffers { void updateCounts(int objectCount, int drawCount) { if (objectCount > maxObjectCount) { - createObjectStorage(objectCount); + var newObjectCount = maxObjectCount; + while (newObjectCount <= objectCount) { + newObjectCount *= objectGrowthFactor; + } + createObjectStorage(newObjectCount); } if (drawCount > maxDrawCount) { - createDrawStorage(drawCount); + var newDrawCount = maxDrawCount; + while (newDrawCount <= drawCount) { + newDrawCount *= drawGrowthFactor; + } + createDrawStorage(newDrawCount); } final long objectSize = objectStride * objectCount; @@ -81,24 +93,62 @@ public class IndirectBuffers { } void createObjectStorage(int objectCount) { + freeObjectStogare(); var objectSize = objectStride * objectCount; var targetSize = INT_SIZE * objectCount; - glNamedBufferStorage(object, objectSize, PERSISTENT_BITS); - glNamedBufferStorage(target, targetSize, GPU_ONLY_BITS); - glNamedBufferStorage(batch, targetSize, PERSISTENT_BITS); + if (maxObjectCount > 0) { + var ptr = buffers.ptr(); + nglCreateBuffers(3, ptr); + + int objectNew = MemoryUtil.memGetInt(ptr); + int targetNew = MemoryUtil.memGetInt(ptr + 4); + int batchNew = MemoryUtil.memGetInt(ptr + 8); + + glNamedBufferStorage(objectNew, objectSize, PERSISTENT_BITS); + glNamedBufferStorage(targetNew, targetSize, GPU_ONLY_BITS); + glNamedBufferStorage(batchNew, targetSize, PERSISTENT_BITS); + + glCopyNamedBufferSubData(object, objectNew, 0, 0, objectStride * maxObjectCount); + glCopyNamedBufferSubData(target, targetNew, 0, 0, INT_SIZE * maxObjectCount); + glCopyNamedBufferSubData(batch, batchNew, 0, 0, INT_SIZE * maxObjectCount); + + glDeleteBuffers(object); + glDeleteBuffers(target); + glDeleteBuffers(batch); + + object = objectNew; + target = targetNew; + batch = batchNew; + } else { + glNamedBufferStorage(object, objectSize, PERSISTENT_BITS); + glNamedBufferStorage(target, targetSize, GPU_ONLY_BITS); + glNamedBufferStorage(batch, targetSize, PERSISTENT_BITS); + } objectPtr = nglMapNamedBufferRange(object, 0, objectSize, MAP_BITS); batchPtr = nglMapNamedBufferRange(batch, 0, targetSize, MAP_BITS); maxObjectCount = objectCount; + + FlwMemoryTracker._allocGPUMemory(maxObjectCount * objectStride + maxObjectCount * INT_SIZE); } void createDrawStorage(int drawCount) { + freeDrawStorage(); var drawSize = DRAW_COMMAND_STRIDE * drawCount; glNamedBufferStorage(draw, drawSize, SUB_DATA_BITS); drawPtr = MemoryUtil.nmemAlloc(drawSize); // drawPtr = nglMapNamedBufferRange(draw, 0, drawSize, MAP_BITS); maxDrawCount = drawCount; + FlwMemoryTracker._allocGPUMemory(maxDrawCount * DRAW_COMMAND_STRIDE); + } + + private void freeObjectStogare() { + FlwMemoryTracker._freeGPUMemory(maxObjectCount * objectStride + maxObjectCount * INT_SIZE); + } + + private void freeDrawStorage() { + FlwMemoryTracker._freeGPUMemory(maxDrawCount * DRAW_COMMAND_STRIDE); } public void bindAll() { @@ -138,5 +188,7 @@ public class IndirectBuffers { public void delete() { nglDeleteBuffers(BUFFER_COUNT, buffers.ptr()); buffers.free(); + freeObjectStogare(); + freeDrawStorage(); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java index 3722d7ee1..a48c46954 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java @@ -88,10 +88,6 @@ public class IndirectEngine implements Engine { RenderSystem.enableCull(); } - public void clearAll() { - factories.values().forEach(IndirectFactory::clear); - } - @Override public void delete() { factories.values() diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectList.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectList.java index 264b644b2..7109e4d83 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectList.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectList.java @@ -45,8 +45,8 @@ public class IndirectList { objectStride = storageBufferWriter.getAlignment(); buffers = new IndirectBuffers(objectStride); buffers.createBuffers(); - buffers.createObjectStorage(64 * 64 * 64); - buffers.createDrawStorage(64); + buffers.createObjectStorage(128); + buffers.createDrawStorage(16); meshPool = new IndirectMeshPool(vertexType, 1024);