mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-14 14:33:57 +01:00
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
This commit is contained in:
parent
bce657804a
commit
11ce4ac185
@ -5,7 +5,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import dev.engine_room.flywheel.api.backend.Backend;
|
||||
import dev.engine_room.flywheel.api.layout.LayoutBuilder;
|
||||
import dev.engine_room.flywheel.api.registry.IdRegistry;
|
||||
import dev.engine_room.flywheel.api.registry.Registry;
|
||||
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
|
||||
import dev.engine_room.flywheel.api.visualization.EntityVisualizer;
|
||||
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
|
||||
@ -18,8 +17,6 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
public interface FlwApiLink {
|
||||
FlwApiLink INSTANCE = DependencyInjection.load(FlwApiLink.class, "dev.engine_room.flywheel.impl.FlwApiLinkImpl");
|
||||
|
||||
<T> Registry<T> createRegistry();
|
||||
|
||||
<T> IdRegistry<T> createIdRegistry();
|
||||
|
||||
Backend getCurrentBackend();
|
||||
|
@ -1,11 +1,7 @@
|
||||
package dev.engine_room.flywheel.api.material;
|
||||
|
||||
import dev.engine_room.flywheel.api.internal.FlwApiLink;
|
||||
import dev.engine_room.flywheel.api.registry.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public interface FogShader {
|
||||
Registry<FogShader> REGISTRY = FlwApiLink.INSTANCE.createRegistry();
|
||||
|
||||
ResourceLocation source();
|
||||
}
|
||||
|
@ -1,18 +0,0 @@
|
||||
package dev.engine_room.flywheel.api.registry;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.UnmodifiableView;
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
public interface Registry<T> extends Iterable<T> {
|
||||
void register(T object);
|
||||
|
||||
<S extends T> S registerAndGet(S object);
|
||||
|
||||
@UnmodifiableView
|
||||
Set<T> getAll();
|
||||
|
||||
boolean isFrozen();
|
||||
}
|
@ -1,14 +1,11 @@
|
||||
package dev.engine_room.flywheel.backend;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import dev.engine_room.flywheel.api.material.CutoutShader;
|
||||
import dev.engine_room.flywheel.api.material.FogShader;
|
||||
import dev.engine_room.flywheel.api.registry.Registry;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
@ -16,25 +13,17 @@ import it.unimi.dsi.fastutil.objects.ObjectList;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public final class MaterialShaderIndices {
|
||||
@Nullable
|
||||
private static Index fogSources;
|
||||
@Nullable
|
||||
private static Index cutoutSources;
|
||||
private static final Index fogSources = new Index();
|
||||
private static final Index cutoutSources = new Index();
|
||||
|
||||
private MaterialShaderIndices() {
|
||||
}
|
||||
|
||||
public static Index fogSources() {
|
||||
if (fogSources == null) {
|
||||
fogSources = indexFromRegistry(FogShader.REGISTRY, FogShader::source);
|
||||
}
|
||||
return fogSources;
|
||||
}
|
||||
|
||||
public static Index cutoutSources() {
|
||||
// if (cutoutSources == null) {
|
||||
// cutoutSources = indexFromRegistry(CutoutShader.REGISTRY, CutoutShader::source);
|
||||
// }
|
||||
return cutoutSources;
|
||||
}
|
||||
|
||||
@ -43,30 +32,23 @@ public final class MaterialShaderIndices {
|
||||
}
|
||||
|
||||
public static int cutoutIndex(CutoutShader cutoutShader) {
|
||||
return 0;//cutoutSources().index(cutoutShader.source());
|
||||
}
|
||||
|
||||
private static <T> Index indexFromRegistry(Registry<T> registry, Function<T, ResourceLocation> sourceFunc) {
|
||||
if (!registry.isFrozen()) {
|
||||
throw new IllegalStateException("Cannot create index from registry that is not frozen!");
|
||||
}
|
||||
|
||||
var builder = new IndexBuilder();
|
||||
|
||||
for (T object : registry) {
|
||||
builder.add(sourceFunc.apply(object));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
return cutoutSources().index(cutoutShader.source());
|
||||
}
|
||||
|
||||
public static class Index {
|
||||
private final Object2IntMap<ResourceLocation> sources2Index;
|
||||
private final ObjectList<ResourceLocation> sources;
|
||||
|
||||
private Index(IndexBuilder builder) {
|
||||
this.sources2Index = new Object2IntOpenHashMap<>(builder.sources2Index);
|
||||
this.sources = new ObjectArrayList<>(builder.sources);
|
||||
private Index() {
|
||||
this.sources2Index = new Object2IntOpenHashMap<>();
|
||||
sources2Index.defaultReturnValue(-1);
|
||||
this.sources = new ObjectArrayList<>();
|
||||
}
|
||||
|
||||
public void add(ResourceLocation source) {
|
||||
if (sources2Index.putIfAbsent(source, sources.size()) == -1) {
|
||||
sources.add(source);
|
||||
}
|
||||
}
|
||||
|
||||
public int index(ResourceLocation source) {
|
||||
@ -82,27 +64,4 @@ public final class MaterialShaderIndices {
|
||||
return sources;
|
||||
}
|
||||
}
|
||||
|
||||
private static class IndexBuilder {
|
||||
private final Object2IntMap<ResourceLocation> sources2Index;
|
||||
private final ObjectList<ResourceLocation> sources;
|
||||
private int index = 0;
|
||||
|
||||
public IndexBuilder() {
|
||||
sources2Index = new Object2IntOpenHashMap<>();
|
||||
sources2Index.defaultReturnValue(-1);
|
||||
sources = new ObjectArrayList<>();
|
||||
}
|
||||
|
||||
public void add(ResourceLocation source) {
|
||||
if (sources2Index.putIfAbsent(source, index) == -1) {
|
||||
sources.add(source);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
public Index build() {
|
||||
return new Index(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,19 +2,13 @@ package dev.engine_room.flywheel.backend.compile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import dev.engine_room.flywheel.api.Flywheel;
|
||||
import dev.engine_room.flywheel.backend.MaterialShaderIndices;
|
||||
import dev.engine_room.flywheel.backend.compile.component.UberShaderComponent;
|
||||
import dev.engine_room.flywheel.backend.compile.core.CompilerStats;
|
||||
import dev.engine_room.flywheel.backend.compile.core.SourceLoader;
|
||||
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
|
||||
import dev.engine_room.flywheel.backend.glsl.SourceComponent;
|
||||
import dev.engine_room.flywheel.backend.glsl.generate.FnSignature;
|
||||
import dev.engine_room.flywheel.backend.glsl.generate.GlslExpr;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
|
||||
@ -23,6 +17,8 @@ public final class FlwPrograms {
|
||||
|
||||
private static final ResourceLocation COMPONENTS_HEADER_FRAG = Flywheel.rl("internal/components_header.frag");
|
||||
|
||||
public static ShaderSources SOURCES;
|
||||
|
||||
private FlwPrograms() {
|
||||
}
|
||||
|
||||
@ -32,52 +28,22 @@ public final class FlwPrograms {
|
||||
IndirectPrograms.setInstance(null);
|
||||
|
||||
var sources = new ShaderSources(resourceManager);
|
||||
SOURCES = sources;
|
||||
var stats = new CompilerStats("ubershaders");
|
||||
var loader = new SourceLoader(sources, stats);
|
||||
|
||||
var fragmentComponentsHeader = loader.find(COMPONENTS_HEADER_FRAG);
|
||||
|
||||
var fogComponent = createFogComponent(loader);
|
||||
var fragmentComponentsHeader = sources.get(COMPONENTS_HEADER_FRAG);
|
||||
|
||||
// TODO: separate compilation for cutout OFF, but keep the rest uber'd?
|
||||
if (stats.errored() || fragmentComponentsHeader == null || fogComponent == null) {
|
||||
if (stats.errored() || fragmentComponentsHeader == null) {
|
||||
// Probably means the shader sources are missing.
|
||||
stats.emitErrorLog();
|
||||
return;
|
||||
}
|
||||
|
||||
List<SourceComponent> vertexComponents = List.of();
|
||||
List<SourceComponent> fragmentComponents = List.of(fragmentComponentsHeader, fogComponent);
|
||||
List<SourceComponent> fragmentComponents = List.of(fragmentComponentsHeader);
|
||||
|
||||
InstancingPrograms.reload(sources, vertexComponents, fragmentComponents);
|
||||
IndirectPrograms.reload(sources, vertexComponents, fragmentComponents);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static UberShaderComponent createFogComponent(SourceLoader loader) {
|
||||
return UberShaderComponent.builder(Flywheel.rl("fog"))
|
||||
.materialSources(MaterialShaderIndices.fogSources()
|
||||
.all())
|
||||
.adapt(FnSignature.create()
|
||||
.returnType("vec4")
|
||||
.name("flw_fogFilter")
|
||||
.arg("vec4", "color")
|
||||
.build(), GlslExpr.variable("color"))
|
||||
.switchOn(GlslExpr.variable("_flw_uberFogIndex"))
|
||||
.build(loader);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static UberShaderComponent createCutoutComponent(SourceLoader loader) {
|
||||
return UberShaderComponent.builder(Flywheel.rl("cutout"))
|
||||
.materialSources(MaterialShaderIndices.cutoutSources()
|
||||
.all())
|
||||
.adapt(FnSignature.create()
|
||||
.returnType("bool")
|
||||
.name("flw_discardPredicate")
|
||||
.arg("vec4", "color")
|
||||
.build(), GlslExpr.boolLiteral(false))
|
||||
.switchOn(GlslExpr.variable("_flw_uberCutoutIndex"))
|
||||
.build(loader);
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,8 @@ import com.google.common.collect.ImmutableList;
|
||||
|
||||
import dev.engine_room.flywheel.api.Flywheel;
|
||||
import dev.engine_room.flywheel.api.instance.InstanceType;
|
||||
import dev.engine_room.flywheel.api.material.CutoutShader;
|
||||
import dev.engine_room.flywheel.api.material.LightShader;
|
||||
import dev.engine_room.flywheel.api.material.MaterialShaders;
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.backend.MaterialShaderIndices;
|
||||
import dev.engine_room.flywheel.backend.compile.component.InstanceStructComponent;
|
||||
import dev.engine_room.flywheel.backend.compile.component.SsboInstanceComponent;
|
||||
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
|
||||
@ -151,7 +150,19 @@ public class IndirectPrograms extends AtomicReferenceCounted {
|
||||
setInstance(null);
|
||||
}
|
||||
|
||||
public GlProgram getIndirectProgram(InstanceType<?> instanceType, ContextShader contextShader, LightShader light, CutoutShader cutout, MaterialShaders shaders) {
|
||||
public GlProgram getIndirectProgram(InstanceType<?> instanceType, ContextShader contextShader, Material material) {
|
||||
var light = material.light();
|
||||
var cutout = material.cutout();
|
||||
var shaders = material.shaders();
|
||||
var fog = material.fog();
|
||||
|
||||
var fogIndex = MaterialShaderIndices.fogSources();
|
||||
if (fogIndex.index(fog.source()) == -1) {
|
||||
fogIndex.add(fog.source());
|
||||
pipeline.delete();
|
||||
PipelineCompiler.createFogComponent();
|
||||
}
|
||||
|
||||
return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light, cutout, shaders, FrameUniforms.debugOn()));
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import dev.engine_room.flywheel.api.instance.InstanceType;
|
||||
import dev.engine_room.flywheel.api.material.CutoutShader;
|
||||
import dev.engine_room.flywheel.api.material.LightShader;
|
||||
import dev.engine_room.flywheel.api.material.MaterialShaders;
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.backend.MaterialShaderIndices;
|
||||
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
|
||||
import dev.engine_room.flywheel.backend.engine.uniform.FrameUniforms;
|
||||
import dev.engine_room.flywheel.backend.gl.GlCompat;
|
||||
@ -74,7 +73,20 @@ public class InstancingPrograms extends AtomicReferenceCounted {
|
||||
setInstance(null);
|
||||
}
|
||||
|
||||
public GlProgram get(InstanceType<?> instanceType, ContextShader contextShader, LightShader light, CutoutShader cutout, MaterialShaders materialShaders) {
|
||||
public GlProgram get(InstanceType<?> instanceType, ContextShader contextShader, Material material) {
|
||||
var light = material.light();
|
||||
var cutout = material.cutout();
|
||||
var materialShaders = material.shaders();
|
||||
|
||||
var fog = material.fog();
|
||||
|
||||
var fogIndex = MaterialShaderIndices.fogSources();
|
||||
if (fogIndex.index(fog.source()) == -1) {
|
||||
fogIndex.add(fog.source());
|
||||
pipeline.delete();
|
||||
PipelineCompiler.createFogComponent();
|
||||
}
|
||||
|
||||
return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light, cutout, materialShaders, FrameUniforms.debugOn()));
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,10 @@ import java.util.List;
|
||||
import dev.engine_room.flywheel.api.Flywheel;
|
||||
import dev.engine_room.flywheel.backend.BackendConfig;
|
||||
import dev.engine_room.flywheel.backend.InternalVertex;
|
||||
import dev.engine_room.flywheel.backend.MaterialShaderIndices;
|
||||
import dev.engine_room.flywheel.backend.Samplers;
|
||||
import dev.engine_room.flywheel.backend.compile.component.InstanceStructComponent;
|
||||
import dev.engine_room.flywheel.backend.compile.component.UberShaderComponent;
|
||||
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
|
||||
import dev.engine_room.flywheel.backend.compile.core.Compile;
|
||||
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
|
||||
@ -16,6 +18,8 @@ import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
|
||||
import dev.engine_room.flywheel.backend.gl.shader.ShaderType;
|
||||
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
|
||||
import dev.engine_room.flywheel.backend.glsl.SourceComponent;
|
||||
import dev.engine_room.flywheel.backend.glsl.generate.FnSignature;
|
||||
import dev.engine_room.flywheel.backend.glsl.generate.GlslExpr;
|
||||
import dev.engine_room.flywheel.lib.material.CutoutShaders;
|
||||
import dev.engine_room.flywheel.lib.util.ResourceUtil;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
@ -23,6 +27,9 @@ import net.minecraft.resources.ResourceLocation;
|
||||
public final class PipelineCompiler {
|
||||
private static final Compile<PipelineProgramKey> PIPELINE = new Compile<>();
|
||||
|
||||
private static UberShaderComponent FOG;
|
||||
private static UberShaderComponent CUTOUT;
|
||||
|
||||
private static final ResourceLocation API_IMPL_VERT = Flywheel.rl("internal/api_impl.vert");
|
||||
private static final ResourceLocation API_IMPL_FRAG = Flywheel.rl("internal/api_impl.frag");
|
||||
|
||||
@ -98,6 +105,7 @@ public final class PipelineCompiler {
|
||||
.withResource(key -> key.materialShaders()
|
||||
.fragmentSource())
|
||||
.withComponents(fragmentComponents)
|
||||
.withComponent(key -> FOG)
|
||||
.withResource(key -> key.light()
|
||||
.source())
|
||||
.withResource(key -> key.cutout()
|
||||
@ -128,4 +136,30 @@ public final class PipelineCompiler {
|
||||
})
|
||||
.harness(pipeline.compilerMarker(), sources);
|
||||
}
|
||||
|
||||
public static void createFogComponent() {
|
||||
FOG = UberShaderComponent.builder(Flywheel.rl("fog"))
|
||||
.materialSources(MaterialShaderIndices.fogSources()
|
||||
.all())
|
||||
.adapt(FnSignature.create()
|
||||
.returnType("vec4")
|
||||
.name("flw_fogFilter")
|
||||
.arg("vec4", "color")
|
||||
.build(), GlslExpr.variable("color"))
|
||||
.switchOn(GlslExpr.variable("_flw_uberFogIndex"))
|
||||
.build(FlwPrograms.SOURCES);
|
||||
}
|
||||
|
||||
private static void createCutoutComponent() {
|
||||
CUTOUT = UberShaderComponent.builder(Flywheel.rl("cutout"))
|
||||
.materialSources(MaterialShaderIndices.cutoutSources()
|
||||
.all())
|
||||
.adapt(FnSignature.create()
|
||||
.returnType("bool")
|
||||
.name("flw_discardPredicate")
|
||||
.arg("vec4", "color")
|
||||
.build(), GlslExpr.boolLiteral(false))
|
||||
.switchOn(GlslExpr.variable("_flw_uberCutoutIndex"))
|
||||
.build(FlwPrograms.SOURCES);
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import dev.engine_room.flywheel.api.Flywheel;
|
||||
import dev.engine_room.flywheel.backend.compile.core.SourceLoader;
|
||||
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
|
||||
import dev.engine_room.flywheel.backend.glsl.SourceComponent;
|
||||
import dev.engine_room.flywheel.backend.glsl.SourceFile;
|
||||
import dev.engine_room.flywheel.backend.glsl.generate.FnSignature;
|
||||
@ -137,7 +137,7 @@ public class UberShaderComponent implements SourceComponent {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public UberShaderComponent build(SourceLoader sources) {
|
||||
public UberShaderComponent build(ShaderSources sources) {
|
||||
if (switchArg == null) {
|
||||
throw new NullPointerException("Switch argument must be set");
|
||||
}
|
||||
@ -147,7 +147,7 @@ public class UberShaderComponent implements SourceComponent {
|
||||
boolean errored = false;
|
||||
int index = 0;
|
||||
for (var rl : materialSources) {
|
||||
SourceFile sourceFile = sources.find(rl);
|
||||
SourceFile sourceFile = sources.get(rl);
|
||||
if (sourceFile != null) {
|
||||
final int finalIndex = index;
|
||||
var adapterMap = createAdapterMap(adaptedFunctions, fnName -> "_" + fnName + "_" + finalIndex);
|
||||
|
@ -5,12 +5,13 @@ import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import dev.engine_room.flywheel.backend.gl.GlObject;
|
||||
import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
|
||||
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
|
||||
|
||||
public class CompilationHarness<K> {
|
||||
private final ShaderSources sources;
|
||||
private final KeyCompiler<K> compiler;
|
||||
private final SourceLoader sourceLoader;
|
||||
private final ShaderCache shaderCache;
|
||||
private final ProgramLinker programLinker;
|
||||
private final CompilerStats stats;
|
||||
@ -18,9 +19,9 @@ public class CompilationHarness<K> {
|
||||
private final Map<K, GlProgram> programs = new HashMap<>();
|
||||
|
||||
public CompilationHarness(String marker, ShaderSources sources, KeyCompiler<K> compiler) {
|
||||
this.sources = sources;
|
||||
this.compiler = compiler;
|
||||
stats = new CompilerStats(marker);
|
||||
sourceLoader = new SourceLoader(sources, stats);
|
||||
shaderCache = new ShaderCache(stats);
|
||||
programLinker = new ProgramLinker(stats);
|
||||
}
|
||||
@ -30,7 +31,7 @@ public class CompilationHarness<K> {
|
||||
}
|
||||
|
||||
private GlProgram compile(K key) {
|
||||
var out = compiler.compile(key, sourceLoader, shaderCache, programLinker);
|
||||
var out = compiler.compile(key, sources, shaderCache, programLinker);
|
||||
|
||||
if (out == null) {
|
||||
// TODO: populate exception with error details
|
||||
@ -43,12 +44,13 @@ public class CompilationHarness<K> {
|
||||
public void delete() {
|
||||
shaderCache.delete();
|
||||
|
||||
for (var program : programs.values()) {
|
||||
program.delete();
|
||||
}
|
||||
programs.values()
|
||||
.forEach(GlObject::delete);
|
||||
|
||||
programs.clear();
|
||||
}
|
||||
|
||||
public interface KeyCompiler<K> {
|
||||
@Nullable GlProgram compile(K key, SourceLoader loader, ShaderCache shaderCache, ProgramLinker programLinker);
|
||||
@Nullable GlProgram compile(K key, ShaderSources loader, ShaderCache shaderCache, ProgramLinker programLinker);
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public class Compile<K> {
|
||||
public static class ShaderCompiler<K> {
|
||||
private final GlslVersion glslVersion;
|
||||
private final ShaderType shaderType;
|
||||
private final List<BiFunction<K, SourceLoader, @Nullable SourceComponent>> fetchers = new ArrayList<>();
|
||||
private final List<BiFunction<K, ShaderSources, @Nullable SourceComponent>> fetchers = new ArrayList<>();
|
||||
private BiConsumer<K, Compilation> compilationCallbacks = ($, $$) -> {
|
||||
};
|
||||
private Function<K, String> nameMapper = Object::toString;
|
||||
@ -59,7 +59,7 @@ public class Compile<K> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ShaderCompiler<K> with(BiFunction<K, SourceLoader, @Nullable SourceComponent> fetch) {
|
||||
public ShaderCompiler<K> with(BiFunction<K, ShaderSources, @Nullable SourceComponent> fetch) {
|
||||
fetchers.add(fetch);
|
||||
return this;
|
||||
}
|
||||
@ -78,7 +78,7 @@ public class Compile<K> {
|
||||
}
|
||||
|
||||
public ShaderCompiler<K> withResource(Function<K, ResourceLocation> sourceFetcher) {
|
||||
return with((key, loader) -> loader.find(sourceFetcher.apply(key)));
|
||||
return with((key, loader) -> loader.get(sourceFetcher.apply(key)));
|
||||
}
|
||||
|
||||
public ShaderCompiler<K> withResource(ResourceLocation resourceLocation) {
|
||||
@ -123,7 +123,7 @@ public class Compile<K> {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private GlShader compile(K key, ShaderCache compiler, SourceLoader loader) {
|
||||
private GlShader compile(K key, ShaderCache compiler, ShaderSources loader) {
|
||||
long start = System.nanoTime();
|
||||
|
||||
var components = new ArrayList<SourceComponent>();
|
||||
@ -183,7 +183,7 @@ public class Compile<K> {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public GlProgram compile(K key, SourceLoader loader, ShaderCache shaderCache, ProgramLinker programLinker) {
|
||||
public GlProgram compile(K key, ShaderSources loader, ShaderCache shaderCache, ProgramLinker programLinker) {
|
||||
if (compilers.isEmpty()) {
|
||||
throw new IllegalStateException("No shader compilers were added!");
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ public class ShaderCache {
|
||||
.map(ShaderResult::unwrap)
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(GlShader::delete);
|
||||
inner.clear();
|
||||
}
|
||||
|
||||
private static void expand(List<SourceComponent> rootSources, Consumer<SourceComponent> out) {
|
||||
|
@ -1,24 +0,0 @@
|
||||
package dev.engine_room.flywheel.backend.compile.core;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import dev.engine_room.flywheel.backend.glsl.ShaderSources;
|
||||
import dev.engine_room.flywheel.backend.glsl.SourceFile;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class SourceLoader {
|
||||
private final ShaderSources sources;
|
||||
private final CompilerStats stats;
|
||||
|
||||
public SourceLoader(ShaderSources sources, CompilerStats stats) {
|
||||
this.sources = sources;
|
||||
this.stats = stats;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public SourceFile find(ResourceLocation location) {
|
||||
var out = sources.find(location);
|
||||
stats.loadResult(out);
|
||||
return out.unwrap();
|
||||
}
|
||||
}
|
@ -202,7 +202,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||
int baseDrawUniformLoc = -1;
|
||||
|
||||
for (var multiDraw : multiDraws.get(visualType)) {
|
||||
var drawProgram = programs.getIndirectProgram(instanceType, multiDraw.embedded ? ContextShader.EMBEDDED : ContextShader.DEFAULT, multiDraw.material.light(), multiDraw.material.cutout(), multiDraw.material.shaders());
|
||||
var drawProgram = programs.getIndirectProgram(instanceType, multiDraw.embedded ? ContextShader.EMBEDDED : ContextShader.DEFAULT, multiDraw.material);
|
||||
if (drawProgram != lastProgram) {
|
||||
lastProgram = drawProgram;
|
||||
|
||||
@ -220,7 +220,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||
}
|
||||
|
||||
public void bindWithContextShader(ContextShader override, Material material) {
|
||||
var program = programs.getIndirectProgram(instanceType, override, material.light(), material.cutout(), material.shaders());
|
||||
var program = programs.getIndirectProgram(instanceType, override, material);
|
||||
|
||||
program.bind();
|
||||
|
||||
|
@ -174,7 +174,7 @@ public class InstancedDrawManager extends DrawManager<InstancedInstancer<?>> {
|
||||
|
||||
for (InstancedDraw draw : instancer.draws()) {
|
||||
CommonCrumbling.applyCrumblingProperties(crumblingMaterial, draw.material());
|
||||
var program = programs.get(shader.instanceType(), ContextShader.CRUMBLING, crumblingMaterial.light(), crumblingMaterial.cutout(), crumblingMaterial.shaders());
|
||||
var program = programs.get(shader.instanceType(), ContextShader.CRUMBLING, crumblingMaterial);
|
||||
program.bind();
|
||||
program.setInt("_flw_baseInstance", index);
|
||||
uploadMaterialUniform(program, crumblingMaterial);
|
||||
|
@ -57,7 +57,7 @@ public class InstancedRenderStage {
|
||||
for (var drawCall : drawCalls.draws) {
|
||||
var material = drawCall.material();
|
||||
|
||||
var program = programs.get(shader.instanceType(), environment.contextShader(), material.light(), material.cutout(), material.shaders());
|
||||
var program = programs.get(shader.instanceType(), environment.contextShader(), material);
|
||||
program.bind();
|
||||
|
||||
environment.setupDraw(program);
|
||||
|
@ -9,6 +9,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.VisibleForTesting;
|
||||
|
||||
import dev.engine_room.flywheel.backend.compile.FlwPrograms;
|
||||
@ -49,6 +50,11 @@ public class ShaderSources {
|
||||
return cache.computeIfAbsent(location, loc -> new LoadResult.Failure(new LoadError.ResourceError(loc)));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public SourceFile get(ResourceLocation location) {
|
||||
return find(location).unwrap();
|
||||
}
|
||||
|
||||
private static boolean isShader(ResourceLocation loc) {
|
||||
var path = loc.getPath();
|
||||
return path.endsWith(".glsl") || path.endsWith(".vert") || path.endsWith(".frag") || path.endsWith(".comp");
|
||||
|
@ -1,19 +1,13 @@
|
||||
package dev.engine_room.flywheel.lib.material;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import dev.engine_room.flywheel.api.Flywheel;
|
||||
import dev.engine_room.flywheel.api.material.FogShader;
|
||||
|
||||
public final class FogShaders {
|
||||
public static final FogShader NONE = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/none.glsl")));
|
||||
public static final FogShader LINEAR = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/linear.glsl")));
|
||||
public static final FogShader LINEAR_FADE = FogShader.REGISTRY.registerAndGet(new SimpleFogShader(Flywheel.rl("fog/linear_fade.glsl")));
|
||||
public static final FogShader NONE = new SimpleFogShader(Flywheel.rl("fog/none.glsl"));
|
||||
public static final FogShader LINEAR = new SimpleFogShader(Flywheel.rl("fog/linear.glsl"));
|
||||
public static final FogShader LINEAR_FADE = new SimpleFogShader(Flywheel.rl("fog/linear_fade.glsl"));
|
||||
|
||||
private FogShaders() {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void init() {
|
||||
}
|
||||
}
|
||||
|
@ -6,13 +6,11 @@ import dev.engine_room.flywheel.api.backend.Backend;
|
||||
import dev.engine_room.flywheel.api.internal.FlwApiLink;
|
||||
import dev.engine_room.flywheel.api.layout.LayoutBuilder;
|
||||
import dev.engine_room.flywheel.api.registry.IdRegistry;
|
||||
import dev.engine_room.flywheel.api.registry.Registry;
|
||||
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
|
||||
import dev.engine_room.flywheel.api.visualization.EntityVisualizer;
|
||||
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
|
||||
import dev.engine_room.flywheel.impl.layout.LayoutBuilderImpl;
|
||||
import dev.engine_room.flywheel.impl.registry.IdRegistryImpl;
|
||||
import dev.engine_room.flywheel.impl.registry.RegistryImpl;
|
||||
import dev.engine_room.flywheel.impl.visualization.VisualizationManagerImpl;
|
||||
import dev.engine_room.flywheel.impl.visualization.VisualizerRegistryImpl;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
@ -22,11 +20,6 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
public class FlwApiLinkImpl implements FlwApiLink {
|
||||
@Override
|
||||
public <T> Registry<T> createRegistry() {
|
||||
return new RegistryImpl<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> IdRegistry<T> createIdRegistry() {
|
||||
return new IdRegistryImpl<>();
|
||||
|
@ -6,8 +6,6 @@ import org.slf4j.LoggerFactory;
|
||||
import dev.engine_room.flywheel.api.Flywheel;
|
||||
import dev.engine_room.flywheel.backend.FlwBackend;
|
||||
import dev.engine_room.flywheel.impl.registry.IdRegistryImpl;
|
||||
import dev.engine_room.flywheel.impl.registry.RegistryImpl;
|
||||
import dev.engine_room.flywheel.lib.material.FogShaders;
|
||||
import dev.engine_room.flywheel.lib.util.ShadersModHandler;
|
||||
import dev.engine_room.flywheel.vanilla.VanillaVisuals;
|
||||
|
||||
@ -24,7 +22,6 @@ public final class FlwImpl {
|
||||
|
||||
// lib
|
||||
ShadersModHandler.init();
|
||||
FogShaders.init();
|
||||
|
||||
// backend
|
||||
FlwBackend.init(FlwConfig.INSTANCE.backendConfig());
|
||||
@ -34,7 +31,6 @@ public final class FlwImpl {
|
||||
}
|
||||
|
||||
public static void freezeRegistries() {
|
||||
RegistryImpl.freezeAll();
|
||||
IdRegistryImpl.freezeAll();
|
||||
}
|
||||
}
|
||||
|
@ -1,68 +0,0 @@
|
||||
package dev.engine_room.flywheel.impl.registry;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.UnmodifiableView;
|
||||
|
||||
import dev.engine_room.flywheel.api.registry.Registry;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectSets;
|
||||
|
||||
public class RegistryImpl<T> implements Registry<T> {
|
||||
private static final ObjectList<RegistryImpl<?>> ALL = new ObjectArrayList<>();
|
||||
|
||||
private final ObjectSet<T> set = ObjectSets.synchronize(new ObjectOpenHashSet<>());
|
||||
private final ObjectSet<T> setView = ObjectSets.unmodifiable(set);
|
||||
private boolean frozen;
|
||||
|
||||
public RegistryImpl() {
|
||||
ALL.add(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(T object) {
|
||||
if (frozen) {
|
||||
throw new IllegalStateException("Cannot register to frozen registry!");
|
||||
}
|
||||
boolean added = set.add(object);
|
||||
if (!added) {
|
||||
throw new IllegalArgumentException("Cannot override registration!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S extends T> S registerAndGet(S object) {
|
||||
register(object);
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
@UnmodifiableView
|
||||
public Set<T> getAll() {
|
||||
return setView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFrozen() {
|
||||
return frozen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return getAll().iterator();
|
||||
}
|
||||
|
||||
private void freeze() {
|
||||
frozen = true;
|
||||
}
|
||||
|
||||
public static void freezeAll() {
|
||||
for (RegistryImpl<?> registry : ALL) {
|
||||
registry.freeze();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user