Vulkan: Synchronize copies/draws to the swap chain.

Grab RenderDoc after creating the Vulkan instance
This commit is contained in:
Dr. Chat 2016-07-29 10:34:54 -05:00
parent f81a99e83a
commit 72d83591e5
3 changed files with 35 additions and 19 deletions

View File

@ -66,9 +66,6 @@ bool VulkanInstance::Initialize(Window* any_target_window) {
auto version = Version::Parse(VK_API_VERSION); auto version = Version::Parse(VK_API_VERSION);
XELOGVK("Initializing Vulkan %s...", version.pretty_string.c_str()); 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. // Get all of the global layers and extensions provided by the system.
if (!QueryGlobals()) { if (!QueryGlobals()) {
XELOGE("Failed to query instance globals"); XELOGE("Failed to query instance globals");
@ -88,6 +85,9 @@ bool VulkanInstance::Initialize(Window* any_target_window) {
return false; return false;
} }
// Hook into renderdoc, if it's available.
EnableRenderDoc();
XELOGVK("Instance initialized successfully!"); XELOGVK("Instance initialized successfully!");
return true; return true;
} }

View File

@ -177,20 +177,19 @@ bool VulkanSwapChain::Initialize(VkSurfaceKHR surface) {
err = vkCreateCommandPool(*device_, &cmd_pool_info, nullptr, &cmd_pool_); err = vkCreateCommandPool(*device_, &cmd_pool_info, nullptr, &cmd_pool_);
CheckResult(err, "vkCreateCommandPool"); 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; VkCommandBufferAllocateInfo cmd_buffer_info;
cmd_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; cmd_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
cmd_buffer_info.pNext = nullptr; cmd_buffer_info.pNext = nullptr;
cmd_buffer_info.commandPool = cmd_pool_; cmd_buffer_info.commandPool = cmd_pool_;
cmd_buffer_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; cmd_buffer_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
cmd_buffer_info.commandBufferCount = 1; cmd_buffer_info.commandBufferCount = 2;
err = VkCommandBuffer command_buffers[2];
vkAllocateCommandBuffers(*device_, &cmd_buffer_info, &render_cmd_buffer_); err = vkAllocateCommandBuffers(*device_, &cmd_buffer_info, command_buffers);
CheckResult(err, "vkCreateCommandBuffer"); CheckResult(err, "vkCreateCommandBuffer");
// Create another command buffer that handles image copies. render_cmd_buffer_ = command_buffers[0];
err = vkAllocateCommandBuffers(*device_, &cmd_buffer_info, &copy_cmd_buffer_); copy_cmd_buffer_ = command_buffers[1];
CheckResult(err, "vkCreateCommandBuffer");
// Create the render pass used to draw to the swap chain. // Create the render pass used to draw to the swap chain.
// The actual framebuffer attached will depend on which image we are drawing // The actual framebuffer attached will depend on which image we are drawing
@ -243,6 +242,11 @@ bool VulkanSwapChain::Initialize(VkSurfaceKHR surface) {
&image_available_semaphore_); &image_available_semaphore_);
CheckResult(err, "vkCreateSemaphore"); 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. // Get images we will be presenting to.
// Note that this may differ from our requested amount. // Note that this may differ from our requested amount.
uint32_t actual_image_count = 0; uint32_t actual_image_count = 0;
@ -387,8 +391,8 @@ bool VulkanSwapChain::Begin() {
wait_submit_info.commandBufferCount = 0; wait_submit_info.commandBufferCount = 0;
wait_submit_info.pCommandBuffers = nullptr; wait_submit_info.pCommandBuffers = nullptr;
wait_submit_info.signalSemaphoreCount = 0; wait_submit_info.signalSemaphoreCount = 1;
wait_submit_info.pSignalSemaphores = nullptr; wait_submit_info.pSignalSemaphores = &image_usage_semaphore_;
{ {
std::lock_guard<std::mutex> queue_lock(device_->primary_queue_mutex()); std::lock_guard<std::mutex> queue_lock(device_->primary_queue_mutex());
err = err =
@ -515,17 +519,28 @@ bool VulkanSwapChain::End() {
err = vkEndCommandBuffer(copy_cmd_buffer_); err = vkEndCommandBuffer(copy_cmd_buffer_);
CheckResult(err, "vkEndCommandBuffer"); 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; VkSubmitInfo render_submit_info;
render_submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; render_submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
render_submit_info.pNext = nullptr; render_submit_info.pNext = nullptr;
render_submit_info.waitSemaphoreCount = 0; render_submit_info.waitSemaphoreCount = 1;
render_submit_info.pWaitSemaphores = nullptr; render_submit_info.pWaitSemaphores = &image_usage_semaphore_;
render_submit_info.commandBufferCount = render_submit_info.pWaitDstStageMask = &wait_dst_stage;
static_cast<uint32_t>(xe::countof(command_buffers)); render_submit_info.commandBufferCount = 1;
render_submit_info.pCommandBuffers = command_buffers; render_submit_info.pCommandBuffers = &copy_cmd_buffer_;
render_submit_info.signalSemaphoreCount = 1;
render_submit_info.pSignalSemaphores = &image_usage_semaphore_;
{
std::lock_guard<std::mutex> 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.signalSemaphoreCount = 0;
render_submit_info.pSignalSemaphores = nullptr; render_submit_info.pSignalSemaphores = nullptr;
{ {

View File

@ -83,6 +83,7 @@ class VulkanSwapChain {
VkCommandBuffer render_cmd_buffer_ = nullptr; VkCommandBuffer render_cmd_buffer_ = nullptr;
VkRenderPass render_pass_ = nullptr; VkRenderPass render_pass_ = nullptr;
VkSemaphore image_available_semaphore_ = nullptr; VkSemaphore image_available_semaphore_ = nullptr;
VkSemaphore image_usage_semaphore_ = nullptr;
uint32_t current_buffer_index_ = 0; uint32_t current_buffer_index_ = 0;
std::vector<Buffer> buffers_; std::vector<Buffer> buffers_;
}; };