Index: sdl-game.cpp
===================================================================
--- sdl-game.cpp	(revision ce9dc9f8d30ef01e9f3c1de05482d87c6c4a1144)
+++ sdl-game.cpp	(revision 8b823e70b085fb1894bc004664a0d5f263df62f4)
@@ -6,6 +6,4 @@
 #include <stdexcept>
 
-#include <stdlib.h>         // abort (only used in check_vk_result)
-
 #include <SDL2/SDL_vulkan.h>
 
@@ -20,11 +18,15 @@
 static bool g_SwapChainRebuild = false;
 
-static void check_vk_result(VkResult err) {
-   if (err == 0) {
+static void check_imgui_vk_result(VkResult res) {
+   if (res == VK_SUCCESS) {
       return;
    }
-   fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err);
-   if (err < 0) {
-      abort();
+
+   ostringstream oss;
+   oss << "[imgui] Vulkan error! VkResult is \"" << VulkanUtils::resultString(res) << "\"" << __LINE__;
+   if (res < 0) {
+         throw runtime_error("Fatal: " + oss.str());
+   } else {
+         cerr << oss.str();
    }
 }
@@ -37,14 +39,13 @@
       g_SwapChainRebuild = true;
       return;
-   } else if (result != VK_SUCCESS) {
-      throw runtime_error("failed to acquire swap chain image!");
-   }
-
-   if (vkWaitForFences(device, 1, &inFlightFences[imageIndex], VK_TRUE, numeric_limits<uint64_t>::max()) != VK_SUCCESS) {
-      throw runtime_error("failed waiting for fence!");
-   }
-   if (vkResetFences(device, 1, &inFlightFences[imageIndex]) != VK_SUCCESS) {
-      throw runtime_error("failed to reset fence!");
-   }
+   } else {
+      VKUTIL_CHECK_RESULT(result, "failed to acquire swap chain image!");
+   }
+
+   VKUTIL_CHECK_RESULT(vkWaitForFences(device, 1, &inFlightFences[imageIndex], VK_TRUE, numeric_limits<uint64_t>::max()),
+      "failed waiting for fence!");
+
+   VKUTIL_CHECK_RESULT(vkResetFences(device, 1, &inFlightFences[imageIndex]),
+      "failed to reset fence!");
 
    // START OF NEW CODE
@@ -52,11 +53,13 @@
    // before the render loop ever starts. I should change this
 
-   result = vkResetCommandPool(device, commandPools[imageIndex], 0);
-   check_vk_result(result);
+   VKUTIL_CHECK_RESULT(vkResetCommandPool(device, commandPools[imageIndex], 0),
+      "failed to reset command pool!");
+
    VkCommandBufferBeginInfo info = {};
    info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
    info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
-   result = vkBeginCommandBuffer(commandBuffers[imageIndex], &info);
-   check_vk_result(result);
+
+   VKUTIL_CHECK_RESULT(vkBeginCommandBuffer(commandBuffers[imageIndex], &info),
+      "failed to begin recording command buffer!");
 
    VkRenderPassBeginInfo renderPassInfo = {};
@@ -81,7 +84,6 @@
    vkCmdEndRenderPass(commandBuffers[imageIndex]);
 
-   if (vkEndCommandBuffer(commandBuffers[imageIndex]) != VK_SUCCESS) {
-      throw runtime_error("failed to record command buffer!");
-   }
+   VKUTIL_CHECK_RESULT(vkEndCommandBuffer(commandBuffers[imageIndex]),
+      "failed to record command buffer!");
 
    // END OF NEW CODE
@@ -101,7 +103,6 @@
    submitInfo.pSignalSemaphores = signalSemaphores;
 
-   if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[imageIndex]) != VK_SUCCESS) {
-      throw runtime_error("failed to submit draw command buffer!");
-   }
+   VKUTIL_CHECK_RESULT(vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[imageIndex]),
+      "failed to submit draw command buffer!");
 }
 
