Skip to content
Permalink
Browse files
Merge pull request #6025 from spxtr/present_queue
Vulkan: Use a separate queue for presenting.
  • Loading branch information
stenzek committed Sep 6, 2017
2 parents 92e5f5c + a5be5a3 commit 2e20cd0
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 34 deletions.
@@ -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: ");
}
@@ -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);
@@ -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,22 +538,44 @@ 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;
device_info.pNext = nullptr;
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;
}

@@ -57,6 +57,8 @@ class VulkanContext
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 @@ class VulkanContext

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;

0 comments on commit 2e20cd0

Please sign in to comment.