diff --git a/src/main/java/me/cortex/voxy/client/core/model/IdNotYetComputedException.java b/src/main/java/me/cortex/voxy/client/core/model/IdNotYetComputedException.java index e21d86e0..1f704720 100644 --- a/src/main/java/me/cortex/voxy/client/core/model/IdNotYetComputedException.java +++ b/src/main/java/me/cortex/voxy/client/core/model/IdNotYetComputedException.java @@ -3,7 +3,8 @@ package me.cortex.voxy.client.core.model; public class IdNotYetComputedException extends RuntimeException { public final int id; public IdNotYetComputedException(int id) { - super("Id not yet computed: " + id); + //super("Id not yet computed: " + id); + super(null, null, false, false); this.id = id; } } diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical2/NodeCleaner.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical2/NodeCleaner.java index 28baf8fd..96c36fb9 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierachical2/NodeCleaner.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierachical2/NodeCleaner.java @@ -34,7 +34,7 @@ public class NodeCleaner { private final AutoBindingShader batchClear = Shader.makeAuto() .define("VISIBILITY_BUFFER_BINDING", 0) .define("LIST_BUFFER_BINDING", 1) - .add(ShaderType.COMPUTE, "voxy:lod/hierarchical/cleaner/batch_visibility_set.com") + .add(ShaderType.COMPUTE, "voxy:lod/hierarchical/cleaner/batch_visibility_set.comp") .compile(); private final GlBuffer visibilityBuffer; @@ -86,5 +86,6 @@ public class NodeCleaner { this.visibilityBuffer.free(); this.outputBuffer.free(); this.scratchBuffer.free(); + this.batchClear.free(); } } diff --git a/src/main/java/me/cortex/voxy/common/storage/StorageBackend.java b/src/main/java/me/cortex/voxy/common/storage/StorageBackend.java index d3ccc100..96776a74 100644 --- a/src/main/java/me/cortex/voxy/common/storage/StorageBackend.java +++ b/src/main/java/me/cortex/voxy/common/storage/StorageBackend.java @@ -11,7 +11,8 @@ import java.util.function.LongConsumer; public abstract class StorageBackend { public abstract void iterateStoredSectionPositions(LongConsumer consumer); - public abstract MemoryBuffer getSectionData(long key); + //Implementation may use the scratch buffer as the return value, it MUST NOT free the scratch buffer + public abstract MemoryBuffer getSectionData(long key, MemoryBuffer scratch); public abstract void setSectionData(long key, MemoryBuffer data); diff --git a/src/main/java/me/cortex/voxy/common/storage/compressors/ZSTDCompressor.java b/src/main/java/me/cortex/voxy/common/storage/compressors/ZSTDCompressor.java index b900dd68..3ba25cfc 100644 --- a/src/main/java/me/cortex/voxy/common/storage/compressors/ZSTDCompressor.java +++ b/src/main/java/me/cortex/voxy/common/storage/compressors/ZSTDCompressor.java @@ -4,6 +4,7 @@ import me.cortex.voxy.common.storage.StorageCompressor; import me.cortex.voxy.common.storage.config.CompressorConfig; import me.cortex.voxy.common.storage.config.ConfigBuildCtx; import me.cortex.voxy.common.util.MemoryBuffer; +import me.cortex.voxy.common.util.ThreadLocalMemoryBuffer; import me.cortex.voxy.common.world.SaveLoadSystem; import java.lang.ref.Cleaner; @@ -29,6 +30,8 @@ public class ZSTDCompressor implements StorageCompressor { private static final ThreadLocal COMPRESSION_CTX = ThreadLocal.withInitial(ZSTDCompressor::createCleanableCompressionContext); private static final ThreadLocal DECOMPRESSION_CTX = ThreadLocal.withInitial(ZSTDCompressor::createCleanableDecompressionContext); + private static final ThreadLocalMemoryBuffer SCRATCH = new ThreadLocalMemoryBuffer(SaveLoadSystem.BIGGEST_SERIALIZED_SECTION_SIZE + 1024); + private final int level; public ZSTDCompressor(int level) { @@ -37,15 +40,16 @@ public class ZSTDCompressor implements StorageCompressor { @Override public MemoryBuffer compress(MemoryBuffer saveData) { - MemoryBuffer compressedData = new MemoryBuffer((int)ZSTD_COMPRESSBOUND(saveData.size)); + MemoryBuffer compressedData = new MemoryBuffer((int)ZSTD_COMPRESSBOUND(saveData.size)); long compressedSize = nZSTD_compressCCtx(COMPRESSION_CTX.get().ptr, compressedData.address, compressedData.size, saveData.address, saveData.size, this.level); return compressedData.subSize(compressedSize); } @Override public MemoryBuffer decompress(MemoryBuffer saveData) { - var decompressed = new MemoryBuffer(SaveLoadSystem.BIGGEST_SERIALIZED_SECTION_SIZE); + var decompressed = SCRATCH.get().createUntrackedUnfreeableReference(); long size = nZSTD_decompressDCtx(DECOMPRESSION_CTX.get().ptr, decompressed.address, decompressed.size, saveData.address, saveData.size); + //TODO:FIXME: DONT ASSUME IT DOESNT FAIL return decompressed.subSize(size); } diff --git a/src/main/java/me/cortex/voxy/common/storage/inmemory/MemoryStorageBackend.java b/src/main/java/me/cortex/voxy/common/storage/inmemory/MemoryStorageBackend.java index f67ceb12..f6dbd73c 100644 --- a/src/main/java/me/cortex/voxy/common/storage/inmemory/MemoryStorageBackend.java +++ b/src/main/java/me/cortex/voxy/common/storage/inmemory/MemoryStorageBackend.java @@ -45,12 +45,13 @@ public class MemoryStorageBackend extends StorageBackend { } @Override - public MemoryBuffer getSectionData(long key) { + public MemoryBuffer getSectionData(long key, MemoryBuffer scratch) { var map = this.getMap(key); synchronized (map) { var data = map.get(key); if (data != null) { - return data.copy(); + data.cpyTo(scratch.address); + return scratch.subSize(data.size); } else { return null; } diff --git a/src/main/java/me/cortex/voxy/common/storage/lmdb/LMDBStorageBackend.java b/src/main/java/me/cortex/voxy/common/storage/lmdb/LMDBStorageBackend.java index f8c2a164..69e0d97e 100644 --- a/src/main/java/me/cortex/voxy/common/storage/lmdb/LMDBStorageBackend.java +++ b/src/main/java/me/cortex/voxy/common/storage/lmdb/LMDBStorageBackend.java @@ -92,7 +92,8 @@ public class LMDBStorageBackend extends StorageBackend { } //TODO: make batch get and updates - public MemoryBuffer getSectionData(long key) { + @Override + public MemoryBuffer getSectionData(long key, MemoryBuffer scratch) { return this.synchronizedTransaction(() -> this.sectionDatabase.transaction(MDB_RDONLY, transaction->{ var buff = transaction.stack.malloc(8); buff.putLong(0, key); @@ -100,9 +101,8 @@ public class LMDBStorageBackend extends StorageBackend { if (bb == null) { return null; } - var copy = new MemoryBuffer(bb.remaining()); - UnsafeUtil.memcpy(MemoryUtil.memAddress(bb), copy.address, copy.size); - return copy; + UnsafeUtil.memcpy(MemoryUtil.memAddress(bb), scratch.address, bb.remaining()); + return scratch.subSize(bb.remaining()); })); } diff --git a/src/main/java/me/cortex/voxy/common/storage/other/CompressionStorageAdaptor.java b/src/main/java/me/cortex/voxy/common/storage/other/CompressionStorageAdaptor.java index 25c04add..f00a122b 100644 --- a/src/main/java/me/cortex/voxy/common/storage/other/CompressionStorageAdaptor.java +++ b/src/main/java/me/cortex/voxy/common/storage/other/CompressionStorageAdaptor.java @@ -20,15 +20,15 @@ public class CompressionStorageAdaptor extends DelegatingStorageAdaptor { this.compressor = compressor; } + + //TODO: figure out a nicer way w.r.t scratch buffer shit @Override - public MemoryBuffer getSectionData(long key) { - var data = this.delegate.getSectionData(key); + public MemoryBuffer getSectionData(long key, MemoryBuffer scratch) { + var data = this.delegate.getSectionData(key, scratch); if (data == null) { return null; } - var decompressed = this.compressor.decompress(data); - data.free(); - return decompressed; + return this.compressor.decompress(data); } @Override diff --git a/src/main/java/me/cortex/voxy/common/storage/other/DelegatingStorageAdaptor.java b/src/main/java/me/cortex/voxy/common/storage/other/DelegatingStorageAdaptor.java index 70103b3b..31542e2a 100644 --- a/src/main/java/me/cortex/voxy/common/storage/other/DelegatingStorageAdaptor.java +++ b/src/main/java/me/cortex/voxy/common/storage/other/DelegatingStorageAdaptor.java @@ -23,8 +23,8 @@ public class DelegatingStorageAdaptor extends StorageBackend { public void iterateStoredSectionPositions(LongConsumer consumer) {this.delegate.iterateStoredSectionPositions(consumer);} @Override - public MemoryBuffer getSectionData(long key) { - return this.delegate.getSectionData(key); + public MemoryBuffer getSectionData(long key, MemoryBuffer scratch) { + return this.delegate.getSectionData(key, scratch); } @Override diff --git a/src/main/java/me/cortex/voxy/common/storage/other/FragmentedStorageBackendAdaptor.java b/src/main/java/me/cortex/voxy/common/storage/other/FragmentedStorageBackendAdaptor.java index ceb6355b..8f3534df 100644 --- a/src/main/java/me/cortex/voxy/common/storage/other/FragmentedStorageBackendAdaptor.java +++ b/src/main/java/me/cortex/voxy/common/storage/other/FragmentedStorageBackendAdaptor.java @@ -41,8 +41,8 @@ public class FragmentedStorageBackendAdaptor extends StorageBackend { // multiple layers of spliced storage backends can be stacked @Override - public MemoryBuffer getSectionData(long key) { - return this.backends[this.getSegmentId(key)].getSectionData(key); + public MemoryBuffer getSectionData(long key, MemoryBuffer scratch) { + return this.backends[this.getSegmentId(key)].getSectionData(key, scratch); } @Override diff --git a/src/main/java/me/cortex/voxy/common/storage/other/ReadonlyCachingLayer.java b/src/main/java/me/cortex/voxy/common/storage/other/ReadonlyCachingLayer.java index f4ef1f85..ad69f98c 100644 --- a/src/main/java/me/cortex/voxy/common/storage/other/ReadonlyCachingLayer.java +++ b/src/main/java/me/cortex/voxy/common/storage/other/ReadonlyCachingLayer.java @@ -21,12 +21,12 @@ public class ReadonlyCachingLayer extends StorageBackend { } @Override - public MemoryBuffer getSectionData(long key) { - var result = this.cache.getSectionData(key); + public MemoryBuffer getSectionData(long key, MemoryBuffer scratch) { + var result = this.cache.getSectionData(key, scratch); if (result != null) { return result; } - result = this.onMiss.getSectionData(key); + result = this.onMiss.getSectionData(key, scratch); if (result != null) { this.cache.setSectionData(key, result); } diff --git a/src/main/java/me/cortex/voxy/common/storage/other/TranslocatingStorageAdaptor.java b/src/main/java/me/cortex/voxy/common/storage/other/TranslocatingStorageAdaptor.java index b79324ba..3b873bb8 100644 --- a/src/main/java/me/cortex/voxy/common/storage/other/TranslocatingStorageAdaptor.java +++ b/src/main/java/me/cortex/voxy/common/storage/other/TranslocatingStorageAdaptor.java @@ -48,28 +48,28 @@ public class TranslocatingStorageAdaptor extends DelegatingStorageAdaptor { } @Override - public MemoryBuffer getSectionData(long key) { + public MemoryBuffer getSectionData(long key, MemoryBuffer scratch) { for (var transform : this.transforms) { long tpos = transform.transformIfInBox(key); if (tpos != -1) { if (transform.mode == Mode.BOX_ONLY || transform.mode == null) { - return super.getSectionData(tpos); + return super.getSectionData(tpos, scratch); } else if (transform.mode == Mode.PRIORITY_BOX) { - var data = super.getSectionData(tpos); + var data = super.getSectionData(tpos, scratch); if (data == null) { - return super.getSectionData(key); + return super.getSectionData(key, scratch); } } else if (transform.mode == Mode.PRIORITY_ORIGINAL) { - var data = super.getSectionData(key); + var data = super.getSectionData(key, scratch); if (data == null) { - return super.getSectionData(tpos); + return super.getSectionData(tpos, scratch); } } else { throw new IllegalStateException(); } } } - return super.getSectionData(key); + return super.getSectionData(key, scratch); } @Override diff --git a/src/main/java/me/cortex/voxy/common/storage/redis/RedisStorageBackend.java b/src/main/java/me/cortex/voxy/common/storage/redis/RedisStorageBackend.java index 474751b5..eb98cee0 100644 --- a/src/main/java/me/cortex/voxy/common/storage/redis/RedisStorageBackend.java +++ b/src/main/java/me/cortex/voxy/common/storage/redis/RedisStorageBackend.java @@ -37,7 +37,7 @@ public class RedisStorageBackend extends StorageBackend { } @Override - public MemoryBuffer getSectionData(long key) { + public MemoryBuffer getSectionData(long key, MemoryBuffer scratch) { try (var jedis = this.pool.getResource()) { if (this.user != null) { jedis.auth(this.user, this.password); @@ -48,9 +48,8 @@ public class RedisStorageBackend extends StorageBackend { return null; } //Need to copy to native memory - var buffer = new MemoryBuffer(result.length); - UnsafeUtil.memcpy(result, buffer.address); - return buffer; + UnsafeUtil.memcpy(result, scratch.address); + return scratch.subSize(result.length); } } diff --git a/src/main/java/me/cortex/voxy/common/storage/rocksdb/RocksDBStorageBackend.java b/src/main/java/me/cortex/voxy/common/storage/rocksdb/RocksDBStorageBackend.java index 6ef3cd61..d175bb52 100644 --- a/src/main/java/me/cortex/voxy/common/storage/rocksdb/RocksDBStorageBackend.java +++ b/src/main/java/me/cortex/voxy/common/storage/rocksdb/RocksDBStorageBackend.java @@ -6,6 +6,9 @@ import me.cortex.voxy.common.storage.config.ConfigBuildCtx; import me.cortex.voxy.common.storage.config.StorageConfig; import me.cortex.voxy.common.util.MemoryBuffer; import me.cortex.voxy.common.util.UnsafeUtil; +import me.cortex.voxy.common.world.SaveLoadSystem; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; import org.rocksdb.*; import java.nio.ByteBuffer; @@ -18,6 +21,7 @@ public class RocksDBStorageBackend extends StorageBackend { private final RocksDB db; private final ColumnFamilyHandle worldSections; private final ColumnFamilyHandle idMappings; + private final ReadOptions sectionReadOps; //NOTE: closes in order private final List closeList = new ArrayList<>(); @@ -65,10 +69,13 @@ public class RocksDBStorageBackend extends StorageBackend { path, cfDescriptors, handles); + this.sectionReadOps = new ReadOptions(); + this.closeList.addAll(handles); this.closeList.add(this.db); this.closeList.add(options); this.closeList.add(cfOpts); + this.closeList.add(this.sectionReadOps); this.worldSections = handles.get(1); this.idMappings = handles.get(2); @@ -85,21 +92,30 @@ public class RocksDBStorageBackend extends StorageBackend { } @Override - public MemoryBuffer getSectionData(long key) { - try { - var result = this.db.get(this.worldSections, longToBytes(key)); - if (result == null) { + public MemoryBuffer getSectionData(long key, MemoryBuffer scratch) { + try (var stack = MemoryStack.stackPush()){ + var buffer = stack.malloc(8); + //HATE JAVA HATE JAVA HATE JAVA, Long.reverseBytes() + //THIS WILL ONLY WORK ON LITTLE ENDIAN SYSTEM AAAAAAAAA ;-; + + MemoryUtil.memPutLong(MemoryUtil.memAddress(buffer), Long.reverseBytes(key)); + + var result = this.db.get(this.worldSections, + this.sectionReadOps, + buffer, + MemoryUtil.memByteBuffer(scratch.address, (int) (scratch.size))); + + if (result == RocksDB.NOT_FOUND) { return null; } - //Need to copy to native memory - var buffer = new MemoryBuffer(result.length); - UnsafeUtil.memcpy(result, buffer.address); - return buffer; + + return scratch.subSize(result); } catch (RocksDBException e) { throw new RuntimeException(e); } } + //TODO: FIXME, use the ByteBuffer variant @Override public void setSectionData(long key, MemoryBuffer data) { try { diff --git a/src/main/java/me/cortex/voxy/common/util/MemoryBuffer.java b/src/main/java/me/cortex/voxy/common/util/MemoryBuffer.java index df6113d1..4a236bcd 100644 --- a/src/main/java/me/cortex/voxy/common/util/MemoryBuffer.java +++ b/src/main/java/me/cortex/voxy/common/util/MemoryBuffer.java @@ -9,6 +9,7 @@ public class MemoryBuffer extends TrackedObject { public final long address; public final long size; private final boolean freeable; + private final boolean tracked; private static final AtomicInteger COUNT = new AtomicInteger(0); private static final AtomicLong TOTAL_SIZE = new AtomicLong(0); @@ -20,11 +21,14 @@ public class MemoryBuffer extends TrackedObject { private MemoryBuffer(boolean track, long address, long size, boolean freeable) { super(track); + this.tracked = track; this.size = size; this.address = address; this.freeable = freeable; - COUNT.incrementAndGet(); + if (track) { + COUNT.incrementAndGet(); + } if (freeable) { TOTAL_SIZE.addAndGet(size); } @@ -38,8 +42,9 @@ public class MemoryBuffer extends TrackedObject { @Override public void free() { super.free0(); - - COUNT.decrementAndGet(); + if (this.tracked) { + COUNT.decrementAndGet(); + } if (this.freeable) { MemoryUtil.nmemFree(this.address); TOTAL_SIZE.addAndGet(-this.size); @@ -56,18 +61,20 @@ public class MemoryBuffer extends TrackedObject { //Creates a new MemoryBuffer, defunking this buffer and sets the size to be a subsize of the current size public MemoryBuffer subSize(long size) { - if (size > this.size) { - throw new IllegalArgumentException("Requested size larger than current size"); + if (size > this.size || size <= 0) { + throw new IllegalArgumentException("Requested size larger than current size, or less than 0, requested: "+size+" capacity: " + this.size); } //Free the current object, but not the memory associated with it this.free0(); - COUNT.decrementAndGet(); + if (this.tracked) { + COUNT.decrementAndGet(); + } if (this.freeable) { TOTAL_SIZE.addAndGet(-this.size); } - return new MemoryBuffer(true, this.address, size, this.freeable); + return new MemoryBuffer(this.tracked, this.address, size, this.freeable); } @@ -89,4 +96,8 @@ public class MemoryBuffer extends TrackedObject { public static long getTotalSize() { return TOTAL_SIZE.get(); } + + public MemoryBuffer createUntrackedUnfreeableReference() { + return new MemoryBuffer(false, this.address, this.size, false); + } } diff --git a/src/main/java/me/cortex/voxy/common/util/ThreadLocalMemoryBuffer.java b/src/main/java/me/cortex/voxy/common/util/ThreadLocalMemoryBuffer.java new file mode 100644 index 00000000..1fc4f1c5 --- /dev/null +++ b/src/main/java/me/cortex/voxy/common/util/ThreadLocalMemoryBuffer.java @@ -0,0 +1,29 @@ +package me.cortex.voxy.common.util; + +import me.cortex.voxy.common.storage.compressors.ZSTDCompressor; + +import java.lang.ref.Cleaner; + +import static org.lwjgl.util.zstd.Zstd.ZSTD_createCCtx; +import static org.lwjgl.util.zstd.Zstd.ZSTD_freeCCtx; + +public class ThreadLocalMemoryBuffer { + private static final Cleaner CLEANER = Cleaner.create(); + private static MemoryBuffer createMemoryBuffer(long size) { + var buffer = new MemoryBuffer(size); + var ref = MemoryBuffer.createUntrackedUnfreeableRawFrom(buffer.address, buffer.size); + CLEANER.register(ref, buffer::free); + return ref; + } + + //TODO: make this much better + private final ThreadLocal threadLocal; + + public ThreadLocalMemoryBuffer(long size) { + this.threadLocal = ThreadLocal.withInitial(()->createMemoryBuffer(size)); + } + + public MemoryBuffer get() { + return this.threadLocal.get(); + } +} diff --git a/src/main/java/me/cortex/voxy/common/util/TrackedObject.java b/src/main/java/me/cortex/voxy/common/util/TrackedObject.java index 6c33c7a4..7b52e1b1 100644 --- a/src/main/java/me/cortex/voxy/common/util/TrackedObject.java +++ b/src/main/java/me/cortex/voxy/common/util/TrackedObject.java @@ -24,7 +24,9 @@ public abstract class TrackedObject { } this.ref.freedRef[0] = true; if (TRACK_OBJECT_ALLOCATIONS) { - this.ref.cleanable.clean(); + if (this.ref.cleanable != null) { + this.ref.cleanable.clean(); + } } } diff --git a/src/main/java/me/cortex/voxy/common/world/WorldEngine.java b/src/main/java/me/cortex/voxy/common/world/WorldEngine.java index 128d1f17..cbcb3395 100644 --- a/src/main/java/me/cortex/voxy/common/world/WorldEngine.java +++ b/src/main/java/me/cortex/voxy/common/world/WorldEngine.java @@ -1,15 +1,15 @@ package me.cortex.voxy.common.world; +import me.cortex.voxy.common.Logger; +import me.cortex.voxy.common.util.ThreadLocalMemoryBuffer; import me.cortex.voxy.common.voxelization.VoxelizedSection; import me.cortex.voxy.common.world.other.Mapper; import me.cortex.voxy.common.world.service.SectionSavingService; import me.cortex.voxy.common.world.service.VoxelIngestService; import me.cortex.voxy.common.storage.StorageBackend; import me.cortex.voxy.common.thread.ServiceThreadPool; -import me.cortex.voxy.commonImpl.VoxyCommon; import java.util.Arrays; -import java.util.function.Consumer; //Use an LMDB backend to store the world, use a local inmemory cache for lod sections // automatically manages and invalidates sections of the world as needed @@ -46,21 +46,19 @@ public class WorldEngine { this.ingestService = new VoxelIngestService(this, serviceThreadPool); } + + private static final ThreadLocalMemoryBuffer MEMORY_CACHE = new ThreadLocalMemoryBuffer(SaveLoadSystem.BIGGEST_SERIALIZED_SECTION_SIZE + 1024); private int unsafeLoadSection(WorldSection into) { - var data = this.storage.getSectionData(into.key); + var data = this.storage.getSectionData(into.key, MEMORY_CACHE.get().createUntrackedUnfreeableReference()); if (data != null) { - try { - if (!SaveLoadSystem.deserialize(into, data)) { - this.storage.deleteSectionData(into.key); - //TODO: regenerate the section from children - Arrays.fill(into.data, Mapper.AIR); - System.err.println("Section " + into.lvl + ", " + into.x + ", " + into.y + ", " + into.z + " was unable to load, removing"); - return -1; - } else { - return 0; - } - } finally { - data.free(); + if (!SaveLoadSystem.deserialize(into, data)) { + this.storage.deleteSectionData(into.key); + //TODO: regenerate the section from children + Arrays.fill(into.data, Mapper.AIR); + Logger.error("Section " + into.lvl + ", " + into.x + ", " + into.y + ", " + into.z + " was unable to load, removing"); + return -1; + } else { + return 0; } } else { //TODO: if we need to fetch an lod from a server, send the request here and block until the request is finished diff --git a/src/main/java/me/cortex/voxy/common/world/WorldSection.java b/src/main/java/me/cortex/voxy/common/world/WorldSection.java index 141bdec7..b17cd3bc 100644 --- a/src/main/java/me/cortex/voxy/common/world/WorldSection.java +++ b/src/main/java/me/cortex/voxy/common/world/WorldSection.java @@ -35,7 +35,7 @@ public final class WorldSection { //TODO: should make it dynamically adjust the size allowance based on memory pressure/WorldSection allocation rate (e.g. is it doing a world import) - private static final int ARRAY_REUSE_CACHE_SIZE = 300; + private static final int ARRAY_REUSE_CACHE_SIZE = 300;//500;//32*32*32*8*ARRAY_REUSE_CACHE_SIZE == number of bytes //TODO: maybe just swap this to a ConcurrentLinkedDeque private static final Deque ARRAY_REUSE_CACHE = new ArrayDeque<>(1024); diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/cleaner/batch_visibility_set.comp b/src/main/resources/assets/voxy/shaders/lod/hierarchical/cleaner/batch_visibility_set.comp index 7d5776f5..c0fb8599 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/cleaner/batch_visibility_set.comp +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/cleaner/batch_visibility_set.comp @@ -13,7 +13,7 @@ layout(binding = LIST_BUFFER_BINDING, std430) restrict readonly buffer SetListBu layout(location=0) uniform uint count; #define SET_TO uint(-1) void main() { - uint id = gl_InvocationID;//It might be this or gl_GlobalInvocationID.x + uint id = gl_GlobalInvocationID.x; if (count <= id) { return; }