ready for async

This commit is contained in:
mcrcortex
2025-10-26 20:05:05 +10:00
parent 4863f607b8
commit 3df37b1102
2 changed files with 24 additions and 17 deletions

View File

@@ -54,11 +54,9 @@ public class ModelBakerySubsystem {
this.blockIdCount.addAndGet(-j); this.blockIdCount.addAndGet(-j);
} }
this.factory.tick();
this.factory.processAllThings(); this.factory.processAllThings();
this.factory.processUploads(); this.factory.tickAndProcessUploads();
//TimingStatistics.modelProcess.stop(); //TimingStatistics.modelProcess.stop();
} }

View File

@@ -42,6 +42,7 @@ import org.lwjgl.system.MemoryUtil;
import java.lang.invoke.VarHandle; import java.lang.invoke.VarHandle;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.locks.ReentrantLock;
import static me.cortex.voxy.client.core.model.ModelStore.MODEL_SIZE; import static me.cortex.voxy.client.core.model.ModelStore.MODEL_SIZE;
import static org.lwjgl.opengl.ARBDirectStateAccess.nglTextureSubImage2D; 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 //Contains the set of all block ids that are currently inflight/being baked
// this is required due to "async" nature of gpu feedback // this is required due to "async" nature of gpu feedback
private final IntOpenHashSet blockStatesInFlight = new IntOpenHashSet(); private final IntOpenHashSet blockStatesInFlight = new IntOpenHashSet();
private final ReentrantLock blockStatesInFlightLock = new ReentrantLock();
private final List<Biome> biomes = new ArrayList<>(); private final List<Biome> biomes = new ArrayList<>();
private final List<Pair<Integer, BlockState>> modelsRequiringBiomeColours = new ArrayList<>(); private final List<Pair<Integer, BlockState>> modelsRequiringBiomeColours = new ArrayList<>();
@@ -122,9 +124,9 @@ public class ModelFactory {
private final ModelStore storage; private final ModelStore storage;
private final RawDownloadStream downstream = new RawDownloadStream(8*1024*1024);//8mb downstream private final RawDownloadStream downstream = new RawDownloadStream(8*1024*1024);//8mb downstream
private final Deque<RawBakeResult> rawBakeResults = new ArrayDeque<>(); private final ConcurrentLinkedDeque<RawBakeResult> rawBakeResults = new ConcurrentLinkedDeque<>();
private final Deque<ResultUploader> uploadResults = new ArrayDeque<>(); private final ConcurrentLinkedDeque<ResultUploader> uploadResults = new ConcurrentLinkedDeque<>();
private Object2IntMap<BlockState> customBlockStateIdMapping; private Object2IntMap<BlockState> customBlockStateIdMapping;
@@ -145,11 +147,6 @@ public class ModelFactory {
this.addEntry(0);//Add air as the first entry this.addEntry(0);//Add air as the first entry
} }
public void tick() {
this.downstream.tick();
}
public void setCustomBlockStateMapping(Object2IntMap<BlockState> mapping) { public void setCustomBlockStateMapping(Object2IntMap<BlockState> mapping) {
this.customBlockStateIdMapping = mapping; this.customBlockStateIdMapping = mapping;
} }
@@ -172,10 +169,13 @@ public class ModelFactory {
//We are (probably) going to be baking the block id //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 // 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 // else add it to the flight as it is going to be baked
this.blockStatesInFlightLock.lock();
if (!this.blockStatesInFlight.add(blockId)) { if (!this.blockStatesInFlight.add(blockId)) {
this.blockStatesInFlightLock.unlock();
//Block baking is already in-flight //Block baking is already in-flight
return false; return false;
} }
this.blockStatesInFlightLock.unlock();
VarHandle.loadLoadFence(); VarHandle.loadLoadFence();
@@ -258,18 +258,21 @@ public class ModelFactory {
while (this.processModelResult()); while (this.processModelResult());
} }
public void processUploads() { public void tickAndProcessUploads() {
if (this.uploadResults.isEmpty()) return; this.downstream.tick();
var upload = this.uploadResults.poll();
if (upload==null) return;
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
while (!this.uploadResults.isEmpty()) { do {
var bakeResult = this.uploadResults.pop(); upload.upload(this.storage);
bakeResult.upload(this.storage); upload.free();
bakeResult.free(); upload = this.uploadResults.poll();
} } while (upload != null);
UploadStream.INSTANCE.commit(); UploadStream.INSTANCE.commit();
} }
@@ -327,9 +330,12 @@ public class ModelFactory {
throw new IllegalStateException("Block id already added: " + blockId + " for state: " + blockState); throw new IllegalStateException("Block id already added: " + blockId + " for state: " + blockState);
} }
this.blockStatesInFlightLock.lock();
if (!this.blockStatesInFlight.contains(blockId)) { if (!this.blockStatesInFlight.contains(blockId)) {
this.blockStatesInFlightLock.unlock();
throw new IllegalStateException("processing a texture bake result but the block state was not in flight!!"); 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()` //TODO: add thing for `blockState.hasEmissiveLighting()` and `blockState.getLuminance()`
@@ -614,9 +620,12 @@ public class ModelFactory {
//Set the mapping at the very end //Set the mapping at the very end
this.idMappings[blockId] = modelId; this.idMappings[blockId] = modelId;
this.blockStatesInFlightLock.lock();
if (!this.blockStatesInFlight.remove(blockId)) { if (!this.blockStatesInFlight.remove(blockId)) {
this.blockStatesInFlightLock.unlock();
throw new IllegalStateException("processing a texture bake result but the block state was not in flight!!"); throw new IllegalStateException("processing a texture bake result but the block state was not in flight!!");
} }
this.blockStatesInFlightLock.unlock();
return uploadResult; return uploadResult;
} }