mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 07:26:48 +01:00
Layoff some workers
- Only one task engine for everything now - Fixes crash on LightUpdater init when Flywheel is off - Attempt to wrangle InstanceWorld init code - Misc. cleanup/renaming
This commit is contained in:
parent
19d757d702
commit
9a69ed1906
11 changed files with 125 additions and 108 deletions
|
@ -1,7 +1,6 @@
|
|||
buildscript {
|
||||
repositories {
|
||||
maven { url = 'https://maven.minecraftforge.net' }
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
maven { url = 'https://repo.spongepowered.org/repository/maven-public' }
|
||||
maven { url = 'https://maven.parchmentmc.org' }
|
||||
|
@ -37,6 +36,7 @@ println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getPro
|
|||
minecraft {
|
||||
mappings channel: 'parchment', version: "${parchment_version}-${minecraft_version}"
|
||||
|
||||
|
||||
runs {
|
||||
client {
|
||||
workingDirectory project.file('run')
|
||||
|
|
|
@ -5,7 +5,7 @@ import org.slf4j.Logger;
|
|||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.OptifineHandler;
|
||||
import com.jozufozu.flywheel.config.EngineArgument;
|
||||
import com.jozufozu.flywheel.config.BackendTypeArgument;
|
||||
import com.jozufozu.flywheel.config.FlwCommands;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.core.Contexts;
|
||||
|
@ -88,7 +88,7 @@ public class Flywheel {
|
|||
}
|
||||
|
||||
private static void setup(final FMLCommonSetupEvent event) {
|
||||
ArgumentTypes.register(rl("engine").toString(), EngineArgument.class, new EmptyArgumentSerializer<>(EngineArgument::getInstance));
|
||||
ArgumentTypes.register(rl("engine").toString(), BackendTypeArgument.class, new EmptyArgumentSerializer<>(BackendTypeArgument::getInstance));
|
||||
}
|
||||
|
||||
public static ArtifactVersion getVersion() {
|
||||
|
|
|
@ -6,8 +6,9 @@ import org.slf4j.Logger;
|
|||
|
||||
import com.jozufozu.flywheel.api.FlywheelWorld;
|
||||
import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
|
||||
import com.jozufozu.flywheel.backend.instancing.ParallelTaskEngine;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.config.FlwEngine;
|
||||
import com.jozufozu.flywheel.config.BackendType;
|
||||
import com.jozufozu.flywheel.core.shader.ProgramSpec;
|
||||
import com.mojang.logging.LogUtils;
|
||||
|
||||
|
@ -19,12 +20,30 @@ import net.minecraft.world.level.LevelAccessor;
|
|||
public class Backend {
|
||||
public static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private static FlwEngine engine;
|
||||
private static BackendType backendType;
|
||||
|
||||
private static ParallelTaskEngine taskEngine;
|
||||
|
||||
private static final Loader loader = new Loader();
|
||||
|
||||
public static FlwEngine getEngine() {
|
||||
return engine;
|
||||
/**
|
||||
* Get the current Flywheel backend type.
|
||||
*/
|
||||
public static BackendType getBackendType() {
|
||||
return backendType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a thread pool for running Flywheel related work in parallel.
|
||||
* @return A global Flywheel thread pool.
|
||||
*/
|
||||
public static ParallelTaskEngine getTaskEngine() {
|
||||
if (taskEngine == null) {
|
||||
taskEngine = new ParallelTaskEngine("Flywheel");
|
||||
taskEngine.startWorkers();
|
||||
}
|
||||
|
||||
return taskEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,7 +51,7 @@ public class Backend {
|
|||
* (Meshlet, MDI, GL31 Draw Instanced are planned), this will name which one is in use.
|
||||
*/
|
||||
public static String getBackendDescriptor() {
|
||||
return engine == null ? "Uninitialized" : engine.getProperName();
|
||||
return backendType == null ? "Uninitialized" : backendType.getProperName();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -41,11 +60,11 @@ public class Backend {
|
|||
}
|
||||
|
||||
public static void refresh() {
|
||||
engine = chooseEngine();
|
||||
backendType = chooseEngine();
|
||||
}
|
||||
|
||||
public static boolean isOn() {
|
||||
return engine != FlwEngine.OFF;
|
||||
return backendType != BackendType.OFF;
|
||||
}
|
||||
|
||||
public static boolean canUseInstancing(@Nullable Level world) {
|
||||
|
@ -73,9 +92,9 @@ public class Backend {
|
|||
RenderWork.enqueue(Minecraft.getInstance().levelRenderer::allChanged);
|
||||
}
|
||||
|
||||
private static FlwEngine chooseEngine() {
|
||||
FlwEngine preferredChoice = FlwConfig.get()
|
||||
.getEngine();
|
||||
private static BackendType chooseEngine() {
|
||||
BackendType preferredChoice = FlwConfig.get()
|
||||
.getBackendType();
|
||||
|
||||
boolean usingShaders = OptifineHandler.isUsingShaders();
|
||||
boolean canUseEngine = switch (preferredChoice) {
|
||||
|
@ -84,7 +103,7 @@ public class Backend {
|
|||
case INSTANCING -> !usingShaders && GlCompat.getInstance().instancedArraysSupported();
|
||||
};
|
||||
|
||||
return canUseEngine ? preferredChoice : FlwEngine.OFF;
|
||||
return canUseEngine ? preferredChoice : BackendType.OFF;
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
|
|
|
@ -7,7 +7,6 @@ import com.jozufozu.flywheel.backend.instancing.batching.BatchingEngine;
|
|||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager;
|
||||
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
|
||||
import com.jozufozu.flywheel.config.FlwEngine;
|
||||
import com.jozufozu.flywheel.core.Contexts;
|
||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||
|
@ -17,7 +16,6 @@ import com.jozufozu.flywheel.util.ClientLevelExtension;
|
|||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
|
@ -34,33 +32,35 @@ public class InstanceWorld {
|
|||
|
||||
public final ParallelTaskEngine taskEngine;
|
||||
|
||||
public InstanceWorld(LevelAccessor levelAccessor) {
|
||||
Level world = (Level) levelAccessor;
|
||||
|
||||
this.taskEngine = new ParallelTaskEngine("Flywheel " + world.dimension().location());
|
||||
this.taskEngine.startWorkers();
|
||||
|
||||
FlwEngine engine = Backend.getEngine();
|
||||
|
||||
switch (engine) {
|
||||
public static InstanceWorld create(LevelAccessor level) {
|
||||
return switch (Backend.getBackendType()) {
|
||||
case INSTANCING -> {
|
||||
InstancingEngine<WorldProgram> manager = InstancingEngine.builder(Contexts.WORLD)
|
||||
.build();
|
||||
|
||||
entityInstanceManager = new EntityInstanceManager(manager);
|
||||
blockEntityInstanceManager = new BlockEntityInstanceManager(manager);
|
||||
var entityInstanceManager = new EntityInstanceManager(manager);
|
||||
var blockEntityInstanceManager = new BlockEntityInstanceManager(manager);
|
||||
|
||||
manager.addListener(entityInstanceManager);
|
||||
manager.addListener(blockEntityInstanceManager);
|
||||
this.engine = manager;
|
||||
yield new InstanceWorld(manager, entityInstanceManager, blockEntityInstanceManager);
|
||||
}
|
||||
case BATCHING -> {
|
||||
this.engine = new BatchingEngine();
|
||||
entityInstanceManager = new EntityInstanceManager(this.engine);
|
||||
blockEntityInstanceManager = new BlockEntityInstanceManager(this.engine);
|
||||
var manager = new BatchingEngine();
|
||||
var entityInstanceManager = new EntityInstanceManager(manager);
|
||||
var blockEntityInstanceManager = new BlockEntityInstanceManager(manager);
|
||||
|
||||
yield new InstanceWorld(manager, entityInstanceManager, blockEntityInstanceManager);
|
||||
}
|
||||
default -> throw new IllegalArgumentException("Unknown engine type");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public InstanceWorld(Engine engine, InstanceManager<Entity> entityInstanceManager, InstanceManager<BlockEntity> blockEntityInstanceManager) {
|
||||
this.engine = engine;
|
||||
this.entityInstanceManager = entityInstanceManager;
|
||||
this.blockEntityInstanceManager = blockEntityInstanceManager;
|
||||
this.taskEngine = Backend.getTaskEngine();
|
||||
}
|
||||
|
||||
public InstanceManager<Entity> getEntityInstanceManager() {
|
||||
|
@ -75,7 +75,6 @@ public class InstanceWorld {
|
|||
* Free all acquired resources and invalidate this instance world.
|
||||
*/
|
||||
public void delete() {
|
||||
taskEngine.stopWorkers();
|
||||
engine.delete();
|
||||
entityInstanceManager.detachLightListeners();
|
||||
blockEntityInstanceManager.detachLightListeners();
|
||||
|
|
|
@ -27,7 +27,7 @@ import net.minecraftforge.fml.common.Mod;
|
|||
@Mod.EventBusSubscriber(Dist.CLIENT)
|
||||
public class InstancedRenderDispatcher {
|
||||
|
||||
private static final WorldAttached<InstanceWorld> instanceWorlds = new WorldAttached<>(InstanceWorld::new);
|
||||
private static final WorldAttached<InstanceWorld> instanceWorlds = new WorldAttached<>(InstanceWorld::create);
|
||||
|
||||
/**
|
||||
* Call this when you want to manually run {@link AbstractInstance#update()}.
|
||||
|
@ -61,10 +61,6 @@ public class InstancedRenderDispatcher {
|
|||
return getInstanceWorld(world).getEntityInstanceManager();
|
||||
}
|
||||
|
||||
public static ParallelTaskEngine getTaskEngine(LevelAccessor world) {
|
||||
return getInstanceWorld(world).taskEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create the {@link InstanceWorld} for the given world.
|
||||
* @throws NullPointerException if the backend is off
|
||||
|
|
51
src/main/java/com/jozufozu/flywheel/config/BackendType.java
Normal file
51
src/main/java/com/jozufozu/flywheel/config/BackendType.java
Normal file
|
@ -0,0 +1,51 @@
|
|||
package com.jozufozu.flywheel.config;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public enum BackendType {
|
||||
OFF("Off"),
|
||||
|
||||
/**
|
||||
* Use a thread pool to buffer instances in parallel on the CPU.
|
||||
*/
|
||||
BATCHING("Parallel Batching"),
|
||||
|
||||
/**
|
||||
* Use GPU instancing to render everything.
|
||||
*/
|
||||
INSTANCING("GL33 Instanced Arrays"),
|
||||
;
|
||||
|
||||
private static final Map<String, BackendType> lookup;
|
||||
|
||||
static {
|
||||
lookup = new HashMap<>();
|
||||
for (BackendType value : values()) {
|
||||
lookup.put(value.name().toLowerCase(Locale.ROOT), value);
|
||||
}
|
||||
}
|
||||
|
||||
private final String properName;
|
||||
|
||||
BackendType(String properName) {
|
||||
this.properName = properName;
|
||||
}
|
||||
|
||||
public String getProperName() {
|
||||
return properName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static BackendType byName(String name) {
|
||||
return lookup.get(name);
|
||||
}
|
||||
|
||||
public static Collection<String> validNames() {
|
||||
return lookup.keySet();
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
|||
import net.minecraft.commands.SharedSuggestionProvider;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
|
||||
public enum EngineArgument implements ArgumentType<FlwEngine> {
|
||||
public enum BackendTypeArgument implements ArgumentType<BackendType> {
|
||||
INSTANCE;
|
||||
|
||||
private static final Dynamic2CommandExceptionType INVALID = new Dynamic2CommandExceptionType((found, constants) -> {
|
||||
|
@ -23,28 +23,28 @@ public enum EngineArgument implements ArgumentType<FlwEngine> {
|
|||
});
|
||||
|
||||
@Override
|
||||
public FlwEngine parse(StringReader reader) throws CommandSyntaxException {
|
||||
public BackendType parse(StringReader reader) throws CommandSyntaxException {
|
||||
String string = reader.readUnquotedString();
|
||||
|
||||
FlwEngine engine = FlwEngine.byName(string);
|
||||
BackendType engine = BackendType.byName(string);
|
||||
|
||||
if (engine == null) {
|
||||
throw INVALID.createWithContext(reader, string, FlwEngine.validNames());
|
||||
throw INVALID.createWithContext(reader, string, BackendType.validNames());
|
||||
}
|
||||
|
||||
return engine;
|
||||
}
|
||||
|
||||
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
|
||||
return SharedSuggestionProvider.suggest(FlwEngine.validNames(), builder);
|
||||
return SharedSuggestionProvider.suggest(BackendType.validNames(), builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getExamples() {
|
||||
return FlwEngine.validNames();
|
||||
return BackendType.validNames();
|
||||
}
|
||||
|
||||
public static EngineArgument getInstance() {
|
||||
public static BackendTypeArgument getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@ public class FlwCommands {
|
|||
|
||||
ConfigCommandBuilder commandBuilder = new ConfigCommandBuilder("flywheel");
|
||||
|
||||
commandBuilder.addValue(config.client.engine, "backend", (builder, value) ->
|
||||
commandBuilder.addValue(config.client.backend, "backend", (builder, value) ->
|
||||
builder
|
||||
.executes(context -> {
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
|
@ -36,11 +36,11 @@ public class FlwCommands {
|
|||
}
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})
|
||||
.then(Commands.argument("type", EngineArgument.INSTANCE)
|
||||
.then(Commands.argument("type", BackendTypeArgument.INSTANCE)
|
||||
.executes(context -> {
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
if (player != null) {
|
||||
FlwEngine type = context.getArgument("type", FlwEngine.class);
|
||||
BackendType type = context.getArgument("type", BackendType.class);
|
||||
value.set(type);
|
||||
|
||||
Component message = getEngineMessage(type);
|
||||
|
@ -51,7 +51,7 @@ public class FlwCommands {
|
|||
return Command.SINGLE_SUCCESS;
|
||||
})));
|
||||
|
||||
commandBuilder.addValue(config.client.debugNormals, "debugNormals", (builder, value) -> booleanValueCommand(builder, config, value,
|
||||
commandBuilder.addValue(config.client.debugNormals, "debugNormals", (builder, value) -> booleanValueCommand(builder, value,
|
||||
(source, bool) -> {
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
if (player == null) return;
|
||||
|
@ -68,7 +68,7 @@ public class FlwCommands {
|
|||
}
|
||||
));
|
||||
|
||||
commandBuilder.addValue(config.client.limitUpdates, "limitUpdates", (builder, value) -> booleanValueCommand(builder, config, value,
|
||||
commandBuilder.addValue(config.client.limitUpdates, "limitUpdates", (builder, value) -> booleanValueCommand(builder, value,
|
||||
(source, bool) -> {
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
if (player == null) return;
|
||||
|
@ -90,7 +90,7 @@ public class FlwCommands {
|
|||
commandBuilder.build(event.getDispatcher());
|
||||
}
|
||||
|
||||
public static void booleanValueCommand(LiteralArgumentBuilder<CommandSourceStack> builder, FlwConfig config, ConfigValue<Boolean> value, BiConsumer<CommandSourceStack, Boolean> displayAction, BiConsumer<CommandSourceStack, Boolean> setAction) {
|
||||
public static void booleanValueCommand(LiteralArgumentBuilder<CommandSourceStack> builder, ConfigValue<Boolean> value, BiConsumer<CommandSourceStack, Boolean> displayAction, BiConsumer<CommandSourceStack, Boolean> setAction) {
|
||||
builder
|
||||
.executes(context -> {
|
||||
displayAction.accept(context.getSource(), value.get());
|
||||
|
@ -114,7 +114,7 @@ public class FlwCommands {
|
|||
return b ? new TextComponent("enabled").withStyle(ChatFormatting.DARK_GREEN) : new TextComponent("disabled").withStyle(ChatFormatting.RED);
|
||||
}
|
||||
|
||||
public static Component getEngineMessage(@NotNull FlwEngine type) {
|
||||
public static Component getEngineMessage(@NotNull BackendType type) {
|
||||
return switch (type) {
|
||||
case OFF -> new TextComponent("Disabled Flywheel").withStyle(ChatFormatting.RED);
|
||||
case INSTANCING -> new TextComponent("Using Instancing Engine").withStyle(ChatFormatting.GREEN);
|
||||
|
|
|
@ -27,8 +27,8 @@ public class FlwConfig {
|
|||
return INSTANCE;
|
||||
}
|
||||
|
||||
public FlwEngine getEngine() {
|
||||
return client.engine.get();
|
||||
public BackendType getBackendType() {
|
||||
return client.backend.get();
|
||||
}
|
||||
|
||||
public boolean debugNormals() {
|
||||
|
@ -43,15 +43,15 @@ public class FlwConfig {
|
|||
}
|
||||
|
||||
public static class ClientConfig {
|
||||
public final EnumValue<FlwEngine> engine;
|
||||
public final EnumValue<BackendType> backend;
|
||||
public final BooleanValue debugNormals;
|
||||
public final BooleanValue limitUpdates;
|
||||
|
||||
public ClientConfig(ForgeConfigSpec.Builder builder) {
|
||||
engine = builder.comment("Enable or disable the entire engine")
|
||||
.defineEnum("backend", FlwEngine.INSTANCING);
|
||||
backend = builder.comment("Select the backend to use.")
|
||||
.defineEnum("backend", BackendType.INSTANCING);
|
||||
|
||||
debugNormals = builder.comment("Enable or disable a debug overlay that colors pixels by their normal")
|
||||
debugNormals = builder.comment("Enable or disable a debug overlay that colors pixels by their normal.")
|
||||
.define("debugNormals", false);
|
||||
|
||||
limitUpdates = builder.comment("Enable or disable instance update limiting with distance.")
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
package com.jozufozu.flywheel.config;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public enum FlwEngine {
|
||||
OFF("off", "Off"),
|
||||
BATCHING("batching", "Parallel Batching"),
|
||||
INSTANCING("instancing", "GL33 Instanced Arrays"),
|
||||
;
|
||||
|
||||
private static final Map<String, FlwEngine> lookup;
|
||||
|
||||
static {
|
||||
lookup = new HashMap<>();
|
||||
for (FlwEngine value : values()) {
|
||||
lookup.put(value.shortName, value);
|
||||
}
|
||||
}
|
||||
|
||||
private final String shortName;
|
||||
private final String properName;
|
||||
|
||||
FlwEngine(String shortName, String properName) {
|
||||
this.shortName = shortName;
|
||||
this.properName = properName;
|
||||
}
|
||||
|
||||
public String getShortName() {
|
||||
return shortName;
|
||||
}
|
||||
|
||||
public String getProperName() {
|
||||
return properName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static FlwEngine byName(String name) {
|
||||
return lookup.get(name);
|
||||
}
|
||||
|
||||
public static Collection<String> validNames() {
|
||||
return lookup.keySet();
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ import java.util.Set;
|
|||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.instancing.ParallelTaskEngine;
|
||||
import com.jozufozu.flywheel.util.WeakHashSet;
|
||||
import com.jozufozu.flywheel.util.WorldAttached;
|
||||
|
@ -37,7 +37,7 @@ public class LightUpdater {
|
|||
private final WeakContainmentMultiMap<LightListener> chunks = new WeakContainmentMultiMap<>();
|
||||
|
||||
public LightUpdater(LevelAccessor world) {
|
||||
taskEngine = InstancedRenderDispatcher.getTaskEngine(world);
|
||||
taskEngine = Backend.getTaskEngine();
|
||||
provider = new BasicProvider(world);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue