foo
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 19 Dec 2021 07:23:03 +0000 (09:23 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 19 Dec 2021 07:23:03 +0000 (09:23 +0200)
src/app.c
src/main_x11.c
src/util.c [new file with mode: 0644]
src/util.h [new file with mode: 0644]
src/vk.c [new file with mode: 0644]
src/vk.h [new file with mode: 0644]

index 9be52ca..4d845c5 100644 (file)
--- a/src/app.c
+++ b/src/app.c
@@ -1,12 +1,17 @@
 #include "app.h"
+#include "vk.h"
 
 int app_init(void)
 {
+       if(vk_init() == -1) {
+               return -1;
+       }
        return 0;
 }
 
 void app_cleanup(void)
 {
+       vk_cleanup();
 }
 
 
index 54f4df6..d593494 100644 (file)
@@ -32,6 +32,10 @@ int main(int argc, char **argv)
                return 1;
        }
 
+       if(app_init() == -1) {
+               goto end;
+       }
+
        for(;;) {
                while(XPending(dpy)) {
                        XNextEvent(dpy, &ev);
@@ -46,6 +50,7 @@ int main(int argc, char **argv)
        }
 
 end:
+       app_cleanup();
        XDestroyWindow(dpy, win);
        XCloseDisplay(dpy);
        return 0;
diff --git a/src/util.c b/src/util.c
new file mode 100644 (file)
index 0000000..dc86d10
--- /dev/null
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "util.h"
+
+void *malloc_nf_impl(size_t sz, const char *file, int line)
+{
+       void *p;
+       if(!(p = malloc(sz))) {
+               fprintf(stderr, "%s:%d failed to allocate %lu bytes\n", file, line, (unsigned long)sz);
+               abort();
+       }
+       return p;
+}
+
+void *calloc_nf_impl(size_t num, size_t sz, const char *file, int line)
+{
+       void *p;
+       if(!(p = calloc(num, sz))) {
+               fprintf(stderr, "%s:%d failed to allocate %lu bytes\n", file, line, (unsigned long)(sz * num));
+               abort();
+       }
+       return p;
+}
+
+void *realloc_nf_impl(void *p, size_t sz, const char *file, int line)
+{
+       if(!(p = realloc(p, sz))) {
+               fprintf(stderr, "%s:%d failed to realloc %lu bytes\n", file, line, (unsigned long)sz);
+               abort();
+       }
+       return p;
+}
+
+char *strdup_nf_impl(const char *s, const char *file, int line)
+{
+       char *res;
+       if(!(res = strdup(s))) {
+               fprintf(stderr, "%s:%d failed to duplicate string\n", file, line);
+               abort();
+       }
+       return res;
+}
diff --git a/src/util.h b/src/util.h
new file mode 100644 (file)
index 0000000..61ae532
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(__WATCOMC__) || defined(WIN32)
+#include <malloc.h>
+#else
+#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
+#include <alloca.h>
+#endif
+#endif
+
+#ifdef _MSC_VER
+#define strcasecmp(s, k) stricmp(s, k)
+#endif
+
+#define malloc_nf(sz)  malloc_nf_impl(sz, __FILE__, __LINE__)
+void *malloc_nf_impl(size_t sz, const char *file, int line);
+
+#define calloc_nf(num, sz)     calloc_nf_impl(num, sz, __FILE__, __LINE__)
+void *calloc_nf_impl(size_t num, size_t sz, const char *file, int line);
+
+#define realloc_nf(p, sz)      realloc_nf_impl(p, sz, __FILE__, __LINE__)
+void *realloc_nf_impl(void *p, size_t sz, const char *file, int line);
+
+#define strdup_nf(s)   strdup_nf_impl(s, __FILE__, __LINE__)
+char *strdup_nf_impl(const char *s, const char *file, int line);
+
+#endif /* UTIL_H_ */
diff --git a/src/vk.c b/src/vk.c
new file mode 100644 (file)
index 0000000..1fcba58
--- /dev/null
+++ b/src/vk.c
@@ -0,0 +1,189 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <vulkan/vulkan.h>
+#include "vk.h"
+#include "util.h"
+
+static int create_instance(void);
+static int create_device(void);
+static int have_inst_layer(const char *name);
+static int have_inst_ext(const char *name);
+static int have_dev_ext(const char *name);
+
+static VkInstance vk;
+
+static VkLayerProperties *inst_layers;
+static VkExtensionProperties *inst_ext, *dev_ext;
+static uint32_t inst_ext_count, dev_ext_count, inst_layers_count;
+
+static VkPhysicalDevice *pdev_list;
+static uint32_t num_pdev;
+
+static int have_debug_report;
+
+#define ARRSZ(arr)     (sizeof arr / sizeof *arr)
+static const char *known_layer_list[] = {
+       "VK_LAYER_GOOGLE_threading",
+       "VK_LAYER_LUNARG_parameter_validation",
+       "VK_LAYER_LUNARG_object_tracker",
+       "VK_LAYER_LUNARG_image",
+       "VK_LAYER_LUNARG_core_validation",
+       "VK_LAYER_LUNARG_swapchain",
+       "VK_LAYER_GOOGLE_unique_objects"
+};
+
+static struct {
+       const char *name;
+       int required;
+} known_ext_list[] = {
+       {"VK_KHR_surface", 1},
+#ifdef __WIN32__
+       {"VK_KHR_win32_surface", 1},
+#else
+       {"VK_KHR_xlib_surface", 1},
+#endif
+       {"VK_KHR_debug_report", 0},
+       {"VK_KHR_acceleration_structure", 0},
+       {"VK_KHR_ray_tracing_pipeline", 0}
+};
+
+int vk_init(void)
+{
+       if(create_instance() == -1) {
+               return -1;
+       }
+       if(create_device() == -1) {
+               return -1;
+       }
+       return 0;
+}
+
+void vk_cleanup(void)
+{
+       vkDestroyInstance(vk, 0);
+       free(inst_layers);
+       free(inst_ext);
+       free(pdev_list);
+}
+
+
+static int create_instance(void)
+{
+       int i, nlayers = 0, next = 0;
+       VkInstanceCreateInfo instinf;
+       VkApplicationInfo appinf;
+       const char *layers[ARRSZ(known_layer_list)];
+       const char *ext[ARRSZ(known_ext_list)];
+       uint32_t apiver;
+
+       vkEnumerateInstanceVersion(&apiver);
+       printf("Vulkan API version: %d.%d.%d\n", (apiver >> 22) & 0x7f,
+                       (apiver >> 12) & 0x3ff, apiver & 0xfff);
+
+       memset(&appinf, 0, sizeof appinf);
+       appinf.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+       appinf.pApplicationName = "vkray";
+       appinf.pEngineName = "vkray";
+       appinf.apiVersion = apiver;
+
+       vkEnumerateInstanceLayerProperties(&inst_layers_count, 0);
+       inst_layers = malloc_nf(inst_layers_count * sizeof *inst_layers);
+       vkEnumerateInstanceLayerProperties(&inst_layers_count, inst_layers);
+
+       vkEnumerateInstanceExtensionProperties(0, &inst_ext_count, 0);
+       inst_ext = malloc_nf(inst_ext_count * sizeof *inst_ext);
+       vkEnumerateInstanceExtensionProperties(0, &inst_ext_count, inst_ext);
+
+       printf("Layers:\n");
+       for(i=0; i<inst_layers_count; i++) {
+               printf(" - %s: %s\n", inst_layers[i].layerName, inst_layers[i].description);
+       }
+       printf("Instance extensions:\n");
+       for(i=0; i<inst_ext_count; i++) {
+               printf(" - %s\n", inst_ext[i].extensionName);
+       }
+       have_debug_report = have_inst_ext("VK_KHR_debug_report");
+
+       for(i=0; i<ARRSZ(known_layer_list); i++) {
+               if(have_inst_layer(known_layer_list[i])) {
+                       layers[nlayers++] = known_layer_list[i];
+               }
+       }
+       for(i=0; i<ARRSZ(known_ext_list); i++) {
+               if(have_inst_ext(known_ext_list[i].name)) {
+                       ext[next++] = known_ext_list[i].name;
+               } else if(known_ext_list[i].required) {
+                       fprintf(stderr, "Vulkan implementation lacks required instance extension: %s\n",
+                                       known_ext_list[i].name);
+                       return -1;
+               }
+       }
+
+       memset(&instinf, 0, sizeof instinf);
+       instinf.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+       instinf.pApplicationInfo = &appinf;
+       instinf.enabledLayerCount = nlayers;
+       instinf.ppEnabledLayerNames = layers;
+       instinf.enabledExtensionCount = next;
+       instinf.ppEnabledExtensionNames = ext;
+       if(vkCreateInstance(&instinf, 0, &vk) != 0) {
+               fprintf(stderr, "failed to create vulkan instance\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+static int create_device(void)
+{
+       int i;
+       VkPhysicalDeviceProperties2 pdevprop2;
+       VkPhysicalDeviceAccelerationStructurePropertiesKHR rayacc_prop;
+
+       vkEnumeratePhysicalDevices(vk, &num_pdev, 0);
+       pdev_list = malloc_nf(num_pdev * sizeof *pdev_list);
+       vkEnumeratePhysicalDevices(vk, &num_pdev, pdev_list);
+
+       printf("Found %d physical devices\n", num_pdev);
+       for(i=0; i<num_pdev; i++) {
+               memset(&rayacc_prop, 0, sizeof rayacc_prop);
+               rayacc_prop.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR;
+
+               memset(&pdevprop2, 0, sizeof pdevprop2);
+               pdevprop2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+               pdevprop2.pNext = &rayacc_prop;
+
+               vkGetPhysicalDeviceProperties2(pdev_list[i], &pdevprop2);
+               printf(" %d: %s\n", i, pdevprop2.properties.deviceName);
+       }
+
+       return 0;
+}
+
+static int have_inst_layer(const char *name)
+{
+       int i;
+       for(i=0; i<inst_layers_count; i++) {
+               if(strcmp(inst_layers[i].layerName, name) == 0) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static int have_inst_ext(const char *name)
+{
+       int i;
+       for(i=0; i<inst_ext_count; i++) {
+               if(strcmp(inst_ext[i].extensionName, name) == 0) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static int have_dev_ext(const char *name)
+{
+       return 0;       /* TODO */
+}
diff --git a/src/vk.h b/src/vk.h
new file mode 100644 (file)
index 0000000..d30853b
--- /dev/null
+++ b/src/vk.h
@@ -0,0 +1,7 @@
+#ifndef VK_H_
+#define VK_H_
+
+int vk_init(void);
+void vk_cleanup(void);
+
+#endif /* VK_H_ */