vulkan_test2
diff src/vku.c @ 4:c31c4115d44a
test 2, open window, create queue, etc ...
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 22 Sep 2017 15:26:29 +0300 |
parents | 68e1c437343f |
children | cec4b0e7fce8 |
line diff
1.1 --- a/src/vku.c Fri Sep 22 01:01:10 2017 +0300 1.2 +++ b/src/vku.c Fri Sep 22 15:26:29 2017 +0300 1.3 @@ -1,7 +1,7 @@ 1.4 #include <stdio.h> 1.5 #include <stdlib.h> 1.6 #include <string.h> 1.7 -#include <alloca.h> 1.8 +#include <stdint.h> 1.9 #include "vku.h" 1.10 1.11 static const char *get_device_name(VkPhysicalDeviceType type); 1.12 @@ -12,26 +12,108 @@ 1.13 static int ver_patch(uint32_t ver); 1.14 static const char *mem_size_str(long sz); 1.15 1.16 - 1.17 VkInstance vk; 1.18 VkDevice vkdev; 1.19 VkQueue vkq; 1.20 1.21 +static VkPhysicalDevice *phys_devices; 1.22 +static int sel_dev, sel_qfamily; 1.23 + 1.24 +static VkExtensionProperties *vkext, *vkdevext; 1.25 +static uint32_t vkext_count, vkdevext_count; 1.26 + 1.27 + 1.28 +int vku_have_extension(const char *name) 1.29 +{ 1.30 + int i; 1.31 + 1.32 + if(!vkext) { 1.33 + vkext_count = 0; 1.34 + vkEnumerateInstanceExtensionProperties(0, &vkext_count, 0); 1.35 + if(vkext_count) { 1.36 + if(!(vkext = malloc(vkext_count * sizeof *vkext))) { 1.37 + perror("failed to allocate instance extension list"); 1.38 + return 0; 1.39 + } 1.40 + vkEnumerateInstanceExtensionProperties(0, &vkext_count, vkext); 1.41 + 1.42 + printf("instance extensions:\n"); 1.43 + for(i=0; i<(int)vkext_count; i++) { 1.44 + printf(" %s (ver: %u)\n", vkext[i].extensionName, (unsigned int)vkext[i].specVersion); 1.45 + } 1.46 + } 1.47 + } 1.48 + 1.49 + for(i=0; i<(int)vkext_count; i++) { 1.50 + if(strcmp(vkext[i].extensionName, name) == 0) { 1.51 + return 1; 1.52 + } 1.53 + } 1.54 + return 0; 1.55 +} 1.56 + 1.57 +int vku_have_device_extension(const char *name) 1.58 +{ 1.59 + int i; 1.60 + 1.61 + if(sel_dev < 0) return 0; 1.62 + 1.63 + if(!vkdevext) { 1.64 + vkdevext_count = 0; 1.65 + vkEnumerateDeviceExtensionProperties(phys_devices[sel_dev], 0, &vkdevext_count, 0); 1.66 + if(vkdevext_count) { 1.67 + if(!(vkdevext = malloc(vkdevext_count * sizeof *vkdevext))) { 1.68 + perror("failed to allocate device extension list"); 1.69 + return 0; 1.70 + } 1.71 + vkEnumerateDeviceExtensionProperties(phys_devices[sel_dev], 0, &vkdevext_count, vkdevext); 1.72 + 1.73 + printf("selected device extensions:\n"); 1.74 + for(i=0; i<(int)vkdevext_count; i++) { 1.75 + printf(" %s (ver: %u)\n", vkdevext[i].extensionName, (unsigned int)vkdevext[i].specVersion); 1.76 + } 1.77 + } 1.78 + } 1.79 + 1.80 + for(i=0; i<(int)vkdevext_count; i++) { 1.81 + if(strcmp(vkdevext[i].extensionName, name) == 0) { 1.82 + return 1; 1.83 + } 1.84 + } 1.85 + return 0; 1.86 +} 1.87 + 1.88 int vku_create_dev(void) 1.89 { 1.90 int i, j; 1.91 VkInstanceCreateInfo inst_info; 1.92 - VkPhysicalDevice *devices; 1.93 VkDeviceCreateInfo dev_info; 1.94 VkDeviceQueueCreateInfo queue_info; 1.95 VkCommandPoolCreateInfo cmdpool_info; 1.96 uint32_t num_devices; 1.97 - int sel_dev = -1; 1.98 - int sel_qfamily = -1; 1.99 float qprio = 0.0f; 1.100 1.101 + static const char *ext_names[] = { 1.102 +#ifdef VK_USE_PLATFORM_XLIB_KHR 1.103 + "VK_KHR_xlib_surface", 1.104 +#endif 1.105 + "VK_KHR_surface" 1.106 + }; 1.107 + 1.108 + sel_dev = -1; 1.109 + sel_qfamily = -1; 1.110 + 1.111 + for(i=0; i<sizeof ext_names / sizeof *ext_names; i++) { 1.112 + if(!vku_have_extension(ext_names[i])) { 1.113 + fprintf(stderr, "required extension (%s) not found\n", ext_names[i]); 1.114 + return -1; 1.115 + } 1.116 + } 1.117 + 1.118 memset(&inst_info, 0, sizeof inst_info); 1.119 inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; 1.120 + inst_info.ppEnabledExtensionNames = ext_names; 1.121 + inst_info.enabledExtensionCount = sizeof ext_names / sizeof *ext_names; 1.122 1.123 if(vkCreateInstance(&inst_info, 0, &vk) != 0) { 1.124 fprintf(stderr, "failed to create vulkan instance\n"); 1.125 @@ -43,8 +125,8 @@ 1.126 fprintf(stderr, "failed to enumerate vulkan physical devices\n"); 1.127 return -1; 1.128 } 1.129 - devices = alloca(num_devices * sizeof *devices); 1.130 - if(vkEnumeratePhysicalDevices(vk, &num_devices, devices) != 0) { 1.131 + phys_devices = malloc(num_devices * sizeof *phys_devices); 1.132 + if(vkEnumeratePhysicalDevices(vk, &num_devices, phys_devices) != 0) { 1.133 fprintf(stderr, "failed to enumerate vulkan physical devices\n"); 1.134 return -1; 1.135 } 1.136 @@ -56,7 +138,7 @@ 1.137 VkQueueFamilyProperties *qprop; 1.138 uint32_t qprop_count; 1.139 1.140 - vkGetPhysicalDeviceProperties(devices[i], &dev_prop); 1.141 + vkGetPhysicalDeviceProperties(phys_devices[i], &dev_prop); 1.142 1.143 printf("Device %d: %s\n", i, dev_prop.deviceName); 1.144 printf(" type: %s\n", get_device_name(dev_prop.deviceType)); 1.145 @@ -67,7 +149,7 @@ 1.146 printf(" vendor id: %x device id: %x\n", dev_prop.vendorID, dev_prop.deviceID); 1.147 1.148 1.149 - vkGetPhysicalDeviceMemoryProperties(devices[i], &mem_prop); 1.150 + vkGetPhysicalDeviceMemoryProperties(phys_devices[i], &mem_prop); 1.151 printf(" %d memory heaps:\n", mem_prop.memoryHeapCount); 1.152 for(j=0; j<mem_prop.memoryHeapCount; j++) { 1.153 VkMemoryHeap heap = mem_prop.memoryHeaps[j]; 1.154 @@ -81,12 +163,12 @@ 1.155 get_mem_prop_flag_string(type.propertyFlags)); 1.156 } 1.157 1.158 - vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &qprop_count, 0); 1.159 + vkGetPhysicalDeviceQueueFamilyProperties(phys_devices[i], &qprop_count, 0); 1.160 if(qprop_count <= 0) { 1.161 continue; 1.162 } 1.163 qprop = malloc(qprop_count * sizeof *qprop); 1.164 - vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &qprop_count, qprop); 1.165 + vkGetPhysicalDeviceQueueFamilyProperties(phys_devices[i], &qprop_count, qprop); 1.166 1.167 for(j=0; j<qprop_count; j++) { 1.168 printf(" Queue family %d:\n", j); 1.169 @@ -119,7 +201,7 @@ 1.170 dev_info.queueCreateInfoCount = 1; 1.171 dev_info.pQueueCreateInfos = &queue_info; 1.172 1.173 - if(vkCreateDevice(devices[sel_dev], &dev_info, 0, &vkdev) != 0) { 1.174 + if(vkCreateDevice(phys_devices[sel_dev], &dev_info, 0, &vkdev) != 0) { 1.175 fprintf(stderr, "failed to create device %d\n", sel_dev); 1.176 return -1; 1.177 } 1.178 @@ -138,6 +220,11 @@ 1.179 return -1; 1.180 } 1.181 1.182 + if(!(vkcmdbuf = vku_alloc_cmdbuf(vkcmdpool, VK_COMMAND_BUFFER_LEVEL_PRIMARY))) { 1.183 + fprintf(stderr, "failed to create primary command buffer\n"); 1.184 + return -1; 1.185 + } 1.186 + 1.187 return 0; 1.188 } 1.189 1.190 @@ -145,15 +232,75 @@ 1.191 { 1.192 if(vk) { 1.193 vkDeviceWaitIdle(vkdev); 1.194 + vkDestroyCommandPool(vkdev, vkcmdpool, 0); 1.195 vkDestroyDevice(vkdev, 0); 1.196 vkDestroyInstance(vk, 0); 1.197 vk = 0; 1.198 } 1.199 + 1.200 + free(phys_devices); 1.201 + phys_devices = 0; 1.202 } 1.203 1.204 -struct vk_buffer *vku_create_buffer(int sz, unsigned int usage) 1.205 +VkCommandBuffer vku_alloc_cmdbuf(VkCommandPool pool, VkCommandBufferLevel level) 1.206 { 1.207 - struct vk_buffer *buf; 1.208 + VkCommandBuffer cmdbuf; 1.209 + VkCommandBufferAllocateInfo inf; 1.210 + 1.211 + memset(&inf, 0, sizeof inf); 1.212 + inf.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 1.213 + inf.commandPool = pool; 1.214 + inf.level = level; 1.215 + inf.commandBufferCount = 1; 1.216 + 1.217 + if(vkAllocateCommandBuffers(vkdev, &inf, &cmdbuf) != 0) { 1.218 + return 0; 1.219 + } 1.220 + return cmdbuf; 1.221 +} 1.222 + 1.223 +void vku_free_cmdbuf(VkCommandPool pool, VkCommandBuffer buf) 1.224 +{ 1.225 + vkFreeCommandBuffers(vkdev, pool, 1, &buf); 1.226 +} 1.227 + 1.228 +void vku_begin_cmdbuf(VkCommandBuffer buf, unsigned int flags) 1.229 +{ 1.230 + VkCommandBufferBeginInfo inf; 1.231 + 1.232 + memset(&inf, 0, sizeof inf); 1.233 + inf.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 1.234 + inf.flags = flags; 1.235 + 1.236 + vkBeginCommandBuffer(buf, &inf); 1.237 +} 1.238 + 1.239 + 1.240 +void vku_end_cmdbuf(VkCommandBuffer buf) 1.241 +{ 1.242 + vkEndCommandBuffer(buf); 1.243 +} 1.244 + 1.245 +void vku_reset_cmdbuf(VkCommandBuffer buf) 1.246 +{ 1.247 + vkResetCommandBuffer(buf, 0); 1.248 +} 1.249 + 1.250 +void vku_submit_cmdbuf(VkQueue q, VkCommandBuffer buf, VkFence done_fence) 1.251 +{ 1.252 + VkSubmitInfo info; 1.253 + 1.254 + memset(&info, 0, sizeof info); 1.255 + info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 1.256 + info.commandBufferCount = 1; 1.257 + info.pCommandBuffers = &buf; 1.258 + 1.259 + vkQueueSubmit(q, 1, &info, done_fence); 1.260 +} 1.261 + 1.262 +struct vku_buffer *vku_create_buffer(int sz, unsigned int usage) 1.263 +{ 1.264 + struct vku_buffer *buf; 1.265 VkBufferCreateInfo binfo; 1.266 1.267 if(!(buf = malloc(sizeof *buf))) { 1.268 @@ -175,7 +322,7 @@ 1.269 return buf; 1.270 } 1.271 1.272 -void vku_destroy_buffer(struct vk_buffer *buf) 1.273 +void vku_destroy_buffer(struct vku_buffer *buf) 1.274 { 1.275 if(buf) { 1.276 vkDestroyBuffer(vkdev, buf->buf, 0); 1.277 @@ -183,6 +330,25 @@ 1.278 } 1.279 } 1.280 1.281 +void vku_cmd_copybuf(VkCommandBuffer cmdbuf, VkBuffer dest, int doffs, 1.282 + VkBuffer src, int soffs, int size) 1.283 +{ 1.284 + VkBufferCopy copy; 1.285 + copy.size = size; 1.286 + copy.srcOffset = soffs; 1.287 + copy.dstOffset = doffs; 1.288 + 1.289 + vkCmdCopyBuffer(cmdbuf, src, dest, 1, ©); 1.290 +} 1.291 + 1.292 +#ifdef VK_USE_PLATFORM_XLIB_KHR 1.293 +int vku_xlib_usable_visual(Display *dpy, VisualID vid) 1.294 +{ 1.295 + return vkGetPhysicalDeviceXlibPresentationSupportKHR(phys_devices[sel_dev], 1.296 + sel_qfamily, dpy, vid); 1.297 +} 1.298 +#endif /* VK_USE_PLATFORM_XLIB_KHR */ 1.299 + 1.300 static const char *get_device_name(VkPhysicalDeviceType type) 1.301 { 1.302 switch(type) {