Skip to content

Commit 11ce4ac

Browse files
committed
Dynamic ubering
- Remove fog shader registry - Remove Registry and RegistryImpl - Make shader indices mutable - Track fog uber component in a static field in PipelineCompiler - When a new fog source is added, delete the pipeline compilation harness and recreate the fog uber component - Inline SourceLoader
1 parent bce6578 commit 11ce4ac

File tree

21 files changed

+115
-258
lines changed

21 files changed

+115
-258
lines changed

common/src/api/java/dev/engine_room/flywheel/api/internal/FlwApiLink.java

-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import dev.engine_room.flywheel.api.backend.Backend;
66
import dev.engine_room.flywheel.api.layout.LayoutBuilder;
77
import dev.engine_room.flywheel.api.registry.IdRegistry;
8-
import dev.engine_room.flywheel.api.registry.Registry;
98
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
109
import dev.engine_room.flywheel.api.visualization.EntityVisualizer;
1110
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
@@ -18,8 +17,6 @@
1817
public interface FlwApiLink {
1918
FlwApiLink INSTANCE = DependencyInjection.load(FlwApiLink.class, "dev.engine_room.flywheel.impl.FlwApiLinkImpl");
2019

21-
<T> Registry<T> createRegistry();
22-
2320
<T> IdRegistry<T> createIdRegistry();
2421

2522
Backend getCurrentBackend();
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
package dev.engine_room.flywheel.api.material;
22

3-
import dev.engine_room.flywheel.api.internal.FlwApiLink;
4-
import dev.engine_room.flywheel.api.registry.Registry;
53
import net.minecraft.resources.ResourceLocation;
64

75
public interface FogShader {
8-
Registry<FogShader> REGISTRY = FlwApiLink.INSTANCE.createRegistry();
9-
106
ResourceLocation source();
117
}

common/src/api/java/dev/engine_room/flywheel/api/registry/Registry.java

-18
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,29 @@
11
package dev.engine_room.flywheel.backend;
22

33
import java.util.List;
4-
import java.util.function.Function;
54

6-
import org.jetbrains.annotations.Nullable;
75
import org.jetbrains.annotations.Unmodifiable;
86

97
import dev.engine_room.flywheel.api.material.CutoutShader;
108
import dev.engine_room.flywheel.api.material.FogShader;
11-
import dev.engine_room.flywheel.api.registry.Registry;
129
import it.unimi.dsi.fastutil.objects.Object2IntMap;
1310
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
1411
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
1512
import it.unimi.dsi.fastutil.objects.ObjectList;
1613
import net.minecraft.resources.ResourceLocation;
1714

1815
public final class MaterialShaderIndices {
19-
@Nullable
20-
private static Index fogSources;
21-
@Nullable
22-
private static Index cutoutSources;
16+
private static final Index fogSources = new Index();
17+
private static final Index cutoutSources = new Index();
2318

2419
private MaterialShaderIndices() {
2520
}
2621

2722
public static Index fogSources() {
28-
if (fogSources == null) {
29-
fogSources = indexFromRegistry(FogShader.REGISTRY, FogShader::source);
30-
}
3123
return fogSources;
3224
}
3325

3426
public static Index cutoutSources() {
35-
// if (cutoutSources == null) {
36-
// cutoutSources = indexFromRegistry(CutoutShader.REGISTRY, CutoutShader::source);
37-
// }
3827
return cutoutSources;
3928
}
4029

@@ -43,30 +32,23 @@ public static int fogIndex(FogShader fogShader) {
4332
}
4433

4534
public static int cutoutIndex(CutoutShader cutoutShader) {
46-
return 0;//cutoutSources().index(cutoutShader.source());
47-
}
48-
49-
private static <T> Index indexFromRegistry(Registry<T> registry, Function<T, ResourceLocation> sourceFunc) {
50-
if (!registry.isFrozen()) {
51-
throw new IllegalStateException("Cannot create index from registry that is not frozen!");
52-
}
53-
54-
var builder = new IndexBuilder();
55-
56-
for (T object : registry) {
57-
builder.add(sourceFunc.apply(object));
58-
}
59-
60-
return builder.build();
35+
return cutoutSources().index(cutoutShader.source());
6136
}
6237

6338
public static class Index {
6439
private final Object2IntMap<ResourceLocation> sources2Index;
6540
private final ObjectList<ResourceLocation> sources;
6641

67-
private Index(IndexBuilder builder) {
68-
this.sources2Index = new Object2IntOpenHashMap<>(builder.sources2Index);
69-
this.sources = new ObjectArrayList<>(builder.sources);
42+
private Index() {
43+
this.sources2Index = new Object2IntOpenHashMap<>();
44+
sources2Index.defaultReturnValue(-1);
45+
this.sources = new ObjectArrayList<>();
46+
}
47+
48+
public void add(ResourceLocation source) {
49+
if (sources2Index.putIfAbsent(source, sources.size()) == -1) {
50+
sources.add(source);
51+
}
7052
}
7153

7254
public int index(ResourceLocation source) {
@@ -82,27 +64,4 @@ public List<ResourceLocation> all() {
8264
return sources;
8365
}
8466
}
85-
86-
private static class IndexBuilder {
87-
private final Object2IntMap<ResourceLocation> sources2Index;
88-
private final ObjectList<ResourceLocation> sources;
89-
private int index = 0;
90-
91-
public IndexBuilder() {
92-
sources2Index = new Object2IntOpenHashMap<>();
93-
sources2Index.defaultReturnValue(-1);
94-
sources = new ObjectArrayList<>();
95-
}
96-
97-
public void add(ResourceLocation source) {
98-
if (sources2Index.putIfAbsent(source, index) == -1) {
99-
sources.add(source);
100-
index++;
101-
}
102-
}
103-
104-
public Index build() {
105-
return new Index(this);
106-
}
107-
}
10867
}

common/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwPrograms.java

+6-40
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,13 @@
22

33
import java.util.List;
44

5-
import org.jetbrains.annotations.Nullable;
65
import org.slf4j.Logger;
76
import org.slf4j.LoggerFactory;
87

98
import dev.engine_room.flywheel.api.Flywheel;
10-
import dev.engine_room.flywheel.backend.MaterialShaderIndices;
11-
import dev.engine_room.flywheel.backend.compile.component.UberShaderComponent;
129
import dev.engine_room.flywheel.backend.compile.core.CompilerStats;
13-
import dev.engine_room.flywheel.backend.compile.core.SourceLoader;
1410
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
1511
import dev.engine_room.flywheel.backend.glsl.SourceComponent;
16-
import dev.engine_room.flywheel.backend.glsl.generate.FnSignature;
17-
import dev.engine_room.flywheel.backend.glsl.generate.GlslExpr;
1812
import net.minecraft.resources.ResourceLocation;
1913
import net.minecraft.server.packs.resources.ResourceManager;
2014

@@ -23,6 +17,8 @@ public final class FlwPrograms {
2317

2418
private static final ResourceLocation COMPONENTS_HEADER_FRAG = Flywheel.rl("internal/components_header.frag");
2519

20+
public static ShaderSources SOURCES;
21+
2622
private FlwPrograms() {
2723
}
2824

@@ -32,52 +28,22 @@ static void reload(ResourceManager resourceManager) {
3228
IndirectPrograms.setInstance(null);
3329

3430
var sources = new ShaderSources(resourceManager);
31+
SOURCES = sources;
3532
var stats = new CompilerStats("ubershaders");
36-
var loader = new SourceLoader(sources, stats);
37-
38-
var fragmentComponentsHeader = loader.find(COMPONENTS_HEADER_FRAG);
3933

40-
var fogComponent = createFogComponent(loader);
34+
var fragmentComponentsHeader = sources.get(COMPONENTS_HEADER_FRAG);
4135

4236
// TODO: separate compilation for cutout OFF, but keep the rest uber'd?
43-
if (stats.errored() || fragmentComponentsHeader == null || fogComponent == null) {
37+
if (stats.errored() || fragmentComponentsHeader == null) {
4438
// Probably means the shader sources are missing.
4539
stats.emitErrorLog();
4640
return;
4741
}
4842

4943
List<SourceComponent> vertexComponents = List.of();
50-
List<SourceComponent> fragmentComponents = List.of(fragmentComponentsHeader, fogComponent);
44+
List<SourceComponent> fragmentComponents = List.of(fragmentComponentsHeader);
5145

5246
InstancingPrograms.reload(sources, vertexComponents, fragmentComponents);
5347
IndirectPrograms.reload(sources, vertexComponents, fragmentComponents);
5448
}
55-
56-
@Nullable
57-
private static UberShaderComponent createFogComponent(SourceLoader loader) {
58-
return UberShaderComponent.builder(Flywheel.rl("fog"))
59-
.materialSources(MaterialShaderIndices.fogSources()
60-
.all())
61-
.adapt(FnSignature.create()
62-
.returnType("vec4")
63-
.name("flw_fogFilter")
64-
.arg("vec4", "color")
65-
.build(), GlslExpr.variable("color"))
66-
.switchOn(GlslExpr.variable("_flw_uberFogIndex"))
67-
.build(loader);
68-
}
69-
70-
@Nullable
71-
private static UberShaderComponent createCutoutComponent(SourceLoader loader) {
72-
return UberShaderComponent.builder(Flywheel.rl("cutout"))
73-
.materialSources(MaterialShaderIndices.cutoutSources()
74-
.all())
75-
.adapt(FnSignature.create()
76-
.returnType("bool")
77-
.name("flw_discardPredicate")
78-
.arg("vec4", "color")
79-
.build(), GlslExpr.boolLiteral(false))
80-
.switchOn(GlslExpr.variable("_flw_uberCutoutIndex"))
81-
.build(loader);
82-
}
8349
}

common/src/backend/java/dev/engine_room/flywheel/backend/compile/IndirectPrograms.java

+15-4
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88

99
import dev.engine_room.flywheel.api.Flywheel;
1010
import dev.engine_room.flywheel.api.instance.InstanceType;
11-
import dev.engine_room.flywheel.api.material.CutoutShader;
12-
import dev.engine_room.flywheel.api.material.LightShader;
13-
import dev.engine_room.flywheel.api.material.MaterialShaders;
11+
import dev.engine_room.flywheel.api.material.Material;
12+
import dev.engine_room.flywheel.backend.MaterialShaderIndices;
1413
import dev.engine_room.flywheel.backend.compile.component.InstanceStructComponent;
1514
import dev.engine_room.flywheel.backend.compile.component.SsboInstanceComponent;
1615
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
@@ -151,7 +150,19 @@ public static void kill() {
151150
setInstance(null);
152151
}
153152

154-
public GlProgram getIndirectProgram(InstanceType<?> instanceType, ContextShader contextShader, LightShader light, CutoutShader cutout, MaterialShaders shaders) {
153+
public GlProgram getIndirectProgram(InstanceType<?> instanceType, ContextShader contextShader, Material material) {
154+
var light = material.light();
155+
var cutout = material.cutout();
156+
var shaders = material.shaders();
157+
var fog = material.fog();
158+
159+
var fogIndex = MaterialShaderIndices.fogSources();
160+
if (fogIndex.index(fog.source()) == -1) {
161+
fogIndex.add(fog.source());
162+
pipeline.delete();
163+
PipelineCompiler.createFogComponent();
164+
}
165+
155166
return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light, cutout, shaders, FrameUniforms.debugOn()));
156167
}
157168

common/src/backend/java/dev/engine_room/flywheel/backend/compile/InstancingPrograms.java

+16-4
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77
import com.google.common.collect.ImmutableList;
88

99
import dev.engine_room.flywheel.api.instance.InstanceType;
10-
import dev.engine_room.flywheel.api.material.CutoutShader;
11-
import dev.engine_room.flywheel.api.material.LightShader;
12-
import dev.engine_room.flywheel.api.material.MaterialShaders;
10+
import dev.engine_room.flywheel.api.material.Material;
11+
import dev.engine_room.flywheel.backend.MaterialShaderIndices;
1312
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
1413
import dev.engine_room.flywheel.backend.engine.uniform.FrameUniforms;
1514
import dev.engine_room.flywheel.backend.gl.GlCompat;
@@ -74,7 +73,20 @@ public static void kill() {
7473
setInstance(null);
7574
}
7675

77-
public GlProgram get(InstanceType<?> instanceType, ContextShader contextShader, LightShader light, CutoutShader cutout, MaterialShaders materialShaders) {
76+
public GlProgram get(InstanceType<?> instanceType, ContextShader contextShader, Material material) {
77+
var light = material.light();
78+
var cutout = material.cutout();
79+
var materialShaders = material.shaders();
80+
81+
var fog = material.fog();
82+
83+
var fogIndex = MaterialShaderIndices.fogSources();
84+
if (fogIndex.index(fog.source()) == -1) {
85+
fogIndex.add(fog.source());
86+
pipeline.delete();
87+
PipelineCompiler.createFogComponent();
88+
}
89+
7890
return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light, cutout, materialShaders, FrameUniforms.debugOn()));
7991
}
8092

common/src/backend/java/dev/engine_room/flywheel/backend/compile/PipelineCompiler.java

+34
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
import dev.engine_room.flywheel.api.Flywheel;
77
import dev.engine_room.flywheel.backend.BackendConfig;
88
import dev.engine_room.flywheel.backend.InternalVertex;
9+
import dev.engine_room.flywheel.backend.MaterialShaderIndices;
910
import dev.engine_room.flywheel.backend.Samplers;
1011
import dev.engine_room.flywheel.backend.compile.component.InstanceStructComponent;
12+
import dev.engine_room.flywheel.backend.compile.component.UberShaderComponent;
1113
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
1214
import dev.engine_room.flywheel.backend.compile.core.Compile;
1315
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
@@ -16,13 +18,18 @@
1618
import dev.engine_room.flywheel.backend.gl.shader.ShaderType;
1719
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
1820
import dev.engine_room.flywheel.backend.glsl.SourceComponent;
21+
import dev.engine_room.flywheel.backend.glsl.generate.FnSignature;
22+
import dev.engine_room.flywheel.backend.glsl.generate.GlslExpr;
1923
import dev.engine_room.flywheel.lib.material.CutoutShaders;
2024
import dev.engine_room.flywheel.lib.util.ResourceUtil;
2125
import net.minecraft.resources.ResourceLocation;
2226

2327
public final class PipelineCompiler {
2428
private static final Compile<PipelineProgramKey> PIPELINE = new Compile<>();
2529

30+
private static UberShaderComponent FOG;
31+
private static UberShaderComponent CUTOUT;
32+
2633
private static final ResourceLocation API_IMPL_VERT = Flywheel.rl("internal/api_impl.vert");
2734
private static final ResourceLocation API_IMPL_FRAG = Flywheel.rl("internal/api_impl.frag");
2835

@@ -98,6 +105,7 @@ static CompilationHarness<PipelineProgramKey> create(ShaderSources sources, Pipe
98105
.withResource(key -> key.materialShaders()
99106
.fragmentSource())
100107
.withComponents(fragmentComponents)
108+
.withComponent(key -> FOG)
101109
.withResource(key -> key.light()
102110
.source())
103111
.withResource(key -> key.cutout()
@@ -128,4 +136,30 @@ static CompilationHarness<PipelineProgramKey> create(ShaderSources sources, Pipe
128136
})
129137
.harness(pipeline.compilerMarker(), sources);
130138
}
139+
140+
public static void createFogComponent() {
141+
FOG = UberShaderComponent.builder(Flywheel.rl("fog"))
142+
.materialSources(MaterialShaderIndices.fogSources()
143+
.all())
144+
.adapt(FnSignature.create()
145+
.returnType("vec4")
146+
.name("flw_fogFilter")
147+
.arg("vec4", "color")
148+
.build(), GlslExpr.variable("color"))
149+
.switchOn(GlslExpr.variable("_flw_uberFogIndex"))
150+
.build(FlwPrograms.SOURCES);
151+
}
152+
153+
private static void createCutoutComponent() {
154+
CUTOUT = UberShaderComponent.builder(Flywheel.rl("cutout"))
155+
.materialSources(MaterialShaderIndices.cutoutSources()
156+
.all())
157+
.adapt(FnSignature.create()
158+
.returnType("bool")
159+
.name("flw_discardPredicate")
160+
.arg("vec4", "color")
161+
.build(), GlslExpr.boolLiteral(false))
162+
.switchOn(GlslExpr.variable("_flw_uberCutoutIndex"))
163+
.build(FlwPrograms.SOURCES);
164+
}
131165
}

0 commit comments

Comments
 (0)