diff --git a/src/main/java/me/cortex/voxy/client/core/gl/GlBuffer.java b/src/main/java/me/cortex/voxy/client/core/gl/GlBuffer.java index ec3a3713..e21b1d35 100644 --- a/src/main/java/me/cortex/voxy/client/core/gl/GlBuffer.java +++ b/src/main/java/me/cortex/voxy/client/core/gl/GlBuffer.java @@ -12,6 +12,7 @@ import static org.lwjgl.opengl.GL45C.*; public class GlBuffer extends TrackedObject { public final int id; private final long size; + private final int flags; private static int COUNT; private static long TOTAL_SIZE; @@ -28,6 +29,7 @@ public class GlBuffer extends TrackedObject { } public GlBuffer(long size, int flags, boolean zero) { + this.flags = flags; this.id = glCreateBuffers(); this.size = size; glNamedBufferStorage(this.id, size, flags); @@ -48,6 +50,10 @@ public class GlBuffer extends TrackedObject { TOTAL_SIZE -= this.size; } + public boolean isSparse() { + return (this.flags&GL_SPARSE_STORAGE_BIT_ARB)!=0; + } + public long size() { return this.size; } diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/building/RenderDataFactory.java b/src/main/java/me/cortex/voxy/client/core/rendering/building/RenderDataFactory.java index ef6a01e7..488d9eaf 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/building/RenderDataFactory.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/building/RenderDataFactory.java @@ -18,7 +18,7 @@ import java.util.Arrays; public class RenderDataFactory { private static final boolean CHECK_NEIGHBOR_FACE_OCCLUSION = true; - private static final boolean DISABLE_CULL_SAME_OCCLUDES = false; + private static final boolean DISABLE_CULL_SAME_OCCLUDES = false;//TODO: FIX TRANSLUCENTS (e.g. stained glass) breaking on chunk boarders with this set to false (it might be something else????) private static final boolean VERIFY_MESHING = VoxyCommon.isVerificationFlagOn("verifyMeshing"); diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/AsyncNodeManager.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/AsyncNodeManager.java index dc1bec47..4822ee96 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/AsyncNodeManager.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical/AsyncNodeManager.java @@ -513,6 +513,7 @@ public class AsyncNodeManager { var upload = results.geometryUpload; if (!upload.dataUploadPoints.isEmpty()) { + ((BasicSectionGeometryData)this.geometryData).ensureAccessable(upload.maxElementAccess); TimingStatistics.A.start(); int copies = upload.dataUploadPoints.size(); @@ -848,6 +849,7 @@ public class AsyncNodeManager { private static class ComputeMemoryCopy { public int currentElemCopyAmount; + public int maxElementAccess; private MemoryBuffer scratchHeaderBuffer = new MemoryBuffer(1<<16); private MemoryBuffer scratchDataBuffer = new MemoryBuffer(1<<20); @@ -899,6 +901,7 @@ public class AsyncNodeManager { public void upload(int point, MemoryBuffer data) { if ((data.size%8)!=0) throw new IllegalStateException("Data must be of size multiple 8"); int elemSize = (int) (data.size / 8); + this.maxElementAccess = Math.max(this.maxElementAccess, point + elemSize); int header = this.dataUploadPoints.get(point); if (header != -1) { //If we already have a header location, we just need to reallocate the data @@ -973,6 +976,7 @@ public class AsyncNodeManager { } public void reset() { + this.maxElementAccess = 0; this.currentElemCopyAmount = 0; this.dataUploadPoints.clear(); this.arena.reset(); diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/section/geometry/BasicSectionGeometryData.java b/src/main/java/me/cortex/voxy/client/core/rendering/section/geometry/BasicSectionGeometryData.java index decd45e6..457ca77a 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/section/geometry/BasicSectionGeometryData.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/section/geometry/BasicSectionGeometryData.java @@ -49,9 +49,6 @@ public class BasicSectionGeometryData implements IGeometryData { buffer.free(); } buffer = new GlBuffer(geometryCapacity, GL_SPARSE_STORAGE_BIT_ARB); - glBindBuffer(GL_ARRAY_BUFFER, buffer.id); - glBufferPageCommitmentARB(GL_ARRAY_BUFFER, 0, geometryCapacity, true); - glBindBuffer(GL_ARRAY_BUFFER, 0); //buffer.zero(); error = glGetError(); if (error != GL_NO_ERROR) { @@ -67,6 +64,20 @@ public class BasicSectionGeometryData implements IGeometryData { Logger.info("Successfully allocated the geometry buffer in " + delta + "ms"); } + private long sparseCommitment = 0;//Tracks the current range of the allocated sparse buffer + public void ensureAccessable(int maxElementAccess) { + long size = (Integer.toUnsignedLong(maxElementAccess)*8L+65535L)&~65535L; + //If we are a sparse buffer, ensure the memory upto the requested size is allocated + if (this.geometryBuffer.isSparse()) { + if (this.sparseCommitment < size) {//if we try to access memory outside the allocation range, allocate it + glBindBuffer(GL_ARRAY_BUFFER, this.geometryBuffer.id); + glBufferPageCommitmentARB(GL_ARRAY_BUFFER, this.sparseCommitment, size-this.sparseCommitment, true); + glBindBuffer(GL_ARRAY_BUFFER, 0); + this.sparseCommitment = size; + } + } + } + public GlBuffer getGeometryBuffer() { return this.geometryBuffer; }