diff --git a/src/main.cpp b/src/main.cpp
index 6ab99a1..543310e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -12,6 +12,7 @@
 #include <vulkan/vulkan_raii.hpp>
 #include <GLFW/glfw3.h>
 #define GLM_FORCE_RADIANS
+#define GLM_FORCE_DEPTH_ZERO_TO_ONE
 #include <glm/glm.hpp>
 #include <glm/gtc/matrix_transform.hpp>
 #define STB_IMAGE_IMPLEMENTATION
@@ -52,7 +53,7 @@ struct SwapChainSupportDetails {
 };
 
 struct Vertex {
-    glm::vec2 pos;
+    glm::vec3 pos;
     glm::vec3 color;
     glm::vec2 texCoord;
 
@@ -67,7 +68,7 @@ struct Vertex {
         std::array<vk::VertexInputAttributeDescription, 3> attributeDescriptions;
         attributeDescriptions[0].binding = 0;
         attributeDescriptions[0].location = 0;
-        attributeDescriptions[0].format = vk::Format::eR32G32Sfloat;
+        attributeDescriptions[0].format = vk::Format::eR32G32B32Sfloat;
         attributeDescriptions[0].offset = offsetof(Vertex, pos);
         attributeDescriptions[1].binding = 0;
         attributeDescriptions[1].location = 1;
@@ -83,14 +84,19 @@ struct Vertex {
 };
 
 const std::vector<Vertex> vertices = {
-    {{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f}},
-    {{0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
-    {{0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f}},
-    {{-0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}
+    {{-0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f}},
+    {{0.5f, -0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
+    {{0.5f, 0.5f, 0.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f}},
+    {{-0.5f, 0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
+    {{-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
+    {{0.5f, -0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
+    {{0.5f, 0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
+    {{-0.5f, 0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}
 };
 
 const std::vector<uint32_t> indices = {
-    0, 1, 2, 2, 3, 0
+    0, 1, 2, 2, 3, 0,
+    4, 5, 6, 6, 7, 4
 };
 
 struct UniformBufferObject {
@@ -125,6 +131,9 @@ private:
     vk::Format m_swapChainImageFormat{};
     vk::Extent2D m_swapChainExtent{};
     std::vector<vk::raii::ImageView> m_swapChainImageViews;
+    vk::raii::DeviceMemory m_depthImageMemory{ nullptr };
+    vk::raii::Image m_depthImage{ nullptr };
+    vk::raii::ImageView m_depthImageView{ nullptr };
     vk::raii::RenderPass m_renderPass{ nullptr };
     std::vector<vk::raii::Framebuffer> m_swapChainFramebuffers;
     std::vector<vk::raii::DescriptorSetLayout> m_descriptorSetLayouts;
@@ -179,11 +188,12 @@ private:
         createSwapChain();
         createImageViews();
         createRenderPass();
-        createFramebuffers();
         createDescriptorSetLayout();
         createGraphicsPipeline();
         createCommandPool();
         createCommandBuffers();
+        createDepthResources();
+        createFramebuffers();
         createSyncObjects();
         createVertexBuffer();
         createIndexBuffer();
@@ -479,7 +489,9 @@ private:
     void createImageViews() {
         m_swapChainImageViews.reserve( m_swapChainImages.size() );
         for (const auto& image : m_swapChainImages) {
-            m_swapChainImageViews.emplace_back( createImageView(image, m_swapChainImageFormat) );
+            m_swapChainImageViews.emplace_back(
+                createImageView(image, m_swapChainImageFormat, vk::ImageAspectFlagBits::eColor)
+            );
         }
     }
     /////////////////////////////////////////////////////////////
@@ -501,20 +513,36 @@ private:
         colorAttachmentRef.attachment = 0;
         colorAttachmentRef.layout = vk::ImageLayout::eColorAttachmentOptimal;
 
+        vk::AttachmentDescription depthAttachment;
+        depthAttachment.format = findDepthFormat({vk::Format::eD32Sfloat, vk::Format::eD32SfloatS8Uint, vk::Format::eD24UnormS8Uint});
+        depthAttachment.samples = vk::SampleCountFlagBits::e1;
+        depthAttachment.loadOp = vk::AttachmentLoadOp::eClear;
+        depthAttachment.storeOp = vk::AttachmentStoreOp::eDontCare;
+        depthAttachment.stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
+        depthAttachment.stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
+        depthAttachment.initialLayout = vk::ImageLayout::eUndefined;
+        depthAttachment.finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
+
+        vk::AttachmentReference depthAttachmentRef;
+        depthAttachmentRef.attachment = 1;
+        depthAttachmentRef.layout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
+
         vk::SubpassDescription subpass;
         subpass.pipelineBindPoint = vk::PipelineBindPoint::eGraphics;
         subpass.setColorAttachments( colorAttachmentRef );
+        subpass.pDepthStencilAttachment = &depthAttachmentRef;
 
         vk::SubpassDependency dependency;
         dependency.srcSubpass = vk::SubpassExternal;
         dependency.dstSubpass = 0;
-        dependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
-        dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
-        dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
+        dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests;
         dependency.srcAccessMask = {};
+        dependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests;
+        dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
 
+        const auto attachments = { colorAttachment, depthAttachment };
         vk::RenderPassCreateInfo renderPassInfo;
-        renderPassInfo.setAttachments( colorAttachment );
+        renderPassInfo.setAttachments( attachments );
         renderPassInfo.setSubpasses( subpass );
         renderPassInfo.setDependencies( dependency );
 
@@ -527,8 +555,9 @@ private:
         framebufferInfo.width = m_swapChainExtent.width;
         framebufferInfo.height = m_swapChainExtent.height;
         framebufferInfo.layers = 1;
-        for (const auto& imageView : m_swapChainImageViews) {
-            framebufferInfo.setAttachments( *imageView );
+        for (const auto& swapchainImageView : m_swapChainImageViews) {
+            const std::array<vk::ImageView, 2> imageViews { swapchainImageView, m_depthImageView };
+            framebufferInfo.setAttachments( imageViews );
             m_swapChainFramebuffers.emplace_back( m_device.createFramebuffer(framebufferInfo) );
         }
     }
@@ -599,6 +628,11 @@ private:
         multisampling.rasterizationSamples =  vk::SampleCountFlagBits::e1;
         multisampling.sampleShadingEnable = false;
 
+        vk::PipelineDepthStencilStateCreateInfo depthStencil;
+        depthStencil.depthTestEnable = true;
+        depthStencil.depthWriteEnable = true;
+        depthStencil.depthCompareOp = vk::CompareOp::eLess;
+
         vk::PipelineColorBlendAttachmentState colorBlendAttachment;
         colorBlendAttachment.blendEnable = false; // default
         colorBlendAttachment.colorWriteMask = vk::FlagTraits<vk::ColorComponentFlagBits>::allFlags;
@@ -621,7 +655,7 @@ private:
         pipelineInfo.pViewportState = &viewportState;
         pipelineInfo.pRasterizationState = &rasterizer;
         pipelineInfo.pMultisampleState = &multisampling;
-        pipelineInfo.pDepthStencilState = nullptr; // Optional
+        pipelineInfo.pDepthStencilState = &depthStencil;
         pipelineInfo.pColorBlendState = &colorBlending;
         pipelineInfo.pDynamicState = &dynamicState;
         pipelineInfo.layout = m_pipelineLayout;
@@ -661,8 +695,12 @@ private:
         renderPassInfo.framebuffer = m_swapChainFramebuffers[imageIndex];
         renderPassInfo.renderArea.offset = vk::Offset2D{0, 0};
         renderPassInfo.renderArea.extent = m_swapChainExtent;
-        constexpr vk::ClearValue clearColor(vk::ClearColorValue(0.0f, 0.0f, 0.0f, 1.0f));
-        renderPassInfo.setClearValues( clearColor );
+
+        std::array<vk::ClearValue, 2> clearValues;
+        clearValues[0].color = vk::ClearColorValue{0.0f, 0.0f, 0.0f, 1.0f};
+        clearValues[1].depthStencil = vk::ClearDepthStencilValue{1.0f, 0};
+
+        renderPassInfo.setClearValues( clearValues );
 
         commandBuffer.beginRenderPass(renderPassInfo, vk::SubpassContents::eInline);
 
@@ -780,8 +818,13 @@ private:
         m_swapChainImages.clear(); // optional
         m_swapChain = nullptr;
 
+        m_depthImageView = nullptr;
+        m_depthImage = nullptr;
+        m_depthImageMemory = nullptr;
+
         createSwapChain();
         createImageViews();
+        createDepthResources();
         createFramebuffers();
 
         m_framebufferResized = false;
@@ -1219,12 +1262,16 @@ private:
             vk::ImageLayout::eShaderReadOnlyOptimal
         );
     }
-    vk::raii::ImageView createImageView(const vk::Image image,const vk::Format format) const {
+    vk::raii::ImageView createImageView(
+        const vk::Image image,
+        const vk::Format format,
+        const vk::ImageAspectFlags aspectFlags
+    ) const {
         vk::ImageViewCreateInfo viewInfo;
         viewInfo.image = image;
         viewInfo.viewType = vk::ImageViewType::e2D;
         viewInfo.format = format;
-        viewInfo.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor;
+        viewInfo.subresourceRange.aspectMask = aspectFlags;
         viewInfo.subresourceRange.baseMipLevel = 0;
         viewInfo.subresourceRange.levelCount = 1;
         viewInfo.subresourceRange.baseArrayLayer = 0;
@@ -1233,7 +1280,7 @@ private:
         return m_device.createImageView(viewInfo);
     }
     void createTextureImageView() {
-        m_textureImageView = createImageView(m_textureImage, vk::Format::eR8G8B8A8Srgb);
+        m_textureImageView = createImageView(m_textureImage, vk::Format::eR8G8B8A8Srgb, vk::ImageAspectFlagBits::eColor);
     }
     void createTextureSampler() {
         vk::SamplerCreateInfo samplerInfo;
@@ -1257,6 +1304,35 @@ private:
         m_textureSampler = m_device.createSampler(samplerInfo);
     }
     /////////////////////////////////////////////////////////////
+
+    /////////////////////////////////////////////////////////////
+    /// depth buffer
+    vk::Format findDepthFormat( const std::vector<vk::Format>& candidates ) const {
+        for(const vk::Format format : candidates) {
+            // vk::FormatProperties
+            const auto props = m_physicalDevice.getFormatProperties(format);
+            if(props.optimalTilingFeatures & vk::FormatFeatureFlagBits::eDepthStencilAttachment){
+                return format;
+            }
+        }
+        throw std::runtime_error("failed to find supported format!");
+    }
+    void createDepthResources() {
+        const vk::Format depthFormat = findDepthFormat({vk::Format::eD32Sfloat, vk::Format::eD32SfloatS8Uint, vk::Format::eD24UnormS8Uint});
+
+        createImage(
+            m_swapChainExtent.width,
+            m_swapChainExtent.height,
+            depthFormat,
+            vk::ImageTiling::eOptimal,
+            vk::ImageUsageFlagBits::eDepthStencilAttachment,
+            vk::MemoryPropertyFlagBits::eDeviceLocal,
+            m_depthImage,
+            m_depthImageMemory
+        );
+        m_depthImageView = createImageView(m_depthImage, depthFormat, vk::ImageAspectFlagBits::eDepth);
+    }
+    /////////////////////////////////////////////////////////////
 };
 
 int main() {
