[Vulkan] Create per-swapchain-image present semaphores
Fixes vulkan validation issues.
This commit is contained in:
@@ -75,9 +75,6 @@ VulkanPresenter::PaintContext::Submission::~Submission() {
|
|||||||
dfn.vkDestroyCommandPool(device, draw_command_pool_, nullptr);
|
dfn.vkDestroyCommandPool(device, draw_command_pool_, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (present_semaphore_ != VK_NULL_HANDLE) {
|
|
||||||
dfn.vkDestroySemaphore(device, present_semaphore_, nullptr);
|
|
||||||
}
|
|
||||||
if (acquire_semaphore_ != VK_NULL_HANDLE) {
|
if (acquire_semaphore_ != VK_NULL_HANDLE) {
|
||||||
dfn.vkDestroySemaphore(device, acquire_semaphore_, nullptr);
|
dfn.vkDestroySemaphore(device, acquire_semaphore_, nullptr);
|
||||||
}
|
}
|
||||||
@@ -98,13 +95,6 @@ bool VulkanPresenter::PaintContext::Submission::Initialize() {
|
|||||||
"semaphore");
|
"semaphore");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (dfn.vkCreateSemaphore(device, &semaphore_create_info, nullptr,
|
|
||||||
&present_semaphore_) != VK_SUCCESS) {
|
|
||||||
XELOGE(
|
|
||||||
"VulkanPresenter: Failed to create a swapchain image presentation "
|
|
||||||
"semaphore");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkCommandPoolCreateInfo command_pool_create_info;
|
VkCommandPoolCreateInfo command_pool_create_info;
|
||||||
command_pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
command_pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
@@ -816,6 +806,29 @@ VulkanPresenter::ConnectOrReconnectPaintingToSurfaceFromUIThread(
|
|||||||
paint_context_.swapchain_framebuffers.emplace_back(image_view, framebuffer);
|
paint_context_.swapchain_framebuffers.emplace_back(image_view, framebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create per-swapchain-image present semaphores to avoid
|
||||||
|
// VUID-vkQueueSubmit-pSignalSemaphores-00067 (semaphore reuse before the
|
||||||
|
// previous present completes).
|
||||||
|
paint_context_.swapchain_image_present_semaphores.reserve(
|
||||||
|
paint_context_.swapchain_images.size());
|
||||||
|
VkSemaphoreCreateInfo present_semaphore_create_info;
|
||||||
|
present_semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
|
present_semaphore_create_info.pNext = nullptr;
|
||||||
|
present_semaphore_create_info.flags = 0;
|
||||||
|
for (size_t i = 0; i < paint_context_.swapchain_images.size(); ++i) {
|
||||||
|
VkSemaphore present_semaphore;
|
||||||
|
if (dfn.vkCreateSemaphore(device, &present_semaphore_create_info, nullptr,
|
||||||
|
&present_semaphore) != VK_SUCCESS) {
|
||||||
|
XELOGE(
|
||||||
|
"VulkanPresenter: Failed to create a per-swapchain-image present "
|
||||||
|
"semaphore");
|
||||||
|
paint_context_.DestroySwapchainAndVulkanSurface();
|
||||||
|
return SurfacePaintConnectResult::kFailure;
|
||||||
|
}
|
||||||
|
paint_context_.swapchain_image_present_semaphores.push_back(
|
||||||
|
present_semaphore);
|
||||||
|
}
|
||||||
|
|
||||||
is_vsync_implicit_out = paint_context_.swapchain_is_fifo;
|
is_vsync_implicit_out = paint_context_.swapchain_is_fifo;
|
||||||
return SurfacePaintConnectResult::kSuccess;
|
return SurfacePaintConnectResult::kSuccess;
|
||||||
}
|
}
|
||||||
@@ -1242,6 +1255,13 @@ VkSwapchainKHR VulkanPresenter::PaintContext::CreateSwapchainForVulkanSurface(
|
|||||||
VkSwapchainKHR VulkanPresenter::PaintContext::PrepareForSwapchainRetirement() {
|
VkSwapchainKHR VulkanPresenter::PaintContext::PrepareForSwapchainRetirement() {
|
||||||
if (swapchain != VK_NULL_HANDLE) {
|
if (swapchain != VK_NULL_HANDLE) {
|
||||||
completion_timeline.AwaitAllSubmissions();
|
completion_timeline.AwaitAllSubmissions();
|
||||||
|
// Also wait for the presentation queue since vkQueuePresentKHR doesn't
|
||||||
|
// signal a fence, and the present semaphores may still be in use.
|
||||||
|
if (present_queue_family != UINT32_MAX) {
|
||||||
|
const VulkanDevice::Queue::Acquisition queue_acquisition =
|
||||||
|
vulkan_device->AcquireQueue(present_queue_family, 0);
|
||||||
|
vulkan_device->functions().vkQueueWaitIdle(queue_acquisition.queue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const VulkanDevice::Functions& dfn = vulkan_device->functions();
|
const VulkanDevice::Functions& dfn = vulkan_device->functions();
|
||||||
const VkDevice device = vulkan_device->device();
|
const VkDevice device = vulkan_device->device();
|
||||||
@@ -1250,6 +1270,10 @@ VkSwapchainKHR VulkanPresenter::PaintContext::PrepareForSwapchainRetirement() {
|
|||||||
dfn.vkDestroyImageView(device, framebuffer.image_view, nullptr);
|
dfn.vkDestroyImageView(device, framebuffer.image_view, nullptr);
|
||||||
}
|
}
|
||||||
swapchain_framebuffers.clear();
|
swapchain_framebuffers.clear();
|
||||||
|
for (VkSemaphore present_semaphore : swapchain_image_present_semaphores) {
|
||||||
|
dfn.vkDestroySemaphore(device, present_semaphore, nullptr);
|
||||||
|
}
|
||||||
|
swapchain_image_present_semaphores.clear();
|
||||||
swapchain_images.clear();
|
swapchain_images.clear();
|
||||||
swapchain_extent.width = 0;
|
swapchain_extent.width = 0;
|
||||||
swapchain_extent.height = 0;
|
swapchain_extent.height = 0;
|
||||||
@@ -1386,6 +1410,8 @@ Presenter::PaintResult VulkanPresenter::PaintAndPresentImpl(
|
|||||||
// safe to return early from this function in case of an error.
|
// safe to return early from this function in case of an error.
|
||||||
|
|
||||||
VkSemaphore acquire_semaphore = paint_submission.acquire_semaphore();
|
VkSemaphore acquire_semaphore = paint_submission.acquire_semaphore();
|
||||||
|
|
||||||
|
|
||||||
uint32_t swapchain_image_index;
|
uint32_t swapchain_image_index;
|
||||||
VkResult acquire_result = dfn.vkAcquireNextImageKHR(
|
VkResult acquire_result = dfn.vkAcquireNextImageKHR(
|
||||||
device, paint_context_.swapchain, UINT64_MAX, acquire_semaphore,
|
device, paint_context_.swapchain, UINT64_MAX, acquire_semaphore,
|
||||||
@@ -1997,7 +2023,8 @@ Presenter::PaintResult VulkanPresenter::PaintAndPresentImpl(
|
|||||||
paint_context_.ui_setup_command_buffer_current_index = SIZE_MAX;
|
paint_context_.ui_setup_command_buffer_current_index = SIZE_MAX;
|
||||||
}
|
}
|
||||||
command_buffers[command_buffer_count++] = draw_command_buffer;
|
command_buffers[command_buffer_count++] = draw_command_buffer;
|
||||||
VkSemaphore present_semaphore = paint_submission.present_semaphore();
|
VkSemaphore present_semaphore =
|
||||||
|
paint_context_.swapchain_image_present_semaphores[swapchain_image_index];
|
||||||
VkSubmitInfo submit_info;
|
VkSubmitInfo submit_info;
|
||||||
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
submit_info.pNext = nullptr;
|
submit_info.pNext = nullptr;
|
||||||
|
|||||||
@@ -297,7 +297,6 @@ class VulkanPresenter final : public Presenter {
|
|||||||
~Submission();
|
~Submission();
|
||||||
|
|
||||||
VkSemaphore acquire_semaphore() const { return acquire_semaphore_; }
|
VkSemaphore acquire_semaphore() const { return acquire_semaphore_; }
|
||||||
VkSemaphore present_semaphore() const { return present_semaphore_; }
|
|
||||||
VkCommandPool draw_command_pool() const { return draw_command_pool_; }
|
VkCommandPool draw_command_pool() const { return draw_command_pool_; }
|
||||||
VkCommandBuffer draw_command_buffer() const {
|
VkCommandBuffer draw_command_buffer() const {
|
||||||
return draw_command_buffer_;
|
return draw_command_buffer_;
|
||||||
@@ -310,7 +309,6 @@ class VulkanPresenter final : public Presenter {
|
|||||||
|
|
||||||
const VulkanDevice* vulkan_device_;
|
const VulkanDevice* vulkan_device_;
|
||||||
VkSemaphore acquire_semaphore_ = VK_NULL_HANDLE;
|
VkSemaphore acquire_semaphore_ = VK_NULL_HANDLE;
|
||||||
VkSemaphore present_semaphore_ = VK_NULL_HANDLE;
|
|
||||||
VkCommandPool draw_command_pool_ = VK_NULL_HANDLE;
|
VkCommandPool draw_command_pool_ = VK_NULL_HANDLE;
|
||||||
VkCommandBuffer draw_command_buffer_ = VK_NULL_HANDLE;
|
VkCommandBuffer draw_command_buffer_ = VK_NULL_HANDLE;
|
||||||
};
|
};
|
||||||
@@ -442,6 +440,7 @@ class VulkanPresenter final : public Presenter {
|
|||||||
bool swapchain_is_fifo = false;
|
bool swapchain_is_fifo = false;
|
||||||
std::vector<VkImage> swapchain_images;
|
std::vector<VkImage> swapchain_images;
|
||||||
std::vector<SwapchainFramebuffer> swapchain_framebuffers;
|
std::vector<SwapchainFramebuffer> swapchain_framebuffers;
|
||||||
|
std::vector<VkSemaphore> swapchain_image_present_semaphores;
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit VulkanPresenter(HostGpuLossCallback host_gpu_loss_callback,
|
explicit VulkanPresenter(HostGpuLossCallback host_gpu_loss_callback,
|
||||||
|
|||||||
Reference in New Issue
Block a user