diff --git a/src/l2/alice/engine.h b/src/l2/alice/engine.h index 953c99b..a7785f3 100644 --- a/src/l2/alice/engine.h +++ b/src/l2/alice/engine.h @@ -629,11 +629,6 @@ void Jane_alice_destroy(VkDevice device, Jane_alice jane) { vkDestroyFence(device, jane.roxy, NULL); } -typedef struct { - VkQueue graphics_queue; - VkQueue presentation_queue; -} UsedVulkanQueues; - void alice_default_callback_on_wl_pointer_button(void* d, uint32_t button, uint32_t btn_action){} void alice_default_callback_on_wl_keyboard_key(void* d, U32 keysym, U32 key_action){} @@ -715,7 +710,7 @@ struct Alice { VkPhysicalDevice physical_device; MargaretChosenQueueFamilies queue_fam; VkDevice device; - UsedVulkanQueues queues; + MargaretUsedQueues queues; VkFormat zbuffer_format; VkFormat IT1_format; VkRenderPass render_pass_0; @@ -1362,7 +1357,7 @@ void alice_frame_drawing(Alice* alice) { alice_reset_and_record_command_buffer_0(alice, t_mat); alice_reset_and_record_command_buffer_1(alice, *VecVkFramebuffer_at(&alice->swfb.framebuffers, ij)); - check(vkQueueSubmit(alice->queues.graphics_queue, 1, &(VkSubmitInfo){ + check(vkQueueSubmit(alice->queues.graphics, 1, &(VkSubmitInfo){ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .commandBufferCount = 1, .pCommandBuffers = (VkCommandBuffer[]){ alice->transfer_command_buf }, @@ -1370,7 +1365,7 @@ void alice_frame_drawing(Alice* alice) { .pSignalSemaphores = (VkSemaphore[]){ alice->jane.in_frame_transfer_complete }, }, NULL) == VK_SUCCESS); - check(vkQueueSubmit(alice->queues.graphics_queue, 1, &(VkSubmitInfo){ + check(vkQueueSubmit(alice->queues.graphics, 1, &(VkSubmitInfo){ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .waitSemaphoreCount = 1, @@ -1386,7 +1381,7 @@ void alice_frame_drawing(Alice* alice) { .pSignalSemaphores = (VkSemaphore[]){ alice->jane.rendered_to_IT1_semaphore }, }, NULL) == VK_SUCCESS); - check(vkQueueSubmit(alice->queues.graphics_queue, 1, &(VkSubmitInfo){ + check(vkQueueSubmit(alice->queues.graphics, 1, &(VkSubmitInfo){ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .waitSemaphoreCount = 2, .pWaitSemaphores = (VkSemaphore[]){ @@ -1410,7 +1405,7 @@ void alice_frame_drawing(Alice* alice) { .pImageIndices = (U32[]){ ij }, .pResults = NULL, }; - VkResult present_ret = vkQueuePresentKHR(alice->queues.presentation_queue, &present_info); + VkResult present_ret = vkQueuePresentKHR(alice->queues.presentation, &present_info); if (present_ret == VK_ERROR_OUT_OF_DATE_KHR || present_ret == VK_SUBOPTIMAL_KHR) { fprintf(stderr, "vkQueuePresentKHR: VK_ERROR_OUT_OF_DATE_KHR or \n"); check(vkWaitForFences(alice->device, 1, &alice->jane.in_flight_fence, VK_TRUE, UINT64_MAX) == VK_SUCCESS); @@ -1762,13 +1757,7 @@ Alice* Alice_new(){ alice->device = margaret_create_logical_device(alice->physical_device, alice->queue_fam); - if (alice->queue_fam.for_graphics == alice->queue_fam.for_presentation) { - vkGetDeviceQueue(alice->device, alice->queue_fam.for_graphics, 0, &alice->queues.graphics_queue); - alice->queues.presentation_queue = alice->queues.graphics_queue; - } else { - vkGetDeviceQueue(alice->device, alice->queue_fam.for_graphics, 0, &alice->queues.graphics_queue); - vkGetDeviceQueue(alice->device, alice->queue_fam.for_presentation, 0, &alice->queues.presentation_queue); - } + alice->queues = margaret_get_device_queues(alice->device, alice->queue_fam); ResultMargaretChosenSwapchainDetailsOrSpanU8 swapchain_details_res = margaret_choose_swapchain_details( alice->physical_device, alice->surface, alice->wl.sane_image_extent_limit); diff --git a/src/l2/margaret/vulkan_utils.h b/src/l2/margaret/vulkan_utils.h index 508ceac..06895d6 100644 --- a/src/l2/margaret/vulkan_utils.h +++ b/src/l2/margaret/vulkan_utils.h @@ -145,6 +145,7 @@ void MargaretInstanceAndItsDebug_drop(MargaretInstanceAndItsDebug instance) { typedef struct { U32 for_graphics; U32 for_presentation; + U32 for_compute; } MargaretChosenQueueFamilies; /* MargaretChosenQueueFamilies or a static string, describing which part could not be found @@ -163,13 +164,13 @@ ResultMargaretChosenQueueFamiliesOrSpanU8 margaret_choose_good_queue_families(Vk VecVkQueueFamilyProperties queue_families = VecVkQueueFamilyProperties_new_zeroinit(queue_family_count); vkGetPhysicalDeviceQueueFamilyProperties(dev, &queue_family_count, queue_families.buf); - OptionU32 index_for_graphics = None_U32(); + OptionU32 index_for_graph_and_comp = None_U32(); OptionU32 index_for_presentation = None_U32(); for (uint32_t i = 0; i < queue_family_count; i++) { const VkQueueFamilyProperties* props = VecVkQueueFamilyProperties_at(&queue_families, i); - if (props->queueFlags & VK_QUEUE_GRAPHICS_BIT && props->queueCount >= 1) { - index_for_graphics = Some_U32(i); + if (props->queueFlags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT) && props->queueCount >= 1) { + index_for_graph_and_comp = Some_U32(i); } VkBool32 isPres = false; if (vkGetPhysicalDeviceSurfaceSupportKHR(dev, i, surface, &isPres) != VK_SUCCESS) @@ -178,15 +179,45 @@ ResultMargaretChosenQueueFamiliesOrSpanU8 margaret_choose_good_queue_families(Vk index_for_presentation = Some_U32(i); } VecVkQueueFamilyProperties_drop(queue_families); - if (index_for_graphics.variant == Option_None) - return (ResultMargaretChosenQueueFamiliesOrSpanU8){ .variant = Result_Err, .err = cstr("No graphics queue family") }; + if (index_for_graph_and_comp.variant == Option_None) + return (ResultMargaretChosenQueueFamiliesOrSpanU8){ .variant = Result_Err, + .err = cstr("No queue family for both graphics and compute") }; if (index_for_presentation.variant == Option_None) return (ResultMargaretChosenQueueFamiliesOrSpanU8){ .variant = Result_Err, .err = cstr("No presentation queue family") }; return (ResultMargaretChosenQueueFamiliesOrSpanU8){ .variant = Result_Ok, .ok = (MargaretChosenQueueFamilies){ - .for_graphics = index_for_graphics.some, .for_presentation = index_for_presentation.some + .for_graphics = index_for_graph_and_comp.some, + .for_compute = index_for_graph_and_comp.some, + .for_presentation = index_for_presentation.some } }; } +typedef struct { + VkQueue graphics; + VkQueue presentation; + VkQueue compute; +} MargaretUsedQueues; + +MargaretUsedQueues margaret_get_device_queues(VkDevice device, MargaretChosenQueueFamilies family) { + MargaretUsedQueues queues; + vkGetDeviceQueue(device, family.for_graphics, 0, &queues.graphics); + + if (family.for_presentation == family.for_graphics) { + queues.presentation = queues.graphics; + } else { + vkGetDeviceQueue(device, family.for_presentation, 0, &queues.presentation); + } + + if (family.for_compute == family.for_graphics) { + queues.compute = queues.graphics; + } else if (family.for_compute == family.for_presentation) { + queues.compute = queues.presentation; + } else { + vkGetDeviceQueue(device, family.for_compute, 0, &queues.compute); + } + return queues; +} + + // These are not the same as instance extensions VecVecU8 margaret_get_extensions_of_physical_device(VkPhysicalDevice physical_device) { uint32_t extensions_count = 0; @@ -311,14 +342,20 @@ VkDevice margaret_create_logical_device(VkPhysicalDevice physical_device, Margar float qfam_queue_priorities[1] = {1.f}; VkDeviceQueueCreateInfo queue_crinfo[2] = { 0 }; int queue_c = 0; - if (queue_fam.for_graphics == queue_fam.for_presentation) { - queue_c = 1; - queue_crinfo[0].queueFamilyIndex = queue_fam.for_graphics; - } else { - queue_c = 2; - queue_crinfo[0].queueFamilyIndex = queue_fam.for_graphics; - queue_crinfo[1].queueFamilyIndex = queue_fam.for_presentation; + + queue_crinfo[queue_c].queueFamilyIndex = queue_fam.for_graphics; + queue_c++; + + if (queue_fam.for_graphics != queue_fam.for_presentation) { + queue_crinfo[queue_c].queueFamilyIndex = queue_fam.for_presentation; + queue_c++; } + + if (queue_fam.for_compute != queue_fam.for_presentation && queue_fam.for_compute != queue_fam.for_graphics) { + queue_crinfo[queue_c].queueFamilyIndex = queue_fam.for_compute; + queue_c++; + } + for (int i = 0; i < queue_c; i++) { queue_crinfo[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queue_crinfo[i].queueCount = 1;