Open AlfishSoftware opened 1 year ago
Unfortunately those engines like Godot using non standard things in GLSL.
#[compute]
is not a valid preprocessor directive according to the GLSL Language Spec.
So the only way to lint these shaders correctly is to workaround the code. So what I can imagine is an additional configuration for replacing things like:
"relpacements": [
["#[compute]", ""]
]
Which will cycle through all replacements and replaces in this case #[compute]
with an empty string.
The mapping to the compute shader stage is already available via the additionalStageAssociations
configuration.
Yeah, since it's non-standard, it makes sense to have such a generic setting. In this case it's better as a regex, since it'd have best flexibility while being easy to implement. I think ideally it could be:
/** Specify special handling for files containing a line that matches a regex.
Only the first match applies. */
"regexRules": {
// (this rule could be included by default, or as an example on how to use the setting)
/** Godot compute shaders */
"^\\s*\\#\\[compute\\]\\s*$": {
/** Optional substitution string for the match, replaced before sending the input to the validator. */
"replacement": " ",
/** Optional stage association to assign when the file has a line matching the regex. */
"stageAssociation": "comp",
},
},
Then you could process it with something like this:
// At this point, stage was already set with the existing association/fallback, if any.
for (let key in regexRules) {
let regex = new RegExp(key, "m");
let match = regex.exec(text);
if (match) {
var r = regexRules[key].replacement;
if (r != undefined)
text = text.substring(0, match.index) + r + text.substring(match.index + match[0].length);
// could also allow back-references to groups like $1 if using something like text.replace(regex, r)
var s = regexRules[key].stageAssociation;
if (s != undefined)
stage = s;
break;
}
}
callValidator(text, stage, ...);
Yes something like this would be possible.
Godot 4 uses
.glsl
files for its compute shaders (it has a different language for normal shaders). Their docs shows one such file as an example:To preserve compatibility, a user could configure a stage association like
.comp.glsl
as a compute shader and use this extension in Godot.However, even after this workaround,
glslangValidator
will show an error on the first line. It doesn't recognize the#[compute]
line, which is necessary for Godot according to docs:To solve this, you can detect the first line with this directive (probably the first thing in the code, excluding comments) and replace all characters in
#[compute]
with spaces' '
(preserving whitespace on this line, before and after the token) before passing the input toglslangValidator
. When you do this, you should also recognize the.glsl
file as a compute shader, without requiring users to make some custom association like.comp.glsl
.So, for example, a file
my_shader.glsl
like this:Would be recognized as a compute shader and become this when being passed to the validator stdin:
I don't think any other changes are needed to make it work, so it should be simple.