diff --git a/include/vkcv/ComputePipelineConfig.hpp b/include/vkcv/ComputePipelineConfig.hpp
index a99d75e6a0e4ec332588e7ff48a7d1ca112eccb4..7695f05349e75dadd166340187ca2770f3dc62cc 100644
--- a/include/vkcv/ComputePipelineConfig.hpp
+++ b/include/vkcv/ComputePipelineConfig.hpp
@@ -1,17 +1,19 @@
 #pragma once
 /**
- * @authors Mark Mints
+ * @authors Mark Mints, Tobias Frisch
  * @file src/vkcv/ComputePipelineConfig.hpp
  * @brief Compute Pipeline Config Struct to hand over required information to Pipeline Creation.
  */
 
 #include <vector>
+
+#include "Handles.hpp"
 #include "ShaderProgram.hpp"
 
 namespace vkcv
 {
     struct ComputePipelineConfig {
         ShaderProgram&                          m_ShaderProgram;
-        std::vector<vk::DescriptorSetLayout>  	m_DescriptorSetLayouts;
+        std::vector<DescriptorSetLayoutHandle>	m_DescriptorSetLayouts;
     };
 }
\ No newline at end of file
diff --git a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp
index f7cf0b4a1e68e46a784723d13366deac899f9963..2045db9ea216d6810ec439114e93e06949c45cc0 100644
--- a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp
+++ b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp
@@ -232,9 +232,9 @@ namespace vkcv::upscaling {
 				program.addShader(shaderStage, path);
 			});
 
-			m_easuPipeline = m_core.createComputePipeline({ program, 
-				{m_core.getDescriptorSetLayout(m_easuDescriptorSetLayout).vulkanHandle} 
-			});
+			m_easuPipeline = m_core.createComputePipeline({program,{
+				m_easuDescriptorSetLayout
+			}});
 
 			
 			DescriptorWrites writes;
@@ -255,7 +255,7 @@ namespace vkcv::upscaling {
 			});
 
 			m_rcasPipeline = m_core.createComputePipeline({ program, {
-				m_core.getDescriptorSetLayout(m_rcasDescriptorSetLayout).vulkanHandle
+				m_rcasDescriptorSetLayout
 			}});
 
 			DescriptorWrites writes;
diff --git a/projects/indirect_dispatch/src/AppSetup.cpp b/projects/indirect_dispatch/src/AppSetup.cpp
index e1b29ad5990d371535794fa72a1d80e2b653045b..d186a5ecbd8d13e70542ec6c9f0f14b40b2d2b5c 100644
--- a/projects/indirect_dispatch/src/AppSetup.cpp
+++ b/projects/indirect_dispatch/src/AppSetup.cpp
@@ -260,7 +260,7 @@ bool loadComputePass(vkcv::Core& core, const std::filesystem::path& path, Comput
 	outComputePass->descriptorSet = core.createDescriptorSet(outComputePass->descriptorSetLayout);
 	outComputePass->pipeline = core.createComputePipeline({
 		shaderProgram,
-		{ core.getDescriptorSetLayout(outComputePass->descriptorSetLayout).vulkanHandle }});
+		{ outComputePass->descriptorSetLayout }});
 
 	if (!outComputePass->pipeline) {
 		vkcv_log(vkcv::LogLevel::ERROR, "Compute shader pipeline creation failed");
diff --git a/projects/indirect_draw/src/main.cpp b/projects/indirect_draw/src/main.cpp
index 88e7005f2912bb448980bd4c1219245481f1559a..d494512056a55179752b94c2b20119b44659f857 100644
--- a/projects/indirect_draw/src/main.cpp
+++ b/projects/indirect_draw/src/main.cpp
@@ -512,7 +512,7 @@ int main(int argc, const char** argv) {
 
     const vkcv::ComputePipelineConfig computeCullingConfig {
         cullingProgram,
-        {core.getDescriptorSetLayout(cullingSetLayout).vulkanHandle}
+        {cullingSetLayout}
     };
     vkcv::ComputePipelineHandle cullingPipelineHandle = core.createComputePipeline(computeCullingConfig);
     if (!cullingPipelineHandle) {
diff --git a/projects/particle_simulation/src/BloomAndFlares.cpp b/projects/particle_simulation/src/BloomAndFlares.cpp
index d0f25122c443eef847ce190c099eef95e8ecc0c8..a437afac25490e35547d53f432f7994d8e02717d 100644
--- a/projects/particle_simulation/src/BloomAndFlares.cpp
+++ b/projects/particle_simulation/src/BloomAndFlares.cpp
@@ -38,7 +38,8 @@ BloomAndFlares::BloomAndFlares(
     }
 
     m_DownsamplePipe = p_Core->createComputePipeline({
-        dsProg, { p_Core->getDescriptorSetLayout(m_DownsampleDescSetLayouts[0]).vulkanHandle }});
+        dsProg, m_DownsampleDescSetLayouts
+	});
 
     // UPSAMPLE
     vkcv::ShaderProgram usProg;
@@ -57,7 +58,8 @@ BloomAndFlares::BloomAndFlares(
     }
 
     m_UpsamplePipe = p_Core->createComputePipeline({
-            usProg, { p_Core->getDescriptorSetLayout(m_UpsampleDescSetLayouts[0]).vulkanHandle }});
+            usProg, m_UpsampleDescSetLayouts
+	});
 
     // LENS FEATURES
     vkcv::ShaderProgram lensProg;
