summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorStenzek <stenzek@users.noreply.github.com>2017-09-06 18:32:43 +1000
committerGitHub <noreply@github.com>2017-09-06 18:32:43 +1000
commit2e20cd0ffdfb909a52a70217474fa5b53bd12996 (patch)
tree559a4d64b6da3be1ee1565dfa8ea8f2da95af216 /Source/Core
parent92e5f5c5684c0ef4fac55497e939e21336eb14cb (diff)
parenta5be5a3a765207b55b16661cc182e5c5bbbf55de (diff)
Merge pull request #6025 from spxtr/present_queue
Vulkan: Use a separate queue for presenting.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp2
-rw-r--r--Source/Core/VideoBackends/Vulkan/SwapChain.cpp12
-rw-r--r--Source/Core/VideoBackends/Vulkan/VulkanContext.cpp95
-rw-r--r--Source/Core/VideoBackends/Vulkan/VulkanContext.h4
4 files changed, 79 insertions, 34 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp b/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp
index 19ebbf3cb7..350757194e 100644
--- a/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp
+++ b/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp
@@ -352,7 +352,7 @@ void CommandBufferManager::SubmitCommandBuffer(size_t index, VkSemaphore wait_se
&present_image_index,
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)
LOG_VULKAN_ERROR(res, "vkQueuePresentKHR failed: ");
}
diff --git a/Source/Core/VideoBackends/Vulkan/SwapChain.cpp b/Source/Core/VideoBackends/Vulkan/SwapChain.cpp
index 21009510bb..c5b3791637 100644
--- a/Source/Core/VideoBackends/Vulkan/SwapChain.cpp
+++ b/Source/Core/VideoBackends/Vulkan/SwapChain.cpp
@@ -327,7 +327,6 @@ bool SwapChain::CreateSwapChain()
VkSwapchainKHR old_swap_chain = m_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,
nullptr,
0,
@@ -346,6 +345,17 @@ bool SwapChain::CreateSwapChain()
m_present_mode,
VK_TRUE,
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 =
vkCreateSwapchainKHR(g_vulkan_context->GetDevice(), &swap_chain_info, nullptr, &m_swap_chain);
diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp
index 8bb7a5088e..9258a28f6f 100644
--- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp
@@ -494,36 +494,41 @@ bool VulkanContext::CreateDevice(VkSurfaceKHR surface, bool enable_validation_la
queue_family_properties.data());
INFO_LOG(VIDEO, "%u vulkan queue families", queue_family_count);
- // Find a graphics queue
- // 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.
+ // Find graphics and present queues.
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++)
{
- 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
- if (surface)
+ m_graphics_queue_family_index = i;
+ // Quit now, no need for a present queue.
+ 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_graphics_queue_family_index = i;
- break;
- }
+ break;
+ }
+ }
+
+ 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;
}
- else
+
+ // 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;
}
}
@@ -533,6 +538,11 @@ bool VulkanContext::CreateDevice(VkSurfaceKHR surface, bool enable_validation_la
ERROR_LOG(VIDEO, "Vulkan: Failed to find an acceptable graphics queue.");
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 = {};
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;
static constexpr float queue_priorities[] = {1.0f};
- VkDeviceQueueCreateInfo queue_info = {};
- queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- queue_info.pNext = nullptr;
- queue_info.flags = 0;
- queue_info.queueFamilyIndex = m_graphics_queue_family_index;
- queue_info.queueCount = 1;
- queue_info.pQueuePriorities = queue_priorities;
+ VkDeviceQueueCreateInfo graphics_queue_info = {};
+ 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.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.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;
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))
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);
+ if (surface)
+ {
+ vkGetDeviceQueue(m_device, m_present_queue_family_index, 0, &m_present_queue);
+ }
return true;
}
diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.h b/Source/Core/VideoBackends/Vulkan/VulkanContext.h
index 17a4a25d2c..fd504560b8 100644
--- a/Source/Core/VideoBackends/Vulkan/VulkanContext.h
+++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.h
@@ -57,6 +57,8 @@ public:
VkDevice GetDevice() const { return m_device; }
VkQueue GetGraphicsQueue() const { return m_graphics_queue; }
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
{
return m_graphics_queue_properties;
@@ -119,6 +121,8 @@ private:
VkQueue m_graphics_queue = VK_NULL_HANDLE;
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 = {};
VkDebugReportCallbackEXT m_debug_report_callback = VK_NULL_HANDLE;