4 #include <vulkan/vulkan.h>
8 static int create_instance(void);
9 static int create_device(void);
10 static int have_inst_layer(const char *name);
11 static int have_inst_ext(const char *name);
12 static int have_dev_ext(const char *name);
16 static VkLayerProperties *inst_layers;
17 static VkExtensionProperties *inst_ext, *dev_ext;
18 static uint32_t inst_ext_count, dev_ext_count, inst_layers_count;
20 static VkPhysicalDevice *pdev_list;
21 static uint32_t num_pdev;
23 static int have_raytrace, have_debug_report;
25 #define ARRSZ(arr) (sizeof arr / sizeof *arr)
26 static const char *known_layer_list[] = {
27 "VK_LAYER_GOOGLE_threading",
28 "VK_LAYER_LUNARG_parameter_validation",
29 "VK_LAYER_LUNARG_object_tracker",
30 "VK_LAYER_LUNARG_image",
31 "VK_LAYER_LUNARG_core_validation",
32 "VK_LAYER_LUNARG_swapchain",
33 "VK_LAYER_GOOGLE_unique_objects"
39 } known_ext_list[] = {
40 {"VK_KHR_surface", 1},
42 {"VK_KHR_win32_surface", 1},
44 {"VK_KHR_xlib_surface", 1},
46 {"VK_KHR_debug_report", 0},
47 {"VK_KHR_acceleration_structure", 0},
48 {"VK_KHR_ray_tracing_pipeline", 0}
53 if(create_instance() == -1) {
56 if(create_device() == -1) {
64 vkDestroyInstance(vk, 0);
71 static int create_instance(void)
73 int i, nlayers = 0, next = 0;
74 VkInstanceCreateInfo instinf;
75 VkApplicationInfo appinf;
76 const char *layers[ARRSZ(known_layer_list)];
77 const char *ext[ARRSZ(known_ext_list)];
80 vkEnumerateInstanceVersion(&apiver);
81 printf("Vulkan API version: %d.%d.%d\n", (apiver >> 22) & 0x7f,
82 (apiver >> 12) & 0x3ff, apiver & 0xfff);
84 memset(&appinf, 0, sizeof appinf);
85 appinf.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
86 appinf.pApplicationName = "vkray";
87 appinf.pEngineName = "vkray";
88 appinf.apiVersion = apiver;
90 vkEnumerateInstanceLayerProperties(&inst_layers_count, 0);
91 inst_layers = malloc_nf(inst_layers_count * sizeof *inst_layers);
92 vkEnumerateInstanceLayerProperties(&inst_layers_count, inst_layers);
94 vkEnumerateInstanceExtensionProperties(0, &inst_ext_count, 0);
95 inst_ext = malloc_nf(inst_ext_count * sizeof *inst_ext);
96 vkEnumerateInstanceExtensionProperties(0, &inst_ext_count, inst_ext);
99 for(i=0; i<inst_layers_count; i++) {
100 printf(" - %s: %s\n", inst_layers[i].layerName, inst_layers[i].description);
102 printf("Instance extensions:\n");
103 for(i=0; i<inst_ext_count; i++) {
104 printf(" - %s\n", inst_ext[i].extensionName);
107 have_raytrace = have_inst_ext("VK_KHR_ray_tracing_pipeline");
108 have_debug_report = have_inst_ext("VK_KHR_debug_report");
110 for(i=0; i<ARRSZ(known_layer_list); i++) {
111 if(have_inst_layer(known_layer_list[i])) {
112 layers[nlayers++] = known_layer_list[i];
115 for(i=0; i<ARRSZ(known_ext_list); i++) {
116 if(have_inst_ext(known_ext_list[i].name)) {
117 ext[next++] = known_ext_list[i].name;
118 } else if(known_ext_list[i].required) {
119 fprintf(stderr, "Vulkan implementation lacks required instance extension: %s\n",
120 known_ext_list[i].name);
125 memset(&instinf, 0, sizeof instinf);
126 instinf.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
127 instinf.pApplicationInfo = &appinf;
128 instinf.enabledLayerCount = nlayers;
129 instinf.ppEnabledLayerNames = layers;
130 instinf.enabledExtensionCount = next;
131 instinf.ppEnabledExtensionNames = ext;
132 if(vkCreateInstance(&instinf, 0, &vk) != 0) {
133 fprintf(stderr, "failed to create vulkan instance\n");
140 static int create_device(void)
143 VkPhysicalDeviceProperties2 pdevprop2;
144 VkPhysicalDeviceRayTracingPipelinePropertiesKHR raypipe_prop;
145 VkPhysicalDeviceAccelerationStructurePropertiesKHR rayacc_prop;
147 vkEnumeratePhysicalDevices(vk, &num_pdev, 0);
148 pdev_list = malloc_nf(num_pdev * sizeof *pdev_list);
149 vkEnumeratePhysicalDevices(vk, &num_pdev, pdev_list);
151 printf("Found %d physical devices\n", num_pdev);
152 for(i=0; i<num_pdev; i++) {
154 memset(&rayacc_prop, 0, sizeof rayacc_prop);
155 rayacc_prop.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR;
157 memset(&raypipe_prop, 0, sizeof raypipe_prop);
158 raypipe_prop.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR;
159 raypipe_prop.pNext = &rayacc_prop;
162 memset(&pdevprop2, 0, sizeof pdevprop2);
163 pdevprop2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
164 pdevprop2.pNext = have_raytrace ? &raypipe_prop : 0;
166 vkGetPhysicalDeviceProperties2(pdev_list[i], &pdevprop2);
167 printf(" %d: %s\n", i, pdevprop2.properties.deviceName);
169 printf(" Raytracing properties:\n");
170 printf(" max ray recursion: %u\n", raypipe_prop.maxRayRecursionDepth);
171 printf(" max ray dispatch: %u\n", raypipe_prop.maxRayDispatchInvocationCount);
172 printf(" max leaf geometry: %llu\n", (unsigned long long)rayacc_prop.maxGeometryCount);
173 printf(" max leaf primitves: %llu\n", (unsigned long long)rayacc_prop.maxPrimitiveCount);
174 printf(" max instances: %llu\n", (unsigned long long)rayacc_prop.maxInstanceCount);
181 static int have_inst_layer(const char *name)
184 for(i=0; i<inst_layers_count; i++) {
185 if(strcmp(inst_layers[i].layerName, name) == 0) {
192 static int have_inst_ext(const char *name)
195 for(i=0; i<inst_ext_count; i++) {
196 if(strcmp(inst_ext[i].extensionName, name) == 0) {
203 static int have_dev_ext(const char *name)