From: Eleni Maria Stea Date: Sat, 2 Oct 2021 07:56:47 +0000 (+0300) Subject: tmp to switch computer: there are logical errors in main, needs fixing X-Git-Url: https://eleni.mutantstargoat.com/git/?p=vkrt;a=commitdiff_plain;h=35f7d10bf03cc666b551490bcae87ac389d63cb7 tmp to switch computer: there are logical errors in main, needs fixing before adding a scene etc --- 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]; diff --git a/src/vk.c b/src/vk.c index 5aabed1..a62fc18 100644 --- a/src/vk.c +++ b/src/vk.c @@ -892,8 +892,9 @@ alloc_memory(struct vk_ctx *ctx, mem_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; mem_alloc_info.pNext = is_external ? &exp_mem_info : VK_NULL_HANDLE; mem_alloc_info.allocationSize = mem_reqs->size; - mem_alloc_info.memoryTypeIndex = - get_memory_type_idx(ctx->pdev, mem_reqs, prop_flags); + mem_alloc_info.memoryTypeIndex = get_memory_type_idx(ctx->pdev, + mem_reqs, + prop_flags); if (mem_alloc_info.memoryTypeIndex == UINT32_MAX) { fprintf(stderr, "No suitable memory type index found.\n"); @@ -917,7 +918,9 @@ alloc_memory(struct vk_ctx *ctx, } static bool -alloc_image_memory(struct vk_ctx *ctx, bool is_external, struct vk_image_obj *img_obj) +alloc_image_memory(struct vk_ctx *ctx, + bool is_external, + struct vk_image_obj *img_obj) { VkMemoryDedicatedRequirements ded_reqs; VkImageMemoryRequirementsInfo2 req_info2; @@ -1129,7 +1132,6 @@ sc_select_supported_present_modes(struct vk_ctx *ctx, { VkPresentModeKHR *present_modes; uint32_t num_present_modes; - int i; /* find supported present modes */ if (vkGetPhysicalDeviceSurfacePresentModesKHR(ctx->pdev, surf, &num_present_modes, 0) != VK_SUCCESS || !num_present_modes) { @@ -1149,20 +1151,21 @@ sc_select_supported_present_modes(struct vk_ctx *ctx, } s_info->presentMode = VK_PRESENT_MODE_FIFO_KHR; +#if 0 if (!has_vsync) { for (i = 0; i < num_present_modes; i++) { if (present_modes[i] == VK_PRESENT_MODE_MAILBOX_KHR) { s_info->presentMode = present_modes[i]; - goto success; + break; } if (present_modes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR) { s_info->presentMode = present_modes[i]; - goto success; + break; } } } +#endif -success: free(present_modes); return true; } @@ -1194,7 +1197,7 @@ vk_init_ctx(struct vk_ctx *ctx, return true; fail: - vk_cleanup_ctx(ctx, enable_layers); + vk_cleanup_ctx(ctx); return false; } @@ -1229,31 +1232,26 @@ vk_init_ctx_for_rendering(struct vk_ctx *ctx, return true; fail: - vk_cleanup_ctx(ctx, enable_layers); + vk_cleanup_ctx(ctx); return false; } void -vk_destroy_cmd_bufs(struct vk_ctx *ctx, - uint32_t num_buffers, - VkCommandBuffer *buffers) +vk_destroy_cmd_buffers(struct vk_ctx *ctx, + uint32_t num_buffers, + VkCommandBuffer *buffers) { int i; for (i = 0; i < num_buffers; i++) { vkResetCommandBuffer(buffers[i], VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); } - vkFreeCommandBuffers(ctx->dev, ctx->cmd_pool, num_buffers, &buffers[i]); + vkFreeCommandBuffers(ctx->dev, ctx->cmd_pool, num_buffers, buffers); } void -vk_cleanup_ctx(struct vk_ctx *ctx, - bool enable_layers) +vk_cleanup_ctx(struct vk_ctx *ctx) { - if (enable_layers) { - return; - } - if (ctx->cmd_pool != VK_NULL_HANDLE) { vkResetCommandPool(ctx->dev, ctx->cmd_pool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT); @@ -1299,7 +1297,7 @@ vk_create_image(struct vk_ctx *ctx, img_info.tiling = props->tiling; img_info.usage = props->usage ? props->usage : VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + img_info.initialLayout = props->in_layout; img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; if (vkCreateImage(ctx->dev, &img_info, 0, &img->img) != VK_SUCCESS) @@ -1625,7 +1623,7 @@ fail: void vk_destroy_buffer(struct vk_ctx *ctx, - struct vk_buf *bo) + struct vk_buf *bo) { if (bo->buf != VK_NULL_HANDLE) vkDestroyBuffer(ctx->dev, bo->buf, 0); @@ -1638,6 +1636,25 @@ vk_destroy_buffer(struct vk_ctx *ctx, bo->mobj.mem = VK_NULL_HANDLE; } +bool +vk_create_fence(struct vk_ctx *ctx, + VkFence *fence) +{ + VkFenceCreateInfo finfo; + + memset(&finfo, 0, sizeof finfo); + finfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + finfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; + + if (vkCreateFence(ctx->dev, &finfo, 0, fence) != VK_SUCCESS) { + fprintf(stderr, "Failed to create fence.\n"); + fence = 0; + return false; + } + + return true; +} + VkCommandBuffer vk_create_cmd_buffer(struct vk_ctx *ctx) { @@ -1675,6 +1692,7 @@ vk_record_cmd_buffer(struct vk_ctx *ctx, VkDeviceSize offsets[] = {0}; int num_vertices; struct vk_dims img_size; + bool create_cmd_buf = false; assert(vk_fb_color_count == 4); @@ -1685,6 +1703,7 @@ vk_record_cmd_buffer(struct vk_ctx *ctx, fprintf(stderr, "Failed to create command buffer.\n"); return false; } + create_cmd_buf = true; } /* VkCommandBufferBeginInfo */ @@ -1799,6 +1818,9 @@ vk_record_cmd_buffer(struct vk_ctx *ctx, #endif vkEndCommandBuffer(cmd_buf); + if (create_cmd_buf) { + vk_destroy_cmd_buffers(ctx, 1, &cmd_buf); + } return true; } @@ -1835,9 +1857,13 @@ vk_draw(struct vk_ctx *ctx, if (vkQueueSubmit(ctx->queue, 1, &submit_info, VK_NULL_HANDLE) != VK_SUCCESS) { fprintf(stderr, "Failed to submit queue.\n"); + abort(); } - vkQueueWaitIdle(ctx->queue); + if (vkQueueWaitIdle(ctx->queue) != VK_SUCCESS) { + fprintf(stderr, "Failed to wait idle.\n"); + abort(); + } } void @@ -2007,6 +2033,33 @@ vk_clear_color(struct vk_ctx *ctx, vkQueueWaitIdle(ctx->queue); } +void +vk_set_viewport(struct vk_ctx *ctx, + VkCommandBuffer cmd_buf, + float x, float y, + float w, float h, + float near, float far) +{ + VkCommandBufferBeginInfo binfo; + VkViewport viewport; + + memset(&viewport, 0, sizeof viewport); + viewport.x = x; + viewport.y = y; + viewport.width = w; + viewport.height = h; + viewport.minDepth = near; + viewport.maxDepth = far; + + memset(&binfo, 0, sizeof binfo); + binfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + binfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; + + vkBeginCommandBuffer(cmd_buf, &binfo); + vkCmdSetViewport(cmd_buf, 0, 1, &viewport); + vkEndCommandBuffer(cmd_buf); +} + bool vk_create_swapchain(struct vk_ctx *ctx, int width, int height, @@ -2155,11 +2208,10 @@ vk_destroy_swapchain(struct vk_ctx *ctx, struct vk_swapchain *swapchain) { vkDestroySwapchainKHR(ctx->dev, swapchain->swapchain, 0); - swapchain = 0; } bool -vk_present_queue(struct vk_swapchain *swapchain, +vk_queue_present(struct vk_swapchain *swapchain, VkQueue queue, uint32_t image_idx, VkSemaphore wait_sema) @@ -2169,12 +2221,11 @@ vk_present_queue(struct vk_swapchain *swapchain, memset(&pinfo, 0, sizeof pinfo); pinfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; pinfo.swapchainCount = 1; + pinfo.pSwapchains = &swapchain->swapchain; pinfo.pImageIndices = &image_idx; - if (wait_sema != VK_NULL_HANDLE) { - pinfo.pWaitSemaphores = &wait_sema; - pinfo.waitSemaphoreCount = 1; - } + pinfo.pWaitSemaphores = &wait_sema; + pinfo.waitSemaphoreCount = 1; if (vkQueuePresentKHR(queue, &pinfo) != VK_SUCCESS) { fprintf(stderr, "Failed to present queue.\n"); diff --git a/src/vk.h b/src/vk.h index 2750d84..5adfbd7 100644 --- a/src/vk.h +++ b/src/vk.h @@ -5,15 +5,15 @@ #include #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + struct vk_ctx { VkInstance inst; + VkPhysicalDevice pdev; VkDevice dev; VkCommandPool cmd_pool; - VkCommandBuffer *cmd_buffers; - uint32_t num_cmd_buffers; VkQueue queue; int qfam_idx; @@ -22,12 +22,6 @@ struct vk_ctx uint8_t driverUUID[VK_UUID_SIZE]; }; -struct vk_cmd_buffer -{ - VkCommandBuffer buffer; - VkSubmitInfo submit_info; -}; - struct vk_swapchain { VkSwapchainKHR swapchain; @@ -133,8 +127,7 @@ bool vk_init_ctx_for_rendering(struct vk_ctx *ctx, bool enable_cache, bool enable_layers); -void vk_cleanup_ctx(struct vk_ctx *ctx, - bool enable_layers); +void vk_cleanup_ctx(struct vk_ctx *ctx); /* images */ @@ -197,12 +190,6 @@ void vk_destroy_semaphores(struct vk_ctx *ctx, struct vk_semaphores *semaphores); -bool -vk_create_fences(struct vk_ctx *ctx, - int num_cmd_buf, - VkFenceCreateFlagBits flags, - VkFence *fences); - void vk_destroy_fences(struct vk_ctx *ctc, int num_fences, @@ -230,7 +217,11 @@ void vk_destroy_renderer(struct vk_ctx *ctx, struct vk_renderer *pipeline); -/* draw */ +/* fences and command buffers */ +bool +vk_create_fence(struct vk_ctx *ctx, + VkFence *fence); + VkCommandBuffer vk_create_cmd_buffer(struct vk_ctx *ctx); @@ -247,13 +238,11 @@ vk_record_cmd_buffer(struct vk_ctx *ctx, float w, float h); void -vk_reset_cmd_buf(struct vk_cmd_buffer *cmd_buf); - -void -vk_destroy_cmd_bufs(struct vk_ctx *ctx, - uint32_t num_buffers, - VkCommandBuffer *buffers); +vk_destroy_cmd_buffers(struct vk_ctx *ctx, + uint32_t num_buffers, + VkCommandBuffer *buffers); +/* draw */ void vk_draw(struct vk_ctx *ctx, struct vk_semaphores *semaphores, @@ -273,6 +262,13 @@ vk_clear_color(struct vk_ctx *ctx, uint32_t n_attachments, float x, float y, float w, float h); +void +vk_set_viewport(struct vk_ctx *ctx, + VkCommandBuffer cmd_buf, + float x, float y, + float w, float h, + float near, float far); + /* swapchain */ bool @@ -287,7 +283,7 @@ vk_destroy_swapchain(struct vk_ctx *ctx, struct vk_swapchain *swapchain); bool -vk_present_queue(struct vk_swapchain *swapchain, +vk_queue_present(struct vk_swapchain *swapchain, VkQueue queue, uint32_t image_idx, VkSemaphore wait_sema);