From 076b975a5a044996d92a5ceefbd3f814b7c80f24 Mon Sep 17 00:00:00 2001
From: Tobias Frisch <tfrisch@uni-koblenz.de>
Date: Tue, 29 Nov 2022 15:06:42 +0100
Subject: [PATCH] Improve descriptor set writes

Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de>
---
 include/vkcv/DescriptorWrites.hpp          |  6 +-
 projects/rt_ambient_occlusion/src/main.cpp |  2 +-
 src/vkcv/DescriptorSetManager.cpp          | 91 +++++++++++++++-------
 src/vkcv/DescriptorWrites.cpp              |  2 +-
 4 files changed, 69 insertions(+), 32 deletions(-)

diff --git a/include/vkcv/DescriptorWrites.hpp b/include/vkcv/DescriptorWrites.hpp
index caff4cef..4bc306bc 100644
--- a/include/vkcv/DescriptorWrites.hpp
+++ b/include/vkcv/DescriptorWrites.hpp
@@ -61,7 +61,7 @@ namespace vkcv {
 	 */
 	struct AccelerationDescriptorWrite {
 		uint32_t binding;
-		std::vector<vk::AccelerationStructureKHR> structures;
+		std::vector<AccelerationStructureHandle> structures;
 	};
 
 	/**
@@ -154,12 +154,12 @@ namespace vkcv {
 		 * of a descriptor set.
 		 *
 		 * @param[in] binding Binding index
-		 * @param[in] structures Acceleration structures
+		 * @param[in] structures Acceleration structure handles
 		 * @return Instance of descriptor writes
 		 */
 		DescriptorWrites &
 		writeAcceleration(uint32_t binding,
-						  const std::vector<vk::AccelerationStructureKHR> &structures);
+						  const std::vector<AccelerationStructureHandle> &structures);
 
 		/**
 		 * @brief Returns the list of stored write entries for sampled images.
diff --git a/projects/rt_ambient_occlusion/src/main.cpp b/projects/rt_ambient_occlusion/src/main.cpp
index 7c77334b..c668ce40 100644
--- a/projects/rt_ambient_occlusion/src/main.cpp
+++ b/projects/rt_ambient_occlusion/src/main.cpp
@@ -103,7 +103,7 @@ int main(int argc, const char** argv) {
 	
 	{
 		vkcv::DescriptorWrites writes;
-		writes.writeAcceleration(1, { core.getVulkanAccelerationStructure(scene_tlas) });
+		writes.writeAcceleration(1, { scene_tlas });
 		writes.writeStorageBuffer(2, geometryData.getVertexBufferBinding().m_buffer);
 		writes.writeStorageBuffer(3, geometryData.getIndexBuffer());
 		core.writeDescriptorSet(descriptorSetHandles[0], writes);
diff --git a/src/vkcv/DescriptorSetManager.cpp b/src/vkcv/DescriptorSetManager.cpp
index b33221b1..76f36e47 100644
--- a/src/vkcv/DescriptorSetManager.cpp
+++ b/src/vkcv/DescriptorSetManager.cpp
@@ -147,10 +147,28 @@ namespace vkcv {
 
 		std::vector<vk::DescriptorImageInfo> imageInfos;
 		std::vector<vk::DescriptorBufferInfo> bufferInfos;
+		
+		bufferInfos.reserve(
+				writes.getUniformBufferWrites().size() +
+				writes.getStorageBufferWrites().size()
+		);
+		
+		std::vector<vk::AccelerationStructureKHR> accelerationStructures;
+		std::vector<size_t> accelerationStructureOffsets;
+		
+		accelerationStructureOffsets.reserve(writes.getAccelerationWrites().size());
 
 		std::vector<vk::WriteDescriptorSetAccelerationStructureKHR> writeStructures;
 
 		std::vector<WriteDescriptorSetInfo> writeInfos;
+		writeInfos.reserve(
+				writes.getSampledImageWrites().size() +
+				writes.getStorageImageWrites().size() +
+				writes.getUniformBufferWrites().size() +
+				writes.getStorageBufferWrites().size() +
+				writes.getSamplerWrites().size() +
+				writes.getAccelerationWrites().size()
+		);
 
 		for (const auto &write : writes.getSampledImageWrites()) {
 			const vk::ImageLayout layout =
@@ -209,15 +227,17 @@ namespace vkcv {
 
 			bufferInfos.push_back(bufferInfo);
 
-			WriteDescriptorSetInfo vulkanWrite = { 0,
-												   bufferInfos.size(),
-												   0,
-												   write.binding,
-												   0,
-												   1,
-												   write.dynamic ?
-													   vk::DescriptorType::eUniformBufferDynamic :
-													   vk::DescriptorType::eUniformBuffer };
+			WriteDescriptorSetInfo vulkanWrite = {
+					0,
+					bufferInfos.size(),
+					0,
+					write.binding,
+					0,
+					1,
+					write.dynamic ?
+						vk::DescriptorType::eUniformBufferDynamic :
+						vk::DescriptorType::eUniformBuffer
+			};
 
 			writeInfos.push_back(vulkanWrite);
 		}
@@ -232,15 +252,17 @@ namespace vkcv {
 
 			bufferInfos.push_back(bufferInfo);
 
-			WriteDescriptorSetInfo vulkanWrite = { 0,
-												   bufferInfos.size(),
-												   0,
-												   write.binding,
-												   0,
-												   1,
-												   write.dynamic ?
-													   vk::DescriptorType::eStorageBufferDynamic :
-													   vk::DescriptorType::eStorageBuffer };
+			WriteDescriptorSetInfo vulkanWrite = {
+					0,
+					bufferInfos.size(),
+					0,
+					write.binding,
+					0,
+					1,
+					write.dynamic ?
+						vk::DescriptorType::eStorageBufferDynamic :
+						vk::DescriptorType::eStorageBuffer
+			};
 
 			writeInfos.push_back(vulkanWrite);
 		}
@@ -258,25 +280,40 @@ namespace vkcv {
 
 			writeInfos.push_back(vulkanWrite);
 		}
-
+		
 		for (const auto &write : writes.getAccelerationWrites()) {
+			accelerationStructureOffsets.push_back(accelerationStructures.size());
+			
+			for (const auto &handle : write.structures) {
+				accelerationStructures.push_back(getCore().getVulkanAccelerationStructure(handle));
+			}
+		}
+
+		for (size_t i = 0; i < writes.getAccelerationWrites().size(); i++) {
+			const auto &write = writes.getAccelerationWrites()[i];
+			
 			const vk::WriteDescriptorSetAccelerationStructureKHR structureWrite(
-				write.structures.size(), write.structures.data());
+					write.structures.size(),
+					&(accelerationStructures[ accelerationStructureOffsets[i] ])
+			);
 
 			writeStructures.push_back(structureWrite);
 
-			WriteDescriptorSetInfo vulkanWrite = { 0,
-												   0,
-												   writeStructures.size(),
-												   write.binding,
-												   0,
-												   1,
-												   vk::DescriptorType::eAccelerationStructureKHR };
+			WriteDescriptorSetInfo vulkanWrite = {
+					0,
+					0,
+					writeStructures.size(),
+					write.binding,
+					0,
+					1,
+					vk::DescriptorType::eAccelerationStructureKHR
+			};
 
 			writeInfos.push_back(vulkanWrite);
 		}
 
 		std::vector<vk::WriteDescriptorSet> vulkanWrites;
+		vulkanWrites.reserve(writeInfos.size());
 
 		for (const auto &write : writeInfos) {
 			vk::WriteDescriptorSet vulkanWrite(
diff --git a/src/vkcv/DescriptorWrites.cpp b/src/vkcv/DescriptorWrites.cpp
index a3b4c5f4..b4be5958 100644
--- a/src/vkcv/DescriptorWrites.cpp
+++ b/src/vkcv/DescriptorWrites.cpp
@@ -77,7 +77,7 @@ namespace vkcv {
 	}
 
 	DescriptorWrites &DescriptorWrites::writeAcceleration(
-		uint32_t binding, const std::vector<vk::AccelerationStructureKHR> &structures) {
+		uint32_t binding, const std::vector<AccelerationStructureHandle> &structures) {
 		AccelerationDescriptorWrite write;
 		write.binding = binding;
 		write.structures = structures;
-- 
GitLab