@@ -71,7 +73,8 @@ BloomAndFlares::BloomAndFlares(
     m_LensFlareDescSetLayout = p_Core->createDescriptorSetLayout(lensProg.getReflectedDescriptors().at(0));
     m_LensFlareDescSet = p_Core->createDescriptorSet(m_LensFlareDescSetLayout);
     m_LensFlarePipe = p_Core->createComputePipeline({
-            lensProg, { p_Core->getDescriptorSetLayout(m_LensFlareDescSetLayout).vulkanHandle }});
+            lensProg, { m_LensFlareDescSetLayout }
+	});
 
     // COMPOSITE
     vkcv::ShaderProgram compProg;
@@ -85,7 +88,8 @@ BloomAndFlares::BloomAndFlares(
     m_CompositeDescSetLayout = p_Core->createDescriptorSetLayout(compProg.getReflectedDescriptors().at(0));
     m_CompositeDescSet = p_Core->createDescriptorSet(m_CompositeDescSetLayout);
     m_CompositePipe = p_Core->createComputePipeline({
-            compProg, { p_Core->getDescriptorSetLayout(m_CompositeDescSetLayout).vulkanHandle }});
+            compProg, { m_CompositeDescSetLayout }
+	});
 }
 
 void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStream,
diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp
index ae3c6795a66cdc81297986acb224a63055d02c44..10eb35bb25d5284ba17709bc6c50ab7005e19570 100644
--- a/projects/particle_simulation/src/main.cpp
+++ b/projects/particle_simulation/src/main.cpp
@@ -133,7 +133,9 @@ int main(int argc, const char **argv) {
 
     vkcv::GraphicsPipelineHandle particlePipeline = core.createGraphicsPipeline(particlePipelineDefinition);
 
-    vkcv::ComputePipelineHandle computePipeline = core.createComputePipeline({ computeShaderProgram, {core.getDescriptorSetLayout(computeDescriptorSetLayout).vulkanHandle} });
+    vkcv::ComputePipelineHandle computePipeline = core.createComputePipeline({
+		computeShaderProgram, {computeDescriptorSetLayout}
+	});
 
     vkcv::Buffer<glm::vec4> color = core.createBuffer<glm::vec4>(
             vkcv::BufferType::UNIFORM,
@@ -238,7 +240,8 @@ int main(int argc, const char **argv) {
     vkcv::DescriptorSetHandle tonemappingDescriptor = core.createDescriptorSet(tonemappingDescriptorLayout);
     vkcv::ComputePipelineHandle tonemappingPipe = core.createComputePipeline({
         tonemappingShader, 
-        { core.getDescriptorSetLayout(tonemappingDescriptorLayout).vulkanHandle }});
+        { tonemappingDescriptorLayout }
+	});
 
     std::uniform_real_distribution<float> rdm = std::uniform_real_distribution<float>(0.95f, 1.05f);
     std::default_random_engine rdmEngine;
diff --git a/projects/path_tracer/src/main.cpp b/projects/path_tracer/src/main.cpp
index 6da36cd6ad03bb7e54e7a57bbf7d4d992607ed52..db25f239fd5845d2bd2ac69243ceb48b0b80a6ce 100644
--- a/projects/path_tracer/src/main.cpp
+++ b/projects/path_tracer/src/main.cpp
@@ -103,7 +103,7 @@ int main(int argc, const char** argv) {
 	vkcv::DescriptorSetHandle       imageCombineDescriptorSet       = core.createDescriptorSet(imageCombineDescriptorSetLayout);
 	vkcv::ComputePipelineHandle     imageCombinePipeline            = core.createComputePipeline({
 		imageCombineShaderProgram, 
-		{ core.getDescriptorSetLayout(imageCombineDescriptorSetLayout).vulkanHandle }
+		{ imageCombineDescriptorSetLayout }
 	});
 
 	vkcv::DescriptorWrites imageCombineDescriptorWrites;
@@ -125,7 +125,7 @@ int main(int argc, const char** argv) {
 	vkcv::DescriptorSetHandle       presentDescriptorSet        = core.createDescriptorSet(presentDescriptorSetLayout);
 	vkcv::ComputePipelineHandle     presentPipeline             = core.createComputePipeline({
 		presentShaderProgram,
-		{ core.getDescriptorSetLayout(presentDescriptorSetLayout).vulkanHandle }
+		{ presentDescriptorSetLayout }
 	});
 
 	// clear shader
@@ -140,7 +140,7 @@ int main(int argc, const char** argv) {
 	vkcv::DescriptorSetHandle       imageClearDescriptorSet         = core.createDescriptorSet(imageClearDescriptorSetLayout);
 	vkcv::ComputePipelineHandle     imageClearPipeline              = core.createComputePipeline({
 		clearShaderProgram,
-		{ core.getDescriptorSetLayout(imageClearDescriptorSetLayout).vulkanHandle }
+		{ imageClearDescriptorSetLayout }
 	});
 
 	vkcv::DescriptorWrites imageClearDescriptorWrites;
@@ -203,7 +203,7 @@ int main(int argc, const char** argv) {
 
 	vkcv::ComputePipelineHandle tracePipeline = core.createComputePipeline({
 		traceShaderProgram,
-		{ core.getDescriptorSetLayout(traceDescriptorSetLayout).vulkanHandle }
+		{ traceDescriptorSetLayout }
 	});
 
 	if (!tracePipeline)
diff --git a/projects/saf_r/src/main.cpp b/projects/saf_r/src/main.cpp
index 354ea7a6c97b37b88ff7b484b13d878f09ae4d0f..49a388a5ef4a03900f5740bb65cfd8a8379675c4 100644
--- a/projects/saf_r/src/main.cpp
+++ b/projects/saf_r/src/main.cpp
@@ -184,7 +184,7 @@ int main(int argc, const char** argv) {
 
 	const vkcv::ComputePipelineConfig computePipelineConfig{
 			computeShaderProgram,
-			{core.getDescriptorSetLayout(computeDescriptorSetLayout).vulkanHandle}
+			{computeDescriptorSetLayout}
 	};
 
 	vkcv::ComputePipelineHandle computePipeline = core.createComputePipeline(computePipelineConfig);
diff --git a/projects/sph/src/BloomAndFlares.cpp b/projects/sph/src/BloomAndFlares.cpp
index 09534815afcd8ab238b79da5c6bbceb6672b043a..0af3bf8cc132db891e070a0068183a702061ee1d 100644
--- a/projects/sph/src/BloomAndFlares.cpp
+++ b/projects/sph/src/BloomAndFlares.cpp
@@ -37,7 +37,8 @@ BloomAndFlares::BloomAndFlares(
 		        p_Core->createDescriptorSet(m_DownsampleDescSetLayouts.back()));
     }
     m_DownsamplePipe = p_Core->createComputePipeline({
-            dsProg, { p_Core->getDescriptorSetLayout(m_DownsampleDescSetLayouts[0]).vulkanHandle } });
+            dsProg, m_DownsampleDescSetLayouts
+	});
 
     // UPSAMPLE
     vkcv::ShaderProgram usProg;
@@ -55,7 +56,8 @@ BloomAndFlares::BloomAndFlares(
                 p_Core->createDescriptorSet(m_UpsampleDescSetLayouts.back()));
     }
     m_UpsamplePipe = p_Core->createComputePipeline({
-            usProg, { p_Core->getDescriptorSetLayout(m_UpsampleDescSetLayouts[0]).vulkanHandle } });
+            usProg, m_UpsampleDescSetLayouts
+	});
 
     // LENS FEATURES
     vkcv::ShaderProgram lensProg;
