diff --git a/include/vkcv/GraphicsPipelineConfig.hpp b/include/vkcv/GraphicsPipelineConfig.hpp
index e235b5a3acaa03f17f93a5f5b679cedffffea462..286411969a5aa1ce818735faea238f246adb40d6 100644
--- a/include/vkcv/GraphicsPipelineConfig.hpp
+++ b/include/vkcv/GraphicsPipelineConfig.hpp
@@ -28,7 +28,7 @@ namespace vkcv {
 		uint32_t                              	m_Height;
         PassHandle                            	m_PassHandle;
         VertexLayout                          	m_VertexLayout;
-        std::vector<vk::DescriptorSetLayout>  	m_DescriptorLayouts;
+        std::vector<DescriptorSetLayoutHandle>	m_DescriptorLayouts;
         bool                                  	m_UseDynamicViewport;
         bool                                  	m_UseConservativeRasterization 	= false;
         PrimitiveTopology                     	m_PrimitiveTopology 			= PrimitiveTopology::TriangleList;
diff --git a/projects/bindless_textures/src/main.cpp b/projects/bindless_textures/src/main.cpp
index 555e3dc65016b0e383fc57ebc3618a35485e9519..0ad6c1250c8a6e01838ae1b52fd52a6dd24fbbe3 100644
--- a/projects/bindless_textures/src/main.cpp
+++ b/projects/bindless_textures/src/main.cpp
@@ -162,7 +162,7 @@ int main(int argc, const char** argv) {
         UINT32_MAX,
         firstMeshPass,
         {firstMeshLayout},
-		{ core.getDescriptorSetLayout(descriptorSetLayout).vulkanHandle },
+		{ descriptorSetLayout },
 		true
 	};
 	vkcv::GraphicsPipelineHandle firstMeshPipeline = core.createGraphicsPipeline(firstMeshPipelineConfig);
diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp
index 0871631827b87539bbe9b0050420088e199a39af..55278b703b6a7c70d7d12e8b86ca5eea2b76cdf8 100644
--- a/projects/first_mesh/src/main.cpp
+++ b/projects/first_mesh/src/main.cpp
@@ -115,7 +115,7 @@ int main(int argc, const char** argv) {
         UINT32_MAX,
         firstMeshPass,
         {firstMeshLayout},
-		{ core.getDescriptorSetLayout(setLayoutHandle).vulkanHandle },
+		{ setLayoutHandle },
 		true
 	};
 	vkcv::GraphicsPipelineHandle firstMeshPipeline = core.createGraphicsPipeline(firstMeshPipelineConfig);
diff --git a/projects/first_scene/src/main.cpp b/projects/first_scene/src/main.cpp
index a078776eb4b7688f51d45cecb7e08d5ba9d0d973..3ec5b9764f70efa8911d8e772d6287e5efc8f056 100644
--- a/projects/first_scene/src/main.cpp
+++ b/projects/first_scene/src/main.cpp
@@ -87,8 +87,9 @@ int main(int argc, const char** argv) {
 		UINT32_MAX,
 		scenePass,
 		{sceneLayout},
-		{ core.getDescriptorSetLayout(material0.getDescriptorSetLayout()).vulkanHandle },
-		true };
+		{ material0.getDescriptorSetLayout() },
+		true
+	};
 	vkcv::GraphicsPipelineHandle scenePipeline = core.createGraphicsPipeline(scenePipelineDefinition);
 	
 	if (!scenePipeline) {
diff --git a/projects/indirect_dispatch/src/AppSetup.cpp b/projects/indirect_dispatch/src/AppSetup.cpp
index d186a5ecbd8d13e70542ec6c9f0f14b40b2d2b5c..1d40204b1ab7c6cd49a0c7924fa1fdbf6c2cc24e 100644
--- a/projects/indirect_dispatch/src/AppSetup.cpp
+++ b/projects/indirect_dispatch/src/AppSetup.cpp
@@ -122,12 +122,12 @@ bool loadGraphicPass(
 
 	const auto descriptorBindings = shaderProgram.getReflectedDescriptors();
 	const bool hasDescriptor = descriptorBindings.size() > 0;
-	std::vector<vk::DescriptorSetLayout> descriptorSetLayouts = {};
+	std::vector<vkcv::DescriptorSetLayoutHandle> descriptorSetLayouts = {};
 	if (hasDescriptor)
 	{
 	    outPassHandles->descriptorSetLayout = core.createDescriptorSetLayout(descriptorBindings.at(0));
 	    outPassHandles->descriptorSet = core.createDescriptorSet(outPassHandles->descriptorSetLayout);
-	    descriptorSetLayouts.push_back(core.getDescriptorSetLayout(outPassHandles->descriptorSetLayout).vulkanHandle);
+	    descriptorSetLayouts.push_back(outPassHandles->descriptorSetLayout);
 	}
 
 
@@ -138,7 +138,8 @@ bool loadGraphicPass(
 		outPassHandles->renderPass,
 		{ vertexLayout },
 		descriptorSetLayouts,
-		true };
+		true
+	};
 	pipelineConfig.m_depthTest  = depthTest;
 	outPassHandles->pipeline    = core.createGraphicsPipeline(pipelineConfig);
 
diff --git a/projects/indirect_draw/src/main.cpp b/projects/indirect_draw/src/main.cpp
index d494512056a55179752b94c2b20119b44659f857..4841743a8e1462bfba572960986a3aba6ea355ab 100644
--- a/projects/indirect_draw/src/main.cpp
+++ b/projects/indirect_draw/src/main.cpp
@@ -467,7 +467,7 @@ int main(int argc, const char** argv) {
         UINT32_MAX,
         passHandle,
         {sponzaVertexLayout},
-		{ core.getDescriptorSetLayout(descriptorSetLayout).vulkanHandle },
+		{ descriptorSetLayout },
 		true
 	};
 	vkcv::GraphicsPipelineHandle sponzaPipelineHandle = core.createGraphicsPipeline(sponzaPipelineConfig);
diff --git a/projects/mesh_shader/src/main.cpp b/projects/mesh_shader/src/main.cpp
index 0ee16b99822e0c8fbeaf58af57f02255493b0fb5..dc7ca7caae5362e74fac82558b530cdce0357bb0 100644
--- a/projects/mesh_shader/src/main.cpp
+++ b/projects/mesh_shader/src/main.cpp
@@ -211,7 +211,7 @@ int main(int argc, const char** argv) {
 			swapchainExtent.height,
 			renderPass,
 			{ bunnyLayout },
-			{ core.getDescriptorSetLayout(vertexShaderDescriptorSetLayout).vulkanHandle },
+			{ vertexShaderDescriptorSetLayout },
 			false
 	};
 
@@ -261,7 +261,7 @@ int main(int argc, const char** argv) {
 		swapchainExtent.height,
 		renderPass,
 		{meshShaderLayout},
-		{core.getDescriptorSetLayout(meshShaderDescriptorSetLayout).vulkanHandle},
+		{meshShaderDescriptorSetLayout},
 		false
 	};
 
diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp
index 10eb35bb25d5284ba17709bc6c50ab7005e19570..291b97f2fde4719530dcb26eb4baeb197f9b2a74 100644
--- a/projects/particle_simulation/src/main.cpp
+++ b/projects/particle_simulation/src/main.cpp
@@ -121,8 +121,9 @@ int main(int argc, const char **argv) {
             UINT32_MAX,
             particlePass,
             {particleLayout},
-            {core.getDescriptorSetLayout(descriptorSetLayout).vulkanHandle},
-            true};
+            {descriptorSetLayout},
+            true
+	};
     particlePipelineDefinition.m_blendMode = vkcv::BlendMode::Additive;
 
     const std::vector<glm::vec3> vertices = {glm::vec3(-0.012, 0.012, 0),
diff --git a/projects/saf_r/src/main.cpp b/projects/saf_r/src/main.cpp
index 49a388a5ef4a03900f5740bb65cfd8a8379675c4..9ffd2845e1081d56e6026a10f19abd36e82d5828 100644
--- a/projects/saf_r/src/main.cpp
+++ b/projects/saf_r/src/main.cpp
@@ -176,7 +176,7 @@ int main(int argc, const char** argv) {
 			(uint32_t)windowHeight,
 			safrPass,
 			{},
-			{ core.getDescriptorSetLayout(descriptorSetLayout).vulkanHandle },
+			{ descriptorSetLayout },
 			false
 	};
 
diff --git a/projects/sph/shaders/force.comp b/projects/sph/shaders/force.comp
index ea9b378b48a23fd0208ab18d884dbccda5ab21f4..9830a42f11a527e570bc77bc2f5a65b347e35819 100644
--- a/projects/sph/shaders/force.comp
+++ b/projects/sph/shaders/force.comp
@@ -40,29 +40,31 @@ layout( push_constant ) uniform constants{
     float particleCount;
 };
 
-float spiky(float r)    
-{
-    return (15.f / (PI * pow(h, 6)) * pow((h-r), 3)) * int(0<=r && r<=h);
-}
-
 float grad_spiky(float r)
 {
-    return -45.f / (PI * pow(h, 6)) * pow((h-r), 2) * int(0<=r && r<=h);
+    return -45.f / (PI * pow(h, 6)) * pow((h-r), 2);
 }
 
-
-
 float laplacian(float r)
 {
-    return (45.f / (PI * pow(h,6)) * (h - r)) * int(0<=r && r<=h);
+    return (45.f / (PI * pow(h,6)) * (h - r));
 }
 
 vec3 pressureForce = vec3(0, 0, 0);
 vec3 viscosityForce = vec3(0, 0, 0); 
 vec3 externalForce = vec3(0, 0, 0);
 
-void main() {
+struct ParticleData
+{
+    vec3 position;
+    float density;
+    vec3 velocity;
+    float pressure;
+};
+
+shared ParticleData particle_data [256];
 
+void main() {
     uint id = gl_GlobalInvocationID.x;
 
     if(id >= int(particleCount))
@@ -70,26 +72,75 @@ void main() {
         return;
     }
 
-    externalForce = inParticle[id].density * gravity * vec3(-gravityDir.x,gravityDir.y,gravityDir.z);
+    uint index_offset = gl_WorkGroupID.x * gl_WorkGroupSize.x;
+
+    particle_data[gl_LocalInvocationIndex].position = inParticle[id].position;
+    particle_data[gl_LocalInvocationIndex].density  = inParticle[id].density;
+    particle_data[gl_LocalInvocationIndex].velocity = inParticle[id].velocity;
+    particle_data[gl_LocalInvocationIndex].pressure = inParticle[id].pressure;
+
+    memoryBarrierShared();
+
+    const float h6 = pow(h, 6);
+    externalForce = particle_data[gl_LocalInvocationIndex].density * gravity * vec3(-gravityDir.x,gravityDir.y,gravityDir.z);
+
+    for(uint j = 1; j < gl_WorkGroupSize.x; j++) {
+        uint i = (gl_LocalInvocationIndex + j) % gl_WorkGroupSize.x;
+
+        vec3 dir = particle_data[gl_LocalInvocationIndex].position - particle_data[i].position;
+        float dist = length(dir);
 
-    for(uint i = 0; i < int(particleCount); i++)  
+        if ((dist > 0.0f) && (dist <= h))
+        {
+            const float h_dist = (h - dist);
+
+            float laplacian = 45.f / (PI * h6) * h_dist;
+            float grad_spiky = -1.0f * laplacian * h_dist;
+
+            pressureForce += mass * -(particle_data[gl_LocalInvocationIndex].pressure + particle_data[i].pressure)/(2.f * particle_data[i].density) * grad_spiky * normalize(dir);
+            viscosityForce += mass * (particle_data[i].velocity - particle_data[gl_LocalInvocationIndex].velocity)/particle_data[i].density * laplacian;
+        }
+    }
+
+    for(uint i = 0; i < index_offset; i++)
+    {
+        vec3 dir = particle_data[gl_LocalInvocationIndex].position - inParticle[i].position;
+        float dist = length(dir);
+
+        if ((dist > 0.0f) && (dist <= h))
+        {
+            const float h_dist = (h - dist);
+
+            float laplacian = 45.f / (PI * h6) * h_dist;
+            float grad_spiky = -1.0f * laplacian * h_dist;
+
+            pressureForce += mass * -(particle_data[gl_LocalInvocationIndex].pressure + inParticle[i].pressure)/(2.f * inParticle[i].density) * grad_spiky * normalize(dir);
+            viscosityForce += mass * (inParticle[i].velocity - particle_data[gl_LocalInvocationIndex].velocity)/inParticle[i].density * laplacian;
+        }
+    }
+
+    for(uint i = index_offset + gl_WorkGroupSize.x; i < int(particleCount); i++)
     {
-        if (id != i)
+        vec3 dir = particle_data[gl_LocalInvocationIndex].position - inParticle[i].position;
+        float dist = length(dir);
+
+        if ((dist > 0.0f) && (dist <= h))
         {
-            vec3 dir = inParticle[id].position - inParticle[i].position;
-            float dist = length(dir);
-            if(dist != 0) 
-            {
-                pressureForce += mass * -(inParticle[id].pressure + inParticle[i].pressure)/(2.f * inParticle[i].density) * grad_spiky(dist) * normalize(dir);
-                viscosityForce += mass * (inParticle[i].velocity - inParticle[id].velocity)/inParticle[i].density * laplacian(dist);
-            }
+            const float h_dist = (h - dist);
+
+            float laplacian = 45.f / (PI * h6) * h_dist;
+            float grad_spiky = -1.0f * laplacian * h_dist;
+
+            pressureForce += mass * -(particle_data[gl_LocalInvocationIndex].pressure + inParticle[i].pressure)/(2.f * inParticle[i].density) * grad_spiky * normalize(dir);
+            viscosityForce += mass * (inParticle[i].velocity - particle_data[gl_LocalInvocationIndex].velocity)/inParticle[i].density * laplacian;
         }
     }
+
     viscosityForce *= viscosity;
 
     outParticle[id].force = externalForce + pressureForce + viscosityForce;
-    outParticle[id].density = inParticle[id].density;
-    outParticle[id].pressure = inParticle[id].pressure;
-    outParticle[id].position = inParticle[id].position;
-    outParticle[id].velocity = inParticle[id].velocity;
+    outParticle[id].density = particle_data[gl_LocalInvocationIndex].density;
+    outParticle[id].pressure = particle_data[gl_LocalInvocationIndex].pressure;
+    outParticle[id].position = particle_data[gl_LocalInvocationIndex].position;
+    outParticle[id].velocity = particle_data[gl_LocalInvocationIndex].velocity;
 }
diff --git a/projects/sph/shaders/pressure.comp b/projects/sph/shaders/pressure.comp
index 05b3af3afb490b427cc1297f21a82a779d4c8ecb..eb2029e35760d732ac8b4095d0ef41819a256736 100644
--- a/projects/sph/shaders/pressure.comp
+++ b/projects/sph/shaders/pressure.comp
@@ -42,11 +42,13 @@ layout( push_constant ) uniform constants{
 
 float poly6(float r)    
 {
-    return (315.f * pow((pow(h,2)-pow(r,2)), 3)/(64.f*PI*pow(h, 9))) * int(0<=r && r<=h);
+    return (315.f * pow((pow(h,2)-pow(r,2)), 3)/(64.f*PI*pow(h, 9))) * int(r<=h);
 }
 
 float densitySum = 0.f;
 
+shared vec3 position_data [256];
+
 void main() {
     
     uint id = gl_GlobalInvocationID.x;
@@ -56,17 +58,34 @@ void main() {
         return;
     }
 
-    for(uint i = 0; i < int(particleCount); i++)   
+    uint index_offset = gl_WorkGroupID.x * gl_WorkGroupSize.x;
+
+    position_data[gl_LocalInvocationIndex] = inParticle[id].position;
+
+    memoryBarrierShared();
+
+    for(uint j = 1; j < gl_WorkGroupSize.x; j++) {
+        uint i = (gl_LocalInvocationIndex + j) % gl_WorkGroupSize.x;
+
+        float dist = distance(position_data[gl_LocalInvocationIndex], position_data[i]);
+        densitySum += mass * poly6(dist);
+    }
+
+    for(uint i = 0; i < index_offset; i++)
     {
-        if (id != i)
-        {
-            float dist = distance(inParticle[id].position, inParticle[i].position);
-            densitySum += mass * poly6(dist);
-        }
+        float dist = distance(position_data[gl_LocalInvocationIndex], inParticle[i].position);
+        densitySum += mass * poly6(dist);
     }
+
+    for(uint i = index_offset + gl_WorkGroupSize.x; i < int(particleCount); i++)
+    {
+        float dist = distance(position_data[gl_LocalInvocationIndex], inParticle[i].position);
+        densitySum += mass * poly6(dist);
+    }
+
     outParticle[id].density = max(densitySum,0.0000001f);
     outParticle[id].pressure = max((densitySum - offset), 0.0000001f) * gasConstant;
-    outParticle[id].position = inParticle[id].position;
+    outParticle[id].position = position_data[gl_LocalInvocationIndex];
     outParticle[id].velocity = inParticle[id].velocity;
     outParticle[id].force = inParticle[id].force;
 }
diff --git a/projects/sph/src/main.cpp b/projects/sph/src/main.cpp
index 616a84069369ba9cdee3d2d6221b11cb39eb7fa1..96968776a6aea9aaa12abfea1bbc966a43548491 100644
--- a/projects/sph/src/main.cpp
+++ b/projects/sph/src/main.cpp
@@ -122,8 +122,9 @@ int main(int argc, const char **argv) {
             UINT32_MAX,
             particlePass,
             {particleLayout},
-            {core.getDescriptorSetLayout(descriptorSetLayout).vulkanHandle},
-            true};
+            {descriptorSetLayout},
+            true
+	};
     particlePipelineDefinition.m_blendMode = vkcv::BlendMode::Additive;
 
     const std::vector<glm::vec3> vertices = {glm::vec3(-0.012, 0.012, 0),
diff --git a/projects/voxelization/src/Voxelization.cpp b/projects/voxelization/src/Voxelization.cpp
index 889912e3e29e49c4b6f9cea763bdb664384dea29..c5d48fb350226896546c1e9ae23bc5bff656aca4 100644
--- a/projects/voxelization/src/Voxelization.cpp
+++ b/projects/voxelization/src/Voxelization.cpp
@@ -110,11 +110,10 @@ Voxelization::Voxelization(
 		voxelResolution,
 		m_voxelizationPass,
 		dependencies.vertexLayout,
-		{ 
-		    m_corePtr->getDescriptorSetLayout(m_voxelizationDescriptorSetLayout).vulkanHandle,
-		    m_corePtr->getDescriptorSetLayout(dummyPerMeshDescriptorSetLayout).vulkanHandle},
+		{ m_voxelizationDescriptorSetLayout, dummyPerMeshDescriptorSetLayout },
 		false,
-		true };
+		true
+	};
 	m_voxelizationPipe = m_corePtr->createGraphicsPipeline(voxelizationPipeConfig);
 
 	vkcv::DescriptorWrites voxelizationDescriptorWrites;
@@ -156,10 +155,11 @@ Voxelization::Voxelization(
 		0,
 		m_visualisationPass,
 		{},
-		{ m_corePtr->getDescriptorSetLayout(m_visualisationDescriptorSetLayout).vulkanHandle },
+		{ m_visualisationDescriptorSetLayout },
 		true,
 		false,
-		vkcv::PrimitiveTopology::PointList };	// points are extended to cubes in the geometry shader
+		vkcv::PrimitiveTopology::PointList
+	};	// points are extended to cubes in the geometry shader
 	voxelVisualisationPipeConfig.m_multisampling = msaa;
 	m_visualisationPipe = m_corePtr->createGraphicsPipeline(voxelVisualisationPipeConfig);
 
diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp
index 8d7a6805add9a0f129bfe986e12e61d17585dd4d..7157d2f625d5d86d0f916dc3c1d6e4f4c596b546 100644
--- a/projects/voxelization/src/main.cpp
+++ b/projects/voxelization/src/main.cpp
@@ -317,10 +317,9 @@ int main(int argc, const char** argv) {
 		swapchainExtent.height,
 		prepassPass,
 		vertexLayout,
-		{ 
-		    core.getDescriptorSetLayout(prepassDescriptorSetLayout).vulkanHandle,
-			core.getDescriptorSetLayout(perMeshDescriptorSetLayouts[0]).vulkanHandle },
-		true };
+		{ prepassDescriptorSetLayout, perMeshDescriptorSetLayouts[0] },
+		true
+	};
 	prepassPipelineConfig.m_culling         = vkcv::CullMode::Back;
 	prepassPipelineConfig.m_multisampling   = msaa;
 	prepassPipelineConfig.m_depthTest       = vkcv::DepthTest::LessEqual;
