vulkan_test2

annotate main.c @ 1:8cb584143df3

comment
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 01 Apr 2016 07:14:47 +0300
parents a13895a5f673
children 5b2ae06283aa
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@0 8 const char *get_queue_flag_string(VkQueueFlagBits flags);
nuclear@0 9 int ver_major(uint32_t ver);
nuclear@0 10 int ver_minor(uint32_t ver);
nuclear@0 11 int ver_patch(uint32_t ver);
nuclear@0 12
nuclear@0 13 int main(void)
nuclear@0 14 {
nuclear@0 15 int i, j;
nuclear@0 16 VkInstance vk;
nuclear@0 17 VkInstanceCreateInfo inst_info;
nuclear@0 18 VkPhysicalDevice *devices;
nuclear@0 19 VkDevice vkdev;
nuclear@0 20 VkDeviceCreateInfo dev_info;
nuclear@0 21 VkDeviceQueueCreateInfo queue_info;
nuclear@0 22 uint32_t num_devices;
nuclear@0 23 int sel_dev = -1;
nuclear@0 24 int sel_qfamily = -1;
nuclear@0 25 float qprio = 0.0f;
nuclear@0 26
nuclear@0 27 memset(&inst_info, 0, sizeof inst_info);
nuclear@0 28 inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
nuclear@0 29
nuclear@0 30 if(vkCreateInstance(&inst_info, 0, &vk) != 0) {
nuclear@0 31 fprintf(stderr, "failed to create vulkan instance\n");
nuclear@0 32 return 1;
nuclear@0 33 }
nuclear@0 34 printf("created vulkan instance\n");
nuclear@0 35
nuclear@0 36 if(vkEnumeratePhysicalDevices(vk, &num_devices, 0) != 0) {
nuclear@0 37 fprintf(stderr, "failed to enumerate vulkan physical devices\n");
nuclear@0 38 return 1;
nuclear@0 39 }
nuclear@0 40 devices = alloca(num_devices * sizeof *devices);
nuclear@0 41 if(vkEnumeratePhysicalDevices(vk, &num_devices, devices) != 0) {
nuclear@0 42 fprintf(stderr, "failed to enumerate vulkan physical devices\n");
nuclear@0 43 return 1;
nuclear@0 44 }
nuclear@0 45 printf("found %u physical device(s)\n", (unsigned int)num_devices);
nuclear@0 46
nuclear@0 47 for(i=0; i<(int)num_devices; i++) {
nuclear@0 48 VkPhysicalDeviceProperties dev_prop;
nuclear@0 49 VkQueueFamilyProperties *qprop;
nuclear@0 50 uint32_t qprop_count;
nuclear@0 51
nuclear@0 52 vkGetPhysicalDeviceProperties(devices[i], &dev_prop);
nuclear@0 53
nuclear@0 54 printf("Device %d: %s\n", i, dev_prop.deviceName);
nuclear@0 55 printf(" type: %s\n", get_device_name(dev_prop.deviceType));
nuclear@0 56 printf(" API version: %d.%d.%d\n", ver_major(dev_prop.apiVersion), ver_minor(dev_prop.apiVersion),
nuclear@0 57 ver_patch(dev_prop.apiVersion));
nuclear@0 58 printf(" driver version: %d.%d.%d\n", ver_major(dev_prop.driverVersion), ver_minor(dev_prop.driverVersion),
nuclear@0 59 ver_patch(dev_prop.driverVersion));
nuclear@0 60 printf(" vendor id: %x device id: %x\n", dev_prop.vendorID, dev_prop.deviceID);
nuclear@0 61
nuclear@0 62 vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &qprop_count, 0);
nuclear@0 63 if(qprop_count <= 0) {
nuclear@0 64 continue;
nuclear@0 65 }
nuclear@0 66 qprop = malloc(qprop_count * sizeof *qprop);
nuclear@0 67 vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &qprop_count, qprop);
nuclear@0 68
nuclear@0 69 for(j=0; j<qprop_count; j++) {
nuclear@0 70 printf(" Queue family %d:\n", j);
nuclear@0 71 printf(" flags: %s\n", get_queue_flag_string(qprop[j].queueFlags));
nuclear@0 72 printf(" num queues: %u\n", qprop[j].queueCount);
nuclear@0 73
nuclear@0 74 if(qprop[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
nuclear@0 75 sel_dev = i;
nuclear@0 76 sel_qfamily = j;
nuclear@0 77 }
nuclear@0 78 }
nuclear@0 79 free(qprop);
nuclear@0 80 }
nuclear@0 81
nuclear@0 82 if(sel_dev < 0 || sel_qfamily < 0) {
nuclear@0 83 fprintf(stderr, "failed to find any device with a graphics-capable command queue\n");
nuclear@0 84 vkDestroyDevice(vkdev, 0);
nuclear@0 85 return 1;
nuclear@0 86 }
nuclear@0 87
nuclear@1 88 // create device & command queue
nuclear@0 89 memset(&queue_info, 0, sizeof queue_info);
nuclear@0 90 queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
nuclear@0 91 queue_info.queueFamilyIndex = sel_qfamily;
nuclear@0 92 queue_info.queueCount = 1;
nuclear@0 93 queue_info.pQueuePriorities = &qprio;
nuclear@0 94
nuclear@0 95 memset(&dev_info, 0, sizeof dev_info);
nuclear@0 96 dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
nuclear@0 97 dev_info.queueCreateInfoCount = 1;
nuclear@0 98 dev_info.pQueueCreateInfos = &queue_info;
nuclear@0 99
nuclear@0 100 if(vkCreateDevice(devices[sel_dev], &dev_info, 0, &vkdev) != 0) {
nuclear@0 101 fprintf(stderr, "failed to create device %d\n", sel_dev);
nuclear@0 102 return 1;
nuclear@0 103 }
nuclear@0 104 printf("created device %d\n", sel_dev);
nuclear@0 105
nuclear@0 106 vkDestroyDevice(vkdev, 0);
nuclear@0 107 vkDestroyInstance(vk, 0);
nuclear@0 108 return 0;
nuclear@0 109 }
nuclear@0 110
nuclear@0 111
nuclear@0 112 const char *get_device_name(VkPhysicalDeviceType type)
nuclear@0 113 {
nuclear@0 114 switch(type) {
nuclear@0 115 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
nuclear@0 116 return "integrated GPU";
nuclear@0 117 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
nuclear@0 118 return "discrete GPU";
nuclear@0 119 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
nuclear@0 120 return "virtual GPU";
nuclear@0 121 case VK_PHYSICAL_DEVICE_TYPE_CPU:
nuclear@0 122 return "CPU";
nuclear@0 123 default:
nuclear@0 124 break;
nuclear@0 125 }
nuclear@0 126 return "unknown";
nuclear@0 127 }
nuclear@0 128
nuclear@0 129 const char *get_queue_flag_string(VkQueueFlagBits flags)
nuclear@0 130 {
nuclear@0 131 static char str[128];
nuclear@0 132
nuclear@0 133 str[0] = 0;
nuclear@0 134 if(flags & VK_QUEUE_GRAPHICS_BIT) {
nuclear@0 135 strcat(str, "graphics ");
nuclear@0 136 }
nuclear@0 137 if(flags & VK_QUEUE_COMPUTE_BIT) {
nuclear@0 138 strcat(str, "compute ");
nuclear@0 139 }
nuclear@0 140 if(flags & VK_QUEUE_TRANSFER_BIT) {
nuclear@0 141 strcat(str, "transfer ");
nuclear@0 142 }
nuclear@0 143 if(flags & VK_QUEUE_SPARSE_BINDING_BIT) {
nuclear@0 144 strcat(str, "sparse-binding ");
nuclear@0 145 }
nuclear@0 146 return str;
nuclear@0 147 }
nuclear@0 148
nuclear@0 149 int ver_major(uint32_t ver)
nuclear@0 150 {
nuclear@0 151 return (ver >> 22) & 0x3ff;
nuclear@0 152 }
nuclear@0 153
nuclear@0 154 int ver_minor(uint32_t ver)
nuclear@0 155 {
nuclear@0 156 return (ver >> 12) & 0x3ff;
nuclear@0 157 }
nuclear@0 158
nuclear@0 159 int ver_patch(uint32_t ver)
nuclear@0 160 {
nuclear@0 161 return ver & 0xfff;
nuclear@0 162 }