5 #include <vulkan/vulkan.h>
11 static const char *vk_strerror(VkResult res);
15 int ggfx_init(const char *appname, unsigned int flags)
18 VkInstanceCreateInfo iinf = {0};
19 VkApplicationInfo appinf = {0};
20 VkLayerProperties *lprop = 0;
21 VkExtensionProperties *iext;
22 uint32_t i, j, num_inst_layers, num_inst_ext, lprop_count, iext_count, pdev_count;
23 char **inst_layers = 0, **inst_ext = 0;
24 VkPhysicalDevice *pdev;
25 VkPhysicalDeviceProperties pdevp;
27 static const char *debug_layers[] = {
28 "VK_LAYER_LUNARG_device_limits",
29 "VK_LAYER_LUNARG_image",
30 "VK_LAYER_LUNARG_object_tracker",
31 "VK_LAYER_LUNARG_core_validation",
32 "VK_LAYER_LUNARG_parameter_validation",
33 "VK_LAYER_LUNARG_swapchain",
34 "VK_LAYER_GOOGLE_threading",
35 "VK_LAYER_GOOGLE_unique_objects",
38 static const char *extensions[] = {
40 "VK_KHR_xlib_surface",
41 "VK_KHR_win32_surface",
45 vkEnumerateInstanceLayerProperties(&lprop_count, 0);
47 if(!(lprop = malloc(lprop_count * sizeof *lprop))) {
48 perror("ggfx_init: failed to allocate layer property list");
51 vkEnumerateInstanceLayerProperties(&lprop_count, lprop);
53 if(flags & GGFX_INIT_DEBUG) {
54 if(!(inst_layers = malloc(lprop_count * sizeof *inst_layers))) {
55 perror("ggfx_init: failed to allocate layer properties");
60 printf("%d available instance layers\n", lprop_count);
62 for(i=0; i<lprop_count; i++) {
65 for(j=0; debug_layers[j]; j++) {
66 if(strcmp(lprop[i].layerName, debug_layers[j]) == 0) {
67 inst_layers[num_inst_layers++] = lprop[i].layerName;
74 printf(" [%c] %s: %s\n", use, lprop[i].layerName, lprop[i].description);
78 vkEnumerateInstanceExtensionProperties(0, &iext_count, 0);
80 if(!(iext = malloc(iext_count * sizeof *iext))) {
81 perror("ggfx_init: failed to allocate instance extensions property list");
84 vkEnumerateInstanceExtensionProperties(0, &iext_count, iext);
86 if(!(inst_ext = malloc(iext_count * sizeof *inst_ext))) {
87 perror("ggfx_init: failed to allocate instance extension properties");
91 printf("%d available instance extensions\n", iext_count);
93 for(i=0; i<iext_count; i++) {
95 for(j=0; extensions[j]; j++) {
96 if(strcmp(iext[i].extensionName, extensions[j]) == 0) {
97 inst_ext[num_inst_ext++] = iext[i].extensionName;
102 printf(" [%c] %s\n", use, iext[i].extensionName);
107 appinf.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
108 appinf.pApplicationName = appname ? appname : "unknown";
109 appinf.applicationVersion = 1;
110 appinf.pEngineName = "gph-gfx";
111 appinf.engineVersion = VK_MAKE_VERSION(VER_MAJOR, VER_MINOR, 0);
113 iinf.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
114 iinf.pApplicationInfo = &appinf;
115 iinf.ppEnabledLayerNames = (const char**)inst_layers;
116 iinf.enabledLayerCount = num_inst_layers;
117 iinf.ppEnabledExtensionNames = (const char**)inst_ext;
118 iinf.enabledExtensionCount = num_inst_ext;
120 if((res = vkCreateInstance(&iinf, 0, &vk)) != 0) {
121 fprintf(stderr, "ggfx_init: failed to create vulkan instance: %s\n", vk_strerror(res));
125 if(vkEnumeratePhysicalDevices(vk, &pdev_count, 0) != 0 || !pdev_count) {
126 fprintf(stderr, "ggfx_init: failed to enumerate physical devices\n");
129 if(!(pdev = malloc(pdev_count * sizeof *pdev))) {
130 perror("ggfx_init: failed to allocate memory for physical devices");
133 vkEnumeratePhysicalDevices(vk, &pdev_count, pdev);
135 printf("Found %d physical devices\n", pdev_count);
136 for(i=0; i<pdev_count; i++) {
137 vkGetPhysicalDeviceProperties(pdev[i], &pdevp);
138 printf(" - %s\n", pdevp.deviceName);
144 void ggfx_shutdown(void)
148 vkDestroyInstance(vk, 0);
152 static const char *vk_strerror(VkResult res)
155 case VK_SUCCESS: return "success";
156 case VK_NOT_READY: return "not ready";
157 case VK_TIMEOUT: return "timeout";
158 case VK_EVENT_SET: return "event set";
159 case VK_EVENT_RESET: return "event reset";
160 case VK_INCOMPLETE: return "incomplete";
161 case VK_ERROR_OUT_OF_HOST_MEMORY: return "out of host memory";
162 case VK_ERROR_OUT_OF_DEVICE_MEMORY: return "out of device memory";
163 case VK_ERROR_INITIALIZATION_FAILED: return "init failed";
164 case VK_ERROR_DEVICE_LOST: return "device lost";
165 case VK_ERROR_MEMORY_MAP_FAILED: return "map failed";
166 case VK_ERROR_LAYER_NOT_PRESENT: return "layer not present";
167 case VK_ERROR_EXTENSION_NOT_PRESENT: return "extension not present";
168 case VK_ERROR_FEATURE_NOT_PRESENT: return "feature not present";
169 case VK_ERROR_INCOMPATIBLE_DRIVER: return "incompatible driver";
170 case VK_ERROR_TOO_MANY_OBJECTS: return "too many objects";
171 case VK_ERROR_FORMAT_NOT_SUPPORTED: return "format not supported";
172 case VK_ERROR_FRAGMENTED_POOL: return "framgented pool";
173 case VK_ERROR_OUT_OF_POOL_MEMORY: return "out of pool memory";
174 case VK_ERROR_INVALID_EXTERNAL_HANDLE: return "invalid external handle";
175 case VK_ERROR_FRAGMENTATION: return "fragmentation";
176 case VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: return "invalid opaque capture address";
177 case VK_ERROR_SURFACE_LOST_KHR: return "surface lost";
178 case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: return "native window in use";
179 case VK_SUBOPTIMAL_KHR: return "suboptimal";
180 case VK_ERROR_OUT_OF_DATE_KHR: return "out of date";
181 case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: return "incompatible display";
182 case VK_ERROR_VALIDATION_FAILED_EXT: return "validation failed";
183 case VK_ERROR_INVALID_SHADER_NV: return "invalid shader";
184 case VK_ERROR_INCOMPATIBLE_VERSION_KHR: return "incompatible version";
185 case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT: return "invalid DRM format modifier plane layout";
186 case VK_ERROR_NOT_PERMITTED_EXT: return "not permitted";
187 case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT: return "fullscreen exclusive mode lost";
188 case VK_THREAD_IDLE_KHR: return "thread idle";
189 case VK_THREAD_DONE_KHR: return "thread done";
190 case VK_OPERATION_DEFERRED_KHR: return "operation deferred";
191 case VK_OPERATION_NOT_DEFERRED_KHR: return "operation not deferred";
192 case VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT: return "pipeline compile required";
194 case VK_ERROR_UNKNOWN: