This commit is contained in:
TheLastRar 2025-12-15 12:43:58 +01:00 committed by GitHub
commit bcac92ae96
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -463,26 +463,72 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer
vkGetPhysicalDeviceQueueFamilyProperties(m_physical_device, &queue_family_count, queue_family_properties.data()); vkGetPhysicalDeviceQueueFamilyProperties(m_physical_device, &queue_family_count, queue_family_properties.data());
DevCon.WriteLn("%u vulkan queue families", queue_family_count); DevCon.WriteLn("%u vulkan queue families", queue_family_count);
// Find graphics and present queues. std::vector<int> queue_family_users(queue_family_count, 0);
m_graphics_queue_family_index = queue_family_count; m_graphics_queue_family_index = queue_family_count;
m_present_queue_family_index = queue_family_count; m_present_queue_family_index = queue_family_count;
u32 present_queue_index = 0;
m_spin_queue_family_index = queue_family_count; m_spin_queue_family_index = queue_family_count;
u32 spin_queue_index = 0; u32 spin_queue_index = 0;
// Graphics Queue
for (uint32_t i = 0; i < queue_family_count; i++) for (uint32_t i = 0; i < queue_family_count; i++)
{ {
VkBool32 graphics_supported = queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT; if (queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
if (graphics_supported)
{ {
m_graphics_queue_family_index = i; m_graphics_queue_family_index = i;
// Quit now, no need for a present queue. queue_family_users[i]++;
if (!surface) break;
{
break;
}
} }
}
if (surface) // Spinwait Queue
for (uint32_t i = 0; i < queue_family_count; i++)
{
if (queue_family_properties[i].queueCount == queue_family_users[i])
continue;
if (!(queue_family_properties[i].queueFlags & VK_QUEUE_COMPUTE_BIT))
continue;
if (queue_family_properties[i].timestampValidBits == 0)
continue; // We need timing
if (!(queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT))
{ {
m_spin_queue_family_index = i;
break;
}
else if (m_spin_queue_family_index == queue_family_count)
m_spin_queue_family_index = i;
}
if (m_spin_queue_family_index != queue_family_count)
{
spin_queue_index = queue_family_users[m_spin_queue_family_index];
queue_family_users[m_spin_queue_family_index]++;
m_spin_queue_is_graphics_queue = false;
}
else
{
// No spare queue? Try the graphics queue.
if ((queue_family_properties[m_graphics_queue_family_index].queueCount & VK_QUEUE_COMPUTE_BIT) &&
(queue_family_properties[m_graphics_queue_family_index].timestampValidBits != 0))
{
m_spin_queue_family_index = m_graphics_queue_family_index;
spin_queue_index = 0;
m_spin_queue_is_graphics_queue = true;
}
else
m_spin_queue_is_graphics_queue = false;
}
// Present Queue
if (surface)
{
for (uint32_t i = 0; i < queue_family_count; i++)
{
if (queue_family_properties[i].queueCount == queue_family_users[i])
continue;
VkBool32 present_supported; VkBool32 present_supported;
VkResult res = vkGetPhysicalDeviceSurfaceSupportKHR(m_physical_device, i, surface, &present_supported); VkResult res = vkGetPhysicalDeviceSurfaceSupportKHR(m_physical_device, i, surface, &present_supported);
if (res != VK_SUCCESS) if (res != VK_SUCCESS)
@ -491,35 +537,48 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer
return false; return false;
} }
if (present_supported) if (!present_supported)
continue;
// Perfer aync compute queue
if ((queue_family_properties[i].queueFlags & VK_QUEUE_COMPUTE_BIT) &&
!(queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT))
{ {
m_present_queue_family_index = i; m_present_queue_family_index = i;
break;
}
else if (m_present_queue_family_index == queue_family_count)
m_present_queue_family_index = i;
}
if (m_present_queue_family_index != queue_family_count)
{
present_queue_index = queue_family_users[m_present_queue_family_index];
queue_family_users[m_present_queue_family_index]++;
}
else
{
// No spare queue? Try the graphics queue.
VkBool32 present_supported;
VkResult res = vkGetPhysicalDeviceSurfaceSupportKHR(m_physical_device, m_graphics_queue_family_index, surface, &present_supported);
if (res != VK_SUCCESS)
{
LOG_VULKAN_ERROR(res, "vkGetPhysicalDeviceSurfaceSupportKHR failed: ");
return false;
} }
// Prefer one queue family index that does both graphics and present. if (present_supported)
if (graphics_supported && present_supported)
{ {
break; m_present_queue_family_index = m_graphics_queue_family_index;
present_queue_index = 0;
} }
} }
} }
for (uint32_t i = 0; i < queue_family_count; i++)
{ // Swap spin and present to simplify queue priorities logic.
// Pick a queue for spinning if (!m_spin_queue_is_graphics_queue && m_present_queue_family_index == m_spin_queue_family_index)
if (!(queue_family_properties[i].queueFlags & VK_QUEUE_COMPUTE_BIT)) std::swap(spin_queue_index, present_queue_index);
continue; // We need compute
if (queue_family_properties[i].timestampValidBits == 0)
continue; // We need timing
const bool queue_is_used = i == m_graphics_queue_family_index || i == m_present_queue_family_index;
if (queue_is_used && m_spin_queue_family_index != queue_family_count)
continue; // Found a non-graphics queue to use
spin_queue_index = 0;
m_spin_queue_family_index = i;
if (queue_is_used && queue_family_properties[i].queueCount > 1)
spin_queue_index = 1;
if (!(queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT))
break; // Async compute queue, definitely pick this one
}
if (m_graphics_queue_family_index == queue_family_count) if (m_graphics_queue_family_index == queue_family_count)
{ {
Console.Error("VK: Failed to find an acceptable graphics queue."); Console.Error("VK: Failed to find an acceptable graphics queue.");
@ -537,14 +596,16 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer
device_info.flags = 0; device_info.flags = 0;
device_info.queueCreateInfoCount = 0; device_info.queueCreateInfoCount = 0;
static constexpr float queue_priorities[] = {1.0f, 0.0f}; // Low priority for the spin queue // Low priority for the spin queue
static constexpr float queue_priorities[] = {1.0f, 1.0f, 0.0f};
std::array<VkDeviceQueueCreateInfo, 3> queue_infos; std::array<VkDeviceQueueCreateInfo, 3> queue_infos;
VkDeviceQueueCreateInfo& graphics_queue_info = queue_infos[device_info.queueCreateInfoCount++]; VkDeviceQueueCreateInfo& graphics_queue_info = queue_infos[device_info.queueCreateInfoCount++];
graphics_queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; graphics_queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
graphics_queue_info.pNext = nullptr; graphics_queue_info.pNext = nullptr;
graphics_queue_info.flags = 0; graphics_queue_info.flags = 0;
graphics_queue_info.queueFamilyIndex = m_graphics_queue_family_index; graphics_queue_info.queueFamilyIndex = m_graphics_queue_family_index;
graphics_queue_info.queueCount = 1; graphics_queue_info.queueCount = queue_family_users[m_graphics_queue_family_index];
graphics_queue_info.pQueuePriorities = queue_priorities; graphics_queue_info.pQueuePriorities = queue_priorities;
if (surface != VK_NULL_HANDLE && m_graphics_queue_family_index != m_present_queue_family_index) if (surface != VK_NULL_HANDLE && m_graphics_queue_family_index != m_present_queue_family_index)
@ -554,19 +615,19 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer
present_queue_info.pNext = nullptr; present_queue_info.pNext = nullptr;
present_queue_info.flags = 0; present_queue_info.flags = 0;
present_queue_info.queueFamilyIndex = m_present_queue_family_index; present_queue_info.queueFamilyIndex = m_present_queue_family_index;
present_queue_info.queueCount = 1; present_queue_info.queueCount = queue_family_users[m_present_queue_family_index];
present_queue_info.pQueuePriorities = queue_priorities; present_queue_info.pQueuePriorities = queue_priorities;
} }
if (m_spin_queue_family_index == m_graphics_queue_family_index) if (m_spin_queue_family_index == m_graphics_queue_family_index)
{ {
if (spin_queue_index != 0) if (spin_queue_index == 1)
graphics_queue_info.queueCount = 2; graphics_queue_info.pQueuePriorities = queue_priorities + 1;
} }
else if (m_spin_queue_family_index == m_present_queue_family_index) else if (m_spin_queue_family_index == m_present_queue_family_index)
{ {
if (spin_queue_index != 0) if (spin_queue_index == 1)
queue_infos[1].queueCount = 2; // present queue queue_infos[1].pQueuePriorities = queue_priorities + 1;
} }
else else
{ {
@ -576,7 +637,7 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer
spin_queue_info.flags = 0; spin_queue_info.flags = 0;
spin_queue_info.queueFamilyIndex = m_spin_queue_family_index; spin_queue_info.queueFamilyIndex = m_spin_queue_family_index;
spin_queue_info.queueCount = 1; spin_queue_info.queueCount = 1;
spin_queue_info.pQueuePriorities = queue_priorities + 1; spin_queue_info.pQueuePriorities = queue_priorities + 2;
} }
device_info.pQueueCreateInfos = queue_infos.data(); device_info.pQueueCreateInfos = queue_infos.data();
@ -655,13 +716,11 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer
vkGetDeviceQueue(m_device, m_graphics_queue_family_index, 0, &m_graphics_queue); vkGetDeviceQueue(m_device, m_graphics_queue_family_index, 0, &m_graphics_queue);
if (surface) if (surface)
{ {
vkGetDeviceQueue(m_device, m_present_queue_family_index, 0, &m_present_queue); vkGetDeviceQueue(m_device, m_present_queue_family_index, present_queue_index, &m_present_queue);
} }
m_spinning_supported = m_spin_queue_family_index != queue_family_count && m_spinning_supported = m_spin_queue_family_index != queue_family_count &&
queue_family_properties[m_graphics_queue_family_index].timestampValidBits > 0 && queue_family_properties[m_graphics_queue_family_index].timestampValidBits > 0 &&
m_device_properties.limits.timestampPeriod > 0; m_device_properties.limits.timestampPeriod > 0;
m_spin_queue_is_graphics_queue =
m_spin_queue_family_index == m_graphics_queue_family_index && spin_queue_index == 0;
m_gpu_timing_supported = (m_device_properties.limits.timestampComputeAndGraphics != 0 && m_gpu_timing_supported = (m_device_properties.limits.timestampComputeAndGraphics != 0 &&
queue_family_properties[m_graphics_queue_family_index].timestampValidBits > 0 && queue_family_properties[m_graphics_queue_family_index].timestampValidBits > 0 &&