diff --git a/config/Sources.cmake b/config/Sources.cmake
index d20fa08abd63880f66fb998e5ef3b682db4c4825..cb73f57c2ca7278765ef0c8d01989c09a445c7b5 100644
--- a/config/Sources.cmake
+++ b/config/Sources.cmake
@@ -55,6 +55,7 @@ set(vkcv_sources
         ${vkcv_source}/vkcv/Framebuffer.cpp
 
 		${vkcv_include}/vkcv/Event.hpp
+
 		${vkcv_source}/vkcv/DescriptorManager.hpp
 		${vkcv_source}/vkcv/DescriptorManager.cpp
 
diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index ec1a239eb2ff37e7672bd6492083ff796e759746..e2fc5c587247a915f5bca345f8077f33ee5d8977 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -61,7 +61,9 @@ namespace vkcv
 
         std::unique_ptr<PassManager> m_PassManager;
         std::unique_ptr<PipelineManager> m_PipelineManager;
+        std::unique_ptr<DescriptorManager> m_DescriptorManager;
         std::unique_ptr<BufferManager> m_BufferManager;
+
 		CommandResources m_CommandResources;
 		SyncResources m_SyncResources;
 		uint32_t m_currentSwapchainImageIndex;
@@ -173,6 +175,7 @@ namespace vkcv
          *   @param setDescriptions
          *   @return
          */
+        [[nodiscard]]
         ResourcesHandle createResourceDescription(const std::vector<DescriptorSet> &descriptorSets);
 
 		/**
diff --git a/include/vkcv/DescriptorConfig.hpp b/include/vkcv/DescriptorConfig.hpp
index 60175a87b8d88578a9e4c7ce006fb47d4cffe9e0..8116259757fe623f97a2814991b226ee27efca50 100644
--- a/include/vkcv/DescriptorConfig.hpp
+++ b/include/vkcv/DescriptorConfig.hpp
@@ -9,6 +9,7 @@ namespace vkcv
     enum class DescriptorType
     {
         UNIFORM_BUFFER,
+        STORAGE_BUFFER,
         SAMPLER,
         IMAGE
     };    
@@ -23,15 +24,12 @@ namespace vkcv
     struct DescriptorBinding
     {
         DescriptorBinding() = delete;
-
         DescriptorBinding(
-            uint32_t p_bindingID,
-            DescriptorType p_descriptorType,
-            uint32_t p_descriptorCount,
-            ShaderStage p_shaderStage
+            DescriptorType descriptorType,
+            uint32_t descriptorCount,
+            ShaderStage shaderStage
         ) noexcept;
 
-        uint32_t bindingID;
         DescriptorType descriptorType;
         uint32_t descriptorCount;
         ShaderStage shaderStage;
@@ -45,12 +43,8 @@ namespace vkcv
     struct DescriptorSet
     {
         DescriptorSet() = delete;
-
-        DescriptorSet(
-            std::vector<DescriptorBinding> p_bindings,
-            uint32_t p_setCount) noexcept;
+        explicit DescriptorSet(std::vector<DescriptorBinding> bindings) noexcept;
 
         std::vector<DescriptorBinding> bindings;
-        uint32_t setCount;
     };
 }
diff --git a/include/vkcv/DescriptorSet.hpp b/include/vkcv/DescriptorSet.hpp
deleted file mode 100644
index 969f3558f7ec2842f26920c0a8c59be86f5d6fc2..0000000000000000000000000000000000000000
--- a/include/vkcv/DescriptorSet.hpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#pragma once
-
-#include <vulkan/vulkan.hpp>
-
-namespace vkcv {
-
-	class DescriptorSet
-	{
-
-	public:
-		DescriptorSet::DescriptorSet();
-		void createDescriptorSets(vk::Device device);
-	private:
-		//std::vector<vk::DescriptorPoolSize> descriptorPoolSizes;
-		//std::vector<vk::DescriptorSetLayoutBinding> descriptorSetLayoutBinding;
-		//vk::DescriptorSetLayout descriptorSetLayout;
-		//vk::DescriptorPool descriptorPool;
-	};
-}
\ No newline at end of file
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index e65818874992637dc6fb09667ffdd288318217e3..07da9506c5546985d4852e5d7d87ecbbcfe5e788 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -95,26 +95,23 @@ int main(int argc, const char** argv) {
 		return EXIT_FAILURE;
 	}
 
-//---------CREATION OF RESOURCES/DESCRIPTORS------------------
 	//just an example
-	//creates 3 descriptor sets with one descriptor each
+	//creates 20 descriptor sets, each containing bindings for 50 uniform buffers, images, and samplers
 	std::vector<vkcv::DescriptorSet> sets;
-	vkcv::DescriptorType typeA = vkcv::DescriptorType::UNIFORM_BUFFER;
-	vkcv::DescriptorType typeB = vkcv::DescriptorType::IMAGE;
-	vkcv::DescriptorType typeC = vkcv::DescriptorType::SAMPLER;
-	std::vector<vkcv::DescriptorType> types = { typeA, typeB, typeC };
-	for (uint32_t i = 0; i < types.size(); i++)
+
+	for (uint32_t i = 0; i < 20; i++)
 	{
-		vkcv::DescriptorBinding bind(i, types[i], static_cast<uint32_t>(1), vkcv::ShaderStage::VERTEX);
+		vkcv::DescriptorBinding uniformBufBinding(vkcv::DescriptorType::UNIFORM_BUFFER, 50, vkcv::ShaderStage::VERTEX);
+        vkcv::DescriptorBinding storageBufBinding(vkcv::DescriptorType::STORAGE_BUFFER, 50, vkcv::ShaderStage::VERTEX);
+        vkcv::DescriptorBinding imageBinding(vkcv::DescriptorType::IMAGE, 50, vkcv::ShaderStage::VERTEX);
+        vkcv::DescriptorBinding samplerBinding(vkcv::DescriptorType::SAMPLER, 50, vkcv::ShaderStage::VERTEX);
 
-		std::vector<vkcv::DescriptorBinding> bindings = { bind };
-		vkcv::DescriptorSet set(bindings, static_cast<uint32_t>(1));
+        vkcv::DescriptorSet set({uniformBufBinding, storageBufBinding, imageBinding, samplerBinding});
 
 		sets.push_back(set);
+        auto resourceHandle = core.createResourceDescription(sets);
+        std::cout << "Resource " << resourceHandle.id << " created." << std::endl;
 	}
-	core.createResourceDescription(sets);
-
-//------------END CREATION OF RESOURCES/DESCRIPTORS------------------
 
 	/*
 	 * BufferHandle triangleVertices = core.createBuffer(vertices);
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index 01aea7c5625ef6f39b8000201dafd3ae88bd836c..fa53b4faa666134bde9230863f78c96e648c9037 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -93,6 +93,7 @@ namespace vkcv
             m_swapchainImageViews(imageViews),
             m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)},
             m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)},
+            m_DescriptorManager(std::make_unique<DescriptorManager>(m_Context.m_Device)),
 			m_BufferManager{std::unique_ptr<BufferManager>(new BufferManager())},
             m_CommandResources(commandResources),
             m_SyncResources(syncResources)
@@ -253,13 +254,8 @@ namespace vkcv
 		}
 	}
 
-
     ResourcesHandle Core::createResourceDescription(const std::vector<DescriptorSet> &descriptorSets)
     {
-        // TODO:
-        //  call DescriptorManager's createResourceDescription
-        //  let it do the actual work! No vulkan stuff here.
-		DescriptorManager descriptorManager = DescriptorManager(m_Context.getDevice());
-        return descriptorManager.createResourceDescription(descriptorSets);
+        return m_DescriptorManager->createResourceDescription(descriptorSets);
     }
 }
diff --git a/src/vkcv/DescriptorConfig.cpp b/src/vkcv/DescriptorConfig.cpp
index de42fe22eb073a78490a85c0eb7f23e421e566a4..f437ab6833edca09f58499b6d74307606bba8999 100644
--- a/src/vkcv/DescriptorConfig.cpp
+++ b/src/vkcv/DescriptorConfig.cpp
@@ -1,25 +1,20 @@
 #include "vkcv/DescriptorConfig.hpp"
 
+#include <utility>
+
 namespace vkcv {
 
     DescriptorBinding::DescriptorBinding(
-        uint32_t p_bindingID,
-        DescriptorType p_descriptorType,
-        uint32_t p_descriptorCount,
-        ShaderStage p_shaderStage
+        DescriptorType descriptorType,
+        uint32_t descriptorCount,
+        ShaderStage shaderStage
     ) noexcept :
-        bindingID{ p_bindingID },
-        descriptorType{ p_descriptorType },
-        descriptorCount{ p_descriptorCount },
-        shaderStage{ p_shaderStage }
+        descriptorType{descriptorType},
+        descriptorCount{descriptorCount},
+        shaderStage{shaderStage}
     {};
 
-    DescriptorSet::DescriptorSet(
-        std::vector<DescriptorBinding> p_bindings,
-        uint32_t p_setCount
-    ) noexcept :
-        bindings{ p_bindings },
-        setCount{ p_setCount }
+    DescriptorSet::DescriptorSet(std::vector<DescriptorBinding> bindings) noexcept :
+        bindings{std::move(bindings)}
     {};
-
-}
\ No newline at end of file
+}
diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp
index 8226c2785eeb7bbcc34de9c55f750cb83d5875b9..bcebb142af2f29c23e77185112cbb83a827e41ba 100644
--- a/src/vkcv/DescriptorManager.cpp
+++ b/src/vkcv/DescriptorManager.cpp
@@ -1,88 +1,124 @@
 #include "DescriptorManager.hpp"
-#include <vkcv/ShaderProgram.hpp>
-
 
 namespace vkcv
 {
+    DescriptorManager::ResourceDescription::ResourceDescription(std::vector<vk::DescriptorSet> sets,
+                                                                std::vector<vk::DescriptorSetLayout> layouts) noexcept :
+    descriptorSets{std::move(sets)},
+    descriptorSetLayouts{std::move(layouts)}
+    {}
     DescriptorManager::DescriptorManager(vk::Device device) noexcept:
-        m_Device{ device }, m_NextDescriptorSetID{ 1 }
+        m_Device{ device }, m_NextResourceDescriptionID{ 1 }
     {
-        m_DescriptorTypes = { DescriptorType::UNIFORM_BUFFER, DescriptorType::SAMPLER, DescriptorType::IMAGE };
-        uint32_t sizesPerType = 1000;
-        uint32_t maxSetsPerPool = 1000;
+        /**
+         * Allocate a set size for the initial pool, namely 1000 units of each descriptor type below.
+         */
+        const std::vector<vk::DescriptorPoolSize> poolSizes = {vk::DescriptorPoolSize(vk::DescriptorType::eSampler, 1000),
+                                                    vk::DescriptorPoolSize(vk::DescriptorType::eSampledImage, 1000),
+                                                    vk::DescriptorPoolSize(vk::DescriptorType::eUniformBuffer, 1000),
+                                                    vk::DescriptorPoolSize(vk::DescriptorType::eStorageBuffer, 1000)};
+
+        vk::DescriptorPoolCreateInfo poolInfo({},
+                                              1000,
+                                              static_cast<uint32_t>(poolSizes.size()),
+                                              poolSizes.data());
+
+        if(m_Device.createDescriptorPool(&poolInfo, nullptr, &m_Pool) != vk::Result::eSuccess)
+        {
+            std::cout << "FAILED TO ALLOCATED DESCRIPTOR POOL." << std::endl;
+            m_Pool = nullptr;
+        };
+    }
 
