From 80127664d215200f3177240446da87827bef4d94 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Wed, 17 Jan 2024 10:37:39 -0800 Subject: [PATCH] Fix crash after compilation error during in-world resource reload - Store *Programs inside engines to disallow replacement and use reference counting to delete programs at the appropriate time - Move CompilationHarness, Compile, and SourceLoader to compile.core - Fix packed material comments - Fix pack.mcmeta pack format - Remove Embeddium version range --- build.gradle | 3 +- gradle.properties | 1 - .../jozufozu/flywheel/backend/Backends.java | 4 +- .../backend/compile/AbstractPrograms.java | 31 ++++++++ .../flywheel/backend/compile/FlwPrograms.java | 6 +- .../backend/compile/IndirectPrograms.java | 75 +++++++++++-------- .../backend/compile/InstancingPrograms.java | 48 +++++++----- .../backend/compile/LayoutInterpreter.java | 27 ++++--- .../backend/compile/PipelineCompiler.java | 2 + .../component/UberShaderComponent.java | 2 +- .../compile/component/UniformComponent.java | 2 +- .../{ => core}/CompilationHarness.java | 5 +- .../backend/compile/{ => core}/Compile.java | 5 +- .../compile/{ => core}/SourceLoader.java | 4 +- .../backend/engine/CommonCrumbling.java | 3 +- .../backend/engine/MaterialEncoder.java | 4 +- .../engine/indirect/IndirectCullingGroup.java | 31 ++++---- .../engine/indirect/IndirectDrawManager.java | 11 ++- .../engine/indirect/IndirectEngine.java | 20 +++-- .../engine/indirect/StagingBuffer.java | 28 ++++--- .../engine/instancing/InstancedCrumbling.java | 7 +- .../engine/instancing/InstancingEngine.java | 22 +++--- src/main/resources/META-INF/mods.toml | 4 +- .../flywheel/internal/packed_material.glsl | 2 +- src/main/resources/pack.mcmeta | 2 +- 25 files changed, 210 insertions(+), 139 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/backend/compile/AbstractPrograms.java rename src/main/java/com/jozufozu/flywheel/backend/compile/{ => core}/CompilationHarness.java (86%) rename src/main/java/com/jozufozu/flywheel/backend/compile/{ => core}/Compile.java (95%) rename src/main/java/com/jozufozu/flywheel/backend/compile/{ => core}/SourceLoader.java (83%) diff --git a/build.gradle b/build.gradle index 20b7af936..65b7f7cfe 100644 --- a/build.gradle +++ b/build.gradle @@ -157,8 +157,7 @@ tasks.named('processResources', ProcessResources).configure { forge_version : forge_version, forge_version_range : forge_version_range, loader_version_range : loader_version_range, - mod_version : mod_version, - embeddium_version_range: embeddium_version_range + mod_version : mod_version ] inputs.properties replaceProperties diff --git a/gradle.properties b/gradle.properties index 89e8f5c5c..43ea1cc3d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,6 @@ forge_version=47.2.19 minecraft_version_range=[1.20.1,1.20.3) forge_version_range=[47,) loader_version_range=[47,) -embeddium_version_range=[0.2.10,0.3) # build dependency versions forgegradle_version = [6.0.16,6.2) diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backends.java b/src/main/java/com/jozufozu/flywheel/backend/Backends.java index 989e23edb..ada863bb0 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backends.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backends.java @@ -21,7 +21,7 @@ public class Backends { public static final Backend INSTANCING = SimpleBackend.builder() .engineMessage(Component.literal("Using Instancing Engine") .withStyle(ChatFormatting.GREEN)) - .engineFactory(level -> new InstancingEngine(256)) + .engineFactory(level -> new InstancingEngine(InstancingPrograms.get(), 256)) .supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.supportsInstancing() && InstancingPrograms.allLoaded()) .register(Flywheel.rl("instancing")); @@ -31,7 +31,7 @@ public class Backends { public static final Backend INDIRECT = SimpleBackend.builder() .engineMessage(Component.literal("Using Indirect Engine") .withStyle(ChatFormatting.GREEN)) - .engineFactory(level -> new IndirectEngine(256)) + .engineFactory(level -> new IndirectEngine(IndirectPrograms.get(), 256)) .fallback(() -> Backends.INSTANCING) .supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.supportsIndirect() && IndirectPrograms.allLoaded()) .register(Flywheel.rl("indirect")); diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/AbstractPrograms.java b/src/main/java/com/jozufozu/flywheel/backend/compile/AbstractPrograms.java new file mode 100644 index 000000000..d3acb56b1 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/AbstractPrograms.java @@ -0,0 +1,31 @@ +package com.jozufozu.flywheel.backend.compile; + +import java.util.concurrent.atomic.AtomicInteger; + +public abstract class AbstractPrograms { + private final AtomicInteger refCount = new AtomicInteger(); + private volatile boolean isDeleted; + + public int refCount() { + return refCount.get(); + } + + public void acquire() { + if (isDeleted) { + throw new IllegalStateException("Tried to acquire deleted instance of '" + getClass().getName() + "'!"); + } + refCount.getAndIncrement(); + } + + public void release() { + int newCount = refCount.decrementAndGet(); + if (newCount == 0) { + isDeleted = true; + delete(); + } else if (newCount < 0) { + throw new IllegalStateException("Tried to delete instance of '" + getClass().getName() + "' more times than it was acquired!"); + } + } + + protected abstract void delete(); +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/FlwPrograms.java b/src/main/java/com/jozufozu/flywheel/backend/compile/FlwPrograms.java index a863d72d5..488948964 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/FlwPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/FlwPrograms.java @@ -11,6 +11,7 @@ import com.jozufozu.flywheel.backend.ShaderIndices; import com.jozufozu.flywheel.backend.compile.component.UberShaderComponent; import com.jozufozu.flywheel.backend.compile.component.UniformComponent; import com.jozufozu.flywheel.backend.compile.core.CompilerStats; +import com.jozufozu.flywheel.backend.compile.core.SourceLoader; import com.jozufozu.flywheel.backend.glsl.ShaderSources; import com.jozufozu.flywheel.backend.glsl.SourceComponent; import com.jozufozu.flywheel.backend.glsl.generate.FnSignature; @@ -19,13 +20,12 @@ import com.jozufozu.flywheel.backend.glsl.generate.GlslExpr; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.ResourceManagerReloadListener; -public class FlwPrograms { +public final class FlwPrograms { private FlwPrograms() { } - public static void reload(ResourceManager resourceManager) { + private static void reload(ResourceManager resourceManager) { var sources = new ShaderSources(resourceManager); - var preLoadStats = new CompilerStats(); var loadChecker = new SourceLoader(sources, preLoadStats); 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 40e4daf44..1ee103788 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java @@ -11,6 +11,8 @@ import com.jozufozu.flywheel.api.context.Context; import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.backend.compile.component.IndirectComponent; import com.jozufozu.flywheel.backend.compile.component.UniformComponent; +import com.jozufozu.flywheel.backend.compile.core.CompilationHarness; +import com.jozufozu.flywheel.backend.compile.core.Compile; import com.jozufozu.flywheel.backend.gl.GlCompat; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.backend.gl.shader.ShaderType; @@ -20,20 +22,23 @@ import com.jozufozu.flywheel.backend.glsl.SourceComponent; import net.minecraft.resources.ResourceLocation; -public class IndirectPrograms { +public class IndirectPrograms extends AbstractPrograms { private static final ResourceLocation CULL_SHADER_MAIN = Flywheel.rl("internal/indirect/cull.glsl"); private static final ResourceLocation APPLY_SHADER_MAIN = Flywheel.rl("internal/indirect/apply.glsl"); private static final ResourceLocation SCATTER_SHADER_MAIN = Flywheel.rl("internal/indirect/scatter.glsl"); - public static IndirectPrograms instance; private static final Compile> CULL = new Compile<>(); private static final Compile UTIL = new Compile<>(); + + @Nullable + private static IndirectPrograms instance; + private final Map pipeline; private final Map, GlProgram> culling; private final GlProgram apply; private final GlProgram scatter; - public IndirectPrograms(Map pipeline, Map, GlProgram> culling, GlProgram apply, GlProgram scatter) { + private IndirectPrograms(Map pipeline, Map, GlProgram> culling, GlProgram apply, GlProgram scatter) { this.pipeline = pipeline; this.culling = culling; this.apply = apply; @@ -41,7 +46,8 @@ public class IndirectPrograms { } static void reload(ShaderSources sources, ImmutableList pipelineKeys, UniformComponent uniformComponent, List vertexComponents, List fragmentComponents) { - _delete(); + IndirectPrograms newInstance = null; + var pipelineCompiler = PipelineCompiler.create(sources, Pipelines.INDIRECT, uniformComponent, vertexComponents, fragmentComponents); var cullingCompiler = createCullingCompiler(uniformComponent, sources); var applyCompiler = createUtilCompiler(sources); @@ -52,38 +58,17 @@ public class IndirectPrograms { var utils = applyCompiler.compileAndReportErrors(List.of(APPLY_SHADER_MAIN, SCATTER_SHADER_MAIN)); if (pipelineResult != null && cullingResult != null && utils != null) { - instance = new IndirectPrograms(pipelineResult, cullingResult, utils.get(APPLY_SHADER_MAIN), utils.get(SCATTER_SHADER_MAIN)); + newInstance = new IndirectPrograms(pipelineResult, cullingResult, utils.get(APPLY_SHADER_MAIN), utils.get(SCATTER_SHADER_MAIN)); } - } catch (Throwable e) { - Flywheel.LOGGER.error("Failed to compile indirect programs", e); + } catch (Throwable t) { + Flywheel.LOGGER.error("Failed to compile indirect programs", t); } + pipelineCompiler.delete(); cullingCompiler.delete(); applyCompiler.delete(); - } - private static ImmutableList> createCullingKeys() { - ImmutableList.Builder> builder = ImmutableList.builder(); - for (InstanceType instanceType : InstanceType.REGISTRY) { - builder.add(instanceType); - } - return builder.build(); - } - - @Nullable - public static IndirectPrograms get() { - return instance; - } - - public static boolean allLoaded() { - return instance != null; - } - - private static void _delete() { - if (instance != null) { - instance.delete(); - instance = null; - } + setInstance(newInstance); } private static CompilationHarness> createCullingCompiler(UniformComponent uniformComponent, ShaderSources sources) { @@ -106,6 +91,33 @@ public class IndirectPrograms { .harness(sources); } + private static ImmutableList> createCullingKeys() { + ImmutableList.Builder> builder = ImmutableList.builder(); + for (InstanceType instanceType : InstanceType.REGISTRY) { + builder.add(instanceType); + } + return builder.build(); + } + + private static void setInstance(@Nullable IndirectPrograms newInstance) { + if (instance != null) { + instance.release(); + } + if (newInstance != null) { + newInstance.acquire(); + } + instance = newInstance; + } + + @Nullable + public static IndirectPrograms get() { + return instance; + } + + public static boolean allLoaded() { + return instance != null; + } + public GlProgram getIndirectProgram(InstanceType instanceType, Context contextShader) { return pipeline.get(new PipelineProgramKey(instanceType, contextShader)); } @@ -122,7 +134,8 @@ public class IndirectPrograms { return scatter; } - public void delete() { + @Override + protected void delete() { pipeline.values() .forEach(GlProgram::delete); culling.values() 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 333aaac4e..ff55b0ee9 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/InstancingPrograms.java @@ -14,28 +14,44 @@ import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.backend.glsl.ShaderSources; import com.jozufozu.flywheel.backend.glsl.SourceComponent; -public class InstancingPrograms { - static InstancingPrograms instance; +public class InstancingPrograms extends AbstractPrograms { + @Nullable + private static InstancingPrograms instance; + private final Map pipeline; - public InstancingPrograms(Map pipeline) { + private InstancingPrograms(Map pipeline) { this.pipeline = pipeline; } static void reload(ShaderSources sources, ImmutableList pipelineKeys, UniformComponent uniformComponent, List vertexComponents, List fragmentComponents) { - _delete(); - var instancingCompiler = PipelineCompiler.create(sources, Pipelines.INSTANCED_ARRAYS, uniformComponent, vertexComponents, fragmentComponents); + InstancingPrograms newInstance = null; + + var pipelineCompiler = PipelineCompiler.create(sources, Pipelines.INSTANCED_ARRAYS, uniformComponent, vertexComponents, fragmentComponents); try { - var result = instancingCompiler.compileAndReportErrors(pipelineKeys); + var pipelineResult = pipelineCompiler.compileAndReportErrors(pipelineKeys); - if (result != null) { - instance = new InstancingPrograms(result); + if (pipelineResult != null) { + newInstance = new InstancingPrograms(pipelineResult); } - } catch (Throwable e) { - Flywheel.LOGGER.error("Failed to compile instancing programs", e); + } catch (Throwable t) { + Flywheel.LOGGER.error("Failed to compile instancing programs", t); } - instancingCompiler.delete(); + + pipelineCompiler.delete(); + + setInstance(newInstance); + } + + private static void setInstance(@Nullable InstancingPrograms newInstance) { + if (instance != null) { + instance.release(); + } + if (newInstance != null) { + newInstance.acquire(); + } + instance = newInstance; } @Nullable @@ -47,18 +63,12 @@ public class InstancingPrograms { return instance != null; } - static void _delete() { - if (instance != null) { - instance.delete(); - instance = null; - } - } - public GlProgram get(InstanceType instanceType, Context contextShader) { return pipeline.get(new PipelineProgramKey(instanceType, contextShader)); } - public void delete() { + @Override + protected void delete() { pipeline.values() .forEach(GlProgram::delete); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/LayoutInterpreter.java b/src/main/java/com/jozufozu/flywheel/backend/compile/LayoutInterpreter.java index 62f255848..c7693405d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/LayoutInterpreter.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/LayoutInterpreter.java @@ -9,7 +9,10 @@ import com.jozufozu.flywheel.api.layout.UnsignedIntegerRepr; import com.jozufozu.flywheel.api.layout.ValueRepr; import com.jozufozu.flywheel.api.layout.VectorElementType; -public class LayoutInterpreter { +public final class LayoutInterpreter { + private LayoutInterpreter() { + } + public static int attributeCount(ElementType type) { if (type instanceof ScalarElementType) { return 1; @@ -34,8 +37,15 @@ public class LayoutInterpreter { throw new IllegalArgumentException("Unknown type " + type); } - public static String matrixTypeName(MatrixElementType matrix) { - return "mat" + matrix.columns() + "x" + matrix.rows(); + public static String scalarTypeName(ValueRepr repr) { + if (repr instanceof IntegerRepr) { + return "int"; + } else if (repr instanceof UnsignedIntegerRepr) { + return "uint"; + } else if (repr instanceof FloatRepr) { + return "float"; + } + throw new IllegalArgumentException("Unknown repr " + repr); } public static String vectorTypeName(ValueRepr repr, int size) { @@ -49,14 +59,7 @@ public class LayoutInterpreter { throw new IllegalArgumentException("Unknown repr " + repr); } - public static String scalarTypeName(ValueRepr repr) { - if (repr instanceof IntegerRepr) { - return "int"; - } else if (repr instanceof UnsignedIntegerRepr) { - return "uint"; - } else if (repr instanceof FloatRepr) { - return "float"; - } - throw new IllegalArgumentException("Unknown repr " + repr); + public static String matrixTypeName(MatrixElementType matrix) { + return "mat" + matrix.columns() + "x" + matrix.rows(); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java index 9d67f6575..75841470a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java @@ -4,6 +4,8 @@ import java.util.List; import com.jozufozu.flywheel.backend.InternalVertex; import com.jozufozu.flywheel.backend.compile.component.UniformComponent; +import com.jozufozu.flywheel.backend.compile.core.CompilationHarness; +import com.jozufozu.flywheel.backend.compile.core.Compile; import com.jozufozu.flywheel.backend.gl.shader.ShaderType; import com.jozufozu.flywheel.backend.glsl.ShaderSources; import com.jozufozu.flywheel.backend.glsl.SourceComponent; diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/component/UberShaderComponent.java b/src/main/java/com/jozufozu/flywheel/backend/compile/component/UberShaderComponent.java index 342405e25..3ec4614a7 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/component/UberShaderComponent.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/component/UberShaderComponent.java @@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.jozufozu.flywheel.backend.compile.SourceLoader; +import com.jozufozu.flywheel.backend.compile.core.SourceLoader; import com.jozufozu.flywheel.backend.glsl.SourceComponent; import com.jozufozu.flywheel.backend.glsl.SourceFile; import com.jozufozu.flywheel.backend.glsl.generate.FnSignature; diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/component/UniformComponent.java b/src/main/java/com/jozufozu/flywheel/backend/compile/component/UniformComponent.java index 9797c32b3..3002bb7ab 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/component/UniformComponent.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/component/UniformComponent.java @@ -5,7 +5,7 @@ import java.util.Collection; import java.util.List; import com.google.common.collect.ImmutableList; -import com.jozufozu.flywheel.backend.compile.SourceLoader; +import com.jozufozu.flywheel.backend.compile.core.SourceLoader; import com.jozufozu.flywheel.backend.glsl.SourceComponent; import com.jozufozu.flywheel.backend.glsl.SourceFile; import com.jozufozu.flywheel.backend.glsl.generate.GlslBuilder; diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/CompilationHarness.java b/src/main/java/com/jozufozu/flywheel/backend/compile/core/CompilationHarness.java similarity index 86% rename from src/main/java/com/jozufozu/flywheel/backend/compile/CompilationHarness.java rename to src/main/java/com/jozufozu/flywheel/backend/compile/core/CompilationHarness.java index f46703981..60a401895 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/CompilationHarness.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/core/CompilationHarness.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.backend.compile; +package com.jozufozu.flywheel.backend.compile.core; import java.util.Collection; import java.util.HashMap; @@ -7,9 +7,6 @@ import java.util.Map; import org.jetbrains.annotations.Nullable; import com.jozufozu.flywheel.Flywheel; -import com.jozufozu.flywheel.backend.compile.core.CompilerStats; -import com.jozufozu.flywheel.backend.compile.core.ProgramLinker; -import com.jozufozu.flywheel.backend.compile.core.ShaderCompiler; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.backend.glsl.ShaderSources; diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/Compile.java b/src/main/java/com/jozufozu/flywheel/backend/compile/core/Compile.java similarity index 95% rename from src/main/java/com/jozufozu/flywheel/backend/compile/Compile.java rename to src/main/java/com/jozufozu/flywheel/backend/compile/core/Compile.java index 46b7460f2..1ef355a83 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/Compile.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/core/Compile.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.backend.compile; +package com.jozufozu.flywheel.backend.compile.core; import java.util.ArrayList; import java.util.Collection; @@ -13,9 +13,6 @@ import java.util.function.Function; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import com.jozufozu.flywheel.backend.compile.core.Compilation; -import com.jozufozu.flywheel.backend.compile.core.ProgramLinker; -import com.jozufozu.flywheel.backend.compile.core.ShaderCompiler; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.backend.gl.shader.GlShader; import com.jozufozu.flywheel.backend.gl.shader.ShaderType; diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/SourceLoader.java b/src/main/java/com/jozufozu/flywheel/backend/compile/core/SourceLoader.java similarity index 83% rename from src/main/java/com/jozufozu/flywheel/backend/compile/SourceLoader.java rename to src/main/java/com/jozufozu/flywheel/backend/compile/core/SourceLoader.java index e903293c2..6c77c2fee 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/SourceLoader.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/core/SourceLoader.java @@ -1,15 +1,13 @@ -package com.jozufozu.flywheel.backend.compile; +package com.jozufozu.flywheel.backend.compile.core; import org.jetbrains.annotations.Nullable; -import com.jozufozu.flywheel.backend.compile.core.CompilerStats; import com.jozufozu.flywheel.backend.glsl.ShaderSources; import com.jozufozu.flywheel.backend.glsl.SourceFile; import net.minecraft.resources.ResourceLocation; public class SourceLoader { - private final ShaderSources sources; private final CompilerStats stats; diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/CommonCrumbling.java b/src/main/java/com/jozufozu/flywheel/backend/engine/CommonCrumbling.java index 22706e3a0..f5ba52738 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/CommonCrumbling.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/CommonCrumbling.java @@ -20,7 +20,8 @@ public class CommonCrumbling { .transparency(Transparency.CRUMBLING) .writeMask(WriteMask.COLOR) .useOverlay(false) - .useLight(false); + .useLight(false) + .diffuse(false); } public static int getDiffuseTexture(Material material) { diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/MaterialEncoder.java b/src/main/java/com/jozufozu/flywheel/backend/engine/MaterialEncoder.java index 9b6dce85d..cd0fb641b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/MaterialEncoder.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/MaterialEncoder.java @@ -8,7 +8,7 @@ import com.jozufozu.flywheel.backend.ShaderIndices; import net.minecraft.util.Mth; -// Materials are unpacked in "flywheel:flywheel/internal/material.glsl" +// Materials are unpacked in "flywheel:flywheel/internal/packed_material.glsl" public final class MaterialEncoder { // The number of bits each property takes up private static final int BLUR_LENGTH = 1; @@ -65,7 +65,7 @@ public final class MaterialEncoder { } // Packed format: - // diffuse[1] | useOverlay[1] | useLight[1] | writeMask[2] | transparency[3] | depthTest[4] | polygonOffset[1] | backfaceCulling[1] | mipmap[1] | blur[1] + // diffuse[1] | useLight[1] | useOverlay[1] | writeMask[2] | transparency[3] | depthTest[4] | polygonOffset[1] | backfaceCulling[1] | mipmap[1] | blur[1] public static int packProperties(Material material) { int bits = 0; diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java index f8222bb80..a9cdea09c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java @@ -36,34 +36,34 @@ public class IndirectCullingGroup { private static final int DRAW_BARRIER_BITS = GL_SHADER_STORAGE_BARRIER_BIT | GL_COMMAND_BARRIER_BIT; - private final GlProgram cullProgram; - private final GlProgram applyProgram; - private final GlProgram drawProgram; - + private final InstanceType instanceType; private final long objectStride; private final IndirectBuffers buffers; private final IndirectMeshPool meshPool; private final List indirectModels = new ArrayList<>(); private final List indirectDraws = new ArrayList<>(); private final Map> multiDraws = new EnumMap<>(RenderStage.class); - private final InstanceType instanceType; + + private final IndirectPrograms programs; + private final GlProgram cullProgram; + private final GlProgram applyProgram; + private final GlProgram drawProgram; + private boolean needsDrawBarrier; private boolean hasNewDraws; private int instanceCountThisFrame; - IndirectCullingGroup(InstanceType instanceType) { + IndirectCullingGroup(InstanceType instanceType, IndirectPrograms programs) { this.instanceType = instanceType; - var programs = IndirectPrograms.get(); + objectStride = instanceType.layout() + .byteSize() + IndirectBuffers.INT_SIZE; + buffers = new IndirectBuffers(objectStride); + meshPool = new IndirectMeshPool(); + + this.programs = programs; cullProgram = programs.getCullingProgram(instanceType); applyProgram = programs.getApplyProgram(); drawProgram = programs.getIndirectProgram(instanceType, Contexts.DEFAULT); - - objectStride = instanceType.layout() - .byteSize() + IndirectBuffers.INT_SIZE; - - buffers = new IndirectBuffers(objectStride); - - meshPool = new IndirectMeshPool(); } public void flush(StagingBuffer stagingBuffer) { @@ -200,8 +200,7 @@ public class IndirectCullingGroup { } public void bindForCrumbling() { - var program = IndirectPrograms.get() - .getIndirectProgram(instanceType, Contexts.CRUMBLING); + var program = programs.getIndirectProgram(instanceType, Contexts.CRUMBLING); program.bind(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java index 781ddd06e..1f92f8976 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java @@ -18,6 +18,7 @@ import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.model.Model; +import com.jozufozu.flywheel.backend.compile.IndirectPrograms; import com.jozufozu.flywheel.backend.engine.CommonCrumbling; import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl; import com.jozufozu.flywheel.backend.engine.InstancerKey; @@ -34,10 +35,16 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.client.resources.model.ModelBakery; public class IndirectDrawManager extends InstancerStorage> { - private final StagingBuffer stagingBuffer = new StagingBuffer(); + private final IndirectPrograms programs; + private final StagingBuffer stagingBuffer; private final Map, IndirectCullingGroup> cullingGroups = new HashMap<>(); private final GlBuffer crumblingDrawBuffer = new GlBuffer(); + public IndirectDrawManager(IndirectPrograms programs) { + this.programs = programs; + stagingBuffer = new StagingBuffer(this.programs); + } + @Override protected IndirectInstancer create(InstanceType type) { return new IndirectInstancer<>(type); @@ -52,7 +59,7 @@ public class IndirectDrawManager extends InstancerStorage> return; } - var group = (IndirectCullingGroup) cullingGroups.computeIfAbsent(key.type(), IndirectCullingGroup::new); + var group = (IndirectCullingGroup) cullingGroups.computeIfAbsent(key.type(), t -> new IndirectCullingGroup<>(t, programs)); group.add((IndirectInstancer) instancer, model, stage); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java index 5cf147b1a..ebec341a9 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java @@ -6,6 +6,7 @@ import com.jozufozu.flywheel.api.event.RenderContext; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.task.Plan; import com.jozufozu.flywheel.api.task.TaskExecutor; +import com.jozufozu.flywheel.backend.compile.IndirectPrograms; import com.jozufozu.flywheel.backend.engine.AbstractEngine; import com.jozufozu.flywheel.backend.engine.AbstractInstancer; import com.jozufozu.flywheel.backend.engine.InstancerStorage; @@ -19,13 +20,18 @@ import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GameRenderer; public class IndirectEngine extends AbstractEngine { - private final IndirectDrawManager drawManager = new IndirectDrawManager(); + private final IndirectPrograms programs; + private final IndirectDrawManager drawManager; private final Flag flushFlag = new NamedFlag("flushed"); - public IndirectEngine(int maxOriginDistance) { + public IndirectEngine(IndirectPrograms programs, int maxOriginDistance) { super(maxOriginDistance); + programs.acquire(); + this.programs = programs; + drawManager = new IndirectDrawManager(this.programs); } @Override @@ -52,9 +58,10 @@ public class IndirectEngine extends AbstractEngine { } try (var restoreState = GlStateTracker.getRestoreState()) { + GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer; int prevActiveTexture = GlStateManager._getActiveTexture(); - Minecraft.getInstance().gameRenderer.overlayTexture().setupOverlayColor(); - Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer(); + gameRenderer.overlayTexture().setupOverlayColor(); + gameRenderer.lightTexture().turnOnLightLayer(); GlTextureUnit.T1.makeActive(); RenderSystem.bindTexture(RenderSystem.getShaderTexture(1)); @@ -65,8 +72,8 @@ public class IndirectEngine extends AbstractEngine { MaterialRenderState.reset(); - Minecraft.getInstance().gameRenderer.overlayTexture().teardownOverlayColor(); - Minecraft.getInstance().gameRenderer.lightTexture().turnOffLightLayer(); + gameRenderer.overlayTexture().teardownOverlayColor(); + gameRenderer.lightTexture().turnOffLightLayer(); GlStateManager._activeTexture(prevActiveTexture); } } @@ -90,5 +97,6 @@ public class IndirectEngine extends AbstractEngine { @Override public void delete() { drawManager.delete(); + programs.release(); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/StagingBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/StagingBuffer.java index 1e66b2c12..1cff2d8c8 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/StagingBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/StagingBuffer.java @@ -12,6 +12,7 @@ import com.jozufozu.flywheel.backend.compile.IndirectPrograms; import com.jozufozu.flywheel.backend.gl.GlCompat; import com.jozufozu.flywheel.backend.gl.GlFence; import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; +import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker; import com.jozufozu.flywheel.lib.memory.MemoryBlock; @@ -29,6 +30,14 @@ public class StagingBuffer { private final long map; private final long capacity; + private final OverflowStagingBuffer overflow = new OverflowStagingBuffer(); + private final TransferList transfers = new TransferList(); + private final PriorityQueue fencedRegions = new ObjectArrayFIFOQueue<>(); + private final GlBuffer scatterBuffer = new GlBuffer(); + private final ScatterList scatterList = new ScatterList(); + + private final GlProgram scatterProgram; + /** * The position in the buffer at the time of the last flush. */ @@ -58,17 +67,14 @@ public class StagingBuffer { @Nullable private MemoryBlock scratch; - private final OverflowStagingBuffer overflow = new OverflowStagingBuffer(); - private final TransferList transfers = new TransferList(); - private final PriorityQueue fencedRegions = new ObjectArrayFIFOQueue<>(); - private final GlBuffer scatterBuffer = new GlBuffer(); - private final ScatterList scatterList = new ScatterList(); - - public StagingBuffer() { - this(DEFAULT_CAPACITY); + public StagingBuffer(IndirectPrograms programs) { + this(DEFAULT_CAPACITY, programs); } - public StagingBuffer(long capacity) { + public StagingBuffer(long capacity, IndirectPrograms programs) { + scatterProgram = IndirectPrograms.get() + .getScatterProgram(); + this.capacity = capacity; vbo = GL45C.glCreateBuffers(); @@ -247,9 +253,7 @@ public class StagingBuffer { * this presentation */ private void dispatchComputeCopies() { - IndirectPrograms.get() - .getScatterProgram() - .bind(); + scatterProgram.bind(); // These bindings don't change between dstVbos. GL45.glBindBufferBase(GL45C.GL_SHADER_STORAGE_BUFFER, 0, scatterBuffer.handle()); diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java index a546c6e8c..28ce76ff7 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java @@ -23,7 +23,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.client.resources.model.ModelBakery; public class InstancedCrumbling { - public static void render(List crumblingBlocks) { + public static void render(List crumblingBlocks, InstancingPrograms programs) { // Sort draw calls into buckets, so we don't have to do as many shader binds. var byShaderState = doCrumblingSort(crumblingBlocks); @@ -48,8 +48,7 @@ public class InstancedCrumbling { CommonCrumbling.applyCrumblingProperties(crumblingMaterial, baseMaterial); - var program = InstancingPrograms.get() - .get(shader.instanceType(), Contexts.CRUMBLING); + var program = programs.get(shader.instanceType(), Contexts.CRUMBLING); program.bind(); UniformBuffer.get().sync(); @@ -108,7 +107,7 @@ public class InstancedCrumbling { } } } + return out; } - } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java index 0abf6ef73..62c83ab4f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java @@ -28,14 +28,17 @@ import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GameRenderer; public class InstancingEngine extends AbstractEngine { + private final InstancingPrograms programs; private final InstancedDrawManager drawManager = new InstancedDrawManager(); - private final Flag flushFlag = new NamedFlag("flushed"); - public InstancingEngine(int maxOriginDistance) { + public InstancingEngine(InstancingPrograms programs, int maxOriginDistance) { super(maxOriginDistance); + programs.acquire(); + this.programs = programs; } @Override @@ -64,9 +67,10 @@ public class InstancingEngine extends AbstractEngine { } try (var state = GlStateTracker.getRestoreState()) { + GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer; int prevActiveTexture = GlStateManager._getActiveTexture(); - Minecraft.getInstance().gameRenderer.overlayTexture().setupOverlayColor(); - Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer(); + gameRenderer.overlayTexture().setupOverlayColor(); + gameRenderer.lightTexture().turnOnLightLayer(); GlTextureUnit.T1.makeActive(); RenderSystem.bindTexture(RenderSystem.getShaderTexture(1)); @@ -75,8 +79,8 @@ public class InstancingEngine extends AbstractEngine { render(drawSet); - Minecraft.getInstance().gameRenderer.overlayTexture().teardownOverlayColor(); - Minecraft.getInstance().gameRenderer.lightTexture().turnOffLightLayer(); + gameRenderer.overlayTexture().teardownOverlayColor(); + gameRenderer.lightTexture().turnOffLightLayer(); GlStateManager._activeTexture(prevActiveTexture); } } @@ -86,7 +90,7 @@ public class InstancingEngine extends AbstractEngine { // Need to wait for flush before we can inspect instancer state. executor.syncUntil(flushFlag::isRaised); - InstancedCrumbling.render(crumblingBlocks); + InstancedCrumbling.render(crumblingBlocks, programs); } @Override @@ -97,6 +101,7 @@ public class InstancingEngine extends AbstractEngine { @Override public void delete() { drawManager.delete(); + programs.release(); } private void render(InstancedDrawManager.DrawSet drawSet) { @@ -110,8 +115,7 @@ public class InstancingEngine extends AbstractEngine { continue; } - var program = InstancingPrograms.get() - .get(shader.instanceType(), Contexts.DEFAULT); + var program = programs.get(shader.instanceType(), Contexts.DEFAULT); program.bind(); UniformBuffer.get().sync(); diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 366b6e035..4ef879737 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -31,9 +31,9 @@ side = "CLIENT" [[dependencies.flywheel]] modId = "rubidium" +# This replicates a "breaks" dependency. +# There's a mixin crash with Rubidium <0.7.0. mandatory = false -# This should be a "breaks" dependency. -# There's a mixin crash with Rubidum < 0.7.0 versionRange = "[0.7.0,)" ordering = "NONE" side = "CLIENT" diff --git a/src/main/resources/assets/flywheel/flywheel/internal/packed_material.glsl b/src/main/resources/assets/flywheel/flywheel/internal/packed_material.glsl index 193667a1d..b56828c1f 100644 --- a/src/main/resources/assets/flywheel/flywheel/internal/packed_material.glsl +++ b/src/main/resources/assets/flywheel/flywheel/internal/packed_material.glsl @@ -35,7 +35,7 @@ const uint _FLW_USE_LIGHT_MASK = ((1u << _FLW_USE_LIGHT_LENGTH) - 1u) << _FLW_US const uint _FLW_DIFFUSE_MASK = ((1u << _FLW_DIFFUSE_LENGTH) - 1u) << _FLW_DIFFUSE_OFFSET; // Packed format: -// diffuse[1] | useOverlay[1] | useLight[1] | writeMask[2] | transparency[3] | depthTest[4] | polygonOffset[1] | backfaceCulling[1] | mipmap[1] | blur[1] +// diffuse[1] | useLight[1] | useOverlay[1] | writeMask[2] | transparency[3] | depthTest[4] | polygonOffset[1] | backfaceCulling[1] | mipmap[1] | blur[1] void _flw_unpackMaterialProperties(uint p, out FlwMaterial m) { m.blur = (p & _FLW_BLUR_MASK) != 0u; m.mipmap = (p & _FLW_MIPMAP_MASK) != 0u; diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index fedc32bb4..2f2b4f1e2 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,6 +1,6 @@ { "pack": { "description": "Flywheel resources", - "pack_format": 18 + "pack_format": 15 } }