vulkan_test2
diff src/vku.c @ 3:68e1c437343f
more vulkan
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 22 Sep 2017 01:01:10 +0300 |
parents | |
children | c31c4115d44a |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/vku.c Fri Sep 22 01:01:10 2017 +0300 1.3 @@ -0,0 +1,281 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <string.h> 1.7 +#include <alloca.h> 1.8 +#include "vku.h" 1.9 + 1.10 +static const char *get_device_name(VkPhysicalDeviceType type); 1.11 +static const char *get_mem_prop_flag_string(VkMemoryPropertyFlags flags); 1.12 +static const char *get_queue_flag_string(VkQueueFlagBits flags); 1.13 +static int ver_major(uint32_t ver); 1.14 +static int ver_minor(uint32_t ver); 1.15 +static int ver_patch(uint32_t ver); 1.16 +static const char *mem_size_str(long sz); 1.17 + 1.18 + 1.19 +VkInstance vk; 1.20 +VkDevice vkdev; 1.21 +VkQueue vkq; 1.22 + 1.23 +int vku_create_dev(void) 1.24 +{ 1.25 + int i, j; 1.26 + VkInstanceCreateInfo inst_info; 1.27 + VkPhysicalDevice *devices; 1.28 + VkDeviceCreateInfo dev_info; 1.29 + VkDeviceQueueCreateInfo queue_info; 1.30 + VkCommandPoolCreateInfo cmdpool_info; 1.31 + uint32_t num_devices; 1.32 + int sel_dev = -1; 1.33 + int sel_qfamily = -1; 1.34 + float qprio = 0.0f; 1.35 + 1.36 + memset(&inst_info, 0, sizeof inst_info); 1.37 + inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; 1.38 + 1.39 + if(vkCreateInstance(&inst_info, 0, &vk) != 0) { 1.40 + fprintf(stderr, "failed to create vulkan instance\n"); 1.41 + return -1; 1.42 + } 1.43 + printf("created vulkan instance\n"); 1.44 + 1.45 + if(vkEnumeratePhysicalDevices(vk, &num_devices, 0) != 0) { 1.46 + fprintf(stderr, "failed to enumerate vulkan physical devices\n"); 1.47 + return -1; 1.48 + } 1.49 + devices = alloca(num_devices * sizeof *devices); 1.50 + if(vkEnumeratePhysicalDevices(vk, &num_devices, devices) != 0) { 1.51 + fprintf(stderr, "failed to enumerate vulkan physical devices\n"); 1.52 + return -1; 1.53 + } 1.54 + printf("found %u physical device(s)\n", (unsigned int)num_devices); 1.55 + 1.56 + for(i=0; i<(int)num_devices; i++) { 1.57 + VkPhysicalDeviceProperties dev_prop; 1.58 + VkPhysicalDeviceMemoryProperties mem_prop; 1.59 + VkQueueFamilyProperties *qprop; 1.60 + uint32_t qprop_count; 1.61 + 1.62 + vkGetPhysicalDeviceProperties(devices[i], &dev_prop); 1.63 + 1.64 + printf("Device %d: %s\n", i, dev_prop.deviceName); 1.65 + printf(" type: %s\n", get_device_name(dev_prop.deviceType)); 1.66 + printf(" API version: %d.%d.%d\n", ver_major(dev_prop.apiVersion), ver_minor(dev_prop.apiVersion), 1.67 + ver_patch(dev_prop.apiVersion)); 1.68 + printf(" driver version: %d.%d.%d\n", ver_major(dev_prop.driverVersion), ver_minor(dev_prop.driverVersion), 1.69 + ver_patch(dev_prop.driverVersion)); 1.70 + printf(" vendor id: %x device id: %x\n", dev_prop.vendorID, dev_prop.deviceID); 1.71 + 1.72 + 1.73 + vkGetPhysicalDeviceMemoryProperties(devices[i], &mem_prop); 1.74 + printf(" %d memory heaps:\n", mem_prop.memoryHeapCount); 1.75 + for(j=0; j<mem_prop.memoryHeapCount; j++) { 1.76 + VkMemoryHeap heap = mem_prop.memoryHeaps[j]; 1.77 + printf(" Heap %d - size: %s, flags: %s\n", j, mem_size_str(heap.size), 1.78 + heap.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT ? "device-local" : "-"); 1.79 + } 1.80 + printf(" %d memory types:\n", mem_prop.memoryTypeCount); 1.81 + for(j=0; j<mem_prop.memoryTypeCount; j++) { 1.82 + VkMemoryType type = mem_prop.memoryTypes[j]; 1.83 + printf(" Type %d - heap: %d, flags: %s\n", j, type.heapIndex, 1.84 + get_mem_prop_flag_string(type.propertyFlags)); 1.85 + } 1.86 + 1.87 + vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &qprop_count, 0); 1.88 + if(qprop_count <= 0) { 1.89 + continue; 1.90 + } 1.91 + qprop = malloc(qprop_count * sizeof *qprop); 1.92 + vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &qprop_count, qprop); 1.93 + 1.94 + for(j=0; j<qprop_count; j++) { 1.95 + printf(" Queue family %d:\n", j); 1.96 + printf(" flags: %s\n", get_queue_flag_string(qprop[j].queueFlags)); 1.97 + printf(" num queues: %u\n", qprop[j].queueCount); 1.98 + 1.99 + if(qprop[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) { 1.100 + sel_dev = i; 1.101 + sel_qfamily = j; 1.102 + } 1.103 + } 1.104 + free(qprop); 1.105 + } 1.106 + 1.107 + if(sel_dev < 0 || sel_qfamily < 0) { 1.108 + fprintf(stderr, "failed to find any device with a graphics-capable command queue\n"); 1.109 + vkDestroyDevice(vkdev, 0); 1.110 + return -1; 1.111 + } 1.112 + 1.113 + /* create device & command queue */ 1.114 + memset(&queue_info, 0, sizeof queue_info); 1.115 + queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 1.116 + queue_info.queueFamilyIndex = sel_qfamily; 1.117 + queue_info.queueCount = 1; 1.118 + queue_info.pQueuePriorities = &qprio; 1.119 + 1.120 + memset(&dev_info, 0, sizeof dev_info); 1.121 + dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 1.122 + dev_info.queueCreateInfoCount = 1; 1.123 + dev_info.pQueueCreateInfos = &queue_info; 1.124 + 1.125 + if(vkCreateDevice(devices[sel_dev], &dev_info, 0, &vkdev) != 0) { 1.126 + fprintf(stderr, "failed to create device %d\n", sel_dev); 1.127 + return -1; 1.128 + } 1.129 + printf("created device %d\n", sel_dev); 1.130 + 1.131 + vkGetDeviceQueue(vkdev, sel_qfamily, 0, &vkq); 1.132 + 1.133 + /* create command buffer pool */ 1.134 + memset(&cmdpool_info, 0, sizeof cmdpool_info); 1.135 + cmdpool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 1.136 + cmdpool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 1.137 + cmdpool_info.queueFamilyIndex = sel_qfamily; 1.138 + 1.139 + if(vkCreateCommandPool(vkdev, &cmdpool_info, 0, &vkcmdpool) != 0) { 1.140 + fprintf(stderr, "failed to get command quque!\n"); 1.141 + return -1; 1.142 + } 1.143 + 1.144 + return 0; 1.145 +} 1.146 + 1.147 +void vku_cleanup(void) 1.148 +{ 1.149 + if(vk) { 1.150 + vkDeviceWaitIdle(vkdev); 1.151 + vkDestroyDevice(vkdev, 0); 1.152 + vkDestroyInstance(vk, 0); 1.153 + vk = 0; 1.154 + } 1.155 +} 1.156 + 1.157 +struct vk_buffer *vku_create_buffer(int sz, unsigned int usage) 1.158 +{ 1.159 + struct vk_buffer *buf; 1.160 + VkBufferCreateInfo binfo; 1.161 + 1.162 + if(!(buf = malloc(sizeof *buf))) { 1.163 + perror("failed to allocate vk_buffer structure"); 1.164 + return 0; 1.165 + } 1.166 + 1.167 + memset(&binfo, 0, sizeof binfo); 1.168 + binfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 1.169 + binfo.size = sz; 1.170 + binfo.usage = usage; 1.171 + binfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 1.172 + 1.173 + if(vkCreateBuffer(vkdev, &binfo, 0, &buf->buf) != 0) { 1.174 + fprintf(stderr, "failed to create %d byte buffer (usage: %x)\n", sz, usage); 1.175 + return 0; 1.176 + } 1.177 + // TODO back with memory 1.178 + return buf; 1.179 +} 1.180 + 1.181 +void vku_destroy_buffer(struct vk_buffer *buf) 1.182 +{ 1.183 + if(buf) { 1.184 + vkDestroyBuffer(vkdev, buf->buf, 0); 1.185 + free(buf); 1.186 + } 1.187 +} 1.188 + 1.189 +static const char *get_device_name(VkPhysicalDeviceType type) 1.190 +{ 1.191 + switch(type) { 1.192 + case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: 1.193 + return "integrated GPU"; 1.194 + case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: 1.195 + return "discrete GPU"; 1.196 + case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: 1.197 + return "virtual GPU"; 1.198 + case VK_PHYSICAL_DEVICE_TYPE_CPU: 1.199 + return "CPU"; 1.200 + default: 1.201 + break; 1.202 + } 1.203 + return "unknown"; 1.204 +} 1.205 + 1.206 +static const char *get_mem_prop_flag_string(VkMemoryPropertyFlags flags) 1.207 +{ 1.208 + static char str[128]; 1.209 + 1.210 + str[0] = 0; 1.211 + if(flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) { 1.212 + strcat(str, "device-local "); 1.213 + } 1.214 + if(flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { 1.215 + strcat(str, "host-visible "); 1.216 + } 1.217 + if(flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) { 1.218 + strcat(str, "host-coherent "); 1.219 + } 1.220 + if(flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) { 1.221 + strcat(str, "host-cached "); 1.222 + } 1.223 + if(flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) { 1.224 + strcat(str, "lazily-allocated "); 1.225 + } 1.226 + 1.227 + if(!*str) { 1.228 + strcat(str, "-"); 1.229 + } 1.230 + return str; 1.231 +} 1.232 + 1.233 +static const char *get_queue_flag_string(VkQueueFlagBits flags) 1.234 +{ 1.235 + static char str[128]; 1.236 + 1.237 + str[0] = 0; 1.238 + if(flags & VK_QUEUE_GRAPHICS_BIT) { 1.239 + strcat(str, "graphics "); 1.240 + } 1.241 + if(flags & VK_QUEUE_COMPUTE_BIT) { 1.242 + strcat(str, "compute "); 1.243 + } 1.244 + if(flags & VK_QUEUE_TRANSFER_BIT) { 1.245 + strcat(str, "transfer "); 1.246 + } 1.247 + if(flags & VK_QUEUE_SPARSE_BINDING_BIT) { 1.248 + strcat(str, "sparse-binding "); 1.249 + } 1.250 + if(!*str) { 1.251 + strcat(str, "-"); 1.252 + } 1.253 + return str; 1.254 +} 1.255 + 1.256 +static int ver_major(uint32_t ver) 1.257 +{ 1.258 + return (ver >> 22) & 0x3ff; 1.259 +} 1.260 + 1.261 +static int ver_minor(uint32_t ver) 1.262 +{ 1.263 + return (ver >> 12) & 0x3ff; 1.264 +} 1.265 + 1.266 +static int ver_patch(uint32_t ver) 1.267 +{ 1.268 + return ver & 0xfff; 1.269 +} 1.270 + 1.271 +static const char *mem_size_str(long sz) 1.272 +{ 1.273 + static char str[64]; 1.274 + static const char *unitstr[] = { "bytes", "KB", "MB", "GB", "TB", "PB", 0 }; 1.275 + int uidx = 0; 1.276 + sz *= 10; 1.277 + 1.278 + while(sz >= 10240 && unitstr[uidx + 1]) { 1.279 + sz /= 1024; 1.280 + ++uidx; 1.281 + } 1.282 + sprintf(str, "%ld.%ld %s", sz / 10, sz % 10, unitstr[uidx]); 1.283 + return str; 1.284 +}