From 113be317b374de8ad13f9f7272b28909e9b647a1 Mon Sep 17 00:00:00 2001
From: Vanessa Karolek <vaka1997@uni-koblenz.de>
Date: Thu, 26 Aug 2021 15:56:05 +0200
Subject: [PATCH] [#92] remove features from RTX, add BLAS building, adjust
 BufferUsageFlags

---
 modules/rtx/include/vkcv/rtx/ASManager.hpp |  9 +++
 modules/rtx/include/vkcv/rtx/RTX.hpp       |  9 +--
 modules/rtx/src/vkcv/rtx/ASManager.cpp     | 94 +++++++++++++++++++---
 modules/rtx/src/vkcv/rtx/RTX.cpp           | 16 ++--
 src/vkcv/BufferManager.cpp                 |  2 +-
 5 files changed, 101 insertions(+), 29 deletions(-)

diff --git a/modules/rtx/include/vkcv/rtx/ASManager.hpp b/modules/rtx/include/vkcv/rtx/ASManager.hpp
index db6c67a6..aecc8d21 100644
--- a/modules/rtx/include/vkcv/rtx/ASManager.hpp
+++ b/modules/rtx/include/vkcv/rtx/ASManager.hpp
@@ -1,12 +1,14 @@
 #pragma once
 
 #include <vkcv/Core.hpp>
+#include <vkcv/scene/Scene.hpp>
 
 namespace vkcv::rtx {
 
     class ASManager {
     private:
         vkcv::BufferHandle m_buffer;
+        Core* m_core;
 
     public:
 
@@ -14,5 +16,12 @@ namespace vkcv::rtx {
          * @brief TODO
          */
         ASManager(vkcv::Core *core);
+
+        /**
+         * @brief Build a Bottom Level Acceleration Structure object from given @p vertexBuffer and @p indexBuffer.
+         * @param[in] vertexBuffer The vertex buffer.
+         * @param[in] indexBuffer The index buffer.
+         */
+        void buildBLAS(Buffer<uint8_t> &vertexBuffer, Buffer<uint8_t> &indexBuffer);
     };
 }
\ No newline at end of file
diff --git a/modules/rtx/include/vkcv/rtx/RTX.hpp b/modules/rtx/include/vkcv/rtx/RTX.hpp
index d7c2e766..82c83747 100644
--- a/modules/rtx/include/vkcv/rtx/RTX.hpp
+++ b/modules/rtx/include/vkcv/rtx/RTX.hpp
@@ -10,8 +10,6 @@ namespace vkcv::rtx {
 
         std::vector<const char*> m_instanceExtensions;
         std::vector<const char*> m_deviceExtensions;
-        vk::PhysicalDevice m_physicalDevice;
-        vk::PhysicalDeviceRayTracingPipelinePropertiesKHR m_rtProperties{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR};
 
     public:
 
@@ -39,10 +37,11 @@ namespace vkcv::rtx {
 
         /**
          * @brief TODO
-         * @param physicalDevice
+         * @param core
+         * @param vertexBuffer
+         * @param indexBuffer
          */
-        void init(vk::PhysicalDevice &physicalDevice);
-
+        void init(vkcv::Buffer<uint8_t> vertexBuffer, vkcv::Buffer<uint8_t> indexBuffer);
     };
 
 }
diff --git a/modules/rtx/src/vkcv/rtx/ASManager.cpp b/modules/rtx/src/vkcv/rtx/ASManager.cpp
index 70d12c4b..2ff7e9dd 100644
--- a/modules/rtx/src/vkcv/rtx/ASManager.cpp
+++ b/modules/rtx/src/vkcv/rtx/ASManager.cpp
@@ -2,22 +2,92 @@
 
 namespace vkcv::rtx {
 
-    ASManager::ASManager(vkcv::Core *core) {
-        // RaytracingBuilder : build BLAS
-        // BLAS is a vector of BLASEntries which take entries of BLASInput vector
+    ASManager::ASManager(vkcv::Core *core) :
+    m_core(core) {
 
-        // we need to prepare build information for acceleration build command
-//        std::vector<vk::AccelerationStructureBuildGeometryInfoKHR> buildInfos(0 /* size of BLAS vector as uint32_t */);
+        // SUGGESTION: recursive call of buildBLAS etc.
 
 
-        // list of BLAS -> for each BLAS take AccelKHR -> createAcceleration(VkAccelerationStructureCreateInfoKHR)
-//        vk::AccelerationStructureCreateInfoKHR asCreateInfo = {
-//                {},
-//                /* hier muss ein buffer hin */
-//        };
-//        asCreateInfo.
 
-//        m_buffer = core->createBuffer<void*>(vkcv::BufferType::RT_ACCELERATION, )   // we need the size for the buffer :c
+    }
+
+    void ASManager::buildBLAS(Buffer<uint8_t> &vertexBuffer, Buffer<uint8_t> &indexBuffer) {
+        vk::BufferDeviceAddressInfo vertexBufferDeviceAddressInfo(vertexBuffer.getVulkanHandle());
+        vk::DeviceAddress vertexBufferAddress = m_core->getContext().getDevice().getBufferAddressKHR(vertexBufferDeviceAddressInfo);
+        vk::DeviceOrHostAddressConstKHR vertexDeviceOrHostAddressConst(vertexBufferAddress);
+
+        vk::BufferDeviceAddressInfo indexBufferDeviceAddressInfo(indexBuffer.getVulkanHandle());
+        vk::DeviceAddress indexBufferAddress = m_core->getContext().getDevice().getBufferAddressKHR(indexBufferDeviceAddressInfo);
+        vk::DeviceOrHostAddressConstKHR indexDeviceOrHostAddressConst(indexBufferAddress);
+
+        // Specify triangle mesh data // TODO: Check if valid entries ...
+        vk::AccelerationStructureGeometryTrianglesDataKHR asTriangles(
+                vk::Format::eR32G32B32Sfloat,   // vertex format
+                vertexDeviceOrHostAddressConst, // vertex buffer address (vk::DeviceOrHostAddressConstKHR)
+                3 * sizeof(float), // vertex stride (vk::DeviceSize)
+                uint32_t(vertexBuffer.getCount() - 1), // maxVertex (uint32_t)
+                vk::IndexType::eUint8EXT, // indexType (vk::IndexType)
+                indexDeviceOrHostAddressConst, // indexData (vk::DeviceOrHostAddressConstKHR)
+                (vk::DeviceOrHostAddressConstKHR) {} // transformData (vk::DeviceOrHostAddressConstKHR)
+        );
+
+        // Encapsulate geometry data
+        vk::AccelerationStructureGeometryKHR asGeometry(
+                vk::GeometryTypeKHR::eTriangles, // The geometry type, e.g. triangles, AABBs, instances
+                asTriangles, // the geometry data
+                vk::GeometryFlagBitsKHR::eOpaque // This flag disables any-hit shaders to increase ray tracing performance
+        );
+
+        // List ranges of data for access
+        vk::AccelerationStructureBuildRangeInfoKHR asRangeInfo(
+                uint32_t(indexBuffer.getCount() / 3), // the primitiveCount (uint32_t)
+                0, // primitiveOffset (uint32_t)
+                0, // firstVertex (uint32_t)
+                0  // transformOffset (uint32_t)
+        );
+
+        // Query the worst-case amount of memory needed for the AS
+        vk::AccelerationStructureBuildGeometryInfoKHR asBuildInfo(
+                vk::AccelerationStructureTypeKHR::eBottomLevel, // type of the AS: bottom vs. top
+                vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace, // some flags for different purposes, e.g. efficiency
+                vk::BuildAccelerationStructureModeKHR::eBuild, // AS mode: build vs. update
+                {}, // src AS (this seems to be for copying AS)
+                {}, // dst AS (this seems to be for copying AS)
+                1, // the geometryCount. TODO: how many do we need?
+                &asGeometry // the next input entry would be a pointer to a pointer to geometries. Maybe geometryCount depends on the next entry?
+        );
+        vk::AccelerationStructureBuildSizesInfoKHR asBuildSizesInfo;
+        m_core->getContext().getDevice().getAccelerationStructureBuildSizesKHR(
+                vk::AccelerationStructureBuildTypeKHR::eDevice, // build on device instead of host
+                &asBuildInfo, // pointer to build info
+                &asRangeInfo.primitiveCount, // array of number of primitives per geometry
+                &asBuildSizesInfo  // output pointer to store sizes
+                );
+
+        // Allocate the AS TODO: which type do we need for the buffer??
+        Buffer<vk::AccelerationStructureKHR> asBuffer = m_core->createBuffer<vk::AccelerationStructureKHR>(BufferType::RT_ACCELERATION, asBuildSizesInfo.accelerationStructureSize, BufferMemoryType::DEVICE_LOCAL);
+        //        core->createBuffer<>()
+
+        // Create an empty AS object
+        vk::AccelerationStructureCreateInfoKHR asCreateInfo(
+                {}, // creation flags
+                asBuffer.getVulkanHandle(), // allocated AS buffer.
+                0,
+                asBuildSizesInfo.accelerationStructureSize, // size of the AS
+                asBuildInfo.type // type of the AS
+        );
+
+        // Create the intended AS object
+        vk::AccelerationStructureKHR blas;
+        vk::Result res = m_core->getContext().getDevice().createAccelerationStructureKHR(
+                &asCreateInfo, // AS create info
+                nullptr, // allocator callbacks
+                &blas // the AS
+        );
+        if(res != vk::Result::eSuccess) {
+            vkcv_log(vkcv::LogLevel::ERROR, "The Bottom Level Acceleration Structure could not be builded!");
+        }
+        asBuildInfo.setDstAccelerationStructure(blas);
     }
 
 }
\ No newline at end of file
diff --git a/modules/rtx/src/vkcv/rtx/RTX.cpp b/modules/rtx/src/vkcv/rtx/RTX.cpp
index 48e8a05f..69eb8fb3 100644
--- a/modules/rtx/src/vkcv/rtx/RTX.cpp
+++ b/modules/rtx/src/vkcv/rtx/RTX.cpp
@@ -1,4 +1,5 @@
 #include "vkcv/rtx/RTX.hpp"
+#include "vkcv/rtx/ASManager.hpp"
 
 namespace vkcv::rtx {
 
@@ -19,19 +20,13 @@ namespace vkcv::rtx {
                 "VK_KHR_ray_query",
                 "VK_KHR_pipeline_library"
         };
-
-        // enable raytracing features!
-        vk::PhysicalDeviceAccelerationStructureFeaturesKHR accelerationFeature(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR);
-        vk::PhysicalDeviceRayTracingPipelineFeaturesKHR raytracingPipelineFeature(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR);
     }
 
-    void RTXModule::init(vk::PhysicalDevice &physicalDevice) {
-        m_physicalDevice = physicalDevice;
+    void RTXModule::init(vkcv::Buffer<uint8_t> vertexBuffer, vkcv::Buffer<uint8_t> indexBuffer) {
+
+        // build acceleration structures BLAS then TLAS --> see ASManager
+//        ASManager asManager(core);
 
-        // Requesting ray tracing properties
-        vk::PhysicalDeviceProperties2 prop2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2};
-        prop2.pNext = &m_rtProperties;
-        m_physicalDevice.getProperties2(&prop2);
     }
 
     std::vector<const char*> RTXModule::getInstanceExtensions() {
@@ -42,5 +37,4 @@ namespace vkcv::rtx {
         return m_deviceExtensions;
     }
 
-
 }
\ No newline at end of file
diff --git a/src/vkcv/BufferManager.cpp b/src/vkcv/BufferManager.cpp
index 7d7fc40e..f978f40e 100644
--- a/src/vkcv/BufferManager.cpp
+++ b/src/vkcv/BufferManager.cpp
@@ -49,7 +49,7 @@ namespace vkcv {
 				usageFlags = vk::BufferUsageFlagBits::eIndexBuffer;
 				break;
 		    case BufferType::RT_ACCELERATION:
-		        usageFlags = vk::BufferUsageFlagBits::eAccelerationStructureStorageKHR | vk::BufferUsageFlagBits::eShaderDeviceAddress;
+		        usageFlags = vk::BufferUsageFlagBits::eAccelerationStructureStorageKHR | vk::BufferUsageFlagBits::eShaderDeviceAddress | vk::BufferUsageFlagBits::eStorageBuffer;
 		        break;
 			default:
 				// TODO: maybe an issue
-- 
GitLab