Skip to content

Commit

Permalink
Add reserved keywords and replace GLSLPreParser with regex (#683)
Browse files Browse the repository at this point in the history
* Add reserved keywords and replace GLSLPreParser with regex

* Add a newline to the version directive in patched shader output

* Only process reserved keywords on GLSL < 400

* Better reserved keyword handling
  • Loading branch information
Cleptomania authored Oct 28, 2024
1 parent e4e6578 commit 8c90f79
Showing 1 changed file with 55 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,41 @@
import net.coderbot.iris.gl.shader.ShaderType;
import net.coderbot.iris.pipeline.transform.parameter.Parameters;
import net.coderbot.iris.pipeline.transform.parameter.AttributeParameters;
import org.antlr.v4.runtime.BufferedTokenStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.taumc.glsl.Util;
import org.taumc.glsl.grammar.GLSLLexer;
import org.taumc.glsl.grammar.GLSLParser;
import org.taumc.glsl.grammar.GLSLPreParser;

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ShaderTransformer {
static String tab = "";

private static final Pattern versionPattern = Pattern.compile("#version\\s+(\\d+)(?:\\s+(\\w+))?");

private static final int CACHE_SIZE = 100;
private static final Object2ObjectLinkedOpenHashMap<TransformKey, Map<PatchShaderType, String>> shaderTransformationCache = new Object2ObjectLinkedOpenHashMap<>();
private static final boolean useCache = true;

private static final List<String> fullReservedWords = new ArrayList<>();
private static final Map<Integer, List<String>> versionedReservedWords = new HashMap<>();;

static {
fullReservedWords.add("texture");
versionedReservedWords.put(400, Arrays.asList("sample"));
}

private static final class TransformKey<P extends Parameters> {
private final Patch patchType;
private final EnumMap<PatchShaderType, String> inputs;
Expand Down Expand Up @@ -117,34 +130,50 @@ private static <P extends Parameters> Map<PatchShaderType, String> transformInte
if (inputs.get(type) == null) {
continue;
}
GLSLLexer lexer = new GLSLLexer(CharStreams.fromString(inputs.get(type)));
GLSLPreParser preParser = new GLSLPreParser(new BufferedTokenStream(lexer));
GLSLParser parser = new GLSLParser(new CommonTokenStream(lexer));
parser.setBuildParseTree(true);
var pre = preParser.translation_unit();
var translationUnit = parser.translation_unit();
var preparsed = pre.compiler_directive();
String profile = "";
String versionString = "0";
GLSLPreParser.Compiler_directiveContext version = null;
for (var entry: preparsed) {
if (entry.version_directive() != null) {
version = entry;
if (entry.version_directive().number() != null) {
versionString = entry.version_directive().number().getText();
}
if (entry.version_directive().profile() != null) {
profile = entry.version_directive().profile().getText();
}
}

String input = inputs.get(type);

Matcher matcher = versionPattern.matcher(input);
if (!matcher.find()) {
throw new IllegalArgumentException("No #version directive found in source code!");
}
pre.children.remove(version);

String versionString = matcher.group(1);
if (versionString == null) {
continue;
}

String profileString = "#version " + versionString + " " + profile;
String profile = "";
int versionInt = Integer.parseInt(versionString);
if (versionInt >= 150) {
profile = matcher.group(2);
if (profile == null) {
profile = "core";
}
}

String profileString = "#version " + versionString + " " + profile + "\n";

// This handles some reserved keywords which cause the AST parser to fail
// but aren't necessarily invalid for GLSL versions prior to 400. This simple
// renames the matching strings and prefixes them with iris_renamed_
for (String reservedWord : fullReservedWords) {
String newName = "iris_renamed_" + reservedWord;
input = input.replaceAll("\\b" + reservedWord + "\\b", newName);
}
for (int version : versionedReservedWords.keySet()) {
if (versionInt < version) {
for (String reservedWord : versionedReservedWords.get(version)) {
String newName = "iris_renamed_" + reservedWord;
input = input.replaceAll("\\b" + reservedWord + "\\b", newName);
}
}
}

GLSLLexer lexer = new GLSLLexer(CharStreams.fromString(input));
GLSLParser parser = new GLSLParser(new CommonTokenStream(lexer));
parser.setBuildParseTree(true);
var translationUnit = parser.translation_unit();

switch(patchType) {
case SODIUM_TERRAIN:
Expand All @@ -161,7 +190,7 @@ private static <P extends Parameters> Map<PatchShaderType, String> transformInte
}
CompatibilityTransformer.transformEach(translationUnit, parameters);
types.put(type, translationUnit);
prepatched.put(type, getFormattedShader((ParseTree) pre, profileString));
prepatched.put(type, profileString);
}
CompatibilityTransformer.transformGrouped(types, parameters);
for (var entry : types.entrySet()) {
Expand Down

0 comments on commit 8c90f79

Please sign in to comment.