diff --git a/.gitmodules b/.gitmodules
index e0aaf2d17c340f98ae875f7e0f1238bfe04f7e5d..cfa32fb462987b3e2f4ffec40caaae37b0ed7285 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -22,3 +22,9 @@
 [submodule "modules/gui/lib/imgui"]
 	path = modules/gui/lib/imgui
 	url = https://github.com/ocornut/imgui.git
+[submodule "lib/VulkanMemoryAllocator"]
+	path = lib/VulkanMemoryAllocator
+	url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
+[submodule "lib/VulkanMemoryAllocator-Hpp"]
+	path = lib/VulkanMemoryAllocator-Hpp
+	url = https://github.com/malte-v/VulkanMemoryAllocator-Hpp.git
diff --git a/config/Libraries.cmake b/config/Libraries.cmake
index ec014f84c820abf4988b070d5b733be08c377319..b0684091d59b659c712aeacecd91e200351e0117 100644
--- a/config/Libraries.cmake
+++ b/config/Libraries.cmake
@@ -19,6 +19,7 @@ set(vkcv_config_msg " - Library: ")
 include(${vkcv_config_lib}/GLFW.cmake)    # glfw-x11 / glfw-wayland					# libglfw3-dev
 include(${vkcv_config_lib}/Vulkan.cmake)  # vulkan-intel / vulkan-radeon / nvidia	# libvulkan-dev
 include(${vkcv_config_lib}/SPIRV_Cross.cmake)  # SPIRV-Cross	                    # libspirv_cross_c_shared
+include(${vkcv_config_lib}/VulkanMemoryAllocator.cmake) # VulkanMemoryAllocator
 
 # cleanup of compiler flags
 if (vkcv_flags)
diff --git a/config/lib/GLFW.cmake b/config/lib/GLFW.cmake
index 1b68d8aa97ba59158a7bd805ab2470f554f705aa..9668694de5b6887c163f74b626c71873e3f611f8 100644
--- a/config/lib/GLFW.cmake
+++ b/config/lib/GLFW.cmake
@@ -10,6 +10,7 @@ else()
         add_subdirectory(${vkcv_lib}/glfw)
 
         list(APPEND vkcv_libraries glfw)
+        list(APPEND vkcv_includes ${vkcv_lib_path}/glfw/include)
 
         message(${vkcv_config_msg} " GLFW    -   " ${glfw3_VERSION})
     else()
diff --git a/config/lib/SPIRV_Cross.cmake b/config/lib/SPIRV_Cross.cmake
index 2e705d7d5a006e3851d14d22a57fd667c61c79f5..00ae45527d0f49c5632d71e19509871d437ae691 100644
--- a/config/lib/SPIRV_Cross.cmake
+++ b/config/lib/SPIRV_Cross.cmake
@@ -25,6 +25,7 @@ else()
         add_subdirectory(${vkcv_lib}/SPIRV-Cross)
 
         list(APPEND vkcv_libraries spirv-cross-cpp)
+        list(APPEND vkcv_includes ${vkcv_lib_path}/SPIV-Cross/include)
 
         message(${vkcv_config_msg} " SPIRV Cross    - " ${SPIRV_CROSS_VERSION})
     else()
