diff --git a/src/main.cpp b/src/main.cpp
index 706a386..fa38a92 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -75,6 +75,8 @@ private:
     std::vector<vk::raii::Framebuffer> m_swapChainFramebuffers;
     vk::raii::PipelineLayout m_pipelineLayout{ nullptr };
     vk::raii::Pipeline m_graphicsPipeline{ nullptr };
+    vk::raii::CommandPool m_commandPool{ nullptr };
+    std::vector<vk::raii::CommandBuffer> m_commandBuffers;
     /////////////////////////////////////////////////////////////
 
     /////////////////////////////////////////////////////////////
@@ -99,6 +101,8 @@ private:
         createRenderPass();
         createFramebuffers();
         createGraphicsPipeline();
+        createCommandPool();
+        createCommandBuffer();
     }
 
     void mainLoop() {
@@ -518,6 +522,62 @@ private:
     }
 
     /////////////////////////////////////////////////////////////
+
+    /////////////////////////////////////////////////////////////
+    /// command
+    void createCommandPool() {
+        const auto [graphicsFamily, presentFamily] = findQueueFamilies( m_physicalDevice );
+
+        vk::CommandPoolCreateInfo poolInfo;
+        poolInfo.flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer;
+        poolInfo.queueFamilyIndex =  graphicsFamily.value();
+
+        m_commandPool = m_device.createCommandPool( poolInfo );
+    }
+    void createCommandBuffer() {
+        vk::CommandBufferAllocateInfo allocInfo;
+        allocInfo.commandPool = m_commandPool;
+        allocInfo.level = vk::CommandBufferLevel::ePrimary;
+        allocInfo.commandBufferCount = 1;
+
+        m_commandBuffers = m_device.allocateCommandBuffers(allocInfo);
+    }
+    void recordCommandBuffer(const vk::raii::CommandBuffer& commandBuffer, uint32_t imageIndex) const {
+        constexpr vk::CommandBufferBeginInfo beginInfo;
+        commandBuffer.begin( beginInfo );
+
+        vk::RenderPassBeginInfo renderPassInfo;
+        renderPassInfo.renderPass = m_renderPass;
+        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 );
+
+        commandBuffer.beginRenderPass(renderPassInfo, vk::SubpassContents::eInline);
+
+        commandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, m_graphicsPipeline );
+
+        const vk::Viewport viewport(
+            0.0f, 0.0f, // x, y
+            static_cast<float>(m_swapChainExtent.width),    // width
+            static_cast<float>(m_swapChainExtent.height),   // height
+            0.0f, 1.0f  // minDepth maxDepth
+        );
+        commandBuffer.setViewport(0, viewport);
+
+        const vk::Rect2D scissor(
+            vk::Offset2D{0, 0}, // offset
+            m_swapChainExtent   // extent
+        );
+        commandBuffer.setScissor(0, scissor);
+
+        commandBuffer.draw(3, 1, 0, 0);
+
+        commandBuffer.endRenderPass();
+        commandBuffer.end();
+    }
+    /////////////////////////////////////////////////////////////
 };
 
 int main() {
