diff --git a/config/Sources.cmake b/config/Sources.cmake
index 0f2c2cf7019f07a44b5fd067f1b7fe38c4db5bc6..784562debdfb485b86e283dc765eca82d352d1b5 100644
--- a/config/Sources.cmake
+++ b/config/Sources.cmake
@@ -36,4 +36,10 @@ set(vkcv_sources
         
         ${vkcv_include}/vkcv/SyncResources.hpp
         ${vkcv_source}/vkcv/SyncResources.cpp
+        
+        ${vkcv_include}/vkcv/Queues.hpp
+        ${vkcv_source}/vkcv/Queues.cpp
+        
+        ${vkcv_source}/vkcv/Surface.hpp
+        ${vkcv_source}/vkcv/Surface.cpp
 )
diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index 7cdb50fc50d437e1ec443f9df71621551cb2a553..57c28ee71ff2b1b547361189ecb5e8975abf3993 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -15,6 +15,7 @@
 #include "vkcv/PipelineConfig.hpp"
 #include "CommandResources.hpp"
 #include "SyncResources.hpp"
+#include "vkcv/Queues.hpp"
 
 namespace vkcv
 {
@@ -35,7 +36,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) noexcept;
+			const CommandResources& commandResources, const SyncResources& syncResources, const VulkanQueues &queues) noexcept;
         // explicit destruction of default constructor
         Core() = delete;
 
@@ -53,6 +54,7 @@ namespace vkcv
         std::unique_ptr<PipelineManager> m_PipelineManager;
 		CommandResources m_CommandResources;
 		SyncResources m_SyncResources;
+		VulkanQueues m_Queues;
     public:
         /**
          * Destructor of #Core destroys the Vulkan objects contained in the core's context.
@@ -139,5 +141,19 @@ namespace vkcv
         // TODO:
         BufferHandle createBuffer(const Buffer &buf);
 
+		/**
+		 * @brief start recording command buffers and increment frame index
+		*/
+		void beginFrame();
+
+		/**
+		 * @brief render a beautiful triangle
+		*/
+		void renderTriangle();
+
+		/**
+		 * @brief end recording and present image
+		*/
+		void endFrame();
     };
 }
