diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index 0278466a48fb6a9b2af3d2b0342188d103b9d264..73939037466796c79e41e66ef62c14944855871c 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -50,8 +50,7 @@ namespace vkcv
 	 * The class handles the core functionality of the framework with most
 	 * calls addressing resource management via more simplified abstraction.
 	 */
-    class Core final
-    {
+    class Core final {
     private:
 
         /**
@@ -817,64 +816,64 @@ namespace vkcv
 		/**
 		 * @brief Sets a debug label to a buffer handle.
 		 *
-		 * @param handle Buffer handle
-		 * @param label Debug label
+		 * @param[in,out] handle Buffer handle
+		 * @param[in] label Debug label
 		 */
 		void setDebugLabel(const BufferHandle &handle, const std::string &label);
 		
 		/**
 		 * @brief Sets a debug label to a pass handle.
 		 *
-		 * @param handle Pass handle
-		 * @param label Debug label
+		 * @param[in,out] handle Pass handle
+		 * @param[in] label Debug label
 		 */
 		void setDebugLabel(const PassHandle &handle, const std::string &label);
 		
 		/**
 		 * @brief Sets a debug label to a graphics pipeline handle.
 		 *
-		 * @param handle Graphics pipeline handle
-		 * @param label Debug label
+		 * @param[in,out] handle Graphics pipeline handle
+		 * @param[in] label Debug label
 		 */
 		void setDebugLabel(const GraphicsPipelineHandle &handle, const std::string &label);
 		
 		/**
 		 * @brief Sets a debug label to a compute pipeline handle.
 		 *
-		 * @param handle Compute pipeline handle
-		 * @param label Debug label
+		 * @param[in,out] handle Compute pipeline handle
+		 * @param[in] label Debug label
 		 */
 		void setDebugLabel(const ComputePipelineHandle &handle, const std::string &label);
 		
 		/**
 		 * @brief Sets a debug label to a descriptor set handle.
 		 *
-		 * @param handle Descriptor set handle
-		 * @param label Debug label
+		 * @param[in,out] handle Descriptor set handle
+		 * @param[in] label Debug label
 		 */
 		void setDebugLabel(const DescriptorSetHandle &handle, const std::string &label);
 		
 		/**
 		 * @brief Sets a debug label to a sampler handle.
 		 *
-		 * @param handle Sampler handle
-		 * @param label Debug label
+		 * @param[in,out] handle Sampler handle
+		 * @param[in] label Debug label
 		 */
 		void setDebugLabel(const SamplerHandle &handle, const std::string &label);
 		
 		/**
 		 * @brief Sets a debug label to an image handle.
 		 *
-		 * @param handle Image handle
-		 * @param label Debug label
+		 * @param[in,out] handle Image handle
+		 * @param[in] label Debug label
 		 */
 		void setDebugLabel(const ImageHandle &handle, const std::string &label);
 		
 		/**
 		 * @brief Sets a debug label to a command stream handle.
 		 *
-		 * @param handle Command stream handle
-		 * @param label Debug label
+		 * @param[in,out] handle Command stream handle
+		 * @param[in] label Debug label
 		 */
 		void setDebugLabel(const CommandStreamHandle &handle, const std::string &label);
 		
@@ -887,5 +886,115 @@ namespace vkcv
 		 */
 		void run(const WindowFrameFunction &frame);
 		
+		/**
+		 * @brief Return the underlying vulkan handle for a render pass
+		 * by its given pass handle.
+		 *
+		 * @param[in] handle Pass handle
+		 * @return Vulkan render pass
+		 */
+		[[nodiscard]]
+		vk::RenderPass getVulkanRenderPass(const PassHandle &handle) const;
+		
+		/**
+		 * @brief Return the underlying vulkan handle for a pipeline
+		 * by its given graphics pipeline handle.
+		 *
+		 * @param[in] handle Graphics pipeline handle
+		 * @return Vulkan pipeline
+		 */
+		[[nodiscard]]
+		vk::Pipeline getVulkanPipeline(const GraphicsPipelineHandle &handle) const;
+	
+		/**
+		 * @brief Return the underlying vulkan handle for a pipeline
+		 * by its given compute pipeline handle.
+		 *
+		 * @param[in] handle Compute pipeline handle
+		 * @return Vulkan pipeline
+		 */
+		[[nodiscard]]
+		vk::Pipeline getVulkanPipeline(const ComputePipelineHandle &handle) const;
+	
+		/**
+		 * @brief Return the underlying vulkan handle for a descriptor set layout
+		 * by its given descriptor set layout handle.
+		 *
+		 * @param[in] handle Descriptor set layout handle
+		 * @return Vulkan descriptor set layout
+		 */
+		[[nodiscard]]
+		vk::DescriptorSetLayout getVulkanDescriptorSetLayout(const DescriptorSetLayoutHandle &handle) const;
+	
+		/**
+		 * @brief Return the underlying vulkan handle for a descriptor set
+		 * by its given descriptor set handle.
+		 *
+		 * @param[in] handle Descriptor set handle
+		 * @return Vulkan descriptor set
+		 */
+		[[nodiscard]]
+		vk::DescriptorSet getVulkanDescriptorSet(const DescriptorSetHandle &handle) const;
+	
+		/**
+		 * @brief Return the underlying vulkan handle for a buffer
+		 * by its given buffer handle.
+		 *
+		 * @param[in] handle Buffer handle
+		 * @return Vulkan buffer
+		 */
+		[[nodiscard]]
+		vk::Buffer getVulkanBuffer(const BufferHandle &handle) const;
+	
+		/**
+		 * @brief Return the underlying vulkan handle for a sampler
+		 * by its given sampler handle.
+		 *
+		 * @param[in] handle Sampler handle
+		 * @return Vulkan sampler
+		 */
+		[[nodiscard]]
+		vk::Sampler getVulkanSampler(const SamplerHandle &handle) const;
+	
+		/**
+		 * @brief Return the underlying vulkan handle for a image
+		 * by its given image handle.
+		 *
+		 * @param[in] handle Image handle
+		 * @return Vulkan image
+		 */
+		[[nodiscard]]
+		vk::Image getVulkanImage(const ImageHandle &handle) const;
+	
+		/**
+		 * @brief Return the underlying vulkan handle for a image view
+		 * by its given image handle.
+		 *
+		 * @param[in] handle Image handle
+		 * @return Vulkan image view
+		 */
+		[[nodiscard]]
+		vk::ImageView getVulkanImageView(const ImageHandle &handle) const;
+	
+		/**
+		 * @brief Return the underlying vulkan handle for a device memory
+		 * by its given buffer handle.
+		 *
+		 * @param[in] handle Buffer handle
+		 * @return Vulkan device memory
+		 */
+		[[nodiscard]]
+		vk::DeviceMemory getVulkanDeviceMemory(const BufferHandle &handle) const;
+	
+		/**
+		 * @brief Return the underlying vulkan handle for a device memory
+		 * by its given image handle.
+		 *
+		 * @param[in] handle Image handle
+		 * @return Vulkan device memory
+		 */
+		[[nodiscard]]
+		vk::DeviceMemory getVulkanDeviceMemory(const ImageHandle &handle) const;
+		
     };
 }
