fixed some queue selection cases

This commit is contained in:
Matthew 2025-03-30 09:10:43 +11:00
parent c76dc917cc
commit 51b02627b1
3 changed files with 56 additions and 17 deletions

View File

@ -341,20 +341,54 @@ static DeviceQueues CheckDeviceQueueSupport(VkPhysicalDevice device, VkSurfaceKH
VkQueueFamilyProperties *families = ArenaAlloc(renderer.arena, sizeof(VkQueueFamilyProperties) * queue_count); VkQueueFamilyProperties *families = ArenaAlloc(renderer.arena, sizeof(VkQueueFamilyProperties) * queue_count);
vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count, families); vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count, families);
if (queue_count == 1 &&
BitEq(families[0].queueFlags, VK_QUEUE_TRANSFER_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT) &&
families[0].queueCount == 1)
{
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++) for (i32 i = 0; i < queue_count; i++)
{ {
if (i == 0 && CheckQueueSurfaceSupport(i, device, surface)) if (queues.graphics < 0 && CheckQueueSurfaceSupport(i, device, surface) && BitEq(families[i].queueFlags, VK_QUEUE_GRAPHICS_BIT))
{ {
queues.graphics = i; queues.graphics = i;
continue; continue;
} }
if (BitEq(families[i].queueFlags, VK_QUEUE_TRANSFER_BIT)) 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; queues.transfer = i;
} }
if (queues.transfer < 0) if (queues.transfer < 0)
queues.transfer = queues.graphics; queues.transfer = queues.graphics;
}
return queues; return queues;
} }
@ -466,6 +500,7 @@ static b32 CreateDevice()
VkDeviceQueueCreateInfo queue_info[2] = {0}; VkDeviceQueueCreateInfo queue_info[2] = {0};
f32 priority = 1.0f; f32 priority = 1.0f;
u32 count = 1; u32 count = 1;
u32 transfer_queue_index = 0;
queue_info[0].sType = STYPE(DEVICE_QUEUE_CREATE_INFO); queue_info[0].sType = STYPE(DEVICE_QUEUE_CREATE_INFO);
queue_info[0].queueFamilyIndex = queues->graphics; queue_info[0].queueFamilyIndex = queues->graphics;
@ -473,12 +508,16 @@ static b32 CreateDevice()
queue_info[0].pQueuePriorities = &priority; queue_info[0].pQueuePriorities = &priority;
queue_info[0].flags = 0; 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].sType = STYPE(DEVICE_QUEUE_CREATE_INFO);
queue_info[1].queueFamilyIndex = queues->transfer; queue_info[1].queueFamilyIndex = queues->transfer;
queue_info[1].queueCount = 1; queue_info[1].queueCount = 1;
queue_info[1].pQueuePriorities = &priority; queue_info[1].pQueuePriorities = &priority;
queue_info[1].flags = 0; queue_info[1].flags = 0;
if (queues->transfer == queues->graphics)
transfer_queue_index = 1;
count++; count++;
} }
@ -492,8 +531,9 @@ static b32 CreateDevice()
else else
{ {
Assert(InitVkDeviceFunctions(), "Failed to initialize device functions"); Assert(InitVkDeviceFunctions(), "Failed to initialize device functions");
vkGetDeviceQueue(renderer.vk.device, queues->graphics, 0, &queues->graphics_queue); 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; success = true;
} }
} }
@ -757,12 +797,10 @@ static b32 CreateImmediateStructures()
ImmediateStructures *imm = &renderer.vk.imm; ImmediateStructures *imm = &renderer.vk.imm;
pool_create_info.queueFamilyIndex = renderer.vk.queues.transfer; pool_create_info.queueFamilyIndex = renderer.vk.queues.transfer;
if (renderer.vk_conf.avail_threads >= 10) if (renderer.vk_conf.avail_threads >= 4 && !renderer.vk.queues.single_queue)
renderer.vk_conf.avail_threads = 3;
else if (renderer.vk_conf.avail_threads >= 8)
renderer.vk_conf.avail_threads = 2;
else
renderer.vk_conf.avail_threads = 1; 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->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); imm->cmds = ArenaAlloc(renderer.perm_arena, sizeof(VkCommandBuffer) * renderer.vk_conf.avail_threads);

View File

@ -236,6 +236,7 @@ typedef struct
typedef struct { typedef struct {
i32 graphics, transfer; i32 graphics, transfer;
VkQueue graphics_queue, transfer_queue; VkQueue graphics_queue, transfer_queue;
b8 single_queue;
} DeviceQueues; } DeviceQueues;
typedef struct { typedef struct {

View File

@ -15,7 +15,7 @@
#define Len(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) #define Len(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
#define MakeString(x) #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 AlignPow2(x, b) (((x) + (b) - 1) & (~((b) - 1)))
#define IsPow2(x) ((x) != 0 && ((x) &((x) - 1)) == 0) #define IsPow2(x) ((x) != 0 && ((x) &((x) - 1)) == 0)
#define PtrAdd(ptr, add) (((char *)ptr) + add) #define PtrAdd(ptr, add) (((char *)ptr) + add)