Index: README.txt
===================================================================
--- README.txt	(revision ab65f848693b96b871a88175e5fdf39315dd7684)
+++ README.txt	(revision b6127d23cf6cc5e4760bb05b426570b2f3bc6366)
@@ -62,4 +62,6 @@
 Download the vulkan sdk (make sure VULKAN_SDK_PATH in the makefile points to it)
 
+source setup-env.sh into your current shell
+
 make vulkcangame && ./vulkangame
 
Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision ab65f848693b96b871a88175e5fdf39315dd7684)
+++ vulkan-game.cpp	(revision b6127d23cf6cc5e4760bb05b426570b2f3bc6366)
@@ -20,4 +20,7 @@
 using namespace std;
 using namespace glm;
+
+bool checkValidationLayerSupport();
+vector<const char*> getRequiredExtensions(SDL_Window* window);
 
 const int SCREEN_WIDTH = 800;
@@ -34,4 +37,28 @@
 #endif
 
+static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
+      VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+      VkDebugUtilsMessageTypeFlagsEXT messageType,
+      const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
+      void* pUserData) {
+   cerr << "validation layer: " << pCallbackData->pMessage << endl;
+
+   return VK_FALSE;
+}
+
+VkResult CreateDebugUtilsMessengerEXT(VkInstance instance,
+      const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
+      const VkAllocationCallbacks* pAllocator,
+      VkDebugUtilsMessengerEXT* pDebugMessenger) {
+   auto func = (PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(
+      instance, "vkCreateDebugUtilsMessengerEXT");
+
+   if (func != nullptr) {
+      return func(instance, pCreateInfo, pAllocator, pDebugMessenger);
+   } else {
+      return VK_ERROR_EXTENSION_NOT_PRESENT;
+   }
+}
+
 class VulkanGame {
    public:
@@ -50,4 +77,5 @@
 
       VkInstance instance;
+      VkDebugUtilsMessengerEXT debugMessenger;
 
       // both SDL and GLFW create window functions return NULL on failure
@@ -77,7 +105,12 @@
       void initVulkan() {
          createInstance();
+	 setupDebugMessenger();
       }
 
       void createInstance() {
+         if (enableValidationLayers && !checkValidationLayerSupport()) {
+            throw runtime_error("validation layers requested, but not available!");
+         }
+
          VkApplicationInfo appInfo = {};
          appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
@@ -92,16 +125,32 @@
          createInfo.pApplicationInfo = &appInfo;
 
-         uint32_t extensionCount;
-         SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, nullptr);
-
-         vector<const char*> extensionNames(extensionCount);
-         SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, extensionNames.data());
-
-         createInfo.enabledExtensionCount = extensionCount;
-         createInfo.ppEnabledExtensionNames = extensionNames.data();
-         createInfo.enabledLayerCount = 0;
+         auto extensions = getRequiredExtensions(window);
+         createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
+         createInfo.ppEnabledExtensionNames = extensions.data();
+
+         if (enableValidationLayers) {
+            createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
+            createInfo.ppEnabledLayerNames = validationLayers.data();
+         } else {
+            createInfo.enabledLayerCount = 0;
+         }
 
          if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
             throw runtime_error("failed to create instance!");
+         }
+      }
+
+      void setupDebugMessenger() {
+         if (!enableValidationLayers) return;
+
+         VkDebugUtilsMessengerCreateInfoEXT createInfo = {};
+         createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
+         createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
+         createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
+         createInfo.pfnUserCallback = debugCallback;
+         createInfo.pUserData = nullptr;
+
+         if (CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger) != VK_SUCCESS) {
+            throw runtime_error("failed to setup debug messenger!");
          }
       }
@@ -156,4 +205,43 @@
 };
 
+vector<const char*> getRequiredExtensions(SDL_Window* window) {
+   uint32_t extensionCount;
+   SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, nullptr);
+
+   vector<const char*> extensions(extensionCount);
+   SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, extensions.data());
+
+   if (enableValidationLayers) {
+      extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
+   }
+
+   return extensions;
+}
+
+bool checkValidationLayerSupport() {
+   uint32_t layerCount;
+   vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
+
+   vector<VkLayerProperties> availableLayers(layerCount);
+   vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
+
+   for (const char* layerName : validationLayers) {
+      bool layerFound = false;
+
+      for (const auto& layerProperties : availableLayers) {
+         if (strcmp(layerName, layerProperties.layerName) == 0) {
+            layerFound = true;
+            break;
+         }
+      }
+
+      if (!layerFound) {
+         return false;
+      }
+   }
+
+   return true;
+}
+
 int main() {
 
@@ -163,27 +251,4 @@
    cout << "DEBUGGING IS ON" << endl;
 #endif
-
-   /*
-   glfwInit();
-
-   glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
-   GLFWwindow* window = glfwCreateWindow(800, 600, "Vulkan window", nullptr, nullptr);
-
-   uint32_t extensionCount = 0;
-   vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
-
-   cout << extensionCount << " extensions supported" << endl;
-   */
-
-   /*
-   while(!glfwWindowShouldClose(window)) {
-      glfwPollEvents();
-   }
-
-   glfwDestroyWindow(window);
-
-   glfwTerminate();
-   */
-
    /*
    mat4 matrix;
