Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision a0c5f287ede32defdc9e98b983e2c26f8bdd1e6f)
+++ vulkan-game.cpp	(revision c1c20210c81af4cba67acbd3a93c3583d12501b6)
@@ -2,4 +2,5 @@
 
 #include <iostream>
+#include <set>
 
 #include "consts.hpp"
@@ -98,4 +99,5 @@
    createVulkanSurface();
    pickPhysicalDevice(deviceExtensions);
+   createLogicalDevice(validationLayers, deviceExtensions);
 }
 
@@ -142,4 +144,6 @@
       renderScene();
    }
+
+   vkDeviceWaitIdle(device);
 }
 
@@ -153,7 +157,13 @@
 
 void VulkanGame::cleanup() {
+   cleanupSwapChain();
+
+   vkDestroyDevice(device, nullptr);
+   vkDestroySurfaceKHR(instance, surface, nullptr);
+
    if (ENABLE_VALIDATION_LAYERS) {
       VulkanUtils::destroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
    }
+
    vkDestroyInstance(instance, nullptr);
 
@@ -164,4 +174,7 @@
    gui->shutdown();
    delete gui;
+}
+
+void VulkanGame::cleanupSwapChain() {
 }
 
@@ -295,2 +308,51 @@
    return indices.isComplete() && extensionsSupported && swapChainAdequate && supportedFeatures.samplerAnisotropy;
 }
+
+void VulkanGame::createLogicalDevice(
+      const vector<const char*> validationLayers,
+      const vector<const char*>& deviceExtensions) {
+   QueueFamilyIndices indices = VulkanUtils::findQueueFamilies(physicalDevice, surface);
+
+   vector<VkDeviceQueueCreateInfo> queueCreateInfos;
+   set<uint32_t> uniqueQueueFamilies = { indices.graphicsFamily.value(), indices.presentFamily.value() };
+
+   float queuePriority = 1.0f;
+   for (uint32_t queueFamily : uniqueQueueFamilies) {
+      VkDeviceQueueCreateInfo queueCreateInfo = {};
+      queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+      queueCreateInfo.queueFamilyIndex = queueFamily;
+      queueCreateInfo.queueCount = 1;
+      queueCreateInfo.pQueuePriorities = &queuePriority;
+
+      queueCreateInfos.push_back(queueCreateInfo);
+   }
+
+   VkPhysicalDeviceFeatures deviceFeatures = {};
+   deviceFeatures.samplerAnisotropy = VK_TRUE;
+
+   VkDeviceCreateInfo createInfo = {};
+   createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+   createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
+   createInfo.pQueueCreateInfos = queueCreateInfos.data();
+
+   createInfo.pEnabledFeatures = &deviceFeatures;
+
+   createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
+   createInfo.ppEnabledExtensionNames = deviceExtensions.data();
+
+   // These fields are ignored  by up-to-date Vulkan implementations,
+   // but it's a good idea to set them for backwards compatibility
+   if (ENABLE_VALIDATION_LAYERS) {
+      createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
+      createInfo.ppEnabledLayerNames = validationLayers.data();
+   } else {
+      createInfo.enabledLayerCount = 0;
+   }
+
+   if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
+      throw runtime_error("failed to create logical device!");
+   }
+
+   vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);
+   vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
+}
Index: vulkan-game.hpp
===================================================================
--- vulkan-game.hpp	(revision a0c5f287ede32defdc9e98b983e2c26f8bdd1e6f)
+++ vulkan-game.hpp	(revision c1c20210c81af4cba67acbd3a93c3583d12501b6)
@@ -28,4 +28,8 @@
       VkSurfaceKHR surface; // TODO: Change the variable name to vulkanSurface
       VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
+      VkDevice device;
+
+      VkQueue graphicsQueue;
+      VkQueue presentQueue;
 
       bool initWindow(int width, int height, unsigned char guiFlags);
@@ -42,4 +46,8 @@
       void pickPhysicalDevice(const vector<const char*>& deviceExtensions);
       bool isDeviceSuitable(VkPhysicalDevice device, const vector<const char*>& deviceExtensions);
+      void createLogicalDevice(
+         const vector<const char*> validationLayers,
+         const vector<const char*>& deviceExtensions);
+      void cleanupSwapChain();
 
       static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
Index: vulkan-ref.cpp
===================================================================
--- vulkan-ref.cpp	(revision a0c5f287ede32defdc9e98b983e2c26f8bdd1e6f)
+++ vulkan-ref.cpp	(revision c1c20210c81af4cba67acbd3a93c3583d12501b6)
@@ -164,9 +164,9 @@
 
       VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
-/*** END OF REFACTORED CODE ***/
       VkDevice device;
 
       VkQueue graphicsQueue;
       VkQueue presentQueue;
+/*** END OF REFACTORED CODE ***/
 
       VkSwapchainKHR swapChain;
@@ -316,6 +316,6 @@
          createSurface();
          pickPhysicalDevice();
+         createLogicalDevice();
 /*** END OF REFACTORED CODE ***/
-         createLogicalDevice();
          createSwapChain();
          createImageViews();
@@ -561,5 +561,4 @@
          return requiredExtensions.empty();
       }
-/*** END OF REFACTORED CODE ***/
 
       void createLogicalDevice() {
@@ -609,4 +608,5 @@
          vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
       }
+/*** END OF REFACTORED CODE ***/
 
       void createSwapChain() {
@@ -1674,4 +1674,5 @@
       }
 
+/*** START OF REFACTORED CODE ***/
       void mainLoop() {
          // TODO: Create some generic event-handling functions in game-gui-*
@@ -1690,4 +1691,5 @@
                   quit = true;
                }
+/*** END OF REFACTORED CODE ***/
                if (e.type == SDL_WINDOWEVENT) {
                   if (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED ||
@@ -1696,4 +1698,5 @@
                   }
                }
+/*** START OF REFACTORED CODE ***/
             }
 
@@ -1705,4 +1708,5 @@
          vkDeviceWaitIdle(device);
       }
+/*** END OF REFACTORED CODE ***/
 
       void drawFrame() {
@@ -1853,6 +1857,8 @@
       }
 
+/*** START OF REFACTORED CODE ***/
       void cleanup() {
          cleanupSwapChain();
+/*** END OF REFACTORED CODE ***/
 
          vkDestroySampler(device, textureSampler, nullptr);
@@ -1880,8 +1886,8 @@
 
          vkDestroyCommandPool(device, commandPool, nullptr);
+/*** START OF REFACTORED CODE ***/
          vkDestroyDevice(device, nullptr);
          vkDestroySurfaceKHR(instance, surface, nullptr);
 
-/*** START OF REFACTORED CODE ***/
          if (enableValidationLayers) {
             DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
@@ -1919,8 +1925,8 @@
          gui->shutdown();
          delete gui;
+      }
+
+      void cleanupSwapChain() {
 /*** END OF REFACTORED CODE ***/
-      }
-
-      void cleanupSwapChain() {
          vkDestroyImageView(device, depthImageView, nullptr);
          vkDestroyImage(device, depthImage, nullptr);
@@ -1948,5 +1954,7 @@
             vkFreeMemory(device, uniformBuffersMemory[i], nullptr);
          }
-      }
+/*** START OF REFACTORED CODE ***/
+      }
+/*** END OF REFACTORED CODE ***/
 
       void cleanupPipeline(GraphicsPipelineInfo& pipeline) {
