diff options
-rw-r--r-- | render/vulkan/device.c | 190 | ||||
-rw-r--r-- | render/vulkan/device.h | 15 | ||||
-rw-r--r-- | render/vulkan/swapchain.c | 11 |
3 files changed, 105 insertions, 111 deletions
diff --git a/render/vulkan/device.c b/render/vulkan/device.c index a123983..1254f76 100644 --- a/render/vulkan/device.c +++ b/render/vulkan/device.c @@ -3,12 +3,10 @@ #include <rune/core/alloc.h> #include <rune/core/logging.h> -struct vkqfam_data { - uint32_t gfx; - uint32_t present; - uint32_t compute; - uint32_t transfer; -}; +static int gfx_qfam = -1; +static int tsfr_qfam = -1; +static int comp_qfam = -1; +static int pres_qfam = -1; struct vkdev_data { VkPhysicalDeviceProperties pdev_props; @@ -18,26 +16,52 @@ struct vkdev_data { const char** pdev_extensions; }; -int _query_qfam_data(VkSurfaceKHR surface, VkPhysicalDevice pdev, VkQueueFamilyProperties **qfam_props) { - uint32_t qfam_count = 0; - vkGetPhysicalDeviceQueueFamilyProperties(pdev, &qfam_count, NULL); - *qfam_props = rune_alloc(sizeof(VkQueueFamilyProperties) * qfam_count); - vkGetPhysicalDeviceQueueFamilyProperties(pdev, &qfam_count, *qfam_props); - return qfam_count; -} - void _query_pdev_data(VkPhysicalDevice pdev, struct vkdev_data *pdata) { vkGetPhysicalDeviceProperties(pdev, &pdata->pdev_props); vkGetPhysicalDeviceFeatures(pdev, &pdata->pdev_feats); vkGetPhysicalDeviceMemoryProperties(pdev, &pdata->pdev_mprops); } -int _get_qfam_index(int num_props, uint32_t queue_type, VkQueueFamilyProperties *qfam_props) { +uint32_t _query_qfam_data(VkSurfaceKHR surface, VkPhysicalDevice pdev, VkQueueFamilyProperties** qfam_props) { + uint32_t count; + vkGetPhysicalDeviceQueueFamilyProperties(pdev, &count, NULL); + *qfam_props = rune_alloc(sizeof(VkQueueFamilyProperties) * count); + vkGetPhysicalDeviceQueueFamilyProperties(pdev, &count, *qfam_props); + return count; +} + +int _query_gfx_index(int num_props, VkQueueFamilyProperties *qfam_props) { for (int i = 0; i < num_props; i++) { - if (qfam_props[i].queueFlags & queue_type) - return i; + if (qfam_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) + gfx_qfam = i; } - return -1; + return gfx_qfam; +} + +int _query_tsfr_index(int num_props, VkQueueFamilyProperties *qfam_props) { + for (int i = 0; i < num_props; i++) { + if (qfam_props[i].queueFlags & VK_QUEUE_TRANSFER_BIT) + tsfr_qfam = i; + } + return tsfr_qfam; +} + +int _query_comp_index(int num_props, VkQueueFamilyProperties *qfam_props) { + for (int i = 0; i < num_props; i++) { + if (qfam_props[i].queueFlags & VK_QUEUE_COMPUTE_BIT) + comp_qfam = i; + } + return comp_qfam; +} + +int _query_pres_index(int num_props, VkQueueFamilyProperties *qfam_props, VkPhysicalDevice pdev, VkSurfaceKHR surface) { + VkBool32 present_bit; + for (int i = 0; i < num_props; i++) { + vkGetPhysicalDeviceSurfaceSupportKHR(pdev, 0, surface, &present_bit); + if (present_bit != VK_FALSE) + pres_qfam = i; + } + return pres_qfam; } int _check_pdev(VkSurfaceKHR surface, VkPhysicalDevice pdev) { @@ -49,90 +73,78 @@ int _check_pdev(VkSurfaceKHR surface, VkPhysicalDevice pdev) { return score; VkQueueFamilyProperties *qfam_props; - int num_qfams = _query_qfam_data(surface, pdev, &qfam_props); - if (_get_qfam_index(num_qfams, VK_QUEUE_GRAPHICS_BIT, qfam_props) != -1) + uint32_t num_qfams = _query_qfam_data(surface, pdev, &qfam_props); + if (_query_gfx_index(num_qfams, qfam_props) != -1) score += 20; - if (_get_qfam_index(num_qfams, VK_QUEUE_COMPUTE_BIT, qfam_props) != -1) - score += 5; - if (_get_qfam_index(num_qfams, VK_QUEUE_TRANSFER_BIT, qfam_props) != -1) + if (_query_comp_index(num_qfams, qfam_props) != -1) score += 20; - - VkBool32 present_bit; - vkGetPhysicalDeviceSurfaceSupportKHR(pdev, 0, surface, &present_bit); - if (present_bit != VK_FALSE) + if (_query_tsfr_index(num_qfams, qfam_props) != -1) + score += 20; + if (_query_pres_index(num_qfams, qfam_props, pdev, surface) != -1) score += 20; rune_free(qfam_props); return score; } -struct vkdev* create_vkdev(VkInstance instance, VkSurfaceKHR surface) { - uint32_t pdev_count; - vkEnumeratePhysicalDevices(instance, &pdev_count, NULL); - if (pdev_count == 0) +VkPhysicalDevice _select_pdev(VkInstance instance, VkSurfaceKHR surface) { + uint32_t count; + vkEnumeratePhysicalDevices(instance, &count, NULL); + if (count == 0) return NULL; - VkPhysicalDevice pdevs[pdev_count]; - vkEnumeratePhysicalDevices(instance, &pdev_count, pdevs); - - uint32_t selected_pdev = -1; - for (uint32_t i = 0; i < pdev_count; i++) { - if (_check_pdev(surface, pdevs[i]) >= 60) { - selected_pdev = i; - break; - } + + VkPhysicalDevice pdevs[count]; + vkEnumeratePhysicalDevices(instance, &count, pdevs); + + for (uint32_t i = 0; i < count; i++) { + if (_check_pdev(surface, pdevs[i]) >= 80) + return pdevs[i]; + } + return NULL; +} + +void _create_queue(struct vkdev *dev, int qfam_index, int queue_index) { + vkGetDeviceQueue(dev->ldev, qfam_index, queue_index, &dev->queues[qfam_index].handle); + if (dev->queues[qfam_index].handle == NULL) { + log_output(LOG_FATAL, "Error creating required Vulkan queue"); + rune_abort(); } +} - if (selected_pdev == -1) { +struct vkdev* create_vkdev(VkInstance instance, VkSurfaceKHR surface) { + VkPhysicalDevice pdev = _select_pdev(instance, surface); + if (pdev == NULL) { log_output(LOG_FATAL, "No device meets minimum requirements for rendering"); - return NULL; + rune_abort(); } - struct vkdev *dev = rune_alloc(sizeof(struct vkdev)); - dev->pdev = pdevs[selected_pdev]; + struct vkdev *dev = rune_calloc(0, sizeof(struct vkdev)); + dev->pdev = pdev; - VkQueueFamilyProperties *qfam_props; - int num_qfams = _query_qfam_data(surface, pdevs[selected_pdev], &qfam_props); - VkBool32 present_support; - for (int i = 0; i < num_qfams; i++) { - vkassert(vkGetPhysicalDeviceSurfaceSupportKHR(dev->pdev, i, surface, &present_support)); - if (present_support == VK_TRUE && i != dev->gfx_index) { - dev->pres_index = i; - } - dev->gfx_index = _get_qfam_index(num_qfams, VK_QUEUE_GRAPHICS_BIT, qfam_props); - dev->tsfr_index = _get_qfam_index(num_qfams, VK_QUEUE_TRANSFER_BIT, qfam_props); - dev->comp_index = _get_qfam_index(num_qfams, VK_QUEUE_COMPUTE_BIT, qfam_props); + dev->queues[0].index = gfx_qfam; + dev->queues[1].index = tsfr_qfam; + dev->queues[2].index = comp_qfam; + dev->queues[3].index = pres_qfam; float queue_priority = 1.0f; VkDeviceQueueCreateInfo qcinfos[3]; - qcinfos[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - qcinfos[0].queueFamilyIndex = dev->gfx_index; - qcinfos[0].queueCount = 1; - qcinfos[0].flags = 0; - qcinfos[0].pNext = NULL; - qcinfos[0].pQueuePriorities = &queue_priority; - - qcinfos[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - qcinfos[1].queueFamilyIndex = dev->tsfr_index; - qcinfos[1].queueCount = 1; - qcinfos[1].flags = 0; - qcinfos[1].pNext = NULL; - qcinfos[1].pQueuePriorities = &queue_priority; - - qcinfos[2].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - qcinfos[2].queueFamilyIndex = dev->comp_index; - qcinfos[2].queueCount = 1; - qcinfos[2].flags = 0; - qcinfos[2].pNext = NULL; - qcinfos[2].pQueuePriorities = &queue_priority; + for (int i = 0; i < 3; i++) { + qcinfos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + qcinfos[i].pNext = NULL; + qcinfos[i].flags = 0; + qcinfos[i].queueFamilyIndex = dev->queues[i].index; + qcinfos[i].queueCount = 1; + qcinfos[i].pQueuePriorities = &queue_priority; + } struct vkdev_data pdata; - _query_pdev_data(pdevs[selected_pdev], &pdata); + _query_pdev_data(pdev, &pdata); VkDeviceCreateInfo dcinfo; dcinfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; dcinfo.pNext = NULL; dcinfo.flags = 0; - dcinfo.queueCreateInfoCount = 2; + dcinfo.queueCreateInfoCount = 3; dcinfo.pQueueCreateInfos = qcinfos; dcinfo.enabledLayerCount = 0; dcinfo.ppEnabledLayerNames = NULL; @@ -142,32 +154,14 @@ struct vkdev* create_vkdev(VkInstance instance, VkSurfaceKHR surface) { dcinfo.pEnabledFeatures = &pdata.pdev_feats; vkassert(vkCreateDevice(dev->pdev, &dcinfo, NULL, &dev->ldev)); - vkGetDeviceQueue(dev->ldev, dev->gfx_index, 0, &dev->gfx_queue); - if (dev->gfx_queue == NULL) { - log_output(LOG_FATAL, "Error creating Vulkan graphics queue"); - rune_abort(); - } - vkGetDeviceQueue(dev->ldev, dev->tsfr_index, 0, &dev->tsfr_queue); - if (dev->tsfr_queue == NULL) { - log_output(LOG_FATAL, "Error creating Vulkan transfer queue"); - rune_abort(); - } - vkGetDeviceQueue(dev->ldev, dev->pres_index, 0, &dev->pres_queue); - if (dev->pres_queue == NULL) { - log_output(LOG_FATAL, "Error creating Vulkan present queue"); - rune_abort(); - } - vkGetDeviceQueue(dev->ldev, dev->comp_index, 0, &dev->comp_queue); - if (dev->comp_queue == NULL) { - log_output(LOG_FATAL, "Error creating Vulkan compute queue"); - rune_abort(); - } + for (uint32_t i = 0; i < 3; i++) + _create_queue(dev, i, 0); VkCommandPoolCreateInfo pcinfo; pcinfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; pcinfo.pNext = NULL; pcinfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - pcinfo.queueFamilyIndex = dev->gfx_index; + pcinfo.queueFamilyIndex = dev->queues[0].index; vkassert(vkCreateCommandPool(dev->ldev, &pcinfo, NULL, &dev->cmd_pool)); log_output(LOG_DEBUG, "Initialized new logical device"); diff --git a/render/vulkan/device.h b/render/vulkan/device.h index 6bdd4f5..e498137 100644 --- a/render/vulkan/device.h +++ b/render/vulkan/device.h @@ -34,18 +34,17 @@ struct vkswapchain_data { uint32_t present_count; }; +struct vkqueue { + uint32_t index; + uint32_t qfam; + VkQueue handle; +}; + struct vkdev { VkPhysicalDevice pdev; VkDevice ldev; struct vkswapchain_data scdata; - uint32_t gfx_index; - uint32_t pres_index; - uint32_t tsfr_index; - uint32_t comp_index; - VkQueue gfx_queue; - VkQueue pres_queue; - VkQueue tsfr_queue; - VkQueue comp_queue; + struct vkqueue queues[4]; VkCommandPool cmd_pool; VkFormat depth_format; }; diff --git a/render/vulkan/swapchain.c b/render/vulkan/swapchain.c index 1247c9a..c6cea29 100644 --- a/render/vulkan/swapchain.c +++ b/render/vulkan/swapchain.c @@ -37,8 +37,8 @@ struct vkswapchain* create_swapchain(struct vksurface *surface, struct vkdev *de cinfo.presentMode = VK_PRESENT_MODE_MAILBOX_KHR; cinfo.clipped = VK_TRUE; cinfo.oldSwapchain = NULL; - if (dev->gfx_index != dev->pres_index) { - uint32_t qfams[] = {dev->gfx_index, dev->pres_index}; + if (dev->queues[0].index != dev->queues[3].index) { + uint32_t qfams[] = {dev->queues[0].index, dev->queues[3].index}; cinfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; cinfo.queueFamilyIndexCount = 2; cinfo.pQueueFamilyIndices = qfams; @@ -57,9 +57,10 @@ struct vkswapchain* create_swapchain(struct vksurface *surface, struct vkdev *de VkImageViewCreateInfo vcinfo; for (uint32_t i = 0; i < swapchain->img_count; i++) { vcinfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + vcinfo.pNext = NULL; vcinfo.image = swapchain->images[i]; vcinfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - vcinfo.format = swapchain->format; + vcinfo.format = swapchain->format_khr.format; vcinfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; vcinfo.subresourceRange.baseMipLevel = 0; vcinfo.subresourceRange.levelCount = 1; @@ -103,10 +104,10 @@ void vkswapchain_present(struct vkswapchain *swapchain, struct vkdev *dev) { pinfo.pWaitSemaphores = &swapchain->render_complete; pinfo.swapchainCount = 1; pinfo.pSwapchains = &swapchain->handle; - pinfo.pImageIndices = &dev->pres_index; + pinfo.pImageIndices = &dev->queues[3].index; pinfo.pResults = NULL; - VkResult res = vkQueuePresentKHR(dev->pres_queue, &pinfo); + VkResult res = vkQueuePresentKHR(dev->queues[3].handle, &pinfo); if (res == VK_ERROR_OUT_OF_DATE_KHR || res == VK_SUBOPTIMAL_KHR) STUBBED("Recreate swapchain"); else if (res != VK_SUCCESS) |