X-Git-Url: http://git.mutantstargoat.com?a=blobdiff_plain;f=src%2Fvulkan%2Fvk.cc;h=0e3725b32150a31678535480a9f9a5597a05974e;hb=32feb79dc3b9ddeeab84a0329d53b8aaff86bb80;hp=3d9862de4d2a79e6d1ba41118100104a06bb3334;hpb=64e2adbbab48320b6cd792e515b44cea112a3be4;p=demo diff --git a/src/vulkan/vk.cc b/src/vulkan/vk.cc index 3d9862d..0e3725b 100644 --- a/src/vulkan/vk.cc +++ b/src/vulkan/vk.cc @@ -1,20 +1,292 @@ -#include "vulkan/vk.h" -extern GLFWwindow win; +#define GLFW_INCLUDE_VULKAN +#include + +#include +#include +#include +#include +#include + +#include + +#include "gfxapi.h" +#include "vkutil.h" + +/* global variables */ +extern GLFWwindow *win; +extern int win_w; +extern int win_h; + +VkCommandBuffer *swapchain_cmd_bufs; + +/* static functions */ +static void error_callback(int error, const char *descr); +static void clear(float r, float g, float b); +static void viewport(int x, int y, int width, int height); +static void zbuffer(bool enable); +static void cull_face(Gfx_cull_face cf); +static void reshape(int width, int height); +static void swapbuffers(); +static void begin_drawing(); +static void end_drawing(); + +static bool create_swapchain_cmd_bufs(VkCommandPool vkcmdpool); +static bool record_cmd_clear(float r, float g, float b); bool init_vulkan() { + gfx_clear = clear; + gfx_viewport = viewport; + gfx_zbuffer = zbuffer; + gfx_cull_face = cull_face; + gfx_reshape = reshape; + gfx_swapbuffers = swapbuffers; + gfx_begin_drawing = begin_drawing; + gfx_end_drawing = end_drawing; + + if(!glfwInit()) { + fprintf(stderr, "Failed to initialize GLFW.\n"); + return false; + } + + if(!glfwVulkanSupported()) { + fprintf(stderr, "No Vulkan support on the device.\n"); + return false; + } + + glfwSetErrorCallback(error_callback); + + if(!vku_create_device()) { + fprintf(stderr, "Failed to initialize vulkan.\n"); + return false; + } + + if(!glfwGetPhysicalDevicePresentationSupport(vkinst, vkpdev, vkqfamily)) { + fprintf(stderr, "Presentation support not found.\n"); + return false; + } + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + if(!(win = glfwCreateWindow(win_w, win_h, "vkcow", 0, 0))) { + fprintf(stderr, "Failed to create window.\n"); + return false; + } + + if(VkResult err = glfwCreateWindowSurface(vkinst, win, 0, &vksurface)) { + fprintf(stderr, "Failed to create KHR surface: %s\n", vku_get_vulkan_error_str(err)); + return false; + } + + if(!vku_create_semaphores()) + return false; + + if(!(vkswapchain = vku_create_swapchain(vksurface, win_w, win_h, 2, + VK_PRESENT_MODE_FIFO_KHR, 0))) { + fprintf(stderr, "Failed to create swapchain.\n"); + return false; + } + + vkswapchain_images = vku_get_swapchain_images(vkswapchain, &vknum_swapchain_images); + if(!vkswapchain_images) { + fprintf(stderr, "Failed to get swapchain images.\n"); + return false; + } + + /* vkswapchain_views = vku_create_image_views(vkswapchain_images, vknum_swapchain_images); + if(!vkswapchain_views) { + fprintf(stderr, "Failed to create swapchain image views.\n"); + delete [] vkswapchain_images; + return false; + } + */ + if(!create_swapchain_cmd_bufs(vkcmdpool)) { + return false; + } + + if(!record_cmd_clear(1.0, 0.1, 0.1)) + return false; + return true; } void cleanup_vulkan() { + vkFreeCommandBuffers(vkdev, vkcmdpool, vknum_swapchain_images, swapchain_cmd_bufs); + if(win) { + glfwDestroyWindow(win); + } + glfwTerminate(); + + //TODOs according to the book: + // 1- make sure all threads have been terminated (when I add threads) + vku_cleanup(); } -GLFWwindow *create_vulkan_window() +static void error_callback(int error, const char *description) { - return 0; + fprintf(stderr, "GLFW error %d: %s.\n", error, description); } -void display_vulkan() +static void reshape(int width, int height) { + VkSwapchainKHR sc; + if(!(sc = vku_create_swapchain(vksurface, width, height, 2, VK_PRESENT_MODE_FIFO_KHR, + vkswapchain))) { + fprintf(stderr, "Failed to create %dx%d double-buffered swapchain\n", width, height); + return; + } + vkswapchain = sc; + + delete [] vkswapchain_images; + vkswapchain_images = vku_get_swapchain_images(sc, 0); + vk_curr_swapchain_image = vku_get_next_image(vkswapchain); +} + +static void clear(float r, float g, float b) +{ +} + +static void viewport(int x, int y, int width, int height) +{ +} + +static void zbuffer(bool enable) +{ +} + +static void cull_face(Gfx_cull_face cf) +{ +} + +static void swapbuffers() +{ +} + +static void begin_drawing() +{ + if((vk_curr_swapchain_image = vku_get_next_image(vkswapchain)) == -1) { + fprintf(stderr, "Failed to get swapchain image. Exiting.\n"); + exit(1); + } +} + +static void end_drawing() +{ + /* submit queue */ + + VkSubmitInfo sinf; + memset(&sinf, 0, sizeof sinf); + sinf.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + sinf.waitSemaphoreCount = 1; + sinf.pWaitSemaphores = &vk_img_avail_sema; + sinf.signalSemaphoreCount = 1; + sinf.pSignalSemaphores = &vk_rend_done_sema; + + // the queue should wait on the semaphore + + VkPipelineStageFlags wait_flags = VK_PIPELINE_STAGE_TRANSFER_BIT; + sinf.pWaitDstStageMask = &wait_flags; + sinf.commandBufferCount = 1; + sinf.pCommandBuffers = &swapchain_cmd_bufs[vk_curr_swapchain_image]; + + if(vkQueueSubmit(vkq, 1, &sinf, VK_NULL_HANDLE) != VK_SUCCESS) { + fprintf(stderr, "Failed to submit drawing command buffer\n"); + exit(1); + } + + /* present drawn image */ + VkPresentInfoKHR pinf; + memset(&pinf, 0, sizeof pinf); + pinf.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + pinf.waitSemaphoreCount = 1; + pinf.pWaitSemaphores = &vk_rend_done_sema; + pinf.swapchainCount = 1; + pinf.pSwapchains = &vkswapchain; + pinf.pImageIndices = (uint32_t *)&vk_curr_swapchain_image; + + if(vkQueuePresentKHR(vkq, &pinf) != VK_SUCCESS) { + fprintf(stderr, "Failed to submit presentation command buffer.\n"); + exit(1); + } +} + +static bool record_cmd_clear(float r, float g, float b) +{ + VkCommandBufferBeginInfo binf; + binf.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + binf.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; + + /* this function must be called outside a renderpass instance */ + const VkClearColorValue pcolor[4] = {r, g, b, 1.0}; + + VkImageSubresourceRange range; + memset(&range, 0, sizeof range); + range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + range.baseMipLevel = 0; + range.baseArrayLayer = 0; + range.layerCount = 1; + + for(int i=0; i