@@ -68,7 +70,8 @@ BloomAndFlares::BloomAndFlares(
     m_LensFlareDescSetLayout = p_Core->createDescriptorSetLayout(lensProg.getReflectedDescriptors().at(0));
     m_LensFlareDescSet = p_Core->createDescriptorSet(m_LensFlareDescSetLayout);
     m_LensFlarePipe = p_Core->createComputePipeline({
-            lensProg, { p_Core->getDescriptorSetLayout(m_LensFlareDescSetLayout).vulkanHandle } });
+            lensProg, { m_LensFlareDescSetLayout }
+	});
 
     // COMPOSITE
     vkcv::ShaderProgram compProg;
@@ -81,7 +84,8 @@ BloomAndFlares::BloomAndFlares(
     m_CompositeDescSetLayout = p_Core->createDescriptorSetLayout(compProg.getReflectedDescriptors().at(0));
     m_CompositeDescSet = p_Core->createDescriptorSet(m_CompositeDescSetLayout);
     m_CompositePipe = p_Core->createComputePipeline({
-            compProg, { p_Core->getDescriptorSetLayout(m_CompositeDescSetLayout).vulkanHandle } });
+            compProg, { m_CompositeDescSetLayout }
+	});
 }
 
 void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStream,
diff --git a/projects/sph/src/PipelineInit.cpp b/projects/sph/src/PipelineInit.cpp
index 6cf941fa0d8f8716b7d05daf9b6fb618b0fa7d85..052c983cb094114853d19dac3e76149db99116db 100644
--- a/projects/sph/src/PipelineInit.cpp
+++ b/projects/sph/src/PipelineInit.cpp
@@ -21,7 +21,8 @@ vkcv::DescriptorSetHandle PipelineInit::ComputePipelineInit(vkcv::Core *pCore, v
 
     pipeline = pCore->createComputePipeline({
             shaderProgram,
-            { pCore->getDescriptorSetLayout(descriptorSetLayout).vulkanHandle } });
+            { descriptorSetLayout }
+	});
 
     return  descriptorSet;
 }
