diff --git a/src/xenia/ui/vulkan/vulkan_instance.cc b/src/xenia/ui/vulkan/vulkan_instance.cc index f6b43644c..d5a8da8f7 100644 --- a/src/xenia/ui/vulkan/vulkan_instance.cc +++ b/src/xenia/ui/vulkan/vulkan_instance.cc @@ -66,9 +66,6 @@ bool VulkanInstance::Initialize(Window* any_target_window) { auto version = Version::Parse(VK_API_VERSION); XELOGVK("Initializing Vulkan %s...", version.pretty_string.c_str()); - // Hook into renderdoc, if it's available. - EnableRenderDoc(); - // Get all of the global layers and extensions provided by the system. if (!QueryGlobals()) { XELOGE("Failed to query instance globals"); @@ -88,6 +85,9 @@ bool VulkanInstance::Initialize(Window* any_target_window) { return false; } + // Hook into renderdoc, if it's available. + EnableRenderDoc(); + XELOGVK("Instance initialized successfully!"); return true; } diff --git a/src/xenia/ui/vulkan/vulkan_swap_chain.cc b/src/xenia/ui/vulkan/vulkan_swap_chain.cc index ab32c2837..f4273bb72 100644 --- a/src/xenia/ui/vulkan/vulkan_swap_chain.cc +++ b/src/xenia/ui/vulkan/vulkan_swap_chain.cc @@ -177,20 +177,19 @@ bool VulkanSwapChain::Initialize(VkSurfaceKHR surface) { err = vkCreateCommandPool(*device_, &cmd_pool_info, nullptr, &cmd_pool_); CheckResult(err, "vkCreateCommandPool"); - // Make a command buffer we'll do all our primary rendering from. + // Make two command buffers we'll do all our primary rendering from. VkCommandBufferAllocateInfo cmd_buffer_info; cmd_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; cmd_buffer_info.pNext = nullptr; cmd_buffer_info.commandPool = cmd_pool_; cmd_buffer_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - cmd_buffer_info.commandBufferCount = 1; - err = - vkAllocateCommandBuffers(*device_, &cmd_buffer_info, &render_cmd_buffer_); + cmd_buffer_info.commandBufferCount = 2; + VkCommandBuffer command_buffers[2]; + err = vkAllocateCommandBuffers(*device_, &cmd_buffer_info, command_buffers); CheckResult(err, "vkCreateCommandBuffer"); - // Create another command buffer that handles image copies. - err = vkAllocateCommandBuffers(*device_, &cmd_buffer_info, ©_cmd_buffer_); - CheckResult(err, "vkCreateCommandBuffer"); + render_cmd_buffer_ = command_buffers[0]; + copy_cmd_buffer_ = command_buffers[1]; // Create the render pass used to draw to the swap chain. // The actual framebuffer attached will depend on which image we are drawing @@ -243,6 +242,11 @@ bool VulkanSwapChain::Initialize(VkSurfaceKHR surface) { &image_available_semaphore_); CheckResult(err, "vkCreateSemaphore"); + // Create another semaphore used to synchronize writes to the swap image. + err = vkCreateSemaphore(*device_, &semaphore_info, nullptr, + &image_usage_semaphore_); + CheckResult(err, "vkCreateSemaphore"); + // Get images we will be presenting to. // Note that this may differ from our requested amount. uint32_t actual_image_count = 0; @@ -387,8 +391,8 @@ bool VulkanSwapChain::Begin() { wait_submit_info.commandBufferCount = 0; wait_submit_info.pCommandBuffers = nullptr; - wait_submit_info.signalSemaphoreCount = 0; - wait_submit_info.pSignalSemaphores = nullptr; + wait_submit_info.signalSemaphoreCount = 1; + wait_submit_info.pSignalSemaphores = &image_usage_semaphore_; { std::lock_guard queue_lock(device_->primary_queue_mutex()); err = @@ -515,17 +519,28 @@ bool VulkanSwapChain::End() { err = vkEndCommandBuffer(copy_cmd_buffer_); CheckResult(err, "vkEndCommandBuffer"); - VkCommandBuffer command_buffers[] = {copy_cmd_buffer_, render_cmd_buffer_}; + VkPipelineStageFlags wait_dst_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - // Submit rendering. + // Submit copy commands. VkSubmitInfo render_submit_info; render_submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; render_submit_info.pNext = nullptr; - render_submit_info.waitSemaphoreCount = 0; - render_submit_info.pWaitSemaphores = nullptr; - render_submit_info.commandBufferCount = - static_cast(xe::countof(command_buffers)); - render_submit_info.pCommandBuffers = command_buffers; + render_submit_info.waitSemaphoreCount = 1; + render_submit_info.pWaitSemaphores = &image_usage_semaphore_; + render_submit_info.pWaitDstStageMask = &wait_dst_stage; + render_submit_info.commandBufferCount = 1; + render_submit_info.pCommandBuffers = ©_cmd_buffer_; + render_submit_info.signalSemaphoreCount = 1; + render_submit_info.pSignalSemaphores = &image_usage_semaphore_; + { + std::lock_guard queue_lock(device_->primary_queue_mutex()); + err = vkQueueSubmit(device_->primary_queue(), 1, &render_submit_info, + nullptr); + } + + // Submit render commands. + render_submit_info.commandBufferCount = 1; + render_submit_info.pCommandBuffers = &render_cmd_buffer_; render_submit_info.signalSemaphoreCount = 0; render_submit_info.pSignalSemaphores = nullptr; { diff --git a/src/xenia/ui/vulkan/vulkan_swap_chain.h b/src/xenia/ui/vulkan/vulkan_swap_chain.h index 773a52053..fe2c0b038 100644 --- a/src/xenia/ui/vulkan/vulkan_swap_chain.h +++ b/src/xenia/ui/vulkan/vulkan_swap_chain.h @@ -83,6 +83,7 @@ class VulkanSwapChain { VkCommandBuffer render_cmd_buffer_ = nullptr; VkRenderPass render_pass_ = nullptr; VkSemaphore image_available_semaphore_ = nullptr; + VkSemaphore image_usage_semaphore_ = nullptr; uint32_t current_buffer_index_ = 0; std::vector buffers_; };