From a504aa1862b78b623cda52daaded9af873456135 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Thu, 22 Feb 2024 14:02:16 -0600 Subject: [PATCH] Hot links - Do not specify layout qualifier for vertex attributes - Bind attribute locations before linking programs - Delete gl programs when linking fails --- .../backend/compile/IndirectPrograms.java | 2 +- .../backend/compile/PipelineCompiler.java | 9 ++++++++- .../flywheel/backend/compile/core/Compile.java | 18 +++++++++++++----- .../backend/compile/core/ProgramLinker.java | 13 +++++++++---- .../flywheel/backend/gl/shader/GlProgram.java | 5 +++++ .../flywheel/internal/vertex_input.vert | 10 +++++----- 6 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java b/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java index 879a4c5b6..7d4e16b5b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/IndirectPrograms.java @@ -81,7 +81,7 @@ public class IndirectPrograms extends AbstractPrograms { .withComponent(IndirectComponent::create) .withResource(InstanceType::cullShader) .withResource(CULL_SHADER_MAIN)) - .then((key, program) -> program.setUniformBlockBinding("_FlwFrameUniforms", 0)) + .postLink((key, program) -> program.setUniformBlockBinding("_FlwFrameUniforms", 0)) .harness("culling", sources); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java index 29f99bb56..46eb05d3b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineCompiler.java @@ -50,7 +50,14 @@ public class PipelineCompiler { .withResource(key -> key.contextShader() .fragmentShader()) .withResource(pipeline.fragmentMain())) - .then((key, program) -> { + .preLink((key, program) -> { + program.bindAttribLocation("_flw_a_pos", 0); + program.bindAttribLocation("_flw_a_color", 1); + program.bindAttribLocation("_flw_a_texCoord", 2); + program.bindAttribLocation("_flw_a_overlay_light", 3); + program.bindAttribLocation("_flw_a_normal", 4); + }) + .postLink((key, program) -> { program.setUniformBlockBinding("_FlwFrameUniforms", 0); program.setUniformBlockBinding("_FlwFogUniforms", 1); diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/core/Compile.java b/src/main/java/com/jozufozu/flywheel/backend/compile/core/Compile.java index 3dc7d8c63..a1a87ca28 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/core/Compile.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/core/Compile.java @@ -42,7 +42,10 @@ public class Compile { public static class ProgramStitcher implements CompilationHarness.KeyCompiler { private final Map> compilers = new EnumMap<>(ShaderType.class); - private BiConsumer onLink = (k, p) -> { + private BiConsumer postLink = (k, p) -> { + + }; + private BiConsumer preLink = (k, p) -> { }; public CompilationHarness harness(String marker, ShaderSources sources) { @@ -57,8 +60,13 @@ public class Compile { return this; } - public ProgramStitcher then(BiConsumer onLink) { - this.onLink = onLink; + public ProgramStitcher postLink(BiConsumer postLink) { + this.postLink = postLink; + return this; + } + + public ProgramStitcher preLink(BiConsumer preLink) { + this.preLink = preLink; return this; } @@ -84,10 +92,10 @@ public class Compile { return null; } - var out = programLinker.link(shaders); + var out = programLinker.link(shaders, p -> preLink.accept(key, p)); if (out != null) { - onLink.accept(key, out); + postLink.accept(key, out); } return out; diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/core/ProgramLinker.java b/src/main/java/com/jozufozu/flywheel/backend/compile/core/ProgramLinker.java index 93359b303..c1c2c1f25 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/core/ProgramLinker.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/core/ProgramLinker.java @@ -9,6 +9,7 @@ import static org.lwjgl.opengl.GL20.glGetProgrami; import static org.lwjgl.opengl.GL20.glLinkProgram; import java.util.List; +import java.util.function.Consumer; import org.jetbrains.annotations.Nullable; @@ -23,26 +24,30 @@ public class ProgramLinker { } @Nullable - public GlProgram link(List shaders) { + public GlProgram link(List shaders, Consumer preLink) { // this probably doesn't need caching - var linkResult = linkInternal(shaders); + var linkResult = linkInternal(shaders, preLink); stats.linkResult(linkResult); return linkResult.unwrap(); } - private LinkResult linkInternal(List shaders) { + private LinkResult linkInternal(List shaders, Consumer preLink) { int handle = glCreateProgram(); + var out = new GlProgram(handle); for (GlShader shader : shaders) { glAttachShader(handle, shader.handle()); } + preLink.accept(out); + glLinkProgram(handle); String log = glGetProgramInfoLog(handle); if (linkSuccessful(handle)) { - return LinkResult.success(new GlProgram(handle), log); + return LinkResult.success(out, log); } else { + out.delete(); return LinkResult.failure(log); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlProgram.java b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlProgram.java index 96ad85df7..8617fd3ee 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlProgram.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlProgram.java @@ -1,5 +1,6 @@ package com.jozufozu.flywheel.backend.gl.shader; +import static org.lwjgl.opengl.GL20.glBindAttribLocation; import static org.lwjgl.opengl.GL20.glDeleteProgram; import static org.lwjgl.opengl.GL20.glGetUniformLocation; import static org.lwjgl.opengl.GL20.glUniform1f; @@ -170,6 +171,10 @@ public class GlProgram extends GlObject implements Shader { glUniformBlockBinding(handle(), index, binding); } + public void bindAttribLocation(String attribute, int binding) { + glBindAttribLocation(handle(), binding, attribute); + } + @Override protected void deleteInternal(int handle) { glDeleteProgram(handle); diff --git a/src/main/resources/assets/flywheel/flywheel/internal/vertex_input.vert b/src/main/resources/assets/flywheel/flywheel/internal/vertex_input.vert index c33509634..e78c58174 100644 --- a/src/main/resources/assets/flywheel/flywheel/internal/vertex_input.vert +++ b/src/main/resources/assets/flywheel/flywheel/internal/vertex_input.vert @@ -1,8 +1,8 @@ -layout(location = 0) in vec3 _flw_a_pos; -layout(location = 1) in vec4 _flw_a_color; -layout(location = 2) in vec2 _flw_a_texCoord; -layout(location = 3) in ivec4 _flw_a_overlay_light; -layout(location = 4) in vec3 _flw_a_normal; +in vec3 _flw_a_pos; +in vec4 _flw_a_color; +in vec2 _flw_a_texCoord; +in ivec4 _flw_a_overlay_light; +in vec3 _flw_a_normal; void _flw_layoutVertex() { flw_vertexPos = vec4(_flw_a_pos, 1.0);