AccelerationStructureImpl.cpp 11 KB

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