 <p>The drawing setup is quite involved, but the actual calls required to draw are fairly straightforward. From the <code>tri.c</code> (which draws a 2D triangle):</p> <pre><code>// ... vkCmdBeginRenderPass(demo-&gt;draw_cmd, &amp;rp_begin, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(demo-&gt;draw_cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, demo-&gt;pipeline); vkCmdBindDescriptorSets(demo-&gt;draw_cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, demo-&gt;pipeline_layout, 0, 1, &amp; demo-&gt;desc_set, 0, NULL); VkViewport viewport = {}; viewport.height = (float) demo-&gt;height; viewport.width = (float) demo-&gt;width; viewport.minDepth = (float) 0.0f; viewport.maxDepth = (float) 1.0f; vkCmdSetViewport(demo-&gt;draw_cmd, 0, 1, &amp;viewport); VkRect2D scissor = {}; scissor.extent.width = demo-&gt;width; scissor.extent.height = demo-&gt;height; scissor.offset.x = 0; scissor.offset.y = 0; vkCmdSetScissor(demo-&gt;draw_cmd, 0, 1, &amp;scissor); VkDeviceSize offsets[1] = {0}; vkCmdBindVertexBuffers(demo-&gt;draw_cmd, VERTEX_BUFFER_BIND_ID, 1, &amp;demo-&gt;vertices.buf, offsets); vkCmdDraw(demo-&gt;draw_cmd, 3, 1, 0, 0); vkCmdEndRenderPass(demo-&gt;draw_cmd); // ... </code></pre> <p>This snippet assumes that you've already gotten the <code>VkPipeline</code> (which include shaders, etc.), <code>VkBuffer</code> (for the vertex buffer), and the <code>VkCommandBuffer</code> in appropriate states. It's the <code>vkCmdDraw</code> that actually issues the command to draw, once the containing <code>VkCommandBuffer</code> is executed.</p>