From 9ba38e2fb3b09c2cebfa780ed548c2a6c5a9ff79 Mon Sep 17 00:00:00 2001 From: Eleni Maria Stea Date: Fri, 4 Jun 2021 16:17:06 +0300 Subject: [PATCH] WIP: started the code to use a swapchain and aquire swapchain images --- Makefile | 2 +- src/main.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/vk.c | 48 ++++++++++++++++-- src/vk.h | 1 - 4 files changed, 204 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index bdbc075..470cf95 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ dbg = -g CC = gcc CFLAGS = -pedantic -Wall $(dbg) $(pkg-config --cflags glfw3) -LDFLAGS = -lvulkan $(pkg-config --libs glfw3) +LDFLAGS = -lvulkan -lglfw #$(pkg-config --libs glfw3) $(bin): $(obj) $(CC) -o $@ $(obj) $(LDFLAGS) diff --git a/src/main.c b/src/main.c index d12433e..cd2f140 100644 --- a/src/main.c +++ b/src/main.c @@ -1,8 +1,166 @@ #include -#include "vk.h" +#define GLFW_INCLUDE_VULKAN +#include +#include +#include + +#include "ui.h" + + +/* static glfw callbacks */ + +static void +clb_key(GLFWwindow *win, int key, int scancode, int action, int mods); + +static void +clb_reshape(GLFWwindow *win, int width, int height); + +/* static functions */ + +static bool +init(); + +static void +cleanup(); + +static void +display(); + + +/* static variables */ + +static GLFWwindow *win; + +static int win_w = 800; +static int win_h = 600; + +static struct vk_ctx vk_core; +static struct vk_swapchain vk_swap; int main(int argc, char** argv) { - printf("hi\n"); + atexit(cleanup); + + if (!init()) { + return 1; + } + + /* reshape window once just in case */ + + glfwGetWindowSize(win, &win_w, &win_h); + clb_reshape(win, win_w, win_h); + + /* event loop */ + + while(!glfwWindowShouldClose(win)) { + display(); + glfwPollEvents(); + } + + return 0; +} + +/* static functions */ + +static bool +init() +{ + /* initialize GLFW */ + + if (!glfwInit()) { + fprintf(stderr, "Failed to initialize GLFW.\n"); + return false; + } + + if (glfwVulkanSupported() != GLFW_TRUE) { + fprintf(stderr, "Vulkan is not supported on this device.\n"); + return false; + } + + /* initialize Vulkan context */ + + if (!vk_init_ctx_for_rendering(&vk_core)) { + fprintf(stderr, "Failed to initialize Vulkan context.\n"); + return false; + } + + memset(&vk_swap, 0, sizeof vk_swap); + + /* create window */ + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + win = glfwCreateWindow(win_w, win_h, "helloworld rt", 0, 0); + + if (!win) { + fprintf(stderr, "Failed to create GLFW window\n"); + return false; + } + + /* create (Xcb) surface */ + + glfwGetFramebufferSize(win, &win_h, &win_h); + if (glfwCreateWindowSurface(vk_core.inst, win, 0, &vk_swap.surface) + != VK_SUCCESS) { + fprintf(stderr, "Failed to create XCB surface.\n"); + return false; + } + + /* create Vulkan swapchain */ + + /* aquire images? */ + + /* create shaders */ + + /* create semaphores? */ + + /* create renderer */ + + /* set GLFW callbacks */ + + glfwSetKeyCallback(win, clb_key); + glfwSetWindowSizeCallback(win, clb_reshape); + + /* + glfwSetCursorPosCallback(win, clb_motion); + glfwSetMouseButtonCallback(win, clb_mouse); + */ + + return true; +} + +static void +display() +{ +} + +static void +cleanup() +{ + vk_cleanup_ctx(&vk_core); + glfwTerminate(); +} + +/* glfw callbacks */ + +static void +clb_key(GLFWwindow *win, int key, int scancode, + int action, int mods) +{ + if (action == GLFW_PRESS) { + switch(key) { + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(win, GLFW_TRUE); + return; + } + } +} + +static void +clb_reshape(GLFWwindow *win, int width, int height) +{ + /* set viewport */ + + win_w = width; + win_h = height; } diff --git a/src/vk.c b/src/vk.c index d280e00..4e3aa1c 100644 --- a/src/vk.c +++ b/src/vk.c @@ -8,8 +8,10 @@ /* static variables */ static VkViewport viewport; static VkRect2D scissor; +static bool enable_layers = true; /* static functions */ + static VkSampleCountFlagBits get_num_samples(uint32_t num_samples) { @@ -94,6 +96,36 @@ enable_validation_layers(VkInstanceCreateInfo *info) } } +static void +enable_extensions(VkInstanceCreateInfo *info) +{ + static const char *ext_names[] = { + "VK_KHR_xcb_surface", + "VK_KHR_surface" + }; + + uint32_t num_extensions; + VkExtensionProperties *extensions; + int i; + + vkEnumerateInstanceExtensionProperties(0, &num_extensions, 0); + if (!num_extensions) { + fprintf(stderr, "No instance extensions found.\n"); + return; + } + + extensions = alloca(num_extensions * sizeof *extensions); + vkEnumerateInstanceExtensionProperties(0, &num_extensions, extensions); + + printf("Available extensions:\n"); + for (i = 0; i < num_extensions; i++) { + printf(" %s\n", extensions[i].extensionName); + } + + info->ppEnabledExtensionNames = ext_names; + info->enabledExtensionCount = ARRAY_SIZE(ext_names); +} + static VkInstance create_instance(bool enable_layers) { @@ -101,17 +133,21 @@ create_instance(bool enable_layers) VkInstanceCreateInfo inst_info; VkInstance inst; + /* VkApplicationInfo */ memset(&app_info, 0, sizeof app_info); app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; app_info.pApplicationName = "vktest"; app_info.apiVersion = VK_API_VERSION_1_1; + /* VkInstanceCreateInfo */ memset(&inst_info, 0, sizeof inst_info); inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; inst_info.pApplicationInfo = &app_info; - if (enable_layers) + enable_extensions(&inst_info); + if (enable_layers) { enable_validation_layers(&inst_info); + } if (vkCreateInstance(&inst_info, 0, &inst) != VK_SUCCESS) return 0; @@ -145,9 +181,7 @@ select_physical_device(VkInstance inst) static VkDevice create_device(struct vk_ctx *ctx, VkPhysicalDevice pdev) { - /* FIXME: swapchain */ - const char *deviceExtensions[] = { "VK_KHR_external_memory_fd", - "VK_KHR_external_semaphore_fd" }; + const char *deviceExtensions[] = { "VK_KHR_swapchain" }; VkDeviceQueueCreateInfo dev_queue_info; VkDeviceCreateInfo dev_info; VkDevice dev; @@ -966,7 +1000,7 @@ are_props_supported(struct vk_ctx *ctx, struct vk_image_props *props) bool vk_init_ctx(struct vk_ctx *ctx) { - if ((ctx->inst = create_instance(false)) == VK_NULL_HANDLE) { + if ((ctx->inst = create_instance(enable_layers)) == VK_NULL_HANDLE) { fprintf(stderr, "Failed to create Vulkan instance.\n"); goto fail; } @@ -1024,6 +1058,10 @@ fail: void vk_cleanup_ctx(struct vk_ctx *ctx) { + if (enable_layers) { + return; + } + if (ctx->cmd_buf != VK_NULL_HANDLE) { vkResetCommandBuffer(ctx->cmd_buf, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); diff --git a/src/vk.h b/src/vk.h index f28930f..7380a40 100644 --- a/src/vk.h +++ b/src/vk.h @@ -72,7 +72,6 @@ struct vk_buf struct vk_mem_obj mobj; }; - struct vk_renderer { VkPipeline pipeline; -- 1.7.10.4