diff --git a/config/lib/VulkanMemoryAllocator.cmake b/config/lib/VulkanMemoryAllocator.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..5f670ff04633e1747accb8f1598fee028a287168
--- /dev/null
+++ b/config/lib/VulkanMemoryAllocator.cmake
@@ -0,0 +1,22 @@
+
+if (EXISTS "${vkcv_lib_path}/VulkanMemoryAllocator-Hpp")
+	set(VMA_HPP_PATH "${vkcv_lib_path}/VulkanMemoryAllocator-Hpp" CACHE INTERNAL "")
+	
+	set(VMA_RECORDING_ENABLED OFF CACHE INTERNAL "")
+	set(VMA_USE_STL_CONTAINERS OFF CACHE INTERNAL "")
+	set(VMA_STATIC_VULKAN_FUNCTIONS ON CACHE INTERNAL "")
+	set(VMA_DYNAMIC_VULKAN_FUNCTIONS OFF CACHE INTERNAL "")
+	set(VMA_DEBUG_ALWAYS_DEDICATED_MEMORY OFF CACHE INTERNAL "")
+	set(VMA_DEBUG_INITIALIZE_ALLOCATIONS OFF CACHE INTERNAL "")
+	set(VMA_DEBUG_GLOBAL_MUTEX OFF CACHE INTERNAL "")
+	set(VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT OFF CACHE INTERNAL "")
+	
+	add_subdirectory(${vkcv_config_lib}/vma)
+	
+	list(APPEND vkcv_libraries VulkanMemoryAllocator)
+	list(APPEND vkcv_includes ${vkcv_lib_path}/VulkanMemoryAllocator-Hpp)
+	
+	message(${vkcv_config_msg} " VMA     - ")
+else()
+	message(WARNING "VulkanMemoryAllocator is required..! Update the submodules!")
+endif ()
diff --git a/config/lib/vma/CMakeLists.txt b/config/lib/vma/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a2c018f2b4894e5ce8e2851ca10f981e2af36605
--- /dev/null
+++ b/config/lib/vma/CMakeLists.txt
@@ -0,0 +1,59 @@
+cmake_minimum_required(VERSION 3.9)
+
+project(VulkanMemoryAllocator)
+
+find_package(Vulkan REQUIRED)
+
+option(VMA_HPP_PATH "Location of C++ headers" "")
+
+message(STATUS "VMA_BUILD_SAMPLE = ${VMA_BUILD_SAMPLE}")
+message(STATUS "VMA_BUILD_SAMPLE_SHADERS = ${VMA_BUILD_SAMPLE_SHADERS}")
+message(STATUS "VMA_BUILD_REPLAY = ${VMA_BUILD_REPLAY}")
+
+option(VMA_RECORDING_ENABLED "Enable VMA memory recording for debugging" OFF)
+option(VMA_USE_STL_CONTAINERS "Use C++ STL containers instead of VMA's containers" OFF)
+option(VMA_STATIC_VULKAN_FUNCTIONS "Link statically with Vulkan API" OFF)
+option(VMA_DYNAMIC_VULKAN_FUNCTIONS "Fetch pointers to Vulkan functions internally (no static linking)" ON)
+option(VMA_DEBUG_ALWAYS_DEDICATED_MEMORY "Every allocation will have its own memory block" OFF)
+option(VMA_DEBUG_INITIALIZE_ALLOCATIONS "Automatically fill new allocations and destroyed allocations with some bit pattern" OFF)
+option(VMA_DEBUG_GLOBAL_MUTEX "Enable single mutex protecting all entry calls to the library" OFF)
+option(VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT "Never exceed VkPhysicalDeviceLimits::maxMemoryAllocationCount and return error" OFF)
+
+message(STATUS "VMA_RECORDING_ENABLED = ${VMA_RECORDING_ENABLED}")
+message(STATUS "VMA_USE_STL_CONTAINERS = ${VMA_USE_STL_CONTAINERS}")
+message(STATUS "VMA_DYNAMIC_VULKAN_FUNCTIONS = ${VMA_DYNAMIC_VULKAN_FUNCTIONS}")
+message(STATUS "VMA_DEBUG_ALWAYS_DEDICATED_MEMORY = ${VMA_DEBUG_ALWAYS_DEDICATED_MEMORY}")
+message(STATUS "VMA_DEBUG_INITIALIZE_ALLOCATIONS = ${VMA_DEBUG_INITIALIZE_ALLOCATIONS}")
+message(STATUS "VMA_DEBUG_GLOBAL_MUTEX = ${VMA_DEBUG_GLOBAL_MUTEX}")
+message(STATUS "VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT = ${VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT}")
+
+add_library(VulkanMemoryAllocator vma.cpp)
+
+set_target_properties(
+		VulkanMemoryAllocator PROPERTIES
+		
+		CXX_EXTENSIONS OFF
+		# Use C++14
+		CXX_STANDARD 14
+		CXX_STANDARD_REQUIRED ON
+)
+
+target_include_directories(VulkanMemoryAllocator PUBLIC ${VMA_HPP_PATH})
+
+# Only link to Vulkan if static linking is used
+if (NOT ${VMA_DYNAMIC_VULKAN_FUNCTIONS})
+	target_link_libraries(VulkanMemoryAllocator PUBLIC Vulkan::Vulkan)
+endif()
+
+target_compile_definitions(
+		VulkanMemoryAllocator
+		
+		PUBLIC
+		VMA_USE_STL_CONTAINERS=$<BOOL:${VMA_USE_STL_CONTAINERS}>
+		VMA_DYNAMIC_VULKAN_FUNCTIONS=$<BOOL:${VMA_DYNAMIC_VULKAN_FUNCTIONS}>
+		VMA_DEBUG_ALWAYS_DEDICATED_MEMORY=$<BOOL:${VMA_DEBUG_ALWAYS_DEDICATED_MEMORY}>
+		VMA_DEBUG_INITIALIZE_ALLOCATIONS=$<BOOL:${VMA_DEBUG_INITIALIZE_ALLOCATIONS}>
+		VMA_DEBUG_GLOBAL_MUTEX=$<BOOL:${VMA_DEBUG_GLOBAL_MUTEX}>
+		VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT=$<BOOL:${VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT}>
+		VMA_RECORDING_ENABLED=$<BOOL:${VMA_RECORDING_ENABLED}>
+)
diff --git a/config/lib/vma/vma.cpp b/config/lib/vma/vma.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0928b552c10e23914054c44b8de43df722aa2cf0
--- /dev/null
+++ b/config/lib/vma/vma.cpp
@@ -0,0 +1,7 @@
+
+#ifndef NDEBUG
+#define _DEBUG
+#endif
+
+#define VMA_IMPLEMENTATION
+#include "vk_mem_alloc.hpp"
diff --git a/include/vkcv/BufferManager.hpp b/include/vkcv/BufferManager.hpp
index 9eb80d70862a79a01593e6fe4c3aabe98d253ac8..c7f32d9f134108bafa87ff493bca4e113d53003a 100644
--- a/include/vkcv/BufferManager.hpp
+++ b/include/vkcv/BufferManager.hpp
@@ -2,6 +2,7 @@
 
 #include <vector>
 #include <vulkan/vulkan.hpp>
+#include <vk_mem_alloc.hpp>
 
 #include "Handles.hpp"
 
@@ -30,9 +31,8 @@ namespace vkcv
 		struct Buffer
 		{
 			vk::Buffer m_handle;
-			vk::DeviceMemory m_memory;
+			vma::Allocation m_allocation;
 			size_t m_size = 0;
-			void* m_mapped = nullptr;
 			bool m_mappable = false;
 		};
 		
diff --git a/include/vkcv/Context.hpp b/include/vkcv/Context.hpp
index 1c01a6134ba1642b3a130a7a4d3d299cc3f7b875..2ecd9203701510837f49d10c1879efd4890145e9 100644
--- a/include/vkcv/Context.hpp
+++ b/include/vkcv/Context.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <vulkan/vulkan.hpp>
+#include <vk_mem_alloc.hpp>
 
 #include "QueueManager.hpp"
 
@@ -32,6 +33,9 @@ namespace vkcv
         
         [[nodiscard]]
         const QueueManager& getQueueManager() const;
+	
+        [[nodiscard]]
+		const vma::Allocator& getAllocator() const;
         
         static Context create(const char *applicationName,
 							  uint32_t applicationVersion,
@@ -47,11 +51,14 @@ namespace vkcv
          * @param physicalDevice Vulkan-PhysicalDevice
          * @param device Vulkan-Device
          */
-        Context(vk::Instance instance, vk::PhysicalDevice physicalDevice, vk::Device device, QueueManager&& queueManager) noexcept;
+        Context(vk::Instance instance, vk::PhysicalDevice physicalDevice, vk::Device device,
+				QueueManager&& queueManager, vma::Allocator&& allocator) noexcept;
         
         vk::Instance        m_Instance;
         vk::PhysicalDevice  m_PhysicalDevice;
         vk::Device          m_Device;
 		QueueManager		m_QueueManager;
+		vma::Allocator 		m_Allocator;
+		
     };
 }
