diff --git a/src/main.cpp b/src/main.cpp
index 2b0dcd3..b39ee73 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -40,6 +40,8 @@ private:
     #else
         static constexpr bool enableValidationLayers = true;
     #endif
+
+    static constexpr int MAX_FRAMES_IN_FLIGHT = 2;
     /////////////////////////////////////////////////////////////////
 
     /////////////////////////////////////////////////////////////////
@@ -64,9 +66,10 @@ private:
     std::vector<vk::raii::Framebuffer> m_swapChainFramebuffers;
     vk::raii::CommandPool m_commandPool{ nullptr };
     std::vector<vk::raii::CommandBuffer> m_commandBuffers;
-    vk::raii::Semaphore m_imageAvailableSemaphore{ nullptr };
-    vk::raii::Semaphore m_renderFinishedSemaphore{ nullptr };
-    vk::raii::Fence m_inFlightFence{ nullptr };
+    std::vector<vk::raii::Semaphore> m_imageAvailableSemaphores;
+    std::vector<vk::raii::Semaphore> m_renderFinishedSemaphores;
+    std::vector<vk::raii::Fence> m_inFlightFences;
+    uint32_t m_currentFrame = 0;
     /////////////////////////////////////////////////////////////////
 
     /////////////////////////////////////////////////////////////////
@@ -92,7 +95,7 @@ private:
         createGraphicsPipeline();
         createFramebuffers();
         createCommandPool();
-        createCommandBuffer();
+        createCommandBuffers();
         createSyncObjects();
     }
 
@@ -624,11 +627,11 @@ private:
 
         m_commandPool = m_device.createCommandPool( poolInfo );
     }
-    void createCommandBuffer() {
+    void createCommandBuffers() {
         vk::CommandBufferAllocateInfo allocInfo;
         allocInfo.commandPool = m_commandPool;
         allocInfo.level = vk::CommandBufferLevel::ePrimary;
-        allocInfo.commandBufferCount = 1;
+        allocInfo.commandBufferCount = MAX_FRAMES_IN_FLIGHT;
 
         m_commandBuffers = m_device.allocateCommandBuffers(allocInfo);
     }
@@ -679,36 +682,38 @@ private:
             vk::FenceCreateFlagBits::eSignaled  // flags
         );
 
-        m_imageAvailableSemaphore = m_device.createSemaphore( semaphoreInfo );
-        m_renderFinishedSemaphore = m_device.createSemaphore( semaphoreInfo );
-        m_inFlightFence = m_device.createFence( fenceInfo );
+        for(size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i){
+            m_imageAvailableSemaphores.emplace_back( m_device, semaphoreInfo );
+            m_renderFinishedSemaphores.emplace_back( m_device,  semaphoreInfo );
+            m_inFlightFences.emplace_back( m_device , fenceInfo );
+        }
     }
     void drawFrame() {
-        if( auto res = m_device.waitForFences( *m_inFlightFence, true, UINT64_MAX );
+        if( auto res = m_device.waitForFences( *m_inFlightFences[m_currentFrame], true, UINT64_MAX );
             res != vk::Result::eSuccess ){
             throw std::runtime_error{ "waitForFences in drawFrame was failed" };
         }
 
-        m_device.resetFences( *m_inFlightFence );
+        m_device.resetFences( *m_inFlightFences[m_currentFrame] );
 
-        auto [nxtRes, imageIndex] = m_swapChain.acquireNextImage(UINT64_MAX, m_imageAvailableSemaphore);
+        auto [nxtRes, imageIndex] = m_swapChain.acquireNextImage(UINT64_MAX, m_imageAvailableSemaphores[m_currentFrame]);
 
-        m_commandBuffers[0].reset();
-        recordCommandBuffer(m_commandBuffers[0], imageIndex);
+        m_commandBuffers[m_currentFrame].reset();
+        recordCommandBuffer(m_commandBuffers[m_currentFrame], imageIndex);
 
         vk::SubmitInfo submitInfo;
 
-        submitInfo.setWaitSemaphores( *m_imageAvailableSemaphore );
+        submitInfo.setWaitSemaphores( *m_imageAvailableSemaphores[m_currentFrame] );
         std::array<vk::PipelineStageFlags,1> waitStages = { vk::PipelineStageFlagBits::eColorAttachmentOutput };
         submitInfo.setWaitDstStageMask( waitStages );
 
-        submitInfo.setCommandBuffers( *m_commandBuffers[0] );
-        submitInfo.setSignalSemaphores( *m_renderFinishedSemaphore );
+        submitInfo.setCommandBuffers( *m_commandBuffers[m_currentFrame] );
+        submitInfo.setSignalSemaphores( *m_renderFinishedSemaphores[m_currentFrame] );
 
-        m_graphicsQueue.submit(submitInfo, m_inFlightFence);
+        m_graphicsQueue.submit(submitInfo, m_inFlightFences[m_currentFrame]);
 
         vk::PresentInfoKHR presentInfo;
-        presentInfo.setWaitSemaphores( *m_renderFinishedSemaphore );
+        presentInfo.setWaitSemaphores( *m_renderFinishedSemaphores[m_currentFrame] );
         presentInfo.setSwapchains( *m_swapChain );
         presentInfo.pImageIndices = &imageIndex;
 
@@ -716,6 +721,8 @@ private:
             res != vk::Result::eSuccess) {
             throw std::runtime_error{ "presentKHR in drawFrame was failed" };
         }
+
+        m_currentFrame = (m_currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
     }
     /////////////////////////////////////////////////////////////////
 };
