yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Jay KwakForce inline functions that takes InputPatch and OutputPatch (#6407)0460eb6a0

master
2.7 KiB100 linesraw
1//TEST:SIMPLE(filecheck=HULL):   -target spirv -stage hull   -entry hullMain
2//TEST:SIMPLE(filecheck=DOMAIN): -target spirv -stage domain -entry domainMain
3
4// Testing if `InputPatch` and `OutputPatch` can be used as function arguments.
5// `[ForceInline]` can be used to workaround but it should work without it.
6
7// HULL: OpEntryPoint TessellationControl %hullMain
8// HULL: = OpVariable %{{[a-zA-Z_0-9]*}} Input
9
10// DOMAIN: OpEntryPoint TessellationEvaluation %domainMain
11// DOMAIN: = OpVariable %{{[a-zA-Z_0-9]*}} Output
12
13struct VS_OUT
14{
15    float3 position : POSITION;
16};
17
18struct HS_OUT
19{
20    float3 position : POSITION;
21};
22
23struct HSC_OUT
24{
25    float EdgeTessFactor[4] : SV_TessFactor;
26    float InsideTessFactor[2] : SV_InsideTessFactor;
27};
28
29struct DS_OUT
30{
31    float4 position : SV_Position;
32};
33
34
35VS_OUT GetInputPatch(InputPatch<VS_OUT, 4> patch, int index)
36{
37    return patch[index];
38}
39
40// Hull Shader (HS)
41[domain("quad")]
42[partitioning("integer")]
43[outputtopology("triangle_cw")]
44[outputcontrolpoints(4)]
45[patchconstantfunc("constants")]
46HS_OUT hullMain(InputPatch<VS_OUT, 4> patch, uint i : SV_OutputControlPointID)
47{
48    HS_OUT o;
49    o.position = patch[i].position;
50    return o;
51}
52
53HSC_OUT constants(InputPatch<VS_OUT, 4> patch)
54{
55    float3 p0 = GetInputPatch(patch, 0).position;
56    float3 p1 = patch[1].position;
57    float3 p2 = patch[2].position;
58    float3 p3 = patch[3].position;
59
60    HSC_OUT o;
61    o.EdgeTessFactor[0] = dot(p0, p1);
62    o.EdgeTessFactor[1] = dot(p0, p3);
63    o.EdgeTessFactor[2] = dot(p2, p3);
64    o.EdgeTessFactor[3] = dot(p1, p2);
65    o.InsideTessFactor[0] = lerp(o.EdgeTessFactor[1], o.EdgeTessFactor[3], 0.5);
66    o.InsideTessFactor[1] = lerp(o.EdgeTessFactor[0], o.EdgeTessFactor[2], 0.5);
67    return o;
68}
69
70HS_OUT GetOutputPatch(const OutputPatch<HS_OUT, 4> patch, int index)
71{
72    return patch[index];
73}
74
75[domain("quad")]
76DS_OUT domainMain(
77    float2 uv : SV_DomainLocation,      // Tessellated coordinates (u, v)
78    const OutputPatch<HS_OUT, 4> patch, // Control points from the hull shader
79    const HSC_OUT patchConstants        // Patch constants calculated by the hull shader
80)
81{
82    DS_OUT o;
83
84    // Interpolate the position of the tessellated point within the patch
85    float3 p0 = GetOutputPatch(patch, 0).position;
86    float3 p1 = patch[1].position;
87    float3 p2 = patch[2].position;
88    float3 p3 = patch[3].position;
89
90    // Bilinear interpolation of the position in the quad
91    float3 interpolatedPosition =
92          p0 * (1 - uv.x) * (1 - uv.y)
93        + p1 * uv.x * (1 - uv.y)
94        + p3 * uv.x * uv.y
95        + p2 * (1 - uv.x) * uv.y;
96
97    // Output final position in clip space
98    o.position = float4(interpolatedPosition, 1.0);
99    return o;
100}