Hot links

- Do not specify layout qualifier for vertex attributes
- Bind attribute locations before linking programs
- Delete gl programs when linking fails
This commit is contained in:
Jozufozu 2024-02-22 14:02:16 -06:00
parent c6ed7c4132
commit a504aa1862
6 changed files with 41 additions and 16 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -42,7 +42,10 @@ public class Compile<K> {
public static class ProgramStitcher<K> implements CompilationHarness.KeyCompiler<K> {
private final Map<ShaderType, ShaderCompiler<K>> compilers = new EnumMap<>(ShaderType.class);
private BiConsumer<K, GlProgram> onLink = (k, p) -> {
private BiConsumer<K, GlProgram> postLink = (k, p) -> {
};
private BiConsumer<K, GlProgram> preLink = (k, p) -> {
};
public CompilationHarness<K> harness(String marker, ShaderSources sources) {
@ -57,8 +60,13 @@ public class Compile<K> {
return this;
}
public ProgramStitcher<K> then(BiConsumer<K, GlProgram> onLink) {
this.onLink = onLink;
public ProgramStitcher<K> postLink(BiConsumer<K, GlProgram> postLink) {
this.postLink = postLink;
return this;
}
public ProgramStitcher<K> preLink(BiConsumer<K, GlProgram> preLink) {
this.preLink = preLink;
return this;
}
@ -84,10 +92,10 @@ public class Compile<K> {
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;

View File

@ -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<GlShader> shaders) {
public GlProgram link(List<GlShader> shaders, Consumer<GlProgram> 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<GlShader> shaders) {
private LinkResult linkInternal(List<GlShader> shaders, Consumer<GlProgram> 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);
}
}

View File

@ -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);

View File

@ -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);