@@ -196,5 +197,7 @@
       pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
       pool_info.pPoolSizes = pool_sizes;
-      check_vk_result(vkCreateDescriptorPool(device, &pool_info, nullptr, &descriptorPool));
+
+      VKUTIL_CHECK_RESULT(vkCreateDescriptorPool(device, &pool_info, nullptr, &descriptorPool),
+         "failed to create descriptor pool");
    }
 
@@ -225,5 +228,5 @@
    init_info.MinImageCount = swapChainMinImageCount;
    init_info.ImageCount = swapChainImageCount;
-   init_info.CheckVkResultFn = check_vk_result;
+   init_info.CheckVkResultFn = check_imgui_vk_result;
    ImGui_ImplVulkan_Init(&init_info, renderPass);
 
Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision ce9dc9f8d30ef01e9f3c1de05482d87c6c4a1144)
+++ vulkan-game.cpp	(revision 8b823e70b085fb1894bc004664a0d5f263df62f4)
@@ -38,11 +38,16 @@
  */
 
-// Put in here to use for IMGUI, but I might use something similar in other places as well
-static void check_vk_result(VkResult result) {
-   if (result == VK_SUCCESS)
+static void check_imgui_vk_result(VkResult res) {
+   if (res == VK_SUCCESS) {
       return;
-   fprintf(stderr, "[vulkan] Error: VkResult = %d\n", result);
-   if (result < 0)
-      abort();
+   }
+
+   ostringstream oss;
+   oss << "[imgui] Vulkan error! VkResult is \"" << VulkanUtils::resultString(res) << "\"" << __LINE__;
+   if (res < 0) {
+      throw runtime_error("Fatal: " + oss.str());
+   } else {
+      cerr << oss.str();
+   }
 }
 
@@ -251,5 +256,5 @@
    init_info.MinImageCount = this->swapChainMinImageCount;
    init_info.ImageCount = this->swapChainImageCount;
-   init_info.CheckVkResultFn = check_vk_result;
+   init_info.CheckVkResultFn = check_imgui_vk_result;
    ImGui_ImplVulkan_Init(&init_info, this->renderPass);
 
@@ -261,6 +266,4 @@
    // Upload Fonts
    {
-      VkResult err;
-
       VkCommandBuffer command_buffer;
 
@@ -271,6 +274,7 @@
       info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
       info.commandBufferCount = 1;
-      err = vkAllocateCommandBuffers(this->device, &info, &command_buffer);
-      check_vk_result(err);
+
+      VKUTIL_CHECK_RESULT(vkAllocateCommandBuffers(this->device, &info, &command_buffer),
+         "failed to allocate command buffers!");
 
       //err = vkResetCommandPool(this->device, command_pool, 0); // Probably not really needed here since the command pool is never used before this
@@ -279,6 +283,6 @@
       begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
       begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
-      err = vkBeginCommandBuffer(command_buffer, &begin_info);
-      check_vk_result(err);
+      VKUTIL_CHECK_RESULT(vkBeginCommandBuffer(command_buffer, &begin_info),
+         "failed to begin recording command buffer!");
 
       ImGui_ImplVulkan_CreateFontsTexture(command_buffer);
@@ -288,8 +292,10 @@
       end_info.commandBufferCount = 1;
       end_info.pCommandBuffers = &command_buffer;
-      err = vkEndCommandBuffer(command_buffer);
-      check_vk_result(err);
-      err = vkQueueSubmit(this->graphicsQueue, 1, &end_info, VK_NULL_HANDLE);
-      check_vk_result(err);
+
+      VKUTIL_CHECK_RESULT(vkEndCommandBuffer(command_buffer),
+         "failed to record command buffer!");
+
+      VKUTIL_CHECK_RESULT(vkQueueSubmit(this->graphicsQueue, 1, &end_info, VK_NULL_HANDLE),
+         "failed to submit draw command buffer!");
 
       if (vkDeviceWaitIdle(this->device) != VK_SUCCESS) {
@@ -300,6 +306,6 @@
 
       // This should make the command pool reusable for later
-      err = vkResetCommandPool(this->device, resourceCommandPool, 0);
-      check_vk_result(err);
+      VKUTIL_CHECK_RESULT(vkResetCommandPool(this->device, resourceCommandPool, 0),
+         "failed to reset command pool!");
    }
 
Index: vulkan-utils.cpp
===================================================================
--- vulkan-utils.cpp	(revision ce9dc9f8d30ef01e9f3c1de05482d87c6c4a1144)
+++ vulkan-utils.cpp	(revision 8b823e70b085fb1894bc004664a0d5f263df62f4)
@@ -8,4 +8,38 @@
 #define STB_IMAGE_IMPLEMENTATION
 #include "stb_image.h" // TODO: Probably switch to SDL_image
+
+string VulkanUtils::resultString(VkResult result) {
+#define STR(r) case VK_ ##r: return #r
+
+   switch (result) {
+      STR(NOT_READY);
+      STR(TIMEOUT);
+      STR(EVENT_SET);
+      STR(EVENT_RESET);
+      STR(INCOMPLETE);
+      STR(ERROR_OUT_OF_HOST_MEMORY);
+      STR(ERROR_OUT_OF_DEVICE_MEMORY);
+      STR(ERROR_INITIALIZATION_FAILED);
+      STR(ERROR_DEVICE_LOST);
+      STR(ERROR_MEMORY_MAP_FAILED);
+      STR(ERROR_LAYER_NOT_PRESENT);
+      STR(ERROR_EXTENSION_NOT_PRESENT);
+      STR(ERROR_FEATURE_NOT_PRESENT);
+      STR(ERROR_INCOMPATIBLE_DRIVER);
+      STR(ERROR_TOO_MANY_OBJECTS);
+      STR(ERROR_FORMAT_NOT_SUPPORTED);
+      STR(ERROR_SURFACE_LOST_KHR);
+      STR(ERROR_NATIVE_WINDOW_IN_USE_KHR);
+      STR(SUBOPTIMAL_KHR);
+      STR(ERROR_OUT_OF_DATE_KHR);
+      STR(ERROR_INCOMPATIBLE_DISPLAY_KHR);
+      STR(ERROR_VALIDATION_FAILED_EXT);
+      STR(ERROR_INVALID_SHADER_NV);
+   default:
+      return "UNKNOWN_ERROR";
+   }
+
+#undef STR
+}
 
 bool VulkanUtils::checkValidationLayerSupport(const vector<const char*> &validationLayers) {
Index: vulkan-utils.hpp
===================================================================
--- vulkan-utils.hpp	(revision ce9dc9f8d30ef01e9f3c1de05482d87c6c4a1144)
+++ vulkan-utils.hpp	(revision 8b823e70b085fb1894bc004664a0d5f263df62f4)
@@ -3,4 +3,6 @@
 
 #include <optional>
+#include <sstream>
+#include <stdexcept>
 #include <string>
 #include <vector>
@@ -32,4 +34,6 @@
 class VulkanUtils {
    public:
+      static string resultString(VkResult result);
+
       static bool checkValidationLayerSupport(const vector<const char*> &validationLayers);
 
@@ -136,3 +140,18 @@
 }
 
+#define VKUTIL_CHECK_RESULT(f, msg) {                                                                                      \
+   VkResult res = (f);                                                                                                     \
+                                                                                                                           \
+   if (res != VK_SUCCESS) {                                                                                                \
+      ostringstream oss;                                                                                                   \
+      oss << msg << " VkResult is \"" << VulkanUtils::resultString(res) << "\" in " << __FILE__ << " at line " << __LINE__;\
+                                                                                                                           \
+      if (res < 0) {                                                                                                       \
+         throw runtime_error("Fatal: " + oss.str());                                                                       \
+      } else {                                                                                                             \
+         cerr << oss.str();                                                                                                \
+      }                                                                                                                    \
+   }                                                                                                                       \
+}
+
 #endif // _VULKAN_UTILS_H
