microsoft / hlsl-specs

HLSL Specifications
MIT License
117 stars 29 forks source link

Annotate entry points inside HLSL source code #267

Open Synxis opened 4 years ago

Synxis commented 4 years ago

Hello !

Currently to compile a shader one needs to specify both the entry point and the shader stage to the compiler:

I think it is better to directly specify the entry points inside the HLSL source. The best solution I see is to add an attribute to the entry points like that: [entry("<stage>")] (or any variation deemed more pleasant obviously).

// some HLSL code...
[entry("vertex")]
float4 simple_projection(float4 pos : SV_Position) : SV_Position
{
    // ...
}
// more code...
[entry("pixel")]
float4 nice_color(float4 pos : SV_Position): SV_Target
{
    // ...
}

The compiler API would be something like Compile(filename, shader_model, options) returning an array of (bytecode, entry_name, shader_stage). This can be done in a backward-compatible fashion. The results for a source with N entry points is N bytecode objects, as if the compiler was called N times.

I really want this and I can try to implement it if you want.

tex3d commented 2 years ago

There is already a supported attribute for DXIL library targets, like: [shader("pixel")], for identifying the entry functions in a library.

The missing piece is producing an array of normal (non-library) compiled shaders from each of the entries exposed in the library. That step could be accomplished with a small utility that introspects a compiled DXIL library and performs a Link operation for each entry point found, producing an array of outputs, either through a collection in a C++ API, or for a command line utility, perhaps a series of output files in a target directory, using some naming convention to include the shader entry name and target profile.

So the outline for the utility would be:

Regarding reflection: Use IDxcUtils::CreateReflection() to create reflection using the ID3D12LibraryReflection interface. Iterate through functions (using GetFunctionByIndex()), use GetDesc() on each function to get the Name and decode the Version token for the shader kind (GetVersionShaderType() in DxilContainer.h - high 16-bits map to `D3D12_SHADER_VERSION_TYPE from d3d12shader.h). Skip functions that are ShaderKind::Library - these are exported library functions, not shader entry points.

damyanp commented 2 months ago

We won't be doing this in DXC, but this scenario is worth considering for Clang, so transferring to hlsl-specs to track future features for shader compilation.