X-Git-Url: https://eleni.mutantstargoat.com/git/?p=vkrt;a=blobdiff_plain;f=src%2Fmain.cc;fp=src%2Fmain.cc;h=ea7071534a2822b04486f1e0d85ab22be47e07bb;hp=893508ff1bad181d558a7b3116715e1eedf6348a;hb=35f7d10bf03cc666b551490bcae87ac389d63cb7;hpb=470723fe1cc3902759399a023a062051c460bd1f diff --git a/src/main.cc b/src/main.cc index 893508f..ea70715 100644 --- a/src/main.cc +++ b/src/main.cc @@ -2,9 +2,13 @@ #define GLFW_INCLUDE_VULKAN #include + +#include #include #include +#include + #include /* extern "C": vulkan framework */ @@ -14,6 +18,10 @@ /* C++ */ #include "camera.h" +/* defines */ + +#define FENCE_TIMEOUT 100000000000 + /**************************/ /* static glfw callbacks */ /**************************/ @@ -53,12 +61,12 @@ vk_init(); static void vk_cleanup(); -/**************************/ -/* static variables */ -/**************************/ +/***************************/ +/* static/global variables */ +/***************************/ static GLFWwindow *win; -static bool redraw_pending; +/* static bool redraw_pending; */ static bool move_camera; /* camera */ @@ -67,25 +75,32 @@ static float cam_theta = 0; static float cam_dist = 16; static Vec3 cam_pos; -static float aspect; static OrbitCamera *camera; -static bool vk_enable_layers = true; +static float aspect; +static Mat4 mproj; +/* win etc */ static int win_w = 800; static int win_h = 600; +/* vulkan */ +static bool vk_enable_layers = true; static struct vk_ctx vk_core; static VkSurfaceKHR vk_surf; -static struct vk_renderer vk_rnd; static struct vk_swapchain vk_chain; +static uint32_t vk_chain_idx; static struct vk_semaphores vk_sema; + +/* for the moment: one cmd buffer per swapchain image */ +static std::vectorvk_cmd_buffers; +static std::vectorvk_wait_fences; + +/* FIXME make them part of each object's functions/params */ +static struct vk_renderer vk_rnd; static struct vk_attachment vk_depth_att; static float vk_fb_color[4] = { 0.0, 0.0, 0.5, 1.0 }; -/* make array later if many cmd buffers */ -static VkCommandBuffer vk_cmd_buf; - /* empty for as long as we hardcode the vertices in the vertex shader */ static struct vk_vertex_info vk_vert_info; @@ -102,30 +117,16 @@ int main(int argc, char** argv) return 1; } - /* reshape window once just in case */ - +#if 0 glfwGetWindowSize(win, &win_w, &win_h); clb_reshape(win, win_w, win_h); +#endif - /* event loop */ - redraw_pending = true; - - while(!glfwWindowShouldClose(win)) { - glfwWaitEvents(); - if (redraw_pending) { - redraw_pending = false; - display(); - } - } - -#if 0 while(!glfwWindowShouldClose(win)) { - display(); - - glfwSwapBuffers(win); glfwPollEvents(); + display(); } -#endif + vkDeviceWaitIdle(vk_core.dev); return 0; } @@ -135,10 +136,6 @@ int main(int argc, char** argv) static bool vk_init() { - char *vsdr = 0; - char *fsdr = 0; - int vsz, fsz; - if (glfwVulkanSupported() != GLFW_TRUE) { fprintf(stderr, "Vulkan is not supported on this device.\n"); return false; @@ -172,6 +169,11 @@ vk_init() return false; } + /* load shaders */ + int vsz, fsz; + char *vsdr = sdr_load("data/main.vert.spv", &vsz); + char *fsdr = sdr_load("data/main.frag.spv", &fsz); + /* create semaphores */ if (!vk_create_semaphores(&vk_core, false, &vk_sema)) { fprintf(stderr, "No semaphores were created.\n"); @@ -189,9 +191,7 @@ vk_init() goto fail; } - /* create shaders */ - vsdr = sdr_load("data/main.vert.spv", &vsz); - fsdr = sdr_load("data/main.frag.spv", &fsz); + /* FIXME: this part is going to be part of each object's functions */ /* create depth attachment (for the moment we are going to use this * for all images */ @@ -222,22 +222,38 @@ vk_init() goto fail; } - /* create cmd buffer */ - if ((vk_cmd_buf = vk_create_cmd_buffer(&vk_core)) == VK_NULL_HANDLE) { - fprintf(stderr, "Failed to create command buffer.\n"); - goto fail; - } + /* create cmd buffers */ + for (size_t i = 0; i < vk_chain.num_atts; i++) { + VkCommandBuffer cmd_buf; + VkFence fence; + if(!(vk_create_fence(&vk_core, &fence))) { + fprintf(stderr, "Failed to create fence: %d.\n", (int)i); + goto fail; + } + vk_wait_fences.push_back(fence); - /* record cmd buffer */ - if (!vk_record_cmd_buffer(&vk_core, vk_cmd_buf, - &vk_rnd, 0, - 4, vk_fb_color, - vk_chain.num_atts + 1, 0, - 0, 0, win_w, win_h)) { - fprintf(stderr, "Failed to record command buffer.\n"); - goto fail; + if (!(cmd_buf = vk_create_cmd_buffer(&vk_core))) { + fprintf(stderr, "Failed to create command buffer: %d.\n", (int)i); + goto fail; + } + + /* record cmd buffer FIXME: + * part of each objects draw? loop for each + * renderer */ + if (!vk_record_cmd_buffer(&vk_core, cmd_buf, + &vk_rnd, 0, + 4, vk_fb_color, + vk_chain.num_atts + 1, 0, + 0, 0, win_w, win_h)) { + fprintf(stderr, "Failed to record command buffer.\n"); + goto fail; + } + + vk_cmd_buffers.push_back(cmd_buf); } + vkResetFences(vk_core.dev, vk_wait_fences.size(), vk_wait_fences.data()); + free(vsdr); free(fsdr); @@ -251,6 +267,20 @@ vk_init() return true; fail: + for (size_t i = 0; i < vk_wait_fences.size(); i++) { + vk_destroy_fences(&vk_core, vk_wait_fences.size(), vk_wait_fences.data()); + } + vk_wait_fences.clear(); + + for (size_t i = 0; i < vk_cmd_buffers.size(); i++) { + vk_destroy_cmd_buffers(&vk_core, vk_cmd_buffers.size(), vk_cmd_buffers.data()); + } + vk_cmd_buffers.clear(); + + if (vk_depth_att.obj.img != VK_NULL_HANDLE) { + vk_destroy_image(&vk_core, &vk_depth_att.obj); + } + free(vsdr); free(fsdr); @@ -272,19 +302,21 @@ init() static void cleanup() { + delete camera; + vk_cleanup(); } +static int count; static void display() { - uint32_t img_idx; + /* each object should have a command buffer renderpass etc? */ VkSubmitInfo sinfo; VkPipelineStageFlags wait_stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - VkPresentInfoKHR pinfo; vkAcquireNextImageKHR(vk_core.dev, vk_chain.swapchain, - UINT64_MAX, vk_sema.frame_ready, 0, &img_idx); + UINT64_MAX, vk_sema.frame_ready, 0, &vk_chain_idx); memset(&sinfo, 0, sizeof sinfo); sinfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; @@ -292,24 +324,42 @@ display() sinfo.pWaitSemaphores = &vk_sema.frame_ready; sinfo.pWaitDstStageMask = &wait_stages; sinfo.commandBufferCount = 1; - sinfo.pCommandBuffers = &vk_cmd_buf; + sinfo.pCommandBuffers = &vk_cmd_buffers[vk_chain_idx]; sinfo.signalSemaphoreCount = 1; sinfo.pSignalSemaphores = &vk_sema.frame_done; - if (vkQueueSubmit(vk_core.queue, 1, &sinfo, 0) != 0) { + if (vkQueueSubmit(vk_core.queue, 1, &sinfo, vk_wait_fences[vk_chain_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 (vkWaitForFences(vk_core.dev, 1, &vk_wait_fences[vk_chain_idx], + VK_TRUE, FENCE_TIMEOUT) != VK_SUCCESS) { + fprintf(stderr, "Waiting for fence: %u failed.\n", vk_chain_idx); + abort(); + } + +#if 0 memset(&pinfo, 0, sizeof pinfo); pinfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; pinfo.waitSemaphoreCount = 1; pinfo.pWaitSemaphores = &vk_sema.frame_done; pinfo.swapchainCount = 1; pinfo.pSwapchains = &vk_chain.swapchain; - pinfo.pImageIndices = &img_idx; + pinfo.pImageIndices = &vk_chain_idx; +#endif + + if (!vk_queue_present(&vk_chain, vk_core.queue, vk_chain_idx, vk_sema.frame_done)) { + abort(); + } + vkResetFences(vk_core.dev, 1, &vk_wait_fences[vk_chain_idx]); - vkQueuePresentKHR(vk_core.queue, &pinfo); + printf("display %d\n", count++); } static void @@ -317,40 +367,54 @@ vk_cleanup() { vkQueueWaitIdle(vk_core.queue); - if (vk_cmd_buf != VK_NULL_HANDLE) { - vkResetCommandBuffer(vk_cmd_buf, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); - } - vk_destroy_image(&vk_core, &vk_depth_att.obj); - vk_destroy_semaphores(&vk_core, &vk_sema); vk_destroy_renderer(&vk_core, &vk_rnd); + vk_destroy_semaphores(&vk_core, &vk_sema); + + glfwDestroyWindow(win); if (vk_chain.swapchain) { vk_destroy_swapchain(&vk_core, &vk_chain); vkDestroySurfaceKHR(vk_core.inst, vk_surf, 0); } - glfwDestroyWindow(win); - - if (!vk_enable_layers) - vkFreeCommandBuffers(vk_core.dev, vk_core.cmd_pool, 1, &vk_cmd_buf); - - vk_cleanup_ctx(&vk_core, vk_enable_layers); + if (vk_enable_layers) + return; + vk_destroy_cmd_buffers(&vk_core, vk_cmd_buffers.size(), vk_cmd_buffers.data()); glfwTerminate(); + + vk_cleanup_ctx(&vk_core); } /* glfw callbacks */ static void +clb_reshape(GLFWwindow *win, + int width, + int height) +{ + aspect = (float)width / (float)height; + mproj = calc_projection_matrix(45, aspect, 0.5, 1000.0f); + + /* FIXME near and far clipping planes */ + vk_set_viewport(&vk_core, vk_cmd_buffers[vk_chain_idx], + 0, 0, win_w, win_h, 0.0f, 1.0f); + win_w = width; + win_h = height; +} + +static void clb_key(GLFWwindow *win, int key, int scancode, int action, int mods) { + if (action == GLFW_REPEAT) return; + if (action == GLFW_PRESS) { switch(key) { case GLFW_KEY_ESCAPE: glfwSetWindowShouldClose(win, GLFW_TRUE); - return; + exit(0); case ' ': move_camera = !move_camera; break; @@ -360,13 +424,6 @@ clb_key(GLFWwindow *win, int key, int scancode, } } -static void -clb_reshape(GLFWwindow *win, - int width, - int height) -{ -} - static double prev_x, prev_y; static bool button[8];