From 51b02627b1b138e3ecb5dd331c54c8b38642fd0e Mon Sep 17 00:00:00 2001 From: Matthew Date: Sun, 30 Mar 2025 09:10:43 +1100 Subject: [PATCH] fixed some queue selection cases --- src/renderer_vulkan.c | 70 +++++++++++++++++++++++++++++++++---------- src/renderer_vulkan.h | 1 + src/util.h | 2 +- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/renderer_vulkan.c b/src/renderer_vulkan.c index 73877bd..83ba3d5 100644 --- a/src/renderer_vulkan.c +++ b/src/renderer_vulkan.c @@ -341,21 +341,55 @@ static DeviceQueues CheckDeviceQueueSupport(VkPhysicalDevice device, VkSurfaceKH VkQueueFamilyProperties *families = ArenaAlloc(renderer.arena, sizeof(VkQueueFamilyProperties) * queue_count); vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count, families); - for (i32 i = 0; i < queue_count; i++) + if (queue_count == 1 && + BitEq(families[0].queueFlags, VK_QUEUE_TRANSFER_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT) && + families[0].queueCount == 1) { - if (i == 0 && CheckQueueSurfaceSupport(i, device, surface)) + queues.graphics = queues.transfer = 0; + queues.single_queue = true; + } + else + { + b8 sparse_binding = false; + b8 transfer_only = false; + for (i32 i = 0; i < queue_count; i++) { - queues.graphics = i; - continue; + if (queues.graphics < 0 && CheckQueueSurfaceSupport(i, device, surface) && BitEq(families[i].queueFlags, VK_QUEUE_GRAPHICS_BIT)) + { + queues.graphics = i; + continue; + } + + if (BitEq(families[i].queueFlags, VK_QUEUE_TRANSFER_BIT | VK_QUEUE_SPARSE_BINDING_BIT) && !BitEq(families[i].queueFlags, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT)) + { + sparse_binding = true; + transfer_only = true; + queues.transfer = i; + continue; + } + + if (BitEq(families[i].queueFlags, VK_QUEUE_TRANSFER_BIT | VK_QUEUE_SPARSE_BINDING_BIT) && !(sparse_binding && transfer_only)) + { + sparse_binding = true; + queues.transfer = i; + continue; + } + + if (BitEq(families[i].queueFlags, VK_QUEUE_TRANSFER_BIT) && !BitEq(families[i].queueFlags, VK_QUEUE_COMPUTE_BIT) && !sparse_binding) + { + transfer_only = true; + queues.transfer = i; + continue; + } + + if (BitEq(families[i].queueFlags, VK_QUEUE_TRANSFER_BIT) && !sparse_binding && !transfer_only) + queues.transfer = i; } - if (BitEq(families[i].queueFlags, VK_QUEUE_TRANSFER_BIT)) - queues.transfer = i; + if (queues.transfer < 0) + queues.transfer = queues.graphics; } - if (queues.transfer < 0) - queues.transfer = queues.graphics; - return queues; } @@ -466,6 +500,7 @@ static b32 CreateDevice() VkDeviceQueueCreateInfo queue_info[2] = {0}; f32 priority = 1.0f; u32 count = 1; + u32 transfer_queue_index = 0; queue_info[0].sType = STYPE(DEVICE_QUEUE_CREATE_INFO); queue_info[0].queueFamilyIndex = queues->graphics; @@ -473,12 +508,16 @@ static b32 CreateDevice() queue_info[0].pQueuePriorities = &priority; queue_info[0].flags = 0; - if (queues->graphics != queues->transfer) { + if (!queues->single_queue) { queue_info[1].sType = STYPE(DEVICE_QUEUE_CREATE_INFO); queue_info[1].queueFamilyIndex = queues->transfer; queue_info[1].queueCount = 1; queue_info[1].pQueuePriorities = &priority; queue_info[1].flags = 0; + + if (queues->transfer == queues->graphics) + transfer_queue_index = 1; + count++; } @@ -492,8 +531,9 @@ static b32 CreateDevice() else { Assert(InitVkDeviceFunctions(), "Failed to initialize device functions"); + vkGetDeviceQueue(renderer.vk.device, queues->graphics, 0, &queues->graphics_queue); - vkGetDeviceQueue(renderer.vk.device, queues->transfer, 0, &queues->transfer_queue); + vkGetDeviceQueue(renderer.vk.device, queues->transfer, transfer_queue_index, &queues->transfer_queue); success = true; } } @@ -757,12 +797,10 @@ static b32 CreateImmediateStructures() ImmediateStructures *imm = &renderer.vk.imm; pool_create_info.queueFamilyIndex = renderer.vk.queues.transfer; - if (renderer.vk_conf.avail_threads >= 10) - renderer.vk_conf.avail_threads = 3; - else if (renderer.vk_conf.avail_threads >= 8) - renderer.vk_conf.avail_threads = 2; - else + if (renderer.vk_conf.avail_threads >= 4 && !renderer.vk.queues.single_queue) renderer.vk_conf.avail_threads = 1; + else + renderer.vk_conf.avail_threads = 0; imm->pools = ArenaAlloc(renderer.perm_arena, sizeof(VkCommandPool) * renderer.vk_conf.avail_threads); imm->cmds = ArenaAlloc(renderer.perm_arena, sizeof(VkCommandBuffer) * renderer.vk_conf.avail_threads); diff --git a/src/renderer_vulkan.h b/src/renderer_vulkan.h index fd8af47..584d618 100644 --- a/src/renderer_vulkan.h +++ b/src/renderer_vulkan.h @@ -236,6 +236,7 @@ typedef struct typedef struct { i32 graphics, transfer; VkQueue graphics_queue, transfer_queue; + b8 single_queue; } DeviceQueues; typedef struct { diff --git a/src/util.h b/src/util.h index 5461f2c..b8be589 100644 --- a/src/util.h +++ b/src/util.h @@ -15,7 +15,7 @@ #define Len(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) #define MakeString(x) #x -#define BitEq(var, bits) (((var) & (bits)) == bits) +#define BitEq(var, bits) (((var) & (bits)) == (bits)) #define AlignPow2(x, b) (((x) + (b) - 1) & (~((b) - 1))) #define IsPow2(x) ((x) != 0 && ((x) &((x) - 1)) == 0) #define PtrAdd(ptr, add) (((char *)ptr) + add)