yum-mirror/slang

Making it easier to work with shaders

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

Harsh Aggarwal (NVIDIA)Fix 7723 - Add autodiff tests (#7919)d10732742

master
5.4 KiB227 linesraw
1//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -shaderobj -output-using-type
2//TEST(compute):COMPARE_COMPUTE_EX:-cuda -compute -shaderobj -output-using-type
3//DISABLE_TEST:SIMPLE(filecheck=CHK):-target hlsl -stage compute -entry computeMain -report-checkpoint-intermediates
4
5//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
6
7RWStructuredBuffer<float> outputBuffer;
8
9struct PathState
10{
11    uint depth;
12    bool terminated;
13
14    bool isHit() { return !terminated; }
15    bool isTerminated() { return terminated; }
16};
17
18struct PathResult : IDifferentiable
19{
20    float thp;
21    float L;
22}
23struct VisibilityQuery
24{
25    bool test();
26}
27
28struct ClosestHitQuery
29{
30    bool test();
31}
32void generatePath(uint pathID, out PathState path)
33{
34    path.terminated = false;
35    path.depth = 0;
36}
37
38[BackwardDifferentiable]
39float lightEval(uint depth)
40{
41    if (depth == 1)
42    {
43        return 5.0f;
44    }
45    else
46    {
47        return 0.0f;
48    }
49}
50
51struct MaterialParam : IDifferentiable
52{
53    float roughness;
54}
55
56[BackwardDifferentiable]
57MaterialParam getParam(uint id)
58{
59    MaterialParam p;
60    p.roughness = 0.5f;
61    return p;
62}
63
64[ForwardDerivativeOf(getParam)]
65DifferentialPair<MaterialParam> d_getParam(uint id)
66{
67    MaterialParam p;
68    p.roughness = 0.5f;
69    MaterialParam.Differential d;
70    d.roughness = 1.0f;
71    return diffPair(p, d);
72}
73
74[BackwardDerivativeOf(getParam)]
75void d_getParam(uint id, MaterialParam.Differential diff)
76{
77    outputBuffer[id] += diff.roughness;
78}
79
80//CHK-DAG: note: checkpointing context of 8 bytes associated with function: 'updatePathThroughput'
81//CHK-DAG: note: 8 bytes (PathResult_0) used to checkpoint the following item:
82[BackwardDifferentiable]
83void updatePathThroughput(inout PathResult path, const float weight)
84{
85    path.thp *= weight;
86}
87
88struct BSDFSample : IDifferentiable
89{
90    float val;
91}
92
93[BackwardDifferentiable]
94bool bsdfGGXSample(const MaterialParam bsdfParams, out BSDFSample result)
95{
96    result.val = bsdfParams.roughness;
97    return true;
98}
99
100[BackwardDifferentiable]
101bool generateScatterRay(const MaterialParam bsdfParams, inout PathState path, inout PathResult pathRes)
102{
103    BSDFSample result;
104    bool valid = bsdfGGXSample(bsdfParams, result);
105    return generateScatterRay(result, bsdfParams, path, pathRes, valid);
106}
107
108/** Generates a new scatter ray using BSDF importance sampling.
109    \param[in] sd Shading data.
110    \param[in] mi Material instance at the shading point.
111    \param[in,out] path The path state.
112    \return True if a ray was generated, false otherwise.
113*/
114[BackwardDifferentiable]
115bool generateScatterRay(const BSDFSample bs, const MaterialParam bsdfParams, inout PathState path, inout PathResult pathRes, bool valid)
116{
117    if (valid) valid = generateScatterRay(bs, bsdfParams, path, pathRes);
118    return valid;
119}
120
121/** Generates a new scatter ray given a valid BSDF sample.
122    \param[in] bs BSDF sample (assumed to be valid).
123    \param[in] sd Shading data.
124    \param[in] mi Material instance at the shading point.
125    \param[in,out] path The path state.
126    \return True if a ray was generated, false otherwise.
127*/
128
129//CHK-DAG: note: checkpointing context of 16 bytes associated with function: 'generateScatterRay'
130[BackwardDifferentiable]
131bool generateScatterRay(const BSDFSample bs, const MaterialParam bsdfParams, inout PathState path, inout PathResult pathRes)
132{
133    //CHK-DAG: note: 8 bytes (s_bwd_prop_updatePathThroughput_Intermediates_0) used to checkpoint the following item:
134    //CHK-DAG: note: 8 bytes (PathResult_0) used to checkpoint the following item:
135    updatePathThroughput(pathRes, bs.val);
136    return true;
137}
138
139[BackwardDifferentiable]
140void handleHit(inout PathState path, inout PathResult rs, inout VisibilityQuery vq)
141{
142    var param = getParam(0);
143
144    bool lastVertex = param.roughness > 0.8;
145    if (lastVertex)
146    {
147        path.terminated = true;
148        return;
149    }
150     
151    generateScatterRay(param, path, rs);
152
153    rs.L = rs.thp * lightEval(path.depth);
154
155    // Decide on next hit
156    if (path.depth < 1)
157        path.terminated = false;
158    else
159        path.terminated = true;
160}
161
162[BackwardDifferentiable]
163float bsdfEval(const MaterialParam mparam)
164{
165    return mparam.roughness;
166}
167
168[BackwardDifferentiable]
169void nextHit(inout PathState path, inout PathResult rs, inout ClosestHitQuery cq)
170{
171    path.depth = path.depth + 1;
172}
173
174[BackwardDifferentiable]
175void handleMiss(inout PathState path, inout PathResult rs)
176{
177    rs.L = 0.0f;
178    path.terminated = true;
179}
180
181[BackwardDifferentiable]
182bool tracePath(uint pathID, out PathState path, inout PathResult pathRes)
183{
184    generatePath(pathID, path);
185
186    float thp = pathRes.thp;
187    float L = pathRes.L;
188
189    for (int i = 0; i < 3; ++i)
190    {
191        if (path.isHit())
192        {
193            VisibilityQuery vq;
194            handleHit(path, pathRes, vq);
195
196            if (path.isTerminated()) break;
197
198            ClosestHitQuery chq;
199            nextHit(path, pathRes, chq);
200        }
201        else
202        {
203            handleMiss(path, pathRes);
204        }
205    }
206    
207    return true;
208}
209
210[numthreads(1, 1, 1)]
211void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID)
212{
213    {
214        PathResult pathRes;
215        pathRes.L = 1.f;
216        pathRes.thp = 1.f;
217
218        PathResult.Differential pathResD;
219        pathResD.L = 1.0f;
220        pathResD.thp = 0.f;
221
222        var dpx = diffPair(pathRes, pathResD);
223        __bwd_diff(tracePath)(1, dpx); // Expect: 5.0 in outputBuffer[3]
224    }
225}
226
227//CHK-NOT: note