--- /dev/null
+#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;
+}
--- /dev/null
+#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 */
+}