diff --git a/lib/VulkanMemoryAllocator-Hpp b/lib/VulkanMemoryAllocator-Hpp
new file mode 160000
index 0000000000000000000000000000000000000000..eae6e8d3bd4593e0d7071c85fba2a8f33fbe5dab
--- /dev/null
+++ b/lib/VulkanMemoryAllocator-Hpp
@@ -0,0 +1 @@
+Subproject commit eae6e8d3bd4593e0d7071c85fba2a8f33fbe5dab
diff --git a/projects/first_mesh/CMakeLists.txt b/projects/first_mesh/CMakeLists.txt
index eb0f028db38707272f9fbcf61662633f2868eedc..6455e75d88eee276fb89b9f7a1b3462fcbc54da2 100644
--- a/projects/first_mesh/CMakeLists.txt
+++ b/projects/first_mesh/CMakeLists.txt
@@ -22,7 +22,7 @@ if(MSVC)
 endif()
 
 # including headers of dependencies and the VkCV framework
-target_include_directories(first_mesh SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include})
+target_include_directories(first_mesh SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_shader_compiler_include})
 
 # linking with libraries from all dependencies and the VkCV framework
-target_link_libraries(first_mesh vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera)
+target_link_libraries(first_mesh vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_shader_compiler)
diff --git a/projects/first_mesh/resources/shaders/compile.bat b/projects/first_mesh/resources/shaders/compile.bat
deleted file mode 100644
index b4521235c40fe5fb163bab874560c2f219b7517f..0000000000000000000000000000000000000000
--- a/projects/first_mesh/resources/shaders/compile.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-%VULKAN_SDK%\Bin32\glslc.exe shader.vert -o vert.spv
-%VULKAN_SDK%\Bin32\glslc.exe shader.frag -o frag.spv
-pause
\ No newline at end of file
diff --git a/projects/first_mesh/resources/shaders/frag.spv b/projects/first_mesh/resources/shaders/frag.spv
deleted file mode 100644
index 087e4e22fb2fcec27d99b3ff2aa1a705fe755796..0000000000000000000000000000000000000000
Binary files a/projects/first_mesh/resources/shaders/frag.spv and /dev/null differ
diff --git a/projects/first_mesh/resources/shaders/vert.spv b/projects/first_mesh/resources/shaders/vert.spv
deleted file mode 100644
index 374c023e14b351eb43cbcda5951cbb8b3d6f96a1..0000000000000000000000000000000000000000
Binary files a/projects/first_mesh/resources/shaders/vert.spv and /dev/null differ
diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp
index 44a370be228be32f2e9d95685bb5297401605945..731d3e56975ff0cd2d8e6d503a19d56de1b922fe 100644
--- a/projects/first_mesh/src/main.cpp
+++ b/projects/first_mesh/src/main.cpp
@@ -4,6 +4,7 @@
 #include <vkcv/camera/CameraManager.hpp>
 #include <chrono>
 #include <vkcv/asset/asset_loader.hpp>
+#include <vkcv/shader/GLSLCompiler.hpp>
 
 int main(int argc, const char** argv) {
 	const char* applicationName = "First Mesh";
@@ -77,10 +78,19 @@ int main(int argc, const char** argv) {
 		return EXIT_FAILURE;
 	}
 
-	vkcv::ShaderProgram firstMeshProgram{};
-    firstMeshProgram.addShader(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/vert.spv"));
-    firstMeshProgram.addShader(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/frag.spv"));
+	vkcv::ShaderProgram firstMeshProgram;
+	vkcv::shader::GLSLCompiler compiler;
 	
+	compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/shader.vert"),
+					 [&firstMeshProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
+		firstMeshProgram.addShader(shaderStage, path);
+	});
+	
+	compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/shader.frag"),
+					 [&firstMeshProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
+		firstMeshProgram.addShader(shaderStage, path);
+	});
+ 
 	auto& attributes = mesh.vertexGroups[0].vertexBuffer.attributes;
 
 	
diff --git a/projects/first_scene/CMakeLists.txt b/projects/first_scene/CMakeLists.txt
index 467663dcb916da78d0625a33c6c88a1af3403af7..ba2f7b1a7ae4845a12b9701269361a0a3f8affb7 100644
--- a/projects/first_scene/CMakeLists.txt
+++ b/projects/first_scene/CMakeLists.txt
@@ -22,7 +22,7 @@ if(MSVC)
 endif()
 
 # including headers of dependencies and the VkCV framework
-target_include_directories(first_scene SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_scene_include})
+target_include_directories(first_scene SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_scene_include} ${vkcv_shader_compiler_include})
 
 # linking with libraries from all dependencies and the VkCV framework
-target_link_libraries(first_scene vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_scene)
+target_link_libraries(first_scene vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_scene vkcv_shader_compiler)
diff --git a/projects/first_scene/resources/shaders/compile.bat b/projects/first_scene/resources/shaders/compile.bat
deleted file mode 100644
index b4521235c40fe5fb163bab874560c2f219b7517f..0000000000000000000000000000000000000000
--- a/projects/first_scene/resources/shaders/compile.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-%VULKAN_SDK%\Bin32\glslc.exe shader.vert -o vert.spv
-%VULKAN_SDK%\Bin32\glslc.exe shader.frag -o frag.spv
-pause
\ No newline at end of file
diff --git a/projects/first_scene/resources/shaders/frag.spv b/projects/first_scene/resources/shaders/frag.spv
deleted file mode 100644
index 087e4e22fb2fcec27d99b3ff2aa1a705fe755796..0000000000000000000000000000000000000000
Binary files a/projects/first_scene/resources/shaders/frag.spv and /dev/null differ
diff --git a/projects/first_scene/resources/shaders/vert.spv b/projects/first_scene/resources/shaders/vert.spv
deleted file mode 100644
index 374c023e14b351eb43cbcda5951cbb8b3d6f96a1..0000000000000000000000000000000000000000
Binary files a/projects/first_scene/resources/shaders/vert.spv and /dev/null differ
diff --git a/projects/first_scene/src/main.cpp b/projects/first_scene/src/main.cpp
index 486b21343926e1b922b73ba8ffb29428de6ea9a7..527eba8c3a1e020e14d92f5d305e2ddced936333 100644
--- a/projects/first_scene/src/main.cpp
+++ b/projects/first_scene/src/main.cpp
@@ -4,11 +4,9 @@
 #include <vkcv/camera/CameraManager.hpp>
 #include <chrono>
 #include <vkcv/asset/asset_loader.hpp>
