- Do not uberize material or cutout shaders
- Add debug log for shader compilations/program links
This commit is contained in:
Jozufozu 2024-09-21 15:10:27 -07:00
parent 27e5b609af
commit 6a6d98c0a7
11 changed files with 66 additions and 53 deletions

View file

@ -39,46 +39,22 @@ public final class FlwPrograms {
var vertexComponentsHeader = loader.find(COMPONENTS_HEADER_VERT); var vertexComponentsHeader = loader.find(COMPONENTS_HEADER_VERT);
var fragmentComponentsHeader = loader.find(COMPONENTS_HEADER_FRAG); var fragmentComponentsHeader = loader.find(COMPONENTS_HEADER_FRAG);
// TODO: de-uber material shaders
var vertexMaterialComponent = createVertexMaterialComponent(loader);
var fragmentMaterialComponent = createFragmentMaterialComponent(loader);
var fogComponent = createFogComponent(loader); var fogComponent = createFogComponent(loader);
// TODO: separate compilation for cutout OFF, but keep the rest uber'd
var cutoutComponent = createCutoutComponent(loader);
if (stats.errored() || vertexComponentsHeader == null || fragmentComponentsHeader == null || vertexMaterialComponent == null || fragmentMaterialComponent == null || fogComponent == null || cutoutComponent == null) { // TODO: separate compilation for cutout OFF, but keep the rest uber'd?
if (stats.errored() || vertexComponentsHeader == null || fragmentComponentsHeader == null || fogComponent == null) {
// Probably means the shader sources are missing. // Probably means the shader sources are missing.
stats.emitErrorLog(); stats.emitErrorLog();
return; return;
} }
List<SourceComponent> vertexComponents = List.of(vertexComponentsHeader, vertexMaterialComponent); List<SourceComponent> vertexComponents = List.of(vertexComponentsHeader);
List<SourceComponent> fragmentComponents = List.of(fragmentComponentsHeader, fragmentMaterialComponent, fogComponent, cutoutComponent); List<SourceComponent> fragmentComponents = List.of(fragmentComponentsHeader, fogComponent);
InstancingPrograms.reload(sources, vertexComponents, fragmentComponents); InstancingPrograms.reload(sources, vertexComponents, fragmentComponents);
IndirectPrograms.reload(sources, vertexComponents, fragmentComponents); IndirectPrograms.reload(sources, vertexComponents, fragmentComponents);
} }
@Nullable
private static UberShaderComponent createVertexMaterialComponent(SourceLoader loader) {
return UberShaderComponent.builder(Flywheel.rl("material_vertex"))
.materialSources(MaterialShaderIndices.vertexSources()
.all())
.adapt(FnSignature.ofVoid("flw_materialVertex"))
.switchOn(GlslExpr.variable("_flw_uberMaterialVertexIndex"))
.build(loader);
}
@Nullable
private static UberShaderComponent createFragmentMaterialComponent(SourceLoader loader) {
return UberShaderComponent.builder(Flywheel.rl("material_fragment"))
.materialSources(MaterialShaderIndices.fragmentSources()
.all())
.adapt(FnSignature.ofVoid("flw_materialFragment"))
.switchOn(GlslExpr.variable("_flw_uberMaterialFragmentIndex"))
.build(loader);
}
@Nullable @Nullable
private static UberShaderComponent createFogComponent(SourceLoader loader) { private static UberShaderComponent createFogComponent(SourceLoader loader) {
return UberShaderComponent.builder(Flywheel.rl("fog")) return UberShaderComponent.builder(Flywheel.rl("fog"))

View file

@ -8,7 +8,9 @@ import com.google.common.collect.ImmutableList;
import dev.engine_room.flywheel.api.Flywheel; import dev.engine_room.flywheel.api.Flywheel;
import dev.engine_room.flywheel.api.instance.InstanceType; 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.LightShader;
import dev.engine_room.flywheel.api.material.MaterialShaders;
import dev.engine_room.flywheel.backend.compile.component.InstanceStructComponent; 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.component.SsboInstanceComponent;
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness; import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
@ -148,8 +150,8 @@ public class IndirectPrograms extends AtomicReferenceCounted {
setInstance(null); setInstance(null);
} }
public GlProgram getIndirectProgram(InstanceType<?> instanceType, ContextShader contextShader, LightShader light) { public GlProgram getIndirectProgram(InstanceType<?> instanceType, ContextShader contextShader, LightShader light, CutoutShader cutout, MaterialShaders shaders) {
return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light)); return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light, cutout, shaders));
} }
public GlProgram getCullingProgram(InstanceType<?> instanceType) { public GlProgram getCullingProgram(InstanceType<?> instanceType) {

View file

@ -7,7 +7,9 @@ import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import dev.engine_room.flywheel.api.instance.InstanceType; 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.LightShader;
import dev.engine_room.flywheel.api.material.MaterialShaders;
import dev.engine_room.flywheel.backend.compile.core.CompilationHarness; import dev.engine_room.flywheel.backend.compile.core.CompilationHarness;
import dev.engine_room.flywheel.backend.gl.GlCompat; import dev.engine_room.flywheel.backend.gl.GlCompat;
import dev.engine_room.flywheel.backend.gl.shader.GlProgram; import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
@ -71,8 +73,8 @@ public class InstancingPrograms extends AtomicReferenceCounted {
setInstance(null); setInstance(null);
} }
public GlProgram get(InstanceType<?> instanceType, ContextShader contextShader, LightShader light) { public GlProgram get(InstanceType<?> instanceType, ContextShader contextShader, LightShader light, CutoutShader cutout, MaterialShaders materialShaders) {
return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light)); return pipeline.get(new PipelineProgramKey(instanceType, contextShader, light, cutout, materialShaders));
} }
@Override @Override

