Add option to choose if to use sodium build threads (default true)

This commit is contained in:
mcrcortex
2025-10-31 11:43:36 +10:00
parent 96bd651f5c
commit 141c2b1f98
10 changed files with 65 additions and 23 deletions

View File

@@ -2,6 +2,7 @@ package me.cortex.voxy.client;
import me.cortex.voxy.client.compat.FlashbackCompat; import me.cortex.voxy.client.compat.FlashbackCompat;
import me.cortex.voxy.client.config.VoxyConfig; import me.cortex.voxy.client.config.VoxyConfig;
import me.cortex.voxy.client.mixin.sodium.AccessorSodiumWorldRenderer;
import me.cortex.voxy.common.Logger; import me.cortex.voxy.common.Logger;
import me.cortex.voxy.common.config.ConfigBuildCtx; import me.cortex.voxy.common.config.ConfigBuildCtx;
import me.cortex.voxy.common.config.Serialization; import me.cortex.voxy.common.config.Serialization;
@@ -14,6 +15,7 @@ import me.cortex.voxy.common.config.storage.rocksdb.RocksDBStorageBackend;
import me.cortex.voxy.commonImpl.ImportManager; import me.cortex.voxy.commonImpl.ImportManager;
import me.cortex.voxy.commonImpl.VoxyInstance; import me.cortex.voxy.commonImpl.VoxyInstance;
import me.cortex.voxy.commonImpl.WorldIdentifier; import me.cortex.voxy.commonImpl.WorldIdentifier;
import net.caffeinemc.mods.sodium.client.render.SodiumWorldRenderer;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.world.level.storage.LevelResource; import net.minecraft.world.level.storage.LevelResource;
import java.nio.file.Files; import java.nio.file.Files;
@@ -27,7 +29,6 @@ public class VoxyClientInstance extends VoxyInstance {
private final boolean noIngestOverride; private final boolean noIngestOverride;
public VoxyClientInstance() { public VoxyClientInstance() {
super(); super();
this.setNumThreads(VoxyConfig.CONFIG.serviceThreads);
var path = FlashbackCompat.getReplayStoragePath(); var path = FlashbackCompat.getReplayStoragePath();
this.noIngestOverride = path != null; this.noIngestOverride = path != null;
if (path == null) { if (path == null) {
@@ -35,6 +36,23 @@ public class VoxyClientInstance extends VoxyInstance {
} }
this.basePath = path; this.basePath = path;
this.storageConfig = getCreateStorageConfig(path); this.storageConfig = getCreateStorageConfig(path);
this.updateDedicatedThreads();
}
@Override
public void updateDedicatedThreads() {
int target = VoxyConfig.CONFIG.serviceThreads;
if (!VoxyConfig.CONFIG.dontUseSodiumBuilderThreads) {
var swr = SodiumWorldRenderer.instanceNullable();
if (swr != null) {
var rsm = ((AccessorSodiumWorldRenderer) swr).getRenderSectionManager();
if (rsm != null) {
this.setNumThreads(Math.max(1, target - rsm.getBuilder().getTotalThreadCount()));
return;
}
}
}
this.setNumThreads(target);
} }
@Override @Override

View File

@@ -33,6 +33,7 @@ public class VoxyConfig implements OptionStorage<VoxyConfig> {
public boolean renderVanillaFog = false; public boolean renderVanillaFog = false;
public boolean useEnvironmentalFog = false; public boolean useEnvironmentalFog = false;
public boolean renderStatistics = false; public boolean renderStatistics = false;
public boolean dontUseSodiumBuilderThreads = false;
private static VoxyConfig loadOrCreate() { private static VoxyConfig loadOrCreate() {
if (VoxyCommon.isAvailable()) { if (VoxyCommon.isAvailable()) {

View File

@@ -66,21 +66,25 @@ public abstract class VoxyConfigScreenPages {
s.serviceThreads = v; s.serviceThreads = v;
var instance = VoxyCommon.getInstance(); var instance = VoxyCommon.getInstance();
if (instance != null) { if (instance != null) {
var swr = SodiumWorldRenderer.instanceNullable(); instance.updateDedicatedThreads();
if (swr != null) {
var rsm = ((AccessorSodiumWorldRenderer)swr).getRenderSectionManager();
if (rsm!=null) {
instance.setNumThreads(Math.max(1, v-rsm.getBuilder().getTotalThreadCount()));
} else {
instance.setNumThreads(v);
}
} else {
instance.setNumThreads(v);
}
} }
}, s -> s.serviceThreads) }, s -> s.serviceThreads)
.setImpact(OptionImpact.HIGH) .setImpact(OptionImpact.HIGH)
.build() .build()
).add(OptionImpl.createBuilder(boolean.class, storage)
.setName(Component.translatable("voxy.config.general.useSodiumBuilder"))
.setTooltip(Component.translatable("voxy.config.general.useSodiumBuilder.tooltip"))
.setControl(TickBoxControl::new)
.setImpact(OptionImpact.VARIES)
.setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD)
.setBinding((s,v)->{
s.dontUseSodiumBuilderThreads = !v;
var instance = VoxyCommon.getInstance();
if (instance != null) {
instance.updateDedicatedThreads();
}
}, s->!s.dontUseSodiumBuilderThreads)
.build()
).add(OptionImpl.createBuilder(boolean.class, storage) ).add(OptionImpl.createBuilder(boolean.class, storage)
.setName(Component.translatable("voxy.config.general.ingest")) .setName(Component.translatable("voxy.config.general.ingest"))
.setTooltip(Component.translatable("voxy.config.general.ingest.tooltip")) .setTooltip(Component.translatable("voxy.config.general.ingest.tooltip"))

View File

@@ -87,5 +87,6 @@ public abstract class MixinLevelRenderer implements IGetVoxyRenderSystem {
throw e; throw e;
} }
} }
instance.updateDedicatedThreads();
} }
} }

