XShaderCompiler icon indicating copy to clipboard operation
XShaderCompiler copied to clipboard

Timeframe for adding geometry shader semantics and other missing features?

Open BearishSun opened this issue 8 years ago • 8 comments

Hey, love this project! Was looking for a shader cross compiler to integrate into my engine (https://github.com/bearishsun/bansheeengine) and this seems like exactly what I need.

I'm wondering do you have a rough timeframe when you might add full support for geometry shaders and (potentially) other missing features? Would love to try integrating it once those features are in.

And as a side note, do you have plans on adding a reflection API so we can query uniforms & vertex inputs? Or just exposing the AST in some way so this information can be easily retrieved (if not already possible)? It could come very handy and avoid having separate reflection code depending on the render API used.

Anyway, keep up the good work.

BearishSun avatar Dec 09 '16 13:12 BearishSun

Thanks for the feedback :) I definitely have planed to support Geometry- and Tessellation Shaders as well. But since I do this in my spare time, I can not give any precise timeframes or deadlines.

In addition to geometry and tessellation, there are a few nice-to-have features, which I don't know if I will implement them at all. One of them are the classes and interfaces in HLSL, because I think it's very hard to translate it to GLSL (subroutines should be the counterpart I guess).

Full access to the AST is not part of the API, but take a look at the Reflection.h file, where a couple of information can be retrieved, such as all attributes of static SamplerState objects for instance. More reflection information may come.

LukasBanana avatar Dec 09 '16 13:12 LukasBanana

Sounds good. Personally I don't care about classes or interfaces - in fact right now I can't think of an engine that actually uses them. Therefore I'd be very happy with a specific minimum subset of functionality, with those less commonly used features left for last (or ignored).

One thing that might be helpful (or not): Generating "binding" qualifiers is very important for GLSL consumed by Vulkan (i.e. converted to SPIR-V). I'm finding them problematic because you pretty much need to explicitly define them in shaders - they can't be auto-generated as shaders get compiled separately, yet they need to be unique across all currently bound shaders - which I'm not sure how to guarantee, other than just explicitly setting the binding indices. I'm guessing you could generate them somehow from HLSL register keywords? Just food for thought, unless you thought about it already.

BearishSun avatar Dec 09 '16 14:12 BearishSun

Do you mean something like the --explicit-bind shell command? Here the binding point is generated from the texture-register slot: GLSLGenerator.cpp.

LukasBanana avatar Dec 09 '16 15:12 LukasBanana

Yep seems like it. As long as a specific register is translated to a specific binding, and that register name maps to the same binding in different shaders.

It might be problematic to deal with different register types, like texture or uniform ones, which need to map to different binding indices across shaders. For example a vertex shader has a constant buffer at b0, and a texture at t0. Ideally constant buffer would map to binding 0, and texture to binding 1. But then what happens when the pixel shader uses the same texture ? When compiled and parsed separately it would receiving binding 0, which is the binding of the constant buffer.

The only decent way of handling that I can think of, is to group bindings into sets (using the "set" qualifier). This way all textures would be in set 0, all constant buffers in set 1, etc. I'm not sure if that has any downsides though.

EDIT: Also, if I'm not mistaken, registers in HLSL are specific to a stage (e.g. separate set of vertex and fragment), are they? In which case separating the bindings per-stage makes more sense - but that eliminates the possibility or sharing the same resource set across all shader stages, which is possible with Vulkan.

BearishSun avatar Dec 09 '16 15:12 BearishSun

Registers in HLSL can be indeed target specific, which is handeld by XShaderCompiler, too. By default, all targets (or rather shader profiles) get the same slot.

But why should it be problematic for uniform buffers and samplers to have the same binding point in GLSL? I see that this is a problem for a "uniform sampler2D" and a "uniform float" for instance, since both are 'standard' uniform qualifiers. But uniform buffers should have there own binding space (correct me if I'm wrong).

LukasBanana avatar Dec 09 '16 16:12 LukasBanana

They don't have their own binding space. Its one shared binding space between all shader stages and all parameter types (uniform buffers, textures, buffers, etc.). You can explicitly pick a different binding space by using the "set" qualifier though.

Not sure if we're misunderstanding each other, so in another words, you can't have same binding for different types in the same shader: layout (binding=0) uniform texture2D mySampledImage; layout (binding=0) uniform myUniformBuffer // Needs to be binding=1 or something other than 0, or a different set { vec4 myElement; };

You also can't have the same binding across shader profiles (if used together): Vertex shader: layout (binding=0) uniform myUniformBuffer { vec4 myElement; };

Pixel shader: layout (binding=0) uniform texture2D mySampledImage; // Needs to be binding=1 or something other than 0, or a different set

BearishSun avatar Dec 09 '16 16:12 BearishSun

Ok, I understand. Maybe in this case, a programmer how knows that a shader will be ported to GLSL should be aware of this issue. It's a similar problem like the lack of Texture/SamplerState-separation. Nonetheless, some kind of reordering of the binding points should be possible, but than host application needs to know the reordered slots, which should be accessible through the shader reflection.

LukasBanana avatar Dec 09 '16 17:12 LukasBanana

Yeah, perhaps just provide a way for the app to specify how to translate registers into bindings (either via a callback, or by providing a builtin way or two). Anyway, just wanted to bring it up in order to keep it in mind :)

BearishSun avatar Dec 09 '16 17:12 BearishSun