vulkan_test2

annotate main.c @ 2:5b2ae06283aa

more queries
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 18 Dec 2016 09:15:16 +0200
parents 8cb584143df3
children
rev   line source
nuclear@0 1 #include <stdio.h>
nuclear@0 2 #include <stdlib.h>
nuclear@0 3 #include <string.h>
nuclear@0 4 #include <alloca.h>
nuclear@0 5 #include <vulkan/vulkan.h>
nuclear@0 6
nuclear@0 7 const char *get_device_name(VkPhysicalDeviceType type);
nuclear@2 8 const char *get_mem_prop_flag_string(VkMemoryPropertyFlags flags);
nuclear@0 9 const char *get_queue_flag_string(VkQueueFlagBits flags);
nuclear@0 10 int ver_major(uint32_t ver);
nuclear@0 11 int ver_minor(uint32_t ver);
nuclear@0 12 int ver_patch(uint32_t ver);
nuclear@2 13 const char *mem_size_str(long sz);
nuclear@0 14
nuclear@0 15 int main(void)
nuclear@0 16 {
nuclear@0 17 int i, j;
nuclear@0 18 VkInstance vk;
nuclear@0 19 VkInstanceCreateInfo inst_info;
nuclear@0 20 VkPhysicalDevice *devices;
nuclear@0 21 VkDevice vkdev;
nuclear@0 22 VkDeviceCreateInfo dev_info;
nuclear@0 23 VkDeviceQueueCreateInfo queue_info;
nuclear@0 24 uint32_t num_devices;
nuclear@0 25 int sel_dev = -1;
nuclear@0 26 int sel_qfamily = -1;
nuclear@0 27 float qprio = 0.0f;
nuclear@0 28
nuclear@0 29 memset(&inst_info, 0, sizeof inst_info);
nuclear@0 30 inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
nuclear@0 31
nuclear@0 32 if(vkCreateInstance(&inst_info, 0, &vk) != 0) {
nuclear@0 33 fprintf(stderr, "failed to create vulkan instance\n");
nuclear@0 34 return 1;
nuclear@0 35 }
nuclear@0 36 printf("created vulkan instance\n");
nuclear@0 37
nuclear@0 38 if(vkEnumeratePhysicalDevices(vk, &num_devices, 0) != 0) {
nuclear@0 39 fprintf(stderr, "failed to enumerate vulkan physical devices\n");
nuclear@0 40 return 1;
nuclear@0 41 }
nuclear@0 42 devices = alloca(num_devices * sizeof *devices);
nuclear@0 43 if(vkEnumeratePhysicalDevices(vk, &num_devices, devices) != 0) {
nuclear@0 44 fprintf(stderr, "failed to enumerate vulkan physical devices\n");
nuclear@0 45 return 1;
nuclear@0 46 }
nuclear@0 47 printf("found %u physical device(s)\n", (unsigned int)num_devices);
nuclear@0 48
nuclear@0 49 for(i=0; i<(int)num_devices; i++) {
nuclear@0 50 VkPhysicalDeviceProperties dev_prop;
nuclear@2 51 VkPhysicalDeviceMemoryProperties mem_prop;
nuclear@0 52 VkQueueFamilyProperties *qprop;
nuclear@0 53 uint32_t qprop_count;
nuclear@0 54
nuclear@0 55 vkGetPhysicalDeviceProperties(devices[i], &dev_prop);
nuclear@0 56
nuclear@0 57 printf("Device %d: %s\n", i, dev_prop.deviceName);
nuclear@0 58 printf(" type: %s\n", get_device_name(dev_prop.deviceType));
nuclear@0 59 printf(" API version: %d.%d.%d\n", ver_major(dev_prop.apiVersion), ver_minor(dev_prop.apiVersion),
nuclear@0 60 ver_patch(dev_prop.apiVersion));
nuclear@0 61 printf(" driver version: %d.%d.%d\n", ver_major(dev_prop.driverVersion), ver_minor(dev_prop.driverVersion),
nuclear@0 62 ver_patch(dev_prop.driverVersion));
nuclear@0 63 printf(" vendor id: %x device id: %x\n", dev_prop.vendorID, dev_prop.deviceID);
nuclear@0 64
nuclear@2 65
nuclear@2 66 vkGetPhysicalDeviceMemoryProperties(devices[i], &mem_prop);
nuclear@2 67 printf(" %d memory heaps:\n", mem_prop.memoryHeapCount);
nuclear@2 68 for(j=0; j<mem_prop.memoryHeapCount; j++) {
nuclear@2 69 VkMemoryHeap heap = mem_prop.memoryHeaps[j];
nuclear@2 70 printf(" Heap %d - size: %s, flags: %s\n", j, mem_size_str(heap.size),
nuclear@2 71 heap.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT ? "device-local" : "-");
nuclear@2 72 }
nuclear@2 73 printf(" %d memory types:\n", mem_prop.memoryTypeCount);
nuclear@2 74 for(j=0; j<mem_prop.memoryTypeCount; j++) {
nuclear@2 75 VkMemoryType type = mem_prop.memoryTypes[j];
nuclear@2 76 printf(" Type %d - heap: %d, flags: %s\n", j, type.heapIndex,
nuclear@2 77 get_mem_prop_flag_string(type.propertyFlags));
nuclear@2 78 }
nuclear@2 79
nuclear@0 80 vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &qprop_count, 0);
nuclear@0 81 if(qprop_count <= 0) {
nuclear@0 82 continue;
nuclear@0 83 }
nuclear@0 84 qprop = malloc(qprop_count * sizeof *qprop);
nuclear@0 85 vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &qprop_count, qprop);
nuclear@0 86
nuclear@0 87 for(j=0; j<qprop_count; j++) {
nuclear@0 88 printf(" Queue family %d:\n", j);
nuclear@0 89 printf(" flags: %s\n", get_queue_flag_string(qprop[j].queueFlags));
nuclear@0 90 printf(" num queues: %u\n", qprop[j].queueCount);
nuclear@0 91
nuclear@0 92 if(qprop[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
nuclear@0 93 sel_dev = i;
nuclear@0 94 sel_qfamily = j;
nuclear@0 95 }
nuclear@0 96 }
nuclear@0 97 free(qprop);
nuclear@0 98 }
nuclear@0 99
nuclear@0 100 if(sel_dev < 0 || sel_qfamily < 0) {
nuclear@0 101 fprintf(stderr, "failed to find any device with a graphics-capable command queue\n");
nuclear@0 102 vkDestroyDevice(vkdev, 0);
nuclear@0 103 return 1;
nuclear@0 104 }
nuclear@0 105
nuclear@1 106 // create device & command queue
nuclear@0 107 memset(&queue_info, 0, sizeof queue_info);
nuclear@0 108 queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
nuclear@0 109 queue_info.queueFamilyIndex = sel_qfamily;
nuclear@0 110 queue_info.queueCount = 1;
nuclear@0 111 queue_info.pQueuePriorities = &qprio;
nuclear@0 112
nuclear@0 113 memset(&dev_info, 0, sizeof dev_info);
nuclear@0 114 dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
nuclear@0 115 dev_info.queueCreateInfoCount = 1;
nuclear@0 116 dev_info.pQueueCreateInfos = &queue_info;
nuclear@0 117
nuclear@0 118 if(vkCreateDevice(devices[sel_dev], &dev_info, 0, &vkdev) != 0) {
nuclear@0 119 fprintf(stderr, "failed to create device %d\n", sel_dev);
nuclear@0 120 return 1;
nuclear@0 121 }
nuclear@0 122 printf("created device %d\n", sel_dev);
nuclear@0 123
nuclear@0 124 vkDestroyDevice(vkdev, 0);
nuclear@0 125 vkDestroyInstance(vk, 0);
nuclear@0 126 return 0;
nuclear@0 127 }
nuclear@0 128
nuclear@0 129
nuclear@0 130 const char *get_device_name(VkPhysicalDeviceType type)
nuclear@0 131 {
nuclear@0 132 switch(type) {
nuclear@0 133 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
nuclear@0 134 return "integrated GPU";
nuclear@0 135 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
nuclear@0 136 return "discrete GPU";
nuclear@0 137 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
nuclear@0 138 return "virtual GPU";
nuclear@0 139 case VK_PHYSICAL_DEVICE_TYPE_CPU:
nuclear@0 140 return "CPU";
nuclear@0 141 default:
nuclear@0 142 break;
nuclear@0 143 }
nuclear@0 144 return "unknown";
nuclear@0 145 }
nuclear@0 146
nuclear@2 147 const char *get_mem_prop_flag_string(VkMemoryPropertyFlags flags)
nuclear@2 148 {
nuclear@2 149 static char str[128];
nuclear@2 150
nuclear@2 151 str[0] = 0;
nuclear@2 152 if(flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
nuclear@2 153 strcat(str, "device-local ");
nuclear@2 154 }
nuclear@2 155 if(flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
nuclear@2 156 strcat(str, "host-visible ");
nuclear@2 157 }
nuclear@2 158 if(flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
nuclear@2 159 strcat(str, "host-coherent ");
nuclear@2 160 }
nuclear@2 161 if(flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) {
nuclear@2 162 strcat(str, "host-cached ");
nuclear@2 163 }
nuclear@2 164 if(flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) {
nuclear@2 165 strcat(str, "lazily-allocated ");
nuclear@2 166 }
nuclear@2 167
nuclear@2 168 if(!*str) {
nuclear@2 169 strcat(str, "-");
nuclear@2 170 }
nuclear@2 171 return str;
nuclear@2 172 }
nuclear@2 173
nuclear@0 174 const char *get_queue_flag_string(VkQueueFlagBits flags)
nuclear@0 175 {
nuclear@0 176 static char str[128];
nuclear@0 177
nuclear@0 178 str[0] = 0;
nuclear@0 179 if(flags & VK_QUEUE_GRAPHICS_BIT) {
nuclear@0 180 strcat(str, "graphics ");
nuclear@0 181 }
nuclear@0 182 if(flags & VK_QUEUE_COMPUTE_BIT) {
nuclear@0 183 strcat(str, "compute ");
nuclear@0 184 }
nuclear@0 185 if(flags & VK_QUEUE_TRANSFER_BIT) {
nuclear@0 186 strcat(str, "transfer ");
nuclear@0 187 }
nuclear@0 188 if(flags & VK_QUEUE_SPARSE_BINDING_BIT) {
nuclear@0 189 strcat(str, "sparse-binding ");
nuclear@0 190 }
nuclear@2 191 if(!*str) {
nuclear@2 192 strcat(str, "-");
nuclear@2 193 }
nuclear@0 194 return str;
nuclear@0 195 }
nuclear@0 196
nuclear@0 197 int ver_major(uint32_t ver)
nuclear@0 198 {
nuclear@0 199 return (ver >> 22) & 0x3ff;
nuclear@0 200 }
nuclear@0 201
nuclear@0 202 int ver_minor(uint32_t ver)
nuclear@0 203 {
nuclear@0 204 return (ver >> 12) & 0x3ff;
nuclear@0 205 }
nuclear@0 206
nuclear@0 207 int ver_patch(uint32_t ver)
nuclear@0 208 {
nuclear@0 209 return ver & 0xfff;
nuclear@0 210 }
nuclear@2 211
nuclear@2 212 const char *mem_size_str(long sz)
nuclear@2 213 {
nuclear@2 214 static char str[64];
nuclear@2 215 static const char *unitstr[] = { "bytes", "KB", "MB", "GB", "TB", "PB", 0 };
nuclear@2 216 int uidx = 0;
nuclear@2 217 sz *= 10;
nuclear@2 218
nuclear@2 219 while(sz >= 10240 && unitstr[uidx + 1]) {
nuclear@2 220 sz /= 1024;
nuclear@2 221 ++uidx;
nuclear@2 222 }
nuclear@2 223 sprintf(str, "%ld.%ld %s", sz / 10, sz % 10, unitstr[uidx]);
nuclear@2 224 return str;
nuclear@2 225 }