CustomDX12API.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #include "CustomDX12API.h"
  2. #include <d3d12.h>
  3. #include <DX12Buffer.h>
  4. #include <DX12CommandQueue.h>
  5. #include <DX12DefaultAnyHitShader.h>
  6. #include <DX12DefaultHitShader.h>
  7. #include <DX12DefaultMissShader.h>
  8. #include <DX12DefaultRayGenShader.h>
  9. #include <DX12Shader.h>
  10. #include <DX12TLAS.h>
  11. #include "CustomChunkAnyHitShader.h"
  12. #include "CustomChunkClosestHitShader.h"
  13. #include "CustomChunkIntersectionShader.h"
  14. #include "Dimension.h"
  15. #include "DX12ChunkData.h"
  16. using namespace Framework;
  17. CustomDX12API::CustomDX12API()
  18. : DirectX12()
  19. {}
  20. CustomDX12API::~CustomDX12API() {}
  21. void CustomDX12API::initializePipeline()
  22. {
  23. if (pipeline->getShaders().getEntryCount() == 0)
  24. { // add default shaders
  25. DX12Shader* rayGenShader = new DX12Shader(
  26. DX12DefaultRayGenShaderBytes, sizeof(DX12DefaultRayGenShaderBytes));
  27. // RayGen from RayGen.hlsl
  28. DX12ShaderSignature* rayGenSignature = new DX12ShaderSignature();
  29. rayGenSignature->addRegisterUsageLinkedToDescriptorHeap(
  30. 0, DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, 0);
  31. rayGenSignature->addRegisterUsageLinkedToDescriptorHeap(
  32. 1, DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, 1);
  33. rayGenSignature->addRegisterUsageLinkedToDescriptorHeap(
  34. 2, DX12_SHADER_REGISTER_B_CONST_BUFFER, 0);
  35. rayGenSignature->addRegisterUsageLinkedToDescriptorHeap(
  36. 3, DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 0);
  37. defaultRayGenerationShaderFunction = new DX12ShaderFunction(
  38. "RayGen", rayGenSignature, DX12_SHADER_FUNCTION_TYPE_RAY_GEN);
  39. rayGenShader->addFunction(defaultRayGenerationShaderFunction);
  40. pipeline->addShader(rayGenShader);
  41. DX12Shader* missShader = new DX12Shader(
  42. DX12DefaultMissShaderBytes, sizeof(DX12DefaultMissShaderBytes));
  43. // Miss from Miss.hlsl
  44. missShader->addFunction(new DX12ShaderFunction(
  45. "Miss", new DX12ShaderSignature(), DX12_SHADER_FUNCTION_TYPE_MISS));
  46. pipeline->addShader(missShader);
  47. DX12ShaderSignature* hitSignature = new DX12ShaderSignature();
  48. hitSignature->addRegisterUsageLinkedToDescriptorHeap(
  49. 0, DX12_SHADER_REGISTER_S_SAMPLER, 0, 0, SAMPLER_DESCRIPTOR_HEAP);
  50. hitSignature->addRegisterUsageLinkedToDescriptorHeap(0,
  51. DX12_SHADER_REGISTER_T_SHADER_RESOURCE,
  52. 0,
  53. 1,
  54. TEXTURE_DESCRIPTOR_HEAP,
  55. 1);
  56. sbtTextureIdBufferOffset
  57. = hitSignature->addRegisterUsageLinkedToShaderBindingTable(
  58. DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 2);
  59. sbtIndexBufferOffset
  60. = hitSignature->addRegisterUsageLinkedToShaderBindingTable(
  61. DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 3);
  62. sbtVertexDataBufferOffset
  63. = hitSignature->addRegisterUsageLinkedToShaderBindingTable(
  64. DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 4);
  65. sbtPolygonSizeBufferOffset
  66. = hitSignature->addRegisterUsageLinkedToShaderBindingTable(
  67. DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 5);
  68. DX12Shader* anyHitShader = new DX12Shader(
  69. DX12DefaultAnyHitShaderBytes, sizeof(DX12DefaultAnyHitShaderBytes));
  70. DX12ShaderFunction* anyHitFunction = new DX12ShaderFunction(
  71. "AnyHit", hitSignature, DX12_SHADER_FUNCTION_TYPE_ANY_HIT);
  72. // AnyHit from AnyHit.hlsl
  73. anyHitShader->addFunction(anyHitFunction);
  74. pipeline->addShader(anyHitShader);
  75. DX12Shader* hitShader = new DX12Shader(
  76. DX12DefaultHitShaderBytes, sizeof(DX12DefaultHitShaderBytes));
  77. // ClosestHit from Hit.hlsl
  78. DX12ShaderFunction* closestHitFunction
  79. = new DX12ShaderFunction("ClosestHit",
  80. dynamic_cast<DX12ShaderSignature*>(hitSignature->getThis()),
  81. DX12_SHADER_FUNCTION_TYPE_CLOSEST_HIT);
  82. hitShader->addFunction(closestHitFunction);
  83. pipeline->addShader(hitShader);
  84. defaultHitGroup = new DX12ShaderHitGroup("HitGroup");
  85. defaultHitGroup->setAttributeSize(8);
  86. defaultHitGroup->setPayloadSize(20 * DEFAULT_MAX_TRANSPARENT_HITS + 4);
  87. defaultHitGroup->setAnyHitShaderFunction(anyHitFunction);
  88. defaultHitGroup->setClosestHitShaderFunction(closestHitFunction);
  89. pipeline->addHitGroup(defaultHitGroup);
  90. DX12ShaderSignature* chunkHitSignature = new DX12ShaderSignature();
  91. chunkHitSignature->addRegisterUsageLinkedToDescriptorHeap(
  92. 0, DX12_SHADER_REGISTER_S_SAMPLER, 0, 0, SAMPLER_DESCRIPTOR_HEAP);
  93. chunkHitSignature->addRegisterUsageLinkedToDescriptorHeap(0,
  94. DX12_SHADER_REGISTER_T_SHADER_RESOURCE,
  95. 0,
  96. 1,
  97. TEXTURE_DESCRIPTOR_HEAP,
  98. 1);
  99. sbtChunkTextureIdBufferOffset
  100. = chunkHitSignature->addRegisterUsageLinkedToShaderBindingTable(
  101. DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 2);
  102. sbtChunkIndexBufferOffset
  103. = chunkHitSignature->addRegisterUsageLinkedToShaderBindingTable(
  104. DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 3);
  105. sbtChunkDataBufferOffset
  106. = chunkHitSignature->addRegisterUsageLinkedToShaderBindingTable(
  107. DX12_SHADER_REGISTER_B_CONST_BUFFER, 0, 2);
  108. DX12Shader* chunkIntersectionShader
  109. = new DX12Shader(CustomChunkIntersectionShader,
  110. sizeof(CustomChunkIntersectionShader));
  111. DX12ShaderFunction* chunkIntersectionFunction
  112. = new DX12ShaderFunction("ChunkIntersection",
  113. chunkHitSignature,
  114. DX12_SHADER_FUNCTION_TYPE_INTERSECTION);
  115. chunkIntersectionShader->addFunction(chunkIntersectionFunction);
  116. pipeline->addShader(chunkIntersectionShader);
  117. DX12Shader* chunkAnyHitShader = new DX12Shader(
  118. CustomChunkAnyHitShader, sizeof(CustomChunkAnyHitShader));
  119. DX12ShaderFunction* chunkAnyHitFunction = new DX12ShaderFunction(
  120. "ChunkAnyHit",
  121. dynamic_cast<DX12ShaderSignature*>(chunkHitSignature->getThis()),
  122. DX12_SHADER_FUNCTION_TYPE_ANY_HIT);
  123. chunkAnyHitShader->addFunction(chunkAnyHitFunction);
  124. pipeline->addShader(chunkAnyHitShader);
  125. DX12Shader* chunkClosestHitShader = new DX12Shader(
  126. CustomChunkClosestHitShader, sizeof(CustomChunkClosestHitShader));
  127. DX12ShaderFunction* chunkClosestHitFunction = new DX12ShaderFunction(
  128. "ChunkClosestHit",
  129. dynamic_cast<DX12ShaderSignature*>(chunkHitSignature->getThis()),
  130. DX12_SHADER_FUNCTION_TYPE_CLOSEST_HIT);
  131. chunkClosestHitShader->addFunction(chunkClosestHitFunction);
  132. pipeline->addShader(chunkClosestHitShader);
  133. chunkHitGroup = new DX12ShaderHitGroup("ChunkHitGroup");
  134. chunkHitGroup->setIntersectionShaderFunction(chunkIntersectionFunction);
  135. chunkHitGroup->setAnyHitShaderFunction(chunkAnyHitFunction);
  136. chunkHitGroup->setClosestHitShaderFunction(chunkClosestHitFunction);
  137. chunkHitGroup->setAttributeSize(12);
  138. chunkHitGroup->setPayloadSize(20 * DEFAULT_MAX_TRANSPARENT_HITS + 4);
  139. pipeline->addHitGroup(chunkHitGroup);
  140. pipeline->setMaxRecursionDepth(10);
  141. }
  142. pipeline->createPipelineState(device, pfnD3D12SerializeRootSignature);
  143. }
  144. void CustomDX12API::initializeGlobalDescriptorHeap()
  145. {
  146. DirectX12::initializeGlobalDescriptorHeap();
  147. }
  148. void CustomDX12API::fillShaderBindingTable(
  149. Framework::DX12ShaderBindingTable* zShaderBindingTable,
  150. Framework::Model3D* zModel,
  151. int objectIndex,
  152. const Framework::DX12BLAS* zBLAS,
  153. int& lastHitGroupIndex)
  154. {
  155. DirectX12::fillShaderBindingTable(
  156. zShaderBindingTable, zModel, objectIndex, zBLAS, lastHitGroupIndex);
  157. }
  158. void CustomDX12API::renderWorld(Framework::World3D* zWorld,
  159. DX12TLAS* zTLAS,
  160. DX12ShaderBindingTable* zSBT,
  161. int& objectIndex)
  162. {
  163. Mat4<float> identity = Mat4<float>::identity();
  164. for (const Model3DCollection* collection : zWorld->getCollections())
  165. {
  166. const Dimension* dim = dynamic_cast<const Dimension*>(collection);
  167. if (dim)
  168. {
  169. for (const Chunk* chunk : dim->getChunks())
  170. {
  171. DX12ChunkData* chunkData = chunk->zDX12Data();
  172. chunkData->updateBuffers(device, directCommandQueue);
  173. bool changed = chunkData->wasBufferChanged()
  174. || chunkData->getLastObjectIndex() != objectIndex;
  175. if (changed)
  176. {
  177. chunkData->setLastObjectIndex(objectIndex);
  178. D3D12_RAYTRACING_INSTANCE_DESC* desc
  179. = zTLAS->nextInstanceDesc();
  180. desc->InstanceID = objectIndex;
  181. desc->InstanceContributionToHitGroupIndex = objectIndex;
  182. desc->Flags = D3D12_RAYTRACING_INSTANCE_FLAG_NONE;
  183. desc->InstanceMask = 0xFF;
  184. desc->AccelerationStructure = chunkData->zBlasBuffer()
  185. ->zBuffer()
  186. ->GetGPUVirtualAddress();
  187. memcpy(desc->Transform, &identity, sizeof(float) * 12);
  188. }
  189. else
  190. {
  191. zTLAS->nextInstanceDesc();
  192. }
  193. int hitGroupOffset = zSBT->addHitGroup(
  194. chunkHitGroup, chunkData->getLastHitGroupIndex());
  195. if (chunkData->getLastHitGroupIndex() != hitGroupOffset)
  196. {
  197. chunkData->setLastHitGroupIndex(hitGroupOffset);
  198. zSBT->setHitGroupShaderInput(hitGroupOffset,
  199. sbtChunkIndexBufferOffset,
  200. chunkData->zBlockIndexBuffer()
  201. ->zBuffer()
  202. ->GetGPUVirtualAddress());
  203. zSBT->setHitGroupShaderInput(hitGroupOffset,
  204. sbtChunkTextureIdBufferOffset,
  205. chunkData->zTextureIdBuffer()
  206. ->zBuffer()
  207. ->GetGPUVirtualAddress());
  208. zSBT->setHitGroupShaderInput(hitGroupOffset,
  209. sbtChunkDataBufferOffset,
  210. chunkData->zChunkInfoBuffer()
  211. ->zBuffer()
  212. ->GetGPUVirtualAddress());
  213. }
  214. ++objectIndex;
  215. }
  216. }
  217. }
  218. DirectX12::renderWorld(zWorld, zTLAS, zSBT, objectIndex);
  219. }