diff --git a/include/vkcv/Queues.hpp b/include/vkcv/Queues.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9b6cbae005515eb0c5754d8df8b22038eb5a81b0
--- /dev/null
+++ b/include/vkcv/Queues.hpp
@@ -0,0 +1,26 @@
+#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);
+
+}
diff --git a/include/vkcv/SwapChain.hpp b/include/vkcv/SwapChain.hpp
index 15633badd4c6a3aef9766049317f3f5c8382bab8..91d2ccbbafdd30fb744a40231414782d4d9a9f1f 100644
--- a/include/vkcv/SwapChain.hpp
+++ b/include/vkcv/SwapChain.hpp
@@ -52,7 +52,7 @@ namespace vkcv {
          * @param context of the application
          * @return returns an object of swapChain
          */
-        static SwapChain create(const Window &window, const Context &context);
+        static SwapChain create(const Window &window, const Context &context, const vk::SurfaceKHR surface);
 
         /**
          * Destructor of SwapChain
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index e725c83ae44c71cc9184f5c2b0f0779e7b562732..0e567db7233fe0f778412a2bd043ed399d4a2e97 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -87,11 +87,9 @@ int main(int argc, const char** argv) {
 
 	while (window.isWindowOpen())
 	{
-        // core.beginFrame(); or something like that
+		core.beginFrame();
 	    // core.execute(trianglePass, trianglePipeline, triangleModel);
-	    // core.endFrame(); or something like that
-
-	    // TBD: synchronization
+	    core.endFrame();
 
 		window.pollEvents();
 	}
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index e10c593b5753ff34c551807d6c21101cdf9bef07..30d5076908e5becd210c173c83efc1b8433e7468 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -7,6 +7,7 @@
 #include "vkcv/Core.hpp"
 #include "PassManager.hpp"
 #include "PipelineManager.hpp"
+#include "Surface.hpp"
 
 namespace vkcv
 {
@@ -79,173 +80,6 @@ namespace vkcv
         return phyDevice;
     }
 
-
-    /**
-     * 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 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();
-
-        // DEBUG
-        std::cout << "Input queue flags:" << std::endl;
-        for (auto qFlag : queueFlags) {
-            std::cout << "\t" << to_string(qFlag) << std::endl;
-        }
-
-        //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);
-            std::cout<< "prio Count: " << prioCount << std::endl;
-        }
-        //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();
-            std::cout << "index: "<< index << std::endl;
-            newFlags.push_back(queueFlags[index]);
-            prios[index] = std::numeric_limits<int>::max();
-        }
-
-        std::cout << "Sorted queue flags:" << std::endl;
-        for (auto qFlag : newFlags) {
-            std::cout << "\t" << to_string(qFlag) << std::endl;
-        }
-
-        // 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]--;
-                            std::cout << "Graphics queue available at queue family #" << i << std::endl;
-                            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]--;
-                            std::cout << "Compute queue available at queue family #" << i << std::endl;
-                            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]--;
-                            std::cout << "Transfer queue available at queue family #" << i << std::endl;
-                            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'.");
-            }
-        }
-
-        std::cout << "Initial queue status:" << std::endl;
-        int x = 0;
-        for (std::vector<int> e : initialQueueFamilyStatus) {
-            std::cout << "#" << x << ":\t[" << e[0] << ", " << e[1] << ", " << e[2] << "]" << std::endl;
-            x++;
-        }
-
-        std::cout << "Actual queue status:" << std::endl;
-        x = 0;
-        for (std::vector<int> e : queueFamilyStatus) {
-            std::cout << "#" << x << ":\t[" << e[0] << ", " << e[1] << ", " << e[2] << "]" << std::endl;
-            x++;
-        }
-
-        // create all requested queues
-        for (int i = 0; i < qFamilyProperties.size(); i++) {
-            uint32_t create = std::abs(initialQueueFamilyStatus[i][0] - queueFamilyStatus[i][0]);
-            std::cout << "For Queue Family #" << i << " create " << create << " queues" << std::endl;
-            if (create > 0) {
-                vk::DeviceQueueCreateInfo qCreateInfo(
-                        vk::DeviceQueueCreateFlags(),
-                        i,
-                        create,
-                        queuePriorities.data()
-                );
-                queueCreateInfos.push_back(qCreateInfo);
-            }
-        }
-    }
-
     /**
      * @brief With the help of the reference "supported" all elements in "check" checked,
      * if they are supported by the physical device.
@@ -282,22 +116,6 @@ namespace vkcv
         return extensions;
     }
 
-    /**
-     * Computes the queue handles from @p queuePairs
-     * @param queuePairs The queuePairs that were created separately for each queue type (e.g., vk::QueueFlagBits::eGraphics)
-     * @param device The device
-     * @return An array of queue handles based on the @p queuePairs
-     */
-    std::vector<vk::Queue> getQueueHandles(const std::vector<std::pair<int, int>> queuePairs, const vk::Device device) {
-        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;
-    }
-
     Core Core::create(const Window &window,
                       const char *applicationName,
                       uint32_t applicationVersion,
@@ -382,47 +200,34 @@ namespace vkcv
             throw std::runtime_error("The requested device extensions are not supported by the physical device!");
         }
 
-        //vector to define the queue priorities
-        std::vector<float> qPriorities;
-        qPriorities.resize(queueFlags.size(), 1.f); // all queues have the same priorities
+		const vk::SurfaceKHR surface = createSurface(window.getWindow(), instance, physicalDevice);
+		const QueueFamilyIndices queueFamilyIndices = getQueueFamilyIndices(physicalDevice, surface);
+		const std::vector<vk::DeviceQueueCreateInfo> qCreateInfos = createDeviceQueueCreateInfo(queueFamilyIndices);
+
+		vk::DeviceCreateInfo deviceCreateInfo(
+			vk::DeviceCreateFlags(),
+			qCreateInfos.size(),
+			qCreateInfos.data(),
+			0,
+			nullptr,
+			deviceExtensions.size(),
+			deviceExtensions.data(),
+			nullptr		// Should our device use some features??? If yes: TODO
+		);
 
-        // create required queues
-        std::vector<vk::DeviceQueueCreateInfo> qCreateInfos;
-        std::vector<std::pair<int, int>> queuePairsGraphics, queuePairsCompute, queuePairsTransfer;
-        queueCreateInfosQueueHandles(physicalDevice, qPriorities, queueFlags, qCreateInfos, queuePairsGraphics, queuePairsCompute, queuePairsTransfer);
 
-        vk::DeviceCreateInfo deviceCreateInfo(
-                vk::DeviceCreateFlags(),
-                qCreateInfos.size(),
-                qCreateInfos.data(),
-                0,
-                nullptr,
-                deviceExtensions.size(),
-                deviceExtensions.data(),
-                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
 
-
         vk::Device device = physicalDevice.createDevice(deviceCreateInfo);
-
-        // maybe it can be useful to store these lists as member variable of Core
-        std::vector<vk::Queue> graphicsQueues = getQueueHandles(queuePairsGraphics, device);
-        std::vector<vk::Queue> computeQueues = getQueueHandles(queuePairsCompute, device);
-        std::vector<vk::Queue> transferQueues = getQueueHandles(queuePairsTransfer, device);
-
-        // examples for accessing queues
-        vk::Queue graphicsQueue = graphicsQueues[0];
-        vk::Queue computeQueue = computeQueues[0];
-        vk::Queue transferQueue = transferQueues[0];
-
         Context context(instance, physicalDevice, device);
 
-        SwapChain swapChain = SwapChain::create(window, context);
+		const VulkanQueues queues = getDeviceQueues(device, queueFamilyIndices);
+
+        SwapChain swapChain = SwapChain::create(window, context, surface);
 
         std::vector<vk::Image> swapChainImages = device.getSwapchainImagesKHR(swapChain.getSwapchain());
         std::vector<vk::ImageView> imageViews;
@@ -450,11 +255,11 @@ namespace vkcv
             imageViews.push_back( device.createImageView( imageViewCreateInfo ) );
         }
 
-		const int graphicQueueFamilyIndex = queuePairsGraphics[0].first;
+		const int graphicQueueFamilyIndex = queueFamilyIndices.graphicsIndex;
 		const auto defaultCommandResources = createDefaultCommandResources(context.getDevice(), graphicQueueFamilyIndex);
 		const auto defaultSyncResources = createDefaultSyncResources(context.getDevice());
 
-        return Core(std::move(context) , window, swapChain, imageViews, defaultCommandResources, defaultSyncResources);
+        return Core(std::move(context) , window, swapChain, imageViews, defaultCommandResources, defaultSyncResources, queues);
     }
 
     const Context &Core::getContext() const
