mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-25 07:09:48 -06:00
Merge pull request #6025 from spxtr/present_queue
Vulkan: Use a separate queue for presenting.
This commit is contained in:
@ -352,7 +352,7 @@ void CommandBufferManager::SubmitCommandBuffer(size_t index, VkSemaphore wait_se
|
|||||||
&present_image_index,
|
&present_image_index,
|
||||||
nullptr};
|
nullptr};
|
||||||
|
|
||||||
res = vkQueuePresentKHR(g_vulkan_context->GetGraphicsQueue(), &present_info);
|
res = vkQueuePresentKHR(g_vulkan_context->GetPresentQueue(), &present_info);
|
||||||
if (res != VK_SUCCESS && res != VK_ERROR_OUT_OF_DATE_KHR && res != VK_SUBOPTIMAL_KHR)
|
if (res != VK_SUCCESS && res != VK_ERROR_OUT_OF_DATE_KHR && res != VK_SUBOPTIMAL_KHR)
|
||||||
LOG_VULKAN_ERROR(res, "vkQueuePresentKHR failed: ");
|
LOG_VULKAN_ERROR(res, "vkQueuePresentKHR failed: ");
|
||||||
}
|
}
|
||||||
|
@ -327,7 +327,6 @@ bool SwapChain::CreateSwapChain()
|
|||||||
VkSwapchainKHR old_swap_chain = m_swap_chain;
|
VkSwapchainKHR old_swap_chain = m_swap_chain;
|
||||||
|
|
||||||
// Now we can actually create the swap chain
|
// Now we can actually create the swap chain
|
||||||
// TODO: Handle case where the present queue is not the graphics queue.
|
|
||||||
VkSwapchainCreateInfoKHR swap_chain_info = {VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
|
VkSwapchainCreateInfoKHR swap_chain_info = {VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
|
||||||
nullptr,
|
nullptr,
|
||||||
0,
|
0,
|
||||||
@ -346,6 +345,17 @@ bool SwapChain::CreateSwapChain()
|
|||||||
m_present_mode,
|
m_present_mode,
|
||||||
VK_TRUE,
|
VK_TRUE,
|
||||||
old_swap_chain};
|
old_swap_chain};
|
||||||
|
std::array<uint32_t, 2> indices = {{
|
||||||
|
g_vulkan_context->GetGraphicsQueueFamilyIndex(),
|
||||||
|
g_vulkan_context->GetPresentQueueFamilyIndex(),
|
||||||
|
}};
|
||||||
|
if (g_vulkan_context->GetGraphicsQueueFamilyIndex() !=
|
||||||
|
g_vulkan_context->GetPresentQueueFamilyIndex())
|
||||||
|
{
|
||||||
|
swap_chain_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||||
|
swap_chain_info.queueFamilyIndexCount = 2;
|
||||||
|
swap_chain_info.pQueueFamilyIndices = indices.data();
|
||||||
|
}
|
||||||
|
|
||||||
res =
|
res =
|
||||||
vkCreateSwapchainKHR(g_vulkan_context->GetDevice(), &swap_chain_info, nullptr, &m_swap_chain);
|
vkCreateSwapchainKHR(g_vulkan_context->GetDevice(), &swap_chain_info, nullptr, &m_swap_chain);
|
||||||
|
@ -494,36 +494,41 @@ bool VulkanContext::CreateDevice(VkSurfaceKHR surface, bool enable_validation_la
|
|||||||
queue_family_properties.data());
|
queue_family_properties.data());
|
||||||
INFO_LOG(VIDEO, "%u vulkan queue families", queue_family_count);
|
INFO_LOG(VIDEO, "%u vulkan queue families", queue_family_count);
|
||||||
|
|
||||||
// Find a graphics queue
|
// Find graphics and present queues.
|
||||||
// Currently we only use a single queue for both graphics and presenting.
|
|
||||||
// TODO: In the future we could do post-processing and presenting on a different queue.
|
|
||||||
m_graphics_queue_family_index = queue_family_count;
|
m_graphics_queue_family_index = queue_family_count;
|
||||||
|
m_present_queue_family_index = queue_family_count;
|
||||||
for (uint32_t i = 0; i < queue_family_count; i++)
|
for (uint32_t i = 0; i < queue_family_count; i++)
|
||||||
{
|
{
|
||||||
if (queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
VkBool32 graphics_supported = queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT;
|
||||||
|
if (graphics_supported)
|
||||||
{
|
{
|
||||||
// Check that it can present to our surface from this queue
|
m_graphics_queue_family_index = i;
|
||||||
if (surface)
|
// Quit now, no need for a present queue.
|
||||||
|
if (!surface)
|
||||||
{
|
{
|
||||||
VkBool32 present_supported;
|
break;
|
||||||
VkResult res =
|
|
||||||
vkGetPhysicalDeviceSurfaceSupportKHR(m_physical_device, i, surface, &present_supported);
|
|
||||||
if (res != VK_SUCCESS)
|
|
||||||
{
|
|
||||||
LOG_VULKAN_ERROR(res, "vkGetPhysicalDeviceSurfaceSupportKHR failed: ");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (present_supported)
|
|
||||||
{
|
|
||||||
m_graphics_queue_family_index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if (surface)
|
||||||
|
{
|
||||||
|
VkBool32 present_supported;
|
||||||
|
VkResult res =
|
||||||
|
vkGetPhysicalDeviceSurfaceSupportKHR(m_physical_device, i, surface, &present_supported);
|
||||||
|
if (res != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
LOG_VULKAN_ERROR(res, "vkGetPhysicalDeviceSurfaceSupportKHR failed: ");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (present_supported)
|
||||||
|
{
|
||||||
|
m_present_queue_family_index = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prefer one queue family index that does both graphics and present.
|
||||||
|
if (graphics_supported && present_supported)
|
||||||
{
|
{
|
||||||
// We don't need present, so any graphics queue will do.
|
|
||||||
m_graphics_queue_family_index = i;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -533,6 +538,11 @@ bool VulkanContext::CreateDevice(VkSurfaceKHR surface, bool enable_validation_la
|
|||||||
ERROR_LOG(VIDEO, "Vulkan: Failed to find an acceptable graphics queue.");
|
ERROR_LOG(VIDEO, "Vulkan: Failed to find an acceptable graphics queue.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (surface && m_present_queue_family_index == queue_family_count)
|
||||||
|
{
|
||||||
|
ERROR_LOG(VIDEO, "Vulkan: Failed to find an acceptable present queue.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
VkDeviceCreateInfo device_info = {};
|
VkDeviceCreateInfo device_info = {};
|
||||||
device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
@ -540,15 +550,32 @@ bool VulkanContext::CreateDevice(VkSurfaceKHR surface, bool enable_validation_la
|
|||||||
device_info.flags = 0;
|
device_info.flags = 0;
|
||||||
|
|
||||||
static constexpr float queue_priorities[] = {1.0f};
|
static constexpr float queue_priorities[] = {1.0f};
|
||||||
VkDeviceQueueCreateInfo queue_info = {};
|
VkDeviceQueueCreateInfo graphics_queue_info = {};
|
||||||
queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
graphics_queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
queue_info.pNext = nullptr;
|
graphics_queue_info.pNext = nullptr;
|
||||||
queue_info.flags = 0;
|
graphics_queue_info.flags = 0;
|
||||||
queue_info.queueFamilyIndex = m_graphics_queue_family_index;
|
graphics_queue_info.queueFamilyIndex = m_graphics_queue_family_index;
|
||||||
queue_info.queueCount = 1;
|
graphics_queue_info.queueCount = 1;
|
||||||
queue_info.pQueuePriorities = queue_priorities;
|
graphics_queue_info.pQueuePriorities = queue_priorities;
|
||||||
|
|
||||||
|
VkDeviceQueueCreateInfo present_queue_info = {};
|
||||||
|
present_queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
|
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.pQueuePriorities = queue_priorities;
|
||||||
|
|
||||||
|
std::array<VkDeviceQueueCreateInfo, 2> queue_infos = {{
|
||||||
|
graphics_queue_info, present_queue_info,
|
||||||
|
}};
|
||||||
|
|
||||||
device_info.queueCreateInfoCount = 1;
|
device_info.queueCreateInfoCount = 1;
|
||||||
device_info.pQueueCreateInfos = &queue_info;
|
if (m_graphics_queue_family_index != m_present_queue_family_index)
|
||||||
|
{
|
||||||
|
device_info.queueCreateInfoCount = 2;
|
||||||
|
}
|
||||||
|
device_info.pQueueCreateInfos = queue_infos.data();
|
||||||
|
|
||||||
ExtensionList enabled_extensions;
|
ExtensionList enabled_extensions;
|
||||||
if (!SelectDeviceExtensions(&enabled_extensions, surface != VK_NULL_HANDLE))
|
if (!SelectDeviceExtensions(&enabled_extensions, surface != VK_NULL_HANDLE))
|
||||||
@ -584,8 +611,12 @@ bool VulkanContext::CreateDevice(VkSurfaceKHR surface, bool enable_validation_la
|
|||||||
if (!LoadVulkanDeviceFunctions(m_device))
|
if (!LoadVulkanDeviceFunctions(m_device))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Grab the graphics queue (only one we're using at this point).
|
// Grab the graphics and present queues.
|
||||||
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)
|
||||||
|
{
|
||||||
|
vkGetDeviceQueue(m_device, m_present_queue_family_index, 0, &m_present_queue);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +57,8 @@ public:
|
|||||||
VkDevice GetDevice() const { return m_device; }
|
VkDevice GetDevice() const { return m_device; }
|
||||||
VkQueue GetGraphicsQueue() const { return m_graphics_queue; }
|
VkQueue GetGraphicsQueue() const { return m_graphics_queue; }
|
||||||
u32 GetGraphicsQueueFamilyIndex() const { return m_graphics_queue_family_index; }
|
u32 GetGraphicsQueueFamilyIndex() const { return m_graphics_queue_family_index; }
|
||||||
|
VkQueue GetPresentQueue() const { return m_present_queue; }
|
||||||
|
u32 GetPresentQueueFamilyIndex() const { return m_present_queue_family_index; }
|
||||||
const VkQueueFamilyProperties& GetGraphicsQueueProperties() const
|
const VkQueueFamilyProperties& GetGraphicsQueueProperties() const
|
||||||
{
|
{
|
||||||
return m_graphics_queue_properties;
|
return m_graphics_queue_properties;
|
||||||
@ -119,6 +121,8 @@ private:
|
|||||||
|
|
||||||
VkQueue m_graphics_queue = VK_NULL_HANDLE;
|
VkQueue m_graphics_queue = VK_NULL_HANDLE;
|
||||||
u32 m_graphics_queue_family_index = 0;
|
u32 m_graphics_queue_family_index = 0;
|
||||||
|
VkQueue m_present_queue = VK_NULL_HANDLE;
|
||||||
|
u32 m_present_queue_family_index = 0;
|
||||||
VkQueueFamilyProperties m_graphics_queue_properties = {};
|
VkQueueFamilyProperties m_graphics_queue_properties = {};
|
||||||
|
|
||||||
VkDebugReportCallbackEXT m_debug_report_callback = VK_NULL_HANDLE;
|
VkDebugReportCallbackEXT m_debug_report_callback = VK_NULL_HANDLE;
|
||||||
|
Reference in New Issue
Block a user