+void
+vk_draw(struct vk_ctx *ctx,
+ struct vk_semaphores *semaphores,
+ uint32_t num_buffers,
+ VkCommandBuffer *cmd_buf)
+{
+ VkSubmitInfo submit_info;
+ VkPipelineStageFlagBits stage_flags;
+
+ /* VkSubmitInfo */
+ memset(&submit_info, 0, sizeof submit_info);
+ submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submit_info.commandBufferCount = num_buffers;
+ submit_info.pCommandBuffers = cmd_buf;
+
+ /* semaphores */
+ if (semaphores) {
+ assert(semaphores->frame_ready);
+ assert(semaphores->frame_done);
+
+ /* The subpasses in a render pass automatically take care of
+ * image layout transitions. These transitions are controlled
+ * by subpass dependencies, which specify memory and execution
+ * dependencies between subpasses. We have only a single subpass
+ * right now, but the operations right before and right after
+ * this subpass also count as implicit "subpasses". There are two
+ * built-in dependencies that take care of the transition at the
+ * start of the render pass and at the end of the render pass,
+ * but the former does not occur at the right time. It assumes
+ * that the transition occurs at the start of the pipeline,
+ * but we haven't acquired the image yet at that point! There are
+ * two ways to deal with this problem.
+ *
+ * We could change the waitStages for the frame_ready semaphore
+ * to VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT to ensure that the render
+ * passes don't begin until the image is available, or we can make
+ * the render pass wait for the
+ * VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT stage.
+ */
+ stage_flags = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
+
+ submit_info.pWaitDstStageMask = &stage_flags;
+ submit_info.waitSemaphoreCount = 1;
+ submit_info.pWaitSemaphores = &semaphores->frame_done;
+
+ submit_info.signalSemaphoreCount = 1;
+ submit_info.pSignalSemaphores = &semaphores->frame_ready;
+ }
+
+
+ if (vkQueueSubmit(ctx->queue, 1, &submit_info,
+ VK_NULL_HANDLE) != VK_SUCCESS) {