diff options
author | makamys <makamys@outlook.com> | 2022-06-07 21:44:14 +0200 |
---|---|---|
committer | makamys <makamys@outlook.com> | 2022-06-07 21:44:14 +0200 |
commit | 3814324d0d83ebf600874356d65687958cd4e42e (patch) | |
tree | e6db43b78e0ebebc6fa2d2a5166919733197fa3b /src/main/java/makamys/lodmod/renderer | |
parent | a5148760dce388602243bbfc43793056ae36d5cd (diff) | |
download | Neodymium-3814324d0d83ebf600874356d65687958cd4e42e.tar.gz Neodymium-3814324d0d83ebf600874356d65687958cd4e42e.tar.bz2 Neodymium-3814324d0d83ebf600874356d65687958cd4e42e.zip |
Incremental GC
Diffstat (limited to 'src/main/java/makamys/lodmod/renderer')
-rw-r--r-- | src/main/java/makamys/lodmod/renderer/GPUMemoryManager.java | 77 | ||||
-rw-r--r-- | src/main/java/makamys/lodmod/renderer/LODRenderer.java | 2 | ||||
-rw-r--r-- | src/main/java/makamys/lodmod/renderer/Mesh.java | 10 |
3 files changed, 53 insertions, 36 deletions
diff --git a/src/main/java/makamys/lodmod/renderer/GPUMemoryManager.java b/src/main/java/makamys/lodmod/renderer/GPUMemoryManager.java index eba0a8f..7693b4a 100644 --- a/src/main/java/makamys/lodmod/renderer/GPUMemoryManager.java +++ b/src/main/java/makamys/lodmod/renderer/GPUMemoryManager.java @@ -1,12 +1,6 @@ package makamys.lodmod.renderer; -import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER; -import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; -import static org.lwjgl.opengl.GL15.glBindBuffer; -import static org.lwjgl.opengl.GL15.glBufferData; -import static org.lwjgl.opengl.GL15.glBufferSubData; -import static org.lwjgl.opengl.GL15.glDeleteBuffers; -import static org.lwjgl.opengl.GL15.glGenBuffers; +import static org.lwjgl.opengl.GL15.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; @@ -21,8 +15,6 @@ public class GPUMemoryManager { public int VBO; - private int nextTri; - private int nextMeshOffset; private int nextMesh; private List<Mesh> sentMeshes = new ArrayList<>(); @@ -32,15 +24,12 @@ public class GPUMemoryManager { glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, BUFFER_SIZE, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, BUFFER_SIZE, GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } public void runGC() { - nextMeshOffset = 0; - nextTri = 0; - glBindBuffer(GL_ARRAY_BUFFER, VBO); int deletedNum = 0; @@ -48,24 +37,39 @@ public class GPUMemoryManager { long t0 = System.nanoTime(); - for(Iterator<Mesh> it = sentMeshes.iterator(); it.hasNext(); ) { - Mesh mesh = it.next(); + int moved = 0; + + Mesh startMesh = null; + + while(moved < 5 && !sentMeshes.isEmpty()) { + if(nextMesh >= sentMeshes.size()) { + nextMesh = 0; + } + Mesh mesh = sentMeshes.get(nextMesh); + + if(mesh == startMesh) { + break; // we have wrapped around + } else if(startMesh == null) { + startMesh = mesh; + } + if(mesh.gpuStatus == GPUStatus.SENT) { - if(mesh.offset != nextMeshOffset) { - glBufferSubData(GL_ARRAY_BUFFER, nextMeshOffset, mesh.buffer); + int offset = nextMesh == 0 ? 0 : sentMeshes.get(nextMesh - 1).getEnd(); + if(mesh.offset != offset) { + glBufferSubData(GL_ARRAY_BUFFER, offset, mesh.buffer); + moved++; } - mesh.iFirst = nextTri; - mesh.offset = nextMeshOffset; - - nextMeshOffset += mesh.bufferSize(); - nextTri += mesh.quadCount * 6; + mesh.iFirst = offset / mesh.getStride(); + mesh.offset = offset; + nextMesh++; } else if(mesh.gpuStatus == GPUStatus.PENDING_DELETE) { mesh.iFirst = mesh.offset = -1; mesh.visible = false; mesh.gpuStatus = GPUStatus.UNSENT; mesh.destroyBuffer(); - it.remove(); + sentMeshes.remove(nextMesh); + deletedNum++; deletedRAM += mesh.bufferSize(); } @@ -73,17 +77,32 @@ public class GPUMemoryManager { long t1 = System.nanoTime(); - System.out.println("Deleted " + deletedNum + " meshes in " + ((t1 - t0) / 1_000_000.0) + " ms, freeing up " + (deletedRAM / 1024 / 1024) + "MB of VRAM"); + //System.out.println("Deleted " + deletedNum + " meshes in " + ((t1 - t0) / 1_000_000.0) + " ms, freeing up " + (deletedRAM / 1024 / 1024) + "MB of VRAM"); glBindBuffer(GL_ARRAY_BUFFER, 0); } + private int malloc(int size) { + int nextBase = 0; + if(!sentMeshes.isEmpty()) { + nextBase = sentMeshes.get(sentMeshes.size() - 1).getEnd(); + } + + if(nextBase + size >= BUFFER_SIZE) { + return -1; + } else { + return nextBase; + } + } + public void sendMeshToGPU(Mesh mesh) { if(mesh == null) { return; } - if(nextMeshOffset + mesh.buffer.limit() >= BUFFER_SIZE) { + int nextMeshOffset = malloc(mesh.buffer.limit()); + + if(nextMeshOffset == -1) { return; } @@ -93,12 +112,10 @@ public class GPUMemoryManager { glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferSubData(GL_ARRAY_BUFFER, nextMeshOffset, mesh.buffer); - mesh.iFirst = nextTri; + mesh.iFirst = nextMeshOffset / mesh.getStride(); mesh.iCount = mesh.quadCount * 6; mesh.offset = nextMeshOffset; - nextTri += mesh.quadCount * 6; - nextMeshOffset += mesh.buffer.limit(); sentMeshes.add(mesh); glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -119,7 +136,7 @@ public class GPUMemoryManager { } public List<String> getDebugText() { - return Arrays.asList("VRAM: " + (nextMeshOffset / 1024 / 1024) + "MB / " + (BUFFER_SIZE / 1024 / 1024) + "MB"); + return Arrays.asList("VRAM: " + (malloc(0) / 1024 / 1024) + "MB / " + (BUFFER_SIZE / 1024 / 1024) + "MB"); } public void drawInfo() { @@ -134,7 +151,7 @@ public class GPUMemoryManager { int o2 = (mesh.offset + mesh.buffer.limit()) / 10000; if(o / rowLength == o2 / rowLength) { if(mesh.gpuStatus != Mesh.GPUStatus.PENDING_DELETE) { - GuiHelper.drawRectangle(o % rowLength, o / rowLength + yOff, mesh.buffer.limit() / scale + 1, 1, meshI % 2 == 0 ? 0xFFFFFF : 0x808080); + GuiHelper.drawRectangle(o % rowLength, o / rowLength + yOff, mesh.buffer.limit() / scale + 1, 1, meshI == nextMesh ? 0x00FF00 : 0xFFFFFF); } } else { for(int i = o; i < o2; i++) { diff --git a/src/main/java/makamys/lodmod/renderer/LODRenderer.java b/src/main/java/makamys/lodmod/renderer/LODRenderer.java index fb49e7b..7dac491 100644 --- a/src/main/java/makamys/lodmod/renderer/LODRenderer.java +++ b/src/main/java/makamys/lodmod/renderer/LODRenderer.java @@ -124,7 +124,7 @@ public class LODRenderer { if(LODMod.debugEnabled && Minecraft.getMinecraft().currentScreen == null) { handleKeyboard(); } - if(lastGCTime == -1 || (System.currentTimeMillis() - lastGCTime) > gcInterval) { + if(lastGCTime == -1 || (System.currentTimeMillis() - lastGCTime) > 10) { mem.runGC(); lastGCTime = System.currentTimeMillis(); } diff --git a/src/main/java/makamys/lodmod/renderer/Mesh.java b/src/main/java/makamys/lodmod/renderer/Mesh.java index 2367b03..600ccf1 100644 --- a/src/main/java/makamys/lodmod/renderer/Mesh.java +++ b/src/main/java/makamys/lodmod/renderer/Mesh.java @@ -25,11 +25,11 @@ public abstract class Mesh { } public int bufferSize() { - int bufferSize = quadCount * 6 * getStride(); - if(buffer != null) { - assert buffer.limit() == bufferSize; - } - return bufferSize; + return buffer.limit(); + } + + public int getEnd() { + return offset + bufferSize(); } public void prepareBuffer() {} |