View File

@@ -1,6 +1,7 @@
package me.cortex.voxy.client.mixin.sodium; package me.cortex.voxy.client.mixin.sodium;
import me.cortex.voxy.client.compat.SemaphoreBlockImpersonator; import me.cortex.voxy.client.compat.SemaphoreBlockImpersonator;
import me.cortex.voxy.client.config.VoxyConfig;
import me.cortex.voxy.common.thread.MultiThreadPrioritySemaphore; import me.cortex.voxy.common.thread.MultiThreadPrioritySemaphore;
import me.cortex.voxy.commonImpl.VoxyCommon; import me.cortex.voxy.commonImpl.VoxyCommon;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@@ -19,7 +20,7 @@ public class MixinChunkJobQueue {
@Redirect(method = "<init>", at = @At(value = "NEW", target = "(I)Ljava/util/concurrent/Semaphore;")) @Redirect(method = "<init>", at = @At(value = "NEW", target = "(I)Ljava/util/concurrent/Semaphore;"))
private Semaphore voxy$injectUnifiedPool(int permits) { private Semaphore voxy$injectUnifiedPool(int permits) {
var instance = VoxyCommon.getInstance(); var instance = VoxyCommon.getInstance();
if (instance != null) { if (instance != null && !VoxyConfig.CONFIG.dontUseSodiumBuilderThreads) {
this.voxy$semaphoreBlock = instance.getThreadPool().groupSemaphore.createBlock(); this.voxy$semaphoreBlock = instance.getThreadPool().groupSemaphore.createBlock();
return new SemaphoreBlockImpersonator(this.voxy$semaphoreBlock); return new SemaphoreBlockImpersonator(this.voxy$semaphoreBlock);
} }

View File

@@ -46,14 +46,6 @@ public class MixinRenderSectionManager {
} }
} }
this.bottomSectionY = this.level.getMinY()>>4; this.bottomSectionY = this.level.getMinY()>>4;
{
//TODO: put in a better position
var instance = VoxyCommon.getInstance();
if (instance != null) {
instance.setNumThreads(Math.max(1, VoxyConfig.CONFIG.serviceThreads - this.builder.getTotalThreadCount()));
}
}
} }
@Inject(method = "onChunkRemoved", at = @At("HEAD")) @Inject(method = "onChunkRemoved", at = @At("HEAD"))

View File

@@ -0,0 +1,17 @@
package me.cortex.voxy.client.mixin.sodium;
import me.cortex.voxy.commonImpl.VoxyCommon;
import me.cortex.voxy.commonImpl.VoxyInstance;
import net.caffeinemc.mods.sodium.client.render.SodiumWorldRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@Mixin(SodiumWorldRenderer.class)
public class MixinSodiumWorldRenderer {
@Inject(method = "initRenderer", at = @At("TAIL"))
private void voxy$injectThreadUpdate() {
var vi = VoxyCommon.getInstance();
if (vi != null) vi.updateDedicatedThreads();
}
}

View File

@@ -57,13 +57,17 @@ public abstract class VoxyInstance {
this.worldCleaner.start(); this.worldCleaner.start();
} }
public void setNumThreads(int threads) { protected void setNumThreads(int threads) {
if (threads<0) throw new IllegalArgumentException("Num threads <0"); if (threads<0) throw new IllegalArgumentException("Num threads <0");
if (this.threadPool.setNumThreads(threads)) { if (this.threadPool.setNumThreads(threads)) {
Logger.info("Dedicated voxy thread pool size: " + threads); Logger.info("Dedicated voxy thread pool size: " + threads);
} }
} }
public void updateDedicatedThreads() {
this.setNumThreads(3);
}
protected ImportManager createImportManager() { protected ImportManager createImportManager() {
return new ImportManager(); return new ImportManager();
} }

View File

@@ -7,6 +7,9 @@
"voxy.config.general.serviceThreads": "Service threads", "voxy.config.general.serviceThreads": "Service threads",
"voxy.config.general.serviceThreads.tooltip": "Number of threads the ServiceThreadPool can use", "voxy.config.general.serviceThreads.tooltip": "Number of threads the ServiceThreadPool can use",
"voxy.config.general.useSodiumBuilder": "Use sodium threads",
"voxy.config.general.useSodiumBuilder.tooltip": "Uses sodium builder threads as part of voxys thread pool, can reduce stuttering and lag when moving quickly at high render distance",
"voxy.config.general.ingest": "Chunk Ingest", "voxy.config.general.ingest": "Chunk Ingest",
"voxy.config.general.ingest.tooltip": "Enables or disables voxies ability to convert new chunks into LoDs", "voxy.config.general.ingest.tooltip": "Enables or disables voxies ability to convert new chunks into LoDs",

View File

@@ -33,7 +33,8 @@
"sodium.MixinChunkJobQueue", "sodium.MixinChunkJobQueue",
"sodium.MixinDefaultChunkRenderer", "sodium.MixinDefaultChunkRenderer",
"sodium.MixinRenderSectionManager", "sodium.MixinRenderSectionManager",
"sodium.MixinSodiumOptionsGUI" "sodium.MixinSodiumOptionsGUI",
"sodium.MixinSodiumWorldRenderer"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1