diff --git a/src/main.cpp b/src/main.cpp
index be62e61..e592d98 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -22,9 +22,6 @@ public:
 private:
     /////////////////////////////////////////////////////////////////
     /// static values
-    #include <array>
-    // ......
-
     static constexpr uint32_t WIDTH = 800;
     static constexpr uint32_t HEIGHT = 600;
 
@@ -45,9 +42,11 @@ private:
     vk::raii::Context m_context;
     vk::raii::Instance m_instance{ nullptr };
     vk::raii::DebugUtilsMessengerEXT m_debugMessenger{ nullptr };
+    vk::raii::SurfaceKHR m_surface{ nullptr };
     vk::raii::PhysicalDevice m_physicalDevice{ nullptr };
     vk::raii::Device m_device{ nullptr };
     vk::raii::Queue m_graphicsQueue{ nullptr };
+    vk::raii::Queue m_presentQueue{ nullptr };
     /////////////////////////////////////////////////////////////////
 
     /////////////////////////////////////////////////////////////////
@@ -64,6 +63,7 @@ private:
     void initVulkan() {
         createInstance();
         setupDebugMessenger();
+        createSurface();
         pickPhysicalDevice();
         createLogicalDevice();
     }
@@ -182,9 +182,10 @@ private:
     /// physical device
     struct QueueFamilyIndices {
         std::optional<uint32_t> graphicsFamily;
+        std::optional<uint32_t> presentFamily;
 
         bool isComplete() {
-            return graphicsFamily.has_value();
+            return graphicsFamily.has_value() && presentFamily.has_value();
         }
     };
     bool isDeviceSuitable(const vk::raii::PhysicalDevice& physicalDevice) {
@@ -218,6 +219,9 @@ private:
             if (queueFamily.queueFlags & vk::QueueFlagBits::eGraphics) {
                 indices.graphicsFamily = i;
             }
+            if(physicalDevice.getSurfaceSupportKHR(i, m_surface)){
+                indices.presentFamily = i;
+            }
             if (indices.isComplete()) {
                 break;
             }
@@ -234,16 +238,22 @@ private:
     void createLogicalDevice() {
         QueueFamilyIndices indices = findQueueFamilies( m_physicalDevice );
 
-        vk::DeviceQueueCreateInfo queueCreateInfo;
-        queueCreateInfo.queueFamilyIndex = indices.graphicsFamily.value();
+        std::vector<vk::DeviceQueueCreateInfo> queueCreateInfos;
+        // isDeviceSuitable() ensure queue availability
+        std::set<uint32_t> uniqueQueueFamilies = {indices.graphicsFamily.value(), indices.presentFamily.value()};
 
         float queuePriority = 1.0f;
-        queueCreateInfo.setQueuePriorities( queuePriority );
+        for (uint32_t queueFamily : uniqueQueueFamilies) {
+            vk::DeviceQueueCreateInfo queueCreateInfo;
+            queueCreateInfo.queueFamilyIndex = queueFamily;
+            queueCreateInfo.setQueuePriorities( queuePriority );
+            queueCreateInfos.emplace_back( queueCreateInfo );
+        }
 
         vk::PhysicalDeviceFeatures deviceFeatures;
 
         vk::DeviceCreateInfo createInfo;
-        createInfo.setQueueCreateInfos( queueCreateInfo );
+        createInfo.setQueueCreateInfos( queueCreateInfos );
         createInfo.pEnabledFeatures = &deviceFeatures;
 
         if (enableValidationLayers) {
@@ -252,6 +262,19 @@ private:
 
         m_device = m_physicalDevice.createDevice( createInfo );
         m_graphicsQueue = m_device.getQueue( indices.graphicsFamily.value(), 0 );
+        m_presentQueue = m_device.getQueue( indices.presentFamily.value(), 0 );
+    }
+    /////////////////////////////////////////////////////////////////
+
+    /////////////////////////////////////////////////////////////////
+    /// surface
+    void createSurface() {
+        VkSurfaceKHR cSurface;
+
+        if (glfwCreateWindowSurface( *m_instance, m_window, nullptr, &cSurface ) != VK_SUCCESS) {
+            throw std::runtime_error("failed to create window surface!");
+        }
+        m_surface = vk::raii::SurfaceKHR( m_instance, cSurface );
     }
     /////////////////////////////////////////////////////////////////
 };