-        std::vector<vk::DescriptorPoolSize> descriptorPoolSizes;
-        for (int i = 0; i < m_DescriptorTypes.size(); i++) {
-            vk::DescriptorType type = convertDescriptorTypeFlag(m_DescriptorTypes[i]);
-            vk::DescriptorPoolSize poolSize(type, sizesPerType);
-            descriptorPoolSizes.push_back(poolSize);
+    DescriptorManager::~DescriptorManager() noexcept
+    {
+        for(const auto &resource : m_ResourceDescriptions)
+        {
+            for(const auto &layout : resource.descriptorSetLayouts)
+                m_Device.destroyDescriptorSetLayout(layout);
         }
-        vk::DescriptorPoolCreateInfo poolInfo({}, maxSetsPerPool, descriptorPoolSizes);
-        m_Pool = m_Device.createDescriptorPool(poolInfo, nullptr);
+        m_Device.destroy(m_Pool);
     }
 
-    ResourcesHandle DescriptorManager::createResourceDescription(const std::vector<DescriptorSet> &p_descriptorSets) 
+    ResourcesHandle DescriptorManager::createResourceDescription(const std::vector<DescriptorSet> &descriptorSets)
     {
-        ResourceDescription resource{};
+        std::vector<vk::DescriptorSet> vk_sets;
+        std::vector<vk::DescriptorSetLayout> vk_setLayouts;
+
+        for (const auto &set : descriptorSets) {
+            std::vector<vk::DescriptorSetLayoutBinding> setBindings = {};
 
-        for (int i = 0; i < p_descriptorSets.size(); i++) {
-            DescriptorSet set = p_descriptorSets[i];
-            std::vector<vk::DescriptorSetLayoutBinding> setBindings;
-            for (int j = 0; j < set.bindings.size(); j++) {
-                //creates each binding of the set
-                DescriptorBinding binding = set.bindings[j];
-                vk::DescriptorType type = convertDescriptorTypeFlag(binding.descriptorType);
-                vk::ShaderStageFlagBits stage = convertShaderStageFlag(binding.shaderStage);
-                vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding(binding.bindingID, type, binding.descriptorCount, stage);
+            //create each set's binding
+            for (uint32_t j = 0; j < set.bindings.size(); j++) {
+                vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding(
+                        j,
+                        convertDescriptorTypeFlag(set.bindings[j].descriptorType),
+                        set.bindings[j].descriptorCount,
+                        convertShaderStageFlag(set.bindings[j].shaderStage));
                 setBindings.push_back(descriptorSetLayoutBinding);
             }
-            //creates the descriptor set layouts
-            vk::DescriptorSetLayoutCreateInfo descriptorSetLayoutInfo({}, setBindings);
-            vk::DescriptorSetLayout allocLayout = m_Device.createDescriptorSetLayout(descriptorSetLayoutInfo, nullptr);
-            std::vector<vk::DescriptorSetLayout> allocLayouts(set.setCount, allocLayout);
-            //binds the layout to the pool
-            vk::DescriptorSetAllocateInfo allocInfo(m_Pool, allocLayout);
-
-            //creates and allocates the set(s) based on the layout
-            vk::DescriptorSet allocSet;
-            std::vector<vk::DescriptorSet> allocSets(set.setCount, allocSet);
-            m_Device.allocateDescriptorSets(&allocInfo, allocSets.data());
 
-            //inserts the descriptor sets and layouts into the resources (also considers copies of the same sets)
-            resource.descriptorSetLayouts.insert(resource.descriptorSetLayouts.begin(), allocLayouts.begin(), allocLayouts.end());
-            resource.descriptorSets.insert(resource.descriptorSets.end(), allocSets.begin(), allocSets.end());
+            //create the descriptor set's layout from the bindings gathered above
+            vk::DescriptorSetLayoutCreateInfo layoutInfo({}, setBindings);
+            vk::DescriptorSetLayout layout = nullptr;
+            if(m_Device.createDescriptorSetLayout(&layoutInfo, nullptr, &layout) != vk::Result::eSuccess)
+            {
+                std::cout << "FAILED TO CREATE DESCRIPTOR SET LAYOUT" << std::endl;
+                return ResourcesHandle{0};
+            };
+            vk_setLayouts.push_back(layout);
         }
-        m_ResourceDescriptions.push_back(resource);
-        return ResourcesHandle{m_NextDescriptorSetID++};
+        //create and allocate the set(s) based on the layouts that have been gathered above
+        vk_sets.resize(vk_setLayouts.size());
+        vk::DescriptorSetAllocateInfo allocInfo(m_Pool, vk_sets.size(), vk_setLayouts.data());
+        auto result = m_Device.allocateDescriptorSets(&allocInfo, vk_sets.data());
+        if(result != vk::Result::eSuccess)
+        {
+            std::cout << "FAILED TO ALLOCATE DESCRIPTOR SET" << std::endl;
+            std::cout << vk::to_string(result) << std::endl;
+            for(const auto &layout : vk_setLayouts)
+                m_Device.destroy(layout);
+
+            return ResourcesHandle{0};
+        };
+
+        m_ResourceDescriptions.emplace_back(vk_sets, vk_setLayouts);
+        return ResourcesHandle{m_NextResourceDescriptionID++};
     }
 
     vk::DescriptorType DescriptorManager::convertDescriptorTypeFlag(DescriptorType type) {
         switch (type)
         {
-        case DescriptorType::UNIFORM_BUFFER:
-            return vk::DescriptorType::eUniformBuffer;
-        case DescriptorType::SAMPLER:
-            return vk::DescriptorType::eSampler;
-        case DescriptorType::IMAGE:
-            return vk::DescriptorType::eSampledImage;
+            case DescriptorType::UNIFORM_BUFFER:
+                return vk::DescriptorType::eUniformBuffer;
+            case DescriptorType::STORAGE_BUFFER:
+                return vk::DescriptorType::eStorageBuffer;
+            case DescriptorType::SAMPLER:
+                return vk::DescriptorType::eSampler;
+            case DescriptorType::IMAGE:
+                return vk::DescriptorType::eSampledImage;
+            default:
+                return vk::DescriptorType::eUniformBuffer;
         }
     }
 
     vk::ShaderStageFlagBits DescriptorManager::convertShaderStageFlag(ShaderStage stage) {
         switch (stage) 
         {
-        case ShaderStage::VERTEX:
-            return vk::ShaderStageFlagBits::eVertex;
-        case ShaderStage::FRAGMENT:
-            return vk::ShaderStageFlagBits::eFragment;
-        case ShaderStage::TESS_CONTROL:
-            return vk::ShaderStageFlagBits::eTessellationControl;
-        case ShaderStage::TESS_EVAL:
-            return vk::ShaderStageFlagBits::eTessellationControl;
-        case ShaderStage::GEOMETRY:
-            return vk::ShaderStageFlagBits::eGeometry;
-        case ShaderStage::COMPUTE:
-            return vk::ShaderStageFlagBits::eCompute;
+            case ShaderStage::VERTEX:
+                return vk::ShaderStageFlagBits::eVertex;
+            case ShaderStage::FRAGMENT:
+                return vk::ShaderStageFlagBits::eFragment;
+            case ShaderStage::TESS_CONTROL:
+                return vk::ShaderStageFlagBits::eTessellationControl;
+            case ShaderStage::TESS_EVAL:
+                return vk::ShaderStageFlagBits::eTessellationEvaluation;
+            case ShaderStage::GEOMETRY:
+                return vk::ShaderStageFlagBits::eGeometry;
+            case ShaderStage::COMPUTE:
+                return vk::ShaderStageFlagBits::eCompute;
+            default:
+                return vk::ShaderStageFlagBits::eAll;
         }
     }
 
diff --git a/src/vkcv/DescriptorManager.hpp b/src/vkcv/DescriptorManager.hpp
index cb8a0f6597c9a0f13ee52fd94d6f635539f07055..744f557051bee3a6524abcf16822c3faa9c78576 100644
--- a/src/vkcv/DescriptorManager.hpp
+++ b/src/vkcv/DescriptorManager.hpp
@@ -9,7 +9,7 @@ namespace vkcv
 	{
 	public:
 	    explicit DescriptorManager(vk::Device device) noexcept;
-	    ~DescriptorManager() = default;
+	    ~DescriptorManager() noexcept;
 
 		/**
 		* Creates all vk::DescriptorSets and allocates them from the pool. 
@@ -18,12 +18,12 @@ namespace vkcv
 		* @param[in] vector of filled vkcv::DescriptorSet structs
 		* @return index into that objects a resource handle
 		*/
-        ResourcesHandle createResourceDescription(const std::vector<DescriptorSet> & p_descriptorSets);
+        ResourcesHandle createResourceDescription(const std::vector<DescriptorSet> & descriptorSets);
 
 	private:
 		vk::Device m_Device;
         vk::DescriptorPool m_Pool;
-		uint64_t m_NextDescriptorSetID;
+
 
 		/**
 		* Container for all resources requested by the user in one call of createResourceDescription.
@@ -31,6 +31,9 @@ namespace vkcv
 		*/
         struct ResourceDescription
         {
+            ResourceDescription() = delete;
+            ResourceDescription(std::vector<vk::DescriptorSet> sets, std::vector<vk::DescriptorSetLayout> layouts) noexcept;
+
             std::vector<vk::DescriptorSet> descriptorSets;
             std::vector<vk::DescriptorSetLayout> descriptorSetLayouts;
         };
@@ -39,24 +42,20 @@ namespace vkcv
 		* Contains all the resource descriptions that were requested by the user in calls of createResourceDescription.
 		*/
         std::vector<ResourceDescription> m_ResourceDescriptions;
-
-		/**
-		* Contains all the allowed vkcv::DescriptorTypes that were also pre-defined in the DescriptorConfig class.
-		* Allowed types are defined in the constructor of DescriptorManager.
-		*/
-		std::vector<DescriptorType> m_DescriptorTypes;
+        // Counter for the vector above
+        uint64_t m_NextResourceDescriptionID;
 		
 		/**
 		* Converts the flags of the descriptor types from VulkanCV (vkcv) to Vulkan (vk).
 		* @param[in] vkcv flag of the DescriptorType (see DescriptorConfig.hpp)
 		* @return vk flag of the DescriptorType
 		*/
-		vk::DescriptorType convertDescriptorTypeFlag(DescriptorType type);
+		static vk::DescriptorType convertDescriptorTypeFlag(DescriptorType type);
 		/**
 		* Converts the flags of the shader stages from VulkanCV (vkcv) to Vulkan (vk).
 		* @param[in] vkcv flag of the ShaderStage (see ShaderProgram.hpp)
 		* @return vk flag of the ShaderStage
 		*/
-		vk::ShaderStageFlagBits convertShaderStageFlag(ShaderStage stage);
+		static vk::ShaderStageFlagBits convertShaderStageFlag(ShaderStage stage);
 	};
 }
\ No newline at end of file