From 296aa7ca084cce85bd1768dbd30cce2bc5497e5e Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Tue, 18 Apr 2023 21:28:28 -0700 Subject: [PATCH] Post-post-pre-refactor-refactor actual refactor - Mark backends as unavailable if their shader compilation failed - Update command output to notify when a fallback occurs --- .../jozufozu/flywheel/backend/Backends.java | 6 +++-- .../backend/compile/AbstractCompiler.java | 10 +++++++- .../backend/compile/CompilerStats.java | 4 +--- .../backend/compile/IndirectPrograms.java | 17 +++++++++++--- .../backend/compile/InstancingPrograms.java | 12 +++++++++- .../flywheel/backend/compile/LinkResult.java | 9 +++++--- .../backend/compile/ShaderResult.java | 9 +++++--- .../jozufozu/flywheel/config/FlwCommands.java | 23 +++++++++++++++---- .../jozufozu/flywheel/glsl/ShaderSources.java | 4 ++-- 9 files changed, 71 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backends.java b/src/main/java/com/jozufozu/flywheel/backend/Backends.java index d2eae65f8..e6e4619f7 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backends.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backends.java @@ -2,6 +2,8 @@ package com.jozufozu.flywheel.backend; import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.backend.Backend; +import com.jozufozu.flywheel.backend.compile.IndirectPrograms; +import com.jozufozu.flywheel.backend.compile.InstancingPrograms; import com.jozufozu.flywheel.backend.engine.batching.BatchingEngine; import com.jozufozu.flywheel.backend.engine.indirect.IndirectEngine; import com.jozufozu.flywheel.backend.engine.instancing.InstancingEngine; @@ -31,7 +33,7 @@ public class Backends { .engineFactory(level -> new InstancingEngine(256, Contexts.WORLD)) .fallback(() -> Backends.BATCHING) .supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.getInstance() - .instancedArraysSupported()) + .instancedArraysSupported() && InstancingPrograms.allLoaded()) .register(Flywheel.rl("instancing")); /** @@ -42,7 +44,7 @@ public class Backends { .engineFactory(level -> new IndirectEngine(256)) .fallback(() -> Backends.INSTANCING) .supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.getInstance() - .supportsIndirect()) + .supportsIndirect() && IndirectPrograms.allLoaded()) .register(Flywheel.rl("indirect")); public static void init() { diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/AbstractCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/compile/AbstractCompiler.java index 20711942b..a37002d2d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/AbstractCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/AbstractCompiler.java @@ -6,6 +6,7 @@ import java.util.Map; import org.jetbrains.annotations.Nullable; import com.google.common.collect.ImmutableList; +import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.gl.shader.GlProgram; import com.jozufozu.flywheel.glsl.ShaderSources; @@ -28,7 +29,8 @@ public abstract class AbstractCompiler { @Nullable protected abstract GlProgram compile(K key); - public Map compile() { + @Nullable + public Map compileAndReportErrors() { stats.start(); Map out = new HashMap<>(); for (var key : keys) { @@ -38,6 +40,12 @@ public abstract class AbstractCompiler { } } stats.finish(); + + if (stats.errored()) { + Flywheel.LOGGER.error(stats.generateErrorLog()); + return null; + } + return out; } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/CompilerStats.java b/src/main/java/com/jozufozu/flywheel/backend/compile/CompilerStats.java index 0f73fad3f..3e8b3d752 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/CompilerStats.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/CompilerStats.java @@ -25,15 +25,13 @@ public class CompilerStats { var elapsed = StringUtil.formatTime(compileEnd - compileStart); Flywheel.LOGGER.info("Compiled " + shaderCount + " shaders (with " + shaderErrors.size() + " compile errors) " + "and " + programCount + " programs (with " + programErrors.size() + " link errors) in " + elapsed); - } - // TODO: use this to turn off backends public boolean errored() { return errored; } - private String generateLog() { + public String generateErrorLog() { return String.join("\n", programErrors) + '\n' + shaderErrors.stream() .map(FailedCompilation::getMessage) .collect(Collectors.joining("\n")); diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java b/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java index 5201be604..560e1b488 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java @@ -25,11 +25,18 @@ public class IndirectPrograms { public static void reload(ShaderSources sources, ImmutableList pipelineKeys, UniformComponent uniformComponent) { if (instance != null) { instance.delete(); + instance = null; } - var indirectCompiler = new PipelineCompiler(sources, pipelineKeys, Pipelines.INDIRECT, uniformComponent); + var pipelineCompiler = new PipelineCompiler(sources, pipelineKeys, Pipelines.INDIRECT, uniformComponent); var cullingCompiler = new CullingCompiler(sources, createCullingKeys(), uniformComponent); - instance = new IndirectPrograms(indirectCompiler.compile(), cullingCompiler.compile()); - indirectCompiler.delete(); + + var pipelineResult = pipelineCompiler.compileAndReportErrors(); + var cullingResult = cullingCompiler.compileAndReportErrors(); + + if (pipelineResult != null && cullingResult != null) { + instance = new IndirectPrograms(pipelineResult, cullingResult); + } + pipelineCompiler.delete(); cullingCompiler.delete(); } @@ -46,6 +53,10 @@ public class IndirectPrograms { return instance; } + public static boolean allLoaded() { + return instance != null; + } + public GlProgram getIndirectProgram(VertexType vertexType, InstanceType instanceType, Context contextShader) { return pipeline.get(new PipelineProgramKey(vertexType, instanceType, contextShader)); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java b/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java index e9fd36356..e13de2885 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java @@ -23,9 +23,15 @@ public class InstancingPrograms { public static void reload(ShaderSources sources, ImmutableList pipelineKeys, UniformComponent uniformComponent) { if (instance != null) { instance.delete(); + instance = null; } var instancingCompiler = new PipelineCompiler(sources, pipelineKeys, Pipelines.INSTANCED_ARRAYS, uniformComponent); - instance = new InstancingPrograms(instancingCompiler.compile()); + var result = instancingCompiler.compileAndReportErrors(); + + if (result != null) { + instance = new InstancingPrograms(result); + } + instancingCompiler.delete(); } @@ -34,6 +40,10 @@ public class InstancingPrograms { return instance; } + public static boolean allLoaded() { + return instance != null; + } + public GlProgram get(VertexType vertexType, InstanceType instanceType, Context contextShader) { return pipeline.get(new PipelineProgramKey(vertexType, instanceType, contextShader)); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/LinkResult.java b/src/main/java/com/jozufozu/flywheel/backend/compile/LinkResult.java index bc592db18..0c77d6b2c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/LinkResult.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/LinkResult.java @@ -1,5 +1,6 @@ package com.jozufozu.flywheel.backend.compile; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import com.jozufozu.flywheel.gl.shader.GlProgram; @@ -8,13 +9,15 @@ public sealed interface LinkResult { @Nullable default GlProgram unwrap() { - if (this instanceof Success s) { - return s.program(); - } return null; } record Success(GlProgram program, String log) implements LinkResult { + @Override + @NotNull + public GlProgram unwrap() { + return program; + } } record Failure(String failure) implements LinkResult { diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/ShaderResult.java b/src/main/java/com/jozufozu/flywheel/backend/compile/ShaderResult.java index 71f97829a..174fa8f9f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/ShaderResult.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/ShaderResult.java @@ -1,5 +1,6 @@ package com.jozufozu.flywheel.backend.compile; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import com.jozufozu.flywheel.gl.shader.GlShader; @@ -7,13 +8,15 @@ import com.jozufozu.flywheel.gl.shader.GlShader; public sealed interface ShaderResult { @Nullable default GlShader unwrap() { - if (this instanceof Success s) { - return s.shader(); - } return null; } record Success(GlShader shader, String infoLog) implements ShaderResult { + @Override + @NotNull + public GlShader unwrap() { + return shader; + } } record Failure(FailedCompilation failure) implements ShaderResult { diff --git a/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java b/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java index b642e7d5d..803308a41 100644 --- a/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java +++ b/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java @@ -3,6 +3,7 @@ package com.jozufozu.flywheel.config; import java.util.function.BiConsumer; import com.jozufozu.flywheel.api.backend.Backend; +import com.jozufozu.flywheel.api.backend.BackendManager; import com.jozufozu.flywheel.lib.uniform.FlwShaderUniforms; import com.mojang.brigadier.Command; import com.mojang.brigadier.arguments.IntegerArgumentType; @@ -60,13 +61,25 @@ public class FlwCommands { .executes(context -> { LocalPlayer player = Minecraft.getInstance().player; if (player != null) { - Backend backend = context.getArgument("id", Backend.class); - value.set(Backend.REGISTRY.getIdOrThrow(backend).toString()); - - Component message = backend.engineMessage(); - player.displayClientMessage(message, false); + Backend requestedBackend = context.getArgument("id", Backend.class); + var requestedId = Backend.REGISTRY.getIdOrThrow(requestedBackend) + .toString(); + value.set(requestedId); + // Reload renderers so we can report the backend that we fell back to. Minecraft.getInstance().levelRenderer.allChanged(); + + var actualBackend = BackendManager.getBackend(); + if (actualBackend == null) { + player.displayClientMessage(new TextComponent("Error switching backends, flywheel disabled"), false); + } else if (actualBackend != requestedBackend) { + player.displayClientMessage(new TextComponent("'" + requestedId + "' not available").withStyle(ChatFormatting.RED), false); + var component = actualBackend.engineMessage(); + player.displayClientMessage(component, false); + } else { + Component message = requestedBackend.engineMessage(); + player.displayClientMessage(message, false); + } } return Command.SINGLE_SUCCESS; }))); diff --git a/src/main/java/com/jozufozu/flywheel/glsl/ShaderSources.java b/src/main/java/com/jozufozu/flywheel/glsl/ShaderSources.java index 73f2e2a7c..b0577aadd 100644 --- a/src/main/java/com/jozufozu/flywheel/glsl/ShaderSources.java +++ b/src/main/java/com/jozufozu/flywheel/glsl/ShaderSources.java @@ -80,10 +80,10 @@ public class ShaderSources { if (findStack.contains(location)) { generateRecursiveImportException(location); } - findStack.add(location); + findStack.addLast(location); } private void popFindStack() { - findStack.pop(); + findStack.removeLast(); } }