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, &copy);
   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) {