+ vkWaitForFences(vk_core.dev, 1, &vk_fences[vk_frame_idx], VK_TRUE, UINT64_MAX);
+ vkResetFences(vk_core.dev, 1, &vk_fences[vk_frame_idx]);
+
+ VkResult err;
+ do {
+ err = vkAcquireNextImageKHR(vk_core.dev, vk_chain.swapchain,
+ UINT64_MAX,
+ vk_semas[vk_frame_idx].frame_ready,
+ 0, &vk_current_image);
+ switch(err) {
+ case VK_ERROR_OUT_OF_DATE_KHR:
+ fprintf(stderr, "acquire next image error: VK_ERROR_OUT_OF_DATE_KHR.\n");
+ abort();
+ break;
+ case VK_SUBOPTIMAL_KHR:
+ fprintf(stderr, "AcquireNextImageKHR returned VK_SUBOPTIMAL_KHR, ignored.\n");
+ abort();
+ break;
+ case VK_ERROR_SURFACE_LOST_KHR:
+ vkDestroySurfaceKHR(vk_core.inst, vk_surf, 0);
+ if (glfwCreateWindowSurface(vk_core.inst, win, 0, &vk_surf) !=
+ VK_SUCCESS) {
+ fprintf(stderr, "Failed to recreate GLFW/XCB surface.\n");
+ }
+ abort();
+ break;
+ default:
+ assert(!err);
+ break;
+ }
+ } while (err != VK_SUCCESS);
+
+ /* FIXME update buffer data */
+ if (!vk_record_cmd_buffer(&vk_core,
+ vk_cmd_buffers[0],
+ &vk_rnd,
+ 4, vk_fb_color,
+ vk_framebuffers[vk_current_image],
+ 2, 0,
+ 0, 0, win_w, win_h)) {
+ fprintf(stderr, "Failed to record command buffer.\n");
+ abort();
+ }
+
+ /* each object should have a command buffer renderpass etc? */
+ VkSubmitInfo sinfo;
+ VkPipelineStageFlags wait_stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+
+ memset(&sinfo, 0, sizeof sinfo);
+ sinfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ sinfo.waitSemaphoreCount = 1;
+ sinfo.pWaitSemaphores = &vk_semas[vk_frame_idx].frame_ready;
+ sinfo.pWaitDstStageMask = &wait_stages;
+ sinfo.commandBufferCount = 1;
+ sinfo.pCommandBuffers = &vk_cmd_buffers[0];
+ sinfo.signalSemaphoreCount = 1;
+ sinfo.pSignalSemaphores = &vk_semas[vk_frame_idx].frame_done;
+
+ if (vkQueueSubmit(vk_core.queue, 1, &sinfo, vk_fences[vk_frame_idx]) != 0) {
+ fprintf(stderr, "Failed to submit draw commands.\n");
+ abort();
+ }
+
+ if (vkQueueWaitIdle(vk_core.queue) != VK_SUCCESS) {
+ fprintf(stderr, "Failed to wait idle.\n");
+ abort();
+ }
+
+ if (!vk_queue_present(&vk_chain, vk_core.queue, vk_current_image,
+ vk_semas[vk_frame_idx].frame_done)) {
+ abort();
+ }
+
+ vk_frame_idx = (vk_frame_idx + 1) % (vk_chain.num_images - 1);
+
+ printf("display %d\n", count++);
+ printf("current image %u\n", vk_current_image);
+ printf("frame idx %d\n", vk_frame_idx);