\ No newline at end of file
diff --git a/projects/voxelization/src/BloomAndFlares.cpp b/projects/voxelization/src/BloomAndFlares.cpp
index 2014d7a0219141ec6363b38a5311cb924b6b6a45..a7ac2904c173d84d45ffec1d03f3c37fef20c76a 100644
--- a/projects/voxelization/src/BloomAndFlares.cpp
+++ b/projects/voxelization/src/BloomAndFlares.cpp
@@ -51,7 +51,7 @@ BloomAndFlares::BloomAndFlares(
     }
 
     m_DownsamplePipe = p_Core->createComputePipeline({
-        dsProg, { p_Core->getDescriptorSetLayout(m_DownsampleDescSetLayouts[0]).vulkanHandle }
+        dsProg, m_DownsampleDescSetLayouts
     });
 
     // UPSAMPLE
@@ -77,7 +77,7 @@ BloomAndFlares::BloomAndFlares(
     }
 
     m_UpsamplePipe = p_Core->createComputePipeline({
-        usProg, { p_Core->getDescriptorSetLayout(m_UpsampleDescSetLayouts[0]).vulkanHandle }
+        usProg, m_UpsampleDescSetLayouts
     });
 
     // LENS FEATURES
@@ -92,7 +92,8 @@ BloomAndFlares::BloomAndFlares(
     m_LensFlareDescSetLayout = p_Core->createDescriptorSetLayout(lensProg.getReflectedDescriptors().at(0));
     m_LensFlareDescSet = p_Core->createDescriptorSet(m_LensFlareDescSetLayout);
     m_LensFlarePipe = p_Core->createComputePipeline(
-        { lensProg, { p_Core->getDescriptorSetLayout(m_LensFlareDescSetLayout).vulkanHandle } });
+        { lensProg, { m_LensFlareDescSetLayout }
+	});
 
 
     // COMPOSITE
