yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
d10732742
master
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