AccelerationStructureImpl.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. // Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Gr/Vulkan/AccelerationStructureImpl.h>
  6. #include <AnKi/Gr/Vulkan/GrManagerImpl.h>
  7. namespace anki {
  8. AccelerationStructureImpl::~AccelerationStructureImpl()
  9. {
  10. m_topLevelInfo.m_blas.destroy();
  11. if(m_handle)
  12. {
  13. vkDestroyAccelerationStructureKHR(getGrManagerImpl().getDevice(), m_handle, nullptr);
  14. }
  15. }
  16. Error AccelerationStructureImpl::init(const AccelerationStructureInitInfo& inf)
  17. {
  18. ANKI_TRACE_SCOPED_EVENT(VkInitAccStruct);
  19. ANKI_ASSERT(inf.isValid());
  20. m_type = inf.m_type;
  21. const VkDevice vkdev = getGrManagerImpl().getDevice();
  22. if(m_type == AccelerationStructureType::kBottomLevel)
  23. {
  24. // Geom
  25. VkAccelerationStructureGeometryKHR& geom = m_geometry;
  26. geom.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
  27. geom.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR;
  28. geom.geometry.triangles.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR;
  29. geom.geometry.triangles.vertexFormat = convertFormat(inf.m_bottomLevel.m_positionsFormat);
  30. geom.geometry.triangles.vertexData.deviceAddress =
  31. inf.m_bottomLevel.m_positionBuffer->getGpuAddress() + inf.m_bottomLevel.m_positionBufferOffset;
  32. geom.geometry.triangles.vertexStride = inf.m_bottomLevel.m_positionStride;
  33. geom.geometry.triangles.maxVertex = inf.m_bottomLevel.m_positionCount - 1;
  34. geom.geometry.triangles.indexType = convertIndexType(inf.m_bottomLevel.m_indexType);
  35. geom.geometry.triangles.indexData.deviceAddress = inf.m_bottomLevel.m_indexBuffer->getGpuAddress() + inf.m_bottomLevel.m_indexBufferOffset;
  36. geom.flags = 0; // VK_GEOMETRY_OPAQUE_BIT_KHR; // TODO
  37. // Geom build info
  38. VkAccelerationStructureBuildGeometryInfoKHR& buildInfo = m_buildInfo;
  39. buildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
  40. buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
  41. buildInfo.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
  42. buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
  43. buildInfo.geometryCount = 1;
  44. buildInfo.pGeometries = &geom;
  45. // Get memory info
  46. VkAccelerationStructureBuildSizesInfoKHR buildSizes = {};
  47. const U32 primitiveCount = inf.m_bottomLevel.m_indexCount / 3;
  48. buildSizes.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR;
  49. vkGetAccelerationStructureBuildSizesKHR(vkdev, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &buildInfo, &primitiveCount, &buildSizes);
  50. m_scratchBufferSize = U32(buildSizes.buildScratchSize);
  51. // Create the buffer that holds the AS memory
  52. BufferInitInfo bufferInit(inf.getName());
  53. bufferInit.m_usage = PrivateBufferUsageBit::kAccelerationStructure;
  54. bufferInit.m_size = buildSizes.accelerationStructureSize;
  55. m_asBuffer = getGrManagerImpl().newBuffer(bufferInit);
  56. // Create the AS
  57. VkAccelerationStructureCreateInfoKHR asCi = {};
  58. asCi.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
  59. asCi.createFlags = 0;
  60. asCi.buffer = static_cast<const BufferImpl&>(*m_asBuffer).getHandle();
  61. asCi.offset = 0;
  62. asCi.size = buildSizes.accelerationStructureSize;
  63. asCi.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
  64. ANKI_VK_CHECK(vkCreateAccelerationStructureKHR(vkdev, &asCi, nullptr, &m_handle));
  65. // Get its address
  66. VkAccelerationStructureDeviceAddressInfoKHR addressInfo = {};
  67. addressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
  68. addressInfo.accelerationStructure = m_handle;
  69. m_deviceAddress = vkGetAccelerationStructureDeviceAddressKHR(vkdev, &addressInfo);
  70. // Almost finalize the build info
  71. buildInfo.dstAccelerationStructure = m_handle;
  72. // Range info
  73. m_rangeInfo.primitiveCount = primitiveCount;
  74. }
  75. else
  76. {
  77. // Create the instances buffer
  78. m_topLevelInfo.m_blas.resizeStorage(inf.m_topLevel.m_instances.getSize());
  79. BufferInitInfo buffInit("AS instances");
  80. buffInit.m_size = sizeof(VkAccelerationStructureInstanceKHR) * inf.m_topLevel.m_instances.getSize();
  81. buffInit.m_usage = PrivateBufferUsageBit::kAccelerationStructure;
  82. buffInit.m_mapAccess = BufferMapAccessBit::kWrite;
  83. m_topLevelInfo.m_instancesBuffer = getGrManagerImpl().newBuffer(buffInit);
  84. VkAccelerationStructureInstanceKHR* instances =
  85. static_cast<VkAccelerationStructureInstanceKHR*>(m_topLevelInfo.m_instancesBuffer->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite));
  86. for(U32 i = 0; i < inf.m_topLevel.m_instances.getSize(); ++i)
  87. {
  88. VkAccelerationStructureInstanceKHR& outInst = instances[i];
  89. const AccelerationStructureInstance& inInst = inf.m_topLevel.m_instances[i];
  90. static_assert(sizeof(outInst.transform) == sizeof(inInst.m_transform), "See file");
  91. memcpy(&outInst.transform, &inInst.m_transform, sizeof(inInst.m_transform));
  92. outInst.instanceCustomIndex = i & 0xFFFFFF;
  93. outInst.mask = inInst.m_mask;
  94. outInst.instanceShaderBindingTableRecordOffset = inInst.m_hitgroupSbtRecordIndex & 0xFFFFFF;
  95. outInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR | VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
  96. outInst.accelerationStructureReference = static_cast<const AccelerationStructureImpl&>(*inInst.m_bottomLevel).m_deviceAddress;
  97. ANKI_ASSERT(outInst.accelerationStructureReference != 0);
  98. // Hold the reference
  99. m_topLevelInfo.m_blas.emplaceBack(inf.m_topLevel.m_instances[i].m_bottomLevel);
  100. }
  101. m_topLevelInfo.m_instancesBuffer->flush(0, kMaxPtrSize);
  102. m_topLevelInfo.m_instancesBuffer->unmap();
  103. // Geom
  104. VkAccelerationStructureGeometryKHR& geom = m_geometry;
  105. geom.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
  106. geom.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
  107. geom.geometry.instances.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR;
  108. geom.geometry.instances.data.deviceAddress = m_topLevelInfo.m_instancesBuffer->getGpuAddress();
  109. geom.geometry.instances.arrayOfPointers = false;
  110. geom.flags = VK_GEOMETRY_OPAQUE_BIT_KHR; // TODO
  111. // Geom build info
  112. VkAccelerationStructureBuildGeometryInfoKHR& buildInfo = m_buildInfo;
  113. buildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
  114. buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
  115. buildInfo.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR;
  116. buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
  117. buildInfo.geometryCount = 1;
  118. buildInfo.pGeometries = &geom;
  119. // Get memory info
  120. VkAccelerationStructureBuildSizesInfoKHR buildSizes = {};
  121. const U32 instanceCount = inf.m_topLevel.m_instances.getSize();
  122. buildSizes.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR;
  123. vkGetAccelerationStructureBuildSizesKHR(vkdev, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &buildInfo, &instanceCount, &buildSizes);
  124. m_scratchBufferSize = U32(buildSizes.buildScratchSize);
  125. // Create the buffer that holds the AS memory
  126. BufferInitInfo bufferInit(inf.getName());
  127. bufferInit.m_usage = PrivateBufferUsageBit::kAccelerationStructure;
  128. bufferInit.m_size = buildSizes.accelerationStructureSize;
  129. m_asBuffer = getGrManagerImpl().newBuffer(bufferInit);
  130. // Create the AS
  131. VkAccelerationStructureCreateInfoKHR asCi = {};
  132. asCi.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
  133. asCi.createFlags = 0;
  134. asCi.buffer = static_cast<const BufferImpl&>(*m_asBuffer).getHandle();
  135. asCi.offset = 0;
  136. asCi.size = buildSizes.accelerationStructureSize;
  137. asCi.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
  138. ANKI_VK_CHECK(vkCreateAccelerationStructureKHR(vkdev, &asCi, nullptr, &m_handle));
  139. // Almost finalize the build info
  140. buildInfo.dstAccelerationStructure = m_handle;
  141. // Range info
  142. m_rangeInfo.primitiveCount = inf.m_topLevel.m_instances.getSize();
  143. }
  144. return Error::kNone;
  145. }
  146. void AccelerationStructureImpl::computeBarrierInfo(AccelerationStructureUsageBit before, AccelerationStructureUsageBit after,
  147. VkPipelineStageFlags& srcStages, VkAccessFlags& srcAccesses, VkPipelineStageFlags& dstStages,
  148. VkAccessFlags& dstAccesses)
  149. {
  150. // Before
  151. srcStages = 0;
  152. srcAccesses = 0;
  153. if(before == AccelerationStructureUsageBit::kNone)
  154. {
  155. srcStages |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
  156. srcAccesses |= 0;
  157. }
  158. if(!!(before & AccelerationStructureUsageBit::kBuild))
  159. {
  160. srcStages |= VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR;
  161. srcAccesses |= VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
  162. }
  163. if(!!(before & AccelerationStructureUsageBit::kAttach))
  164. {
  165. srcStages |= VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR;
  166. srcAccesses |= VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
  167. }
  168. if(!!(before & AccelerationStructureUsageBit::kGeometryRead))
  169. {
  170. srcStages |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
  171. | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
  172. srcAccesses |= VK_ACCESS_MEMORY_READ_BIT; // READ_BIT is the only viable solution by elimination
  173. }
  174. if(!!(before & AccelerationStructureUsageBit::kFragmentRead))
  175. {
  176. srcStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  177. srcAccesses |= VK_ACCESS_MEMORY_READ_BIT;
  178. }
  179. if(!!(before & AccelerationStructureUsageBit::kComputeRead))
  180. {
  181. srcStages |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
  182. srcAccesses |= VK_ACCESS_MEMORY_READ_BIT;
  183. }
  184. if(!!(before & AccelerationStructureUsageBit::kTraceRaysRead))
  185. {
  186. srcStages |= VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR;
  187. srcAccesses |= VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
  188. }
  189. // After
  190. dstStages = 0;
  191. dstAccesses = 0;
  192. if(!!(after & AccelerationStructureUsageBit::kBuild))
  193. {
  194. dstStages |= VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR;
  195. dstAccesses |= VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
  196. }
  197. if(!!(after & AccelerationStructureUsageBit::kAttach))
  198. {
  199. dstStages |= VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR;
  200. dstAccesses |= VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
  201. }
  202. if(!!(after & AccelerationStructureUsageBit::kGeometryRead))
  203. {
  204. dstStages |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
  205. | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
  206. dstAccesses |= VK_ACCESS_MEMORY_READ_BIT; // READ_BIT is the only viable solution by elimination
  207. }
  208. if(!!(after & AccelerationStructureUsageBit::kFragmentRead))
  209. {
  210. dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  211. dstAccesses |= VK_ACCESS_MEMORY_READ_BIT;
  212. }
  213. if(!!(after & AccelerationStructureUsageBit::kComputeRead))
  214. {
  215. dstStages |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
  216. dstAccesses |= VK_ACCESS_MEMORY_READ_BIT;
  217. }
  218. if(!!(after & AccelerationStructureUsageBit::kTraceRaysRead))
  219. {
  220. dstStages |= VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR;
  221. dstAccesses |= VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
  222. }
  223. ANKI_ASSERT(srcStages && dstStages);
  224. }
  225. } // end namespace anki