summaryrefslogtreecommitdiff
path: root/render/vulkan/device.c
diff options
context:
space:
mode:
Diffstat (limited to 'render/vulkan/device.c')
-rw-r--r--render/vulkan/device.c190
1 files changed, 92 insertions, 98 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");