[Vulkan] SwapChain: Wait for previous commands to finish before reusing command buffers
This commit is contained in:
parent
56ee88b59d
commit
9c48875a5d
|
@ -355,6 +355,19 @@ VkResult VulkanSwapChain::Initialize(VkSurfaceKHR surface) {
|
||||||
buffers_[i].image_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
buffers_[i].image_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a fence we'll use to wait for commands to finish.
|
||||||
|
VkFenceCreateInfo fence_create_info = {
|
||||||
|
VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
|
||||||
|
nullptr,
|
||||||
|
VK_FENCE_CREATE_SIGNALED_BIT,
|
||||||
|
};
|
||||||
|
status = vkCreateFence(*device_, &fence_create_info, nullptr,
|
||||||
|
&synchronization_fence_);
|
||||||
|
CheckResult(status, "vkGetSwapchainImagesKHR");
|
||||||
|
if (status != VK_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
XELOGVK("Swap chain initialized successfully!");
|
XELOGVK("Swap chain initialized successfully!");
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -445,14 +458,11 @@ void VulkanSwapChain::Shutdown() {
|
||||||
DestroyBuffer(&buffer);
|
DestroyBuffer(&buffer);
|
||||||
}
|
}
|
||||||
buffers_.clear();
|
buffers_.clear();
|
||||||
if (image_available_semaphore_) {
|
|
||||||
vkDestroySemaphore(*device_, image_available_semaphore_, nullptr);
|
VK_SAFE_DESTROY(vkDestroySemaphore, *device_, image_available_semaphore_,
|
||||||
image_available_semaphore_ = nullptr;
|
nullptr);
|
||||||
}
|
VK_SAFE_DESTROY(vkDestroyRenderPass, *device_, render_pass_, nullptr);
|
||||||
if (render_pass_) {
|
|
||||||
vkDestroyRenderPass(*device_, render_pass_, nullptr);
|
|
||||||
render_pass_ = nullptr;
|
|
||||||
}
|
|
||||||
if (copy_cmd_buffer_) {
|
if (copy_cmd_buffer_) {
|
||||||
vkFreeCommandBuffers(*device_, cmd_pool_, 1, ©_cmd_buffer_);
|
vkFreeCommandBuffers(*device_, cmd_pool_, 1, ©_cmd_buffer_);
|
||||||
copy_cmd_buffer_ = nullptr;
|
copy_cmd_buffer_ = nullptr;
|
||||||
|
@ -461,10 +471,8 @@ void VulkanSwapChain::Shutdown() {
|
||||||
vkFreeCommandBuffers(*device_, cmd_pool_, 1, &render_cmd_buffer_);
|
vkFreeCommandBuffers(*device_, cmd_pool_, 1, &render_cmd_buffer_);
|
||||||
render_cmd_buffer_ = nullptr;
|
render_cmd_buffer_ = nullptr;
|
||||||
}
|
}
|
||||||
if (cmd_pool_) {
|
VK_SAFE_DESTROY(vkDestroyCommandPool, *device_, cmd_pool_, nullptr);
|
||||||
vkDestroyCommandPool(*device_, cmd_pool_, nullptr);
|
|
||||||
cmd_pool_ = nullptr;
|
|
||||||
}
|
|
||||||
if (presentation_queue_) {
|
if (presentation_queue_) {
|
||||||
if (!presentation_queue_mutex_) {
|
if (!presentation_queue_mutex_) {
|
||||||
// We own the queue and need to release it.
|
// We own the queue and need to release it.
|
||||||
|
@ -474,15 +482,12 @@ void VulkanSwapChain::Shutdown() {
|
||||||
presentation_queue_mutex_ = nullptr;
|
presentation_queue_mutex_ = nullptr;
|
||||||
presentation_queue_family_ = -1;
|
presentation_queue_family_ = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VK_SAFE_DESTROY(vkDestroyFence, *device_, synchronization_fence_, nullptr);
|
||||||
|
|
||||||
// images_ doesn't need to be cleaned up as the swapchain does it implicitly.
|
// images_ doesn't need to be cleaned up as the swapchain does it implicitly.
|
||||||
if (handle) {
|
VK_SAFE_DESTROY(vkDestroySwapchainKHR, *device_, handle, nullptr);
|
||||||
vkDestroySwapchainKHR(*device_, handle, nullptr);
|
VK_SAFE_DESTROY(vkDestroySurfaceKHR, *instance_, surface_, nullptr);
|
||||||
handle = nullptr;
|
|
||||||
}
|
|
||||||
if (surface_) {
|
|
||||||
vkDestroySurfaceKHR(*instance_, surface_, nullptr);
|
|
||||||
surface_ = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult VulkanSwapChain::Begin() {
|
VkResult VulkanSwapChain::Begin() {
|
||||||
|
@ -490,6 +495,17 @@ VkResult VulkanSwapChain::Begin() {
|
||||||
|
|
||||||
VkResult status;
|
VkResult status;
|
||||||
|
|
||||||
|
// Wait for the last swap to finish.
|
||||||
|
status = vkWaitForFences(*device_, 1, &synchronization_fence_, VK_TRUE, -1);
|
||||||
|
if (status != VK_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = vkResetFences(*device_, 1, &synchronization_fence_);
|
||||||
|
if (status != VK_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the index of the next available swapchain image.
|
// Get the index of the next available swapchain image.
|
||||||
status =
|
status =
|
||||||
vkAcquireNextImageKHR(*device_, handle, 0, image_available_semaphore_,
|
vkAcquireNextImageKHR(*device_, handle, 0, image_available_semaphore_,
|
||||||
|
@ -735,7 +751,8 @@ VkResult VulkanSwapChain::End() {
|
||||||
if (presentation_queue_mutex_) {
|
if (presentation_queue_mutex_) {
|
||||||
presentation_queue_mutex_->lock();
|
presentation_queue_mutex_->lock();
|
||||||
}
|
}
|
||||||
status = vkQueueSubmit(presentation_queue_, 1, &render_submit_info, nullptr);
|
status = vkQueueSubmit(presentation_queue_, 1, &render_submit_info,
|
||||||
|
synchronization_fence_);
|
||||||
if (presentation_queue_mutex_) {
|
if (presentation_queue_mutex_) {
|
||||||
presentation_queue_mutex_->unlock();
|
presentation_queue_mutex_->unlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,7 @@ class VulkanSwapChain {
|
||||||
VulkanInstance* instance_ = nullptr;
|
VulkanInstance* instance_ = nullptr;
|
||||||
VulkanDevice* device_ = nullptr;
|
VulkanDevice* device_ = nullptr;
|
||||||
|
|
||||||
|
VkFence synchronization_fence_ = nullptr;
|
||||||
VkQueue presentation_queue_ = nullptr;
|
VkQueue presentation_queue_ = nullptr;
|
||||||
std::mutex* presentation_queue_mutex_ = nullptr;
|
std::mutex* presentation_queue_mutex_ = nullptr;
|
||||||
uint32_t presentation_queue_family_ = -1;
|
uint32_t presentation_queue_family_ = -1;
|
||||||
|
|
Loading…
Reference in New Issue