diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6aa10e6c26b7e8534c1e0a4c2afbd0bd4ed3fa9b..4079e35a9921c08885c0a04eae28449c9fcb629c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,21 +1,31 @@
+stages:
+  - build
+  - deploy
+
 build_ubuntu_gcc:
-  variables:
-    GIT_SUBMODULE_STRATEGY: recursive
   stage: build
   tags: 
     - ubuntu-gcc
+  variables:
+    GIT_SUBMODULE_STRATEGY: recursive
   script:
     - mkdir debug
     - cd debug
     - cmake -DCMAKE_BUILD_TYPE=Debug ..
     - cmake --build .
+  artifacts:
+    name: "Documentation - $CI_PIPELINE_ID"
+    paths:
+      - doc/html
+      - doc/latex
+    expire_in: never
 
 build_win10_msvc:
-  variables:
-    GIT_SUBMODULE_STRATEGY: recursive
   stage: build
   tags: 
     - win10-msvc
+  variables:
+    GIT_SUBMODULE_STRATEGY: recursive
   script:
     - cd 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\'
     - .\Launch-VsDevShell.ps1
@@ -23,4 +33,36 @@ build_win10_msvc:
     - mkdir debug
     - cd debug
     - cmake -DCMAKE_BUILD_TYPE=Debug ..