View file

@ -35,9 +35,11 @@ public final class PipelineCompiler {
var instance = ResourceUtil.toDebugFileNameNoExtension(key.instanceType() var instance = ResourceUtil.toDebugFileNameNoExtension(key.instanceType()
.vertexShader()); .vertexShader());
var material = ResourceUtil.toDebugFileNameNoExtension(key.materialShaders()
.vertexSource());
var context = key.contextShader() var context = key.contextShader()
.nameLowerCase(); .nameLowerCase();
return "pipeline/" + pipeline.compilerMarker() + "/" + instance + "_" + context; return "pipeline/" + pipeline.compilerMarker() + "/" + instance + "/" + material + "_" + context;
}) })
.requireExtensions(extensions) .requireExtensions(extensions)
.onCompile((key, comp) -> key.contextShader() .onCompile((key, comp) -> key.contextShader()
@ -47,6 +49,8 @@ public final class PipelineCompiler {
.withComponent(key -> new InstanceStructComponent(key.instanceType())) .withComponent(key -> new InstanceStructComponent(key.instanceType()))
.withResource(key -> key.instanceType() .withResource(key -> key.instanceType()
.vertexShader()) .vertexShader())
.withResource(key -> key.materialShaders()
.vertexSource())
.withComponents(vertexComponents) .withComponents(vertexComponents)
.withResource(InternalVertex.LAYOUT_SHADER) .withResource(InternalVertex.LAYOUT_SHADER)
.withComponent(key -> pipeline.assembler() .withComponent(key -> pipeline.assembler()
@ -56,8 +60,16 @@ public final class PipelineCompiler {
.nameMapper(key -> { .nameMapper(key -> {
var context = key.contextShader() var context = key.contextShader()
.nameLowerCase(); .nameLowerCase();
return "pipeline/" + pipeline.compilerMarker() + "/" + ResourceUtil.toDebugFileNameNoExtension(key.light()
.source()) + "_" + context; var material = ResourceUtil.toDebugFileNameNoExtension(key.materialShaders()
.fragmentSource());
var cutout = ResourceUtil.toDebugFileNameNoExtension(key.cutout()
.source());
var light = ResourceUtil.toDebugFileNameNoExtension(key.light()
.source());
return "pipeline/" + pipeline.compilerMarker() + "/frag/" + material + "/" + light + "_" + cutout + "_" + context;
}) })
.requireExtensions(extensions) .requireExtensions(extensions)
.enableExtension("GL_ARB_conservative_depth") .enableExtension("GL_ARB_conservative_depth")
@ -65,9 +77,13 @@ public final class PipelineCompiler {
.onCompile(comp)) .onCompile(comp))
.onCompile((key, comp) -> lightSmoothness.onCompile(comp)) .onCompile((key, comp) -> lightSmoothness.onCompile(comp))
.withResource(API_IMPL_FRAG) .withResource(API_IMPL_FRAG)
.withResource(key -> key.materialShaders()
.fragmentSource())
.withComponents(fragmentComponents) .withComponents(fragmentComponents)
.withResource(key -> key.light() .withResource(key -> key.light()
.source()) .source())
.withResource(key -> key.cutout()
.source())
.withResource(pipeline.fragmentMain())) .withResource(pipeline.fragmentMain()))
.preLink((key, program) -> { .preLink((key, program) -> {
program.bindAttribLocation("_flw_aPos", 0); program.bindAttribLocation("_flw_aPos", 0);

View file

@ -1,7 +1,9 @@
package dev.engine_room.flywheel.backend.compile; package dev.engine_room.flywheel.backend.compile;
import dev.engine_room.flywheel.api.instance.InstanceType; 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.LightShader;
import dev.engine_room.flywheel.api.material.MaterialShaders;
/** /**
* Represents the entire context of a program's usage. * Represents the entire context of a program's usage.
@ -10,5 +12,6 @@ import dev.engine_room.flywheel.api.material.LightShader;
* @param contextShader The context shader to use. * @param contextShader The context shader to use.
* @param light The light shader to use. * @param light The light shader to use.
*/ */
public record PipelineProgramKey(InstanceType<?> instanceType, ContextShader contextShader, LightShader light) { public record PipelineProgramKey(InstanceType<?> instanceType, ContextShader contextShader, LightShader light,
CutoutShader cutout, MaterialShaders materialShaders) {
} }

View file

@ -12,12 +12,14 @@ import java.util.function.Function;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import dev.engine_room.flywheel.backend.compile.FlwPrograms;
import dev.engine_room.flywheel.backend.gl.shader.GlProgram; import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
import dev.engine_room.flywheel.backend.gl.shader.GlShader; import dev.engine_room.flywheel.backend.gl.shader.GlShader;
import dev.engine_room.flywheel.backend.gl.shader.ShaderType; import dev.engine_room.flywheel.backend.gl.shader.ShaderType;
import dev.engine_room.flywheel.backend.glsl.GlslVersion; import dev.engine_room.flywheel.backend.glsl.GlslVersion;
import dev.engine_room.flywheel.backend.glsl.ShaderSources; import dev.engine_room.flywheel.backend.glsl.ShaderSources;
import dev.engine_room.flywheel.backend.glsl.SourceComponent; import dev.engine_room.flywheel.backend.glsl.SourceComponent;
import dev.engine_room.flywheel.lib.util.StringUtil;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
/** /**
@ -122,6 +124,8 @@ public class Compile<K> {
@Nullable @Nullable
private GlShader compile(K key, ShaderCache compiler, SourceLoader loader) { private GlShader compile(K key, ShaderCache compiler, SourceLoader loader) {
long start = System.nanoTime();
var components = new ArrayList<SourceComponent>(); var components = new ArrayList<SourceComponent>();
boolean ok = true; boolean ok = true;
for (var fetcher : fetchers) { for (var fetcher : fetchers) {
@ -137,7 +141,14 @@ public class Compile<K> {
} }
Consumer<Compilation> cb = ctx -> compilationCallbacks.accept(key, ctx); Consumer<Compilation> cb = ctx -> compilationCallbacks.accept(key, ctx);
return compiler.compile(glslVersion, shaderType, nameMapper.apply(key), cb, components); var name = nameMapper.apply(key);
var out = compiler.compile(glslVersion, shaderType, name, cb, components);
long end = System.nanoTime();
FlwPrograms.LOGGER.debug("Compiled {} in {}", name, StringUtil.formatTime(end - start));
return out;
} }
} }
@ -177,6 +188,8 @@ public class Compile<K> {
throw new IllegalStateException("No shader compilers were added!"); throw new IllegalStateException("No shader compilers were added!");
} }
long start = System.nanoTime();
List<GlShader> shaders = new ArrayList<>(); List<GlShader> shaders = new ArrayList<>();
boolean ok = true; boolean ok = true;
@ -198,6 +211,10 @@ public class Compile<K> {
postLink.accept(key, out); postLink.accept(key, out);
} }
long end = System.nanoTime();
FlwPrograms.LOGGER.debug("Linked {} in {}", key, StringUtil.formatTime(end - start));
return out; return out;
} }
} }

View file

@ -5,6 +5,7 @@ import dev.engine_room.flywheel.api.material.Transparency;
import dev.engine_room.flywheel.api.material.WriteMask; import dev.engine_room.flywheel.api.material.WriteMask;
import dev.engine_room.flywheel.lib.material.CutoutShaders; import dev.engine_room.flywheel.lib.material.CutoutShaders;
import dev.engine_room.flywheel.lib.material.FogShaders; import dev.engine_room.flywheel.lib.material.FogShaders;
import dev.engine_room.flywheel.lib.material.LightShaders;
import dev.engine_room.flywheel.lib.material.SimpleMaterial; import dev.engine_room.flywheel.lib.material.SimpleMaterial;
public class CommonCrumbling { public class CommonCrumbling {
@ -12,6 +13,7 @@ public class CommonCrumbling {
crumblingMaterial.copyFrom(baseMaterial) crumblingMaterial.copyFrom(baseMaterial)
.fog(FogShaders.NONE) .fog(FogShaders.NONE)
.cutout(CutoutShaders.ONE_TENTH) .cutout(CutoutShaders.ONE_TENTH)
.light(LightShaders.SMOOTH_WHEN_EMBEDDED)
.polygonOffset(true) .polygonOffset(true)
.transparency(Transparency.CRUMBLING) .transparency(Transparency.CRUMBLING)
.writeMask(WriteMask.COLOR) .writeMask(WriteMask.COLOR)

View file

@ -26,7 +26,6 @@ import dev.engine_room.flywheel.backend.engine.MeshPool;
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms; import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
import dev.engine_room.flywheel.backend.gl.GlCompat; import dev.engine_room.flywheel.backend.gl.GlCompat;
import dev.engine_room.flywheel.backend.gl.shader.GlProgram; import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
import dev.engine_room.flywheel.lib.material.LightShaders;
import dev.engine_room.flywheel.lib.math.MoreMath; import dev.engine_room.flywheel.lib.math.MoreMath;
public class IndirectCullingGroup<I extends Instance> { public class IndirectCullingGroup<I extends Instance> {
@ -204,7 +203,7 @@ public class IndirectCullingGroup<I extends Instance> {
int baseDrawUniformLoc = -1; int baseDrawUniformLoc = -1;
for (var multiDraw : multiDraws.get(visualType)) { for (var multiDraw : multiDraws.get(visualType)) {
var drawProgram = programs.getIndirectProgram(instanceType, multiDraw.embedded ? ContextShader.EMBEDDED : ContextShader.DEFAULT, multiDraw.material.light()); var drawProgram = programs.getIndirectProgram(instanceType, multiDraw.embedded ? ContextShader.EMBEDDED : ContextShader.DEFAULT, multiDraw.material.light(), multiDraw.material.cutout(), multiDraw.material.shaders());
if (drawProgram != lastProgram) { if (drawProgram != lastProgram) {
lastProgram = drawProgram; lastProgram = drawProgram;
@ -221,8 +220,8 @@ public class IndirectCullingGroup<I extends Instance> {
} }
} }
public void bindWithContextShader(ContextShader override) { public void bindWithContextShader(ContextShader override, Material material) {
var program = programs.getIndirectProgram(instanceType, override, LightShaders.SMOOTH_WHEN_EMBEDDED); var program = programs.getIndirectProgram(instanceType, override, material.light(), material.cutout(), material.shaders());
program.bind(); program.bind();

View file

@ -216,8 +216,6 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
continue; continue;
} }
cullingGroup.bindWithContextShader(ContextShader.CRUMBLING);
for (var progressEntry : byProgress.int2ObjectEntrySet()) { for (var progressEntry : byProgress.int2ObjectEntrySet()) {
Samplers.CRUMBLING.makeActive(); Samplers.CRUMBLING.makeActive();
TextureBinder.bind(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())); TextureBinder.bind(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey()));
@ -230,6 +228,8 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
// Transform the material to be suited for crumbling. // Transform the material to be suited for crumbling.
CommonCrumbling.applyCrumblingProperties(crumblingMaterial, draw.material()); CommonCrumbling.applyCrumblingProperties(crumblingMaterial, draw.material());
cullingGroup.bindWithContextShader(ContextShader.CRUMBLING, crumblingMaterial);
MaterialRenderState.setup(crumblingMaterial); MaterialRenderState.setup(crumblingMaterial);
// Upload the draw command. // Upload the draw command.

View file

@ -28,7 +28,6 @@ import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
import dev.engine_room.flywheel.backend.gl.TextureBuffer; import dev.engine_room.flywheel.backend.gl.TextureBuffer;
import dev.engine_room.flywheel.backend.gl.array.GlVertexArray; import dev.engine_room.flywheel.backend.gl.array.GlVertexArray;
import dev.engine_room.flywheel.backend.gl.shader.GlProgram; import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
import dev.engine_room.flywheel.lib.material.LightShaders;
import dev.engine_room.flywheel.lib.material.SimpleMaterial; import dev.engine_room.flywheel.lib.material.SimpleMaterial;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.client.resources.model.ModelBakery;
@ -169,9 +168,6 @@ public class InstancedDrawManager extends DrawManager<InstancedInstancer<?>> {
GroupKey<?> shader = groupEntry.getKey(); GroupKey<?> shader = groupEntry.getKey();
var program = programs.get(shader.instanceType(), ContextShader.CRUMBLING, LightShaders.SMOOTH_WHEN_EMBEDDED);
program.bind();
for (var progressEntry : byProgress.int2ObjectEntrySet()) { for (var progressEntry : byProgress.int2ObjectEntrySet()) {
Samplers.CRUMBLING.makeActive(); Samplers.CRUMBLING.makeActive();
TextureBinder.bind(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())); TextureBinder.bind(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey()));
@ -180,10 +176,11 @@ public class InstancedDrawManager extends DrawManager<InstancedInstancer<?>> {
InstancedInstancer<?> instancer = instanceHandlePair.getFirst(); InstancedInstancer<?> instancer = instanceHandlePair.getFirst();
var index = instanceHandlePair.getSecond().index; var index = instanceHandlePair.getSecond().index;
program.setInt("_flw_baseInstance", index);
for (InstancedDraw draw : instancer.draws()) { for (InstancedDraw draw : instancer.draws()) {
CommonCrumbling.applyCrumblingProperties(crumblingMaterial, draw.material()); CommonCrumbling.applyCrumblingProperties(crumblingMaterial, draw.material());
var program = programs.get(shader.instanceType(), ContextShader.CRUMBLING, crumblingMaterial.light(), crumblingMaterial.cutout(), crumblingMaterial.shaders());
program.bind();
program.setInt("_flw_baseInstance", index);
uploadMaterialUniform(program, crumblingMaterial); uploadMaterialUniform(program, crumblingMaterial);
MaterialRenderState.setup(crumblingMaterial); MaterialRenderState.setup(crumblingMaterial);

View file

@ -55,14 +55,13 @@ public class InstancedRenderStage {
var environment = shader.environment(); var environment = shader.environment();
for (var drawCall : drawCalls.draws) { for (var drawCall : drawCalls.draws) {
var program = programs.get(shader.instanceType(), environment.contextShader(), drawCall.material() var material = drawCall.material();
.light());
var program = programs.get(shader.instanceType(), environment.contextShader(), material.light(), material.cutout(), material.shaders());
program.bind(); program.bind();
environment.setupDraw(program); environment.setupDraw(program);
var material = drawCall.material();
uploadMaterialUniform(program, material); uploadMaterialUniform(program, material);
MaterialRenderState.setup(material); MaterialRenderState.setup(material);