VkAccelerationStructure.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. // Copyright (C) 2009-present, 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/VkAccelerationStructure.h>
  6. #include <AnKi/Gr/Vulkan/VkGrManager.h>
  7. #include <AnKi/Gr/Vulkan/VkFrameGarbageCollector.h>
  8. #include <AnKi/Gr/Vulkan/VkBuffer.h>
  9. namespace anki {
  10. AccelerationStructure* AccelerationStructure::newInstance(const AccelerationStructureInitInfo& init)
  11. {
  12. AccelerationStructureImpl* impl = anki::newInstance<AccelerationStructureImpl>(GrMemoryPool::getSingleton(), init.getName());
  13. const Error err = impl->init(init);
  14. if(err)
  15. {
  16. deleteInstance(GrMemoryPool::getSingleton(), impl);
  17. impl = nullptr;
  18. }
  19. return impl;
  20. }
  21. U64 AccelerationStructure::getGpuAddress() const
  22. {
  23. ANKI_VK_SELF_CONST(AccelerationStructureImpl);
  24. return self.getAsDeviceAddress();
  25. }
  26. AccelerationStructureImpl::~AccelerationStructureImpl()
  27. {
  28. if(m_handle)
  29. {
  30. ASGarbage* garbage = anki::newInstance<ASGarbage>(GrMemoryPool::getSingleton());
  31. garbage->m_asHandle = m_handle;
  32. getGrManagerImpl().getFrameGarbageCollector().newASGarbage(garbage);
  33. }
  34. }
  35. Error AccelerationStructureImpl::init(const AccelerationStructureInitInfo& inf)
  36. {
  37. ANKI_TRACE_SCOPED_EVENT(VkInitAccStruct);
  38. ANKI_ASSERT(inf.isValid());
  39. m_type = inf.m_type;
  40. const VkDevice vkdev = getGrManagerImpl().getDevice();
  41. if(m_type == AccelerationStructureType::kBottomLevel)
  42. {
  43. // Geom
  44. VkAccelerationStructureGeometryKHR& geom = m_geometry;
  45. geom.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
  46. geom.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR;
  47. geom.geometry.triangles.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR;
  48. geom.geometry.triangles.vertexFormat = convertFormat(inf.m_bottomLevel.m_positionsFormat);
  49. geom.geometry.triangles.vertexData.deviceAddress =
  50. inf.m_bottomLevel.m_positionBuffer.getBuffer().getGpuAddress() + inf.m_bottomLevel.m_positionBuffer.getOffset();
  51. geom.geometry.triangles.vertexStride = inf.m_bottomLevel.m_positionStride;
  52. geom.geometry.triangles.maxVertex = inf.m_bottomLevel.m_positionCount - 1;
  53. geom.geometry.triangles.indexType = convertIndexType(inf.m_bottomLevel.m_indexType);
  54. geom.geometry.triangles.indexData.deviceAddress =
  55. inf.m_bottomLevel.m_indexBuffer.getBuffer().getGpuAddress() + inf.m_bottomLevel.m_indexBuffer.getOffset();
  56. geom.flags = 0; // VK_GEOMETRY_OPAQUE_BIT_KHR; // TODO
  57. // Geom build info
  58. VkAccelerationStructureBuildGeometryInfoKHR& buildInfo = m_buildInfo;
  59. buildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
  60. buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
  61. buildInfo.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
  62. buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
  63. buildInfo.geometryCount = 1;
  64. buildInfo.pGeometries = &geom;
  65. // Get memory info
  66. VkAccelerationStructureBuildSizesInfoKHR buildSizes = {};
  67. const U32 primitiveCount = inf.m_bottomLevel.m_indexCount / 3;
  68. buildSizes.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR;
  69. vkGetAccelerationStructureBuildSizesKHR(vkdev, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &buildInfo, &primitiveCount, &buildSizes);
  70. m_scratchBufferSize = buildSizes.buildScratchSize;
  71. // Create the buffer that holds the AS memory
  72. BufferInitInfo bufferInit(inf.getName());
  73. bufferInit.m_usage = PrivateBufferUsageBit::kAccelerationStructure;
  74. bufferInit.m_size = buildSizes.accelerationStructureSize;
  75. m_asBuffer = getGrManagerImpl().newBuffer(bufferInit);
  76. // Create the AS
  77. VkAccelerationStructureCreateInfoKHR asCi = {};
  78. asCi.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
  79. asCi.createFlags = 0;
  80. asCi.buffer = static_cast<const BufferImpl&>(*m_asBuffer).getHandle();
  81. asCi.offset = 0;
  82. asCi.size = buildSizes.accelerationStructureSize;
  83. asCi.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
  84. ANKI_VK_CHECK(vkCreateAccelerationStructureKHR(vkdev, &asCi, nullptr, &m_handle));
  85. // Get its address
  86. VkAccelerationStructureDeviceAddressInfoKHR addressInfo = {};
  87. addressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
  88. addressInfo.accelerationStructure = m_handle;
  89. m_deviceAddress = vkGetAccelerationStructureDeviceAddressKHR(vkdev, &addressInfo);
  90. // Almost finalize the build info
  91. buildInfo.dstAccelerationStructure = m_handle;
  92. // Range info
  93. m_rangeInfo.primitiveCount = primitiveCount;
  94. }
  95. else
  96. {
  97. const Bool isIndirect = inf.m_topLevel.m_indirectArgs.m_maxInstanceCount > 0;
  98. if(!isIndirect)
  99. {
  100. // Create and populate the instances buffer
  101. m_topLevelInfo.m_blases.resizeStorage(inf.m_topLevel.m_directArgs.m_instances.getSize());
  102. BufferInitInfo buffInit("AS instances");
  103. buffInit.m_size = sizeof(VkAccelerationStructureInstanceKHR) * inf.m_topLevel.m_directArgs.m_instances.getSize();
  104. buffInit.m_usage = PrivateBufferUsageBit::kAccelerationStructure;
  105. buffInit.m_mapAccess = BufferMapAccessBit::kWrite;
  106. m_topLevelInfo.m_instancesBuffer = getGrManagerImpl().newBuffer(buffInit);
  107. VkAccelerationStructureInstanceKHR* instances =
  108. static_cast<VkAccelerationStructureInstanceKHR*>(m_topLevelInfo.m_instancesBuffer->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite));
  109. for(U32 i = 0; i < inf.m_topLevel.m_directArgs.m_instances.getSize(); ++i)
  110. {
  111. VkAccelerationStructureInstanceKHR& outInst = instances[i];
  112. const AccelerationStructureInstanceInfo& inInst = inf.m_topLevel.m_directArgs.m_instances[i];
  113. static_assert(sizeof(outInst.transform) == sizeof(inInst.m_transform), "See file");
  114. memcpy(&outInst.transform, &inInst.m_transform, sizeof(inInst.m_transform));
  115. outInst.instanceCustomIndex = i & 0xFFFFFF;
  116. outInst.mask = inInst.m_mask;
  117. outInst.instanceShaderBindingTableRecordOffset = inInst.m_hitgroupSbtRecordIndex & 0xFFFFFF;
  118. outInst.flags =
  119. VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR | VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
  120. outInst.accelerationStructureReference = static_cast<const AccelerationStructureImpl&>(*inInst.m_bottomLevel).m_deviceAddress;
  121. ANKI_ASSERT(outInst.accelerationStructureReference != 0);
  122. // Hold the reference
  123. m_topLevelInfo.m_blases.emplaceBack(inf.m_topLevel.m_directArgs.m_instances[i].m_bottomLevel);
  124. }
  125. m_topLevelInfo.m_instancesBuffer->flush(0, kMaxPtrSize);
  126. m_topLevelInfo.m_instancesBuffer->unmap();
  127. }
  128. else
  129. {
  130. // Instances buffer already created
  131. ANKI_ASSERT(inf.m_topLevel.m_indirectArgs.m_instancesBuffer.getOffset()
  132. + sizeof(VkAccelerationStructureInstanceKHR) * inf.m_topLevel.m_indirectArgs.m_maxInstanceCount
  133. <= inf.m_topLevel.m_indirectArgs.m_instancesBuffer.getRange());
  134. m_topLevelInfo.m_instancesBuffer.reset(&inf.m_topLevel.m_indirectArgs.m_instancesBuffer.getBuffer());
  135. m_topLevelInfo.m_maxInstanceCount = inf.m_topLevel.m_indirectArgs.m_maxInstanceCount;
  136. }
  137. // Geom
  138. VkAccelerationStructureGeometryKHR& geom = m_geometry;
  139. geom.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
  140. geom.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
  141. geom.geometry.instances.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR;
  142. geom.geometry.instances.data.deviceAddress = m_topLevelInfo.m_instancesBuffer->getGpuAddress();
  143. if(isIndirect)
  144. {
  145. geom.geometry.instances.data.deviceAddress += inf.m_topLevel.m_indirectArgs.m_instancesBuffer.getRange();
  146. }
  147. geom.geometry.instances.arrayOfPointers = false;
  148. geom.flags = VK_GEOMETRY_OPAQUE_BIT_KHR; // TODO
  149. // Geom build info
  150. VkAccelerationStructureBuildGeometryInfoKHR& buildInfo = m_buildInfo;
  151. buildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
  152. buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
  153. buildInfo.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR;
  154. buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
  155. buildInfo.geometryCount = 1;
  156. buildInfo.pGeometries = &geom;
  157. // Get memory info
  158. VkAccelerationStructureBuildSizesInfoKHR buildSizes = {};
  159. const U32 instanceCount = (isIndirect) ? inf.m_topLevel.m_indirectArgs.m_maxInstanceCount : inf.m_topLevel.m_directArgs.m_instances.getSize();
  160. buildSizes.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR;
  161. vkGetAccelerationStructureBuildSizesKHR(vkdev, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &buildInfo, &instanceCount, &buildSizes);
  162. m_scratchBufferSize = buildSizes.buildScratchSize;
  163. // Create the buffer that holds the AS memory
  164. BufferInitInfo bufferInit(inf.getName());
  165. bufferInit.m_usage = PrivateBufferUsageBit::kAccelerationStructure;
  166. bufferInit.m_size = buildSizes.accelerationStructureSize;
  167. m_asBuffer = getGrManagerImpl().newBuffer(bufferInit);
  168. // Create the AS
  169. VkAccelerationStructureCreateInfoKHR asCi = {};
  170. asCi.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
  171. asCi.createFlags = 0;
  172. asCi.buffer = static_cast<const BufferImpl&>(*m_asBuffer).getHandle();
  173. asCi.offset = 0;
  174. asCi.size = buildSizes.accelerationStructureSize;
  175. asCi.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
  176. ANKI_VK_CHECK(vkCreateAccelerationStructureKHR(vkdev, &asCi, nullptr, &m_handle));
  177. // Almost finalize the build info
  178. buildInfo.dstAccelerationStructure = m_handle;
  179. // Range info
  180. m_rangeInfo.primitiveCount = instanceCount;
  181. }
  182. return Error::kNone;
  183. }
  184. VkMemoryBarrier AccelerationStructureImpl::computeBarrierInfo(AccelerationStructureUsageBit before, AccelerationStructureUsageBit after,
  185. VkPipelineStageFlags& srcStages_, VkPipelineStageFlags& dstStages_)
  186. {
  187. VkMemoryBarrier barrier = {};
  188. barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
  189. // Before
  190. VkPipelineStageFlags srcStages = 0;
  191. if(before == AccelerationStructureUsageBit::kNone)
  192. {
  193. srcStages |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
  194. barrier.srcAccessMask |= 0;
  195. }
  196. if(!!(before & AccelerationStructureUsageBit::kBuild))
  197. {
  198. srcStages |= VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR;
  199. barrier.srcAccessMask |= VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
  200. }
  201. if(!!(before & AccelerationStructureUsageBit::kAttach))
  202. {
  203. srcStages |= VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR;
  204. barrier.srcAccessMask |= VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
  205. }
  206. if(!!(before & AccelerationStructureUsageBit::kGeometrySrv))
  207. {
  208. srcStages |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
  209. | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
  210. barrier.srcAccessMask |= VK_ACCESS_MEMORY_READ_BIT; // READ_BIT is the only viable solution by elimination
  211. }
  212. if(!!(before & AccelerationStructureUsageBit::kPixelSrv))
  213. {
  214. srcStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  215. barrier.srcAccessMask |= VK_ACCESS_MEMORY_READ_BIT;
  216. }
  217. if(!!(before & AccelerationStructureUsageBit::kComputeSrv))
  218. {
  219. srcStages |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
  220. barrier.srcAccessMask |= VK_ACCESS_MEMORY_READ_BIT;
  221. }
  222. if(!!(before & AccelerationStructureUsageBit::kTraceRaysSrv))
  223. {
  224. srcStages |= VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR;
  225. barrier.srcAccessMask |= VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
  226. }
  227. // After
  228. VkPipelineStageFlags dstStages = 0;
  229. if(!!(after & AccelerationStructureUsageBit::kBuild))
  230. {
  231. dstStages |= VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR;
  232. barrier.dstAccessMask |= VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
  233. }
  234. if(!!(after & AccelerationStructureUsageBit::kAttach))
  235. {
  236. dstStages |= VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR;
  237. barrier.dstAccessMask |= VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
  238. }
  239. if(!!(after & AccelerationStructureUsageBit::kGeometrySrv))
  240. {
  241. dstStages |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
  242. | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
  243. barrier.dstAccessMask |= VK_ACCESS_MEMORY_READ_BIT; // READ_BIT is the only viable solution by elimination
  244. }
  245. if(!!(after & AccelerationStructureUsageBit::kPixelSrv))
  246. {
  247. dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  248. barrier.dstAccessMask |= VK_ACCESS_MEMORY_READ_BIT;
  249. }
  250. if(!!(after & AccelerationStructureUsageBit::kComputeSrv))
  251. {
  252. dstStages |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
  253. barrier.dstAccessMask |= VK_ACCESS_MEMORY_READ_BIT;
  254. }
  255. if(!!(after & AccelerationStructureUsageBit::kTraceRaysSrv))
  256. {
  257. dstStages |= VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR;
  258. barrier.dstAccessMask |= VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
  259. }
  260. ANKI_ASSERT(srcStages && dstStages);
  261. srcStages_ |= srcStages;
  262. dstStages_ |= dstStages;
  263. return barrier;
  264. }
  265. } // end namespace anki