@@ -107,7 +108,8 @@ BloomAndFlares::BloomAndFlares(
     m_CompositeDescSetLayout = p_Core->createDescriptorSetLayout(compProg.getReflectedDescriptors().at(0));
     m_CompositeDescSet = p_Core->createDescriptorSet(m_CompositeDescSetLayout);
     m_CompositePipe = p_Core->createComputePipeline(
-        { compProg, { p_Core->getDescriptorSetLayout(m_CompositeDescSetLayout).vulkanHandle } });
+        { compProg, { m_CompositeDescSetLayout }
+	});
 
     // radial LUT
     const auto texture = vkcv::asset::loadTexture("assets/RadialLUT.png");
diff --git a/projects/voxelization/src/ShadowMapping.cpp b/projects/voxelization/src/ShadowMapping.cpp
index ce4261ff2403139d10b9d677e7aa216a3e41178f..c2e1631098146c8ee82586995a5a9d21e6d85252 100644
--- a/projects/voxelization/src/ShadowMapping.cpp
+++ b/projects/voxelization/src/ShadowMapping.cpp
@@ -192,7 +192,7 @@ ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vert
 
 	m_depthToMomentsDescriptorSetLayout         = corePtr->createDescriptorSetLayout(depthToMomentsShader.getReflectedDescriptors().at(0));
 	m_depthToMomentsDescriptorSet               = corePtr->createDescriptorSet(m_depthToMomentsDescriptorSetLayout);
-    m_depthToMomentsPipe = corePtr->createComputePipeline({ depthToMomentsShader, { corePtr->getDescriptorSetLayout(m_depthToMomentsDescriptorSetLayout).vulkanHandle }});
+    m_depthToMomentsPipe = corePtr->createComputePipeline({ depthToMomentsShader, { m_depthToMomentsDescriptorSetLayout }});
 
 	vkcv::DescriptorWrites depthToMomentDescriptorWrites;
 	depthToMomentDescriptorWrites.sampledImageWrites    = { vkcv::SampledImageDescriptorWrite(0, m_shadowMapDepth.getHandle()) };
