Open pzgulyas opened 5 years ago
@pzgulyas EDIT: Oops, I see now that you're describing a different issue than I initially thought. There is a parallel issue in the Vulkan backend that prevents it from working with different entry point names at the moment.
Could you provide more info about how you are producing the SPIR-V that causes this issue?
I have my glsl sources, and do a ReadAllBytes on them. So it is the same way how you describe it here in the README.md Usage section.
EDIT: Oh, sorry, not exactly. I have the glsl sources in the files, not the compiled bytecode. Hmmm, maybe that was the problem? But it still works with "main" and ReadAllBytes.
EDIT2: Just to add some code how I thought:
byte[] vertexShader = File.ReadAllBytes("sky.vert");
byte[] fragmentShader = File.ReadAllBytes("sky.frag");
Shader[] SkyShader = factory.CreateFromSpirv(
new ShaderDescription(ShaderStages.Vertex, vertexShader, "main"),
new ShaderDescription(ShaderStages.Fragment, fragmentShader, "main"));
Shader[] CloudsShader = factory.CreateFromSpirv(
new ShaderDescription(ShaderStages.Vertex, vertexShader, "main"),
new ShaderDescription(ShaderStages.Fragment, fragmentShader, "clouds"));
or something similar.
As far as I know, there's no way to use an entrypoint other than "main()" in GLSL. So unless I'm missing something, you'll need to specify "main" in the ShaderDescription since that's what the code will have. This isn't true for HLSL (it lets you specify any function name you want), so that's what I initially thought you were referring to. Could you provide a sample GLSL shader that would exhibit this problem?
Below is a sample of my technical experiment. Not that this particular one could not be easily exploded into multiple files, but I also have some more difficult ones. :-)
Anyway, temporarily I am just doing some replacing code, like
var shaderBytes = File.ReadAllText(shaderFile)
.Replace("void main()", "void origmain()")
.Replace($"void {shaderEntry}()", "void main()")
.Select(c => (byte)c).ToArray();
Okay, I'm able to compile that shader using the following glslangvalidator command:
glslangvalidator sky.frag -V -S frag -e moon --sep main
glslangvalidator sky.frag -V -S frag -e clouds --sep main
The confusing part is this --sep
parameter always needs to be "main", as far as I can tell. Nothing else seems to work, and you can't leave the parameter off. However, the actual "main" function needs to be deleted, otherwise it complains about duplicate functions. It feels like this feature is a little half-baked, but it does work. I'm looking at the SPIR-V output and the shader's "OpEntryPoint" correctly matches what the input function's name was, and the function body looks correct. It should be possible to support this same functionality through the shaderc library, instead of just ignoring the entry point as it currently does.
I expect that I will fix this when I finish up the HLSL support, which will hopefully be soon. HLSL has better support for defining multiple shaders in a single file, so being able to control which entry point is used will be more valuable there, anyways.
When I try to load a shader with an entryPoint of the ShaderDescription set to something else than "main", I get a null reference exception in CreateFromSpirv, no matter if that function actually exists in shader or not.
(Since includes are quite mystical to mee, how they are supposed to work in glsl and also here, my idea was to just shovel everything into a single file, and generating different actual shaders by setting different entry points, but it doesn't work with this parameter.)