MinimalTraverseShaderLib-pp.hlsl 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792
  1. // RUN: %dxc -T lib_6_3 -HV 2017 -O3 -Zpr -default-linkage external %s | FileCheck %s
  2. // CHECK: define void @"\01?Fallback_TraceRay
  3. #line 1 "dxr-fl\\MinimalTraverseShaderLib.hlsl"
  4. #line 13 "dxr-fl\\MinimalTraverseShaderLib.hlsl"
  5. #line 1 "dxr-fl/TraverseShader.hlsli"
  6. #line 11 "dxr-fl/TraverseShader.hlsli"
  7. #line 1 "dxr-fl/HLSLRaytracingInternalPrototypes.h"
  8. #line 24 "dxr-fl/HLSLRaytracingInternalPrototypes.h"
  9. void Fallback_SetWorldRayOrigin(float3 val);
  10. void Fallback_SetWorldRayDirection(float3 val);
  11. void Fallback_SetRayTMin(float val);
  12. void Fallback_SetRayTCurrent(float val);
  13. void Fallback_SetRayFlags(uint rayFlags);
  14. void Fallback_SetPrimitiveIndex(uint val);
  15. void Fallback_SetInstanceIndex(uint val);
  16. void Fallback_SetInstanceID(uint val);
  17. void Fallback_SetObjectRayOrigin(float3 val);
  18. void Fallback_SetObjectRayDirection(float3 val);
  19. void Fallback_SetObjectToWorld(row_major float3x4 val);
  20. void Fallback_SetWorldToObject(row_major float3x4 val);
  21. void Fallback_SetHitKind(uint val);
  22. void Fallback_SetShaderRecordOffset(uint offset);
  23. void Fallback_SetPendingRayTCurrent(float t);
  24. void Fallback_SetPendingHitKind(uint hitKind);
  25. void Fallback_SetPendingTriVals(uint shaderRecordOffset, uint primitiveIndex, uint instanceIndex, uint instanceID, float t, uint hitKind);
  26. void Fallback_SetPendingCustomVals(uint shaderRecordOffset, uint primitiveIndex, uint instanceIndex, uint instanceID);
  27. uint Fallback_SetPayloadOffset(uint payloadOffset);
  28. uint Fallback_TraceRayBegin(uint rayFlags, float3 origin, float tmin, float3 dir, float tmax, uint newPayloadOffset);
  29. void Fallback_TraceRayEnd(int oldPayloadOffset);
  30. uint Fallback_GroupIndex();
  31. uint Fallback_ShaderRecordOffset();
  32. int Fallback_AnyHitResult();
  33. void Fallback_SetAnyHitResult(int result);
  34. int Fallback_AnyHitStateId();
  35. void Fallback_SetAnyHitStateId(int stateId);
  36. void Fallback_CommitHit();
  37. void Fallback_CallIndirect(int stateId);
  38. void Fallback_Scheduler(int initialStateId, uint dimx, uint dimy);
  39. uint Fallback_InstanceIndex();
  40. float Fallback_RayTCurrent();
  41. #line 11 "dxr-fl/TraverseShader.hlsli"
  42. #line 1 "dxr-fl/UberShaderBindings.h"
  43. #line 12 "dxr-fl/UberShaderBindings.h"
  44. #line 1 "dxr-fl/FallbackDebug.h"
  45. #line 12 "dxr-fl/UberShaderBindings.h"
  46. #line 1 "dxr-fl/FallbackDxil.h"
  47. #line 13 "dxr-fl/UberShaderBindings.h"
  48. #line 1 "dxr-fl/ShaderUtil.hlsli"
  49. #line 18 "dxr-fl/UberShaderBindings.h"
  50. struct DebugVariables
  51. {
  52. uint LevelToVisualize;
  53. };
  54. cbuffer Constants : register(b0, space214743647)
  55. {
  56. uint RayDispatchDimensionsWidth;
  57. uint RayDispatchDimensionsHeight;
  58. uint HitGroupShaderRecordStride;
  59. uint MissShaderRecordStride;
  60. uint SamplerDescriptorHeapStartLo;
  61. uint SamplerDescriptorHeapStartHi;
  62. uint SrvCbvUavDescriptorHeapStartLo;
  63. uint SrvCbvUavDescriptorHeapStartHi;
  64. };
  65. cbuffer AccelerationStructureList : register(b1, space214743647)
  66. {
  67. uint2 TopLevelAccelerationStructureGpuVA;
  68. };
  69. ByteAddressBuffer HitGroupShaderTable : register(t0, space214743647);
  70. ByteAddressBuffer MissShaderTable : register(t1, space214743647);
  71. ByteAddressBuffer RayGenShaderTable : register(t2, space214743647);
  72. ByteAddressBuffer CallableShaderTable : register(t3, space214743647);
  73. RWByteAddressBuffer DescriptorHeapBufferTable[] : register(u0, space214743648);
  74. #line 15 "dxr-fl/TraverseShader.hlsli"
  75. #line 1 "dxr-fl/DebugLog.h"
  76. #line 27 "dxr-fl/DebugLog.h"
  77. void BeginLog();
  78. void LogInt(int val);
  79. void LogInt2(int2 val);
  80. void LogInt3(int3 val);
  81. void LogFloat(float val);
  82. void LogFloat3(float3 val);
  83. void LogTraceRayStart();
  84. void LogTraceRayEnd();
  85. #line 16 "dxr-fl/TraverseShader.hlsli"
  86. #line 1 "dxr-fl/RayTracingHelper.hlsli"
  87. #line 14 "dxr-fl/RayTracingHelper.hlsli"
  88. #line 1 "dxr-fl/EmulatedPointer.hlsli"
  89. #line 18 "dxr-fl/EmulatedPointer.hlsli"
  90. uint2 PointerAdd(uint2 address, uint offset)
  91. {
  92. address[0] += offset;
  93. return address;
  94. }
  95. struct RWByteAddressBufferPointer
  96. {
  97. RWByteAddressBuffer buffer;
  98. uint offsetInBytes;
  99. };
  100. static
  101. RWByteAddressBufferPointer CreateRWByteAddressBufferPointer(in RWByteAddressBuffer buffer, uint offsetInBytes)
  102. {
  103. RWByteAddressBufferPointer pointer;
  104. pointer.buffer = buffer;
  105. pointer.offsetInBytes = offsetInBytes;
  106. return pointer;
  107. }
  108. #line 14 "dxr-fl/RayTracingHelper.hlsli"
  109. #line 1 "dxr-fl/RayTracingHlslCompat.h"
  110. #line 13 "dxr-fl/RayTracingHlslCompat.h"
  111. #line 1 "dxr-fl/WaveDimensions.h"
  112. #line 13 "dxr-fl/RayTracingHlslCompat.h"
  113. #line 46 "dxr-fl/RayTracingHlslCompat.h"
  114. struct HierarchyNode
  115. {
  116. uint ParentIndex;
  117. uint LeftChildIndex;
  118. uint RightChildIndex;
  119. static const int IsCollapseChildren = 0x80000000;
  120. };
  121. struct AABB
  122. {
  123. float3 min;
  124. float3 max;
  125. #line 77 "dxr-fl/RayTracingHlslCompat.h"
  126. };
  127. void AABBToRawData(in AABB aabb, out uint4 a, out uint2 b)
  128. {
  129. a = asuint(float4(aabb.min.xyz, aabb.max.x));
  130. b = asuint(float2(aabb.max.yz));
  131. }
  132. struct Triangle
  133. {
  134. float3 v0;
  135. float3 v1;
  136. float3 v2;
  137. #line 107 "dxr-fl/RayTracingHlslCompat.h"
  138. };
  139. Triangle RawDataToTriangle(uint4 a, uint4 b, uint c)
  140. {
  141. Triangle tri;
  142. tri.v0 = asfloat(a.xyz);
  143. tri.v1 = asfloat(uint3(a.w, b.xy));
  144. tri.v2 = asfloat(uint3(b.zw, c));
  145. return tri;
  146. }
  147. void TriangleToRawData(in Triangle tri, out uint4 a, out uint4 b, out uint c)
  148. {
  149. a = asuint(float4(tri.v0.xyz, tri.v1.x));
  150. b = asuint(float4(tri.v1.yz, tri.v2.xy));
  151. c = asuint(tri.v2.z);
  152. }
  153. struct Primitive
  154. {
  155. uint PrimitiveType;
  156. uint4 data0;
  157. uint4 data1;
  158. uint data2;
  159. };
  160. Primitive NullPrimitive()
  161. {
  162. Primitive primitive;
  163. primitive.PrimitiveType = 0;
  164. primitive.data0 = 0;
  165. primitive.data1 = 0;
  166. primitive.data2 = 0;
  167. return primitive;
  168. }
  169. Primitive CreateProceduralGeometryPrimitive(AABB aabb)
  170. {
  171. Primitive primitive = NullPrimitive();
  172. primitive.PrimitiveType = 0x2;
  173. AABBToRawData(aabb, primitive.data0, primitive.data1.xy);
  174. return primitive;
  175. }
  176. Primitive CreateTrianglePrimitive(Triangle tri)
  177. {
  178. Primitive primitive = NullPrimitive();
  179. primitive.PrimitiveType = 0x1;
  180. TriangleToRawData(tri, primitive.data0, primitive.data1, primitive.data2);
  181. return primitive;
  182. }
  183. Triangle GetTriangle(Primitive prim)
  184. {
  185. return RawDataToTriangle(prim.data0, prim.data1, prim.data2);
  186. }
  187. AABB GetProceduralPrimitiveAABB(Primitive prim)
  188. {
  189. AABB aabb;
  190. aabb.min = asfloat(prim.data0.xyz);
  191. aabb.max = asfloat(uint3(prim.data0.w, prim.data1.xy));
  192. return aabb;
  193. }
  194. #line 197 "dxr-fl/RayTracingHlslCompat.h"
  195. struct PrimitiveMetaData
  196. {
  197. uint GeometryContributionToHitGroupIndex;
  198. uint PrimitiveIndex;
  199. uint GeometryFlags;
  200. };
  201. #line 213 "dxr-fl/RayTracingHlslCompat.h"
  202. float3x4 CreateMatrix(float4 rows[3])
  203. {
  204. float3x4 mat;
  205. mat[0] = rows[0];
  206. mat[1] = rows[1];
  207. mat[2] = rows[2];
  208. return mat;
  209. }
  210. static const uint D3D12_RAYTRACING_INSTANCE_FLAG_NONE = 0;
  211. static const uint D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_CULL_DISABLE = 0x1;
  212. static const uint D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE = 0x2;
  213. static const uint D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_OPAQUE = 0x4;
  214. static const uint D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_NON_OPAQUE = 0x8;
  215. static const uint D3D12_RAYTRACING_GEOMETRY_FLAG_NONE = 0;
  216. static const uint D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE = 0x1;
  217. static const uint D3D12_RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION = 0x2;
  218. struct RaytracingInstanceDesc
  219. {
  220. float4 Transform[3];
  221. uint InstanceIDAndMask;
  222. uint InstanceContributionToHitGroupIndexAndFlags;
  223. uint2 AccelerationStructure;
  224. };
  225. struct BVHMetadata
  226. {
  227. RaytracingInstanceDesc instanceDesc;
  228. float4 ObjectToWorld[3];
  229. uint InstanceIndex;
  230. };
  231. static
  232. void StoreBVHMetadataToRawData(RWByteAddressBuffer buffer, uint offset, BVHMetadata metadata)
  233. {
  234. uint4 data[7];
  235. uint dataRemainder;
  236. data[0] = asuint(metadata.instanceDesc.Transform[0]);
  237. data[1] = asuint(metadata.instanceDesc.Transform[1]);
  238. data[2] = asuint(metadata.instanceDesc.Transform[2]);
  239. data[3].x = metadata.instanceDesc.InstanceIDAndMask;
  240. data[3].y = metadata.instanceDesc.InstanceContributionToHitGroupIndexAndFlags;
  241. data[3].zw = metadata.instanceDesc.AccelerationStructure;
  242. data[4] = asuint(metadata.ObjectToWorld[0]);
  243. data[5] = asuint(metadata.ObjectToWorld[1]);
  244. data[6] = asuint(metadata.ObjectToWorld[2]);
  245. dataRemainder = metadata.InstanceIndex;
  246. [unroll]
  247. for (uint i = 0; i < 7; i++)
  248. {
  249. buffer.Store4(offset, data[i]);
  250. offset += 16;
  251. }
  252. buffer.Store(offset, dataRemainder);
  253. }
  254. RaytracingInstanceDesc RawDataToRaytracingInstanceDesc(uint4 a, uint4 b, uint4 c, uint4 d)
  255. {
  256. RaytracingInstanceDesc desc;
  257. desc.Transform[0] = asfloat(a);
  258. desc.Transform[1] = asfloat(b);
  259. desc.Transform[2] = asfloat(c);
  260. desc.InstanceIDAndMask = d.x;
  261. desc.InstanceContributionToHitGroupIndexAndFlags = d.y;
  262. desc.AccelerationStructure = d.zw;
  263. return desc;
  264. }
  265. static
  266. BVHMetadata LoadBVHMetadata(RWByteAddressBuffer buffer, uint offset)
  267. {
  268. uint4 data[7];
  269. [unroll]
  270. for (uint i = 0; i < 7; i++)
  271. {
  272. data[i] = buffer.Load4(offset);
  273. offset += 16;
  274. }
  275. BVHMetadata metadata;
  276. metadata.instanceDesc = RawDataToRaytracingInstanceDesc(data[0], data[1], data[2], data[3]);
  277. metadata.ObjectToWorld[0] = asfloat(data[4]);
  278. metadata.ObjectToWorld[1] = asfloat(data[5]);
  279. metadata.ObjectToWorld[2] = asfloat(data[6]);
  280. metadata.InstanceIndex = buffer.Load(offset);
  281. return metadata;
  282. }
  283. static
  284. RaytracingInstanceDesc LoadRaytracingInstanceDesc(RWByteAddressBuffer buffer, uint offset)
  285. {
  286. uint4 data[4];
  287. [unroll]
  288. for (uint i = 0; i < 4; i++)
  289. {
  290. data[i] = buffer.Load4(offset + 16 * i);
  291. }
  292. return RawDataToRaytracingInstanceDesc(data[0], data[1], data[2], data[3]);
  293. }
  294. static
  295. RaytracingInstanceDesc LoadRaytracingInstanceDesc(ByteAddressBuffer buffer, uint offset)
  296. {
  297. uint4 data[4];
  298. [unroll]
  299. for (uint i = 0; i < 4; i++)
  300. {
  301. data[i] = buffer.Load4(offset + 16 * i);
  302. }
  303. return RawDataToRaytracingInstanceDesc(data[0], data[1], data[2], data[3]);
  304. }
  305. uint GetInstanceContributionToHitGroupIndex(RaytracingInstanceDesc desc)
  306. {
  307. return desc.InstanceContributionToHitGroupIndexAndFlags & 0xffffff;
  308. }
  309. uint GetInstanceFlags(RaytracingInstanceDesc desc)
  310. {
  311. return desc.InstanceContributionToHitGroupIndexAndFlags >> 24;
  312. }
  313. uint GetInstanceMask(RaytracingInstanceDesc desc)
  314. {
  315. return desc.InstanceIDAndMask >> 24;
  316. }
  317. uint GetInstanceID(RaytracingInstanceDesc desc)
  318. {
  319. return desc.InstanceIDAndMask & 0xFFFFFF;
  320. }
  321. struct AABBNodeSibling
  322. {
  323. uint childIndex;
  324. #line 375 "dxr-fl/RayTracingHlslCompat.h"
  325. float center[3];
  326. float halfDim[3];
  327. uint primitiveFlags;
  328. #line 389 "dxr-fl/RayTracingHlslCompat.h"
  329. };
  330. struct AABBNode
  331. {
  332. AABBNodeSibling left;
  333. AABBNodeSibling right;
  334. };
  335. struct BVHOffsets
  336. {
  337. uint offsetToBoxes;
  338. uint offsetToVertices;
  339. uint offsetToPrimitiveMetaData;
  340. uint totalSize;
  341. };
  342. inline
  343. uint GetNumInternalNodes(uint numLeaves)
  344. {
  345. return numLeaves - 1;
  346. }
  347. inline
  348. uint GetNumAABBNodes(uint numLeaves)
  349. {
  350. return numLeaves <= 1 ? 1 : GetNumInternalNodes(numLeaves);
  351. }
  352. inline
  353. uint GetOffsetFromSortedIndicesToAABBParents(uint numPrimitives) {
  354. return 4 * numPrimitives;
  355. }
  356. inline
  357. uint GetOffsetToBVHMetadata(uint numElements)
  358. {
  359. return (4 * 4) + GetNumAABBNodes(numElements) * ((8 * 4) * 2);
  360. }
  361. inline
  362. uint GetOffsetToBVHSortedIndices(uint numElements) {
  363. return GetOffsetToBVHMetadata(numElements) + 116 * numElements;
  364. }
  365. inline
  366. uint GetOffsetFromPrimitiveMetaDataToSortedIndices(uint numPrimitives)
  367. {
  368. return (4 * 3) * numPrimitives;
  369. }
  370. inline
  371. uint GetOffsetFromPrimitivesToPrimitiveMetaData(uint numPrimitives)
  372. {
  373. return 40 * numPrimitives;
  374. }
  375. inline
  376. uint GetOffsetToPrimitives(uint numElements)
  377. {
  378. return (4 * 4) + GetNumAABBNodes(numElements) * ((8 * 4) * 2);
  379. }
  380. #line 15 "dxr-fl/RayTracingHelper.hlsli"
  381. #line 1 "dxr-fl/ShaderUtil.hlsli"
  382. #line 16 "dxr-fl/RayTracingHelper.hlsli"
  383. static const int IsLeafFlag = 0x80000000;
  384. static const int IsProceduralGeometryFlag = 0x40000000;
  385. static const int IsDummyFlag = 0x20000000;
  386. static const int LeafFlags = IsLeafFlag | IsProceduralGeometryFlag | IsDummyFlag;
  387. static const int MinNumberOfPrimitives = 1;
  388. static const int MinNumberOfLeafNodeBVHs = 1;
  389. #line 43 "dxr-fl/RayTracingHelper.hlsli"
  390. static const int OffsetToBoxesOffset = 0;
  391. static const int OffsetToPrimitivesOffset = 4;
  392. static const int OffsetToPrimitiveMetaDataOffset = 8;
  393. static const int OffsetToLeafNodeMetaDataOffset = 4;
  394. static const int OffsetToTotalSize = 12;
  395. int GetLeafIndexFromFlag(uint2 flag)
  396. {
  397. return flag.x & ~LeafFlags;
  398. }
  399. uint GetActualParentIndex(uint index)
  400. {
  401. return index & ~HierarchyNode::IsCollapseChildren;
  402. }
  403. struct BoundingBox
  404. {
  405. float3 center;
  406. float3 halfDim;
  407. };
  408. static
  409. int GetOffsetToAABBNodes(RWByteAddressBufferPointer pointer)
  410. {
  411. return pointer.offsetInBytes + (4 * 4);
  412. }
  413. static
  414. int GetOffsetToVertices(RWByteAddressBufferPointer pointer)
  415. {
  416. return pointer.buffer.Load(OffsetToPrimitivesOffset + pointer.offsetInBytes) + pointer.offsetInBytes;
  417. }
  418. static
  419. int GetOffsetToPrimitiveMetaData(RWByteAddressBufferPointer pointer)
  420. {
  421. return pointer.buffer.Load(OffsetToPrimitiveMetaDataOffset + pointer.offsetInBytes) + pointer.offsetInBytes;
  422. }
  423. bool IsLeaf(uint2 info)
  424. {
  425. return (info.y & IsLeafFlag);
  426. }
  427. bool IsProceduralGeometry(uint2 info)
  428. {
  429. return (info.y & IsProceduralGeometryFlag);
  430. }
  431. bool IsDummy(uint2 info)
  432. {
  433. return (info.y & IsDummyFlag);
  434. }
  435. uint GetLeafIndexFromInfo(uint2 info)
  436. {
  437. return info.x;
  438. }
  439. uint GetChildIndexFromInfo(uint2 info)
  440. {
  441. return info.x;
  442. }
  443. uint GetLeafFlagsFromPrimitiveFlags(uint flags)
  444. {
  445. return flags & LeafFlags;
  446. }
  447. uint GetNumPrimitivesFromPrimitiveFlags(uint flags)
  448. {
  449. return flags & ~LeafFlags;
  450. }
  451. uint GetNumPrimitivesFromInfo(uint2 info)
  452. {
  453. return GetNumPrimitivesFromPrimitiveFlags(info.y);
  454. }
  455. uint CombinePrimitiveFlags(uint flags1, uint flags2)
  456. {
  457. uint combinedFlags = GetLeafFlagsFromPrimitiveFlags(flags1)
  458. | GetLeafFlagsFromPrimitiveFlags(flags2);
  459. combinedFlags &= ~(IsLeafFlag | IsDummyFlag);
  460. uint combinedPrimitives = GetNumPrimitivesFromPrimitiveFlags(flags1)
  461. + GetNumPrimitivesFromPrimitiveFlags(flags2);
  462. return combinedFlags | combinedPrimitives;
  463. }
  464. uint GetAABBNodeAddress(uint startAddress, uint boxIndex)
  465. {
  466. return startAddress + boxIndex * ((8 * 4) * 2);
  467. }
  468. BoundingBox CreateDummyBox(out uint2 info)
  469. {
  470. BoundingBox box;
  471. info = uint2(0, IsLeafFlag | IsDummyFlag);
  472. return box;
  473. }
  474. static
  475. void CompressBox(BoundingBox box, uint childIndex, uint primitiveFlags, out uint4 data1, out uint4 data2)
  476. {
  477. data1.x = childIndex;
  478. data1.y = asuint(box.center.x);
  479. data1.z = asuint(box.center.y);
  480. data1.w = asuint(box.center.z);
  481. data2.x = asuint(box.halfDim.x);
  482. data2.y = asuint(box.halfDim.y);
  483. data2.z = asuint(box.halfDim.z);
  484. data2.w = primitiveFlags;
  485. }
  486. static
  487. void WriteBoxToBuffer(
  488. RWByteAddressBuffer buffer,
  489. uint boxAddress,
  490. BoundingBox box,
  491. uint2 extraInfo)
  492. {
  493. uint4 data1, data2;
  494. CompressBox(box, extraInfo.x, extraInfo.y, data1, data2);
  495. buffer.Store4(boxAddress, data1);
  496. buffer.Store4(boxAddress + 16, data2);
  497. }
  498. static
  499. void WriteLeftBoxToBuffer(
  500. RWByteAddressBuffer buffer,
  501. uint nodeStartOffset,
  502. uint nodeIndex,
  503. BoundingBox box,
  504. uint2 extraInfo)
  505. {
  506. uint boxAddress = GetAABBNodeAddress(nodeStartOffset, nodeIndex);
  507. WriteBoxToBuffer(buffer, boxAddress, box, extraInfo);
  508. }
  509. static
  510. void WriteRightBoxToBuffer(
  511. RWByteAddressBuffer buffer,
  512. uint nodeStartOffset,
  513. uint nodeIndex,
  514. BoundingBox box,
  515. uint2 extraInfo)
  516. {
  517. uint boxAddress = GetAABBNodeAddress(nodeStartOffset, nodeIndex) + (8 * 4);
  518. WriteBoxToBuffer(buffer, boxAddress, box, extraInfo);
  519. }
  520. static
  521. BoundingBox RawDataToBoundingBox(uint4 a, uint4 b, out uint2 extraInfo)
  522. {
  523. BoundingBox box;
  524. box.center.x = asfloat(a.y);
  525. box.center.y = asfloat(a.z);
  526. box.center.z = asfloat(a.w);
  527. box.halfDim.x = asfloat(b.x);
  528. box.halfDim.y = asfloat(b.y);
  529. box.halfDim.z = asfloat(b.z);
  530. extraInfo.x = a.x;
  531. extraInfo.y = b.w;
  532. return box;
  533. }
  534. static
  535. BoundingBox GetBoxFromBuffer(RWByteAddressBuffer buffer, uint aabbNodeAddress, out uint2 extraInfo)
  536. {
  537. uint4 data1 = buffer.Load4(aabbNodeAddress);
  538. uint4 data2 = buffer.Load4(aabbNodeAddress + 16);
  539. return RawDataToBoundingBox(data1, data2, extraInfo);
  540. }
  541. static
  542. BoundingBox GetLeftBoxFromBuffer(
  543. RWByteAddressBuffer buffer,
  544. uint nodeStartOffset,
  545. uint parentNodeIndex,
  546. out uint2 extraInfo)
  547. {
  548. uint aabbNodeAddress = GetAABBNodeAddress(nodeStartOffset, parentNodeIndex);
  549. return GetBoxFromBuffer(buffer, aabbNodeAddress, extraInfo);
  550. }
  551. static
  552. BoundingBox GetRightBoxFromBuffer(
  553. RWByteAddressBuffer buffer,
  554. uint nodeStartOffset,
  555. uint parentNodeIndex,
  556. out uint2 extraInfo)
  557. {
  558. uint aabbNodeAddress = GetAABBNodeAddress(nodeStartOffset, parentNodeIndex) + (8 * 4);
  559. return GetBoxFromBuffer(buffer, aabbNodeAddress, extraInfo);
  560. }
  561. static
  562. BoundingBox GetLeftBoxFromBVH(RWByteAddressBufferPointer pointer, int nodeIndex, out uint2 extraInfo)
  563. {
  564. uint nodeStartOffset = GetOffsetToAABBNodes(pointer);
  565. uint aabbNodeAddress = GetAABBNodeAddress(nodeStartOffset, nodeIndex);
  566. return GetBoxFromBuffer(pointer.buffer, aabbNodeAddress, extraInfo);
  567. }
  568. static
  569. BoundingBox GetRightBoxFromBVH(RWByteAddressBufferPointer pointer, int nodeIndex, out uint2 extraInfo)
  570. {
  571. uint nodeStartOffset = GetOffsetToAABBNodes(pointer);
  572. uint aabbNodeAddress = GetAABBNodeAddress(nodeStartOffset, nodeIndex) + (8 * 4);
  573. return GetBoxFromBuffer(pointer.buffer, aabbNodeAddress, extraInfo);
  574. }
  575. #line 288 "dxr-fl/RayTracingHelper.hlsli"
  576. uint GetPrimitiveMetaDataAddress(uint startAddress, uint triangleIndex)
  577. {
  578. return startAddress + triangleIndex * (4 * 3);
  579. }
  580. static
  581. PrimitiveMetaData BVHReadPrimitiveMetaData(RWByteAddressBufferPointer pointer, int primitiveIndex)
  582. {
  583. const uint readAddress = GetPrimitiveMetaDataAddress(GetOffsetToPrimitiveMetaData(pointer), primitiveIndex);
  584. PrimitiveMetaData metadata;
  585. const uint3 a = pointer.buffer.Load3(readAddress);
  586. metadata.GeometryContributionToHitGroupIndex = a.x;
  587. metadata.PrimitiveIndex = a.y;
  588. metadata.GeometryFlags = a.z;
  589. return metadata;
  590. }
  591. static
  592. void BVHReadTriangle(
  593. RWByteAddressBufferPointer pointer,
  594. out float3 v0,
  595. out float3 v1,
  596. out float3 v2,
  597. uint triId)
  598. {
  599. uint baseOffset = GetOffsetToVertices(pointer) + triId * 40
  600. + 4;
  601. const float4 a = asfloat(pointer.buffer.Load4(baseOffset));
  602. const float4 b = asfloat(pointer.buffer.Load4(baseOffset + 16));
  603. const float c = asfloat(pointer.buffer.Load(baseOffset + 32));
  604. v0 = a.xyz;
  605. v1 = float3(a.w, b.xy);
  606. v2 = float3(b.zw, c);
  607. }
  608. static
  609. BoundingBox AABBtoBoundingBox(AABB aabb)
  610. {
  611. BoundingBox box;
  612. box.center = (aabb.min + aabb.max) * 0.5f;
  613. box.halfDim = aabb.max - box.center;
  614. return box;
  615. }
  616. static
  617. AABB BoundingBoxToAABB(BoundingBox boundingBox)
  618. {
  619. AABB aabb;
  620. aabb.min = boundingBox.center - boundingBox.halfDim;
  621. aabb.max = boundingBox.center + boundingBox.halfDim;
  622. return aabb;
  623. }
  624. static
  625. AABB RawDataToAABB(int4 a, int4 b)
  626. {
  627. uint2 unusedInfo;
  628. return BoundingBoxToAABB(RawDataToBoundingBox(a, b, unusedInfo));
  629. }
  630. static
  631. BoundingBox GetBoxDataFromTriangle(float3 v0, float3 v1, float3 v2, int triangleIndex, out uint2 triangleInfo)
  632. {
  633. AABB aabb;
  634. aabb.min = min(min(v0, v1), v2);
  635. aabb.max = max(max(v0, v1), v2);
  636. aabb.min = min(aabb.min, aabb.max - 0.001);
  637. BoundingBox box = AABBtoBoundingBox(aabb);
  638. triangleInfo.x = triangleIndex;
  639. triangleInfo.y = IsLeafFlag | MinNumberOfPrimitives;
  640. return box;
  641. }
  642. float3 GetMinCorner(BoundingBox box)
  643. {
  644. return box.center - box.halfDim;
  645. }
  646. float3 GetMaxCorner(BoundingBox box)
  647. {
  648. return box.center + box.halfDim;
  649. }
  650. AABB GetAABBFromChildBoxes(BoundingBox boxA, BoundingBox boxB)
  651. {
  652. AABB aabb;
  653. aabb.min = min(GetMinCorner(boxA), GetMinCorner(boxB));
  654. aabb.max = max(GetMaxCorner(boxA), GetMaxCorner(boxB));
  655. return aabb;
  656. }
  657. BoundingBox GetBoxFromChildBoxes(BoundingBox boxA, BoundingBox boxB)
  658. {
  659. return AABBtoBoundingBox(GetAABBFromChildBoxes(boxA, boxB));
  660. }
  661. float Determinant(in float3x4 transform)
  662. {
  663. return transform[0][0] * transform[1][1] * transform[2][2] -
  664. transform[0][0] * transform[2][1] * transform[1][2] -
  665. transform[1][0] * transform[0][1] * transform[2][2] +
  666. transform[1][0] * transform[2][1] * transform[0][2] +
  667. transform[2][0] * transform[0][1] * transform[1][2] -
  668. transform[2][0] * transform[1][1] * transform[0][2];
  669. }
  670. float3x4 InverseAffineTransform(float3x4 transform)
  671. {
  672. const float invDet = rcp(Determinant(transform));
  673. float3x4 invertedTransform;
  674. invertedTransform[0][0] = invDet * (transform[1][1] * (transform[2][2] * 1.0f - 0.0f * transform[2][3]) + transform[2][1] * (0.0f * transform[1][3] - transform[1][2] * 1.0f) + 0.0f * (transform[1][2] * transform[2][3] - transform[2][2] * transform[1][3]));
  675. invertedTransform[1][0] = invDet * (transform[1][2] * (transform[2][0] * 1.0f - 0.0f * transform[2][3]) + transform[2][2] * (0.0f * transform[1][3] - transform[1][0] * 1.0f) + 0.0f * (transform[1][0] * transform[2][3] - transform[2][0] * transform[1][3]));
  676. invertedTransform[2][0] = invDet * (transform[1][3] * (transform[2][0] * 0.0f - 0.0f * transform[2][1]) + transform[2][3] * (0.0f * transform[1][1] - transform[1][0] * 0.0f) + 1.0f * (transform[1][0] * transform[2][1] - transform[2][0] * transform[1][1]));
  677. invertedTransform[0][1] = invDet * (transform[2][1] * (transform[0][2] * 1.0f - 0.0f * transform[0][3]) + 0.0f * (transform[2][2] * transform[0][3] - transform[0][2] * transform[2][3]) + transform[0][1] * (0.0f * transform[2][3] - transform[2][2] * 1.0f));
  678. invertedTransform[1][1] = invDet * (transform[2][2] * (transform[0][0] * 1.0f - 0.0f * transform[0][3]) + 0.0f * (transform[2][0] * transform[0][3] - transform[0][0] * transform[2][3]) + transform[0][2] * (0.0f * transform[2][3] - transform[2][0] * 1.0f));
  679. invertedTransform[2][1] = invDet * (transform[2][3] * (transform[0][0] * 0.0f - 0.0f * transform[0][1]) + 1.0f * (transform[2][0] * transform[0][1] - transform[0][0] * transform[2][1]) + transform[0][3] * (0.0f * transform[2][1] - transform[2][0] * 0.0f));
  680. invertedTransform[0][2] = invDet * (0.0f * (transform[0][2] * transform[1][3] - transform[1][2] * transform[0][3]) + transform[0][1] * (transform[1][2] * 1.0f - 0.0f * transform[1][3]) + transform[1][1] * (0.0f * transform[0][3] - transform[0][2] * 1.0f));
  681. invertedTransform[1][2] = invDet * (0.0f * (transform[0][0] * transform[1][3] - transform[1][0] * transform[0][3]) + transform[0][2] * (transform[1][0] * 1.0f - 0.0f * transform[1][3]) + transform[1][2] * (0.0f * transform[0][3] - transform[0][0] * 1.0f));
  682. invertedTransform[2][2] = invDet * (1.0f * (transform[0][0] * transform[1][1] - transform[1][0] * transform[0][1]) + transform[0][3] * (transform[1][0] * 0.0f - 0.0f * transform[1][1]) + transform[1][3] * (0.0f * transform[0][1] - transform[0][0] * 0.0f));
  683. invertedTransform[0][3] = invDet * (transform[0][1] * (transform[2][2] * transform[1][3] - transform[1][2] * transform[2][3]) + transform[1][1] * (transform[0][2] * transform[2][3] - transform[2][2] * transform[0][3]) + transform[2][1] * (transform[1][2] * transform[0][3] - transform[0][2] * transform[1][3]));
  684. invertedTransform[1][3] = invDet * (transform[0][2] * (transform[2][0] * transform[1][3] - transform[1][0] * transform[2][3]) + transform[1][2] * (transform[0][0] * transform[2][3] - transform[2][0] * transform[0][3]) + transform[2][2] * (transform[1][0] * transform[0][3] - transform[0][0] * transform[1][3]));
  685. invertedTransform[2][3] = invDet * (transform[0][3] * (transform[2][0] * transform[1][1] - transform[1][0] * transform[2][1]) + transform[1][3] * (transform[0][0] * transform[2][1] - transform[2][0] * transform[0][1]) + transform[2][3] * (transform[1][0] * transform[0][1] - transform[0][0] * transform[1][1]));
  686. return invertedTransform;
  687. }
  688. AABB TransformAABB(AABB box, float3x4 transform)
  689. {
  690. const uint verticesPerAABB = 8;
  691. float4 boxVertices[verticesPerAABB];
  692. boxVertices[0] = float4(box.min, 1.0);
  693. boxVertices[1] = float4(box.min.xy, box.max.z, 1.0);
  694. boxVertices[2] = float4(box.min.x, box.max.yz, 1.0);
  695. boxVertices[3] = float4(box.min.x, box.max.y, box.min.z, 1.0);
  696. boxVertices[4] = float4(box.max.x, box.min.yz, 1.0);
  697. boxVertices[6] = float4(box.max.x, box.min.y, box.max.z, 1.0);
  698. boxVertices[5] = float4(box.max.xy, box.min.z, 1.0);
  699. boxVertices[7] = float4(box.max, 1.0);
  700. AABB transformedBox;
  701. transformedBox.min = float3(asfloat(0x7F7FFFFF), asfloat(0x7F7FFFFF), asfloat(0x7F7FFFFF));
  702. transformedBox.max = float3(-asfloat(0x7F7FFFFF), -asfloat(0x7F7FFFFF), -asfloat(0x7F7FFFFF));
  703. for (uint i = 0; i < verticesPerAABB; i++)
  704. {
  705. float3 tranformedVertex = mul(transform, boxVertices[i]);
  706. transformedBox.min = min(transformedBox.min, tranformedVertex);
  707. transformedBox.max = max(transformedBox.max, tranformedVertex);
  708. }
  709. return transformedBox;
  710. }
  711. static const uint OffsetToAnyHitStateId = 4;
  712. static const uint OffsetToIntersectionStateId = 8;
  713. static
  714. uint GetAnyHitStateId(ByteAddressBuffer shaderTable, uint recordOffset)
  715. {
  716. return shaderTable.Load(recordOffset + OffsetToAnyHitStateId);
  717. }
  718. static
  719. void GetAnyHitAndIntersectionStateId(ByteAddressBuffer shaderTable, uint recordOffset, out uint AnyHitStateId, out uint IntersectionStateId)
  720. {
  721. uint2 stateIds = shaderTable.Load2(recordOffset + OffsetToAnyHitStateId);
  722. AnyHitStateId = stateIds.x;
  723. IntersectionStateId = stateIds.y;
  724. }
  725. #line 17 "dxr-fl/TraverseShader.hlsli"
  726. #line 1 "dxr-fl/EmulatedPointerIntrinsics.hlsli"
  727. #line 14 "dxr-fl/EmulatedPointerIntrinsics.hlsli"
  728. static
  729. RWByteAddressBuffer PointerGetBuffer(uint2 address)
  730. {
  731. return DescriptorHeapBufferTable[NonUniformResourceIndex(address[1])];
  732. }
  733. uint PointerGetBufferStartOffset(uint2 address)
  734. {
  735. return address[0];
  736. }
  737. uint4 Load4(uint2 address)
  738. {
  739. return PointerGetBuffer(address).Load4(PointerGetBufferStartOffset(address));
  740. }
  741. static
  742. RWByteAddressBufferPointer CreateRWByteAddressBufferPointerFromGpuVA(uint2 address)
  743. {
  744. return CreateRWByteAddressBufferPointer(PointerGetBuffer(address), PointerGetBufferStartOffset(address));
  745. }
  746. #line 18 "dxr-fl/TraverseShader.hlsli"
  747. #line 1 "dxr-fl/TraverseFunction.hlsli"
  748. #line 19 "dxr-fl/TraverseFunction.hlsli"
  749. static
  750. uint2 stacks[2][32];
  751. #line 48 "dxr-fl/TraverseFunction.hlsli"
  752. void RecordClosestBox(uint currentLevel, inout bool leftTest, float leftT, inout bool rightTest, float rightT, inout float closestBoxT)
  753. {
  754. #line 66 "dxr-fl/TraverseFunction.hlsli"
  755. }
  756. void StackPush(inout int stackTop, uint level, uint2 nodeInfo, uint depth)
  757. {
  758. uint stackIndex = stackTop++;
  759. stacks[level][stackIndex] = nodeInfo;
  760. }
  761. uint2 StackPop(inout int stackTop, uint level, out uint depth)
  762. {
  763. uint stackIndex = --stackTop;
  764. return stacks[level][stackIndex];
  765. }
  766. int InvokeAnyHit(int stateId)
  767. {
  768. Fallback_SetAnyHitResult(1);
  769. Fallback_CallIndirect(stateId);
  770. return Fallback_AnyHitResult();
  771. }
  772. void Fallback_IgnoreHit()
  773. {
  774. Fallback_SetAnyHitResult(0);
  775. }
  776. void Fallback_AcceptHitAndEndSearch()
  777. {
  778. Fallback_SetAnyHitResult(-1);
  779. }
  780. bool IsOpaque(bool geomOpaque, uint instanceFlags, uint rayFlags)
  781. {
  782. bool opaque = geomOpaque;
  783. if (instanceFlags & 0x4)
  784. opaque = true;
  785. else if (instanceFlags & 0x8)
  786. opaque = false;
  787. if (rayFlags & RAY_FLAG_FORCE_OPAQUE)
  788. opaque = true;
  789. else if (rayFlags & RAY_FLAG_FORCE_NON_OPAQUE)
  790. opaque = false;
  791. return opaque;
  792. }
  793. int Fallback_ReportHit(float tHit, uint hitKind)
  794. {
  795. if (tHit < RayTMin() || Fallback_RayTCurrent() <= tHit)
  796. return 0;
  797. Fallback_SetPendingRayTCurrent(tHit);
  798. Fallback_SetPendingHitKind(hitKind);
  799. int stateId = Fallback_AnyHitStateId();
  800. int ret = 1;
  801. bool geomOpaque = true;
  802. if (stateId > 0 && !IsOpaque(geomOpaque, 0, RayFlags()))
  803. ret = InvokeAnyHit(stateId);
  804. if (ret != 0)
  805. {
  806. Fallback_CommitHit();
  807. if (RayFlags() & RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH)
  808. ret = -1;
  809. }
  810. return ret;
  811. }
  812. void UpdateObjectSpaceProperties(float3 objectRayOrigin, float3 objectRayDirection, float3x4 worldToObject, float3x4 objectToWorld )
  813. {
  814. Fallback_SetObjectRayOrigin(objectRayOrigin);
  815. Fallback_SetObjectRayDirection(objectRayDirection);
  816. Fallback_SetWorldToObject(worldToObject);
  817. Fallback_SetObjectToWorld(objectToWorld);
  818. }
  819. inline
  820. bool RayBoxTest(
  821. out float resultT,
  822. float closestT,
  823. float3 rayOriginTimesRayInverseDirection,
  824. float3 rayInverseDirection,
  825. float3 boxCenter,
  826. float3 boxHalfDim)
  827. {
  828. const float3 relativeMiddle = boxCenter * rayInverseDirection - rayOriginTimesRayInverseDirection;
  829. const float3 maxL = relativeMiddle + boxHalfDim * abs(rayInverseDirection);
  830. const float3 minL = relativeMiddle - boxHalfDim * abs(rayInverseDirection);
  831. const float minT = max(max(minL.x, minL.y), minL.z);
  832. const float maxT = min(min(maxL.x, maxL.y), maxL.z);
  833. resultT = max(minT, 0);
  834. return max(minT, 0) < min(maxT, closestT);
  835. }
  836. float3 Swizzle(float3 v, int3 swizzleOrder)
  837. {
  838. return float3(v[swizzleOrder.x], v[swizzleOrder.y], v[swizzleOrder.z]);
  839. }
  840. bool IsPositive(float f) { return f > 0.0f; }
  841. inline
  842. void RayTriangleIntersect(
  843. inout float hitT,
  844. in uint instanceFlags,
  845. out float2 bary,
  846. float3 rayOrigin,
  847. float3 rayDirection,
  848. int3 swizzledIndicies,
  849. float3 shear,
  850. float3 v0,
  851. float3 v1,
  852. float3 v2)
  853. {
  854. bool useCulling = !(instanceFlags & D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_CULL_DISABLE);
  855. bool flipFaces = instanceFlags & D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE;
  856. uint backFaceCullingFlag = flipFaces ? RAY_FLAG_CULL_FRONT_FACING_TRIANGLES : RAY_FLAG_CULL_BACK_FACING_TRIANGLES;
  857. uint frontFaceCullingFlag = flipFaces ? RAY_FLAG_CULL_BACK_FACING_TRIANGLES : RAY_FLAG_CULL_FRONT_FACING_TRIANGLES;
  858. bool useBackfaceCulling = useCulling && (RayFlags() & backFaceCullingFlag);
  859. bool useFrontfaceCulling = useCulling && (RayFlags() & frontFaceCullingFlag);
  860. float3 A = Swizzle(v0 - rayOrigin, swizzledIndicies);
  861. float3 B = Swizzle(v1 - rayOrigin, swizzledIndicies);
  862. float3 C = Swizzle(v2 - rayOrigin, swizzledIndicies);
  863. A.xy = A.xy - shear.xy * A.z;
  864. B.xy = B.xy - shear.xy * B.z;
  865. C.xy = C.xy - shear.xy * C.z;
  866. precise float U = C.x * B.y - C.y * B.x;
  867. precise float V = A.x * C.y - A.y * C.x;
  868. precise float W = B.x * A.y - B.y * A.x;
  869. float det = U + V + W;
  870. if (useFrontfaceCulling)
  871. {
  872. if (U > 0.0f || V > 0.0f || W > 0.0f) return;
  873. }
  874. else if (useBackfaceCulling)
  875. {
  876. if (U < 0.0f || V < 0.0f || W < 0.0f) return;
  877. }
  878. else
  879. {
  880. if ((U < 0.0f || V < 0.0f || W < 0.0f) &&
  881. (U > 0.0f || V > 0.0f || W > 0.0f)) return;
  882. }
  883. if (det == 0.0f) return;
  884. A.z = shear.z * A.z;
  885. B.z = shear.z * B.z;
  886. C.z = shear.z * C.z;
  887. const float T = U * A.z + V * B.z + W * C.z;
  888. if (useFrontfaceCulling)
  889. {
  890. if (T > 0.0f || T < hitT * det)
  891. return;
  892. }
  893. else if (useBackfaceCulling)
  894. {
  895. if (T < 0.0f || T > hitT * det)
  896. return;
  897. }
  898. else
  899. {
  900. float signCorrectedT = abs(T);
  901. if (IsPositive(T) != IsPositive(det))
  902. {
  903. signCorrectedT = -signCorrectedT;
  904. }
  905. if (signCorrectedT < 0.0f || signCorrectedT > hitT * abs(det))
  906. {
  907. return;
  908. }
  909. }
  910. const float rcpDet = rcp(det);
  911. bary.x = V * rcpDet;
  912. bary.y = W * rcpDet;
  913. hitT = T * rcpDet;
  914. }
  915. static
  916. bool TestLeafNodeIntersections(
  917. RWByteAddressBufferPointer accelStruct,
  918. uint2 flags,
  919. uint instanceFlags,
  920. float3 rayOrigin,
  921. float3 rayDirection,
  922. int3 swizzledIndicies,
  923. float3 shear,
  924. inout float2 resultBary,
  925. inout float resultT,
  926. inout uint resultTriId)
  927. {
  928. const uint firstId = GetLeafIndexFromInfo(flags);
  929. const uint numTris = GetNumPrimitivesFromInfo(flags);
  930. uint i = 0;
  931. bool bIsIntersect = false;
  932. #line 352 "dxr-fl/TraverseFunction.hlsli"
  933. {
  934. const uint triId0 = firstId + i;
  935. float3 v0, v1, v2;
  936. BVHReadTriangle(accelStruct, v0, v1, v2, triId0);
  937. float2 bary0;
  938. float t0 = resultT;
  939. RayTriangleIntersect(
  940. t0,
  941. instanceFlags,
  942. bary0,
  943. rayOrigin,
  944. rayDirection,
  945. swizzledIndicies,
  946. shear,
  947. v0, v1, v2);
  948. if (t0 < resultT && t0 > RayTMin())
  949. {
  950. resultBary = bary0.xy;
  951. resultT = t0;
  952. resultTriId = triId0;
  953. bIsIntersect = true;
  954. }
  955. }
  956. return bIsIntersect;
  957. }
  958. int GetIndexOfBiggestChannel(float3 vec)
  959. {
  960. if (vec.x > vec.y && vec.x > vec.z)
  961. {
  962. return 0;
  963. }
  964. else if (vec.y > vec.z)
  965. {
  966. return 1;
  967. }
  968. else
  969. {
  970. return 2;
  971. }
  972. }
  973. void swap(inout int a, inout int b)
  974. {
  975. int temp = a;
  976. a = b;
  977. b = temp;
  978. }
  979. struct HitData
  980. {
  981. uint ContributionToHitGroupIndex;
  982. uint PrimitiveIndex;
  983. };
  984. struct RayData
  985. {
  986. float3 InverseDirection;
  987. float3 OriginTimesRayInverseDirection;
  988. float3 Shear;
  989. int3 SwizzledIndices;
  990. };
  991. RayData GetRayData(float3 rayOrigin, float3 rayDirection)
  992. {
  993. RayData data;
  994. data.InverseDirection = rcp(rayDirection);
  995. data.OriginTimesRayInverseDirection = rayOrigin * data.InverseDirection;
  996. int zIndex = GetIndexOfBiggestChannel(abs(rayDirection));
  997. data.SwizzledIndices = int3(
  998. (zIndex + 1) % 3,
  999. (zIndex + 2) % 3,
  1000. zIndex);
  1001. if (rayDirection[data.SwizzledIndices.z] < 0.0f) swap(data.SwizzledIndices.x, data.SwizzledIndices.y);
  1002. data.Shear = float3(
  1003. rayDirection[data.SwizzledIndices.x] / rayDirection[data.SwizzledIndices.z],
  1004. rayDirection[data.SwizzledIndices.y] / rayDirection[data.SwizzledIndices.z],
  1005. 1.0 / rayDirection[data.SwizzledIndices.z]);
  1006. return data;
  1007. }
  1008. bool Cull(bool opaque, uint rayFlags)
  1009. {
  1010. return (opaque && (rayFlags & RAY_FLAG_CULL_OPAQUE)) || (!opaque && (rayFlags & RAY_FLAG_CULL_NON_OPAQUE));
  1011. }
  1012. float ComputeCullFaceDir(uint instanceFlags, uint rayFlags)
  1013. {
  1014. float cullFaceDir = 0;
  1015. if (rayFlags & RAY_FLAG_CULL_FRONT_FACING_TRIANGLES)
  1016. cullFaceDir = 1;
  1017. else if (rayFlags & RAY_FLAG_CULL_BACK_FACING_TRIANGLES)
  1018. cullFaceDir = -1;
  1019. if (instanceFlags & 0x1)
  1020. cullFaceDir = 0;
  1021. return cullFaceDir;
  1022. }
  1023. #line 471 "dxr-fl/TraverseFunction.hlsli"
  1024. void dump(BoundingBox box, uint2 flags)
  1025. {
  1026. LogFloat3(box.center);
  1027. LogFloat3(box.halfDim);
  1028. LogInt2(flags);
  1029. }
  1030. void Fallback_SetPendingAttr(BuiltInTriangleIntersectionAttributes);;
  1031. void SetBoolFlag(inout uint flagContainer, uint flag, bool enable)
  1032. {
  1033. if (enable)
  1034. {
  1035. flagContainer |= flag;
  1036. }
  1037. else
  1038. {
  1039. flagContainer &= ~flag;
  1040. }
  1041. }
  1042. bool GetBoolFlag(uint flagContainer, uint flag)
  1043. {
  1044. return flagContainer & flag;
  1045. }
  1046. struct BLASContext {
  1047. uint instanceIndex;
  1048. uint instanceFlags;
  1049. uint instanceOffset;
  1050. uint instanceId;
  1051. uint2 instanceGpuVA;
  1052. float3x4 worldToObject;
  1053. float3x4 objectToWorld;
  1054. float3 objectSpaceOrigin;
  1055. float3 objectSpaceDirection;
  1056. RayData rayData;
  1057. };
  1058. inline bool GetBLASFromTopLevelLeaf(
  1059. in uint2 leafInfo,
  1060. in RWByteAddressBufferPointer topLevelAccelerationStructure,
  1061. in uint offsetToInstanceDescs,
  1062. in uint InstanceInclusionMask,
  1063. out BLASContext blasContext
  1064. )
  1065. {
  1066. LogInt(6*100+10+0);
  1067. uint leafIndex = GetLeafIndexFromInfo(leafInfo);
  1068. BVHMetadata metadata = LoadBVHMetadata(topLevelAccelerationStructure.buffer, offsetToInstanceDescs + leafIndex * 116);
  1069. RaytracingInstanceDesc instanceDesc = metadata.instanceDesc;
  1070. bool isValidInstance = GetInstanceMask(instanceDesc) & InstanceInclusionMask;
  1071. if (isValidInstance)
  1072. {
  1073. LogInt(7*100+10+0);
  1074. blasContext.instanceIndex = metadata.InstanceIndex;
  1075. blasContext.instanceOffset = GetInstanceContributionToHitGroupIndex(instanceDesc);
  1076. blasContext.instanceId = GetInstanceID(instanceDesc);
  1077. blasContext.instanceGpuVA = instanceDesc.AccelerationStructure;
  1078. blasContext.instanceFlags = GetInstanceFlags(instanceDesc);
  1079. blasContext.worldToObject = CreateMatrix(instanceDesc.Transform);
  1080. blasContext.objectToWorld = CreateMatrix(metadata.ObjectToWorld);
  1081. blasContext.objectSpaceOrigin = mul(blasContext.worldToObject, float4(WorldRayOrigin(), 1));
  1082. blasContext.objectSpaceDirection = mul(blasContext.worldToObject, float4(WorldRayDirection(), 0));
  1083. blasContext.rayData = GetRayData(blasContext.objectSpaceOrigin, blasContext.objectSpaceDirection);
  1084. }
  1085. return isValidInstance;
  1086. }
  1087. inline bool CheckHitProcedural(
  1088. in uint hitGroupRecordOffset,
  1089. in uint primitiveIndex,
  1090. in BLASContext blasContext
  1091. )
  1092. {
  1093. Fallback_SetPendingCustomVals(hitGroupRecordOffset, primitiveIndex, blasContext.instanceIndex, blasContext.instanceId);
  1094. uint intersectionStateId, anyHitStateId;
  1095. GetAnyHitAndIntersectionStateId(HitGroupShaderTable, hitGroupRecordOffset, anyHitStateId, intersectionStateId);
  1096. Fallback_SetAnyHitStateId(anyHitStateId);
  1097. Fallback_SetAnyHitResult(1);
  1098. Fallback_CallIndirect(intersectionStateId);
  1099. return (Fallback_AnyHitResult() == -1);
  1100. }
  1101. inline bool CheckHitTriangles(
  1102. in uint2 nodeInfo,
  1103. in uint hitGroupRecordOffset,
  1104. in uint primitiveIndex,
  1105. in bool opaque,
  1106. in RWByteAddressBufferPointer bottomLevelAccelerationStructure,
  1107. in BLASContext blasContext,
  1108. in uint searchDepth
  1109. )
  1110. {
  1111. float resultT = Fallback_RayTCurrent();
  1112. float2 resultBary;
  1113. uint resultTriId;
  1114. bool triangleHit = TestLeafNodeIntersections(
  1115. bottomLevelAccelerationStructure,
  1116. nodeInfo,
  1117. blasContext.instanceFlags,
  1118. ObjectRayOrigin(),
  1119. ObjectRayDirection(),
  1120. blasContext.rayData.SwizzledIndices,
  1121. blasContext.rayData.Shear,
  1122. resultBary,
  1123. resultT,
  1124. resultTriId);
  1125. if (!triangleHit)
  1126. {
  1127. return false;
  1128. }
  1129. uint hitKind = HIT_KIND_TRIANGLE_FRONT_FACE;
  1130. BuiltInTriangleIntersectionAttributes attr;
  1131. attr.barycentrics = resultBary;
  1132. Fallback_SetPendingAttr(attr);
  1133. Fallback_SetPendingTriVals(hitGroupRecordOffset, primitiveIndex, blasContext.instanceIndex, blasContext.instanceId, resultT, hitKind);
  1134. #line 636 "dxr-fl/TraverseFunction.hlsli"
  1135. bool skipAnyHit = true;
  1136. bool hitEndsSearch;
  1137. if (skipAnyHit)
  1138. {
  1139. LogInt(8*100+10+1);
  1140. Fallback_CommitHit();
  1141. hitEndsSearch = (RayFlags() & RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH);
  1142. }
  1143. else
  1144. {
  1145. LogInt(8*100+10+2);
  1146. uint anyhitStateId = GetAnyHitStateId(HitGroupShaderTable, hitGroupRecordOffset);
  1147. int ret = 1;
  1148. if (anyhitStateId)
  1149. {
  1150. ret = InvokeAnyHit(anyhitStateId);
  1151. }
  1152. if (ret != 0)
  1153. {
  1154. Fallback_CommitHit();
  1155. }
  1156. hitEndsSearch = (ret == -1) || (RayFlags() & RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH);
  1157. }
  1158. return hitEndsSearch;
  1159. }
  1160. inline bool CheckHitOnBottomLevelLeaf(
  1161. in uint2 leafInfo,
  1162. in RWByteAddressBufferPointer bottomLevelAccelerationStructure,
  1163. in BLASContext blasContext,
  1164. in uint RayContributionToHitGroupIndex,
  1165. in uint MultiplierForGeometryContributionToHitGroupIndex,
  1166. in uint searchDepth
  1167. )
  1168. {
  1169. LogInt(8*100+10+0);
  1170. const uint leafIndex = GetLeafIndexFromInfo(leafInfo);
  1171. PrimitiveMetaData primitiveMetadata = BVHReadPrimitiveMetaData(bottomLevelAccelerationStructure, leafIndex);
  1172. bool geomOpaque = primitiveMetadata.GeometryFlags & D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE;
  1173. bool opaque = IsOpaque(geomOpaque, blasContext.instanceFlags, RayFlags());
  1174. bool culled = Cull(opaque, RayFlags());
  1175. bool isProceduralGeometry = IsProceduralGeometry(leafInfo);
  1176. isProceduralGeometry = false;
  1177. if (!culled)
  1178. {
  1179. uint hitGroupGeometryContribution = primitiveMetadata.GeometryContributionToHitGroupIndex * MultiplierForGeometryContributionToHitGroupIndex;
  1180. uint hitGroupRecordIndex = RayContributionToHitGroupIndex + hitGroupGeometryContribution + blasContext.instanceOffset;
  1181. uint hitGroupRecordOffset = HitGroupShaderRecordStride * hitGroupRecordIndex;
  1182. uint primitiveIndex = primitiveMetadata.PrimitiveIndex;
  1183. if (isProceduralGeometry)
  1184. {
  1185. return CheckHitProcedural(
  1186. hitGroupRecordOffset,
  1187. primitiveIndex,
  1188. blasContext
  1189. );
  1190. }
  1191. else
  1192. {
  1193. return CheckHitTriangles(
  1194. leafInfo,
  1195. hitGroupRecordOffset,
  1196. primitiveIndex,
  1197. opaque,
  1198. bottomLevelAccelerationStructure,
  1199. blasContext,
  1200. searchDepth
  1201. );
  1202. }
  1203. }
  1204. return false;
  1205. }
  1206. static
  1207. bool Traverse(
  1208. uint InstanceInclusionMask,
  1209. uint RayContributionToHitGroupIndex,
  1210. uint MultiplierForGeometryContributionToHitGroupIndex
  1211. )
  1212. {
  1213. uint GI = Fallback_GroupIndex();
  1214. RayData currentRayData = GetRayData(WorldRayOrigin(), WorldRayDirection());
  1215. uint nodesToProcess[2];
  1216. nodesToProcess[0] = 0;
  1217. nodesToProcess[1] = 0;
  1218. uint currentBVHLevel = 0;
  1219. BLASContext blasContext;
  1220. RWByteAddressBufferPointer topLevelAccelerationStructure = CreateRWByteAddressBufferPointerFromGpuVA(TopLevelAccelerationStructureGpuVA);
  1221. uint offsetToInstanceDescs = topLevelAccelerationStructure.buffer.Load(OffsetToLeafNodeMetaDataOffset + topLevelAccelerationStructure.offsetInBytes) + topLevelAccelerationStructure.offsetInBytes;
  1222. RWByteAddressBufferPointer currentBVH = topLevelAccelerationStructure;
  1223. float closestBoxT = asfloat(0x7F7FFFFF);
  1224. int NO_HIT_SENTINEL = ~0;
  1225. Fallback_SetInstanceIndex(NO_HIT_SENTINEL);
  1226. uint currentDepth = 0;
  1227. uint2 rootInfo = 0;
  1228. StackPush(nodesToProcess[0], 0, rootInfo, currentDepth);
  1229. uint moo = 0;
  1230. LogInt(2*100+10+0);
  1231. do
  1232. {
  1233. LogInt(3*100+10+0);
  1234. uint2 parentNodeInfo = StackPop(nodesToProcess[currentBVHLevel], currentBVHLevel, currentDepth);
  1235. bool isLeaf = IsLeaf(parentNodeInfo);
  1236. uint childIndex = GetChildIndexFromInfo(parentNodeInfo);
  1237. if (isLeaf)
  1238. {
  1239. LogInt(5*100+10+0);
  1240. if (currentBVHLevel == 0)
  1241. {
  1242. LogInt(6*100+10+0);
  1243. if (GetBLASFromTopLevelLeaf(
  1244. parentNodeInfo,
  1245. topLevelAccelerationStructure,
  1246. offsetToInstanceDescs,
  1247. InstanceInclusionMask,
  1248. blasContext
  1249. ))
  1250. {
  1251. LogInt(7*100+10+0);
  1252. currentRayData = blasContext.rayData;
  1253. currentBVH = CreateRWByteAddressBufferPointerFromGpuVA(blasContext.instanceGpuVA);
  1254. UpdateObjectSpaceProperties(
  1255. blasContext.objectSpaceOrigin,
  1256. blasContext.objectSpaceDirection,
  1257. blasContext.worldToObject,
  1258. blasContext.objectToWorld
  1259. );
  1260. StackPush(nodesToProcess[1], 1, rootInfo, currentDepth + 1);
  1261. currentBVHLevel = 1;
  1262. }
  1263. }
  1264. else
  1265. {
  1266. if(CheckHitOnBottomLevelLeaf(
  1267. parentNodeInfo,
  1268. currentBVH,
  1269. blasContext,
  1270. RayContributionToHitGroupIndex,
  1271. MultiplierForGeometryContributionToHitGroupIndex,
  1272. currentDepth
  1273. ))
  1274. {
  1275. break;
  1276. }
  1277. }
  1278. }
  1279. else
  1280. {
  1281. moo++;
  1282. LogInt(4*100+10+0);
  1283. BoundingBox leftBox, rightBox;
  1284. uint2 leftInfo, rightInfo;
  1285. bool leftHit, rightHit;
  1286. float leftT, rightT;
  1287. leftBox = GetLeftBoxFromBVH(currentBVH, childIndex, leftInfo);
  1288. rightBox = GetRightBoxFromBVH(currentBVH, childIndex, rightInfo);
  1289. leftHit = RayBoxTest(
  1290. leftT,
  1291. RayTCurrent(),
  1292. currentRayData.OriginTimesRayInverseDirection,
  1293. currentRayData.InverseDirection,
  1294. leftBox.center,
  1295. leftBox.halfDim);
  1296. rightHit = !IsDummy(rightInfo) && RayBoxTest(
  1297. rightT,
  1298. RayTCurrent(),
  1299. currentRayData.OriginTimesRayInverseDirection,
  1300. currentRayData.InverseDirection,
  1301. rightBox.center,
  1302. rightBox.halfDim);
  1303. bool singleHit, doubleHit;
  1304. singleHit = leftHit || rightHit;
  1305. doubleHit = leftHit && rightHit;
  1306. uint2 firstInfo, secondInfo;
  1307. if (doubleHit)
  1308. {
  1309. if (rightT < leftT)
  1310. {
  1311. firstInfo = rightInfo; secondInfo = leftInfo;
  1312. }
  1313. else
  1314. {
  1315. firstInfo = leftInfo; secondInfo = rightInfo;
  1316. }
  1317. }
  1318. else if (singleHit)
  1319. {
  1320. firstInfo = leftHit ? leftInfo : rightInfo;
  1321. }
  1322. if (doubleHit)
  1323. {
  1324. StackPush(nodesToProcess[currentBVHLevel], currentBVHLevel, secondInfo, currentDepth + 1);
  1325. }
  1326. if (singleHit)
  1327. {
  1328. StackPush(nodesToProcess[currentBVHLevel], currentBVHLevel, firstInfo, currentDepth + 1);
  1329. }
  1330. }
  1331. if (nodesToProcess[1] == 0)
  1332. {
  1333. if (currentBVHLevel == 1)
  1334. {
  1335. currentBVHLevel = 0;
  1336. currentRayData = GetRayData(WorldRayOrigin(), WorldRayDirection());
  1337. currentBVH = topLevelAccelerationStructure;
  1338. }
  1339. }
  1340. } while(nodesToProcess[currentBVHLevel] != 0);
  1341. LogInt(10*100+10+0);
  1342. bool isHit = Fallback_InstanceIndex() != NO_HIT_SENTINEL;
  1343. return isHit;
  1344. }
  1345. #line 19 "dxr-fl/TraverseShader.hlsli"
  1346. [experimental("shader", "internal")]
  1347. void Fallback_TraceRay(
  1348. uint rayFlags,
  1349. uint instanceInclusionMask,
  1350. uint rayContributionToHitGroupIndex,
  1351. uint multiplierForGeometryContributionToHitGroupIndex,
  1352. uint missShaderIndex,
  1353. float originX,
  1354. float originY,
  1355. float originZ,
  1356. float tMin,
  1357. float directionX,
  1358. float directionY,
  1359. float directionZ,
  1360. float tMax,
  1361. uint payloadOffset)
  1362. {
  1363. LogTraceRayStart();
  1364. uint oldPayloadOffset = Fallback_TraceRayBegin(rayFlags, float3(originX, originY, originZ), tMin, float3(directionX, directionY, directionZ), tMax, payloadOffset);
  1365. bool hit = Traverse(
  1366. instanceInclusionMask,
  1367. rayContributionToHitGroupIndex,
  1368. multiplierForGeometryContributionToHitGroupIndex
  1369. );
  1370. uint stateID;
  1371. if (hit)
  1372. {
  1373. if (RayFlags() & RAY_FLAG_SKIP_CLOSEST_HIT_SHADER)
  1374. {
  1375. stateID = 0;
  1376. }
  1377. else
  1378. {
  1379. stateID = HitGroupShaderTable.Load(Fallback_ShaderRecordOffset());
  1380. }
  1381. }
  1382. else
  1383. {
  1384. int missShaderRecordOffset = missShaderIndex * MissShaderRecordStride;
  1385. Fallback_SetShaderRecordOffset(missShaderRecordOffset);
  1386. stateID = MissShaderTable.Load(missShaderRecordOffset);
  1387. }
  1388. if (stateID != 0)
  1389. {
  1390. Fallback_CallIndirect(stateID);
  1391. }
  1392. Fallback_TraceRayEnd(oldPayloadOffset);
  1393. LogTraceRayEnd();
  1394. }
  1395. #line 13 "dxr-fl\\MinimalTraverseShaderLib.hlsl"