Organize and improve compiler code

- Ensure current backend is never null
- Fix StringUtil#countLines
- Use material index instead of file location when adapting material
shader function name
- Merge Includer and Compilation factory into ShaderCompiler and remove
builder
- Remove CompileUtil
- Remove Index
- Remove unnecessary code from ShaderSources
- Move source component classes to backend.compile.component
- Move core compilation classes to backend.compile.core
- Move pipeline classes to backend.compile
- Move GLSLVersion to glsl package
- Move SourceChecks to backend.compile
This commit is contained in:
PepperCode1 2023-04-20 12:22:51 -07:00
parent 0adb742ef6
commit 167d417a98
35 changed files with 188 additions and 382 deletions

View File

@ -5,7 +5,7 @@ import org.slf4j.Logger;
import com.jozufozu.flywheel.backend.Backends;
import com.jozufozu.flywheel.backend.Loader;
import com.jozufozu.flywheel.backend.compile.pipeline.Pipelines;
import com.jozufozu.flywheel.backend.compile.Pipelines;
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
import com.jozufozu.flywheel.backend.engine.batching.DrawBuffer;
import com.jozufozu.flywheel.config.BackendArgument;

View File

@ -1,14 +1,11 @@
package com.jozufozu.flywheel.api.backend;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.impl.BackendManagerImpl;
public final class BackendManager {
/**
* Get the current backend.
*/
@Nullable
public static Backend getBackend() {
return BackendManagerImpl.getBackend();
}

View File

@ -7,6 +7,9 @@ import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList;
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.gl.shader.GlProgram;
import com.jozufozu.flywheel.glsl.ShaderSources;
@ -21,8 +24,7 @@ public abstract class AbstractCompiler<K> {
this.sources = sources;
this.keys = keys;
shaderCompiler = ShaderCompiler.builder()
.build(stats);
shaderCompiler = new ShaderCompiler(stats);
programLinker = new ProgramLinker(stats);
}

View File

@ -1,60 +0,0 @@
package com.jozufozu.flywheel.backend.compile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jetbrains.annotations.NotNull;
import com.jozufozu.flywheel.gl.GLSLVersion;
import com.jozufozu.flywheel.gl.shader.ShaderType;
import com.jozufozu.flywheel.glsl.SourceFile;
public class CompileUtil {
public static final Pattern vecType = Pattern.compile("^[biud]?vec([234])$");
public static final Pattern matType = Pattern.compile("^mat([234])(?:x([234]))?$");
public static String generateHeader(GLSLVersion version, ShaderType type) {
return version.getVersionLine() + type.getDefineStatement();
}
public static int getElementCount(String type) {
Matcher vec = vecType.matcher(type);
if (vec.find()) {
return Integer.parseInt(vec.group(1));
}
Matcher mat = matType.matcher(type);
if (mat.find()) {
int n = Integer.parseInt(mat.group(1));
String m = mat.group(2);
if (m != null) {
return Integer.parseInt(m) * n;
}
return n;
}
return 1;
}
public static int getAttributeCount(CharSequence type) {
Matcher mat = matType.matcher(type);
if (mat.find()) {
return Integer.parseInt(mat.group(1));
}
return 1;
}
@NotNull
public static String generateDebugName(SourceFile... stages) {
return Stream.of(stages)
.map(SourceFile::toString)
.collect(Collectors.joining(" -> "));
}
}

View File

@ -5,10 +5,11 @@ import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.backend.engine.indirect.IndirectComponent;
import com.jozufozu.flywheel.gl.GLSLVersion;
import com.jozufozu.flywheel.backend.compile.component.IndirectComponent;
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
import com.jozufozu.flywheel.gl.shader.GlProgram;
import com.jozufozu.flywheel.gl.shader.ShaderType;
import com.jozufozu.flywheel.glsl.GLSLVersion;
import com.jozufozu.flywheel.glsl.ShaderSources;
import com.jozufozu.flywheel.glsl.SourceComponent;
import com.jozufozu.flywheel.glsl.SourceFile;

View File

@ -5,8 +5,8 @@ import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
import com.jozufozu.flywheel.glsl.ShaderSources;
import com.jozufozu.flywheel.glsl.error.ErrorReporter;
import com.jozufozu.flywheel.lib.context.Contexts;
import net.minecraft.server.packs.resources.ResourceManager;
@ -16,9 +16,7 @@ public class FlwPrograms {
}
public static void reload(ResourceManager resourceManager) {
var errorReporter = new ErrorReporter();
var sources = new ShaderSources(errorReporter, resourceManager);
var sources = new ShaderSources(resourceManager);
var pipelineKeys = createPipelineKeys();
var uniformComponent = UniformComponent.builder(Flywheel.rl("uniforms"))
.sources(ShaderUniforms.REGISTRY.getAll()

View File

@ -1,21 +0,0 @@
package com.jozufozu.flywheel.backend.compile;
import java.util.function.Consumer;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.glsl.SourceComponent;
/**
* A component of a ShaderCompiler, responsible for expanding root sources into the complete set of included sources.
*/
public interface Includer {
/**
* Expand the given root sources into the complete set of included sources.
* <p> Each unique source will be seen exactly once.
*
* @param rootSources The root sources to expand.
* @param out A consumer to which all sources should be passed in the order they should be included.
*/
void expand(ImmutableList<SourceComponent> rootSources, Consumer<SourceComponent> out);
}

View File

@ -8,7 +8,7 @@ import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.compile.pipeline.Pipelines;
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
import com.jozufozu.flywheel.gl.shader.GlProgram;
import com.jozufozu.flywheel.glsl.ShaderSources;

View File

@ -8,7 +8,7 @@ import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.compile.pipeline.Pipelines;
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
import com.jozufozu.flywheel.gl.shader.GlProgram;
import com.jozufozu.flywheel.glsl.ShaderSources;

View File

@ -1,8 +1,8 @@
package com.jozufozu.flywheel.backend.compile.pipeline;
package com.jozufozu.flywheel.backend.compile;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.gl.GLSLVersion;
import com.jozufozu.flywheel.glsl.GLSLVersion;
import com.jozufozu.flywheel.glsl.ShaderSources;
import com.jozufozu.flywheel.glsl.SourceComponent;

View File

@ -4,7 +4,8 @@ import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.compile.pipeline.Pipeline;
import com.jozufozu.flywheel.backend.compile.component.MaterialAdapterComponent;
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
import com.jozufozu.flywheel.gl.shader.GlProgram;
import com.jozufozu.flywheel.gl.shader.ShaderType;
import com.jozufozu.flywheel.glsl.ShaderSources;

View File

@ -1,11 +1,9 @@
package com.jozufozu.flywheel.backend.compile.pipeline;
import java.util.List;
package com.jozufozu.flywheel.backend.compile;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.engine.indirect.IndirectComponent;
import com.jozufozu.flywheel.backend.engine.instancing.InstancedArraysComponent;
import com.jozufozu.flywheel.gl.GLSLVersion;
import com.jozufozu.flywheel.backend.compile.component.IndirectComponent;
import com.jozufozu.flywheel.backend.compile.component.InstancedArraysComponent;
import com.jozufozu.flywheel.glsl.GLSLVersion;
import net.minecraft.resources.ResourceLocation;
@ -23,8 +21,6 @@ public final class Pipelines {
.assembler(IndirectComponent::new)
.build();
public static final List<Pipeline> ALL = List.of(INSTANCED_ARRAYS, INDIRECT);
public static void init() {
}

View File

@ -1,33 +0,0 @@
package com.jozufozu.flywheel.backend.compile;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Consumer;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.glsl.SourceComponent;
public class RecursiveIncluder implements Includer {
public static final RecursiveIncluder INSTANCE = new RecursiveIncluder();
private RecursiveIncluder() {
}
@Override
public void expand(ImmutableList<SourceComponent> rootSources, Consumer<SourceComponent> out) {
var included = new LinkedHashSet<SourceComponent>(); // use hash set to deduplicate. linked to preserve order
for (var component : rootSources) {
recursiveDepthFirstInclude(included, component);
included.add(component);
}
included.forEach(out);
}
private static void recursiveDepthFirstInclude(Set<SourceComponent> included, SourceComponent component) {
for (var include : component.included()) {
recursiveDepthFirstInclude(included, include);
}
included.addAll(component.included());
}
}

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.glsl;
package com.jozufozu.flywheel.backend.compile;
import java.util.Optional;
import java.util.function.BiConsumer;
@ -6,14 +6,13 @@ import java.util.function.BiConsumer;
import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.glsl.SourceFile;
import com.jozufozu.flywheel.glsl.error.ErrorReporter;
import com.jozufozu.flywheel.glsl.parse.ShaderFunction;
import com.jozufozu.flywheel.glsl.parse.ShaderVariable;
// TODO: recycle to be invoked by the shader compiler
public class SourceChecks {
// TODO: recycle to be invoked by the shader compiler
public static final BiConsumer<ErrorReporter, SourceFile> LAYOUT_VERTEX = checkFunctionArity("flw_layoutVertex", 0);
public static final BiConsumer<ErrorReporter, SourceFile> INSTANCE_VERTEX = checkFunctionParameterTypeExists("flw_instanceVertex", 1, 0);
public static final BiConsumer<ErrorReporter, SourceFile> MATERIAL_VERTEX = checkFunctionArity("flw_materialVertex", 0);
@ -22,7 +21,6 @@ public class SourceChecks {
public static final BiConsumer<ErrorReporter, SourceFile> CONTEXT_FRAGMENT = checkFunctionArity("flw_contextFragment", 0).andThen(checkFunctionArity("flw_initFragment", 0));
public static final BiConsumer<ErrorReporter, SourceFile> PIPELINE = checkFunctionArity("main", 0);
public static BiConsumer<ErrorReporter, SourceFile> checkFunctionArity(String name, int arity) {
return (errorReporter, file) -> checkFunctionArity(errorReporter, file, name, arity);
}

View File

@ -1,78 +0,0 @@
package com.jozufozu.flywheel.backend.compile;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.glsl.ShaderSources;
import com.jozufozu.flywheel.glsl.SourceComponent;
import com.jozufozu.flywheel.glsl.SourceFile;
import com.jozufozu.flywheel.glsl.generate.GlslBuilder;
import net.minecraft.resources.ResourceLocation;
public class UniformComponent implements SourceComponent {
private final ResourceLocation name;
private final ImmutableList<SourceFile> uniformShaders;
public static Builder builder(ResourceLocation uniforms) {
return new Builder(uniforms);
}
private UniformComponent(ResourceLocation name, ImmutableList<SourceFile> uniformShaders) {
this.name = name;
this.uniformShaders = uniformShaders;
}
@Override
public Collection<? extends SourceComponent> included() {
return uniformShaders;
}
@Override
public String source() {
var builder = new GlslBuilder();
builder.uniformBlock()
.layout("std140")
.binding(0)
.name("FLWUniforms")
.member("flywheel_uniforms", "flywheel");
builder.blankLine();
return builder.build();
}
@Override
public ResourceLocation name() {
return name;
}
public static class Builder {
private final ResourceLocation name;
private final List<ResourceLocation> uniformShaders = new ArrayList<>();
public Builder(ResourceLocation name) {
this.name = name;
}
public Builder sources(List<ResourceLocation> sources) {
this.uniformShaders.addAll(sources);
return this;
}
public UniformComponent build(ShaderSources sources) {
var out = ImmutableList.<SourceFile>builder();
for (var fileResolution : uniformShaders) {
out.add(sources.find(fileResolution));
}
return new UniformComponent(name, out.build());
}
}
}

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.backend.engine.indirect;
package com.jozufozu.flywheel.backend.compile.component;
import java.util.Collection;
import java.util.List;
@ -7,8 +7,8 @@ import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.layout.LayoutItem;
import com.jozufozu.flywheel.backend.compile.pipeline.Pipeline;
import com.jozufozu.flywheel.backend.compile.pipeline.Pipelines;
import com.jozufozu.flywheel.backend.compile.Pipeline;
import com.jozufozu.flywheel.backend.compile.Pipelines;
import com.jozufozu.flywheel.glsl.ShaderSources;
import com.jozufozu.flywheel.glsl.SourceComponent;
import com.jozufozu.flywheel.glsl.SourceFile;
@ -20,11 +20,11 @@ import com.jozufozu.flywheel.glsl.generate.GlslExpr;
import net.minecraft.resources.ResourceLocation;
public class IndirectComponent implements SourceComponent {
private static final String UNPACK_ARG = "p";
private static final GlslExpr.Variable UNPACKING_VARIABLE = GlslExpr.variable(UNPACK_ARG);
private static final String STRUCT_NAME = "IndirectStruct";
private static final String PACKED_STRUCT_NAME = STRUCT_NAME + "_packed";
private static final String STRUCT_NAME = "FlwInstance";
private static final String PACKED_STRUCT_NAME = "FlwPackedInstance";
private static final String UNPACK_FN_NAME = "_flw_unpackInstance";
private final List<LayoutItem> layoutItems;
private final ImmutableList<SourceFile> included;
@ -55,15 +55,12 @@ public class IndirectComponent implements SourceComponent {
public String generateIndirect() {
var builder = new GlslBuilder();
builder.define("FlwInstance", STRUCT_NAME);
builder.define("FlwPackedInstance", PACKED_STRUCT_NAME);
builder.blankLine();
var packed = builder.struct();
builder.blankLine();
var instance = builder.struct();
packed.setName(PACKED_STRUCT_NAME);
instance.setName(STRUCT_NAME);
builder.blankLine();
var packed = builder.struct();
packed.setName(PACKED_STRUCT_NAME);
for (var field : layoutItems) {
field.addPackedToStruct(packed);
@ -75,7 +72,7 @@ public class IndirectComponent implements SourceComponent {
builder.function()
.signature(FnSignature.create()
.returnType(STRUCT_NAME)
.name("_flw_unpackInstance")
.name(UNPACK_FN_NAME)
.arg(PACKED_STRUCT_NAME, UNPACK_ARG)
.build())
.body(this::generateUnpackingBody);

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.backend.engine.instancing;
package com.jozufozu.flywheel.backend.compile.component;
import java.util.Collection;
import java.util.Collections;
@ -6,7 +6,7 @@ import java.util.List;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.layout.LayoutItem;
import com.jozufozu.flywheel.backend.compile.pipeline.Pipeline;
import com.jozufozu.flywheel.backend.compile.Pipeline;
import com.jozufozu.flywheel.glsl.SourceComponent;
import com.jozufozu.flywheel.glsl.generate.FnSignature;
import com.jozufozu.flywheel.glsl.generate.GlslBlock;
@ -17,7 +17,8 @@ import net.minecraft.resources.ResourceLocation;
public class InstancedArraysComponent implements SourceComponent {
private static final String ATTRIBUTE_PREFIX = "_flw_i_";
private static final String STRUCT_NAME = "Instance";
private static final String STRUCT_NAME = "FlwInstance";
private static final String UNPACK_FN_NAME = "_flw_unpackInstance";
private final List<LayoutItem> layoutItems;
private final int baseIndex;
@ -43,9 +44,6 @@ public class InstancedArraysComponent implements SourceComponent {
@Override
public String source() {
var builder = new GlslBuilder();
builder.define("FlwInstance", STRUCT_NAME);
builder.blankLine();
int i = baseIndex;
for (var field : layoutItems) {
@ -72,7 +70,7 @@ public class InstancedArraysComponent implements SourceComponent {
// unpacking function
builder.function()
.signature(FnSignature.of(STRUCT_NAME, "_flw_unpackInstance"))
.signature(FnSignature.of(STRUCT_NAME, UNPACK_FN_NAME))
.body(this::generateUnpackingBody);
builder.blankLine();

View File

@ -1,16 +1,16 @@
package com.jozufozu.flywheel.backend.compile;
package com.jozufozu.flywheel.backend.compile.component;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.function.UnaryOperator;
import javax.annotation.Nonnull;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.jozufozu.flywheel.glsl.ShaderSources;
import com.jozufozu.flywheel.glsl.SourceComponent;
import com.jozufozu.flywheel.glsl.generate.FnSignature;
@ -18,12 +18,10 @@ import com.jozufozu.flywheel.glsl.generate.GlslBlock;
import com.jozufozu.flywheel.glsl.generate.GlslBuilder;
import com.jozufozu.flywheel.glsl.generate.GlslExpr;
import com.jozufozu.flywheel.glsl.generate.GlslSwitch;
import com.jozufozu.flywheel.util.ResourceUtil;
import net.minecraft.resources.ResourceLocation;
public class MaterialAdapterComponent implements SourceComponent {
// TODO: material id handling in pipeline shader
private final ResourceLocation name;
private final GlslExpr switchArg;
@ -59,9 +57,9 @@ public class MaterialAdapterComponent implements SourceComponent {
builder.function()
.signature(adaptedFunction.signature())
.body(body -> generateAdapter(body, adaptedFunction));
}
builder.blankLine();
builder.blankLine();
}
return builder.build();
}
@ -145,31 +143,28 @@ public class MaterialAdapterComponent implements SourceComponent {
var transformed = ImmutableList.<StringSubstitutionSourceComponent>builder();
int index = 0;
for (var rl : materialSources) {
var sourceFile = sources.find(rl);
var adapterMap = createAdapterMap(adaptedFunctions, getSuffix(rl));
final int finalIndex = index;
var adapterMap = createAdapterMap(adaptedFunctions, fnName -> "_" + fnName + "_" + finalIndex);
transformed.add(new StringSubstitutionSourceComponent(sourceFile, adapterMap));
index++;
}
return new MaterialAdapterComponent(name, switchArg, adaptedFunctions, transformed.build());
}
}
@NotNull
private static HashMap<String, String> createAdapterMap(List<AdaptedFn> adaptedFunctions, String suffix) {
HashMap<String, String> out = new HashMap<>();
private static ImmutableMap<String, String> createAdapterMap(List<AdaptedFn> adaptedFunctions, UnaryOperator<String> nameAdapter) {
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
for (var adapted : adaptedFunctions) {
var fnName = adapted.signature()
.name();
out.put(fnName, fnName + suffix);
builder.put(fnName, nameAdapter.apply(fnName));
}
return out;
}
@NotNull
private static String getSuffix(ResourceLocation rl) {
return '_' + ResourceUtil.toSafeString(rl);
return builder.build();
}
}

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.backend.compile;
package com.jozufozu.flywheel.backend.compile.component;
import java.util.Collection;
import java.util.Map;

View File

@ -0,0 +1,76 @@
package com.jozufozu.flywheel.backend.compile.component;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.glsl.ShaderSources;
import com.jozufozu.flywheel.glsl.SourceComponent;
import com.jozufozu.flywheel.glsl.SourceFile;
import com.jozufozu.flywheel.glsl.generate.GlslBuilder;
import net.minecraft.resources.ResourceLocation;
public class UniformComponent implements SourceComponent {
private final ResourceLocation name;
private final ImmutableList<SourceFile> uniformShaders;
public static Builder builder(ResourceLocation uniforms) {
return new Builder(uniforms);
}
private UniformComponent(ResourceLocation name, ImmutableList<SourceFile> uniformShaders) {
this.name = name;
this.uniformShaders = uniformShaders;
}
@Override
public Collection<? extends SourceComponent> included() {
return uniformShaders;
}
@Override
public String source() {
var builder = new GlslBuilder();
builder.uniformBlock()
.layout("std140")
.binding(0)
.name("FLWUniforms")
.member("flywheel_uniforms", "flywheel");
builder.blankLine();
return builder.build();
}
@Override
public ResourceLocation name() {
return name;
}
public static class Builder {
private final ResourceLocation name;
private final List<ResourceLocation> uniformShaders = new ArrayList<>();
public Builder(ResourceLocation name) {
this.name = name;
}
public Builder sources(List<ResourceLocation> sources) {
this.uniformShaders.addAll(sources);
return this;
}
public UniformComponent build(ShaderSources sources) {
var out = ImmutableList.<SourceFile>builder();
for (var fileResolution : uniformShaders) {
out.add(sources.find(fileResolution));
}
return new UniformComponent(name, out.build());
}
}
}

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.backend.compile;
package com.jozufozu.flywheel.backend.compile.core;
import java.io.File;
import java.io.FileWriter;
@ -10,10 +10,10 @@ import org.jetbrains.annotations.NotNull;
import org.lwjgl.opengl.GL20;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.gl.GLSLVersion;
import com.jozufozu.flywheel.gl.shader.GlShader;
import com.jozufozu.flywheel.gl.shader.ShaderType;
import com.jozufozu.flywheel.gl.versioned.GlCompat;
import com.jozufozu.flywheel.glsl.GLSLVersion;
import com.jozufozu.flywheel.glsl.SourceComponent;
import com.jozufozu.flywheel.glsl.SourceFile;
import com.jozufozu.flywheel.util.StringUtil;
@ -39,10 +39,11 @@ public class Compilation {
private int generatedLines = 0;
public Compilation(GLSLVersion glslVersion, ShaderType shaderType) {
this.generatedSource = new StringBuilder();
this.fullSource = new StringBuilder(CompileUtil.generateHeader(glslVersion, shaderType)).append('\n');
this.glslVersion = glslVersion;
this.shaderType = shaderType;
generatedSource = new StringBuilder();
fullSource = new StringBuilder(glslVersion.getVersionLine()).append(shaderType.getDefineStatement()).append('\n');
}
@NotNull

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.backend.compile;
package com.jozufozu.flywheel.backend.compile.core;
import java.util.ArrayList;
import java.util.List;

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.backend.compile;
package com.jozufozu.flywheel.backend.compile.core;
import java.util.List;
import java.util.regex.Matcher;

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.backend.compile;
package com.jozufozu.flywheel.backend.compile.core;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -6,7 +6,6 @@ import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.gl.shader.GlProgram;
public sealed interface LinkResult {
@Nullable
default GlProgram unwrap() {
return null;

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.backend.compile;
package com.jozufozu.flywheel.backend.compile.core;
import static org.lwjgl.opengl.GL11.GL_TRUE;
import static org.lwjgl.opengl.GL20.GL_LINK_STATUS;

View File

@ -1,28 +1,27 @@
package com.jozufozu.flywheel.backend.compile;
package com.jozufozu.flywheel.backend.compile.core;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.gl.GLSLVersion;
import com.jozufozu.flywheel.gl.shader.GlShader;
import com.jozufozu.flywheel.gl.shader.ShaderType;
import com.jozufozu.flywheel.glsl.GLSLVersion;
import com.jozufozu.flywheel.glsl.SourceComponent;
public class ShaderCompiler {
private final Map<ShaderKey, ShaderResult> shaderCache = new HashMap<>();
private final CompilerStats stats;
private final CompilationFactory factory;
private final Includer includer;
public ShaderCompiler(CompilerStats stats, CompilationFactory factory, Includer includer) {
public ShaderCompiler(CompilerStats stats) {
this.stats = stats;
this.factory = factory;
this.includer = includer;
}
public int shaderCount() {
@ -37,7 +36,7 @@ public class ShaderCompiler {
return cached.unwrap();
}
ShaderResult out = compileUncached(factory.create(glslVersion, shaderType), sourceComponents);
ShaderResult out = compileUncached(new Compilation(glslVersion, shaderType), sourceComponents);
shaderCache.put(key, out);
stats.shaderResult(out);
return out.unwrap();
@ -56,41 +55,28 @@ public class ShaderCompiler {
ctx.enableExtension("GL_ARB_explicit_attrib_location");
ctx.enableExtension("GL_ARB_conservative_depth");
includer.expand(sourceComponents, ctx::appendComponent);
expand(sourceComponents, ctx::appendComponent);
return ctx.compile();
}
private static void expand(ImmutableList<SourceComponent> rootSources, Consumer<SourceComponent> out) {
var included = new LinkedHashSet<SourceComponent>(); // use hash set to deduplicate. linked to preserve order
for (var component : rootSources) {
recursiveDepthFirstInclude(included, component);
included.add(component);
}
included.forEach(out);
}
private static void recursiveDepthFirstInclude(Set<SourceComponent> included, SourceComponent component) {
for (var include : component.included()) {
recursiveDepthFirstInclude(included, include);
}
included.addAll(component.included());
}
private record ShaderKey(GLSLVersion glslVersion, ShaderType shaderType,
ImmutableList<SourceComponent> sourceComponents) {
}
public static Builder builder() {
return new Builder();
}
@FunctionalInterface
public interface CompilationFactory {
Compilation create(GLSLVersion version, ShaderType shaderType);
}
public static class Builder {
private CompilationFactory factory = Compilation::new;
private Includer includer = RecursiveIncluder.INSTANCE;
public Builder compilationFactory(CompilationFactory factory) {
this.factory = factory;
return this;
}
public Builder includer(Includer includer) {
this.includer = includer;
return this;
}
public ShaderCompiler build(CompilerStats stats) {
return new ShaderCompiler(stats, factory, includer);
}
}
}

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.backend.compile;
package com.jozufozu.flywheel.backend.compile.core;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

View File

@ -70,16 +70,12 @@ public class FlwCommands {
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) {
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);
}
Component message = actualBackend.engineMessage();
player.displayClientMessage(message, false);
}
return Command.SINGLE_SUCCESS;
})));

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.gl;
package com.jozufozu.flywheel.glsl;
public enum GLSLVersion {
V110(110),

View File

@ -1,42 +0,0 @@
package com.jozufozu.flywheel.glsl;
import java.util.Collection;
import java.util.Map;
import com.google.common.collect.Multimap;
import com.google.common.collect.MultimapBuilder;
import com.jozufozu.flywheel.glsl.parse.ShaderFunction;
import com.jozufozu.flywheel.glsl.parse.ShaderStruct;
import net.minecraft.resources.ResourceLocation;
/**
* Indexes many shader source definitions to allow for error fix suggestions.
*/
public class Index {
private final Multimap<String, ShaderStruct> knownStructs = MultimapBuilder.hashKeys()
.hashSetValues()
.build();
private final Multimap<String, ShaderFunction> knownFunctions = MultimapBuilder.hashKeys()
.hashSetValues()
.build();
public Index(Map<ResourceLocation, SourceFile> sources) {
Collection<SourceFile> files = sources.values();
for (SourceFile file : files) {
file.structs.forEach(knownStructs::put);
file.functions.forEach(knownFunctions::put);
}
}
public Collection<ShaderStruct> getStructDefinitionsMatching(CharSequence name) {
return knownStructs.get(name.toString());
}
public Collection<ShaderFunction> getFunctionDefinitionsMatching(CharSequence name) {
return knownFunctions.get(name.toString());
}
}

View File

@ -2,7 +2,6 @@ package com.jozufozu.flywheel.glsl;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
@ -10,8 +9,6 @@ import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import com.google.common.collect.Lists;
import com.jozufozu.flywheel.glsl.error.ErrorReporter;
import com.jozufozu.flywheel.util.ResourceUtil;
import com.jozufozu.flywheel.util.StringUtil;
@ -23,7 +20,8 @@ import net.minecraft.server.packs.resources.ResourceManager;
*/
public class ShaderSources {
public static final String SHADER_DIR = "flywheel/";
public static final ArrayList<String> EXTENSIONS = Lists.newArrayList(".vert", ".vsh", ".frag", ".fsh", ".glsl");
private final ResourceManager manager;
private final Map<ResourceLocation, SourceFile> cache = new HashMap<>();
@ -32,11 +30,7 @@ public class ShaderSources {
*/
private final Deque<ResourceLocation> findStack = new ArrayDeque<>();
private final ResourceManager manager;
private final ErrorReporter errorReporter;
public ShaderSources(ErrorReporter errorReporter, ResourceManager manager) {
this.errorReporter = errorReporter;
public ShaderSources(ResourceManager manager) {
this.manager = manager;
}

View File

@ -27,7 +27,6 @@ import net.minecraft.resources.ResourceLocation;
* </p>
*/
public class SourceFile implements SourceComponent {
public final ResourceLocation name;
public final ShaderSources parent;

View File

@ -30,15 +30,14 @@ public final class BackendManagerImpl {
private static final Backend DEFAULT_BACKEND = findDefaultBackend();
private static Backend backend;
private static Backend backend = OFF_BACKEND;
@Nullable
public static Backend getBackend() {
return backend;
}
public static boolean isOn() {
return backend != null && backend != OFF_BACKEND;
return backend != OFF_BACKEND;
}
public static Backend getOffBackend() {
@ -80,9 +79,6 @@ public final class BackendManagerImpl {
public static void init() {
CrashReportCallables.registerCrashCallable("Flywheel Backend", () -> {
if (backend == null) {
return "Uninitialized";
}
var backendId = Backend.REGISTRY.getId(backend);
if (backendId == null) {
return "Unregistered";

View File

@ -21,13 +21,23 @@ import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker;
public class StringUtil {
private static final NumberFormat THREE_DECIMAL_PLACES = new DecimalFormat("#0.000");
// FIXME: this method should count trailing newlines
public static int countLines(String s) {
return (int) s.lines()
.count();
int lines = 1;
int length = s.length();
for (int i = 0; i < length; i++) {
char c = s.charAt(i);
if (c == '\n') {
lines++;
} else if (c == '\r') {
lines++;
if (i + 1 < length && s.charAt(i + 1) == '\n') {
i++;
}
}
}
return lines;
}
public static String formatBytes(long bytes) {

View File

@ -3,12 +3,12 @@
uniform uvec2 _flw_materialID_instancing;
void main() {
flw_layoutVertex();
_flw_materialVertexID = _flw_materialID_instancing.x;
_flw_materialFragmentID = _flw_materialID_instancing.y;
FlwInstance i = _flw_unpackInstance();
flw_layoutVertex();
flw_instanceVertex(i);
flw_materialVertex();
flw_contextVertex();