@@ -204,7 +204,7 @@ ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vert
 	vkcv::ShaderProgram shadowBlurXShader   = loadShadowBlurXShader();
 	m_shadowBlurXDescriptorSetLayout        = corePtr->createDescriptorSetLayout(shadowBlurXShader.getReflectedDescriptors().at(0));
 	m_shadowBlurXDescriptorSet              = corePtr->createDescriptorSet(m_shadowBlurXDescriptorSetLayout);
-	m_shadowBlurXPipe                       = corePtr->createComputePipeline({ shadowBlurXShader, { corePtr->getDescriptorSetLayout(m_shadowBlurXDescriptorSetLayout).vulkanHandle }});
+	m_shadowBlurXPipe                       = corePtr->createComputePipeline({ shadowBlurXShader, { m_shadowBlurXDescriptorSetLayout }});
 
 	vkcv::DescriptorWrites shadowBlurXDescriptorWrites;
 	shadowBlurXDescriptorWrites.sampledImageWrites   = { vkcv::SampledImageDescriptorWrite(0, m_shadowMap.getHandle()) };
@@ -216,7 +216,7 @@ ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vert
 	vkcv::ShaderProgram shadowBlurYShader   = loadShadowBlurYShader();
 	m_shadowBlurYDescriptorSetLayout        = corePtr->createDescriptorSetLayout(shadowBlurYShader.getReflectedDescriptors().at(0));
 	m_shadowBlurYDescriptorSet              = corePtr->createDescriptorSet(m_shadowBlurYDescriptorSetLayout);
-    m_shadowBlurYPipe                       = corePtr->createComputePipeline({ shadowBlurYShader, { corePtr->getDescriptorSetLayout(m_shadowBlurYDescriptorSetLayout).vulkanHandle }});
+    m_shadowBlurYPipe                       = corePtr->createComputePipeline({ shadowBlurYShader, { m_shadowBlurYDescriptorSetLayout }});
 
     vkcv::DescriptorWrites shadowBlurYDescriptorWrites;
 	shadowBlurYDescriptorWrites.sampledImageWrites  = { vkcv::SampledImageDescriptorWrite(0, m_shadowMapIntermediate.getHandle()) };
diff --git a/projects/voxelization/src/Voxelization.cpp b/projects/voxelization/src/Voxelization.cpp
index c023af21c673651984e945ab03d16280c18f0768..889912e3e29e49c4b6f9cea763bdb664384dea29 100644
--- a/projects/voxelization/src/Voxelization.cpp
+++ b/projects/voxelization/src/Voxelization.cpp
@@ -176,7 +176,8 @@ Voxelization::Voxelization(
 	m_voxelResetDescriptorSet = m_corePtr->createDescriptorSet(m_voxelResetDescriptorSetLayout);
 	m_voxelResetPipe = m_corePtr->createComputePipeline({
 		resetVoxelShader,
-		{ m_corePtr->getDescriptorSetLayout(m_voxelResetDescriptorSetLayout).vulkanHandle }});
+		{ m_voxelResetDescriptorSetLayout }
+	});
 
 	vkcv::DescriptorWrites resetVoxelWrites;
 	resetVoxelWrites.storageBufferWrites = { vkcv::BufferDescriptorWrite(0, m_voxelBuffer.getHandle()) };
@@ -189,7 +190,8 @@ Voxelization::Voxelization(
 	m_bufferToImageDescriptorSet = m_corePtr->createDescriptorSet(m_bufferToImageDescriptorSetLayout);
 	m_bufferToImagePipe = m_corePtr->createComputePipeline({
 		bufferToImageShader,
-		{ m_corePtr->getDescriptorSetLayout(m_bufferToImageDescriptorSetLayout).vulkanHandle }});
+		{ m_bufferToImageDescriptorSetLayout }
+	});
 
 	vkcv::DescriptorWrites bufferToImageDescriptorWrites;
 	bufferToImageDescriptorWrites.storageBufferWrites = { vkcv::BufferDescriptorWrite(0, m_voxelBuffer.getHandle()) };
