shader-slang / slang

Making it easier to work with shaders
MIT License
1.79k stars 160 forks source link

Define system value semantics in the standard library #411

Open tangent-vector opened 6 years ago

tangent-vector commented 6 years ago

The handling of system-value semantics is going to get messy if we can't systematize it, and unfortunately this is also one part of the compiler where we can expect a reasonable amount of churn when supporting new targets, extensions, etc.

In an ideal world we should be able to define a system-value semantic in the standard library using code like:

[profile(vertex)]
out __systemValue SV_Position : float4;

Here the name of the system value is SV_Position, and it is registered as an out semantic for the vertex profile/stage, with type float4.

Semantics like this would need to occupy their own namespace, distinct from ordinary identifiers, so we might actually register this in the symbol tables with a name like semantic$sv_position (note that we case-fold the semantic name because semantics are case-insensitive).

During the front-end checking of an entry-point function, we should scan its input/output varying signature, and discover any system-value semantics used. This requires a table of known "system-value semantic prefixes", which could either be constructed by the stdlib, or be built into the compiler (with support for extending via API).

For a semantic that matches a known system-value semantic prefix, we'd look for a matching system-value semantic by name. We'd then apply a process similar to function overload resolution to refine a list of "candidate" semantic declarations down to the one we actually can use. If at any step we find that we run out of candidates, we would issue an error message. Error conditions we should diagnose separately include:

One gotcha here is that some system-value semantics may support a variety of different declaration types (e.g., you can write out a float3 for SV_Position). We could either exhaustively enumerate the available cases, or else we could introduce support for generic __systemValue declarations if we really need that degree of flexibility (I'd rather not...).

A few more details to keep track of:

In a completely ideal world, it would be great to be able to treat a system value as if it were a function declaration, so that a read of the given system value turns into a call of the chosen function (a function that returns the value in the in case, or that consumes the value in the out case). That might be feasible in the GLSL output case, but it would take more work to figure out what is needed in the SPIR-V or DXIL output case.

For now, by-hand translation of the system values we care about is probably okay.

csyonghe commented 7 months ago

Q3 language cleanup.