2
0

AccelerationStructureImpl.cpp 11 KB

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