-    - cmake --build .
\ No newline at end of file
+    - cmake --build .
+
+deploy_doc_develop:
+  only:
+    refs:
+      - develop
+  stage: deploy
+  needs: ["build_ubuntu_gcc"]
+  dependencies: 
+    - build_ubuntu_gcc
+  tags: 
+    - webserver
+  variables:
+    GIT_STRATEGY: none
+  script:
+    - rsync -avh doc/html/ /var/www/html/develop --delete
+    - echo "Check it out at https://vkcv.de/develop"
+
+deploy_doc_branch:
+  except:
+    refs:
+      - develop
+  stage: deploy
+  needs: ["build_ubuntu_gcc"]
+  dependencies: 
+    - build_ubuntu_gcc
+  tags: 
+    - webserver
+  variables:
+    GIT_STRATEGY: none
+  script:
+    - rsync -avh  doc/html/ /var/www/html/branch/$CI_COMMIT_BRANCH --delete
+    - echo "Check it out at https://vkcv.de/branch/$CI_COMMIT_BRANCH"
\ No newline at end of file
diff --git a/config/Sources.cmake b/config/Sources.cmake
index dce76b39f362161941a94280a3f3c04efbc79d33..b8c2dcbdf87a08225cebefa3197277715845e961 100644
--- a/config/Sources.cmake
+++ b/config/Sources.cmake
@@ -37,8 +37,8 @@ set(vkcv_sources
         ${vkcv_include}/vkcv/SyncResources.hpp
         ${vkcv_source}/vkcv/SyncResources.cpp
         
-        ${vkcv_include}/vkcv/Queues.hpp
-        ${vkcv_source}/vkcv/Queues.cpp
+        ${vkcv_include}/vkcv/QueueManager.hpp
+        ${vkcv_source}/vkcv/QueueManager.cpp
         
         ${vkcv_source}/vkcv/Surface.hpp
         ${vkcv_source}/vkcv/Surface.cpp
diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index 110683df4d65c9b963829537a85a0b7e3d35b3ee..54a9cbbe922f42083b65eae4999d0802e6c2c27e 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -5,8 +5,8 @@
  */
 
 #include <memory>
-
 #include <vulkan/vulkan.hpp>
+
 #include "vkcv/Context.hpp"
 #include "vkcv/SwapChain.hpp"
 #include "vkcv/Window.hpp"
@@ -15,8 +15,8 @@
 #include "vkcv/PipelineConfig.hpp"
 #include "CommandResources.hpp"
 #include "SyncResources.hpp"
-#include "vkcv/Queues.hpp"
 #include "Result.hpp"
+#include "vkcv/QueueManager.hpp"
 
 namespace vkcv
 {
@@ -37,7 +37,7 @@ namespace vkcv
          * @param context encapsulates various Vulkan objects
          */
         Core(Context &&context, const Window &window, SwapChain swapChain,  std::vector<vk::ImageView> imageViews, 
-			const CommandResources& commandResources, const SyncResources& syncResources, const VulkanQueues &queues) noexcept;
+			const CommandResources& commandResources, const SyncResources& syncResources, const QueueManager &queues) noexcept;
         // explicit destruction of default constructor
         Core() = delete;
 
@@ -54,7 +54,7 @@ namespace vkcv
         std::unique_ptr<PipelineManager> m_PipelineManager;
 		CommandResources m_CommandResources;
 		SyncResources m_SyncResources;
-		VulkanQueues m_Queues;
+		QueueManager m_QueueManager;
 		uint32_t m_currentSwapchainImageIndex;
 		std::vector<vk::Framebuffer> m_TemporaryFramebuffers;
     public:
diff --git a/include/vkcv/QueueManager.hpp b/include/vkcv/QueueManager.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1779fb669eadb67682bdca6610402ce0dcbacff5
--- /dev/null
+++ b/include/vkcv/QueueManager.hpp
@@ -0,0 +1,36 @@
+#pragma once
+#include <vulkan/vulkan.hpp>
+
+namespace vkcv {
+	class QueueManager {
+	public:
+		static QueueManager create(vk::Device device,
+                            std::vector<std::pair<int, int>> &queuePairsGraphics,
+                            std::vector<std::pair<int, int>> &queuePairsCompute,
+                            std::vector<std::pair<int, int>> &queuePairsTransfer);
+
+        const vk::Queue &getPresentQueue() const;
+
+		const std::vector<vk::Queue> &getGraphicsQueues() const;
+
+        const std::vector<vk::Queue> &getComputeQueues() const;
+
+        const std::vector<vk::Queue> &getTransferQueues() const;
+
+        static void queueCreateInfosQueueHandles(vk::PhysicalDevice &physicalDevice,
+                std::vector<float> &queuePriorities,
+                std::vector<vk::QueueFlagBits> &queueFlags,
+                std::vector<vk::DeviceQueueCreateInfo> &queueCreateInfos,
+                std::vector<std::pair<int, int>> &queuePairsGraphics,
+                std::vector<std::pair<int, int>> &queuePairsCompute,
+                std::vector<std::pair<int, int>> &queuePairsTransfer);
+
+    private:
+        vk::Queue m_presentQueue;
+        std::vector<vk::Queue> m_graphicsQueues;
+        std::vector<vk::Queue> m_computeQueues;
+        std::vector<vk::Queue> m_transferQueues;
+
+        QueueManager(std::vector<vk::Queue> graphicsQueues, std::vector<vk::Queue> computeQueues, std::vector<vk::Queue> transferQueues, vk::Queue presentQueue);
+	};
+}
diff --git a/include/vkcv/Queues.hpp b/include/vkcv/Queues.hpp
deleted file mode 100644
index c1cca7099f2f57adb821e9f1dcbfa01928e01c76..0000000000000000000000000000000000000000
--- a/include/vkcv/Queues.hpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-#include <vulkan/vulkan.hpp>
-
-namespace vkcv {
-	struct VulkanQueues {
-		vk::Queue graphicsQueue;
-		vk::Queue computeQueue;
-		vk::Queue transferQueue;
-		vk::Queue presentQueue;
-	};
-
-	struct QueueFamilyIndices {
-		int graphicsIndex = -1;
-		int computeIndex = -1;
-		int transferIndex = -1;
-		int presentIndex = -1;
-	};
-
-	VulkanQueues getDeviceQueues(const vk::Device& device, const QueueFamilyIndices& familyIndices);
-
-	QueueFamilyIndices getQueueFamilyIndices(const vk::PhysicalDevice& physicalDevice, const vk::SurfaceKHR surface);
-
-	// TODO: try to use specialised queues
-	std::vector<vk::DeviceQueueCreateInfo> createDeviceQueueCreateInfo(const QueueFamilyIndices& indices, 
-		std::vector<float> *outQueuePriorities);
-
-}
diff --git a/include/vkcv/SwapChain.hpp b/include/vkcv/SwapChain.hpp
index 351905fa2af5e30ee41cead4c1b7d449aa2472da..1087d6364f6f811b741904d4e2b31fcfeb450901 100644
--- a/include/vkcv/SwapChain.hpp
+++ b/include/vkcv/SwapChain.hpp
@@ -2,7 +2,6 @@
 #include "vulkan/vulkan.hpp"
 #include "Context.hpp"
 #include "vkcv/Window.hpp"
-#include <iostream>
 
 namespace vkcv {
     class SwapChain final {
@@ -13,7 +12,6 @@ namespace vkcv {
         vk::SurfaceFormatKHR m_format;
 
 		uint32_t m_ImageCount;
-		vk::Format m_ImageFormat;
 
         /**
          * Constructor of a SwapChain object
@@ -66,8 +64,6 @@ namespace vkcv {
 		 * @return number of images in swapchain
 		*/
 		uint32_t getImageCount();
-
-		vk::Format getImageFormat();
     };
 
 }
diff --git a/src/vkcv/Context.cpp b/src/vkcv/Context.cpp
index 761add2c9c0792bbf098c1f7f6122e84978a6735..d5261285557f07310c02acd50b6ccd6ca16cac59 100644
--- a/src/vkcv/Context.cpp
+++ b/src/vkcv/Context.cpp
@@ -1,4 +1,3 @@
-#include <iostream>
 #include "vkcv/Context.hpp"
 
 namespace vkcv
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index e4603e30faa0bbf0db058ce2d0342efde893aba9..5e23fe2b564b10998945960ad840c56ddf97b690 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -205,9 +205,13 @@ namespace vkcv
         }
 
 		const vk::SurfaceKHR surface = createSurface(window.getWindow(), instance, physicalDevice);
-		const QueueFamilyIndices queueFamilyIndices = getQueueFamilyIndices(physicalDevice, surface);
-		std::vector<float> queuePriorities;
-		const std::vector<vk::DeviceQueueCreateInfo> qCreateInfos = createDeviceQueueCreateInfo(queueFamilyIndices, &queuePriorities);
+		std::vector<vk::DeviceQueueCreateInfo> qCreateInfos;
+
+        // create required queues
+        std::vector<float> qPriorities;
+        qPriorities.resize(queueFlags.size(), 1.f);
+        std::vector<std::pair<int, int>> queuePairsGraphics, queuePairsCompute, queuePairsTransfer;
+        QueueManager::queueCreateInfosQueueHandles(physicalDevice, qPriorities, queueFlags, qCreateInfos, queuePairsGraphics, queuePairsCompute, queuePairsTransfer);
 
 		vk::DeviceCreateInfo deviceCreateInfo(
 			vk::DeviceCreateFlags(),
@@ -220,17 +224,21 @@ namespace vkcv
 			nullptr		// Should our device use some features??? If yes: TODO
 		);
 
-
-
 #ifndef NDEBUG
         deviceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
         deviceCreateInfo.ppEnabledLayerNames = validationLayers.data();
 #endif
 
+        // Ablauf
+        // qCreateInfos erstellen --> braucht das Device
+        // device erstellen
+        // jetzt koennen wir mit dem device die queues erstellen
+
         vk::Device device = physicalDevice.createDevice(deviceCreateInfo);
-        Context context(instance, physicalDevice, device);
 
-		const VulkanQueues queues = getDeviceQueues(device, queueFamilyIndices);
+        QueueManager queueManager = QueueManager::create(device, queuePairsGraphics, queuePairsCompute, queuePairsTransfer);
+
+        Context context (instance, physicalDevice, device);
 
         SwapChain swapChain = SwapChain::create(window, context, surface);
 
@@ -257,14 +265,14 @@ namespace vkcv
                     subResourceRange
             );
 
