diff --git a/src/main/java/com/jozufozu/flywheel/Flywheel.java b/src/main/java/com/jozufozu/flywheel/Flywheel.java index 95effd761..cecf6fae8 100644 --- a/src/main/java/com/jozufozu/flywheel/Flywheel.java +++ b/src/main/java/com/jozufozu/flywheel/Flywheel.java @@ -4,15 +4,26 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.maven.artifact.versioning.ArtifactVersion; +import com.jozufozu.flywheel.backend.Backend; +import com.jozufozu.flywheel.backend.OptifineHandler; import com.jozufozu.flywheel.config.EngineArgument; import com.jozufozu.flywheel.config.FlwCommands; import com.jozufozu.flywheel.config.FlwConfig; +import com.jozufozu.flywheel.core.Contexts; +import com.jozufozu.flywheel.core.PartialModel; +import com.jozufozu.flywheel.core.StitchedSprite; +import com.jozufozu.flywheel.core.compile.ProgramCompiler; +import com.jozufozu.flywheel.event.ReloadRenderersEvent; +import com.jozufozu.flywheel.mixin.PausedPartialTickAccessor; +import com.jozufozu.flywheel.vanilla.VanillaInstances; import net.minecraft.commands.synchronization.ArgumentTypes; import net.minecraft.commands.synchronization.EmptyArgumentSerializer; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.CrashReportCallables; import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.common.Mod; @@ -39,18 +50,44 @@ public class Flywheel { .getModEventBus() .addListener(this::setup); - MinecraftForge.EVENT_BUS.addListener(FlwCommands::onServerStarting); - FlwConfig.init(); - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> FlywheelClient::clientInit); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> Flywheel::clientInit); } public static ResourceLocation rl(String path) { return new ResourceLocation(ID, path); } - private void setup(final FMLCommonSetupEvent event) { + public static void clientInit() { + CrashReportCallables.registerCrashCallable("Flywheel Backend", Backend::getBackendDescriptor); + + OptifineHandler.init(); + Backend.init(); + IEventBus modEventBus = FMLJavaModLoadingContext.get() + .getModEventBus(); + + modEventBus.addListener(Contexts::flwInit); + modEventBus.addListener(PartialModel::onModelRegistry); + modEventBus.addListener(PartialModel::onModelBake); + modEventBus.addListener(StitchedSprite::onTextureStitchPre); + modEventBus.addListener(StitchedSprite::onTextureStitchPost); + + MinecraftForge.EVENT_BUS.addListener(FlwCommands::registerClientCommands); + + MinecraftForge.EVENT_BUS.addListener(ProgramCompiler::invalidateAll); + + VanillaInstances.init(); + + // https://github.com/Jozufozu/Flywheel/issues/69 + // Weird issue with accessor loading. + // Only thing I've seen that's close to a fix is to force the class to load before trying to use it. + // From the SpongePowered discord: + // https://discord.com/channels/142425412096491520/626802111455297538/675007581168599041 + LOGGER.info("Successfully loaded {}", PausedPartialTickAccessor.class.getName()); + } + + private void setup(final FMLCommonSetupEvent event) { ArgumentTypes.register(rl("engine").toString(), EngineArgument.class, new EmptyArgumentSerializer<>(EngineArgument::getInstance)); } } diff --git a/src/main/java/com/jozufozu/flywheel/FlywheelClient.java b/src/main/java/com/jozufozu/flywheel/FlywheelClient.java deleted file mode 100644 index 4b74ab5ce..000000000 --- a/src/main/java/com/jozufozu/flywheel/FlywheelClient.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.jozufozu.flywheel; - -import com.jozufozu.flywheel.backend.Backend; -import com.jozufozu.flywheel.backend.OptifineHandler; -import com.jozufozu.flywheel.core.Contexts; -import com.jozufozu.flywheel.core.PartialModel; -import com.jozufozu.flywheel.core.StitchedSprite; -import com.jozufozu.flywheel.core.compile.ProgramCompiler; -import com.jozufozu.flywheel.event.ReloadRenderersEvent; -import com.jozufozu.flywheel.mixin.PausedPartialTickAccessor; -import com.jozufozu.flywheel.vanilla.VanillaInstances; - -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.fml.CrashReportCallables; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; - -public class FlywheelClient { - - public static void clientInit() { - CrashReportCallables.registerCrashCallable("Flywheel Backend", Backend::getBackendDescriptor); - - OptifineHandler.init(); - Backend.init(); - IEventBus modEventBus = FMLJavaModLoadingContext.get() - .getModEventBus(); - - modEventBus.addListener(Contexts::flwInit); - modEventBus.addListener(PartialModel::onModelRegistry); - modEventBus.addListener(PartialModel::onModelBake); - modEventBus.addListener(StitchedSprite::onTextureStitchPre); - modEventBus.addListener(StitchedSprite::onTextureStitchPost); - - MinecraftForge.EVENT_BUS.addListener(ProgramCompiler::invalidateAll); - - VanillaInstances.init(); - - // https://github.com/Jozufozu/Flywheel/issues/69 - // Weird issue with accessor loading. - // Only thing I've seen that's close to a fix is to force the class to load before trying to use it. - // From the SpongePowered discord: - // https://discord.com/channels/142425412096491520/626802111455297538/675007581168599041 - Flywheel.LOGGER.info("Successfully loaded {}", PausedPartialTickAccessor.class.getName()); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/backend/Backend.java index 6988f3239..c6c58f13b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backend.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backend.java @@ -21,8 +21,6 @@ public class Backend { private static FlwEngine engine; - public static GlCompat compat; - private static final Loader loader = new Loader(); public static FlwEngine getEngine() { @@ -45,9 +43,7 @@ public class Backend { public static void refresh() { OptifineHandler.refresh(); - compat = new GlCompat(); - - engine = chooseEngine(compat); + engine = chooseEngine(); } public static boolean isOn() { @@ -79,7 +75,7 @@ public class Backend { RenderWork.enqueue(Minecraft.getInstance().levelRenderer::allChanged); } - private static FlwEngine chooseEngine(GlCompat compat) { + private static FlwEngine chooseEngine() { FlwEngine preferredChoice = FlwConfig.get() .getEngine(); @@ -87,7 +83,7 @@ public class Backend { boolean canUseEngine = switch (preferredChoice) { case OFF -> true; case BATCHING -> !usingShaders; - case INSTANCING -> !usingShaders && compat.instancedArraysSupported(); + case INSTANCING -> !usingShaders && GlCompat.getInstance().instancedArraysSupported(); }; return canUseEngine ? preferredChoice : FlwEngine.OFF; diff --git a/src/main/java/com/jozufozu/flywheel/backend/Loader.java b/src/main/java/com/jozufozu/flywheel/backend/Loader.java index 9f0f9b43c..7d08882d7 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Loader.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Loader.java @@ -42,7 +42,7 @@ public class Loader implements ResourceManagerReloadListener { public static final String PROGRAM_DIR = "flywheel/programs/"; private static final Gson GSON = new GsonBuilder().create(); - private final Map programSpecRegistry = new HashMap<>(); + private final Map programs = new HashMap<>(); private boolean firstLoad = true; @@ -59,7 +59,7 @@ public class Loader implements ResourceManagerReloadListener { @Nullable public ProgramSpec get(ResourceLocation name) { - return programSpecRegistry.get(name); + return programs.get(name); } @Override @@ -91,6 +91,8 @@ public class Loader implements ResourceManagerReloadListener { } private void loadProgramSpecs(ResourceManager manager) { + programs.clear(); + Collection programSpecs = manager.listResources(PROGRAM_DIR, s -> s.endsWith(".json")); for (ResourceLocation location : programSpecs) { @@ -109,21 +111,15 @@ public class Loader implements ResourceManagerReloadListener { spec.setName(specName); - register(spec); + if (programs.containsKey(specName)) { + throw new IllegalStateException("Program spec '" + specName + "' already registered."); + } + programs.put(specName, spec); + } catch (Exception e) { Backend.LOGGER.error(e); } } } - /** - * Register a shader program. - */ - private void register(ProgramSpec spec) { - ResourceLocation name = spec.name; - if (programSpecRegistry.containsKey(name)) { - throw new IllegalStateException("Program spec '" + name + "' already registered."); - } - programSpecRegistry.put(name, spec); - } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java index 346db8814..55d8d7037 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBuffer.java @@ -4,8 +4,8 @@ import java.nio.ByteBuffer; import org.lwjgl.opengl.GL20; -import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.gl.GlObject; +import com.jozufozu.flywheel.backend.gl.versioned.GlCompat; public abstract class GlBuffer extends GlObject { @@ -21,7 +21,8 @@ public abstract class GlBuffer extends GlObject { * @return A buffer that will be persistent if the driver supports it. */ public static GlBuffer requestPersistent(GlBufferType type) { - if (Backend.compat.bufferStorageSupported()) { + if (GlCompat.getInstance() + .bufferStorageSupported()) { return new PersistentGlBuffer(type); } else { return new MappedGlBuffer(type); diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/PersistentGlBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/PersistentGlBuffer.java index 6c4b474cd..ff81679c2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/PersistentGlBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/PersistentGlBuffer.java @@ -8,10 +8,10 @@ import java.nio.ByteBuffer; import org.lwjgl.opengl.GL30; -import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.gl.GlFence; import com.jozufozu.flywheel.backend.gl.error.GlError; import com.jozufozu.flywheel.backend.gl.error.GlException; +import com.jozufozu.flywheel.backend.gl.versioned.GlCompat; public class PersistentGlBuffer extends GlBuffer implements Mappable { @@ -46,7 +46,7 @@ public class PersistentGlBuffer extends GlBuffer implements Mappable { fence.clear(); - Backend.compat.bufferStorage.bufferStorage(type, size, flags); + GlCompat.getInstance().bufferStorage.bufferStorage(type, size, flags); ByteBuffer byteBuffer = GL30.glMapBufferRange(type.glEnum, 0, size, flags); diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlCompat.java b/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlCompat.java index 0d550124f..0aaffe754 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlCompat.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlCompat.java @@ -20,11 +20,20 @@ import net.minecraft.Util; */ public class GlCompat { + private static GlCompat instance; + + public static GlCompat getInstance() { + if (instance == null) { + instance = new GlCompat(); + } + return instance; + } + public final InstancedArrays instancedArrays; public final BufferStorage bufferStorage; public final boolean amd; - public GlCompat() { + private GlCompat() { GLCapabilities caps = GL.createCapabilities(); instancedArrays = getLatest(InstancedArrays.class, caps); bufferStorage = getLatest(BufferStorage.class, caps); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java index 9595069eb..02ec9ceac 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java @@ -1,8 +1,5 @@ package com.jozufozu.flywheel.backend.instancing; -import java.util.List; - -import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.backend.Backend; @@ -137,10 +134,4 @@ public class InstanceWorld { .forEach(entityInstanceManager::add); } - public void getDebugString(List debug) { - debug.add(""); - debug.add("Flywheel: " + Flywheel.VERSION); - debug.add("B: " + blockEntityInstanceManager.getObjectCount() + ", E: " + entityInstanceManager.getObjectCount()); - engine.addDebugInfo(debug); - } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java index f434a4871..e1a4eb904 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java @@ -2,6 +2,7 @@ package com.jozufozu.flywheel.backend.instancing; import java.util.List; +import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.event.BeginFrameEvent; import com.jozufozu.flywheel.event.ReloadRenderersEvent; @@ -116,7 +117,16 @@ public class InstancedRenderDispatcher { } public static void getDebugString(List debug) { - instanceWorlds.get(Minecraft.getInstance().level) - .getDebugString(debug); + debug.add(""); + debug.add("Flywheel: " + Flywheel.VERSION); + + if (Backend.isOn()) { + InstanceWorld instanceWorld = instanceWorlds.get(Minecraft.getInstance().level); + + debug.add("B: " + instanceWorld.blockEntityInstanceManager.getObjectCount() + ", E: " + instanceWorld.entityInstanceManager.getObjectCount()); + instanceWorld.engine.addDebugInfo(debug); + } else { + debug.add("Disabled"); + } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java index ffac02ae3..3f0ff7c87 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java @@ -6,11 +6,11 @@ import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.api.struct.StructWriter; -import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.gl.GlVertexArray; import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; +import com.jozufozu.flywheel.backend.gl.versioned.GlCompat; import com.jozufozu.flywheel.backend.instancing.AbstractInstancer; import com.jozufozu.flywheel.backend.model.BufferedModel; import com.jozufozu.flywheel.backend.model.ModelAllocator; @@ -198,7 +198,7 @@ public class GPUInstancer extends AbstractInstancer { vao.bindAttributes(attributeBaseIndex, instanceFormat); for (int i = 0; i < instanceFormat.getAttributeCount(); i++) { - Backend.compat.instancedArrays.vertexAttribDivisor(attributeBaseIndex + i, 1); + GlCompat.getInstance().instancedArrays.vertexAttribDivisor(attributeBaseIndex + i, 1); } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java index 6c640f716..73ea3e1c5 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancedMaterialGroup.java @@ -7,8 +7,8 @@ import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.MaterialGroup; import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.api.struct.StructType; -import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.RenderLayer; +import com.jozufozu.flywheel.backend.gl.versioned.GlCompat; import com.jozufozu.flywheel.backend.model.FallbackAllocator; import com.jozufozu.flywheel.backend.model.ModelAllocator; import com.jozufozu.flywheel.backend.model.ModelPool; @@ -40,7 +40,8 @@ public class InstancedMaterialGroup

implements MaterialG public InstancedMaterialGroup(InstancingEngine

owner, RenderType type) { this.owner = owner; this.type = type; - if (Backend.compat.onAMDWindows()) { + if (GlCompat.getInstance() + .onAMDWindows()) { this.allocator = FallbackAllocator.INSTANCE; } else { this.allocator = new ModelPool(Formats.POS_TEX_NORMAL, 2048); diff --git a/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java b/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java index 5562d535a..5d945cc26 100644 --- a/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java +++ b/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java @@ -9,7 +9,7 @@ import net.minecraft.commands.Commands; import net.minecraftforge.client.event.RegisterClientCommandsEvent; public class FlwCommands { - public static void onServerStarting(RegisterClientCommandsEvent event) { + public static void registerClientCommands(RegisterClientCommandsEvent event) { CommandDispatcher dispatcher = event.getDispatcher(); dispatcher.register(Commands.literal("flywheel")