From 0ff2db188191a58fb6c9980800c7f87b33981721 Mon Sep 17 00:00:00 2001 From: mcrcortex <{ID}+{username}@users.noreply.github.com> Date: Mon, 15 Jul 2024 20:40:13 +1000 Subject: [PATCH] Working even better --- .../me/cortex/voxy/client/core/VoxelCore.java | 4 ++ .../rendering/Gl46HierarchicalRenderer.java | 51 +++++++++++++++++-- .../building/RenderGenerationService.java | 6 +-- .../rendering/hierarchical/MeshManager.java | 3 +- .../rendering/hierarchical/NodeManager.java | 2 + .../core/rendering/util/DownloadStream.java | 20 ++++++++ .../shaders/lod/hierarchical/traversal.comp | 3 +- 7 files changed, 80 insertions(+), 9 deletions(-) diff --git a/src/main/java/me/cortex/voxy/client/core/VoxelCore.java b/src/main/java/me/cortex/voxy/client/core/VoxelCore.java index 0a00d78c..b3460ad5 100644 --- a/src/main/java/me/cortex/voxy/client/core/VoxelCore.java +++ b/src/main/java/me/cortex/voxy/client/core/VoxelCore.java @@ -7,6 +7,7 @@ import me.cortex.voxy.client.core.model.ModelManager; import me.cortex.voxy.client.core.rendering.*; import me.cortex.voxy.client.core.rendering.building.RenderGenerationService; import me.cortex.voxy.client.core.rendering.post.PostProcessing; +import me.cortex.voxy.client.core.rendering.util.DownloadStream; import me.cortex.voxy.client.core.util.IrisUtil; import me.cortex.voxy.client.saver.ContextSelectionSystem; import me.cortex.voxy.common.world.WorldEngine; @@ -212,6 +213,9 @@ public class VoxelCore { // since they are AABBS crossing the normal is impossible without one of the axis being equal public void shutdown() { + System.out.println("Flushing download stream"); + DownloadStream.INSTANCE.flushWaitClear(); + //if (Thread.currentThread() != this.shutdownThread) { // Runtime.getRuntime().removeShutdownHook(this.shutdownThread); //} diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/Gl46HierarchicalRenderer.java b/src/main/java/me/cortex/voxy/client/core/rendering/Gl46HierarchicalRenderer.java index ef5b9c4c..e834036a 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/Gl46HierarchicalRenderer.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/Gl46HierarchicalRenderer.java @@ -14,17 +14,21 @@ import me.cortex.voxy.client.core.rendering.hierarchical.INodeInteractor; import me.cortex.voxy.client.core.rendering.hierarchical.MeshManager; import me.cortex.voxy.client.core.rendering.util.UploadStream; import me.cortex.voxy.client.mixin.joml.AccessFrustumIntersection; +import me.cortex.voxy.common.world.WorldEngine; import me.cortex.voxy.common.world.WorldSection; import me.cortex.voxy.common.world.other.Mapper; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.Camera; import net.minecraft.client.render.Frustum; import net.minecraft.client.render.RenderLayer; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.util.Identifier; import org.joml.Matrix4f; import org.joml.Vector3f; import org.lwjgl.system.MemoryUtil; import java.util.List; +import java.util.concurrent.ConcurrentLinkedDeque; import java.util.function.Consumer; import static org.lwjgl.opengl.ARBDirectStateAccess.glTextureParameteri; @@ -52,6 +56,12 @@ public class Gl46HierarchicalRenderer implements IRenderInterface blockStateUpdates = new ConcurrentLinkedDeque<>(); + private final ConcurrentLinkedDeque biomeUpdates = new ConcurrentLinkedDeque<>(); + + protected final ConcurrentLinkedDeque buildResults = new ConcurrentLinkedDeque<>(); + private final ModelManager modelManager; private RenderGenerationService sectionGenerationService; private Consumer resultConsumer; @@ -72,7 +82,12 @@ public class Gl46HierarchicalRenderer implements IRenderInterface 0)) { + var update = this.blockStateUpdates.pop(); + this.modelManager.addEntry(update.id, update.state); + } + } } @Override public void renderFarAwayOpaque(Gl46HierarchicalViewport viewport) { + //Process all the build results + while (!this.buildResults.isEmpty()) { + this.resultConsumer.accept(this.buildResults.pop()); + } + + //Render terrain from previous frame (renderSections) @@ -121,12 +164,12 @@ public class Gl46HierarchicalRenderer implements IRenderInterface sectionSupplier) {} + private record BuildTask(long position, Supplier sectionSupplier) {} private volatile boolean running = true; private final Thread[] workers; @@ -60,6 +59,7 @@ public class RenderGenerationService { } var section = task.sectionSupplier.get(); if (section == null) { + this.resultConsumer.accept(new BuiltSection(task.position)); continue; } section.assertNotFree(); @@ -130,7 +130,7 @@ public class RenderGenerationService { synchronized (this.taskQueue) { this.taskQueue.computeIfAbsent(ikey, key->{ this.taskCounter.release(); - return new BuildTask(()->{ + return new BuildTask(ikey, ()->{ if (checker.check(lvl, x, y, z)) { return this.world.acquireIfExists(lvl, x, y, z); } else { diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/MeshManager.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/MeshManager.java index 71ed7897..1ff4b025 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/MeshManager.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/MeshManager.java @@ -24,7 +24,8 @@ public class MeshManager { //Varient of uploadMesh that releases the previous mesh at the same time, this is a performance optimization public int uploadReplaceMesh(int old, BuiltSection section) { - return -1; + section.free(); + return 1; } public void removeMesh(int mesh) { diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/NodeManager.java b/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/NodeManager.java index 37c9fb3e..6d2aa958 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/NodeManager.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/hierarchical/NodeManager.java @@ -400,6 +400,8 @@ public class NodeManager { if ((msk&(1< Integer.MAX_VALUE) { throw new IllegalArgumentException(); } + if (size <= 0) { + throw new IllegalArgumentException(); + } + if (destOffset+size > buffer.size()) { + throw new IllegalArgumentException(); + } long addr; if (this.caddr == -1 || !this.allocationArena.expand(this.caddr, (int) size)) { @@ -125,6 +131,20 @@ public class DownloadStream { } } + //Synchonize force flushes everything + public void flushWaitClear() { + this.tick(); + var fence = new GlFence(); + glFinish(); + while (!fence.signaled()) + Thread.onSpinWait(); + fence.free(); + this.tick(); + if (!this.frames.isEmpty()) { + throw new IllegalStateException(); + } + } + private record DownloadFrame(GlFence fence, LongArrayList allocations, ArrayList data) {} private record DownloadData(GlBuffer target, long downloadStreamOffset, long targetOffset, long size, DownloadResultConsumer resultConsumer) {} diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal.comp b/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal.comp index bb1dd982..20509603 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal.comp +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/traversal.comp @@ -120,7 +120,8 @@ void main() { } else { //It is visible, TODO: maybe do a more detailed hiz test? (or make it so that ) - if (shouldDecend()) { + //Only decend if not a root node + if (node.lodLevel!=0 && shouldDecend()) { if (hasChildren(node)) { enqueueChildren(node); } else {