quick backup
[demo] / src / vulkan / vk.cc
1 #define GLFW_INCLUDE_VULKAN
2 #include <GLFW/glfw3.h>
3
4 #include <alloca.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <string>
8 #include <vector>
9
10 #include "gfxapi.h"
11 #include "vkutil.h"
12
13 /* global variables */
14 extern GLFWwindow *win;
15 extern int win_w;
16 extern int win_h;
17
18 /* static functions */
19 static void error_callback(int error, const char *descr);
20 static void clear(float r, float g, float b);
21 static void viewport(int x, int y, int width, int height);
22 static void zbuffer(bool enable);
23 static void cull_face(Gfx_cull_face cf);
24 static void reshape(int width, int height);
25
26 bool init_vulkan()
27 {
28         if(!glfwInit()) {
29                 fprintf(stderr, "Failed to initialize GLFW.\n");
30                 return false;
31         }
32
33         if(!glfwVulkanSupported()) {
34                 fprintf(stderr, "No Vulkan support on the device.\n");
35                 return false;
36         }
37
38         glfwSetErrorCallback(error_callback);
39
40         if(!vku_create_device()) {
41                 fprintf(stderr, "Failed to initialize vulkan.\n");
42                 return false;
43         }
44
45         if(!glfwGetPhysicalDevicePresentationSupport(vkinst, vkpdev, vkqfamily)) {
46                 fprintf(stderr, "Presentation support not found.\n");
47                 return false;
48         }
49
50         glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
51         if(!(win = glfwCreateWindow(win_w, win_h, "vkcow", 0, 0))) {
52                 fprintf(stderr, "Failed to create window.\n");
53                 return false;
54         }
55
56         if(VkResult err = glfwCreateWindowSurface(vkinst, win, 0, &vksurface)) {
57                 fprintf(stderr, "Failed to create KHR surface: %s\n", vku_get_vulkan_error_str(err));
58                 return false;
59         }
60
61         if(!(vkswapchain = vku_create_swapchain(vksurface, win_w, win_h, 2,
62                                                 VK_PRESENT_MODE_FIFO_KHR, 0))) {
63                 fprintf(stderr, "Failed to create swapchain.\n");
64                 return false;
65         }
66
67         vkswapchain_images = vku_get_swapchain_images(vkswapchain, &vknum_swapchain_images);
68         if(!vkswapchain_images) {
69                 fprintf(stderr, "Failed to get swapchain images.\n");
70                 return false;
71         }
72
73         vkswapchain_views = vku_create_image_views(vkswapchain_images, vknum_swapchain_images);
74         if(!vkswapchain_views) {
75                 fprintf(stderr, "Failed to create swapchain image views.\n");
76                 delete [] vkswapchain_images;
77                 return false;
78         }
79
80         if(!vku_create_renderpass()) {
81                 fprintf(stderr, "Failed to create renderpass'\n");
82                 return false;
83         }
84
85         if(!vku_create_framebuffers(vkswapchain_views, vknum_swapchain_images, win_w, win_h)) {
86                 fprintf(stderr, "Failed to create framebuffers.\n");
87                 return false;
88         }
89
90         gfx_clear = clear;
91         gfx_viewport = viewport;
92         gfx_zbuffer = zbuffer;
93         gfx_cull_face = cull_face;
94         gfx_reshape = reshape;
95
96         return true;
97 }
98
99 void cleanup_vulkan()
100 {
101         if(win) {
102                 glfwDestroyWindow(win);
103         }
104         glfwTerminate();
105
106         //TODOs according to the book:
107         // 1- make sure all threads have been terminated (when I add threads)
108
109         // 2- destroy objects in *reverse* order
110         vkDestroyRenderPass(vkdev, vkrpass, 0);
111         vkDestroySurfaceKHR(vkinst, vksurface, 0);
112
113         vku_cleanup();
114 }
115
116 static void error_callback(int error, const char *description)
117 {
118         fprintf(stderr, "GLFW error %d: %s.\n", error, description);
119 }
120
121 static void reshape(int width, int height)
122 {
123         VkSwapchainKHR sc;
124         if(!(sc = vku_create_swapchain(vksurface, width, height, 2, VK_PRESENT_MODE_FIFO_KHR,
125                                        vkswapchain))) {
126                 fprintf(stderr, "Failed to create %dx%d double-buffered swapchain\n", width, height);
127                 return;
128         }
129         vkswapchain = sc;
130
131         delete [] vkswapchain_images;
132         vkswapchain_images = vku_get_swapchain_images(sc, 0);
133         vknext_swapchain_image = vku_get_next_image(vkswapchain);
134 }
135
136 static void clear(float r, float g, float b)
137 {
138 }
139
140 static void viewport(int x, int y, int width, int height)
141 {
142 }
143
144 static void zbuffer(bool enable)
145 {
146 }
147
148 static void cull_face(Gfx_cull_face cf)
149 {
150 }