mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-10 20:45:59 +01:00
Dynamically indirect
- Indirect engine now only allocates as much memory as it needs
This commit is contained in:
parent
bcaf36c48c
commit
ebef176089
@ -5,6 +5,7 @@ import static org.lwjgl.opengl.GL46.*;
|
|||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
import org.lwjgl.system.Pointer;
|
import org.lwjgl.system.Pointer;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.memory.FlwMemoryTracker;
|
||||||
import com.jozufozu.flywheel.backend.memory.MemoryBlock;
|
import com.jozufozu.flywheel.backend.memory.MemoryBlock;
|
||||||
|
|
||||||
public class IndirectBuffers {
|
public class IndirectBuffers {
|
||||||
@ -43,8 +44,11 @@ public class IndirectBuffers {
|
|||||||
long batchPtr;
|
long batchPtr;
|
||||||
long drawPtr;
|
long drawPtr;
|
||||||
|
|
||||||
int maxObjectCount;
|
int maxObjectCount = 0;
|
||||||
int maxDrawCount;
|
int maxDrawCount = 0;
|
||||||
|
|
||||||
|
float objectGrowthFactor = 2f;
|
||||||
|
float drawGrowthFactor = 2f;
|
||||||
|
|
||||||
IndirectBuffers(long objectStride) {
|
IndirectBuffers(long objectStride) {
|
||||||
this.objectStride = objectStride;
|
this.objectStride = objectStride;
|
||||||
@ -63,10 +67,18 @@ public class IndirectBuffers {
|
|||||||
void updateCounts(int objectCount, int drawCount) {
|
void updateCounts(int objectCount, int drawCount) {
|
||||||
|
|
||||||
if (objectCount > maxObjectCount) {
|
if (objectCount > maxObjectCount) {
|
||||||
createObjectStorage(objectCount);
|
var newObjectCount = maxObjectCount;
|
||||||
|
while (newObjectCount <= objectCount) {
|
||||||
|
newObjectCount *= objectGrowthFactor;
|
||||||
|
}
|
||||||
|
createObjectStorage(newObjectCount);
|
||||||
}
|
}
|
||||||
if (drawCount > maxDrawCount) {
|
if (drawCount > maxDrawCount) {
|
||||||
createDrawStorage(drawCount);
|
var newDrawCount = maxDrawCount;
|
||||||
|
while (newDrawCount <= drawCount) {
|
||||||
|
newDrawCount *= drawGrowthFactor;
|
||||||
|
}
|
||||||
|
createDrawStorage(newDrawCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
final long objectSize = objectStride * objectCount;
|
final long objectSize = objectStride * objectCount;
|
||||||
@ -81,24 +93,62 @@ public class IndirectBuffers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void createObjectStorage(int objectCount) {
|
void createObjectStorage(int objectCount) {
|
||||||
|
freeObjectStogare();
|
||||||
var objectSize = objectStride * objectCount;
|
var objectSize = objectStride * objectCount;
|
||||||
var targetSize = INT_SIZE * objectCount;
|
var targetSize = INT_SIZE * objectCount;
|
||||||
|
|
||||||
glNamedBufferStorage(object, objectSize, PERSISTENT_BITS);
|
if (maxObjectCount > 0) {
|
||||||
glNamedBufferStorage(target, targetSize, GPU_ONLY_BITS);
|
var ptr = buffers.ptr();
|
||||||
glNamedBufferStorage(batch, targetSize, PERSISTENT_BITS);
|
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);
|
objectPtr = nglMapNamedBufferRange(object, 0, objectSize, MAP_BITS);
|
||||||
batchPtr = nglMapNamedBufferRange(batch, 0, targetSize, MAP_BITS);
|
batchPtr = nglMapNamedBufferRange(batch, 0, targetSize, MAP_BITS);
|
||||||
maxObjectCount = objectCount;
|
maxObjectCount = objectCount;
|
||||||
|
|
||||||
|
FlwMemoryTracker._allocGPUMemory(maxObjectCount * objectStride + maxObjectCount * INT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createDrawStorage(int drawCount) {
|
void createDrawStorage(int drawCount) {
|
||||||
|
freeDrawStorage();
|
||||||
var drawSize = DRAW_COMMAND_STRIDE * drawCount;
|
var drawSize = DRAW_COMMAND_STRIDE * drawCount;
|
||||||
glNamedBufferStorage(draw, drawSize, SUB_DATA_BITS);
|
glNamedBufferStorage(draw, drawSize, SUB_DATA_BITS);
|
||||||
drawPtr = MemoryUtil.nmemAlloc(drawSize);
|
drawPtr = MemoryUtil.nmemAlloc(drawSize);
|
||||||
// drawPtr = nglMapNamedBufferRange(draw, 0, drawSize, MAP_BITS);
|
// drawPtr = nglMapNamedBufferRange(draw, 0, drawSize, MAP_BITS);
|
||||||
maxDrawCount = drawCount;
|
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() {
|
public void bindAll() {
|
||||||
@ -138,5 +188,7 @@ public class IndirectBuffers {
|
|||||||
public void delete() {
|
public void delete() {
|
||||||
nglDeleteBuffers(BUFFER_COUNT, buffers.ptr());
|
nglDeleteBuffers(BUFFER_COUNT, buffers.ptr());
|
||||||
buffers.free();
|
buffers.free();
|
||||||
|
freeObjectStogare();
|
||||||
|
freeDrawStorage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,10 +88,6 @@ public class IndirectEngine implements Engine {
|
|||||||
RenderSystem.enableCull();
|
RenderSystem.enableCull();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearAll() {
|
|
||||||
factories.values().forEach(IndirectFactory::clear);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
factories.values()
|
factories.values()
|
||||||
|
@ -45,8 +45,8 @@ public class IndirectList<T extends InstancedPart> {
|
|||||||
objectStride = storageBufferWriter.getAlignment();
|
objectStride = storageBufferWriter.getAlignment();
|
||||||
buffers = new IndirectBuffers(objectStride);
|
buffers = new IndirectBuffers(objectStride);
|
||||||
buffers.createBuffers();
|
buffers.createBuffers();
|
||||||
buffers.createObjectStorage(64 * 64 * 64);
|
buffers.createObjectStorage(128);
|
||||||
buffers.createDrawStorage(64);
|
buffers.createDrawStorage(16);
|
||||||
|
|
||||||
meshPool = new IndirectMeshPool(vertexType, 1024);
|
meshPool = new IndirectMeshPool(vertexType, 1024);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user