-            imageViews.push_back( device.createImageView( imageViewCreateInfo ) );
+            imageViews.push_back( device.createImageView( imageViewCreateInfo ));
         }
 
-		const int graphicQueueFamilyIndex = queueFamilyIndices.graphicsIndex;
+		const int graphicQueueFamilyIndex = queuePairsGraphics[0].first;
 		const auto defaultCommandResources = createDefaultCommandResources(context.getDevice(), graphicQueueFamilyIndex);
 		const auto defaultSyncResources = createDefaultSyncResources(context.getDevice());
 
-        return Core(std::move(context) , window, swapChain, imageViews, defaultCommandResources, defaultSyncResources, queues);
+        return Core(std::move(context) , window, swapChain, imageViews, defaultCommandResources, defaultSyncResources, queueManager);
     }
 
     const Context &Core::getContext() const
@@ -273,16 +281,16 @@ namespace vkcv
     }
 
 	Core::Core(Context &&context, const Window &window , SwapChain swapChain,  std::vector<vk::ImageView> imageViews, 
-		const CommandResources& commandResources, const SyncResources& syncResources, const VulkanQueues& queues) noexcept :
-			m_Context(std::move(context)),
-			m_window(window),
-			m_swapchain(swapChain),
-			m_swapchainImageViews(imageViews),
-			m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)},
-			m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)},
-			m_CommandResources(commandResources),
-			m_SyncResources(syncResources),
-			m_Queues(queues)
+		const CommandResources& commandResources, const SyncResources& syncResources, const QueueManager& queueManager) noexcept :
+            m_Context(std::move(context)),
+            m_window(window),
+            m_swapchain(swapChain),
+            m_swapchainImageViews(imageViews),
+            m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)},
+            m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)},
+            m_CommandResources(commandResources),
+            m_SyncResources(syncResources),
+            m_QueueManager(queueManager)
 	{}
 
 	Core::~Core() noexcept {
@@ -391,19 +399,19 @@ namespace vkcv
 		m_CommandResources.commandBuffer.end();
 		
 		const vk::SubmitInfo submitInfo(0, nullptr, 0, 1, &(m_CommandResources.commandBuffer), 1, &m_SyncResources.renderFinished);
-		m_Queues.graphicsQueue.submit(submitInfo);
+		m_QueueManager.getGraphicsQueues()[0].submit(submitInfo);
 
 		vk::Result presentResult;
 		const vk::SwapchainKHR& swapchain = m_swapchain.getSwapchain();
 		const vk::PresentInfoKHR presentInfo(1, &m_SyncResources.renderFinished, 1, &swapchain, 
 			&m_currentSwapchainImageIndex, &presentResult);
-		m_Queues.presentQueue.presentKHR(presentInfo);
+        m_QueueManager.getPresentQueue().presentKHR(presentInfo);
 		if (presentResult != vk::Result::eSuccess) {
 			std::cout << "Error: swapchain present failed" << std::endl;
 		}
 	}
 
 	vk::Format Core::getSwapchainImageFormat() {
-		return m_swapchain.getImageFormat();
+		return m_swapchain.getSurfaceFormat().format;
 	}
 }