@@ -335,9 +334,7 @@ int main(int argc, const char** argv) {
 		swapchainExtent.height,
 		forwardPass,
 		vertexLayout,
-		{	
-		    core.getDescriptorSetLayout(forwardShadingDescriptorSetLayout).vulkanHandle,
-			core.getDescriptorSetLayout(perMeshDescriptorSetLayouts[0]).vulkanHandle },
+		{ forwardShadingDescriptorSetLayout, perMeshDescriptorSetLayouts[0] },
 		true
 	};
     forwardPipelineConfig.m_culling         = vkcv::CullMode::Back;
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index b64d296f13aa6c3a633c5a26e1f6d9caabbefd11..12d2090de47e5d002734c9a44773affdb4f99b3e 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -80,7 +80,7 @@ namespace vkcv
 	
 	GraphicsPipelineHandle Core::createGraphicsPipeline(const GraphicsPipelineConfig &config)
     {
-        return m_PipelineManager->createPipeline(config, *m_PassManager);
+        return m_PipelineManager->createPipeline(config, *m_PassManager, *m_DescriptorManager);
     }
 
     ComputePipelineHandle Core::createComputePipeline(const ComputePipelineConfig &config)
diff --git a/src/vkcv/DescriptorManager.hpp b/src/vkcv/DescriptorManager.hpp
index acc6edd9b704c377480e7acbbc40b3e763003d5f..d60a6d5c6eb1a66db07487c888505e8b3731b046 100644
--- a/src/vkcv/DescriptorManager.hpp
+++ b/src/vkcv/DescriptorManager.hpp
@@ -1,3 +1,5 @@
+#pragma once
+
 /**
  * @authors Artur Wasmut, Susanne D�tsch, Simeon Hermann
  * @file src/vkcv/DescriptorManager.cpp
@@ -21,7 +23,7 @@ namespace vkcv
 	    explicit DescriptorManager(vk::Device device) noexcept;
 	    ~DescriptorManager() noexcept;
 
-	    DescriptorSetLayoutHandle createDescriptorSetLayout(const std::unordered_map<uint32_t, DescriptorBinding> &setBindingsMap);
+	    DescriptorSetLayoutHandle createDescriptorSetLayout(const DescriptorBindings &setBindingsMap);
         DescriptorSetHandle createDescriptorSet(const DescriptorSetLayoutHandle &setLayoutHandle);
 
 		void writeDescriptorSet(
diff --git a/src/vkcv/GraphicsPipelineManager.cpp b/src/vkcv/GraphicsPipelineManager.cpp
index 5eaf2c85bfa0c15df0d3c4a6002b2456c86f2922..ab0d9f26fdf482698f679b598d5b087e3674c638 100644
--- a/src/vkcv/GraphicsPipelineManager.cpp
+++ b/src/vkcv/GraphicsPipelineManager.cpp
@@ -361,7 +361,8 @@ namespace vkcv
 	 * @param config sets Push Constant Size and Descriptor Layouts.
 	 * @return Pipeline Layout Create Info Struct
 	 */
