From d89cf80ac2fea69a26bf203954bb5c072738caae Mon Sep 17 00:00:00 2001
From: Vanessa Karolek <vaka1997@uni-koblenz.de>
Date: Wed, 1 Sep 2021 14:49:09 +0200
Subject: [PATCH] [#92] get required RTX Features in RTXModule now

---
 modules/rtx/include/vkcv/rtx/RTX.hpp |   7 ++
 modules/rtx/src/vkcv/rtx/RTX.cpp     | 115 ++++++++++++++++++++++++---
 projects/rtx/src/main.cpp            |  32 +++-----
 3 files changed, 123 insertions(+), 31 deletions(-)

diff --git a/modules/rtx/include/vkcv/rtx/RTX.hpp b/modules/rtx/include/vkcv/rtx/RTX.hpp
index 13469b5b..957ce9bb 100644
--- a/modules/rtx/include/vkcv/rtx/RTX.hpp
+++ b/modules/rtx/include/vkcv/rtx/RTX.hpp
@@ -11,6 +11,7 @@ namespace vkcv::rtx {
 
         std::vector<const char*> m_instanceExtensions;
         std::vector<const char*> m_deviceExtensions;
+        vkcv::Features m_features;
 
     public:
 
@@ -36,6 +37,12 @@ namespace vkcv::rtx {
          */
         std::vector<const char*> getDeviceExtensions();
 
+        /**
+         * @brief TODO
+         * @return
+         */
+        vkcv::Features getFeatures();
+
         /**
          * @brief TODO
          * @param core
diff --git a/modules/rtx/src/vkcv/rtx/RTX.cpp b/modules/rtx/src/vkcv/rtx/RTX.cpp
index b4e07e71..7b81f4a0 100644
--- a/modules/rtx/src/vkcv/rtx/RTX.cpp
+++ b/modules/rtx/src/vkcv/rtx/RTX.cpp
@@ -7,19 +7,110 @@ namespace vkcv::rtx {
 
         // prepare needed raytracing extensions
         m_instanceExtensions = {
-                "VK_KHR_get_physical_device_properties2"
+                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME
         };
         m_deviceExtensions = {
-                "VK_KHR_maintenance3",
-                "VK_EXT_descriptor_indexing",
-                "VK_KHR_buffer_device_address",
-                "VK_KHR_deferred_host_operations",
-                "VK_KHR_acceleration_structure",
-                "VK_KHR_spirv_1_4",
-                "VK_KHR_ray_tracing_pipeline",
-                "VK_KHR_ray_query",
-                "VK_KHR_pipeline_library"
+                VK_KHR_MAINTENANCE3_EXTENSION_NAME,
+                VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME,
+                VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME,
+                VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME,
+                VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME,
+                VK_KHR_SPIRV_1_4_EXTENSION_NAME,
+                VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME,
+                VK_KHR_RAY_QUERY_EXTENSION_NAME,
+                VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME
         };
+
+        // get all features required by the device extensions
+        for(auto deviceExtension : m_deviceExtensions) {
+            m_features.requireExtension(deviceExtension);
+        }
+
+        /* FIXME : We must disable features that will be mentioned as "not supported" by the FeatureManager. If every unsupported feature is disabled, this should work.
+         * Maybe we find a better workaround...
+         */
+        m_features.requireFeature<vk::PhysicalDeviceVulkan12Features>(
+                [](vk::PhysicalDeviceVulkan12Features &features) {
+                    features.setSamplerMirrorClampToEdge(true);
+                    features.setDrawIndirectCount(true);
+                    features.setStorageBuffer8BitAccess(true);
+                    features.setUniformAndStorageBuffer8BitAccess(true);
+                    features.setStoragePushConstant8(true);
+                    features.setShaderBufferInt64Atomics(true);
+                    features.setShaderSharedInt64Atomics(true);
+                    features.setShaderFloat16(true);
+                    features.setShaderInt8(true);
+                    features.setDescriptorIndexing(true);
+                    features.setShaderInputAttachmentArrayDynamicIndexing(true);
+                    features.setShaderUniformTexelBufferArrayDynamicIndexing(true);
+                    features.setShaderStorageTexelBufferArrayDynamicIndexing(true);
+                    features.setShaderUniformBufferArrayNonUniformIndexing(true);
+                    features.setShaderSampledImageArrayNonUniformIndexing(true);
+                    features.setShaderStorageBufferArrayNonUniformIndexing(true);
+                    features.setShaderStorageImageArrayNonUniformIndexing(true);
+                    features.setShaderInputAttachmentArrayNonUniformIndexing(true);
+                    features.setShaderUniformTexelBufferArrayNonUniformIndexing(true);
+                    features.setShaderStorageTexelBufferArrayNonUniformIndexing(true);
+                    features.setDescriptorBindingUniformBufferUpdateAfterBind(true);
+                    features.setDescriptorBindingSampledImageUpdateAfterBind(true);
+                    features.setDescriptorBindingStorageImageUpdateAfterBind(true);
+                    features.setDescriptorBindingStorageBufferUpdateAfterBind(true);
+                    features.setDescriptorBindingUniformTexelBufferUpdateAfterBind(true);
+                    features.setDescriptorBindingStorageTexelBufferUpdateAfterBind(true);
+                    features.setDescriptorBindingUpdateUnusedWhilePending(true);
+                    features.setDescriptorBindingPartiallyBound(true);
+                    features.setDescriptorBindingVariableDescriptorCount(true);
+                    features.setRuntimeDescriptorArray(true);
+                    features.setSamplerFilterMinmax(true);
+                    features.setScalarBlockLayout(true);
+                    features.setImagelessFramebuffer(true);
+                    features.setUniformBufferStandardLayout(true);
+                    features.setShaderSubgroupExtendedTypes(true);
+                    features.setSeparateDepthStencilLayouts(true);
+                    features.setHostQueryReset(true);
+                    features.setTimelineSemaphore(true);
+                    features.setBufferDeviceAddress(true);
+                    features.setBufferDeviceAddressCaptureReplay(true);
+                    features.setBufferDeviceAddressMultiDevice(true);
+                    features.setVulkanMemoryModel(true);
+                    features.setVulkanMemoryModelDeviceScope(true);
+                    features.setVulkanMemoryModelAvailabilityVisibilityChains(true);
+                    features.setShaderOutputViewportIndex(true);
+                    features.setShaderOutputLayer(true);
+                    features.setSubgroupBroadcastDynamicId(true);
+                    features.setBufferDeviceAddress(true);
+                });
+        m_features.requireFeature<vk::PhysicalDeviceVulkan11Features>(
+                [](vk::PhysicalDeviceVulkan11Features &features) {
+                    features.setMultiview(true);
+                    features.setMultiviewGeometryShader(true);
+                    features.setMultiviewTessellationShader(true);
+//                    features.setProtectedMemory(true);    // not supported
+                    features.setSamplerYcbcrConversion(true);
+                    features.setShaderDrawParameters(true);
+                    features.setStorageBuffer16BitAccess(true);
+//                    features.setStorageInputOutput16(true);   // not supported
+                    features.setStoragePushConstant16(true);
+                    features.setUniformAndStorageBuffer16BitAccess(true);
+                    features.setVariablePointers(true);
+                    features.setVariablePointersStorageBuffer(true);
+                });
+        m_features.requireFeature<vk::PhysicalDeviceAccelerationStructureFeaturesKHR>(
+                [](vk::PhysicalDeviceAccelerationStructureFeaturesKHR &features) {
+                    features.setAccelerationStructure(true);
+                    features.setAccelerationStructureCaptureReplay(true);
+//                    features.setAccelerationStructureIndirectBuild(true); // not supported
+//                    features.setAccelerationStructureHostCommands(true);  // not supported
+                    features.setDescriptorBindingAccelerationStructureUpdateAfterBind(true);
+                });
+        m_features.requireExtensionFeature<vk::PhysicalDeviceRayTracingPipelineFeaturesKHR>(
+                VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, [](vk::PhysicalDeviceRayTracingPipelineFeaturesKHR &features) {
+                    features.setRayTracingPipeline(true);
+//                    features.setRayTracingPipelineShaderGroupHandleCaptureReplay(true);   // not supported
+//                    features.setRayTracingPipelineShaderGroupHandleCaptureReplayMixed(true);  // not supported
+                    features.setRayTracingPipelineTraceRaysIndirect(true);
+                    features.setRayTraversalPrimitiveCulling(true);
+                });
     }
 
     void RTXModule::init(Core* core, Buffer<uint16_t> &vertexBuffer, Buffer<uint16_t> &indexBuffer) {
@@ -38,4 +129,8 @@ namespace vkcv::rtx {
         return m_deviceExtensions;
     }
 
+    vkcv::Features RTXModule::getFeatures() {
+        return m_features;
+    }
+
 }
\ No newline at end of file
diff --git a/projects/rtx/src/main.cpp b/projects/rtx/src/main.cpp
index b9bb30ac..72783398 100644
--- a/projects/rtx/src/main.cpp
+++ b/projects/rtx/src/main.cpp
@@ -33,24 +33,19 @@ int main(int argc, const char** argv) {
 	// prepare raytracing extensions. IMPORTANT: configure compiler to build in 64 bit mode
     vkcv::rtx::RTXModule rtxModule;
     std::vector<const char*> raytracingInstanceExtensions = rtxModule.getInstanceExtensions();
-    std::vector<const char*> raytracingDeviceExtensions = rtxModule.getDeviceExtensions();
 
     std::vector<const char*> instanceExtensions = {};   // add some more instance extensions, if needed
     instanceExtensions.insert(instanceExtensions.end(), raytracingInstanceExtensions.begin(), raytracingInstanceExtensions.end());  // merge together all instance extensions
 
-    std::vector<const char*> deviceExtensions = {
-        "VK_KHR_swapchain"
-    };
-    deviceExtensions.insert(deviceExtensions.end(), raytracingDeviceExtensions.begin(), raytracingDeviceExtensions.end());  // merge together all device extensions
-
-
+    vkcv::Features features = rtxModule.getFeatures();  // all features required by the RTX device extensions
+    features.requireExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
 	vkcv::Core core = vkcv::Core::create(
 		window,
 		applicationName,
 		VK_MAKE_VERSION(0, 0, 1),
 		{ vk::QueueFlagBits::eGraphics ,vk::QueueFlagBits::eCompute , vk::QueueFlagBits::eTransfer },
-        instanceExtensions,
-		deviceExtensions
+		features,
+        instanceExtensions
 	);
 
 	vkcv::scene::Scene scene = vkcv::scene::Scene::load(core, std::filesystem::path(
@@ -71,32 +66,27 @@ int main(int argc, const char** argv) {
 	}
 
 	assert(!mesh.vertexGroups.empty());
+
 	auto vertexBuffer = core.createBuffer<uint16_t>(
 	        vkcv::BufferType::RT_ACCELERATION_VERTEX,
 	        mesh.vertexGroups[0].vertexBuffer.data.size(),
 	        vkcv::BufferMemoryType::DEVICE_LOCAL
 	        );
-
 	std::vector<uint16_t> vertices = {};
-
-	for (int i=0; i<mesh.vertexGroups[0].vertexBuffer.data.size(); i++) {
+	for (size_t i=0; i<mesh.vertexGroups[0].vertexBuffer.data.size(); i++) {
 	    vertices.emplace_back((uint16_t)mesh.vertexGroups[0].vertexBuffer.data[i]);
 	}
-
 	vertexBuffer.fill(vertices);
 
 	auto indexBuffer = core.createBuffer<uint16_t>(
 	        vkcv::BufferType::RT_ACCELERATION_INDEX,
 	        mesh.vertexGroups[0].indexBuffer.data.size(),
 	        vkcv::BufferMemoryType::DEVICE_LOCAL
-	        );
-
+    );
 	std::vector<uint16_t> indices = {};
-
-	for (int i=0; i<mesh.vertexGroups[0].vertexBuffer.data.size(); i++) {
+	for (size_t i=0; i<mesh.vertexGroups[0].indexBuffer.data.size(); i++) {
 	    indices.emplace_back((uint16_t)mesh.vertexGroups[0].indexBuffer.data[i]);
 	}
-
 	indexBuffer.fill(indices);
 
 
@@ -146,15 +136,15 @@ int main(int argc, const char** argv) {
 	
 	const auto& material0 = scene.getMaterial(0);
 
-	const vkcv::PipelineConfig scenePipelineDefsinition{
+	const vkcv::PipelineConfig scenePipelineDefinition{
 		sceneShaderProgram,
 		UINT32_MAX,
 		UINT32_MAX,
 		scenePass,
 		{sceneLayout},
-		{ core.getDescriptorSet(material0.getDescriptorSet()).layout },
+		{ core.getDescriptorSetLayout(material0.getDescriptorSetLayout()).vulkanHandle },
 		true };
-	vkcv::PipelineHandle scenePipeline = core.createGraphicsPipeline(scenePipelineDefsinition);
+	vkcv::PipelineHandle scenePipeline = core.createGraphicsPipeline(scenePipelineDefinition);
 	
 	if (!scenePipeline) {
 		std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl;
-- 
GitLab