mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-06 04:16:36 +01:00
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
This commit is contained in:
parent
4c8e174712
commit
296aa7ca08
9 changed files with 71 additions and 23 deletions
|
@ -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() {
|
||||
|
|
|
@ -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<K> {
|
|||
@Nullable
|
||||
protected abstract GlProgram compile(K key);
|
||||
|
||||
public Map<K, GlProgram> compile() {
|
||||
@Nullable
|
||||
public Map<K, GlProgram> compileAndReportErrors() {
|
||||
stats.start();
|
||||
Map<K, GlProgram> out = new HashMap<>();
|
||||
for (var key : keys) {
|
||||
|
@ -38,6 +40,12 @@ public abstract class AbstractCompiler<K> {
|
|||
}
|
||||
}
|
||||
stats.finish();
|
||||
|
||||
if (stats.errored()) {
|
||||
Flywheel.LOGGER.error(stats.generateErrorLog());
|
||||
return null;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -25,11 +25,18 @@ public class IndirectPrograms {
|
|||
public static void reload(ShaderSources sources, ImmutableList<PipelineProgramKey> 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));
|
||||
}
|
||||
|
|
|
@ -23,9 +23,15 @@ public class InstancingPrograms {
|
|||
public static void reload(ShaderSources sources, ImmutableList<PipelineProgramKey> 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));
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
})));
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue