diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 196 |
1 files changed, 148 insertions, 48 deletions
@@ -3,13 +3,15 @@ #include <stdio.h> #include <vulkan/vulkan.h> -#include <SDL2/SDL.h> -#include <SDL2/SDL_vulkan.h> +#include <vulkan/vulkan_wayland.h> +#include <wayland-client.h> #include <stdbool.h> #include <string.h> #include <libpng16/png.h> #include "linmath.h" #include "stb_image.h" +#include "xdg-shell-protocol.h" +#include "xdg-decoration.h" #define MAX_FRAMES_INFLIGHT 2 @@ -66,7 +68,18 @@ void get_attribute_description(VkVertexInputAttributeDescription out[3]) { }; } -static SDL_Window *window = NULL; +static struct wl_display *dpy; +static struct wl_registry *reg; +static struct wl_surface *wl_surface; +static struct wl_compositor *comp; +static struct xdg_wm_base *xdg_base; +static struct xdg_surface *xdg_surface; +static struct xdg_toplevel *xdg_toplevel; +static struct zxdg_decoration_manager_v1 *deco_manager; +static struct zxdg_toplevel_decoration_v1 *decoration; +static int32_t width, height; +static bool running = true; +static bool resize = false, should_resize = false; static VkDebugUtilsMessengerEXT debug_messenger; static VkInstance instance = VK_NULL_HANDLE; static VkPhysicalDevice phy_gpu = VK_NULL_HANDLE; @@ -182,12 +195,9 @@ VkExtent2D pick_swap_extent(const VkSurfaceCapabilitiesKHR *caps) { if (caps->currentExtent.width != UINT32_MAX) return caps->currentExtent; - int32_t w, h; - SDL_GetWindowSize(window, &w, &h); - VkExtent2D actual_extent = { - .width = w > caps->minImageExtent.width ? w < caps->maxImageExtent.width ? w : caps->maxImageExtent.width : caps->minImageExtent.width, - .height = h > caps->minImageExtent.height ? h < caps->maxImageExtent.height ? h : caps->maxImageExtent.height : caps->minImageExtent.height, + .width = width> caps->minImageExtent.width ? width< caps->maxImageExtent.width ? width: caps->maxImageExtent.width : caps->minImageExtent.width, + .height = height> caps->minImageExtent.height ? height< caps->maxImageExtent.height ? height: caps->maxImageExtent.height : caps->minImageExtent.height, }; return actual_extent; @@ -259,7 +269,21 @@ void cleanup() { vkDestroyDevice(gpu, NULL); vkDestroyInstance(instance, NULL); - SDL_DestroyWindow(window); + + zxdg_toplevel_decoration_v1_destroy(decoration); + zxdg_decoration_manager_v1_destroy(deco_manager); + + xdg_toplevel_destroy(xdg_toplevel); + xdg_surface_destroy(xdg_surface); + + wl_surface_destroy(wl_surface); + + xdg_wm_base_destroy(xdg_base); + wl_compositor_destroy(comp); + + wl_registry_destroy(reg); + wl_display_disconnect(dpy); + } static VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, @@ -278,16 +302,14 @@ void create_instance() { .apiVersion = VK_API_VERSION_1_0 }; - uint32_t sdl_exts = 0; - SDL_Vulkan_GetInstanceExtensions(window, &sdl_exts, NULL); - - const char *sdl_exts_names[sdl_exts + 1]; - SDL_Vulkan_GetInstanceExtensions(window, &sdl_exts, sdl_exts_names); - - sdl_exts_names[sdl_exts++] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME; + const char *exts[] = { + VK_KHR_SURFACE_EXTENSION_NAME, + VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, + VK_EXT_DEBUG_UTILS_EXTENSION_NAME + }; - for (size_t i = 0; i < sdl_exts; i++) { - puts(sdl_exts_names[i]); + for (size_t i = 0; i < sizeof(exts) / sizeof(*exts); i++) { + puts(exts[i]); }; const char *validation_layers[] = { "VK_LAYER_KHRONOS_validation" }; @@ -297,8 +319,8 @@ void create_instance() { .pApplicationInfo = &app_info, .enabledLayerCount = 1, .ppEnabledLayerNames = validation_layers, - .enabledExtensionCount = sdl_exts, - .ppEnabledExtensionNames = sdl_exts_names, + .enabledExtensionCount = sizeof(exts) / sizeof(*exts), + .ppEnabledExtensionNames = exts, }; VkResult res = vkCreateInstance(&create_info, NULL, &instance); @@ -1486,13 +1508,9 @@ void create_depth_resources() { } void recreate_swapchain() { - int32_t width = 0, height = 0; - SDL_GetWindowSize(window, &width, &height); - while (width == 0 || height == 0) { - SDL_Event e; - SDL_PollEvent(&e); - SDL_GetWindowSize(window, &width, &height); - } + //while (width == 0 || height == 0) { + //wl_display_roundtrip(dpy); + //} vkDeviceWaitIdle(gpu); @@ -1598,11 +1616,97 @@ void load_model() { free(obj.faces.data); } +static void global(void *data, struct wl_registry *reg, + uint32_t name, const char *interface, uint32_t version) { + if (strcmp(wl_compositor_interface.name, interface) == 0) { + comp = wl_registry_bind(reg, name, &wl_compositor_interface, version); + } else if (strcmp(xdg_wm_base_interface.name, interface) == 0) { + xdg_base = wl_registry_bind(reg, name, &xdg_wm_base_interface, version); + } else if (strcmp(zxdg_decoration_manager_v1_interface.name, interface) == 0) { + deco_manager = wl_registry_bind(reg, name, &zxdg_decoration_manager_v1_interface, version); + } +} + +static void global_remove(void *data, struct wl_registry *reg, uint32_t name) {} + +static struct wl_registry_listener reg_listener = { + .global = global, + .global_remove = global_remove +}; + +void ping(void *data, struct xdg_wm_base *base, uint32_t serial) { + xdg_wm_base_pong(base, serial); +} + +static struct xdg_wm_base_listener xdg_wm_list = { + .ping = ping +}; + +void xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial) { + xdg_surface_ack_configure(xdg_surface, serial); +} + +static struct xdg_surface_listener xdg_surface_listener = { + .configure = xdg_surface_configure, +}; + +void toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, + int32_t in_width, int32_t in_height, struct wl_array *states) { + printf("toplevel configure, w: %d, h: %d\n", in_width, in_height); + resize = true; + width = in_width != 0 ? in_width : 300; + height = in_height != 0 ? in_height : 300; +} + +void toplevel_close(void *data, struct xdg_toplevel *toplevel) { + struct state *state = data; + running = false; +} + +static struct xdg_toplevel_listener toplevel_listener = { + .configure = toplevel_configure, + .close = toplevel_close, +}; + void init() { - SDL_Init(SDL_INIT_VIDEO); - window = SDL_CreateWindow("vk", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 800, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE); - if (!window) { - fputs("failed to create sdl window", stderr); + dpy = wl_display_connect(NULL); + if (!dpy) { + fputs("failed to connect to wayland display", stderr); + exit(-1); + } + + reg = wl_display_get_registry(dpy); + wl_registry_add_listener(reg, ®_listener, NULL); + wl_display_roundtrip(dpy); + + resize = true; + if (!comp || !xdg_base || !deco_manager) { + fputs("failed to bind either compositor, xdg_base, or xdg_decoration", stderr); + exit(-1); + } + + xdg_wm_base_add_listener(xdg_base, &xdg_wm_list, NULL); + + wl_surface = wl_compositor_create_surface(comp); + xdg_surface = xdg_wm_base_get_xdg_surface(xdg_base, wl_surface); + xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, NULL); + + xdg_toplevel = xdg_surface_get_toplevel(xdg_surface); + xdg_toplevel_set_title(xdg_toplevel, "vk"); + xdg_toplevel_set_min_size(xdg_toplevel, 300, 300); + xdg_toplevel_add_listener(xdg_toplevel, &toplevel_listener, NULL); + + decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(deco_manager, xdg_toplevel); + zxdg_toplevel_decoration_v1_set_mode(decoration, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + + wl_surface_commit(wl_surface); + while(!resize) { + wl_display_roundtrip(dpy); + resize = false; + } + + if (!wl_surface) { + fputs("failed to create wl surface", stderr); exit(-1); } @@ -1621,8 +1725,15 @@ void init() { create_instance(); - if (SDL_Vulkan_CreateSurface(window, instance, &surface) != SDL_TRUE) { - fputs("failed to create surface", stderr); + VkWaylandSurfaceCreateInfoKHR wl_create_info = { + .sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, + .display = dpy, + .surface = wl_surface, + }; + + VkResult res = vkCreateWaylandSurfaceKHR(instance, &wl_create_info, NULL, &surface); + if (res != VK_SUCCESS) { + fputs("failed to create vk surface", stderr); exit(-1); } @@ -1739,23 +1850,12 @@ void draw() { int main() { init(); - bool running = true; - SDL_Event e; while (running) { - SDL_PollEvent(&e); - switch (e.type) { - case SDL_WINDOWEVENT: - if (e.window.event == SDL_WINDOWEVENT_RESIZED) - recreate_swapchain(); - break; - case SDL_KEYDOWN: - if (e.key.keysym.sym == SDLK_q) - running = false; - break; - case SDL_QUIT: - running = false; - break; + if (resize) { + recreate_swapchain(); + resize = false; } + wl_display_roundtrip(dpy); draw(); } |