vulkan_test2

view 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 source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <alloca.h>
5 #include "vku.h"
7 static const char *get_device_name(VkPhysicalDeviceType type);
8 static const char *get_mem_prop_flag_string(VkMemoryPropertyFlags flags);
9 static const char *get_queue_flag_string(VkQueueFlagBits flags);
10 static int ver_major(uint32_t ver);
11 static int ver_minor(uint32_t ver);
12 static int ver_patch(uint32_t ver);
13 static const char *mem_size_str(long sz);
16 VkInstance vk;
17 VkDevice vkdev;
18 VkQueue vkq;
20 int vku_create_dev(void)
21 {
22 int i, j;
23 VkInstanceCreateInfo inst_info;
24 VkPhysicalDevice *devices;
25 VkDeviceCreateInfo dev_info;
26 VkDeviceQueueCreateInfo queue_info;
27 VkCommandPoolCreateInfo cmdpool_info;
28 uint32_t num_devices;
29 int sel_dev = -1;
30 int sel_qfamily = -1;
31 float qprio = 0.0f;
33 memset(&inst_info, 0, sizeof inst_info);
34 inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
36 if(vkCreateInstance(&inst_info, 0, &vk) != 0) {
37 fprintf(stderr, "failed to create vulkan instance\n");
38 return -1;
39 }
40 printf("created vulkan instance\n");
42 if(vkEnumeratePhysicalDevices(vk, &num_devices, 0) != 0) {
43 fprintf(stderr, "failed to enumerate vulkan physical devices\n");
44 return -1;
45 }
46 devices = alloca(num_devices * sizeof *devices);
47 if(vkEnumeratePhysicalDevices(vk, &num_devices, devices) != 0) {
48 fprintf(stderr, "failed to enumerate vulkan physical devices\n");
49 return -1;
50 }
51 printf("found %u physical device(s)\n", (unsigned int)num_devices);
53 for(i=0; i<(int)num_devices; i++) {
54 VkPhysicalDeviceProperties dev_prop;
55 VkPhysicalDeviceMemoryProperties mem_prop;
56 VkQueueFamilyProperties *qprop;
57 uint32_t qprop_count;
59 vkGetPhysicalDeviceProperties(devices[i], &dev_prop);
61 printf("Device %d: %s\n", i, dev_prop.deviceName);
62 printf(" type: %s\n", get_device_name(dev_prop.deviceType));
63 printf(" API version: %d.%d.%d\n", ver_major(dev_prop.apiVersion), ver_minor(dev_prop.apiVersion),
64 ver_patch(dev_prop.apiVersion));
65 printf(" driver version: %d.%d.%d\n", ver_major(dev_prop.driverVersion), ver_minor(dev_prop.driverVersion),
66 ver_patch(dev_prop.driverVersion));
67 printf(" vendor id: %x device id: %x\n", dev_prop.vendorID, dev_prop.deviceID);
70 vkGetPhysicalDeviceMemoryProperties(devices[i], &mem_prop);
71 printf(" %d memory heaps:\n", mem_prop.memoryHeapCount);
72 for(j=0; j<mem_prop.memoryHeapCount; j++) {
73 VkMemoryHeap heap = mem_prop.memoryHeaps[j];
74 printf(" Heap %d - size: %s, flags: %s\n", j, mem_size_str(heap.size),
75 heap.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT ? "device-local" : "-");
76 }
77 printf(" %d memory types:\n", mem_prop.memoryTypeCount);
78 for(j=0; j<mem_prop.memoryTypeCount; j++) {
79 VkMemoryType type = mem_prop.memoryTypes[j];
80 printf(" Type %d - heap: %d, flags: %s\n", j, type.heapIndex,
81 get_mem_prop_flag_string(type.propertyFlags));
82 }
84 vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &qprop_count, 0);
85 if(qprop_count <= 0) {
86 continue;
87 }
88 qprop = malloc(qprop_count * sizeof *qprop);
89 vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &qprop_count, qprop);
91 for(j=0; j<qprop_count; j++) {
92 printf(" Queue family %d:\n", j);
93 printf(" flags: %s\n", get_queue_flag_string(qprop[j].queueFlags));
94 printf(" num queues: %u\n", qprop[j].queueCount);
96 if(qprop[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
97 sel_dev = i;
98 sel_qfamily = j;
99 }
100 }
101 free(qprop);
102 }
104 if(sel_dev < 0 || sel_qfamily < 0) {
105 fprintf(stderr, "failed to find any device with a graphics-capable command queue\n");
106 vkDestroyDevice(vkdev, 0);
107 return -1;
108 }
110 /* create device & command queue */
111 memset(&queue_info, 0, sizeof queue_info);
112 queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
113 queue_info.queueFamilyIndex = sel_qfamily;
114 queue_info.queueCount = 1;
115 queue_info.pQueuePriorities = &qprio;
117 memset(&dev_info, 0, sizeof dev_info);
118 dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
119 dev_info.queueCreateInfoCount = 1;
120 dev_info.pQueueCreateInfos = &queue_info;
122 if(vkCreateDevice(devices[sel_dev], &dev_info, 0, &vkdev) != 0) {
123 fprintf(stderr, "failed to create device %d\n", sel_dev);
124 return -1;
125 }
126 printf("created device %d\n", sel_dev);
128 vkGetDeviceQueue(vkdev, sel_qfamily, 0, &vkq);
130 /* create command buffer pool */
131 memset(&cmdpool_info, 0, sizeof cmdpool_info);
132 cmdpool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
133 cmdpool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
134 cmdpool_info.queueFamilyIndex = sel_qfamily;
136 if(vkCreateCommandPool(vkdev, &cmdpool_info, 0, &vkcmdpool) != 0) {
137 fprintf(stderr, "failed to get command quque!\n");
138 return -1;
139 }
141 return 0;
142 }
144 void vku_cleanup(void)
145 {
146 if(vk) {
147 vkDeviceWaitIdle(vkdev);
148 vkDestroyDevice(vkdev, 0);
149 vkDestroyInstance(vk, 0);
150 vk = 0;
151 }
152 }
154 struct vk_buffer *vku_create_buffer(int sz, unsigned int usage)
155 {
156 struct vk_buffer *buf;
157 VkBufferCreateInfo binfo;
159 if(!(buf = malloc(sizeof *buf))) {
160 perror("failed to allocate vk_buffer structure");
161 return 0;
162 }
164 memset(&binfo, 0, sizeof binfo);
165 binfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
166 binfo.size = sz;
167 binfo.usage = usage;
168 binfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
170 if(vkCreateBuffer(vkdev, &binfo, 0, &buf->buf) != 0) {
171 fprintf(stderr, "failed to create %d byte buffer (usage: %x)\n", sz, usage);
172 return 0;
173 }
174 // TODO back with memory
175 return buf;
176 }
178 void vku_destroy_buffer(struct vk_buffer *buf)
179 {
180 if(buf) {
181 vkDestroyBuffer(vkdev, buf->buf, 0);
182 free(buf);
183 }
184 }
186 static const char *get_device_name(VkPhysicalDeviceType type)
187 {
188 switch(type) {
189 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
190 return "integrated GPU";
191 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
192 return "discrete GPU";
193 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
194 return "virtual GPU";
195 case VK_PHYSICAL_DEVICE_TYPE_CPU:
196 return "CPU";
197 default:
198 break;
199 }
200 return "unknown";
201 }
203 static const char *get_mem_prop_flag_string(VkMemoryPropertyFlags flags)
204 {
205 static char str[128];
207 str[0] = 0;
208 if(flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
209 strcat(str, "device-local ");
210 }
211 if(flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
212 strcat(str, "host-visible ");
213 }
214 if(flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
215 strcat(str, "host-coherent ");
216 }
217 if(flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) {
218 strcat(str, "host-cached ");
219 }
220 if(flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) {
221 strcat(str, "lazily-allocated ");
222 }
224 if(!*str) {
225 strcat(str, "-");
226 }
227 return str;
228 }
230 static const char *get_queue_flag_string(VkQueueFlagBits flags)
231 {
232 static char str[128];
234 str[0] = 0;
235 if(flags & VK_QUEUE_GRAPHICS_BIT) {
236 strcat(str, "graphics ");
237 }
238 if(flags & VK_QUEUE_COMPUTE_BIT) {
239 strcat(str, "compute ");
240 }
241 if(flags & VK_QUEUE_TRANSFER_BIT) {
242 strcat(str, "transfer ");
243 }
244 if(flags & VK_QUEUE_SPARSE_BINDING_BIT) {
245 strcat(str, "sparse-binding ");
246 }
247 if(!*str) {
248 strcat(str, "-");
249 }
250 return str;
251 }
253 static int ver_major(uint32_t ver)
254 {
255 return (ver >> 22) & 0x3ff;
256 }
258 static int ver_minor(uint32_t ver)
259 {
260 return (ver >> 12) & 0x3ff;
261 }
263 static int ver_patch(uint32_t ver)
264 {
265 return ver & 0xfff;
266 }
268 static const char *mem_size_str(long sz)
269 {
270 static char str[64];
271 static const char *unitstr[] = { "bytes", "KB", "MB", "GB", "TB", "PB", 0 };
272 int uidx = 0;
273 sz *= 10;
275 while(sz >= 10240 && unitstr[uidx + 1]) {
276 sz /= 1024;
277 ++uidx;
278 }
279 sprintf(str, "%ld.%ld %s", sz / 10, sz % 10, unitstr[uidx]);
280 return str;
281 }