Advertisement
Guest User

Vulkan TLAS building problems

a guest
Nov 30th, 2024
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.82 KB | Source Code | 0 0
  1. void AccelerationStructure::build(vk::BuildAccelerationStructureModeKHR mode, vk::ArrayProxyNoTemporaries<vk::SharedSemaphore> waitSemaphores, vk::ArrayProxyNoTemporaries<vk::SharedSemaphore> signalSemaphores) {
  2.     device->waitForFences(*buildFinishedFence, vk::True, std::numeric_limits<uint64_t>::max());
  3.     asBuildCmdBuffer->reset();
  4.     asBuildCmdBuffer->begin(vk::CommandBufferBeginInfo{}.setFlags(vk::CommandBufferUsageFlagBits::eOneTimeSubmit));
  5.  
  6.     std::vector<std::unique_ptr<Buffer>> blasScratchBuffers;
  7.     buildBLAS(blasScratchBuffers, mode);
  8.  
  9.     // Insert pipeline barrier betwee BLAS and TLAS build
  10.     auto& memBarrier = vk::MemoryBarrier{}
  11.         .setSrcAccessMask(vk::AccessFlagBits::eAccelerationStructureWriteKHR)
  12.         .setDstAccessMask(vk::AccessFlagBits::eAccelerationStructureReadKHR);
  13.     std::vector<vk::BufferMemoryBarrier> blasMemBarriers;
  14.     blasMemBarriers.reserve(blasBuffers.size());
  15.     for (auto& b : blasBuffers) {
  16.         blasMemBarriers.push_back(vk::BufferMemoryBarrier{}
  17.                                   .setBuffer(**b)
  18.                                   .setSrcAccessMask(vk::AccessFlagBits::eAccelerationStructureWriteKHR)
  19.                                   .setDstAccessMask(vk::AccessFlagBits::eAccelerationStructureReadKHR)
  20.                                   .setOffset(0u)
  21.                                   .setSize(vk::WholeSize));
  22.     }
  23.     asBuildCmdBuffer->pipelineBarrier(vk::PipelineStageFlagBits::eAccelerationStructureBuildKHR, vk::PipelineStageFlagBits::eAccelerationStructureBuildKHR,
  24.                                       {}, memBarrier, blasMemBarriers, {});
  25.  
  26.     std::unique_ptr<Buffer> instancesBuffer, tlasScratchBuffer;
  27.     buildTLAS(instancesBuffer, tlasScratchBuffer, mode);
  28.     asBuildCmdBuffer->end();
  29.  
  30.     // Submit build commands
  31.     std::vector<vk::PipelineStageFlags> submitWaitDstStageMask(waitSemaphores.size());
  32.     std::vector<vk::Semaphore> submitWaitSemaphores(waitSemaphores.size());
  33.     std::vector<vk::Semaphore> submitSignalSemaphores(signalSemaphores.size());
  34.     std::fill(submitWaitDstStageMask.begin(), submitWaitDstStageMask.end(), vk::PipelineStageFlagBits::eAccelerationStructureBuildKHR);
  35.     std::transform(waitSemaphores.begin(), waitSemaphores.end(), submitWaitSemaphores.begin(),
  36.                    [](const vk::SharedSemaphore& ws) { return *ws; });
  37.     std::transform(signalSemaphores.begin(), signalSemaphores.end(), submitSignalSemaphores.begin(),
  38.                    [](const vk::SharedSemaphore& ss) { return *ss; });
  39.     auto& submitInfo = vk::SubmitInfo{}
  40.         .setCommandBuffers(*asBuildCmdBuffer)
  41.         .setWaitDstStageMask(submitWaitDstStageMask)
  42.         .setWaitSemaphores(submitWaitSemaphores)
  43.         .setSignalSemaphores(submitSignalSemaphores);
  44.     device->resetFences(*buildFinishedFence);
  45.     std::get<vk::Queue>(computeQueue).submit(submitInfo, *buildFinishedFence);
  46.     CHECK_VULKAN_RESULT(device->waitForFences(*buildFinishedFence, vk::True, std::numeric_limits<uint64_t>::max()));
  47. }
  48.  
  49. void AccelerationStructure::buildTLAS(std::unique_ptr<Buffer>& instancesBuffer, std::unique_ptr<Buffer>& scratchBuffer, vk::BuildAccelerationStructureModeKHR mode) {
  50.     std::vector<vk::AccelerationStructureInstanceKHR> instanceData;
  51.     instanceData.reserve(scene.objectCount);
  52.  
  53.     uint32_t idx = 0;
  54.     for (auto& it = scene.begin(); it != scene.end(); it++) {
  55.         auto& sceneObject = (*it);
  56.         if (sceneObject.meshIdx) {
  57.             std::array<std::array<float, 4Ui64>, 3Ui64> transformMatrix;
  58.             auto& affineTransform = glm::mat3x4(glm::transpose(it.transform));
  59.             memcpy(transformMatrix.data(), &affineTransform, sizeof(transformMatrix));
  60.             instanceData.push_back(vk::AccelerationStructureInstanceKHR{}
  61.                                    .setTransform(vk::TransformMatrixKHR{}.setMatrix(transformMatrix))
  62.                                    .setInstanceCustomIndex(*sceneObject.meshIdx)
  63.                                    .setMask(0xFF)
  64.                                    .setInstanceShaderBindingTableRecordOffset(0u)
  65.                                    .setFlags(vk::GeometryInstanceFlagBitsKHR::eTriangleFacingCullDisable)
  66.                                    .setAccelerationStructureReference(device->getAccelerationStructureAddressKHR(*blas[*sceneObject.meshIdx])));
  67.             idx++;
  68.         }
  69.     }
  70.     auto& instancesBufferCI = vk::BufferCreateInfo{}
  71.         .setSize(sizeof(vk::AccelerationStructureInstanceKHR) * instanceData.size())
  72.         .setUsage(vk::BufferUsageFlagBits::eAccelerationStructureBuildInputReadOnlyKHR | vk::BufferUsageFlagBits::eShaderDeviceAddress);
  73.     instancesBuffer = std::make_unique<Buffer>(device, dmm, rch, instancesBufferCI,
  74.                                                vk::ArrayProxyNoTemporaries{ static_cast<uint32_t>(sizeof(vk::AccelerationStructureInstanceKHR) * instanceData.size()), (char*)instanceData.data() },
  75.                                                MemoryStorage::DeviceDynamic);
  76.  
  77.     auto& accelerationStructureGeometry = vk::AccelerationStructureGeometryKHR{}
  78.         .setGeometryType(vk::GeometryTypeKHR::eInstances)
  79.         .setFlags(vk::GeometryFlagBitsKHR::eOpaque)
  80.         .setGeometry(vk::AccelerationStructureGeometryInstancesDataKHR{}
  81.                      .setArrayOfPointers(vk::False)
  82.                      .setData(device->getBufferAddress(**instancesBuffer)));
  83.     auto& accelerationStructureBGI = vk::AccelerationStructureBuildGeometryInfoKHR{}
  84.         .setType(vk::AccelerationStructureTypeKHR::eTopLevel)
  85.         .setFlags(vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace)
  86.         .setGeometries(accelerationStructureGeometry);
  87.     auto& accelerationStructureBSI = device->getAccelerationStructureBuildSizesKHR(vk::AccelerationStructureBuildTypeKHR::eDevice, accelerationStructureBGI, instanceData.size());
  88.  
  89.     if (mode == vk::BuildAccelerationStructureModeKHR::eBuild) {
  90.         tlasBuffer = std::make_unique<Buffer>(device, dmm, rch, vk::BufferCreateInfo{}
  91.                                               .setSize(accelerationStructureBSI.accelerationStructureSize)
  92.                                               .setUsage(vk::BufferUsageFlagBits::eAccelerationStructureStorageKHR | vk::BufferUsageFlagBits::eShaderDeviceAddress),
  93.                                               nullptr, MemoryStorage::DevicePersistent);
  94.         auto& accelerationStructureCI = vk::AccelerationStructureCreateInfoKHR{}
  95.             .setBuffer(**tlasBuffer)
  96.             .setSize(accelerationStructureBSI.accelerationStructureSize)
  97.             .setType(vk::AccelerationStructureTypeKHR::eTopLevel);
  98.         tlas = device->createAccelerationStructureKHRUnique(accelerationStructureCI);
  99.     }
  100.  
  101.     auto& scratchBufferCI = vk::BufferCreateInfo{}
  102.         .setSize(mode == vk::BuildAccelerationStructureModeKHR::eBuild ? accelerationStructureBSI.buildScratchSize : accelerationStructureBSI.updateScratchSize)
  103.         .setUsage(vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eShaderDeviceAddress);
  104.     scratchBuffer = std::make_unique<Buffer>(device, dmm, rch, scratchBufferCI,
  105.                                              nullptr, MemoryStorage::DeviceDynamic);
  106.  
  107.     accelerationStructureBGI
  108.         .setMode(mode)
  109.         .setSrcAccelerationStructure(mode == vk::BuildAccelerationStructureModeKHR::eUpdate ? *tlas : nullptr)
  110.         .setDstAccelerationStructure(*tlas)
  111.         .setScratchData(device->getBufferAddress(**scratchBuffer));
  112.     auto& accelerationStructureBRI = vk::AccelerationStructureBuildRangeInfoKHR{}
  113.         .setPrimitiveCount(instanceData.size())
  114.         .setPrimitiveOffset(0u)
  115.         .setFirstVertex(0u)
  116.         .setTransformOffset(0u);
  117.  
  118.     asBuildCmdBuffer->buildAccelerationStructuresKHR(accelerationStructureBGI, &accelerationStructureBRI);
  119. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement