static VkInstance vk;
static VkPhysicalDevice vkpdev;
-static int vkqfam_idx = -1;
+static int vkqfam_idx, vkqfam_maxq;
static VkDevice vkdev;
static VkQueue vkq;
static VkSurfaceKHR vksurf;
{"VK_KHR_debug_report", 0}
};
+static struct {
+ const char *name;
+ int required;
+} known_devext_list[] = {
+ {"VK_KHR_swapchain", 1},
+ {"VK_KHR_acceleration_structure", 0},
+ {"VK_KHR_ray_tracing_pipeline", 0}
+};
+
static int create_instance(void)
{
int i, nlayers = 0, next = 0;
static int create_surface(void)
{
- int res;
-
/*
VkXlibSurfaceCreateInfoKHR xinf = {0};
xinf.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
xinf.connection = XGetXCBConnection(dpy);
xinf.window = (xcb_window_t)win;
- if((res = vkCreateXcbSurfaceKHR(vk, &xinf, 0, &vksurf)) != 0) {
- fprintf(stderr, "failed to create XCB window surface (%d)\n", res);
+ if(vkCreateXcbSurfaceKHR(vk, &xinf, 0, &vksurf) != 0) {
+ fprintf(stderr, "failed to create XCB window surface\n");
return -1;
}
return 0;
int choose_phys_dev(void)
{
- uint32_t i, num_pdev, score, best_score, best_dev;
+ uint32_t i, num_pdev, num_qfam, score, best_score, best_dev;
VkPhysicalDevice *pdev;
VkPhysicalDeviceProperties pdevprop;
+ VkQueueFamilyProperties *qfam;
vkEnumeratePhysicalDevices(vk, &num_pdev, 0);
if(!num_pdev) {
free(pdev);
return -1;
}
+ vkpdev = pdev[best_dev];
+
+ vkGetPhysicalDeviceQueueFamilyProperties(dev, &num_qfam, 0);
+ qfam = malloc_nf(num_qfam * sizeof *qfam);
+ vkGetPhysicalDeviceQueueFamilyProperties(dev, &num_qfam, qfam);
- vkpdev = pdev[i];
+ vkqfam_idx = -1;
+ for(i=0; i<num_qfam; i++) {
+ vkGetPhysicalDeviceSurfaceSupportKHR(dev, i, vksurf, &can_pres);
+ if(qfam[i].queueCount && (qfam[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) && can_pres) {
+ vkqfam_maxq = qfam[i].queueCount;
+ vkqfam_idx = i;
+ break;
+ }
+ }
+ free(qfam);
free(pdev);
choose_pixfmt();
return 0;
static int create_device(void)
{
+ float prio = 1.0f;
+ VkDeviceQueueCreateInfo qinf = {0};
+ VkPhysicalDeviceFeatures feat = {0};
+ VkDeviceCreateInfo devinf = {0};
+ const char *ext[ARRSZ(known_devext_list)];
+ int i, num_ext;
+
+ vkEnumerateDeviceExtensionProperties(vkpdev, 0, &dev_ext_count, 0);
+ dev_ext = malloc_nf(dev_ext_count * sizeof *dev_ext);
+ vkEnumerateDeviceExtensionProperties(vkpdev, 0, &dev_ext_count, dev_ext);
+
+ for(i=0; i<ARRSZ(known_devext_list); i++) {
+ if(have_ext(dev_ext, dev_ext_count, known_devext_list[i].name)) {
+ ext[num_ext++] = known_devext_list[i].name;
+ } else if(known_devext_list[i].required) {
+ fprintf(stderr, "Vulkan device lacks required extension: %s\n",
+ known_devext_list[i].name);
+ return -1;
+ }
+ }
+
+ qinf.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+ qinf.queueFamilyIndex = vkqfam_idx;
+ qinf.queueCount = 1;
+ qinf.pQueuePriorities = &prio;
+
+ devinf.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+ devinf.pQueueCreateInfos = &qinf;
+ devinf.queueCreateInfoCount = 1;
+ devinf.pEnabledFeatures = &feat;
+ devinf.enabledExtensionCount = num_ext;
+ devinf.ppEnabledExtensionNames = ext;
+
+ if(vkCreateDevice(vkpdev, &devinf, 0, &vkdev) != 0) {
+ fprintf(stderr, "failed to create vulkan device\n");
+ return -1;
+ }
+
+ vkGetDeviceQueue(vkdev, vkqfam_idx, 0, &vkq);
return 0;
}
+static int create_swapchain(void)
+{
+ uint32_t num;
+ VkSwapchainCreateInfoKHR scinf;
+
+ vksc_extent.width = win_width;
+ vksc_extent.height = win_height;
+
+ memset(&scinf, 0, sizeof scinf);
+ scinf.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+ scinf.surface = vksurf;
+ scinf.minImageCount = 2;
+ scinf.imageFormat = vksurf_fmt[vksurf_selfmt].format;
+ scinf.imageColorSpace = vksurf_fmt[vksurf_selfmt].colorSpace;
+ scinf.imageExtent = vksc_extent;
+ scinf.imageArrayLayers = 1;
+ scinf.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+ scinf.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ scinf.preTransform = vksurf_caps.currentTransform;
+ scinf.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+ scinf.presentMode = VK_PRESENT_MODE_FIFO_KHR;
+ scinf.clipped = VK_TRUE;
+
+ if(vkCreateSwapchainKHR(vkdev, &scinf, 0, &vksc) != 0) {
+ fprintf(stderr, "failed to create swapchain\n");
+ return -1;
+ }
+
+ vkGetSwapchainImagesKHR(vkdev, vksc, &num, 0);
+ vksc_img = malloc_nf(num * sizeof *vksc_img);
+ vkGetSwapchainImagesKHR(vkdev, vksc, &num, vksc_img);
+ vksc_numimg = num;
+
+ return 0;
+}
+
+
static int eval_pdev_score(VkPhysicalDevice dev)
{
uint32_t i, num_fmt, num_qfam, num_ext;
qfam = malloc_nf(num_qfam * sizeof *qfam);
vkGetPhysicalDeviceQueueFamilyProperties(dev, &num_qfam, qfam);
- vkqfam_idx = -1;
for(i=0; i<num_qfam; i++) {
vkGetPhysicalDeviceSurfaceSupportKHR(dev, i, vksurf, &can_pres);
if(qfam[i].queueCount && (qfam[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) && can_pres) {
- vkqfam_idx = i;
free(ext);
free(sfmt);
free(qfam);