summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--render/vulkan/device.c190
-rw-r--r--render/vulkan/device.h15
-rw-r--r--render/vulkan/swapchain.c11
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)