spirv-cross --hlsl cannot consume SPIR-V "library" modules, that is, modules with OpCapability Linkage, no OpEntryPoint, and one or more functions decorated with OpDecorate LinkageAttributes "" Export. Such modules are produced by dxc -T lib_6_* and are useful for distributing pre-compiled shader libraries that callers can include from HLSL/GLSL source.
Today, parsing fails immediately:
SPIRV-Cross threw an exception: There is no entry point in the SPIR-V module.
at spirv_parser.cpp:155.
Repro:
// lib.hlsl
static const uint table[4] = { 10u, 20u, 30u, 40u };
export uint lookup(uint i) {
return table[i];
}
dxc -T lib_6_3 -spirv -fspv-target-env=universal1.5 lib.hlsl -Fo lib.spv
spirv-cross --hlsl lib.spv
# SPIRV-Cross threw an exception: There is no entry point in the SPIR-V module.
(For the constant table to actually carry its values into the SPV, a separate DXC fix is needed tracked at microsoft/DirectXShaderCompiler#8425. The spirv-cross issue here is independent, even with that fix, spirv-cross can't process the module because there's no entry point.)
Desired Behavior:
When the module has no entry point but does have Export-decorated functions, emit each exported function as a top-level free function in the target language (HLSL/GLSL), with no [numthreads]/main() boilerplate. Output should be includable as a header by HLSL/GLSL source code.
Expected output for the repro:
static const uint table[4] = { 10u, 20u, 30u, 40u };
uint lookup(uint i) {
return table[i];
}
Motivation:
I'd like to distribute the Spark codecs as SPIR-V libraries that users can transform to HLSL/GLSL header-only libraries and include in their shader code.
Proposed approach:
- Parser (spirv_parser.cpp): collect function IDs decorated with LinkageAttributes ... Export. If no OpEntryPoint exists but exports do, synthesize a stub entry point pointing at the first export (model GLCompute) so the rest of the pipeline (analyses keyed on default_entry_point) keeps working. Mark the IR as a library module via a new is_library_module flag on ParsedIR. Fall back to the linkage name when OpName was stripped (e.g. by spirv-opt --strip-debug).
- CFG analysis (spirv_cross.cpp): extend build_function_control_flow_graphs_and_analyze to walk each library export's call tree (not just default_entry_point's).
- HLSL emitter (spirv_hlsl.cpp): in library mode, replace the emit_function(default_entry_point) + emit_hlsl_entry_point() calls with a loop emitting each library export. Skip the main rename. Patch emit_function_prototype so the first export, which happens to be default_entry_point for analysis purposes, is emitted as a normal function, not as the entry point.
- Reachability filter for declarations: in library mode, build a set of IDs referenced anywhere in the SPIR-V stream (excluding each instruction's own result id). Gate emit_specialization_constants_and_structs and emit_composite_constants on that set so unused constants/undefs/specializations don't leak into the output.
I have a working implementation locally on top of vulkan-sdk-1.4.341.0. The HLSL pipeline produces clean, includable output for all our shaders. I'd be happy to open a PR. Would you be open to reviewing it? Or would you suggest a different approach?
spirv-cross --hlslcannot consume SPIR-V "library" modules, that is, modules with OpCapability Linkage, no OpEntryPoint, and one or more functions decorated with OpDecorate LinkageAttributes "" Export. Such modules are produced by dxc -T lib_6_* and are useful for distributing pre-compiled shader libraries that callers can include from HLSL/GLSL source.Today, parsing fails immediately:
SPIRV-Cross threw an exception: There is no entry point in the SPIR-V module.
at spirv_parser.cpp:155.
Repro:
(For the constant table to actually carry its values into the SPV, a separate DXC fix is needed tracked at microsoft/DirectXShaderCompiler#8425. The spirv-cross issue here is independent, even with that fix, spirv-cross can't process the module because there's no entry point.)
Desired Behavior:
When the module has no entry point but does have Export-decorated functions, emit each exported function as a top-level free function in the target language (HLSL/GLSL), with no [numthreads]/main() boilerplate. Output should be includable as a header by HLSL/GLSL source code.
Expected output for the repro:
Motivation:
I'd like to distribute the Spark codecs as SPIR-V libraries that users can transform to HLSL/GLSL header-only libraries and include in their shader code.
Proposed approach:
I have a working implementation locally on top of vulkan-sdk-1.4.341.0. The HLSL pipeline produces clean, includable output for all our shaders. I'd be happy to open a PR. Would you be open to reviewing it? Or would you suggest a different approach?