@@ -203,7 +205,8 @@ Voxelization::Voxelization(
 	m_secondaryBounceDescriptorSet = m_corePtr->createDescriptorSet(m_secondaryBounceDescriptorSetLayout);
 	m_secondaryBouncePipe = m_corePtr->createComputePipeline({
 		secondaryBounceShader,
-		{ m_corePtr->getDescriptorSetLayout(m_secondaryBounceDescriptorSetLayout).vulkanHandle }});
+		{ m_secondaryBounceDescriptorSetLayout }
+	});
 
 	vkcv::DescriptorWrites secondaryBounceDescriptorWrites;
 	secondaryBounceDescriptorWrites.storageBufferWrites = { vkcv::BufferDescriptorWrite(0, m_voxelBuffer.getHandle()) };
diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp
index a4ffb668e74d0a0829bb3c436ed5b992695b6ecf..8d7a6805add9a0f129bfe986e12e61d17585dd4d 100644
--- a/projects/voxelization/src/main.cpp
+++ b/projects/voxelization/src/main.cpp
@@ -468,7 +468,8 @@ int main(int argc, const char** argv) {
 	vkcv::DescriptorSetHandle tonemappingDescriptorSet = core.createDescriptorSet(tonemappingDescriptorSetLayout);
 	vkcv::ComputePipelineHandle tonemappingPipeline = core.createComputePipeline({
 		tonemappingProgram,
-		{ core.getDescriptorSetLayout(tonemappingDescriptorSetLayout).vulkanHandle }});
+		{ tonemappingDescriptorSetLayout }
+	});
 	
 	// tonemapping compute shader
 	vkcv::ShaderProgram postEffectsProgram;
@@ -482,7 +483,8 @@ int main(int argc, const char** argv) {
 	vkcv::DescriptorSetHandle postEffectsDescriptorSet = core.createDescriptorSet(postEffectsDescriptorSetLayout);
 	vkcv::ComputePipelineHandle postEffectsPipeline = core.createComputePipeline({
 			postEffectsProgram,
-			{ core.getDescriptorSetLayout(postEffectsDescriptorSetLayout).vulkanHandle }});
+			{ postEffectsDescriptorSetLayout }
+	});
 
 	// resolve compute shader
 	vkcv::ShaderProgram resolveProgram;
@@ -496,7 +498,8 @@ int main(int argc, const char** argv) {
 	vkcv::DescriptorSetHandle resolveDescriptorSet = core.createDescriptorSet(resolveDescriptorSetLayout);
 	vkcv::ComputePipelineHandle resolvePipeline = core.createComputePipeline({
 		resolveProgram,
-		{ core.getDescriptorSetLayout(resolveDescriptorSetLayout).vulkanHandle }});
+		{ resolveDescriptorSetLayout }
+	});
 
 	vkcv::SamplerHandle resolveSampler = core.createSampler(
 		vkcv::SamplerFilterType::NEAREST,
@@ -1001,7 +1004,8 @@ int main(int argc, const char** argv) {
 
 				vkcv::ComputePipelineHandle newPipeline = core.createComputePipeline({
 					newProgram,
-					{ core.getDescriptorSetLayout(tonemappingDescriptorSetLayout).vulkanHandle }});
+					{ tonemappingDescriptorSetLayout }
+				});
 
 				if (newPipeline) {
 					tonemappingPipeline = newPipeline;
diff --git a/src/vkcv/ComputePipelineManager.cpp b/src/vkcv/ComputePipelineManager.cpp
index f090b6dbe7e05f488958c072a758fbf2d2938ab5..a599001d3c60e126cfa0a52a1347abfe48b961a9 100644
--- a/src/vkcv/ComputePipelineManager.cpp
+++ b/src/vkcv/ComputePipelineManager.cpp
@@ -41,11 +41,12 @@ namespace vkcv
         return pipeline.m_layout;
     }
 
