diff --git a/src/main/java/me/cortex/voxy/client/TimingStatistics.java b/src/main/java/me/cortex/voxy/client/TimingStatistics.java index 5143a004..bd66d84c 100644 --- a/src/main/java/me/cortex/voxy/client/TimingStatistics.java +++ b/src/main/java/me/cortex/voxy/client/TimingStatistics.java @@ -71,7 +71,6 @@ public class TimingStatistics { } public static TimeSampler all = new TimeSampler(); - public static TimeSampler setup = new TimeSampler(); public static TimeSampler main = new TimeSampler(); public static TimeSampler dynamic = new TimeSampler(); diff --git a/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java b/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java index f3609659..714e9b24 100644 --- a/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java +++ b/src/main/java/me/cortex/voxy/client/core/VoxyRenderSystem.java @@ -16,6 +16,7 @@ import me.cortex.voxy.client.core.rendering.post.PostProcessing; import me.cortex.voxy.client.core.rendering.util.DownloadStream; import me.cortex.voxy.client.core.rendering.util.PrintfDebugUtil; import me.cortex.voxy.client.core.rendering.util.SharedIndexBuffer; +import me.cortex.voxy.client.core.rendering.util.UploadStream; import me.cortex.voxy.client.core.util.IrisUtil; import me.cortex.voxy.common.Logger; import me.cortex.voxy.common.thread.ServiceThreadPool; @@ -107,17 +108,21 @@ public class VoxyRenderSystem { downstream.submit(); downstream.tick(); }*/ + } - TimingStatistics.all.start(); - TimingStatistics.setup.start(); - this.renderDistanceTracker.setCenterAndProcess(camera.getBlockPos().getX(), camera.getBlockPos().getZ()); + private void autoBalanceSubDivSize() { + //only increase quality while there are very few mesh queues, this stops, + // e.g. while flying and is rendering alot of low quality chunks + boolean canDecreaseSize = this.renderer.getMeshQueueCount() < 5000; + float CHANGE_PER_SECOND = 30; + //Auto fps targeting + if (MinecraftClient.getInstance().getCurrentFps() < 45) { + VoxyConfig.CONFIG.subDivisionSize = Math.min(VoxyConfig.CONFIG.subDivisionSize + CHANGE_PER_SECOND / Math.max(1f, MinecraftClient.getInstance().getCurrentFps()), 256); + } - //Done here as is allows less gl state resetup - this.renderer.tickModelService(); - - PrintfDebugUtil.tick(); - TimingStatistics.setup.stop(); - TimingStatistics.all.stop(); + if (55 < MinecraftClient.getInstance().getCurrentFps() && canDecreaseSize) { + VoxyConfig.CONFIG.subDivisionSize = Math.max(VoxyConfig.CONFIG.subDivisionSize - CHANGE_PER_SECOND / Math.max(1f, MinecraftClient.getInstance().getCurrentFps()), 30); + } } private static Matrix4f makeProjectionMatrix(float near, float far) { @@ -147,30 +152,17 @@ public class VoxyRenderSystem { if (IrisUtil.irisShadowActive()) { return; } - TimingStatistics.all.start(); - TimingStatistics.main.start(); - - if (false) { - //only increase quality while there are very few mesh queues, this stops, - // e.g. while flying and is rendering alot of low quality chunks - boolean canDecreaseSize = this.renderer.getMeshQueueCount() < 5000; - float CHANGE_PER_SECOND = 30; - //Auto fps targeting - if (MinecraftClient.getInstance().getCurrentFps() < 45) { - VoxyConfig.CONFIG.subDivisionSize = Math.min(VoxyConfig.CONFIG.subDivisionSize + CHANGE_PER_SECOND / Math.max(1f, MinecraftClient.getInstance().getCurrentFps()), 256); - } - - if (55 < MinecraftClient.getInstance().getCurrentFps() && canDecreaseSize) { - VoxyConfig.CONFIG.subDivisionSize = Math.max(VoxyConfig.CONFIG.subDivisionSize - CHANGE_PER_SECOND / Math.max(1f, MinecraftClient.getInstance().getCurrentFps()), 30); - } - } - //Do some very cheeky stuff for MiB if (false) { int sector = (((int)Math.floor(cameraX)>>4)+512)>>10; cameraX -= sector<<14;//10+4 cameraY += (16+(256-32-sector*30))*16; } + long startTime = System.nanoTime(); + TimingStatistics.all.start(); + TimingStatistics.main.start(); + + //this.autoBalanceSubDivSize(); var projection = computeProjectionMat(matrices.projection());//RenderSystem.getProjectionMatrix(); //var projection = new Matrix4f(matrices.projection()); @@ -196,13 +188,9 @@ public class VoxyRenderSystem { this.chunkBoundRenderer.render(viewport); - //TODO: use the raw depth buffer texture instead - //int boundDepthBuffer = glGetNamedFramebufferAttachmentParameteri(boundFB, GL_DEPTH_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); - - //TODO:FIXME!!! ?? this.postProcessing.setup(target.textureWidth, target.textureHeight, boundFB); - this.renderer.renderFarAwayOpaque(viewport, this.chunkBoundRenderer.getDepthBoundTexture()); + this.renderer.renderFarAwayOpaque(viewport, this.chunkBoundRenderer.getDepthBoundTexture(), startTime); //Compute the SSAO of the rendered terrain, TODO: fix it breaking depth or breaking _something_ am not sure what this.postProcessing.computeSSAO(viewport.MVP); @@ -212,6 +200,20 @@ public class VoxyRenderSystem { this.postProcessing.renderPost(projection, matrices.projection(), boundFB); + + PrintfDebugUtil.tick(); + + //As much dynamic runtime stuff here + { + //Tick upload stream (this is ok to do here as upload ticking is just memory management) + UploadStream.INSTANCE.tick(); + + this.renderDistanceTracker.setCenterAndProcess(cameraX, cameraZ); + + //Done here as is allows less gl state resetup + this.renderer.tickModelService(4_000_000-(System.nanoTime()-startTime)); + } + glBindFramebuffer(GlConst.GL_FRAMEBUFFER, oldFB); TimingStatistics.main.stop(); TimingStatistics.all.stop(); @@ -222,7 +224,7 @@ public class VoxyRenderSystem { this.renderer.addDebugData(debug); { TimingStatistics.update(); - debug.add("Voxy frame runtime (millis): " + TimingStatistics.setup.pVal() + ", " + TimingStatistics.dynamic.pVal() + ", " + TimingStatistics.main.pVal()+ ", " + TimingStatistics.all.pVal()); + debug.add("Voxy frame runtime (millis): " + TimingStatistics.dynamic.pVal() + ", " + TimingStatistics.main.pVal()+ ", " + TimingStatistics.all.pVal()); } PrintfDebugUtil.addToOut(debug); } @@ -273,7 +275,7 @@ public class VoxyRenderSystem { { //Bake everything while (!modelService.areQueuesEmpty()) { - modelService.tick(); + modelService.tick(5_000_000); glFinish(); } } @@ -314,7 +316,7 @@ public class VoxyRenderSystem { } int i = 0; while (true) { - modelService.tick(); + modelService.tick(5_000_000); if (i++%5000==0) System.out.println(completedCounter.get()); glFinish(); @@ -344,7 +346,7 @@ public class VoxyRenderSystem { while (true) { //if (i++%5000==0) // System.out.println(completedCounter.get()); - modelService.tick(); + modelService.tick(5_000_000); glFinish(); List a = new ArrayList<>(); generationService.addDebugData(a); diff --git a/src/main/java/me/cortex/voxy/client/core/model/ModelBakerySubsystem.java b/src/main/java/me/cortex/voxy/client/core/model/ModelBakerySubsystem.java index e5bd061e..cf03c65d 100644 --- a/src/main/java/me/cortex/voxy/client/core/model/ModelBakerySubsystem.java +++ b/src/main/java/me/cortex/voxy/client/core/model/ModelBakerySubsystem.java @@ -35,7 +35,7 @@ public class ModelBakerySubsystem { this.factory = new ModelFactory(mapper, this.storage); } - public void tick() { + public void tick(long totalBudget) { //Upload all biomes while (!this.biomeQueue.isEmpty()) { var biome = this.biomeQueue.poll(); @@ -65,12 +65,11 @@ public class ModelBakerySubsystem { this.factory.addEntry(est[j]); } }*/ - long totalBudget = 2_000_000; //TimingStatistics.modelProcess.start(); long start = System.nanoTime(); VarHandle.fullFence(); { - long budget = Math.min(totalBudget-200_000, totalBudget-(this.factory.resultJobs.size()*20_000L))-200_000; + long budget = Math.min(totalBudget-150_000, totalBudget-(this.factory.resultJobs.size()*10_000L))-150_000; if (budget > 50_000) { Integer i = this.blockIdQueue.poll(); if (i != null) { diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java b/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java index eb02f393..1c221833 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/RenderService.java @@ -103,11 +103,11 @@ public class RenderService, J extends Vi this.nodeManager.removeTopLevelNode(pos); } - public void tickModelService() { - this.modelService.tick(); + public void tickModelService(long budget) { + this.modelService.tick(budget); } - public void renderFarAwayOpaque(J viewport, GlTexture depthBoundTexture) { + public void renderFarAwayOpaque(J viewport, GlTexture depthBoundTexture, long frameStart) { //LightMapHelper.tickLightmap(); //Render previous geometry with the abstract renderer @@ -133,25 +133,15 @@ public class RenderService, J extends Vi { TimingStatistics.main.stop(); TimingStatistics.dynamic.start(); - long start = System.nanoTime(); - VarHandle.fullFence(); //Tick download stream + //TODO: make this so that can DownloadStream.INSTANCE.tick(); - //Tick upload stream (this is ok to do here as upload ticking is just memory management) - UploadStream.INSTANCE.tick(); - this.sectionUpdateQueue.consume(128); - VarHandle.fullFence(); - long updateBudget = Math.max(1_000_000-(System.nanoTime()-start), 0); - VarHandle.fullFence(); - - if (updateBudget > 50_000) { - //Cap the number of consumed sections per frame to 40 + 2% of the queue size, cap of 200 - //int geoUpdateCap = 20;//Math.max(100, Math.min((int)(0.15*this.geometryUpdateQueue.count()), 260)); - this.geometryUpdateQueue.consumeNano(updateBudget); + if (this.modelService.getProcessingCount() < 750) {//Very bad hack to try control things + this.geometryUpdateQueue.consumeNano(1_500_000 - (System.nanoTime() - frameStart)); } this.nodeCleaner.tick(this.traversal.getNodeBuffer());//Probably do this here?? diff --git a/src/main/java/me/cortex/voxy/common/util/MessageQueue.java b/src/main/java/me/cortex/voxy/common/util/MessageQueue.java index 6c906ca5..30729cf8 100644 --- a/src/main/java/me/cortex/voxy/common/util/MessageQueue.java +++ b/src/main/java/me/cortex/voxy/common/util/MessageQueue.java @@ -41,11 +41,11 @@ public class MessageQueue { } public int consumeNano(long budget) { + if (budget < 25_000) return 0; if (this.count.get() == 0) { return 0; } int i = 0; - VarHandle.fullFence(); long nano = System.nanoTime(); VarHandle.fullFence(); do {