@@ -463,7 +268,7 @@ namespace vkcv
     }
 
 	Core::Core(Context &&context, const Window &window , SwapChain swapChain,  std::vector<vk::ImageView> imageViews, 
-		const CommandResources& commandResources, const SyncResources& syncResources) noexcept :
+		const CommandResources& commandResources, const SyncResources& syncResources, const VulkanQueues& queues) noexcept :
 			m_Context(std::move(context)),
 			m_window(window),
 			m_swapchain(swapChain),
@@ -474,12 +279,11 @@ namespace vkcv
 			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_SyncResources(syncResources),
+			m_Queues(queues)
 	{}
 
 	Core::~Core() noexcept {
-		std::cout << " Core " << std::endl;
-
 		for(const auto &layout : m_PipelineLayouts)
         {
 		    m_Context.m_Device.destroy(layout);
@@ -517,4 +321,19 @@ namespace vkcv
         return m_PassManager->createPass(config);
     }
 
+	void Core::beginFrame() {
+		const vk::CommandBufferUsageFlags beginFlags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit;
+		const vk::CommandBufferBeginInfo beginInfos(beginFlags);
+		m_CommandResources.commandBuffer.begin(beginInfos);
+	}
+
+	void Core::renderTriangle() {
+
+	}
+
+	void Core::endFrame() {
+		m_CommandResources.commandBuffer.end();
+		//m_Context.
+	}
+
 }