-    ComputePipelineHandle ComputePipelineManager::createComputePipeline(const ComputePipelineConfig& config) {
+    ComputePipelineHandle ComputePipelineManager::createComputePipeline(const ShaderProgram& shaderProgram,
+																		const std::vector<vk::DescriptorSetLayout>& descriptorSetLayouts) {
 
         // Temporally handing over the Shader Program instead of a pipeline config
         vk::ShaderModule computeModule{};
-        if (createShaderModule(computeModule, config.m_ShaderProgram, ShaderStage::COMPUTE) != vk::Result::eSuccess)
+        if (createShaderModule(computeModule, shaderProgram, ShaderStage::COMPUTE) != vk::Result::eSuccess)
             return ComputePipelineHandle();
 
         vk::PipelineShaderStageCreateInfo pipelineComputeShaderStageInfo(
@@ -56,9 +57,9 @@ namespace vkcv
                 nullptr
         );
 
-        vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo({}, config.m_DescriptorSetLayouts);
+        vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo({}, descriptorSetLayouts);
 
-        const size_t pushConstantSize = config.m_ShaderProgram.getPushConstantSize();
+        const size_t pushConstantSize = shaderProgram.getPushConstantSize();
         vk::PushConstantRange pushConstantRange(vk::ShaderStageFlagBits::eCompute, 0, pushConstantSize);
         if (pushConstantSize > 0) {
             pipelineLayoutCreateInfo.setPushConstantRangeCount(1);
diff --git a/src/vkcv/ComputePipelineManager.hpp b/src/vkcv/ComputePipelineManager.hpp
index 527243e6ec43850d416a7d929e01351454c40086..acb50bbdef99d037374c140836d25bb161132b2b 100644
--- a/src/vkcv/ComputePipelineManager.hpp
+++ b/src/vkcv/ComputePipelineManager.hpp
@@ -1,7 +1,7 @@
 #pragma once
 
 /**
- * @authors Mark Mints
+ * @authors Mark Mints, Tobias Frisch
  * @file src/vkcv/ComputePipelineManager.hpp
  * @brief Creation and handling of Compute Pipelines
  */
@@ -49,10 +49,12 @@ namespace vkcv
          * Creates a Compute Pipeline based on the set shader stages in the Config Struct.
          * This function is wrapped in /src/vkcv/Core.cpp by Core::createComputePipeline(const ComputePipelineConfig &config).
          * On application level it is necessary first to fill a ComputePipelineConfig Struct.
-         * @param config Hands over all needed information for pipeline creation.
+         * @param shaderProgram Hands over all needed information for pipeline creation.
+         * @param descriptorSetLayouts Hands over all needed information for pipeline creation.
          * @return A Handler to the created Compute Pipeline Object.
          */
-        ComputePipelineHandle createComputePipeline(const ComputePipelineConfig& config);
+        ComputePipelineHandle createComputePipeline(const ShaderProgram& shaderProgram,
+													const std::vector<vk::DescriptorSetLayout>& descriptorSetLayouts);
 
     private:
         struct ComputePipeline {
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index 99d27496ba134c75dc555dca18fc26410005ed23..b64d296f13aa6c3a633c5a26e1f6d9caabbefd11 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -85,7 +85,14 @@ namespace vkcv
 
     ComputePipelineHandle Core::createComputePipeline(const ComputePipelineConfig &config)
     {
-        return m_ComputePipelineManager->createComputePipeline(config);
+		std::vector<vk::DescriptorSetLayout> layouts;
+		layouts.resize(config.m_DescriptorSetLayouts.size());
+	
+		for (size_t i = 0; i < layouts.size(); i++) {
+			layouts[i] = getDescriptorSetLayout(config.m_DescriptorSetLayouts[i]).vulkanHandle;
+		}
+		
+        return m_ComputePipelineManager->createComputePipeline(config.m_ShaderProgram, layouts);
     }
 
     PassHandle Core::createPass(const PassConfig &config)