-#include <vkcv/Logger.hpp>
+#include <vkcv/shader/GLSLCompiler.hpp>
 #include <vkcv/scene/Scene.hpp>
 
-
-
 int main(int argc, const char** argv) {
 	const char* applicationName = "First Scene";
 
@@ -64,9 +62,18 @@ int main(int argc, const char** argv) {
 		return EXIT_FAILURE;
 	}
 
-	vkcv::ShaderProgram sceneShaderProgram{};
-	sceneShaderProgram.addShader(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/vert.spv"));
-	sceneShaderProgram.addShader(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/frag.spv"));
+	vkcv::ShaderProgram sceneShaderProgram;
+	vkcv::shader::GLSLCompiler compiler;
+	
+	compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/shader.vert"),
+					 [&sceneShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
+		sceneShaderProgram.addShader(shaderStage, path);
+	});
+	
+	compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/shader.frag"),
+					 [&sceneShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
+		sceneShaderProgram.addShader(shaderStage, path);
+	});
 
 	const std::vector<vkcv::VertexAttachment> vertexAttachments = sceneShaderProgram.getVertexAttachments();
 	std::vector<vkcv::VertexBinding> bindings;
diff --git a/projects/first_triangle/shaders/comp.spv b/projects/first_triangle/shaders/comp.spv
deleted file mode 100644
index b414e36b2bea66dab00746298e536d029091e0fd..0000000000000000000000000000000000000000
Binary files a/projects/first_triangle/shaders/comp.spv and /dev/null differ
diff --git a/projects/first_triangle/shaders/compile.bat b/projects/first_triangle/shaders/compile.bat
deleted file mode 100644
index 17743a7c49cdfc6e091c43a42a0adb755a731682..0000000000000000000000000000000000000000
--- a/projects/first_triangle/shaders/compile.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-%VULKAN_SDK%\Bin32\glslc.exe shader.vert -o vert.spv
-%VULKAN_SDK%\Bin32\glslc.exe shader.frag -o frag.spv
-%VULKAN_SDK%\Bin32\glslc.exe shader.comp -o comp.spv
-pause
\ No newline at end of file
diff --git a/projects/first_triangle/shaders/frag.spv b/projects/first_triangle/shaders/frag.spv
deleted file mode 100644
index cb13e606fc0041e24ff6a63c0ec7dcca466732aa..0000000000000000000000000000000000000000
Binary files a/projects/first_triangle/shaders/frag.spv and /dev/null differ
diff --git a/projects/first_triangle/shaders/shader.comp b/projects/first_triangle/shaders/shader.comp
deleted file mode 100644
index fad6cd0815f2f09bf92dcc3171e2e3723f5466df..0000000000000000000000000000000000000000
--- a/projects/first_triangle/shaders/shader.comp
+++ /dev/null
@@ -1,25 +0,0 @@
-#version 440
-
-layout(std430, binding = 0) buffer testBuffer
-{ 
-    float test1[10];
-    float test2[10];
-    float test3[10];
-};
-
-layout( push_constant ) uniform constants{
-    float pushConstant;
-};
-
-layout(local_size_x = 5) in;
-
-void main(){
-
-    if(gl_GlobalInvocationID.x >= 10){
-        return;
-    }
-
-    test1[gl_GlobalInvocationID.x] = gl_GlobalInvocationID.x;
-    test2[gl_GlobalInvocationID.x] = 69;  // nice!
-    test3[gl_GlobalInvocationID.x] = pushConstant;    
-}
\ No newline at end of file
diff --git a/projects/first_triangle/shaders/vert.spv b/projects/first_triangle/shaders/vert.spv
deleted file mode 100644
index 03af5758ffff1b5b6505fe98b02044849026832d..0000000000000000000000000000000000000000
Binary files a/projects/first_triangle/shaders/vert.spv and /dev/null differ
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index a69f9bc755f9cfa3a75d0a51dd242876aedabf79..253efad491e6e320ba5e5e8b270b187e2e79da82 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -2,10 +2,8 @@
 #include <vkcv/Core.hpp>
 #include <GLFW/glfw3.h>
 #include <vkcv/camera/CameraManager.hpp>
-#include <chrono>
-
 #include <vkcv/shader/GLSLCompiler.hpp>
-#include <vkcv/gui/GUI.hpp>
+#include <chrono>
 
 int main(int argc, const char** argv) {
 	const char* applicationName = "First Triangle";
@@ -49,7 +47,7 @@ int main(int argc, const char** argv) {
 		return EXIT_FAILURE;
 	}
 
-	vkcv::ShaderProgram triangleShaderProgram{};
+	vkcv::ShaderProgram triangleShaderProgram;
 	vkcv::shader::GLSLCompiler compiler;
 	
 	compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("shaders/shader.vert"),
diff --git a/src/vkcv/BufferManager.cpp b/src/vkcv/BufferManager.cpp
index aec96411c5d9e07f200b24fbdcf9fa69e2af53d5..cfa233290b89702f196ed97c706254e002a0551b 100644
--- a/src/vkcv/BufferManager.cpp
+++ b/src/vkcv/BufferManager.cpp
@@ -28,32 +28,6 @@ namespace vkcv {
 		}
 	}
 	
-	/**
-	 * @brief searches memory type index for buffer allocation, combines requirements of buffer and application
-	 * @param physicalMemoryProperties Memory Properties of physical device
-	 * @param typeBits Bit field for suitable memory types
-	 * @param requirements Property flags that are required
-	 * @return memory type index for Buffer
-	 */
-	uint32_t searchBufferMemoryType(const vk::PhysicalDeviceMemoryProperties& physicalMemoryProperties, uint32_t typeBits, vk::MemoryPropertyFlags requirements) {
-		const uint32_t memoryCount = physicalMemoryProperties.memoryTypeCount;
-		for (uint32_t memoryIndex = 0; memoryIndex < memoryCount; ++memoryIndex) {
-			const uint32_t memoryTypeBits = (1 << memoryIndex);
-			const bool isRequiredMemoryType = typeBits & memoryTypeBits;
-
-			const vk::MemoryPropertyFlags properties =
-				physicalMemoryProperties.memoryTypes[memoryIndex].propertyFlags;
-			const bool hasRequiredProperties =
-				(properties & requirements) == requirements;
-
-			if (isRequiredMemoryType && hasRequiredProperties)
-				return static_cast<int32_t>(memoryIndex);
-		}
-
-		// failed to find memory type
-		return -1;
-	}
-	
 	BufferHandle BufferManager::createBuffer(BufferType type, size_t size, BufferMemoryType memoryType) {
 		vk::BufferCreateFlags createFlags;
 		vk::BufferUsageFlags usageFlags;
@@ -83,43 +57,48 @@ namespace vkcv {
 			usageFlags |= vk::BufferUsageFlagBits::eTransferDst;
 		}
 		
-		const vk::Device& device = m_core->getContext().getDevice();
-		
-		vk::Buffer buffer = device.createBuffer(
-				vk::BufferCreateInfo(createFlags, size, usageFlags)
-		);
-		
-		const vk::MemoryRequirements requirements = device.getBufferMemoryRequirements(buffer);
-		const vk::PhysicalDevice& physicalDevice = m_core->getContext().getPhysicalDevice();
+		const vma::Allocator& allocator = m_core->getContext().getAllocator();
 		
 		vk::MemoryPropertyFlags memoryTypeFlags;
+		vma::MemoryUsage memoryUsage;
 		bool mappable = false;
 		
 		switch (memoryType) {
 			case BufferMemoryType::DEVICE_LOCAL:
 				memoryTypeFlags = vk::MemoryPropertyFlagBits::eDeviceLocal;
+				memoryUsage = vma::MemoryUsage::eGpuOnly;
+				mappable = false;
 				break;
 			case BufferMemoryType::HOST_VISIBLE:
 				memoryTypeFlags = vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent;
+				memoryUsage = vma::MemoryUsage::eCpuOnly;
 				mappable = true;
 				break;
 			default:
-				// TODO: maybe an issue
+				vkcv_log(LogLevel::WARNING, "Unknown buffer memory type");
+				memoryUsage = vma::MemoryUsage::eUnknown;
+				mappable = false;
 				break;
 		}
 		
-		const uint32_t memoryTypeIndex = searchBufferMemoryType(
-				physicalDevice.getMemoryProperties(),
-				requirements.memoryTypeBits,
-				memoryTypeFlags
+		auto bufferAllocation = allocator.createBuffer(
+				vk::BufferCreateInfo(createFlags, size, usageFlags),
+				vma::AllocationCreateInfo(
+						vma::AllocationCreateFlags(),
+						memoryUsage,
+						memoryTypeFlags,
+						memoryTypeFlags,
+						0,
+						vma::Pool(),
+						nullptr
+				)
 		);
 		
-		vk::DeviceMemory memory = device.allocateMemory(vk::MemoryAllocateInfo(requirements.size, memoryTypeIndex));
-		
-		device.bindBufferMemory(buffer, memory, 0);
+		vk::Buffer buffer = bufferAllocation.first;
+		vma::Allocation allocation = bufferAllocation.second;
 		
 		const uint64_t id = m_buffers.size();
-		m_buffers.push_back({ buffer, memory, size, nullptr, mappable });
+		m_buffers.push_back({ buffer, allocation, size, mappable });
 		return BufferHandle(id, [&](uint64_t id) { destroyBufferById(id); });
 	}
 	
@@ -130,7 +109,7 @@ namespace vkcv {
 		
 		vk::Buffer buffer;
 		vk::Buffer stagingBuffer;
-		vk::DeviceMemory stagingMemory;
+		vma::Allocation stagingAllocation;
 		
 		size_t stagingLimit;
 		size_t stagingPosition;
@@ -150,11 +129,11 @@ namespace vkcv {
 		const size_t remaining = info.size - info.stagingPosition;
 		const size_t mapped_size = std::min(remaining, info.stagingLimit);
 		
-		const vk::Device& device = core->getContext().getDevice();
+		const vma::Allocator& allocator = core->getContext().getAllocator();
 		
-		void* mapped = device.mapMemory(info.stagingMemory, 0, mapped_size);
+		void* mapped = allocator.mapMemory(info.stagingAllocation);
 		memcpy(mapped, reinterpret_cast<const char*>(info.data) + info.stagingPosition, mapped_size);
-		device.unmapMemory(info.stagingMemory);
+		allocator.unmapMemory(info.stagingAllocation);
 		
 		SubmitInfo submitInfo;
 		submitInfo.queueType = QueueType::Transfer;
@@ -216,7 +195,13 @@ namespace vkcv {
 		
 		auto& buffer = m_buffers[id];
 		
-		return buffer.m_memory;
+		const vma::Allocator& allocator = m_core->getContext().getAllocator();
+		
+		auto info = allocator.getAllocationInfo(
+				buffer.m_allocation
+		);
+		
+		return info.deviceMemory;
 	}
 	
 	void BufferManager::fillBuffer(const BufferHandle& handle, const void *data, size_t size, size_t offset) {
@@ -232,11 +217,7 @@ namespace vkcv {
 		
 		auto& buffer = m_buffers[id];
 		
-		if (buffer.m_mapped) {
-			return;
-		}
-		
-		const vk::Device& device = m_core->getContext().getDevice();
+		const vma::Allocator& allocator = m_core->getContext().getAllocator();
 		
 		if (offset > buffer.m_size) {
 			return;
@@ -245,9 +226,9 @@ namespace vkcv {
 		const size_t max_size = std::min(size, buffer.m_size - offset);
 		
 		if (buffer.m_mappable) {
-			void* mapped = device.mapMemory(buffer.m_memory, offset, max_size);
-			memcpy(mapped, data, max_size);
-			device.unmapMemory(buffer.m_memory);
+			void* mapped = allocator.mapMemory(buffer.m_allocation);
+			memcpy(reinterpret_cast<char*>(mapped) + offset, data, max_size);
+			allocator.unmapMemory(buffer.m_allocation);
 		} else {
 			auto& stagingBuffer = m_buffers[ m_stagingBuffer.getId() ];
 			
@@ -258,11 +239,9 @@ namespace vkcv {
 			
 			info.buffer = buffer.m_handle;
 			info.stagingBuffer = stagingBuffer.m_handle;
-			info.stagingMemory = stagingBuffer.m_memory;
+			info.stagingAllocation = stagingBuffer.m_allocation;
 			
-			const vk::MemoryRequirements stagingRequirements = device.getBufferMemoryRequirements(stagingBuffer.m_handle);
-			
-			info.stagingLimit = stagingRequirements.size;
+			info.stagingLimit = stagingBuffer.m_size;
 			info.stagingPosition = 0;
 			
 			copyFromStagingBuffer(m_core, info);
@@ -282,19 +261,13 @@ namespace vkcv {
 		
 		auto& buffer = m_buffers[id];
 		
-		if (buffer.m_mapped) {
-			return nullptr;
-		}
-		
-		const vk::Device& device = m_core->getContext().getDevice();
+		const vma::Allocator& allocator = m_core->getContext().getAllocator();
 		
 		if (offset > buffer.m_size) {
 			return nullptr;
 		}
 		
-		const size_t max_size = std::min(size, buffer.m_size - offset);
-		buffer.m_mapped = device.mapMemory(buffer.m_memory, offset, max_size);
-		return buffer.m_mapped;
+		return reinterpret_cast<char*>(allocator.mapMemory(buffer.m_allocation)) + offset;
 	}
 	
 	void BufferManager::unmapBuffer(const BufferHandle& handle) {
@@ -306,14 +279,9 @@ namespace vkcv {
 		
 		auto& buffer = m_buffers[id];
 		
-		if (buffer.m_mapped == nullptr) {
-			return;
-		}
-		
-		const vk::Device& device = m_core->getContext().getDevice();
+		const vma::Allocator& allocator = m_core->getContext().getAllocator();
 		
-		device.unmapMemory(buffer.m_memory);
-		buffer.m_mapped = nullptr;
+		allocator.unmapMemory(buffer.m_allocation);
 	}
 	
 	void BufferManager::destroyBufferById(uint64_t id) {
@@ -323,16 +291,13 @@ namespace vkcv {
 		
 		auto& buffer = m_buffers[id];
 		
-		const vk::Device& device = m_core->getContext().getDevice();
-		
-		if (buffer.m_memory) {
-			device.freeMemory(buffer.m_memory);
-			buffer.m_memory = nullptr;
-		}
+		const vma::Allocator& allocator = m_core->getContext().getAllocator();
 		
 		if (buffer.m_handle) {
-			device.destroyBuffer(buffer.m_handle);
+			allocator.destroyBuffer(buffer.m_handle, buffer.m_allocation);
+			
 			buffer.m_handle = nullptr;
+			buffer.m_allocation = nullptr;
 		}
 	}
 
diff --git a/src/vkcv/Context.cpp b/src/vkcv/Context.cpp
index e23213b41a3c9a289b679652b66bbe2e75cf0340..5db50869498600fa8e926c0feff2cb5fda1eb22e 100644
--- a/src/vkcv/Context.cpp
+++ b/src/vkcv/Context.cpp
@@ -9,11 +9,13 @@ namespace vkcv
             m_Instance(other.m_Instance),
             m_PhysicalDevice(other.m_PhysicalDevice),
             m_Device(other.m_Device),
-            m_QueueManager(other.m_QueueManager)
+            m_QueueManager(other.m_QueueManager),
+            m_Allocator(other.m_Allocator)
     {
         other.m_Instance        = nullptr;
         other.m_PhysicalDevice  = nullptr;
         other.m_Device          = nullptr;
+		other.m_Allocator		= nullptr;
     }
 
     Context & Context::operator=(Context &&other) noexcept
@@ -22,10 +24,12 @@ namespace vkcv
         m_PhysicalDevice    = other.m_PhysicalDevice;
         m_Device            = other.m_Device;
         m_QueueManager		= other.m_QueueManager;
+        m_Allocator			= other.m_Allocator;
 
         other.m_Instance        = nullptr;
         other.m_PhysicalDevice  = nullptr;
         other.m_Device          = nullptr;
+        other.m_Allocator		= nullptr;
 
         return *this;
     }
@@ -33,15 +37,18 @@ namespace vkcv
     Context::Context(vk::Instance instance,
                      vk::PhysicalDevice physicalDevice,
                      vk::Device device,
-					 QueueManager&& queueManager) noexcept :
-    m_Instance{instance},
-    m_PhysicalDevice{physicalDevice},
-    m_Device{device},
-    m_QueueManager{queueManager}
+					 QueueManager&& queueManager,
+					 vma::Allocator&& allocator) noexcept :
+    m_Instance(instance),
+    m_PhysicalDevice(physicalDevice),
+    m_Device(device),
+    m_QueueManager(queueManager),
+    m_Allocator(allocator)
     {}
 
     Context::~Context() noexcept
     {
+    	m_Allocator.destroy();
         m_Device.destroy();
         m_Instance.destroy();
     }
@@ -64,6 +71,10 @@ namespace vkcv
     const QueueManager& Context::getQueueManager() const {
     	return m_QueueManager;
     }
+    
+    const vma::Allocator& Context::getAllocator() const {
+    	return m_Allocator;
+    }
 	
 	/**
 	 * @brief The physical device is evaluated by three categories:
@@ -290,9 +301,44 @@ namespace vkcv
 		
 		vk::Device device = physicalDevice.createDevice(deviceCreateInfo);
 		
-		QueueManager queueManager = QueueManager::create(device, queuePairsGraphics, queuePairsCompute, queuePairsTransfer);
+		QueueManager queueManager = QueueManager::create(
+				device,
+				queuePairsGraphics,
+				queuePairsCompute,
+				queuePairsTransfer
+		);
+		
+		const vma::AllocatorCreateInfo allocatorCreateInfo (
+				vma::AllocatorCreateFlags(),
+				physicalDevice,
+				device,
+				0,
+				nullptr,
+				nullptr,
+				0,
+				nullptr,
+				nullptr,
+				nullptr,
+				instance,
+				
+				/* Uses default version when set to 0 (currently VK_VERSION_1_0):
+				 *
+				 * The reason for this is that the allocator restricts the allowed version
+				 * to be at maximum VK_VERSION_1_1 which is already less than
+				 * VK_HEADER_VERSION_COMPLETE at most platforms.
+				 * */
+				0
+		);
+		
+		vma::Allocator allocator = vma::createAllocator(allocatorCreateInfo);
 		
-		return Context(instance, physicalDevice, device, std::move(queueManager));
+		return Context(
+				instance,
+				physicalDevice,
+				device,
+				std::move(queueManager),
+				std::move(allocator)
+		);
 	}
  
 }
diff --git a/src/vkcv/ImageManager.cpp b/src/vkcv/ImageManager.cpp
index ba96cf8ff1be1988dbaf3f9cb01bdaa96c84ac0b..1cb6ad3a1187c08cf1aa014ae4ae259591f5c786 100644
--- a/src/vkcv/ImageManager.cpp
+++ b/src/vkcv/ImageManager.cpp
@@ -12,26 +12,6 @@
 
 namespace vkcv {
 
-	ImageManager::Image::Image(
-		vk::Image                   handle,
-		vk::DeviceMemory            memory,
-		std::vector<vk::ImageView>  views,
-		uint32_t                    width,
-		uint32_t                    height,
-		uint32_t                    depth,
-		vk::Format                  format,
-		uint32_t                    layers)
-		:
-		m_handle(handle),
-		m_memory(memory),
-        m_viewPerMip(views),
-		m_width(width),
-		m_height(height),
-		m_depth(depth),
-		m_format(format),
-		m_layers(layers)
-	{}
-
 	/**
 	 * @brief searches memory type index for image allocation, combines requirements of image and application
 	 * @param physicalMemoryProperties Memory Properties of physical device
@@ -124,7 +104,7 @@ namespace vkcv {
 			imageUsageFlags |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
 		}
 
-		const vk::Device& device = m_core->getContext().getDevice();
+		const vma::Allocator& allocator = m_core->getContext().getAllocator();
 
 		vk::ImageType imageType = vk::ImageType::e3D;
 		vk::ImageViewType imageViewType = vk::ImageViewType::e3D;
@@ -158,7 +138,7 @@ namespace vkcv {
 
 		vk::SampleCountFlagBits sampleCountFlag = msaaToVkSampleCountFlag(msaa);
 
-		const vk::ImageCreateInfo imageCreateInfo(
+		const vk::ImageCreateInfo imageCreateInfo (
 			createFlags,
 			imageType,
 			format,
@@ -172,21 +152,22 @@ namespace vkcv {
 			{},
 			vk::ImageLayout::eUndefined
 		);
-
-		vk::Image image = device.createImage(imageCreateInfo);
 		
-		const vk::MemoryRequirements requirements = device.getImageMemoryRequirements(image);
-
-		vk::MemoryPropertyFlags memoryTypeFlags = vk::MemoryPropertyFlagBits::eDeviceLocal;
-
-		const uint32_t memoryTypeIndex = searchImageMemoryType(
-			physicalDevice.getMemoryProperties(),
-			requirements.memoryTypeBits,
-			memoryTypeFlags
+		auto imageAllocation = allocator.createImage(
+				imageCreateInfo,
+				vma::AllocationCreateInfo(
+						vma::AllocationCreateFlags(),
+						vma::MemoryUsage::eGpuOnly,
+						vk::MemoryPropertyFlagBits::eDeviceLocal,
+						vk::MemoryPropertyFlagBits::eDeviceLocal,
+						0,
+						vma::Pool(),
+						nullptr
+				)
 		);
 
-		vk::DeviceMemory memory = device.allocateMemory(vk::MemoryAllocateInfo(requirements.size, memoryTypeIndex));
-		device.bindImageMemory(image, memory, 0);
+		vk::Image image = imageAllocation.first;
+		vma::Allocation allocation = imageAllocation.second;
 
 		vk::ImageAspectFlags aspectFlags;
 		
@@ -196,6 +177,8 @@ namespace vkcv {
 			aspectFlags = vk::ImageAspectFlagBits::eColor;
 		}
 		
+		const vk::Device& device = m_core->getContext().getDevice();
+		
 		std::vector<vk::ImageView> views;
 		for (uint32_t mip = 0; mip < mipCount; mip++) {
 			const vk::ImageViewCreateInfo imageViewCreateInfo(
@@ -222,11 +205,11 @@ namespace vkcv {
 		}
 		
 		const uint64_t id = m_images.size();
-		m_images.push_back(Image(image, memory, views, width, height, depth, format, arrayLayers));
+		m_images.push_back({ image, allocation, views, width, height, depth, format, arrayLayers, vk::ImageLayout::eUndefined });
 		return ImageHandle(id, [&](uint64_t id) { destroyImageById(id); });
 	}
 	
-	ImageHandle ImageManager::createSwapchainImage() {
+	ImageHandle ImageManager::createSwapchainImage() const {
 		return ImageHandle::createSwapchainImageHandle();
 	}
 	
@@ -262,10 +245,16 @@ namespace vkcv {
 		
 		auto& image = m_images[id];
 		
-		return image.m_memory;
+		const vma::Allocator& allocator = m_core->getContext().getAllocator();
+		
+		auto info = allocator.getAllocationInfo(
+				image.m_allocation
+		);
+		
+		return info.deviceMemory;
 	}
 	
-	vk::ImageView ImageManager::getVulkanImageView(const ImageHandle &handle, const size_t mipLevel) const {
+	vk::ImageView ImageManager::getVulkanImageView(const ImageHandle &handle, size_t mipLevel) const {
 		
 		if (handle.isSwapchainImage()) {
 			return m_swapchainImages[m_currentSwapchainInputImage].m_viewPerMip[0];
@@ -626,15 +615,14 @@ namespace vkcv {
 				view = nullptr;
 			}
 		}
-
-		if (image.m_memory) {
-			device.freeMemory(image.m_memory);
-			image.m_memory = nullptr;
-		}
+		
+		const vma::Allocator& allocator = m_core->getContext().getAllocator();
 
 		if (image.m_handle) {
-			device.destroyImage(image.m_handle);
+			allocator.destroyImage(image.m_handle, image.m_allocation);
+			
 			image.m_handle = nullptr;
+			image.m_allocation = nullptr;
 		}
 	}
 
@@ -670,11 +658,11 @@ namespace vkcv {
 		m_currentSwapchainInputImage = index;
 	}
 
-	void ImageManager::setSwapchainImages(const std::vector<vk::Image>& images, std::vector<vk::ImageView> views, 
+	void ImageManager::setSwapchainImages(const std::vector<vk::Image>& images, const std::vector<vk::ImageView>& views,
 		uint32_t width, uint32_t height, vk::Format format) {
 
 		// destroy old views
-		for (auto image : m_swapchainImages) {
+		for (const auto& image : m_swapchainImages) {
 			for (const auto& view : image.m_viewPerMip) {
 				m_core->getContext().getDevice().destroyImageView(view);
 			}
@@ -683,7 +671,17 @@ namespace vkcv {
 		assert(images.size() == views.size());
 		m_swapchainImages.clear();
 		for (size_t i = 0; i < images.size(); i++) {
-			m_swapchainImages.push_back(Image(images[i], nullptr, { views[i] }, width, height, 1, format, 1));
+			m_swapchainImages.push_back({
+				images[i],
+				nullptr,
+				{ views[i] },
+				width,
+				height,
+				1,
+				format,
+				1,
+				vk::ImageLayout::eUndefined
+			});
 		}
 	}
 
diff --git a/src/vkcv/ImageManager.hpp b/src/vkcv/ImageManager.hpp
index 9edd747141305a8a795a2ec8ada04f46e96c9852..646b3211f761f0c71596fc088b39b784d5f39a5c 100644
--- a/src/vkcv/ImageManager.hpp
+++ b/src/vkcv/ImageManager.hpp
@@ -6,6 +6,7 @@
  */
 #include <vector>
 #include <vulkan/vulkan.hpp>
+#include <vk_mem_alloc.hpp>
 
 #include "vkcv/BufferManager.hpp"
 #include "vkcv/Handles.hpp"
@@ -20,28 +21,16 @@ namespace vkcv {
 		struct Image
 		{
 			vk::Image                   m_handle;
-			vk::DeviceMemory            m_memory;
+			vma::Allocation             m_allocation;
 			std::vector<vk::ImageView>  m_viewPerMip;
-			uint32_t                    m_width     = 0;
-			uint32_t                    m_height    = 0;
-			uint32_t                    m_depth     = 0;
+			uint32_t                    m_width;
+			uint32_t                    m_height;
+			uint32_t                    m_depth;
 			vk::Format                  m_format;
-			uint32_t                    m_layers    = 1;
-			vk::ImageLayout             m_layout    = vk::ImageLayout::eUndefined;
+			uint32_t                    m_layers;
+			vk::ImageLayout             m_layout;
 		private:
-			// struct is public so utility functions can access members, but only ImageManager can create Image
 			friend ImageManager;
-			Image(
-				vk::Image                   handle,
-				vk::DeviceMemory            memory,
-				std::vector<vk::ImageView>  views,
-				uint32_t                    width,
-				uint32_t                    height,
-				uint32_t                    depth,
-				vk::Format                  format,
-				uint32_t                    layers);
-
-			Image();
 		};
 	private:
 		
@@ -52,7 +41,7 @@ namespace vkcv {
 		std::vector<Image> m_swapchainImages;
 		int m_currentSwapchainInputImage;
 		
-		ImageManager(BufferManager& bufferManager) noexcept;
+		explicit ImageManager(BufferManager& bufferManager) noexcept;
 		
 		/**
 		 * Destroys and deallocates image represented by a given
@@ -82,7 +71,8 @@ namespace vkcv {
 			bool            supportColorAttachment,
 			Multisampling   msaa);
 		
-		ImageHandle createSwapchainImage();
+		[[nodiscard]]
+		ImageHandle createSwapchainImage() const;
 		
 		[[nodiscard]]
 		vk::Image getVulkanImage(const ImageHandle& handle) const;
@@ -91,7 +81,7 @@ namespace vkcv {
 		vk::DeviceMemory getVulkanDeviceMemory(const ImageHandle& handle) const;
 		
 		[[nodiscard]]
-		vk::ImageView getVulkanImageView(const ImageHandle& handle, const size_t mipLevel = 0) const;
+		vk::ImageView getVulkanImageView(const ImageHandle& handle, size_t mipLevel = 0) const;
 
 		void switchImageLayoutImmediate(const ImageHandle& handle, vk::ImageLayout newLayout);
 		void recordImageLayoutTransition(
@@ -124,8 +114,9 @@ namespace vkcv {
 		uint32_t getImageMipCount(const ImageHandle& handle) const;
 
 		void setCurrentSwapchainImageIndex(int index);
-		void setSwapchainImages(const std::vector<vk::Image>& images, std::vector<vk::ImageView> views,
-			uint32_t width, uint32_t height, vk::Format format);
+		
+		void setSwapchainImages(const std::vector<vk::Image>& images, const std::vector<vk::ImageView>& views,
+								uint32_t width, uint32_t height, vk::Format format);
 
 	};
 }
\ No newline at end of file