diff --git a/src/vkcv/Queues.cpp b/src/vkcv/Queues.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a0b7967f93574119cee39aa125f2c9ad856f4cb6
--- /dev/null
+++ b/src/vkcv/Queues.cpp
@@ -0,0 +1,67 @@
+#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) {
+
+		// 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 = {};
+		const float priority = 1.f;
+		std::vector<vk::DeviceQueueCreateInfo> createInfos;
+
+		for (const auto index : familyIndexSet) {
+			const vk::DeviceQueueCreateInfo graphicsCreateInfo(flags, index, 1, &priority);
+			createInfos.push_back(graphicsCreateInfo);
+		}
+		return createInfos;
+	}
+}
\ No newline at end of file
diff --git a/src/vkcv/Surface.cpp b/src/vkcv/Surface.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..29b6c646dc212cba2cc31f32dca5c4fcc023cd03
--- /dev/null
+++ b/src/vkcv/Surface.cpp
@@ -0,0 +1,27 @@
+#include "Surface.hpp"
+
+#define GLFW_INCLUDE_VULKAN
+#include <GLFW/glfw3.h>
+
+namespace vkcv {
+	/**
+	* creates surface and checks availability
+	* @param window current window for the surface
+	* @param instance Vulkan-Instance
+	* @param physicalDevice Vulkan-PhysicalDevice
+	* @return created surface
+	*/
+	vk::SurfaceKHR createSurface(GLFWwindow* window, const vk::Instance& instance, const vk::PhysicalDevice& physicalDevice) {
+		//create surface
+		VkSurfaceKHR surface;
+		if (glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &surface) != VK_SUCCESS) {
+			throw std::runtime_error("failed to create a window surface!");
+		}
+		vk::Bool32 surfaceSupport = false;
+		if (physicalDevice.getSurfaceSupportKHR(0, vk::SurfaceKHR(surface), &surfaceSupport) != vk::Result::eSuccess && surfaceSupport != true) {
+			throw std::runtime_error("surface is not supported by the device!");
+		}
+
+		return vk::SurfaceKHR(surface);
+	}
+}
diff --git a/src/vkcv/Surface.hpp b/src/vkcv/Surface.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..74aafeba821334767ac5e13cd33e1d9674e12f5b
--- /dev/null
+++ b/src/vkcv/Surface.hpp
@@ -0,0 +1,8 @@
+#pragma once
+#include <vulkan/vulkan.hpp>
+
+struct GLFWwindow;
+
+namespace vkcv {	
+	vk::SurfaceKHR createSurface(GLFWwindow* window, const vk::Instance& instance, const vk::PhysicalDevice& physicalDevice);
+}
\ No newline at end of file
diff --git a/src/vkcv/SwapChain.cpp b/src/vkcv/SwapChain.cpp
index 85f67b8d0fe252a2ab65d4e0d5baf388a7cfa862..a9aecceae02d6e909daebe8d6f0d9a6c555397fe 100644
--- a/src/vkcv/SwapChain.cpp
+++ b/src/vkcv/SwapChain.cpp
@@ -1,4 +1,3 @@
-
 #include <vkcv/SwapChain.hpp>
 
 namespace vkcv {
@@ -27,27 +26,6 @@ namespace vkcv {
         return m_format;
     }
 
-    /**
-     * creates surface and checks availability
-     * @param window current window for the surface
-     * @param instance Vulkan-Instance
-     * @param physicalDevice Vulkan-PhysicalDevice
-     * @return created surface
-     */
-    vk::SurfaceKHR createSurface(GLFWwindow *window, const vk::Instance &instance, const vk::PhysicalDevice& physicalDevice) {
-        //create surface
-        VkSurfaceKHR surface;
-        if (glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &surface) != VK_SUCCESS) {
-            throw std::runtime_error("failed to create a window surface!");
-        }
-        vk::Bool32 surfaceSupport = false;
-        if (physicalDevice.getSurfaceSupportKHR(0, vk::SurfaceKHR(surface), &surfaceSupport) != vk::Result::eSuccess && surfaceSupport != true) {
-            throw std::runtime_error("surface is not supported by the device!");
-        }
-
-        return vk::SurfaceKHR(surface);
-    }
-
     /**
      * chooses Extent and clapms values to the available
      * @param physicalDevice Vulkan-PhysicalDevice
@@ -148,13 +126,11 @@ namespace vkcv {
      * @param context that keeps instance, physicalDevice and a device.
      * @return swapchain
      */
-    SwapChain SwapChain::create(const Window &window, const Context &context) {
+    SwapChain SwapChain::create(const Window &window, const Context &context, const vk::SurfaceKHR surface) {
         const vk::Instance& instance = context.getInstance();
         const vk::PhysicalDevice& physicalDevice = context.getPhysicalDevice();
         const vk::Device& device = context.getDevice();
 
-        vk::SurfaceKHR surface = createSurface(window.getWindow(),instance,physicalDevice);
-
         vk::Extent2D extent2D = chooseSwapExtent(physicalDevice, surface, window);
         vk::SurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(physicalDevice, surface);
         vk::PresentModeKHR presentMode = choosePresentMode(physicalDevice, surface);