diff --git a/src/vkcv/QueueManager.cpp b/src/vkcv/QueueManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6f46e61ad5b658ca38749565309ae06646b9090a
--- /dev/null
+++ b/src/vkcv/QueueManager.cpp
@@ -0,0 +1,192 @@
+
+#include <unordered_set>
+#include <limits>
+
+#include "vkcv/QueueManager.hpp"
+
+namespace vkcv {
+
+    /**
+     * Given the @p physicalDevice and the @p queuePriorities, the @p queueCreateInfos are computed. First, the requested
+     * queues are sorted by priority depending on the availability of queues in the queue families of the given
+     * @p physicalDevice. Then check, if all requested queues are creatable. If so, the @p queueCreateInfos will be computed.
+     * Furthermore, lists of index pairs (queueFamilyIndex, queueIndex) for later referencing of the separate queues will
+     * be computed.
+     * @param[in] physicalDevice The physical device
+     * @param[in] queuePriorities The queue priorities used for the computation of @p queueCreateInfos
+     * @param[in] queueFlags The queue flags requesting the queues
+     * @param[in,out] queueCreateInfos The queue create info structures to be created
+     * @param[in,out] queuePairsGraphics The list of index pairs (queueFamilyIndex, queueIndex) of queues of type
+     *      vk::QueueFlagBits::eGraphics
+     * @param[in,out] queuePairsCompute The list of index pairs (queueFamilyIndex, queueIndex) of queues of type
+     *      vk::QueueFlagBits::eCompute
+     * @param[in,out] queuePairsTransfer The list of index pairs (queueFamilyIndex, queueIndex) of queues of type
+     *      vk::QueueFlagBits::eTransfer
+     * @throws std::runtime_error If the requested queues from @p queueFlags are not creatable due to insufficient availability.
+     */
+    void QueueManager::queueCreateInfosQueueHandles(vk::PhysicalDevice &physicalDevice,
+                                      std::vector<float> &queuePriorities,
+                                      std::vector<vk::QueueFlagBits> &queueFlags,
+                                      std::vector<vk::DeviceQueueCreateInfo> &queueCreateInfos,
+                                      std::vector<std::pair<int, int>> &queuePairsGraphics,
+                                      std::vector<std::pair<int, int>> &queuePairsCompute,
+                                      std::vector<std::pair<int, int>> &queuePairsTransfer)
+    {
+        queueCreateInfos = {};
+        queuePairsGraphics = {};
+        queuePairsCompute = {};
+        queuePairsTransfer = {};
+        std::vector<vk::QueueFamilyProperties> qFamilyProperties = physicalDevice.getQueueFamilyProperties();
+
+        //check priorities of flags -> the lower prioCount the higher the priority
+        std::vector<int> prios;
+        for(auto flag: queueFlags) {
+            int prioCount = 0;
+            for (int i = 0; i < qFamilyProperties.size(); i++) {
+                prioCount += (static_cast<uint32_t>(flag & qFamilyProperties[i].queueFlags) != 0) * qFamilyProperties[i].queueCount;
+            }
+            prios.push_back(prioCount);
+        }
+        //resort flags with heighest priority before allocating the queues
+        std::vector<vk::QueueFlagBits> newFlags;
+        for(int i = 0; i < prios.size(); i++) {
+            auto minElem = std::min_element(prios.begin(), prios.end());
+            int index = minElem - prios.begin();
+            newFlags.push_back(queueFlags[index]);
+            prios[index] = std::numeric_limits<int>::max();
+        }
+
+        // create requested queues and check if more requested queues are supported
+        // herefore: create vector that updates available queues in each queue family
+        // structure: [qFamily_0, ..., qFamily_n] where
+        // - qFamily_i = [GraphicsCount, ComputeCount, TransferCount], 0 <= i <= n
+        std::vector<std::vector<int>> queueFamilyStatus, initialQueueFamilyStatus;
+
+        for (auto qFamily : qFamilyProperties) {
+            int graphicsCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eGraphics) != 0) * qFamily.queueCount;
+            int computeCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eCompute) != 0) * qFamily.queueCount;
+            int transferCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eTransfer) != 0) * qFamily.queueCount;
+            queueFamilyStatus.push_back({graphicsCount, computeCount, transferCount});
+        }
+
+        initialQueueFamilyStatus = queueFamilyStatus;
+        // check if every queue with the specified queue flag can be created
+        // this automatically checks for queue flag support!
+        for (auto qFlag : newFlags) {
+            bool found;
+            switch (qFlag) {
+                case vk::QueueFlagBits::eGraphics:
+                    found = false;
+                    for (int i = 0; i < queueFamilyStatus.size() && !found; i++) {
+                        if (queueFamilyStatus[i][0] > 0) {
+                            queuePairsGraphics.push_back(std::pair(i, initialQueueFamilyStatus[i][0] - queueFamilyStatus[i][0]));
+                            queueFamilyStatus[i][0]--;
+                            queueFamilyStatus[i][1]--;
+                            queueFamilyStatus[i][2]--;
+                            found = true;
+                        }
+                    }
+                    if (!found) {
+                        throw std::runtime_error("Too many graphics queues were requested than being available!");
+                    }
+                    break;
+                case vk::QueueFlagBits::eCompute:
+                    found = false;
+                    for (int i = 0; i < queueFamilyStatus.size() && !found; i++) {
+                        if (queueFamilyStatus[i][1] > 0) {
+                            queuePairsCompute.push_back(std::pair(i, initialQueueFamilyStatus[i][1] - queueFamilyStatus[i][1]));
+                            queueFamilyStatus[i][0]--;
+                            queueFamilyStatus[i][1]--;
+                            queueFamilyStatus[i][2]--;
+                            found = true;
+                        }
+                    }
+                    if (!found) {
+                        throw std::runtime_error("Too many compute queues were requested than being available!");
+                    }
+                    break;
+                case vk::QueueFlagBits::eTransfer:
+                    found = false;
+                    for (int i = 0; i < queueFamilyStatus.size() && !found; i++) {
+                        if (queueFamilyStatus[i][2] > 0) {
+                            queuePairsTransfer.push_back(std::pair(i, initialQueueFamilyStatus[i][2] - queueFamilyStatus[i][2]));
+                            queueFamilyStatus[i][0]--;
+                            queueFamilyStatus[i][1]--;
+                            queueFamilyStatus[i][2]--;
+                            found = true;
+                        }
+                    }
+                    if (!found) {
+                        throw std::runtime_error("Too many transfer queues were requested than being available!");
+                    }
+                    break;
+                default:
+                    throw std::runtime_error("Invalid input for queue flag bits. Valid inputs are 'vk::QueueFlagBits::eGraphics', 'vk::QueueFlagBits::eCompute' and 'vk::QueueFlagBits::eTransfer'.");
+            }
+        }
+
+        // create all requested queues
+        for (int i = 0; i < qFamilyProperties.size(); i++) {
+            uint32_t create = std::abs(initialQueueFamilyStatus[i][0] - queueFamilyStatus[i][0]);
+            if (create > 0) {
+                vk::DeviceQueueCreateInfo qCreateInfo(
+                        vk::DeviceQueueCreateFlags(),
+                        i,
+                        create,
+                        queuePriorities.data()
+                );
+                queueCreateInfos.push_back(qCreateInfo);
+            }
+        }
+    }
+
+    /**
+     * Computes the queue handles from @p queuePairs
+     * @param device The device
+     * @param queuePairs The queuePairs that were created separately for each queue type (e.g., vk::QueueFlagBits::eGraphics)
+     * @return An array of queue handles based on the @p queuePairs
+     */
+    std::vector<vk::Queue> getQueueHandles(const vk::Device device, const std::vector<std::pair<int, int>> queuePairs) {
+        std::vector<vk::Queue> queueHandles;
+        for (auto q : queuePairs) {
+            int queueFamilyIndex = q.first; // the queueIndex of the queue family
+            int queueIndex = q.second;   // the queueIndex within a queue family
+            queueHandles.push_back(device.getQueue(queueFamilyIndex, queueIndex));
+        }
+        return queueHandles;
+    }
+
+
+    QueueManager QueueManager::create(vk::Device device,
+                                      std::vector<std::pair<int, int>> &queuePairsGraphics,
+                                      std::vector<std::pair<int, int>> &queuePairsCompute,
+                                      std::vector<std::pair<int, int>> &queuePairsTransfer) {
+
+        std::vector<vk::Queue> graphicsQueues = getQueueHandles(device, queuePairsGraphics);
+        std::vector<vk::Queue> computeQueues = getQueueHandles(device, queuePairsCompute );
+        std::vector<vk::Queue> transferQueues = getQueueHandles(device, queuePairsTransfer);
+
+    return QueueManager( graphicsQueues, computeQueues, transferQueues, graphicsQueues[0]);
+	}
+
+	QueueManager::QueueManager(std::vector<vk::Queue> graphicsQueues, std::vector<vk::Queue> computeQueues, std::vector<vk::Queue> transferQueues,  vk::Queue presentQueue)
+	: m_graphicsQueues(graphicsQueues), m_computeQueues(computeQueues), m_transferQueues(transferQueues), m_presentQueue(presentQueue)
+    {}
+
+    const vk::Queue &QueueManager::getPresentQueue() const {
+        return m_presentQueue;
+    }
+
+    const std::vector<vk::Queue> &QueueManager::getGraphicsQueues() const {
+        return m_graphicsQueues;
+    }
+
+    const std::vector<vk::Queue> &QueueManager::getComputeQueues() const {
+        return m_computeQueues;
+    }
+
+    const std::vector<vk::Queue> &QueueManager::getTransferQueues() const {
+        return m_transferQueues;
+    }
+
+}
\ No newline at end of file
diff --git a/src/vkcv/Queues.cpp b/src/vkcv/Queues.cpp
deleted file mode 100644
index 49e992ff79b821ccd884310ab5f4489340bf263c..0000000000000000000000000000000000000000
--- a/src/vkcv/Queues.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-#include "vkcv/Queues.hpp"
-#include <unordered_set>
-
-namespace vkcv {
-
-	VulkanQueues getDeviceQueues(const vk::Device& device, const QueueFamilyIndices& familyIndices) {
-		VulkanQueues queues;
-		queues.graphicsQueue = device.getQueue(familyIndices.graphicsIndex, 0);
-		queues.computeQueue = device.getQueue(familyIndices.computeIndex, 0);
-		queues.transferQueue = device.getQueue(familyIndices.transferIndex, 0);
-		queues.presentQueue = device.getQueue(familyIndices.presentIndex, 0);
-		return queues;
-	}
-
-	QueueFamilyIndices getQueueFamilyIndices(const vk::PhysicalDevice& physicalDevice, const vk::SurfaceKHR surface) {
-		const std::vector<vk::QueueFamilyProperties> familyProps = physicalDevice.getQueueFamilyProperties();
-
-		QueueFamilyIndices indices;
-
-		for (int i = 0; i < familyProps.size(); i++) {
-			const auto& property = familyProps[i];
-
-			const bool hasQueues = property.queueCount >= 1;
-			if (!hasQueues) {
-				continue;
-			}
-
-			if (property.queueFlags & vk::QueueFlagBits::eGraphics) {
-				indices.graphicsIndex = i;
-			}
-			if (property.queueFlags & vk::QueueFlagBits::eCompute) {
-				indices.computeIndex = i;
-			}
-			if (property.queueFlags & vk::QueueFlagBits::eTransfer) {
-				indices.transferIndex = i;
-			}
-			if (physicalDevice.getSurfaceSupportKHR(i, surface)) {
-				indices.presentIndex = i;
-			}
-		}
-		assert(indices.graphicsIndex != -1);
-		assert(indices.computeIndex  != -1);
-		assert(indices.transferIndex != -1);
-		assert(indices.presentIndex  != -1);
-		return indices;
-	}
-
-	std::vector<vk::DeviceQueueCreateInfo> createDeviceQueueCreateInfo(const QueueFamilyIndices& indices,
-		std::vector<float>* outQueuePriorities) {
-
-		// use set to avoid duplicate queues
-		std::unordered_set<int> familyIndexSet;
-		familyIndexSet.insert(indices.graphicsIndex);
-		familyIndexSet.insert(indices.computeIndex);
-		familyIndexSet.insert(indices.transferIndex);
-		familyIndexSet.insert(indices.presentIndex);
-
-		const vk::DeviceQueueCreateFlagBits flags = {};
-		std::vector<vk::DeviceQueueCreateInfo> createInfos;
-
-		outQueuePriorities->resize(familyIndexSet.size(), 1.f);
-		int priorityIndex = 0;
-
-		for (const auto index : familyIndexSet) {
-			const vk::DeviceQueueCreateInfo graphicsCreateInfo(flags, index, 1, &outQueuePriorities->at(priorityIndex));
-			createInfos.push_back(graphicsCreateInfo);
-			priorityIndex++;
-		}
-		return createInfos;
-	}
-}
\ No newline at end of file
diff --git a/src/vkcv/SwapChain.cpp b/src/vkcv/SwapChain.cpp
index ef182bcd180e781e1effb63b978a459bc8dff61e..3483ae37e718453a99d56d31e025433acb7f4422 100644
--- a/src/vkcv/SwapChain.cpp
+++ b/src/vkcv/SwapChain.cpp
@@ -3,7 +3,7 @@
 namespace vkcv {
 
     SwapChain::SwapChain(vk::SurfaceKHR surface, vk::SwapchainKHR swapchain, vk::SurfaceFormatKHR format, uint32_t imageCount)
-        : m_surface(surface), m_swapchain(swapchain), m_format( format), m_ImageCount(imageCount), m_ImageFormat(format.format)
+        : m_surface(surface), m_swapchain(swapchain), m_format( format), m_ImageCount(imageCount)
     {}
 
     const vk::SwapchainKHR& SwapChain::getSwapchain() const {
@@ -168,8 +168,4 @@ namespace vkcv {
 	uint32_t SwapChain::getImageCount() {
 		return m_ImageCount;
 	}
-
-	vk::Format SwapChain::getImageFormat() {
-		return m_ImageFormat;
-	}
 }