diff --git a/modules/denoising/include/vkcv/denoising/ReflectionDenoiser.hpp b/modules/denoising/include/vkcv/denoising/ReflectionDenoiser.hpp
index 51dc369ac9bb4e90d07a1c2a1d5dd76eca213ebe..3a3419789642f021e4d2643c438e632c7e51d250 100644
--- a/modules/denoising/include/vkcv/denoising/ReflectionDenoiser.hpp
+++ b/modules/denoising/include/vkcv/denoising/ReflectionDenoiser.hpp
@@ -9,10 +9,20 @@ namespace vkcv::denoising {
 		ComputePipelineHandle m_prefilterPipeline;
 		ComputePipelineHandle m_reprojectPipeline;
 		ComputePipelineHandle m_resolveTemporalPipeline;
+
+		/**
+		 * The common descriptor set layout.
+		 */
+		DescriptorSetLayoutHandle m_commonDescriptorSetLayout;
+
+		/**
+		 * The common descriptor set.
+		 */
+		DescriptorSetHandle m_commonDescriptorSet;
 		
 		/**
-         * The descriptor set layout of the filter pipeline.
-         */
+		 * The descriptor set layout of the filter pipeline.
+		 */
 		DescriptorSetLayoutHandle m_prefilterDescriptorSetLayout;
 		
 		/**
@@ -21,8 +31,8 @@ namespace vkcv::denoising {
 		DescriptorSetHandle m_prefilterDescriptorSet;
 		
 		/**
-         * The descriptor set layout of the reproject pipeline.
-         */
+		 * The descriptor set layout of the reproject pipeline.
+		 */
 		DescriptorSetLayoutHandle m_reprojectDescriptorSetLayout;
 		
 		/**
@@ -31,8 +41,8 @@ namespace vkcv::denoising {
 		DescriptorSetHandle m_reprojectDescriptorSet;
 		
 		/**
-         * The descriptor set layout of the resolve temporal pipeline.
-         */
+		 * The descriptor set layout of the resolve temporal pipeline.
+		 */
 		DescriptorSetLayoutHandle m_resolveTemporalDescriptorSetLayout;
 		
 		/**
@@ -42,21 +52,21 @@ namespace vkcv::denoising {
 		
 	public:
 		/**
-         * Constructor to create a reflection denoiser instance.
-         *
-         * @param[in,out] core Reference to a Core instance
-         */
+		 * Constructor to create a reflection denoiser instance.
+		 *
+		 * @param[in,out] core Reference to a Core instance
+		 */
 		explicit ReflectionDenoiser(Core& core);
 		
 		/**
-         * Record the commands of the given reflection denoiser instance
-         * to reduce the noise from the image of the input handle and
-         * pass the important details to the output image handle.
-         *
-         * @param[in] cmdStream Command stream handle to record commands
-         * @param[in] input Input image handle
-         * @param[in] output Output image handle
-         */
+		 * Record the commands of the given reflection denoiser instance
+		 * to reduce the noise from the image of the input handle and
+		 * pass the important details to the output image handle.
+		 *
+		 * @param[in] cmdStream Command stream handle to record commands
+		 * @param[in] input Input image handle
+		 * @param[in] output Output image handle
+		 */
 		void recordDenoising(const CommandStreamHandle& cmdStream,
 							 const ImageHandle& input,
 							 const ImageHandle& output) override;
diff --git a/modules/denoising/src/vkcv/denoising/ReflectionDenoiser.cpp b/modules/denoising/src/vkcv/denoising/ReflectionDenoiser.cpp
index 220a128004d68fc3b2c497fc11f8ac5d4bcd7d4f..606815422e85db6be422b2a663352589a46a5793 100644
--- a/modules/denoising/src/vkcv/denoising/ReflectionDenoiser.cpp
+++ b/modules/denoising/src/vkcv/denoising/ReflectionDenoiser.cpp
@@ -2,7 +2,7 @@
 #include "vkcv/denoising/ReflectionDenoiser.hpp"
 
 #include <vkcv/File.hpp>
-#include <vkcv/shader/HLSLCompiler.hpp>
+#include <vkcv/shader/SlangCompiler.hpp>
 
 #include "ffx_denoiser_reflections_common.h.hxx"
 #include "ffx_denoiser_reflections_config.h.hxx"
@@ -17,29 +17,117 @@
 
 namespace vkcv::denoising {
 	
-	static DescriptorBindings getDescriptorBindings() {
+	static DescriptorBindings getDescriptorBindings(uint32_t step) {
 		DescriptorBindings descriptorBindings = {};
+		uint32_t inputs, outputs;
+
+		switch (step) {
+			case 0:
+				{
+					auto binding = DescriptorBinding {
+						0,
+						DescriptorType::UNIFORM_BUFFER,
+						1,
+						ShaderStage::COMPUTE,
+						false,
+						false
+					};
+
+					descriptorBindings.insert(std::make_pair(0, binding));
+				}
+
+				return descriptorBindings;
+			case 1:
+				inputs = 7;
+				outputs = 3;
+				break;
+			case 2:
+				inputs = 13;
+				outputs = 4;
+				break;
+			case 3:
+				inputs = 6;
+				outputs = 3;
+				break;
+			default:
+				return descriptorBindings;
+		}
+
+		for (uint32_t i = 0; i < inputs; i++) {
+			auto input_binding = DescriptorBinding {
+				i,
+				DescriptorType::IMAGE_SAMPLED,
+				1,
+				ShaderStage::COMPUTE,
+				false,
+				false
+			};
+
+			descriptorBindings.insert(std::make_pair(i, input_binding));
+		}
+
+		{
+			auto sampler_binding = DescriptorBinding {
+				inputs + 0,
+				DescriptorType::SAMPLER,
+				1,
+				ShaderStage::COMPUTE,
+				false,
+				false
+			};
+
+			descriptorBindings.insert(std::make_pair(inputs + 0, sampler_binding));
+		}
+
+		for (uint32_t i = 0; i < outputs; i++) {
+			auto output_binding = DescriptorBinding {
+				inputs + 1 + i,
+				DescriptorType::IMAGE_STORAGE,
+				1,
+				ShaderStage::COMPUTE,
+				false,
+				false
+			};
+
+			descriptorBindings.insert(std::make_pair(inputs + 1 + i, output_binding));
+		}
+
+		{
+			auto buffer_binding = DescriptorBinding {
+				inputs + 1 + outputs,
+				DescriptorType::STORAGE_BUFFER,
+				1,
+				ShaderStage::COMPUTE,
+				false,
+				false
+			};
+
+			descriptorBindings.insert(std::make_pair(inputs + 1 + outputs, buffer_binding));
+		}
 		
 		return descriptorBindings;
 	}
 	
 	ReflectionDenoiser::ReflectionDenoiser(Core &core) :
 	Denoiser(core),
-	
+
 	m_prefilterPipeline(),
 	m_reprojectPipeline(),
 	m_resolveTemporalPipeline(),
-	
-	m_prefilterDescriptorSetLayout(m_core.createDescriptorSetLayout(getDescriptorBindings())),
+
+	m_commonDescriptorSetLayout(m_core.createDescriptorSetLayout(getDescriptorBindings(0))),
+	m_commonDescriptorSet(m_core.createDescriptorSet(m_commonDescriptorSetLayout)),
+
+	m_prefilterDescriptorSetLayout(m_core.createDescriptorSetLayout(getDescriptorBindings(1))),
 	m_prefilterDescriptorSet(m_core.createDescriptorSet(m_prefilterDescriptorSetLayout)),
-	
-	m_reprojectDescriptorSetLayout(m_core.createDescriptorSetLayout(getDescriptorBindings())),
+
+	m_reprojectDescriptorSetLayout(m_core.createDescriptorSetLayout(getDescriptorBindings(2))),
 	m_reprojectDescriptorSet(m_core.createDescriptorSet(m_reprojectDescriptorSetLayout)),
-	
-	m_resolveTemporalDescriptorSetLayout(m_core.createDescriptorSetLayout(getDescriptorBindings())),
+
+	m_resolveTemporalDescriptorSetLayout(m_core.createDescriptorSetLayout(getDescriptorBindings(3))),
 	m_resolveTemporalDescriptorSet(m_core.createDescriptorSet(m_resolveTemporalDescriptorSetLayout))
 	{
-		vkcv::shader::HLSLCompiler compiler;
+		vkcv::shader::SlangCompiler compiler (vkcv::shader::SlangCompileProfile::HLSL);
 		
 		{
 			ShaderProgram program;
@@ -59,7 +147,8 @@ namespace vkcv::denoising {
 			);
 			
 			m_prefilterPipeline = m_core.createComputePipeline({ program, {
-					m_prefilterDescriptorSetLayout
+				m_commonDescriptorSetLayout,
+				m_prefilterDescriptorSetLayout
 			}});
 			
 			DescriptorWrites writes;
@@ -84,7 +173,8 @@ namespace vkcv::denoising {
 			);
 			
 			m_reprojectPipeline = m_core.createComputePipeline({ program, {
-					m_reprojectDescriptorSetLayout
+				m_commonDescriptorSetLayout,
+				m_reprojectDescriptorSetLayout
 			}});
 			
 			DescriptorWrites writes;
@@ -109,7 +199,8 @@ namespace vkcv::denoising {
 			);
 			
 			m_resolveTemporalPipeline = m_core.createComputePipeline({ program, {
-					m_resolveTemporalDescriptorSetLayout
+				m_commonDescriptorSetLayout,
+				m_resolveTemporalDescriptorSetLayout
 			}});
 			
 			DescriptorWrites writes;
diff --git a/src/vkcv/BufferManager.cpp b/src/vkcv/BufferManager.cpp
index f1676870ab8cd711f29af22425c710446d1bdac1..b9b7289b119e3ad518042684d101fb2d0a41f573 100644
--- a/src/vkcv/BufferManager.cpp
+++ b/src/vkcv/BufferManager.cpp
@@ -5,6 +5,7 @@
 
 #include "BufferManager.hpp"
 #include "vkcv/Core.hpp"
+#include <vkcv/Handles.hpp>
 #include <vkcv/Logger.hpp>
 
 #include <limits>
@@ -118,8 +119,8 @@ namespace vkcv {
 	}
 
 	BufferHandle BufferManager::createBuffer(const TypeGuard &typeGuard, BufferType type,
-											 BufferMemoryType memoryType, size_t size,
-											 bool readable, size_t alignment) {
+																					 BufferMemoryType memoryType, size_t size,
+																					 bool readable, size_t alignment) {
 		vk::BufferCreateFlags createFlags;
 		vk::BufferUsageFlags usageFlags;
 
@@ -181,6 +182,10 @@ namespace vkcv {
 
 		const vma::Allocator &allocator = getCore().getContext().getAllocator();
 
+		if (0 == size) {
+			vkcv_log(LogLevel::WARNING, "Invalid buffer size");
+		}
+
 		vma::MemoryUsage memoryUsage;
 		bool mappable;