Missing lines

- Fix crash trying to generate pretty errors in generated source
- Generate short, unique file names for shaders
- Cleanup some legacy code
- Catch exceptions while compiling shaders for each backend
This commit is contained in:
Jozufozu 2023-05-15 16:37:22 -07:00
parent 98ebe9d95a
commit 2d923a91aa
3 changed files with 38 additions and 54 deletions

View file

@ -5,6 +5,7 @@ import java.util.Map;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.context.Context; import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.api.vertex.VertexType;
@ -27,12 +28,16 @@ public class IndirectPrograms {
var pipelineCompiler = PipelineCompiler.create(loadChecker, Pipelines.INDIRECT, pipelineKeys, uniformComponent, vertexMaterialComponent, fragmentMaterialComponent); var pipelineCompiler = PipelineCompiler.create(loadChecker, Pipelines.INDIRECT, pipelineKeys, uniformComponent, vertexMaterialComponent, fragmentMaterialComponent);
var cullingCompiler = CullingCompiler.create(loadChecker, createCullingKeys(), uniformComponent); var cullingCompiler = CullingCompiler.create(loadChecker, createCullingKeys(), uniformComponent);
try {
var pipelineResult = pipelineCompiler.compileAndReportErrors(); var pipelineResult = pipelineCompiler.compileAndReportErrors();
var cullingResult = cullingCompiler.compileAndReportErrors(); var cullingResult = cullingCompiler.compileAndReportErrors();
if (pipelineResult != null && cullingResult != null) { if (pipelineResult != null && cullingResult != null) {
instance = new IndirectPrograms(pipelineResult, cullingResult); instance = new IndirectPrograms(pipelineResult, cullingResult);
} }
} catch (Throwable e) {
Flywheel.LOGGER.error("Failed to compile indirect programs", e);
}
pipelineCompiler.delete(); pipelineCompiler.delete();
cullingCompiler.delete(); cullingCompiler.delete();
} }

View file

@ -5,6 +5,7 @@ import java.util.Map;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.context.Context; import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.api.vertex.VertexType;
@ -24,11 +25,15 @@ public class InstancingPrograms {
_delete(); _delete();
var instancingCompiler = PipelineCompiler.create(loadChecker, Pipelines.INSTANCED_ARRAYS, pipelineKeys, uniformComponent, vertexMaterialComponent, fragmentMaterialComponent); var instancingCompiler = PipelineCompiler.create(loadChecker, Pipelines.INSTANCED_ARRAYS, pipelineKeys, uniformComponent, vertexMaterialComponent, fragmentMaterialComponent);
try {
var result = instancingCompiler.compileAndReportErrors(); var result = instancingCompiler.compileAndReportErrors();
if (result != null) { if (result != null) {
instance = new InstancingPrograms(result); instance = new InstancingPrograms(result);
} }
} catch (Throwable e) {
Flywheel.LOGGER.error("Failed to compile instancing programs", e);
}
instancingCompiler.delete(); instancingCompiler.delete();
} }

View file

@ -4,7 +4,6 @@ import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
@ -19,7 +18,6 @@ import com.jozufozu.flywheel.glsl.SourceFile;
import com.jozufozu.flywheel.util.StringUtil; import com.jozufozu.flywheel.util.StringUtil;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation;
/** /**
* Builder style class for compiling shaders. * Builder style class for compiling shaders.
@ -31,7 +29,6 @@ public class Compilation {
public static final boolean DUMP_SHADER_SOURCE = System.getProperty("flw.dumpShaderSource") != null; public static final boolean DUMP_SHADER_SOURCE = System.getProperty("flw.dumpShaderSource") != null;
private final List<SourceFile> files = new ArrayList<>(); private final List<SourceFile> files = new ArrayList<>();
private final List<ResourceLocation> componentNames = new ArrayList<>();
private final StringBuilder generatedSource; private final StringBuilder generatedSource;
private final StringBuilder fullSource; private final StringBuilder fullSource;
private final GLSLVersion glslVersion; private final GLSLVersion glslVersion;
@ -54,7 +51,7 @@ public class Compilation {
GlCompat.safeShaderSource(handle, source); GlCompat.safeShaderSource(handle, source);
GL20.glCompileShader(handle); GL20.glCompileShader(handle);
var shaderName = buildShaderName(); var shaderName = shaderType.name + glslVersion + '_' + Integer.toUnsignedString(source.hashCode());
dumpSource(source, shaderType.getFileName(shaderName)); dumpSource(source, shaderType.getFileName(shaderName));
var infoLog = GL20.glGetShaderInfoLog(handle); var infoLog = GL20.glGetShaderInfoLog(handle);
@ -76,58 +73,35 @@ public class Compilation {
public void appendComponent(SourceComponent component) { public void appendComponent(SourceComponent component) {
var source = component.source(); var source = component.source();
if (component instanceof SourceFile file) { appendHeader(component, source);
fullSource.append(sourceHeader(file));
} else {
fullSource.append(generatedHeader(source, component.name()
.toString()));
}
fullSource.append(source); fullSource.append(source);
componentNames.add(component.name());
} }
private String sourceHeader(SourceFile sourceFile) { private void appendHeader(SourceComponent component, String source) {
return '\n' + "#line " + 0 + ' ' + getOrCreateFileID(sourceFile) + " // " + sourceFile.name + '\n'; if (component instanceof SourceFile file) {
int fileID = files.size();
files.add(file);
fullSource.append("\n#line 0 ")
.append(fileID)
.append(" // ")
.append(file.name)
.append('\n');
} else {
// Add extra newline to keep line numbers consistent
generatedSource.append(source)
.append('\n');
fullSource.append("\n#line ")
.append(generatedLines)
.append(" 0 // (generated) ") // all generated code is put in file 0
.append(component.name())
.append('\n');
generatedLines += StringUtil.countLines(source);
} }
private String generatedHeader(String generatedCode, String comment) {
generatedSource.append(generatedCode);
int lines = StringUtil.countLines(generatedCode);
// all generated code is put in file 0,
var out = '\n' + "#line " + generatedLines + ' ' + 0;
generatedLines += lines;
return out + " // (generated) " + comment + '\n';
}
/**
* Returns an arbitrary file ID for use this compilation context, or generates one if missing.
*
* @param sourceFile The file to retrieve the ID for.
* @return A file ID unique to the given sourceFile.
*/
private int getOrCreateFileID(SourceFile sourceFile) {
int i = files.indexOf(sourceFile);
if (i != -1) {
return i + 1;
}
files.add(sourceFile);
return files.size();
}
@NotNull
private String buildShaderName() {
// TODO: This name is so long it fails to create the file. Use index and map indices to component sources in separate file?
var components = componentNames.stream()
.map(ResourceLocation::toString)
.map(s -> s.replaceAll("/", "_")
.replaceAll(":", "\\$"))
.collect(Collectors.joining(";"));
return shaderType.name + glslVersion + ';' /*+ components*/;
} }
private static void dumpSource(String source, String fileName) { private static void dumpSource(String source, String fileName) {