diff --git a/include/vkcv/DescriptorWrites.hpp b/include/vkcv/DescriptorWrites.hpp
index eb532119fabe394202a410b9a166b0d190dabbf3..869b1061af8f8da217978f962fd68d41ba289cad 100644
--- a/include/vkcv/DescriptorWrites.hpp
+++ b/include/vkcv/DescriptorWrites.hpp
@@ -6,6 +6,7 @@
  */
 
 #include <vector>
+#include <vulkan/vulkan.hpp>
 
 #include "Handles.hpp"
 
@@ -60,6 +61,7 @@ namespace vkcv {
 	 */
 	struct AccelerationDescriptorWrite {
 	    uint32_t binding;
+		std::vector<vk::AccelerationStructureKHR> structures;
 	};
 
 	/**
@@ -162,9 +164,11 @@ namespace vkcv {
 		 * of a descriptor set.
 		 *
 		 * @param[in] binding Binding index
+		 * @param[in] structures Acceleration structures
 		 * @return Instance of descriptor writes
 		 */
-		DescriptorWrites& writeAcceleration(uint32_t binding);
+		DescriptorWrites& writeAcceleration(uint32_t binding,
+											const std::vector<vk::AccelerationStructureKHR> &structures);
 		
 		/**
 		 * @brief Returns the list of stored write entries for sampled images.
diff --git a/projects/rtx_ambient_occlusion/src/RTX/RTX.cpp b/projects/rtx_ambient_occlusion/src/RTX/RTX.cpp
index 406f145161661880f6a2d726090f1fb6889ed7e1..bd5453abae353eed6739c41dbff084a0c909aaca 100644
--- a/projects/rtx_ambient_occlusion/src/RTX/RTX.cpp
+++ b/projects/rtx_ambient_occlusion/src/RTX/RTX.cpp
@@ -104,7 +104,7 @@ namespace vkcv::rtx {
 
         vk::WriteDescriptorSet tlasWrite;
         tlasWrite.setPNext(&AccelerationDescriptor);
-        tlasWrite.setDstSet(m_core->getDescriptorSet(descriptorSetHandles[0]).vulkanHandle);
+        tlasWrite.setDstSet(m_core->getVulkanDescriptorSet(descriptorSetHandles[0]));
         tlasWrite.setDstBinding(1);
         tlasWrite.setDstArrayElement(0);
         tlasWrite.setDescriptorCount(1);
@@ -123,7 +123,7 @@ namespace vkcv::rtx {
         vertexInfo.setRange(blas.vertexBuffer.deviceSize); //maybe check if size is correct
 
         vk::WriteDescriptorSet vertexWrite;
-        vertexWrite.setDstSet(m_core->getDescriptorSet().vulkanHandle);
+        vertexWrite.setDstSet(m_core->getVulkanDescriptorSet(descriptorSetHandles[0]));
         vertexWrite.setDstBinding(3);
         vertexWrite.setDescriptorCount(1);
         vertexWrite.setDescriptorType(vk::DescriptorType::eStorageBuffer);
@@ -137,7 +137,7 @@ namespace vkcv::rtx {
         indexInfo.setRange(blas.indexBuffer.deviceSize); //maybe check if size is correct
 
         vk::WriteDescriptorSet indexWrite;
-        indexWrite.setDstSet(m_core->getDescriptorSet(descriptorSetHandles[0]).vulkanHandle);
+        indexWrite.setDstSet(m_core->getVulkanDescriptorSet(descriptorSetHandles[0]));
         indexWrite.setDstBinding(4);
         indexWrite.setDescriptorCount(1);
         indexWrite.setDescriptorType(vk::DescriptorType::eStorageBuffer);
@@ -245,7 +245,7 @@ namespace vkcv::rtx {
 
         std::vector<vk::DescriptorSetLayout> descriptorSetLayoutsVulkan;
         for (size_t i=0; i<descriptorSetLayouts.size(); i++) {
-            descriptorSetLayoutsVulkan.push_back(m_core->getDescriptorSetLayout(descriptorSetLayouts[i]).vulkanHandle);
+            descriptorSetLayoutsVulkan.push_back(m_core->getVulkanDescriptorSetLayout(descriptorSetLayouts[i]));
         }
 
         vk::PushConstantRange pushConstant(
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index 7d4d9b596c405671ef5f46feba2bf6c9ae0416c5..ad0b7d4947c624be0d38e3f6aee79eb1b291537b 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -1089,7 +1089,8 @@ namespace vkcv
 			writes, 
 			*m_ImageManager, 
 			*m_BufferManager, 
-			*m_SamplerManager);
+			*m_SamplerManager
+		);
 	}
 
 	void Core::prepareSwapchainImageForPresent(const CommandStreamHandle& cmdStream) {
@@ -1443,4 +1444,48 @@ namespace vkcv
 		}
 	}
 	
+	vk::RenderPass Core::getVulkanRenderPass(const PassHandle &handle) const {
+		return m_PassManager->getVkPass(handle);
+	}
+	
+	vk::Pipeline Core::getVulkanPipeline(const GraphicsPipelineHandle &handle) const {
+		return m_GraphicsPipelineManager->getVkPipeline(handle);
+	}
+	
+	vk::Pipeline Core::getVulkanPipeline(const ComputePipelineHandle &handle) const {
+		return m_ComputePipelineManager->getVkPipeline(handle);
+	}
+	
+	vk::DescriptorSetLayout Core::getVulkanDescriptorSetLayout(const DescriptorSetLayoutHandle &handle) const {
+		return m_DescriptorSetLayoutManager->getDescriptorSetLayout(handle).vulkanHandle;
+	}
+	
+	vk::DescriptorSet Core::getVulkanDescriptorSet(const DescriptorSetHandle &handle) const {
+		return m_DescriptorSetManager->getDescriptorSet(handle).vulkanHandle;
+	}
+	
+	vk::Buffer Core::getVulkanBuffer(const BufferHandle &handle) const {
+		return m_BufferManager->getBuffer(handle);
+	}
+	
+	vk::Sampler Core::getVulkanSampler(const SamplerHandle &handle) const {
+		return m_SamplerManager->getVulkanSampler(handle);
+	}
+	
+	vk::Image Core::getVulkanImage(const ImageHandle &handle) const {
+		return m_ImageManager->getVulkanImage(handle);
+	}
+	
+	vk::ImageView Core::getVulkanImageView(const vkcv::ImageHandle &handle) const {
+		return m_ImageManager->getVulkanImageView(handle);
+	}
+	
+	vk::DeviceMemory Core::getVulkanDeviceMemory(const BufferHandle &handle) const {
+		return m_BufferManager->getDeviceMemory(handle);
+	}
+	
+	vk::DeviceMemory Core::getVulkanDeviceMemory(const ImageHandle &handle) const {
+		return m_ImageManager->getVulkanDeviceMemory(handle);
+	}
+	
 }
diff --git a/src/vkcv/DescriptorSetManager.cpp b/src/vkcv/DescriptorSetManager.cpp
index 31432bf2bd26920a3811255376f02e415e176b84..d7d680d9a3d72d694bd1cafa83c7c4f92bf2825f 100644
--- a/src/vkcv/DescriptorSetManager.cpp
+++ b/src/vkcv/DescriptorSetManager.cpp
@@ -132,6 +132,7 @@ namespace vkcv {
 	struct WriteDescriptorSetInfo {
 		size_t imageInfoIndex;
 		size_t bufferInfoIndex;
+		size_t structureIndex;
 		uint32_t binding;
 		uint32_t arrayElementIndex;
 		uint32_t descriptorCount;
@@ -148,6 +149,8 @@ namespace vkcv {
 		std::vector<vk::DescriptorImageInfo> imageInfos;
 		std::vector<vk::DescriptorBufferInfo> bufferInfos;
 		
+		std::vector<vk::WriteDescriptorSetAccelerationStructureKHR> writeStructures;
+		
 		std::vector<WriteDescriptorSetInfo> writeInfos;
 		
 		for (const auto& write : writes.getSampledImageWrites()) {
@@ -173,6 +176,7 @@ namespace vkcv {
 			WriteDescriptorSetInfo vulkanWrite = {
 					imageInfos.size() + 1 - write.mipCount,
 					0,
+					0,
 					write.binding,
 					write.arrayIndex,
 					write.mipCount,
@@ -200,6 +204,7 @@ namespace vkcv {
 			WriteDescriptorSetInfo vulkanWrite = {
 					imageInfos.size() + 1 - write.mipCount,
 					0,
+					0,
 					write.binding,
 					0,
 					write.mipCount,
@@ -226,6 +231,7 @@ namespace vkcv {
 			WriteDescriptorSetInfo vulkanWrite = {
 					0,
 					bufferInfos.size(),
+					0,
 					write.binding,
 					0,
 					1,
@@ -254,6 +260,7 @@ namespace vkcv {
 			WriteDescriptorSetInfo vulkanWrite = {
 					0,
 					bufferInfos.size(),
+					0,
 					write.binding,
 					0,
 					1,
@@ -279,6 +286,7 @@ namespace vkcv {
 			WriteDescriptorSetInfo vulkanWrite = {
 					imageInfos.size(),
 					0,
+					0,
 					write.binding,
 					0,
 					1,
@@ -288,6 +296,27 @@ namespace vkcv {
 			writeInfos.push_back(vulkanWrite);
 		}
 		
+		for (const auto& write : writes.getAccelerationWrites()) {
+			const vk::WriteDescriptorSetAccelerationStructureKHR structureWrite (
+					write.structures.size(),
+					write.structures.data()
+			);
+			
+			writeStructures.push_back(structureWrite);
+			
+			WriteDescriptorSetInfo vulkanWrite = {
+					0,
+					0,
+					writeStructures.size(),
+					write.binding,
+					0,
+					1,
+					vk::DescriptorType::eAccelerationStructureKHR
+			};
+			
+			writeInfos.push_back(vulkanWrite);
+		}
+		
 		std::vector<vk::WriteDescriptorSet> vulkanWrites;
 		
 		for (const auto& write : writeInfos) {
@@ -301,6 +330,10 @@ namespace vkcv {
 					(write.bufferInfoIndex > 0? &(bufferInfos[write.bufferInfoIndex - 1]) : nullptr)
 			);
 			
+			if (write.structureIndex > 0) {
+				vulkanWrite.setPNext(&(writeStructures[write.structureIndex - 1]));
+			}
+			
 			vulkanWrites.push_back(vulkanWrite);
 		}
 		
diff --git a/src/vkcv/DescriptorWrites.cpp b/src/vkcv/DescriptorWrites.cpp
index c64eeb5c4037018e949436d984c112d10e44a434..4f9c50ea1ac4628659b18decab6573b73fbdcb38 100644
--- a/src/vkcv/DescriptorWrites.cpp
+++ b/src/vkcv/DescriptorWrites.cpp
@@ -63,8 +63,9 @@ namespace vkcv {
 		return *this;
 	}
 	
-	DescriptorWrites &DescriptorWrites::writeAcceleration(uint32_t binding) {
-		m_accelerationWrites.emplace_back(binding);
+	DescriptorWrites &DescriptorWrites::writeAcceleration(uint32_t binding,
+														  const std::vector<vk::AccelerationStructureKHR> &structures) {
+		m_accelerationWrites.emplace_back(binding, structures);
 		return *this;
 	}