glslang icon indicating copy to clipboard operation
glslang copied to clipboard

Define input-file format for holding multiple shaders in a single file.

Open ioquatix opened this issue 8 years ago • 19 comments

It's not clear how one should name files.

For example, you outline that files would normally be named e.g. .frag for fragment shader. But the syntax of the file is glsl, so does .glsl also suit? You mention that the glslValidator uses the file extension to choose the appropriate internal logic, but it's not clear whether this can be overridden or this is establishing a standard.

In addition, it's not clear how the output files should be named. For example, we've been using $shader.frag.spv but this isn't ideal in cases where you are trying to determine the file type based purely on the file extension. It would be good to have a discussion here and then put forward a standard naming convention for shader files, in particular both glsl related files, and the spv counterparts.

The reason for this request is two fold:

1/ Set a baseline for engine and 3D software developers so that people can work consistently (e.g. resource loading systems). 2/ Make it clear what extensions should be recognised by IDEs, tools, e.g. for syntax highlighting, file icons, etc. e.g. https://github.com/hughsk/language-glsl/blob/5edd8bd17af5913f977bd7efe8c815786e6a4adf/grammars/glsl.cson#L1-L18

Thanks for your time.

ioquatix avatar Jun 05 '16 04:06 ioquatix

I guess I'll add one more point. The file extension usually indicates the contents of the file, e.g. it's format, not the function. Ideally, I think it would make the most sense to use .glsl and compile that to .spv (e.g. how .c compiles to .o). But, that's counter the existing recommendations so I guess having a discussion here would be good.

Ideally, one could put multiple functions into the .glsl file, e.g. both the vertex and fragment functions, etc.

ioquatix avatar Jun 05 '16 04:06 ioquatix

GLSL internally has no declaration of what stage a shader is meant for, so the information is external. Hence, a .glsl suffix doesn't help much for a single shader staying with GLSL syntax.

There is also no syntax for bundling multiple shaders into a single file. This could be layered on top of GLSL, in a tool like glslang or a wrapper around it, as GLSL proper has no concept of a file either.

It does establish a convention though for stage-specific file-name suffixes, which would be fine to follow, though there is standard to force that.

What does that leave? Just a command-line option request to explicitly set the stage and ignore the file suffix?

johnkslang avatar Jun 05 '16 21:06 johnkslang

What does that leave? Just a command-line option request to explicitly set the stage and ignore the file suffix?

I see both pros and cons in this.

I'm also suggesting the the output file name be "suggested" or "recommended", e.g. foo.frag should canonically map to foo.frag.spv or something along those lines.

ioquatix avatar Jun 05 '16 23:06 ioquatix

Note that a SPIR-V binary can have lots of stages and shaders in it. With a bit more functionality, glslang, or some other tool can turn input GLSL of shader.vert shader.frag into a single SPIR-V file, where the .vert and .frag know their stage only externally, but the .spv internally documents what stage each entry point is for.

johnkslang avatar Jun 06 '16 06:06 johnkslang

@johnkslang Yes, I think that's a great thing and I'd like to see that working. I even tried to do this by specifying a single output path and multiple inputs but it didn't work correctly.

ioquatix avatar Jun 06 '16 06:06 ioquatix

Even if the current behaviour is documented, to explain ideally how one uses the tool, and then perhaps working on the single file output with .spv extension going forward. Does that mean you'd have different functions in the .spv file corresponding to the main function for each stage?

ioquatix avatar Jun 06 '16 06:06 ioquatix

Looking back at the original questions, and what you've said, would it make sense to define a new format, e.g. ending in .glsl, which has discrete functions, e.g. void vertex(...) and void fragment(...) that can be compiled to a single .spv file?

ioquatix avatar Jun 06 '16 07:06 ioquatix

What does that leave? Just a command-line option request to explicitly set the stage and ignore the file suffix?

That would be useful. I use glslang as a syntax checker with emacs and flycheck. There is a lot of existing code with .glsl that it barfs on. Being able to specify allows some flexibility to infer or make it user definable from emacs.

yrns avatar Aug 10 '16 20:08 yrns

I think this is getting addressed by PR #450, maybe the only question is how to handle lots of files simultaneously. Glslang can take lots of files across multiple stages and link them all together, so we need a way of specifying this per input file.

johnkslang avatar Aug 11 '16 04:08 johnkslang

