mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-12-16 04:08:48 +00:00
Merge c74e043827 into a33612cf7d
This commit is contained in:
commit
1f5d410114
@ -463,26 +463,72 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(m_physical_device, &queue_family_count, queue_family_properties.data());
|
||||
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_present_queue_family_index = queue_family_count;
|
||||
u32 present_queue_index = 0;
|
||||
m_spin_queue_family_index = queue_family_count;
|
||||
u32 spin_queue_index = 0;
|
||||
|
||||
// Graphics Queue
|
||||
for (uint32_t i = 0; i < queue_family_count; i++)
|
||||
{
|
||||
VkBool32 graphics_supported = queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT;
|
||||
if (graphics_supported)
|
||||
if (queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
||||
{
|
||||
m_graphics_queue_family_index = i;
|
||||
// Quit now, no need for a present queue.
|
||||
if (!surface)
|
||||
{
|
||||
break;
|
||||
}
|
||||
queue_family_users[i]++;
|
||||
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;
|
||||
VkResult res = vkGetPhysicalDeviceSurfaceSupportKHR(m_physical_device, i, surface, &present_supported);
|
||||
if (res != VK_SUCCESS)
|
||||
@ -491,35 +537,48 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer
|
||||
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;
|
||||
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 (graphics_supported && present_supported)
|
||||
if (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++)
|
||||
{
|
||||
// Pick a queue for spinning
|
||||
if (!(queue_family_properties[i].queueFlags & VK_QUEUE_COMPUTE_BIT))
|
||||
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
|
||||
}
|
||||
|
||||
// Swap spin and present to simplify queue priorities logic.
|
||||
if (!m_spin_queue_is_graphics_queue && m_present_queue_family_index == m_spin_queue_family_index)
|
||||
std::swap(spin_queue_index, present_queue_index);
|
||||
|
||||
if (m_graphics_queue_family_index == queue_family_count)
|
||||
{
|
||||
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.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;
|
||||
VkDeviceQueueCreateInfo& graphics_queue_info = queue_infos[device_info.queueCreateInfoCount++];
|
||||
graphics_queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
graphics_queue_info.pNext = nullptr;
|
||||
graphics_queue_info.flags = 0;
|
||||
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;
|
||||
|
||||
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.flags = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
if (m_spin_queue_family_index == m_graphics_queue_family_index)
|
||||
{
|
||||
if (spin_queue_index != 0)
|
||||
graphics_queue_info.queueCount = 2;
|
||||
if (spin_queue_index == 1)
|
||||
graphics_queue_info.pQueuePriorities = queue_priorities + 1;
|
||||
}
|
||||
else if (m_spin_queue_family_index == m_present_queue_family_index)
|
||||
{
|
||||
if (spin_queue_index != 0)
|
||||
queue_infos[1].queueCount = 2; // present queue
|
||||
if (spin_queue_index == 1)
|
||||
queue_infos[1].pQueuePriorities = queue_priorities + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -576,7 +637,7 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer
|
||||
spin_queue_info.flags = 0;
|
||||
spin_queue_info.queueFamilyIndex = m_spin_queue_family_index;
|
||||
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();
|
||||
@ -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);
|
||||
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 &&
|
||||
queue_family_properties[m_graphics_queue_family_index].timestampValidBits > 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 &&
|
||||
queue_family_properties[m_graphics_queue_family_index].timestampValidBits > 0 &&
|
||||
|
||||
Loading…
Reference in New Issue
Block a user