-	vk::PipelineLayoutCreateInfo createPipelineLayoutCreateInfo(const GraphicsPipelineConfig &config) {
+	vk::PipelineLayoutCreateInfo createPipelineLayoutCreateInfo(const GraphicsPipelineConfig &config,
+																const std::vector<vk::DescriptorSetLayout>& descriptorSetLayouts) {
 		static vk::PushConstantRange pushConstantRange;
 		
 		const size_t pushConstantSize = config.m_ShaderProgram.getPushConstantSize();
@@ -371,7 +372,7 @@ namespace vkcv
 		
 		vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo(
 				{},
-				(config.m_DescriptorLayouts),
+				(descriptorSetLayouts),
 				(pushConstantRange)
 		);
 		
@@ -427,7 +428,9 @@ namespace vkcv
 		return dynamicStateCreateInfo;
 	}
 
-    GraphicsPipelineHandle GraphicsPipelineManager::createPipeline(const GraphicsPipelineConfig &config, PassManager& passManager) {
+    GraphicsPipelineHandle GraphicsPipelineManager::createPipeline(const GraphicsPipelineConfig &config,
+																   const PassManager& passManager,
+																   const DescriptorManager& descriptorManager) {
         const vk::RenderPass &pass = passManager.getVkPass(config.m_PassHandle);
 
         const bool existsTaskShader     = config.m_ShaderProgram.existsShader(ShaderStage::TASK);
@@ -625,9 +628,15 @@ namespace vkcv
         vk::PipelineDynamicStateCreateInfo dynamicStateCreateInfo =
                 createPipelineDynamicStateCreateInfo(config);
 
+		std::vector<vk::DescriptorSetLayout> descriptorSetLayouts;
+		descriptorSetLayouts.reserve(config.m_DescriptorLayouts.size());
+		for (const auto& handle : config.m_DescriptorLayouts) {
+			descriptorSetLayouts.push_back(descriptorManager.getDescriptorSetLayout(handle).vulkanHandle);
+		}
+		
         // pipeline layout
         vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo =
-                createPipelineLayoutCreateInfo(config);
+                createPipelineLayoutCreateInfo(config, descriptorSetLayouts);
 
         vk::PipelineLayout vkPipelineLayout{};
         if (m_Device.createPipelineLayout(&pipelineLayoutCreateInfo, nullptr, &vkPipelineLayout) != vk::Result::eSuccess) {
diff --git a/src/vkcv/GraphicsPipelineManager.hpp b/src/vkcv/GraphicsPipelineManager.hpp
index 782603ab0e1ffa9bde05fda96c5d2d259eff1953..09900c37760f07d1967aa56a75cfc8b94aa289d5 100644
--- a/src/vkcv/GraphicsPipelineManager.hpp
+++ b/src/vkcv/GraphicsPipelineManager.hpp
@@ -13,6 +13,7 @@
 #include "vkcv/Handles.hpp"
 #include "vkcv/GraphicsPipelineConfig.hpp"
 #include "PassManager.hpp"
+#include "DescriptorManager.hpp"
 
 namespace vkcv
 {
@@ -36,9 +37,12 @@ namespace vkcv
          * On application level it is necessary first to fill a PipelineConfig Struct.
          * @param config Hands over all needed information for pipeline creation.
          * @param passManager Hands over the corresponding render pass.
+         * @param descriptorManager Hands over the corresponding descriptor set layouts
          * @return A Handler to the created Graphics Pipeline Object.
          */
-		GraphicsPipelineHandle createPipeline(const GraphicsPipelineConfig &config, PassManager& passManager);
+		GraphicsPipelineHandle createPipeline(const GraphicsPipelineConfig &config,
+											  const PassManager& passManager,
+											  const DescriptorManager& descriptorManager);
 
         /**
          * Returns a vk::Pipeline object by handle.