mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-22 07:24:34 +00:00
TEMP: Try to use 2 locks for swapchain resizing example
This commit is contained in:
parent
4a30810a87
commit
0b7529d0da
@ -22,10 +22,11 @@ std::atomic_bool should_resize;
|
|||||||
uint32_t current_width = default_window_width;
|
uint32_t current_width = default_window_width;
|
||||||
uint32_t current_height = default_window_height;
|
uint32_t current_height = default_window_height;
|
||||||
|
|
||||||
std::mutex main_mutex;
|
std::mutex swapchain_mutex;
|
||||||
|
std::mutex render_mutex;
|
||||||
|
|
||||||
std::mutex render_wait_mutex;
|
std::mutex render_thread_sleep_mutex;
|
||||||
std::condition_variable render_wait_condition_variable;
|
std::condition_variable render_thread_sleep_condition_variable;
|
||||||
|
|
||||||
const bool run_multithreaded = true;
|
const bool run_multithreaded = true;
|
||||||
const bool use_refresh_callback = true;
|
const bool use_refresh_callback = true;
|
||||||
@ -46,6 +47,8 @@ struct Renderer {
|
|||||||
|
|
||||||
vkb::SwapchainManager swapchain_manager;
|
vkb::SwapchainManager swapchain_manager;
|
||||||
vkb::SwapchainInfo swap_info;
|
vkb::SwapchainInfo swap_info;
|
||||||
|
// where to place the new framebuffer when a resize event happens
|
||||||
|
VkFramebuffer new_framebuffer = VK_NULL_HANDLE;
|
||||||
|
|
||||||
vkb::DeletionQueue delete_queue;
|
vkb::DeletionQueue delete_queue;
|
||||||
|
|
||||||
@ -73,7 +76,7 @@ void unlock(std::mutex& mutex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int recreate_swapchain(Renderer& renderer);
|
int recreate_swapchain(Renderer& renderer);
|
||||||
int draw_frame(Renderer& renderer);
|
int draw_frame(Renderer& renderer, bool try_lock);
|
||||||
|
|
||||||
void glfw_resize_callback(GLFWwindow* window, int width, int height) {
|
void glfw_resize_callback(GLFWwindow* window, int width, int height) {
|
||||||
if (!is_running || width == 0 || height == 0) {
|
if (!is_running || width == 0 || height == 0) {
|
||||||
@ -82,8 +85,6 @@ void glfw_resize_callback(GLFWwindow* window, int width, int height) {
|
|||||||
should_resize = true;
|
should_resize = true;
|
||||||
current_width = width;
|
current_width = width;
|
||||||
current_height = height;
|
current_height = height;
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lg(main_mutex);
|
|
||||||
Renderer* renderer = reinterpret_cast<Renderer*>(glfwGetWindowUserPointer(window));
|
Renderer* renderer = reinterpret_cast<Renderer*>(glfwGetWindowUserPointer(window));
|
||||||
int res = recreate_swapchain(*renderer);
|
int res = recreate_swapchain(*renderer);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
@ -91,23 +92,23 @@ void glfw_resize_callback(GLFWwindow* window, int width, int height) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!use_refresh_callback) {
|
if (!use_refresh_callback) {
|
||||||
res = draw_frame(*renderer);
|
res = draw_frame(*renderer, false);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
is_running = false;
|
is_running = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
should_resize = false;
|
should_resize = false;
|
||||||
render_wait_condition_variable.notify_one();
|
render_thread_sleep_condition_variable.notify_one();
|
||||||
}
|
}
|
||||||
void glfw_refresh_callback(GLFWwindow* window) {
|
void glfw_refresh_callback(GLFWwindow* window) {
|
||||||
if (try_lock(main_mutex)) {
|
// if (try_lock(render_mutex)) {
|
||||||
Renderer* renderer = reinterpret_cast<Renderer*>(glfwGetWindowUserPointer(window));
|
Renderer* renderer = reinterpret_cast<Renderer*>(glfwGetWindowUserPointer(window));
|
||||||
int res = draw_frame(*renderer);
|
int res = draw_frame(*renderer, true);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
is_running = false;
|
is_running = false;
|
||||||
}
|
|
||||||
unlock(main_mutex);
|
|
||||||
}
|
}
|
||||||
|
// unlock(render_mutex);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
inline VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
inline VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||||
@ -240,15 +241,14 @@ int create_render_pass(Renderer& renderer) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int create_framebuffer(Renderer& renderer) {
|
int create_framebuffer(Renderer& renderer, VkFramebuffer& output) {
|
||||||
|
|
||||||
vkb::ImagelessFramebufferBuilder if_builder(renderer.device);
|
vkb::ImagelessFramebufferBuilder if_builder(renderer.device);
|
||||||
renderer.framebuffer =
|
output = if_builder.set_renderpass(renderer.render_pass)
|
||||||
if_builder.set_renderpass(renderer.render_pass)
|
.set_extent(renderer.swap_info.extent)
|
||||||
.set_extent(renderer.swap_info.extent)
|
.set_layers(1)
|
||||||
.set_layers(1)
|
.add_attachment(renderer.swap_info.image_usage_flags, renderer.swap_info.image_format)
|
||||||
.add_attachment(renderer.swap_info.image_usage_flags, renderer.swap_info.image_format)
|
.build();
|
||||||
.build();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -507,41 +507,59 @@ int record_command_buffer(Renderer& renderer, VkCommandBuffer command_buffer, Vk
|
|||||||
}
|
}
|
||||||
|
|
||||||
int recreate_swapchain(Renderer& renderer) {
|
int recreate_swapchain(Renderer& renderer) {
|
||||||
renderer.delete_queue.add_framebuffer(renderer.framebuffer);
|
std::lock_guard<std::mutex> lg(swapchain_mutex);
|
||||||
renderer.framebuffer = VK_NULL_HANDLE;
|
|
||||||
auto ret = renderer.swapchain_manager.recreate();
|
auto ret = renderer.swapchain_manager.recreate();
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
std::cout << "failed to recreate swapchain\n";
|
std::cout << "failed to recreate swapchain\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
renderer.swap_info = ret.value();
|
renderer.swap_info = ret.value();
|
||||||
if (0 != create_framebuffer(renderer)) return -1;
|
if (renderer.new_framebuffer != VK_NULL_HANDLE) {
|
||||||
|
renderer.delete_queue.add_framebuffer(renderer.new_framebuffer);
|
||||||
|
}
|
||||||
|
if (0 != create_framebuffer(renderer, renderer.new_framebuffer)) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int draw_frame(Renderer& renderer) {
|
int draw_frame(Renderer& renderer, bool try_lock) {
|
||||||
|
std::unique_lock<std::mutex> lg(render_mutex, std::try_to_lock);
|
||||||
vkb::SwapchainAcquireInfo acquire_info;
|
if (!try_lock && !lg.owns_lock()) {
|
||||||
auto acquire_ret = renderer.swapchain_manager.acquire_image();
|
lg.lock();
|
||||||
if (acquire_ret.matches_error(vkb::SwapchainManagerError::swapchain_out_of_date)) {
|
} else if (!lg.owns_lock()) {
|
||||||
return 1;
|
return 0;
|
||||||
} else if (!acquire_ret.has_value()) {
|
|
||||||
std::cout << "failed to acquire swapchain image\n";
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
vkb::SwapchainAcquireInfo acquire_info;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> slg(swapchain_mutex);
|
||||||
|
// swap old framebuffer with new one now that both locks are held
|
||||||
|
if (renderer.new_framebuffer != VK_NULL_HANDLE) {
|
||||||
|
renderer.delete_queue.add_framebuffer(renderer.framebuffer);
|
||||||
|
renderer.framebuffer = renderer.new_framebuffer;
|
||||||
|
renderer.new_framebuffer = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
acquire_info = acquire_ret.value();
|
auto acquire_ret = renderer.swapchain_manager.acquire_image();
|
||||||
if (should_resize) return 1;
|
if (acquire_ret.matches_error(vkb::SwapchainManagerError::swapchain_out_of_date)) {
|
||||||
|
return 1;
|
||||||
|
} else if (!acquire_ret.has_value()) {
|
||||||
|
std::cout << "failed to acquire swapchain image\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
acquire_info = acquire_ret.value();
|
||||||
|
}
|
||||||
|
if (should_resize) {
|
||||||
|
renderer.swapchain_manager.cancel_acquire_frame();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
renderer.dispatch.waitForFences(1, &renderer.fences[renderer.current_index], VK_TRUE, UINT64_MAX);
|
renderer.dispatch.waitForFences(1, &renderer.fences[renderer.current_index], VK_TRUE, UINT64_MAX);
|
||||||
renderer.dispatch.resetFences(1, &renderer.fences[renderer.current_index]);
|
renderer.dispatch.resetFences(1, &renderer.fences[renderer.current_index]);
|
||||||
|
|
||||||
record_command_buffer(renderer, renderer.command_buffers[renderer.current_index], acquire_info.image_view);
|
record_command_buffer(renderer, renderer.command_buffers[renderer.current_index], acquire_info.image_view);
|
||||||
|
|
||||||
auto semaphores = renderer.swapchain_manager.get_submit_semaphores().value();
|
VkSemaphore wait_semaphores[1] = { acquire_info.wait_semaphore };
|
||||||
|
VkSemaphore signal_semaphores[1] = { acquire_info.signal_semaphore };
|
||||||
VkSemaphore wait_semaphores[1] = { semaphores.wait };
|
|
||||||
VkSemaphore signal_semaphores[1] = { semaphores.signal };
|
|
||||||
VkPipelineStageFlags wait_stages[1] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
VkPipelineStageFlags wait_stages[1] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||||
|
|
||||||
VkSubmitInfo submit_info = {};
|
VkSubmitInfo submit_info = {};
|
||||||
@ -554,21 +572,31 @@ int draw_frame(Renderer& renderer) {
|
|||||||
submit_info.signalSemaphoreCount = 1;
|
submit_info.signalSemaphoreCount = 1;
|
||||||
submit_info.pSignalSemaphores = signal_semaphores;
|
submit_info.pSignalSemaphores = signal_semaphores;
|
||||||
|
|
||||||
if (renderer.dispatch.queueSubmit(
|
VkResult res = renderer.dispatch.queueSubmit(
|
||||||
renderer.graphics_queue, 1, &submit_info, renderer.fences[renderer.current_index]) != VK_SUCCESS) {
|
renderer.graphics_queue, 1, &submit_info, renderer.fences[renderer.current_index]);
|
||||||
std::cout << "failed to submit command buffer\n";
|
if (res != VK_SUCCESS) {
|
||||||
|
std::cout << "failed to submit command buffer" << res << "\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
renderer.current_index = (renderer.current_index + 1) % MAX_FRAMES_IN_FLIGHT;
|
renderer.current_index = (renderer.current_index + 1) % MAX_FRAMES_IN_FLIGHT;
|
||||||
if (should_resize) return 1;
|
|
||||||
|
|
||||||
auto present_ret = renderer.swapchain_manager.present();
|
if (should_resize) {
|
||||||
|
renderer.swapchain_manager.cancel_present_frame();
|
||||||
if (present_ret.matches_error(vkb::SwapchainManagerError::swapchain_out_of_date)) {
|
|
||||||
return 1;
|
return 1;
|
||||||
} else if (!present_ret) {
|
}
|
||||||
std::cout << "failed to present swapchain image\n";
|
{
|
||||||
return -1;
|
std::lock_guard<std::mutex> slg(swapchain_mutex);
|
||||||
|
if (!renderer.swapchain_manager.able_to_present()) {
|
||||||
|
renderer.swapchain_manager.cancel_present_frame();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto present_ret = renderer.swapchain_manager.present();
|
||||||
|
if (present_ret.matches_error(vkb::SwapchainManagerError::swapchain_out_of_date)) {
|
||||||
|
return 1;
|
||||||
|
} else if (!present_ret) {
|
||||||
|
std::cout << "failed to present swapchain image " << present_ret.error().message() << "\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
renderer.delete_queue.tick();
|
renderer.delete_queue.tick();
|
||||||
renderer.current_time = glfwGetTime();
|
renderer.current_time = glfwGetTime();
|
||||||
@ -600,21 +628,14 @@ void cleanup(Renderer& renderer) {
|
|||||||
|
|
||||||
void render_loop(Renderer* renderer) {
|
void render_loop(Renderer* renderer) {
|
||||||
while (is_running) {
|
while (is_running) {
|
||||||
std::unique_lock<std::mutex> lg(main_mutex, std::try_to_lock);
|
int res = draw_frame(*renderer, true);
|
||||||
if (!lg.owns_lock()) {
|
if (res < 0) {
|
||||||
std::unique_lock<std::mutex> ulg(render_wait_mutex);
|
is_running = false;
|
||||||
render_wait_condition_variable.wait(ulg);
|
break;
|
||||||
continue;
|
}
|
||||||
} else {
|
if (res == 1) {
|
||||||
int res = draw_frame(*renderer);
|
std::unique_lock<std::mutex> ulg(render_thread_sleep_mutex);
|
||||||
if (res < 0) {
|
render_thread_sleep_condition_variable.wait(ulg);
|
||||||
is_running = false;
|
|
||||||
}
|
|
||||||
if (res == 1) {
|
|
||||||
lg.unlock();
|
|
||||||
std::unique_lock<std::mutex> ulg(render_wait_mutex);
|
|
||||||
render_wait_condition_variable.wait(ulg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -628,25 +649,24 @@ int main() {
|
|||||||
if (0 != device_initialization(renderer)) return -1;
|
if (0 != device_initialization(renderer)) return -1;
|
||||||
if (0 != get_queues(renderer)) return -1;
|
if (0 != get_queues(renderer)) return -1;
|
||||||
if (0 != create_render_pass(renderer)) return -1;
|
if (0 != create_render_pass(renderer)) return -1;
|
||||||
if (0 != create_framebuffer(renderer)) return -1;
|
if (0 != create_framebuffer(renderer, renderer.framebuffer)) return -1;
|
||||||
if (0 != create_graphics_pipeline(renderer)) return -1;
|
if (0 != create_graphics_pipeline(renderer)) return -1;
|
||||||
if (0 != create_command_buffers(renderer)) return -1;
|
if (0 != create_command_buffers(renderer)) return -1;
|
||||||
is_running = true;
|
is_running = true;
|
||||||
renderer.current_time = glfwGetTime();
|
renderer.current_time = glfwGetTime();
|
||||||
if (run_multithreaded) {
|
if (run_multithreaded) {
|
||||||
std::thread render_thread{ render_loop, &renderer };
|
std::thread render_thread{ render_loop, &renderer };
|
||||||
|
|
||||||
while (!glfwWindowShouldClose(renderer.window) && is_running) {
|
while (!glfwWindowShouldClose(renderer.window) && is_running) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
glfwWaitEvents();
|
glfwWaitEvents();
|
||||||
}
|
}
|
||||||
is_running = false;
|
is_running = false;
|
||||||
render_wait_condition_variable.notify_one();
|
render_thread_sleep_condition_variable.notify_one();
|
||||||
render_thread.join();
|
render_thread.join();
|
||||||
} else {
|
} else {
|
||||||
while (!glfwWindowShouldClose(renderer.window) && is_running) {
|
while (!glfwWindowShouldClose(renderer.window) && is_running) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
int res = draw_frame(renderer);
|
int res = draw_frame(renderer, false);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
is_running = false;
|
is_running = false;
|
||||||
}
|
}
|
||||||
|
@ -2299,6 +2299,8 @@ SwapchainManager::SwapchainManager(SwapchainBuilder const& builder,
|
|||||||
detail::vulkan_functions().get_device_proc_addr(device, detail.fp_vkGetDeviceQueue, "vkGetDeviceQueue");
|
detail::vulkan_functions().get_device_proc_addr(device, detail.fp_vkGetDeviceQueue, "vkGetDeviceQueue");
|
||||||
detail::vulkan_functions().get_device_proc_addr(device, detail.fp_vkAcquireNextImageKHR, "vkAcquireNextImageKHR");
|
detail::vulkan_functions().get_device_proc_addr(device, detail.fp_vkAcquireNextImageKHR, "vkAcquireNextImageKHR");
|
||||||
detail::vulkan_functions().get_device_proc_addr(device, detail.fp_vkQueuePresentKHR, "vkQueuePresentKHR");
|
detail::vulkan_functions().get_device_proc_addr(device, detail.fp_vkQueuePresentKHR, "vkQueuePresentKHR");
|
||||||
|
detail::vulkan_functions().get_device_proc_addr(device, detail.fp_vkQueueSubmit, "vkQueueSubmit");
|
||||||
|
|
||||||
detail.fp_vkGetSwapchainImagesKHR = fp_vkGetSwapchainImagesKHR;
|
detail.fp_vkGetSwapchainImagesKHR = fp_vkGetSwapchainImagesKHR;
|
||||||
detail.fp_vkCreateImageView = fp_vkCreateImageView;
|
detail.fp_vkCreateImageView = fp_vkCreateImageView;
|
||||||
detail.fp_vkGetDeviceQueue(device, detail.builder.info.graphics_queue_index, 0, &detail.graphics_queue);
|
detail.fp_vkGetDeviceQueue(device, detail.builder.info.graphics_queue_index, 0, &detail.graphics_queue);
|
||||||
@ -2387,21 +2389,15 @@ detail::Result<SwapchainAcquireInfo> SwapchainManager::acquire_image() noexcept
|
|||||||
SwapchainAcquireInfo out{};
|
SwapchainAcquireInfo out{};
|
||||||
out.image_view = detail.swapchain_resources.image_views[detail.current_image_index];
|
out.image_view = detail.swapchain_resources.image_views[detail.current_image_index];
|
||||||
out.image_index = detail.current_image_index;
|
out.image_index = detail.current_image_index;
|
||||||
|
out.wait_semaphore = detail.semaphore_manager.get_acquire_semaphore();
|
||||||
|
out.signal_semaphore = detail.semaphore_manager.get_submit_semaphore();
|
||||||
|
detail.current_acquire_semaphore = out.wait_semaphore;
|
||||||
|
detail.current_present_semaphore = out.signal_semaphore;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
detail::Result<SwapchainSubmitSemaphores> SwapchainManager::get_submit_semaphores() noexcept {
|
bool SwapchainManager::able_to_present() noexcept {
|
||||||
assert(detail.current_status != Status::destroyed && "SwapchainManager was destroyed!");
|
return detail.current_status == Status::ready_to_present;
|
||||||
if (detail.current_status == Status::expired) {
|
|
||||||
return make_error_code(SwapchainManagerError::swapchain_out_of_date);
|
|
||||||
}
|
|
||||||
if (detail.current_status == Status::ready_to_acquire) {
|
|
||||||
return make_error_code(SwapchainManagerError::must_call_acquire_image_first);
|
|
||||||
}
|
|
||||||
SwapchainSubmitSemaphores semaphores;
|
|
||||||
semaphores.signal = detail.semaphore_manager.get_submit_semaphore();
|
|
||||||
semaphores.wait = detail.semaphore_manager.get_acquire_semaphore();
|
|
||||||
return semaphores;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
detail::Result<detail::void_t> SwapchainManager::present() noexcept {
|
detail::Result<detail::void_t> SwapchainManager::present() noexcept {
|
||||||
@ -2413,7 +2409,9 @@ detail::Result<detail::void_t> SwapchainManager::present() noexcept {
|
|||||||
return make_error_code(SwapchainManagerError::must_call_acquire_image_first);
|
return make_error_code(SwapchainManagerError::must_call_acquire_image_first);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSemaphore wait_semaphores[1] = { detail.semaphore_manager.get_submit_semaphore() };
|
VkSemaphore wait_semaphores[1] = { detail.current_present_semaphore };
|
||||||
|
detail.current_acquire_semaphore = VK_NULL_HANDLE;
|
||||||
|
detail.current_present_semaphore = VK_NULL_HANDLE;
|
||||||
|
|
||||||
VkPresentInfoKHR present_info = {};
|
VkPresentInfoKHR present_info = {};
|
||||||
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
@ -2437,13 +2435,43 @@ detail::Result<detail::void_t> SwapchainManager::present() noexcept {
|
|||||||
} else {
|
} else {
|
||||||
detail.current_status = Status::ready_to_acquire;
|
detail.current_status = Status::ready_to_acquire;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up old swapchain resources
|
// clean up old swapchain resources
|
||||||
detail.delete_queue.tick();
|
detail.delete_queue.tick();
|
||||||
|
|
||||||
return detail::void_t{};
|
return detail::void_t{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SwapchainManager::cancel_acquire_frame() noexcept {
|
||||||
|
VkPipelineStageFlags wait_stages[1] = { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT };
|
||||||
|
|
||||||
|
VkSubmitInfo submit_info = {};
|
||||||
|
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submit_info.waitSemaphoreCount = 1;
|
||||||
|
submit_info.pWaitSemaphores = &detail.current_acquire_semaphore;
|
||||||
|
submit_info.pWaitDstStageMask = wait_stages;
|
||||||
|
|
||||||
|
VkResult res = detail.fp_vkQueueSubmit(detail.graphics_queue, 1, &submit_info, VK_NULL_HANDLE);
|
||||||
|
assert(res == VK_SUCCESS);
|
||||||
|
|
||||||
|
detail.current_acquire_semaphore = VK_NULL_HANDLE;
|
||||||
|
detail.current_present_semaphore = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
void SwapchainManager::cancel_present_frame() noexcept {
|
||||||
|
VkPipelineStageFlags wait_stages[1] = { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT };
|
||||||
|
|
||||||
|
VkSubmitInfo submit_info = {};
|
||||||
|
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submit_info.waitSemaphoreCount = 1;
|
||||||
|
submit_info.pWaitSemaphores = &detail.current_present_semaphore;
|
||||||
|
submit_info.pWaitDstStageMask = wait_stages;
|
||||||
|
|
||||||
|
|
||||||
|
VkResult res = detail.fp_vkQueueSubmit(detail.graphics_queue, 1, &submit_info, VK_NULL_HANDLE);
|
||||||
|
assert(res == VK_SUCCESS);
|
||||||
|
detail.current_acquire_semaphore = VK_NULL_HANDLE;
|
||||||
|
detail.current_present_semaphore = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
detail::Result<SwapchainInfo> SwapchainManager::recreate(uint32_t width, uint32_t height) noexcept {
|
detail::Result<SwapchainInfo> SwapchainManager::recreate(uint32_t width, uint32_t height) noexcept {
|
||||||
assert(detail.current_status != Status::destroyed && "SwapchainManager was destroyed!");
|
assert(detail.current_status != Status::destroyed && "SwapchainManager was destroyed!");
|
||||||
|
|
||||||
|
@ -978,11 +978,8 @@ struct SwapchainAcquireInfo {
|
|||||||
VkImageView image_view{};
|
VkImageView image_view{};
|
||||||
// index of the swapchain image to use this frame
|
// index of the swapchain image to use this frame
|
||||||
uint32_t image_index = detail::INDEX_MAX_VALUE;
|
uint32_t image_index = detail::INDEX_MAX_VALUE;
|
||||||
};
|
VkSemaphore signal_semaphore;
|
||||||
|
VkSemaphore wait_semaphore;
|
||||||
struct SwapchainSubmitSemaphores {
|
|
||||||
VkSemaphore signal;
|
|
||||||
VkSemaphore wait;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1098,10 +1095,12 @@ class SwapchainManager {
|
|||||||
// Get a VkImageView handle to use in rendering
|
// Get a VkImageView handle to use in rendering
|
||||||
detail::Result<SwapchainAcquireInfo> acquire_image() noexcept;
|
detail::Result<SwapchainAcquireInfo> acquire_image() noexcept;
|
||||||
|
|
||||||
detail::Result<SwapchainSubmitSemaphores> get_submit_semaphores() noexcept;
|
bool able_to_present() noexcept;
|
||||||
|
|
||||||
detail::Result<detail::void_t> present() noexcept;
|
detail::Result<detail::void_t> present() noexcept;
|
||||||
|
|
||||||
|
void cancel_acquire_frame() noexcept;
|
||||||
|
void cancel_present_frame() noexcept;
|
||||||
|
|
||||||
// Recreate the swapchain, putting currently in-use internal resources in a delete queue
|
// Recreate the swapchain, putting currently in-use internal resources in a delete queue
|
||||||
detail::Result<SwapchainInfo> recreate(uint32_t width = 0, uint32_t height = 0) noexcept;
|
detail::Result<SwapchainInfo> recreate(uint32_t width = 0, uint32_t height = 0) noexcept;
|
||||||
|
|
||||||
@ -1138,6 +1137,9 @@ class SwapchainManager {
|
|||||||
PFN_vkQueuePresentKHR fp_vkQueuePresentKHR;
|
PFN_vkQueuePresentKHR fp_vkQueuePresentKHR;
|
||||||
PFN_vkGetSwapchainImagesKHR fp_vkGetSwapchainImagesKHR;
|
PFN_vkGetSwapchainImagesKHR fp_vkGetSwapchainImagesKHR;
|
||||||
PFN_vkCreateImageView fp_vkCreateImageView;
|
PFN_vkCreateImageView fp_vkCreateImageView;
|
||||||
|
PFN_vkQueueSubmit fp_vkQueueSubmit;
|
||||||
|
VkSemaphore current_acquire_semaphore;
|
||||||
|
VkSemaphore current_present_semaphore;
|
||||||
} detail;
|
} detail;
|
||||||
|
|
||||||
explicit SwapchainManager(SwapchainBuilder const& builder,
|
explicit SwapchainManager(SwapchainBuilder const& builder,
|
||||||
|
Loading…
Reference in New Issue
Block a user