From 3df37b11021a5e55e4584942e6c1dc537c34bcbd Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Sun, 26 Oct 2025 20:05:05 +1000 Subject: [PATCH] ready for async --- .../core/model/ModelBakerySubsystem.java | 4 +- .../voxy/client/core/model/ModelFactory.java | 37 ++++++++++++------- 2 files changed, 24 insertions(+), 17 deletions(-) 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 7178646c..b1cc5b1a 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 @@ -54,11 +54,9 @@ public class ModelBakerySubsystem { this.blockIdCount.addAndGet(-j); } - this.factory.tick(); - this.factory.processAllThings(); - this.factory.processUploads(); + this.factory.tickAndProcessUploads(); //TimingStatistics.modelProcess.stop(); } diff --git a/src/main/java/me/cortex/voxy/client/core/model/ModelFactory.java b/src/main/java/me/cortex/voxy/client/core/model/ModelFactory.java index 4b7f5859..60b382cb 100644 --- a/src/main/java/me/cortex/voxy/client/core/model/ModelFactory.java +++ b/src/main/java/me/cortex/voxy/client/core/model/ModelFactory.java @@ -42,6 +42,7 @@ import org.lwjgl.system.MemoryUtil; import java.lang.invoke.VarHandle; import java.util.*; import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.locks.ReentrantLock; import static me.cortex.voxy.client.core.model.ModelStore.MODEL_SIZE; import static org.lwjgl.opengl.ARBDirectStateAccess.nglTextureSubImage2D; @@ -112,6 +113,7 @@ public class ModelFactory { //Contains the set of all block ids that are currently inflight/being baked // this is required due to "async" nature of gpu feedback private final IntOpenHashSet blockStatesInFlight = new IntOpenHashSet(); + private final ReentrantLock blockStatesInFlightLock = new ReentrantLock(); private final List biomes = new ArrayList<>(); private final List> modelsRequiringBiomeColours = new ArrayList<>(); @@ -122,9 +124,9 @@ public class ModelFactory { private final ModelStore storage; private final RawDownloadStream downstream = new RawDownloadStream(8*1024*1024);//8mb downstream - private final Deque rawBakeResults = new ArrayDeque<>(); + private final ConcurrentLinkedDeque rawBakeResults = new ConcurrentLinkedDeque<>(); - private final Deque uploadResults = new ArrayDeque<>(); + private final ConcurrentLinkedDeque uploadResults = new ConcurrentLinkedDeque<>(); private Object2IntMap customBlockStateIdMapping; @@ -145,11 +147,6 @@ public class ModelFactory { this.addEntry(0);//Add air as the first entry } - - public void tick() { - this.downstream.tick(); - } - public void setCustomBlockStateMapping(Object2IntMap mapping) { this.customBlockStateIdMapping = mapping; } @@ -172,10 +169,13 @@ public class ModelFactory { //We are (probably) going to be baking the block id // check that it is currently not inflight, if it is, return as its already being baked // else add it to the flight as it is going to be baked + this.blockStatesInFlightLock.lock(); if (!this.blockStatesInFlight.add(blockId)) { + this.blockStatesInFlightLock.unlock(); //Block baking is already in-flight return false; } + this.blockStatesInFlightLock.unlock(); VarHandle.loadLoadFence(); @@ -258,18 +258,21 @@ public class ModelFactory { while (this.processModelResult()); } - public void processUploads() { - if (this.uploadResults.isEmpty()) return; + public void tickAndProcessUploads() { + this.downstream.tick(); + + var upload = this.uploadResults.poll(); + if (upload==null) return; glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - while (!this.uploadResults.isEmpty()) { - var bakeResult = this.uploadResults.pop(); - bakeResult.upload(this.storage); - bakeResult.free(); - } + do { + upload.upload(this.storage); + upload.free(); + upload = this.uploadResults.poll(); + } while (upload != null); UploadStream.INSTANCE.commit(); } @@ -327,9 +330,12 @@ public class ModelFactory { throw new IllegalStateException("Block id already added: " + blockId + " for state: " + blockState); } + this.blockStatesInFlightLock.lock(); if (!this.blockStatesInFlight.contains(blockId)) { + this.blockStatesInFlightLock.unlock(); throw new IllegalStateException("processing a texture bake result but the block state was not in flight!!"); } + this.blockStatesInFlightLock.unlock(); //TODO: add thing for `blockState.hasEmissiveLighting()` and `blockState.getLuminance()` @@ -614,9 +620,12 @@ public class ModelFactory { //Set the mapping at the very end this.idMappings[blockId] = modelId; + this.blockStatesInFlightLock.lock(); if (!this.blockStatesInFlight.remove(blockId)) { + this.blockStatesInFlightLock.unlock(); throw new IllegalStateException("processing a texture bake result but the block state was not in flight!!"); } + this.blockStatesInFlightLock.unlock(); return uploadResult; }