Perhaps it would make more sense to have a separate compiler and linker command - or to logically separate out these functions within the glgslang command, e.g. glslang -c (compile mode) vs glslang (link mode)

ioquatix avatar Aug 11 '16 05:08 ioquatix

What I would recommend is creating an input file. Actually, it's essentially critical you have an input file because on windows at least there is a maximum number of arguments you can pass via the command line before the buffer fills up. We use cmake to generate an input file from proj files.

It's pretty awkward to have different file extensions for different shader stages. It's even more awkward for Vulkan seeing that a pipeline is a collection of shader stages, which seems logical to often want to put in one file. And, for HLSL, the .hlsl extension is actually natively understood and parsed in Visual Studio 2015 so you get alot of the code coloring and I think even some code completion stuff now.

However, generally speaking if you get really serious about compiling lots of shaders you'll wrap your own compiler exe which is what we do. We only use FXC (the standalone HLSL compiler) on spot checks for specific files.

dankbaker avatar Aug 11 '16 15:08 dankbaker

@dankbaker What is an input file? Do you mean a file which lists other paths? Also, just on your point that having a lot of arguments is bad because there is a limit in a specific OS - while I agree that it might be pragmatic, this is a leaky abstraction.

It's pretty awkward to have different file extensions for different shader stages. And, for HLSL, the .hlsl extension is actually natively understood and parsed in Visual Studio 2015 so you get alot of the code coloring and I think even some code completion stuff now.

I had a couple of situations where this was a problem - *.glsl files have syntax highlighting in Atom, but the specific shader extensions don't by default. Agree with you here.

It's even more awkward for Vulkan seeing that a pipeline is a collection of shader stages, which seems logical to often want to put in one file.

In some cases, this might be true, but in other cases we do load and assemble a pipeline using the same vertex shader but different pixel shaders, etc.

However, generally speaking if you get really serious about compiling lots of shaders you'll wrap your own compiler exe which is what we do. We only use FXC (the standalone HLSL compiler) on spot checks for specific files.

That's a interesting approach. Do you publish this code open source somewhere?

ioquatix avatar Aug 12 '16 01:08 ioquatix

That's a interesting approach. Do you publish this code open source somewhere?

No, It's part of the Nitrous Engine. We have our own meta language that sits on top of HLSL and manages more of the logistics of actually creating a material or shader and binding it to the engine somewhere, we call it OXSL for Oxide Shading language, but all the shader parts of it are just pasted into the target platforms compiler. We don't attempt to even parse them. Eventually, we might get to the point where we parse the syntax directly and that would be more elegant. GLSLang might be a good starting point for that customization.

Most game engines have similar systems, That is, complex material systems which layer on top of the shader language. It's easiest just to link in the compiler directly to compile the shaders. I find it pretty unlikely that someone would use the standalone executable of the standalone app in a major project.

dankbaker avatar Aug 12 '16 01:08 dankbaker

That's an interesting approach. I appreciate the unix model where we have lots of small components that do one thing and one thing well, rather than a large vertical.

I did also in the past use a simple syntax which would parse out separate files, something like this:

@shader version=blah

vec3 shared_between_stages;

@vertex

void main() {
 ... vertex shader code
}

@fragment

void main() {
 ... fragment shader code
}

It wasn't a bad approach but I found we ended up duplicating a lot of code. Obviously we could do things like have custom directives (@ prefixed lines). This sounds similar to what you did but perhaps with more high level directives.

ioquatix avatar Aug 12 '16 01:08 ioquatix

Glslang now has command line options to manage file endings. The main thing I see here is the meta-file format, which does not exist. Change the title for that.

johnkslang avatar Apr 03 '17 20:04 johnkslang

Should we close this issue or keep it open?

ioquatix avatar Jun 10 '23 15:06 ioquatix

If you don't plan on working on this yourself, we should close the issue as there are no plans to work on this in the foreseeable future.

arcady-lunarg avatar Jun 12 '23 16:06 arcady-lunarg

Are you willing to accept PRs of this nature?

ioquatix avatar Jun 13 '23 00:06 ioquatix

We're willing to accept PRs that add new features as long as someone is actually using those features and they don't cause issues for the core functionality of glslang. If you are actually going to be using this, I think this would not be an unreasonable addition to glslang.

arcady-lunarg avatar Jun 13 '23 15:06 arcady-lunarg