Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision f94eea9cc8966583fd608bcd0f1a25213a8e8d71)
+++ vulkan-game.cpp	(revision 6fc24c7297278ec4d1c89725b3f9a0f98a6adcca)
@@ -1,4 +1,5 @@
 #include "vulkan-game.hpp"
 
+#include <array>
 #include <iostream>
 #include <set>
@@ -102,4 +103,5 @@
    createSwapChain();
    createImageViews();
+   createRenderPass();
 }
 
@@ -419,5 +421,74 @@
 }
 
+void VulkanGame::createRenderPass() {
+   VkAttachmentDescription colorAttachment = {};
+   colorAttachment.format = swapChainImageFormat;
+   colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
+   colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+   colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+   colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+   colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+   colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+   colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+
+   VkAttachmentReference colorAttachmentRef = {};
+   colorAttachmentRef.attachment = 0;
+   colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+   VkAttachmentDescription depthAttachment = {};
+   depthAttachment.format = findDepthFormat();
+   depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
+   depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+   depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+   depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+   depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+   depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+   depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+   VkAttachmentReference depthAttachmentRef = {};
+   depthAttachmentRef.attachment = 1;
+   depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+   VkSubpassDescription subpass = {};
+   subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+   subpass.colorAttachmentCount = 1;
+   subpass.pColorAttachments = &colorAttachmentRef;
+   subpass.pDepthStencilAttachment = &depthAttachmentRef;
+
+   VkSubpassDependency dependency = {};
+   dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
+   dependency.dstSubpass = 0;
+   dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+   dependency.srcAccessMask = 0;
+   dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+   dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+
+   array<VkAttachmentDescription, 2> attachments = { colorAttachment, depthAttachment };
+   VkRenderPassCreateInfo renderPassInfo = {};
+   renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+   renderPassInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
+   renderPassInfo.pAttachments = attachments.data();
+   renderPassInfo.subpassCount = 1;
+   renderPassInfo.pSubpasses = &subpass;
+   renderPassInfo.dependencyCount = 1;
+   renderPassInfo.pDependencies = &dependency;
+
+   if (vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) {
+      throw runtime_error("failed to create render pass!");
+   }
+}
+
+VkFormat VulkanGame::findDepthFormat() {
+   return VulkanUtils::findSupportedFormat(
+      physicalDevice,
+      { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT },
+      VK_IMAGE_TILING_OPTIMAL,
+      VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
+   );
+}
+
 void VulkanGame::cleanupSwapChain() {
+   vkDestroyRenderPass(device, renderPass, nullptr);
+
    for (auto imageView : swapChainImageViews) {
       vkDestroyImageView(device, imageView, nullptr);
Index: vulkan-game.hpp
===================================================================
--- vulkan-game.hpp	(revision f94eea9cc8966583fd608bcd0f1a25213a8e8d71)
+++ vulkan-game.hpp	(revision 6fc24c7297278ec4d1c89725b3f9a0f98a6adcca)
@@ -38,4 +38,5 @@
       VkExtent2D swapChainExtent;
       vector<VkImageView> swapChainImageViews;
+      VkRenderPass renderPass;
 
       bool initWindow(int width, int height, unsigned char guiFlags);
@@ -57,4 +58,6 @@
       void createSwapChain();
       void createImageViews();
+      void createRenderPass();
+      VkFormat findDepthFormat();
 
       void cleanupSwapChain();
Index: vulkan-ref.cpp
===================================================================
--- vulkan-ref.cpp	(revision f94eea9cc8966583fd608bcd0f1a25213a8e8d71)
+++ vulkan-ref.cpp	(revision 6fc24c7297278ec4d1c89725b3f9a0f98a6adcca)
@@ -177,5 +177,7 @@
       vector<VkFramebuffer> swapChainFramebuffers;
 
+/*** START OF REFACTORED CODE ***/
       VkRenderPass renderPass;
+/*** END OF REFACTORED CODE ***/
 
       VkCommandPool commandPool;
@@ -319,6 +321,6 @@
          createSwapChain();
          createImageViews();
+         createRenderPass();
 /*** END OF REFACTORED CODE ***/
-         createRenderPass();
 
          createCommandPool();
@@ -734,5 +736,4 @@
          }
       }
-/*** END OF REFACTORED CODE ***/
 
       void createRenderPass() {
@@ -793,4 +794,5 @@
          }
       }
+/*** END OF REFACTORED CODE ***/
 
       void initGraphicsPipelineInfo(GraphicsPipelineInfo& info,
@@ -1080,4 +1082,5 @@
       }
 
+/*** START OF REFACTORED CODE ***/
       VkFormat findDepthFormat() {
          return findSupportedFormat(
@@ -1105,4 +1108,5 @@
          throw runtime_error("failed to find supported format!");
       }
+/*** END OF REFACTORED CODE ***/
 
       bool hasStencilComponent(VkFormat format) {
@@ -1948,7 +1952,7 @@
          cleanupPipeline(overlayPipeline);
 
+/*** START OF REFACTORED CODE ***/
          vkDestroyRenderPass(device, renderPass, nullptr);
 
-/*** START OF REFACTORED CODE ***/
          for (auto imageView : swapChainImageViews) {
             vkDestroyImageView(device, imageView, nullptr);
Index: vulkan-utils.cpp
===================================================================
--- vulkan-utils.cpp	(revision f94eea9cc8966583fd608bcd0f1a25213a8e8d71)
+++ vulkan-utils.cpp	(revision 6fc24c7297278ec4d1c89725b3f9a0f98a6adcca)
@@ -192,2 +192,20 @@
    return imageView;
 }
+
+VkFormat VulkanUtils::findSupportedFormat(VkPhysicalDevice physicalDevice, const vector<VkFormat>& candidates,
+      VkImageTiling tiling, VkFormatFeatureFlags features) {
+   for (VkFormat format : candidates) {
+      VkFormatProperties props;
+      vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &props);
+
+      if (tiling == VK_IMAGE_TILING_LINEAR &&
+            (props.linearTilingFeatures & features) == features) {
+         return format;
+      } else if (tiling == VK_IMAGE_TILING_OPTIMAL &&
+            (props.optimalTilingFeatures & features) == features) {
+         return format;
+      }
+   }
+
+   throw runtime_error("failed to find supported format!");
+}
Index: vulkan-utils.hpp
===================================================================
--- vulkan-utils.hpp	(revision f94eea9cc8966583fd608bcd0f1a25213a8e8d71)
+++ vulkan-utils.hpp	(revision 6fc24c7297278ec4d1c89725b3f9a0f98a6adcca)
@@ -44,4 +44,6 @@
       static VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, int width, int height);
       static VkImageView createImageView(VkDevice device, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags);
+      static VkFormat findSupportedFormat(VkPhysicalDevice physicalDevice, const vector<VkFormat>& candidates,
+            VkImageTiling tiling, VkFormatFeatureFlags features);
 };
 
