aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/makamys/lodmod/renderer
diff options
context:
space:
mode:
authormakamys <makamys@outlook.com>2022-06-07 21:44:14 +0200
committermakamys <makamys@outlook.com>2022-06-07 21:44:14 +0200
commit3814324d0d83ebf600874356d65687958cd4e42e (patch)
treee6db43b78e0ebebc6fa2d2a5166919733197fa3b /src/main/java/makamys/lodmod/renderer
parenta5148760dce388602243bbfc43793056ae36d5cd (diff)
downloadNeodymium-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.java77
-rw-r--r--src/main/java/makamys/lodmod/renderer/LODRenderer.java2
-rw-r--r--src/main/java/makamys/lodmod/renderer/Mesh.java10
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() {}