nuclear@3: #include nuclear@3: #include nuclear@3: #include nuclear@3: #include nuclear@3: #include "vku.h" nuclear@3: nuclear@3: static const char *get_device_name(VkPhysicalDeviceType type); nuclear@3: static const char *get_mem_prop_flag_string(VkMemoryPropertyFlags flags); nuclear@3: static const char *get_queue_flag_string(VkQueueFlagBits flags); nuclear@3: static int ver_major(uint32_t ver); nuclear@3: static int ver_minor(uint32_t ver); nuclear@3: static int ver_patch(uint32_t ver); nuclear@3: static const char *mem_size_str(long sz); nuclear@3: nuclear@3: nuclear@3: VkInstance vk; nuclear@3: VkDevice vkdev; nuclear@3: VkQueue vkq; nuclear@3: nuclear@3: int vku_create_dev(void) nuclear@3: { nuclear@3: int i, j; nuclear@3: VkInstanceCreateInfo inst_info; nuclear@3: VkPhysicalDevice *devices; nuclear@3: VkDeviceCreateInfo dev_info; nuclear@3: VkDeviceQueueCreateInfo queue_info; nuclear@3: VkCommandPoolCreateInfo cmdpool_info; nuclear@3: uint32_t num_devices; nuclear@3: int sel_dev = -1; nuclear@3: int sel_qfamily = -1; nuclear@3: float qprio = 0.0f; nuclear@3: nuclear@3: memset(&inst_info, 0, sizeof inst_info); nuclear@3: inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; nuclear@3: nuclear@3: if(vkCreateInstance(&inst_info, 0, &vk) != 0) { nuclear@3: fprintf(stderr, "failed to create vulkan instance\n"); nuclear@3: return -1; nuclear@3: } nuclear@3: printf("created vulkan instance\n"); nuclear@3: nuclear@3: if(vkEnumeratePhysicalDevices(vk, &num_devices, 0) != 0) { nuclear@3: fprintf(stderr, "failed to enumerate vulkan physical devices\n"); nuclear@3: return -1; nuclear@3: } nuclear@3: devices = alloca(num_devices * sizeof *devices); nuclear@3: if(vkEnumeratePhysicalDevices(vk, &num_devices, devices) != 0) { nuclear@3: fprintf(stderr, "failed to enumerate vulkan physical devices\n"); nuclear@3: return -1; nuclear@3: } nuclear@3: printf("found %u physical device(s)\n", (unsigned int)num_devices); nuclear@3: nuclear@3: for(i=0; i<(int)num_devices; i++) { nuclear@3: VkPhysicalDeviceProperties dev_prop; nuclear@3: VkPhysicalDeviceMemoryProperties mem_prop; nuclear@3: VkQueueFamilyProperties *qprop; nuclear@3: uint32_t qprop_count; nuclear@3: nuclear@3: vkGetPhysicalDeviceProperties(devices[i], &dev_prop); nuclear@3: nuclear@3: printf("Device %d: %s\n", i, dev_prop.deviceName); nuclear@3: printf(" type: %s\n", get_device_name(dev_prop.deviceType)); nuclear@3: printf(" API version: %d.%d.%d\n", ver_major(dev_prop.apiVersion), ver_minor(dev_prop.apiVersion), nuclear@3: ver_patch(dev_prop.apiVersion)); nuclear@3: printf(" driver version: %d.%d.%d\n", ver_major(dev_prop.driverVersion), ver_minor(dev_prop.driverVersion), nuclear@3: ver_patch(dev_prop.driverVersion)); nuclear@3: printf(" vendor id: %x device id: %x\n", dev_prop.vendorID, dev_prop.deviceID); nuclear@3: nuclear@3: nuclear@3: vkGetPhysicalDeviceMemoryProperties(devices[i], &mem_prop); nuclear@3: printf(" %d memory heaps:\n", mem_prop.memoryHeapCount); nuclear@3: for(j=0; jbuf) != 0) { nuclear@3: fprintf(stderr, "failed to create %d byte buffer (usage: %x)\n", sz, usage); nuclear@3: return 0; nuclear@3: } nuclear@3: // TODO back with memory nuclear@3: return buf; nuclear@3: } nuclear@3: nuclear@3: void vku_destroy_buffer(struct vk_buffer *buf) nuclear@3: { nuclear@3: if(buf) { nuclear@3: vkDestroyBuffer(vkdev, buf->buf, 0); nuclear@3: free(buf); nuclear@3: } nuclear@3: } nuclear@3: nuclear@3: static const char *get_device_name(VkPhysicalDeviceType type) nuclear@3: { nuclear@3: switch(type) { nuclear@3: case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: nuclear@3: return "integrated GPU"; nuclear@3: case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: nuclear@3: return "discrete GPU"; nuclear@3: case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: nuclear@3: return "virtual GPU"; nuclear@3: case VK_PHYSICAL_DEVICE_TYPE_CPU: nuclear@3: return "CPU"; nuclear@3: default: nuclear@3: break; nuclear@3: } nuclear@3: return "unknown"; nuclear@3: } nuclear@3: nuclear@3: static const char *get_mem_prop_flag_string(VkMemoryPropertyFlags flags) nuclear@3: { nuclear@3: static char str[128]; nuclear@3: nuclear@3: str[0] = 0; nuclear@3: if(flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) { nuclear@3: strcat(str, "device-local "); nuclear@3: } nuclear@3: if(flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { nuclear@3: strcat(str, "host-visible "); nuclear@3: } nuclear@3: if(flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) { nuclear@3: strcat(str, "host-coherent "); nuclear@3: } nuclear@3: if(flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) { nuclear@3: strcat(str, "host-cached "); nuclear@3: } nuclear@3: if(flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) { nuclear@3: strcat(str, "lazily-allocated "); nuclear@3: } nuclear@3: nuclear@3: if(!*str) { nuclear@3: strcat(str, "-"); nuclear@3: } nuclear@3: return str; nuclear@3: } nuclear@3: nuclear@3: static const char *get_queue_flag_string(VkQueueFlagBits flags) nuclear@3: { nuclear@3: static char str[128]; nuclear@3: nuclear@3: str[0] = 0; nuclear@3: if(flags & VK_QUEUE_GRAPHICS_BIT) { nuclear@3: strcat(str, "graphics "); nuclear@3: } nuclear@3: if(flags & VK_QUEUE_COMPUTE_BIT) { nuclear@3: strcat(str, "compute "); nuclear@3: } nuclear@3: if(flags & VK_QUEUE_TRANSFER_BIT) { nuclear@3: strcat(str, "transfer "); nuclear@3: } nuclear@3: if(flags & VK_QUEUE_SPARSE_BINDING_BIT) { nuclear@3: strcat(str, "sparse-binding "); nuclear@3: } nuclear@3: if(!*str) { nuclear@3: strcat(str, "-"); nuclear@3: } nuclear@3: return str; nuclear@3: } nuclear@3: nuclear@3: static int ver_major(uint32_t ver) nuclear@3: { nuclear@3: return (ver >> 22) & 0x3ff; nuclear@3: } nuclear@3: nuclear@3: static int ver_minor(uint32_t ver) nuclear@3: { nuclear@3: return (ver >> 12) & 0x3ff; nuclear@3: } nuclear@3: nuclear@3: static int ver_patch(uint32_t ver) nuclear@3: { nuclear@3: return ver & 0xfff; nuclear@3: } nuclear@3: nuclear@3: static const char *mem_size_str(long sz) nuclear@3: { nuclear@3: static char str[64]; nuclear@3: static const char *unitstr[] = { "bytes", "KB", "MB", "GB", "TB", "PB", 0 }; nuclear@3: int uidx = 0; nuclear@3: sz *= 10; nuclear@3: nuclear@3: while(sz >= 10240 && unitstr[uidx + 1]) { nuclear@3: sz /= 1024; nuclear@3: ++uidx; nuclear@3: } nuclear@3: sprintf(str, "%ld.%ld %s", sz / 10, sz % 10, unitstr[uidx]); nuclear@3: return str; nuclear@3: }