mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-28 05:44:59 +01:00
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:
parent
c6ed7c4132
commit
a504aa1862
6 changed files with 41 additions and 16 deletions
|
@ -81,7 +81,7 @@ public class IndirectPrograms extends AbstractPrograms {
|
||||||
.withComponent(IndirectComponent::create)
|
.withComponent(IndirectComponent::create)
|
||||||
.withResource(InstanceType::cullShader)
|
.withResource(InstanceType::cullShader)
|
||||||
.withResource(CULL_SHADER_MAIN))
|
.withResource(CULL_SHADER_MAIN))
|
||||||
.then((key, program) -> program.setUniformBlockBinding("_FlwFrameUniforms", 0))
|
.postLink((key, program) -> program.setUniformBlockBinding("_FlwFrameUniforms", 0))
|
||||||
.harness("culling", sources);
|
.harness("culling", sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,14 @@ public class PipelineCompiler {
|
||||||
.withResource(key -> key.contextShader()
|
.withResource(key -> key.contextShader()
|
||||||
.fragmentShader())
|
.fragmentShader())
|
||||||
.withResource(pipeline.fragmentMain()))
|
.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("_FlwFrameUniforms", 0);
|
||||||
program.setUniformBlockBinding("_FlwFogUniforms", 1);
|
program.setUniformBlockBinding("_FlwFogUniforms", 1);
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,10 @@ public class Compile<K> {
|
||||||
|
|
||||||
public static class ProgramStitcher<K> implements CompilationHarness.KeyCompiler<K> {
|
public static class ProgramStitcher<K> implements CompilationHarness.KeyCompiler<K> {
|
||||||
private final Map<ShaderType, ShaderCompiler<K>> compilers = new EnumMap<>(ShaderType.class);
|
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) {
|
public CompilationHarness<K> harness(String marker, ShaderSources sources) {
|
||||||
|
@ -57,8 +60,13 @@ public class Compile<K> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProgramStitcher<K> then(BiConsumer<K, GlProgram> onLink) {
|
public ProgramStitcher<K> postLink(BiConsumer<K, GlProgram> postLink) {
|
||||||
this.onLink = onLink;
|
this.postLink = postLink;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProgramStitcher<K> preLink(BiConsumer<K, GlProgram> preLink) {
|
||||||
|
this.preLink = preLink;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,10 +92,10 @@ public class Compile<K> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var out = programLinker.link(shaders);
|
var out = programLinker.link(shaders, p -> preLink.accept(key, p));
|
||||||
|
|
||||||
if (out != null) {
|
if (out != null) {
|
||||||
onLink.accept(key, out);
|
postLink.accept(key, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
|
|
@ -9,6 +9,7 @@ import static org.lwjgl.opengl.GL20.glGetProgrami;
|
||||||
import static org.lwjgl.opengl.GL20.glLinkProgram;
|
import static org.lwjgl.opengl.GL20.glLinkProgram;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@ -23,26 +24,30 @@ public class ProgramLinker {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public GlProgram link(List<GlShader> shaders) {
|
public GlProgram link(List<GlShader> shaders, Consumer<GlProgram> preLink) {
|
||||||
// this probably doesn't need caching
|
// this probably doesn't need caching
|
||||||
var linkResult = linkInternal(shaders);
|
var linkResult = linkInternal(shaders, preLink);
|
||||||
stats.linkResult(linkResult);
|
stats.linkResult(linkResult);
|
||||||
return linkResult.unwrap();
|
return linkResult.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
private LinkResult linkInternal(List<GlShader> shaders) {
|
private LinkResult linkInternal(List<GlShader> shaders, Consumer<GlProgram> preLink) {
|
||||||
int handle = glCreateProgram();
|
int handle = glCreateProgram();
|
||||||
|
var out = new GlProgram(handle);
|
||||||
|
|
||||||
for (GlShader shader : shaders) {
|
for (GlShader shader : shaders) {
|
||||||
glAttachShader(handle, shader.handle());
|
glAttachShader(handle, shader.handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preLink.accept(out);
|
||||||
|
|
||||||
glLinkProgram(handle);
|
glLinkProgram(handle);
|
||||||
String log = glGetProgramInfoLog(handle);
|
String log = glGetProgramInfoLog(handle);
|
||||||
|
|
||||||
if (linkSuccessful(handle)) {
|
if (linkSuccessful(handle)) {
|
||||||
return LinkResult.success(new GlProgram(handle), log);
|
return LinkResult.success(out, log);
|
||||||
} else {
|
} else {
|
||||||
|
out.delete();
|
||||||
return LinkResult.failure(log);
|
return LinkResult.failure(log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.gl.shader;
|
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.glDeleteProgram;
|
||||||
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
|
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
|
||||||
import static org.lwjgl.opengl.GL20.glUniform1f;
|
import static org.lwjgl.opengl.GL20.glUniform1f;
|
||||||
|
@ -170,6 +171,10 @@ public class GlProgram extends GlObject implements Shader {
|
||||||
glUniformBlockBinding(handle(), index, binding);
|
glUniformBlockBinding(handle(), index, binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void bindAttribLocation(String attribute, int binding) {
|
||||||
|
glBindAttribLocation(handle(), binding, attribute);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void deleteInternal(int handle) {
|
protected void deleteInternal(int handle) {
|
||||||
glDeleteProgram(handle);
|
glDeleteProgram(handle);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
layout(location = 0) in vec3 _flw_a_pos;
|
in vec3 _flw_a_pos;
|
||||||
layout(location = 1) in vec4 _flw_a_color;
|
in vec4 _flw_a_color;
|
||||||
layout(location = 2) in vec2 _flw_a_texCoord;
|
in vec2 _flw_a_texCoord;
|
||||||
layout(location = 3) in ivec4 _flw_a_overlay_light;
|
in ivec4 _flw_a_overlay_light;
|
||||||
layout(location = 4) in vec3 _flw_a_normal;
|
in vec3 _flw_a_normal;
|
||||||
|
|
||||||
void _flw_layoutVertex() {
|
void _flw_layoutVertex() {
|
||||||
flw_vertexPos = vec4(_flw_a_pos, 1.0);
|
flw_vertexPos = vec4(_flw_a_pos, 1.0);
|
||||||
|
|
Loading…
Reference in a new issue