diff --git a/include/vkcv/BufferManager.hpp b/include/vkcv/BufferManager.hpp
index c66e66ed7003842dd20ea756f2abfc7be1cdc0c8..3ac685b06068c4581202f5371f8dafab5445ecf1 100644
--- a/include/vkcv/BufferManager.hpp
+++ b/include/vkcv/BufferManager.hpp
@@ -13,6 +13,10 @@
 
 namespace vkcv
 {
+	
+	/**
+	 * @brief Enum class to specify types of buffers.
+	 */
 	enum class BufferType {
 		INDEX,
 		VERTEX,
@@ -22,6 +26,9 @@ namespace vkcv
 		INDIRECT
 	};
 	
+	/**
+	 * @brief Enum class to specify types of buffer memory.
+	 */
 	enum class BufferMemoryType {
 		DEVICE_LOCAL,
 		HOST_VISIBLE
diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index 6907d68f5559ebbf337d29a95de9b032802583ba..6505599489f405d135d33ce1c4aeeba295e2176a 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -46,6 +46,9 @@ namespace vkcv
 	class WindowManager;
 	class SwapchainManager;
 
+	/**
+	 * @brief Structure to store details about a queue submission.
+	 */
 	struct SubmitInfo {
 		QueueType queueType;
 		std::vector<vk::Semaphore> waitSemaphores;
diff --git a/include/vkcv/DrawcallRecording.hpp b/include/vkcv/DrawcallRecording.hpp
index abcd8d6f95c417289935a5850b850758b4fea38d..76b94dc8b4f8595d98e87920329eb616d703f0db 100644
--- a/include/vkcv/DrawcallRecording.hpp
+++ b/include/vkcv/DrawcallRecording.hpp
@@ -84,9 +84,7 @@ namespace vkcv {
         std::vector<DescriptorSetUsage> descriptorSets;
         uint32_t instanceCount;
     };
-
-    void InitMeshShaderDrawFunctions(vk::Device device);
-
+	
 	/**
 	 * @brief Structure to store details for a mesh shader drawcall.
 	 */
diff --git a/src/vkcv/BufferManager.cpp b/src/vkcv/BufferManager.cpp
index 52915ff04800ef3b6cb1e6caefdb3f25f6568aac..2d29719f4a34d305f90c1b76db6b56277eb3def5 100644
--- a/src/vkcv/BufferManager.cpp
+++ b/src/vkcv/BufferManager.cpp
@@ -111,6 +111,9 @@ namespace vkcv {
 		return BufferHandle(id, [&](uint64_t id) { destroyBufferById(id); });
 	}
 	
+	/**
+	 * @brief Structure to store details required for a staging process.
+	 */
 	struct StagingStepInfo {
 		const void* data;
 		size_t size;
diff --git a/src/vkcv/ComputePipelineManager.hpp b/src/vkcv/ComputePipelineManager.hpp
index acb50bbdef99d037374c140836d25bb161132b2b..4c186ac7508a0cb8ff98d691d25cd8c3b1726f47 100644
--- a/src/vkcv/ComputePipelineManager.hpp
+++ b/src/vkcv/ComputePipelineManager.hpp
@@ -16,6 +16,9 @@
 namespace vkcv
 {
 
+	/**
+	 * @brief Class to manage compute pipelines.
+	 */
     class ComputePipelineManager
     {
     public:
diff --git a/src/vkcv/Context.cpp b/src/vkcv/Context.cpp
index f6358c41d3052642c705e9ccf48a4be430fb599d..4a5b314f0bca5aa7af820c7bc876b954bf1ca0f3 100644
--- a/src/vkcv/Context.cpp
+++ b/src/vkcv/Context.cpp
@@ -495,10 +495,6 @@ namespace vkcv
 		deviceCreateInfo.setPNext(&(featureManager.getFeatures()));
 		
 		vk::Device device = physicalDevice.createDevice(deviceCreateInfo);
-
-		if (featureManager.isExtensionActive(VK_NV_MESH_SHADER_EXTENSION_NAME)) {
-			InitMeshShaderDrawFunctions(device);
-		}
 		
 		QueueManager queueManager = QueueManager::create(
 				device,
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index 417157ab37bcded7deca5c092fd96a828a4de7e6..df3170d1524b69d23a67c91d1ec94829bcc08c8c 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -1071,7 +1071,7 @@ namespace vkcv
 	
 	static void setDebugObjectLabel(const vk::Device& device, const vk::ObjectType& type,
 									uint64_t handle, const std::string& label) {
-#ifndef VULKAN_DEBUG_LABELS
+#ifdef VULKAN_DEBUG_LABELS
 		static PFN_vkSetDebugUtilsObjectNameEXT setDebugLabel = reinterpret_cast<PFN_vkSetDebugUtilsObjectNameEXT>(
 				device.getProcAddr("vkSetDebugUtilsObjectNameEXT")
 		);
diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp
index 526bea60764bdc36ea79ce1964f8fdf1f72b3484..d12a5287e2317bdfc21fb15872681138b4f0d64f 100644
--- a/src/vkcv/DescriptorManager.cpp
+++ b/src/vkcv/DescriptorManager.cpp
@@ -111,10 +111,10 @@ namespace vkcv
         return DescriptorSetLayoutHandle(id, [&](uint64_t id) { destroyDescriptorSetLayoutById(id); });
     }
 
-    DescriptorSetHandle DescriptorManager::createDescriptorSet(const DescriptorSetLayoutHandle &setLayoutHandle)
+    DescriptorSetHandle DescriptorManager::createDescriptorSet(const DescriptorSetLayoutHandle &layout)
     {
         //create and allocate the set based on the layout provided
-        DescriptorSetLayout setLayout = m_DescriptorSetLayouts[setLayoutHandle.getId()];
+        DescriptorSetLayout setLayout = m_DescriptorSetLayouts[layout.getId()];
         vk::DescriptorSet vulkanHandle;
         vk::DescriptorSetAllocateInfo allocInfo(m_Pools.back(), 1, &setLayout.vulkanHandle);
 
@@ -151,10 +151,13 @@ namespace vkcv
 	
 		size_t poolIndex = (m_Pools.size() - 1);
         const uint64_t id = m_DescriptorSets.size();
-        m_DescriptorSets.push_back({vulkanHandle, setLayoutHandle, poolIndex});
+        m_DescriptorSets.push_back({ vulkanHandle, layout, poolIndex });
         return DescriptorSetHandle(id, [&](uint64_t id) { destroyDescriptorSetById(id); });
     }
     
+	/**
+	 * @brief Structure to store details to write to a descriptor set.
+	 */
     struct WriteDescriptorSetInfo {
 		size_t imageInfoIndex;
 		size_t bufferInfoIndex;
diff --git a/src/vkcv/DescriptorManager.hpp b/src/vkcv/DescriptorManager.hpp
index 4f8bff93a3f780fbbbe732289073fd691891201c..c996e8c94f6dbb6f45f173f60f59f344a9a58623 100644
--- a/src/vkcv/DescriptorManager.hpp
+++ b/src/vkcv/DescriptorManager.hpp
@@ -17,24 +17,60 @@
 
 namespace vkcv
 {
+	
+	/**
+	 * @brief Class to manage descriptor sets and descriptor set layouts.
+	 */
 	class DescriptorManager
 	{
 	public:
+		/**
+		 * @brief Constructor of the descriptor manager
+		 *
+		 * @param[in,out] device Vulkan device
+		 */
 	    explicit DescriptorManager(vk::Device device) noexcept;
+		
+		/**
+		 * @brief Destructor of the descriptor manager
+		 */
 	    ~DescriptorManager() noexcept;
 
+		/**
+		 * @brief Creates a descriptor set layout with given descriptor bindings
+		 * or returns a matching handle.
+		 *
+		 * @param[in] bindings Descriptor bindings
+		 * @return Handle of descriptor set layout
+		 */
 	    DescriptorSetLayoutHandle createDescriptorSetLayout(const DescriptorBindings &bindings);
-        DescriptorSetHandle createDescriptorSet(const DescriptorSetLayoutHandle &setLayoutHandle);
+		
+		/**
+		 * @brief Creates a descriptor set using a given descriptor set layout.
+		 *
+		 * @param[in] layout Handle of descriptor set layout
+		 * @return Handle of descriptor set
+		 */
+        DescriptorSetHandle createDescriptorSet(const DescriptorSetLayoutHandle &layout);
 
-		void writeDescriptorSet(
-			const DescriptorSetHandle	&handle,
-			const DescriptorWrites  &writes,
-			const ImageManager      &imageManager,
-			const BufferManager     &bufferManager,
-			const SamplerManager    &samplerManager);
+		/**
+		 * @brief Writes to a descriptor set using writes and all required managers.
+		 *
+		 * @param[in] handle Handle of descriptor set
+		 * @param[in] writes Descriptor set writes
+		 * @param[in] imageManager Image manager
+		 * @param[in] bufferManager Buffer manager
+		 * @param[in] samplerManager Sampler manager
+		 */
+		void writeDescriptorSet(const DescriptorSetHandle &handle,
+								const DescriptorWrites &writes,
+								const ImageManager &imageManager,
+								const BufferManager &bufferManager,
+								const SamplerManager &samplerManager);
 
 		[[nodiscard]]
 		DescriptorSetLayout getDescriptorSetLayout(const DescriptorSetLayoutHandle handle) const;
+		
 		[[nodiscard]]
 		DescriptorSet getDescriptorSet(const DescriptorSetHandle handle) const;
 
@@ -80,4 +116,5 @@ namespace vkcv
 		vk::DescriptorPool allocateDescriptorPool();
 		
 	};
+	
 }
\ No newline at end of file
diff --git a/src/vkcv/DrawcallRecording.cpp b/src/vkcv/DrawcallRecording.cpp
index ce7c2e600147c19859e570e1c3d1483511e323fd..eef87ca65d5f461f1c37b678634cf3e6f8973397 100644
--- a/src/vkcv/DrawcallRecording.cpp
+++ b/src/vkcv/DrawcallRecording.cpp
@@ -5,20 +5,6 @@
 
 namespace vkcv {
 
-    struct MeshShaderFunctions
-    {
-        PFN_vkCmdDrawMeshTasksNV cmdDrawMeshTasks                           = nullptr;
-        PFN_vkCmdDrawMeshTasksIndirectNV cmdDrawMeshTasksIndirect           = nullptr;
-        PFN_vkCmdDrawMeshTasksIndirectCountNV cmdDrawMeshTasksIndirectCount = nullptr;
-    } MeshShaderFunctions;
-
-    void InitMeshShaderDrawFunctions(vk::Device device)
-    {
-        MeshShaderFunctions.cmdDrawMeshTasks = PFN_vkCmdDrawMeshTasksNV(device.getProcAddr("vkCmdDrawMeshTasksNV"));
-        MeshShaderFunctions.cmdDrawMeshTasksIndirect = PFN_vkCmdDrawMeshTasksIndirectNV(device.getProcAddr("vkCmdDrawMeshTasksIndirectNV"));
-        MeshShaderFunctions.cmdDrawMeshTasksIndirectCount = PFN_vkCmdDrawMeshTasksIndirectCountNV (device.getProcAddr( "vkCmdDrawMeshTasksIndirectCountNV"));
-    }
-
     void recordMeshShaderDrawcall(const Core& core,
                                   vk::CommandBuffer cmdBuffer,
                                   vk::PipelineLayout pipelineLayout,
@@ -26,6 +12,14 @@ namespace vkcv {
                                   uint32_t pushConstantOffset,
                                   const MeshShaderDrawcall& drawcall,
                                   uint32_t firstTask) {
+        static PFN_vkCmdDrawMeshTasksNV cmdDrawMeshTasks = reinterpret_cast<PFN_vkCmdDrawMeshTasksNV>(
+                core.getContext().getDevice().getProcAddr("vkCmdDrawMeshTasksNV")
+        );
+	
+		if (!cmdDrawMeshTasks) {
+			vkcv_log(LogLevel::ERROR, "Mesh shader drawcalls are not supported");
+			return;
+		}
 
         for (const auto& descriptorUsage : drawcall.descriptorSets) {
             cmdBuffer.bindDescriptorSets(
@@ -47,7 +41,7 @@ namespace vkcv {
                 pushConstantData.getSizePerDrawcall(),
                 drawcallPushConstantData);
         }
-
-        MeshShaderFunctions.cmdDrawMeshTasks(VkCommandBuffer(cmdBuffer), drawcall.taskCount, firstTask);
+    
+        cmdDrawMeshTasks(VkCommandBuffer(cmdBuffer), drawcall.taskCount, firstTask);
     }
 }
diff --git a/src/vkcv/GraphicsPipelineManager.hpp b/src/vkcv/GraphicsPipelineManager.hpp
index 09900c37760f07d1967aa56a75cfc8b94aa289d5..511dcf47988028617712c191f79bdf1f292a200a 100644
--- a/src/vkcv/GraphicsPipelineManager.hpp
+++ b/src/vkcv/GraphicsPipelineManager.hpp
@@ -17,6 +17,10 @@
 
 namespace vkcv
 {
+	
+	/**
+	 * @brief Class to manage graphics pipelines.
+	 */
     class GraphicsPipelineManager
     {
     public:
@@ -82,4 +86,5 @@ namespace vkcv
         void destroyPipelineById(uint64_t id);
 
     };
+	
 }
diff --git a/src/vkcv/ImageManager.hpp b/src/vkcv/ImageManager.hpp
index 124508d5e36711a13ad49ae289b9de98600e0d6e..aedf726031ef43ac723b93f3dbd1276d92f3f704 100644
--- a/src/vkcv/ImageManager.hpp
+++ b/src/vkcv/ImageManager.hpp
@@ -14,8 +14,19 @@
 
 namespace vkcv {
 	
+	/**
+	 * @brief Determine whether an image format is valid
+	 * for depth buffers.
+	 *
+	 * @param[in] format Image format
+	 * @return True, if the format is usable for depth buffers, otherwise false.
+	 */
 	bool isDepthImageFormat(vk::Format format);
 
+	/**
+	 * @brief Class to manage the creation, destruction, allocation
+	 * and filling of images.
+	 */
 	class ImageManager
 	{
 		friend class Core;
diff --git a/src/vkcv/PassManager.hpp b/src/vkcv/PassManager.hpp
index 661a8b277ecb446c4bbaeeb63560ffde28c31d99..1ef976e0482ea39afad33346068f2a168eac70d8 100644
--- a/src/vkcv/PassManager.hpp
+++ b/src/vkcv/PassManager.hpp
@@ -7,6 +7,10 @@
 
 namespace vkcv
 {
+	
+	/**
+	 * @brief Class to manage the creation and destruction of passes.
+	 */
     class PassManager
     {
     private:
@@ -40,4 +44,5 @@ namespace vkcv
         const PassConfig& getPassConfig(const PassHandle &handle) const;
         
     };
+	
 }
diff --git a/src/vkcv/SamplerManager.hpp b/src/vkcv/SamplerManager.hpp
index 128faa711993ac052cf774a1d31144d19362658f..24d89f0d6af151ff009a2f2bb64953d48a9e7213 100644
--- a/src/vkcv/SamplerManager.hpp
+++ b/src/vkcv/SamplerManager.hpp
@@ -10,6 +10,9 @@ namespace vkcv {
 	
 	class Core;
 	
+	/**
+	 * @brief Class to manage the creation and destruction of samplers.
+	 */
 	class SamplerManager {
 		friend class Core;
 	private:
diff --git a/src/vkcv/SwapchainManager.hpp b/src/vkcv/SwapchainManager.hpp
index 39fe8cf68254683fc6fdf53cf4cb181839538d7b..285641db25f98d1e3dd8d8ed1375fa27e7db5708 100644
--- a/src/vkcv/SwapchainManager.hpp
+++ b/src/vkcv/SwapchainManager.hpp
@@ -8,8 +8,13 @@
 #include "vkcv/Handles.hpp"
 
 namespace vkcv {
+	
 	class Core;
-
+	
+	/**
+	 * @brief Class to manage the creation, destruction and
+	 * allocation of swapchains.
+	 */
 	class SwapchainManager {
 		friend class Core;
 
@@ -76,4 +81,5 @@ namespace vkcv {
 		 */
 		std::vector<vk::ImageView> createSwapchainImageViews(SwapchainHandle& handle);
 	};
+	
 }
\ No newline at end of file
diff --git a/src/vkcv/WindowManager.hpp b/src/vkcv/WindowManager.hpp
index cb73fad06ff491d2737212dc09a4d785d5f4d2e9..81658c241174c62359457c04e143accf07253edb 100644
--- a/src/vkcv/WindowManager.hpp
+++ b/src/vkcv/WindowManager.hpp
@@ -9,10 +9,14 @@
 #include "SwapchainManager.hpp"
 
 namespace vkcv {
+	
 	class Context;
 
 	class SwapchainManager;
 
+	/**
+	 * @brief Class to manage the windows of applications.
+	 */
 	class WindowManager {
 		friend class Core;
 
@@ -65,4 +69,5 @@ namespace vkcv {
 		Window &getWindow(const WindowHandle handle) const;
 
 	};
+	
 }
\ No newline at end of file