Skip to content

Commit 252c44e

Browse files
authored
HLSL: regression test for library-mode emission (#2626)
This removes the need for a special case for default_entry_point and correctly handles exports that call other exports.
1 parent a4e9fe4 commit 252c44e

3 files changed

Lines changed: 96 additions & 2 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
uint add_one(uint x)
2+
{
3+
return x + 1u;
4+
}
5+
6+
uint helper_add(uint a, uint b)
7+
{
8+
return a + b;
9+
}
10+
11+
uint add_two(uint y)
12+
{
13+
uint _22 = y;
14+
uint _23 = 2u;
15+
return helper_add(_22, _23);
16+
}
17+
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
; SPIR-V
2+
; Version: 1.5
3+
; Generator: Khronos SPIR-V Tools Assembler; 0
4+
; Bound: 40
5+
; Schema: 0
6+
OpCapability Linkage
7+
OpCapability Shader
8+
OpMemoryModel Logical GLSL450
9+
OpSource HLSL 630
10+
OpName %add_one "add_one"
11+
OpName %x "x"
12+
OpName %add_two "add_two"
13+
OpName %y "y"
14+
OpName %helper_add "helper_add"
15+
OpName %a "a"
16+
OpName %b "b"
17+
OpDecorate %add_one LinkageAttributes "add_one" Export
18+
OpDecorate %add_two LinkageAttributes "add_two" Export
19+
%uint = OpTypeInt 32 0
20+
%uint_1 = OpConstant %uint 1
21+
%uint_2 = OpConstant %uint 2
22+
%_ptr_Function_uint = OpTypePointer Function %uint
23+
%fn1 = OpTypeFunction %uint %_ptr_Function_uint
24+
%fn2 = OpTypeFunction %uint %_ptr_Function_uint %_ptr_Function_uint
25+
26+
%helper_add = OpFunction %uint None %fn2
27+
%a = OpFunctionParameter %_ptr_Function_uint
28+
%b = OpFunctionParameter %_ptr_Function_uint
29+
%h_bb = OpLabel
30+
%h_av = OpLoad %uint %a
31+
%h_bv = OpLoad %uint %b
32+
%h_sum = OpIAdd %uint %h_av %h_bv
33+
OpReturnValue %h_sum
34+
OpFunctionEnd
35+
36+
%add_one = OpFunction %uint None %fn1
37+
%x = OpFunctionParameter %_ptr_Function_uint
38+
%o_bb = OpLabel
39+
%o_xv = OpLoad %uint %x
40+
%o_r = OpIAdd %uint %o_xv %uint_1
41+
OpReturnValue %o_r
42+
OpFunctionEnd
43+
44+
%add_two = OpFunction %uint None %fn1
45+
%y = OpFunctionParameter %_ptr_Function_uint
46+
%t_bb = OpLabel
47+
%t_arg1 = OpVariable %_ptr_Function_uint Function
48+
%t_arg2 = OpVariable %_ptr_Function_uint Function
49+
%t_yv = OpLoad %uint %y
50+
OpStore %t_arg1 %t_yv
51+
OpStore %t_arg2 %uint_2
52+
%t_r = OpFunctionCall %uint %helper_add %t_arg1 %t_arg2
53+
OpReturnValue %t_r
54+
OpFunctionEnd

test_shaders.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,11 @@ def validate_shader_hlsl(shader, force_no_external_validation, paths):
470470
test_glslang = False
471471
if '.task' in shader or '.mesh' in shader:
472472
test_glslang = False
473+
if shader_is_library(shader):
474+
# Library HLSL output has no entry point; glslangValidator's -e main
475+
# would fail. Skip the round-trip — the output is meant to be
476+
# included by HLSL/GLSL source rather than compiled standalone.
477+
test_glslang = False
473478

474479
hlsl_args = [paths.glslang, '--amb', '-e', 'main', '-D', '--target-env', 'vulkan1.1', '-V', shader]
475480
if '.sm30.' in shader:
@@ -522,7 +527,12 @@ def cross_compile_hlsl(shader, spirv, opt, force_no_external_validation, iterati
522527
spirv_16 = '.spv16.' in shader
523528
spirv_14 = '.spv14.' in shader
524529

525-
if spirv_16:
530+
if shader_is_library(shader):
531+
# Library modules use the Linkage capability, which is rejected
532+
# by Vulkan target envs. Use a universal/spv target instead.
533+
spirv_env = 'spv1.5'
534+
glslang_env = 'spirv1.5'
535+
elif spirv_16:
526536
spirv_env = 'spv1.6'
527537
glslang_env = 'vulkan1.3'
528538
elif spirv_14:
@@ -551,7 +561,14 @@ def cross_compile_hlsl(shader, spirv, opt, force_no_external_validation, iterati
551561

552562
sm = shader_to_sm(shader)
553563

554-
hlsl_args = [spirv_cross_path, '--entry', 'main', '--output', hlsl_path, spirv_path, '--hlsl-enable-compat', '--hlsl', '--shader-model', sm, '--iterations', str(iterations)]
564+
# Library SPIR-V modules (e.g. dxc -T lib_6_*) have no OpEntryPoint;
565+
# skip the --entry flag for those so spirv-cross does not try to
566+
# select an entry point that does not exist.
567+
is_library = shader_is_library(shader)
568+
hlsl_args = [spirv_cross_path]
569+
if not is_library:
570+
hlsl_args += ['--entry', 'main']
571+
hlsl_args += ['--output', hlsl_path, spirv_path, '--hlsl-enable-compat', '--hlsl', '--shader-model', sm, '--iterations', str(iterations)]
555572
if '.line.' in shader:
556573
hlsl_args.append('--emit-line-directives')
557574
if '.flatten.' in shader:
@@ -845,6 +862,12 @@ def shader_is_eliminate_dead_variables(shader):
845862
def shader_is_spirv(shader):
846863
return '.asm.' in shader
847864

865+
def shader_is_library(shader):
866+
# SPIR-V library module: no OpEntryPoint, exports declared via
867+
# OpDecorate ... LinkageAttributes ... Export. Recognised by the
868+
# `.lib` filename suffix (e.g. foo.asm.lib).
869+
return shader.endswith('.lib')
870+
848871
def shader_is_invalid_spirv(shader):
849872
return '.invalid.' in shader
850873

0 commit comments

Comments
 (0)