|
|
@ -64,15 +64,15 @@ VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, u32 wi |
|
|
|
|
|
|
|
|
} // Anonymous namespace
|
|
|
} // Anonymous namespace
|
|
|
|
|
|
|
|
|
VKSwapchain::VKSwapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_, |
|
|
|
|
|
u32 width, u32 height, bool srgb) |
|
|
|
|
|
|
|
|
Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_, u32 width, |
|
|
|
|
|
u32 height, bool srgb) |
|
|
: surface{surface_}, device{device_}, scheduler{scheduler_} { |
|
|
: surface{surface_}, device{device_}, scheduler{scheduler_} { |
|
|
Create(width, height, srgb); |
|
|
Create(width, height, srgb); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
VKSwapchain::~VKSwapchain() = default; |
|
|
|
|
|
|
|
|
Swapchain::~Swapchain() = default; |
|
|
|
|
|
|
|
|
void VKSwapchain::Create(u32 width, u32 height, bool srgb) { |
|
|
|
|
|
|
|
|
void Swapchain::Create(u32 width, u32 height, bool srgb) { |
|
|
is_outdated = false; |
|
|
is_outdated = false; |
|
|
is_suboptimal = false; |
|
|
is_suboptimal = false; |
|
|
|
|
|
|
|
|
@ -93,7 +93,7 @@ void VKSwapchain::Create(u32 width, u32 height, bool srgb) { |
|
|
resource_ticks.resize(image_count); |
|
|
resource_ticks.resize(image_count); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void VKSwapchain::AcquireNextImage() { |
|
|
|
|
|
|
|
|
void Swapchain::AcquireNextImage() { |
|
|
const VkResult result = device.GetLogical().AcquireNextImageKHR( |
|
|
const VkResult result = device.GetLogical().AcquireNextImageKHR( |
|
|
*swapchain, std::numeric_limits<u64>::max(), *present_semaphores[frame_index], |
|
|
*swapchain, std::numeric_limits<u64>::max(), *present_semaphores[frame_index], |
|
|
VK_NULL_HANDLE, &image_index); |
|
|
VK_NULL_HANDLE, &image_index); |
|
|
@ -114,7 +114,7 @@ void VKSwapchain::AcquireNextImage() { |
|
|
resource_ticks[image_index] = scheduler.CurrentTick(); |
|
|
resource_ticks[image_index] = scheduler.CurrentTick(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void VKSwapchain::Present(VkSemaphore render_semaphore) { |
|
|
|
|
|
|
|
|
void Swapchain::Present(VkSemaphore render_semaphore) { |
|
|
const auto present_queue{device.GetPresentQueue()}; |
|
|
const auto present_queue{device.GetPresentQueue()}; |
|
|
const VkPresentInfoKHR present_info{ |
|
|
const VkPresentInfoKHR present_info{ |
|
|
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, |
|
|
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, |
|
|
@ -145,8 +145,8 @@ void VKSwapchain::Present(VkSemaphore render_semaphore) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, |
|
|
|
|
|
u32 height, bool srgb) { |
|
|
|
|
|
|
|
|
void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height, |
|
|
|
|
|
bool srgb) { |
|
|
const auto physical_device{device.GetPhysical()}; |
|
|
const auto physical_device{device.GetPhysical()}; |
|
|
const auto formats{physical_device.GetSurfaceFormatsKHR(surface)}; |
|
|
const auto formats{physical_device.GetSurfaceFormatsKHR(surface)}; |
|
|
const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)}; |
|
|
const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)}; |
|
|
@ -212,13 +212,13 @@ void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, |
|
|
image_view_format = srgb ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_B8G8R8A8_UNORM; |
|
|
image_view_format = srgb ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_B8G8R8A8_UNORM; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void VKSwapchain::CreateSemaphores() { |
|
|
|
|
|
|
|
|
void Swapchain::CreateSemaphores() { |
|
|
present_semaphores.resize(image_count); |
|
|
present_semaphores.resize(image_count); |
|
|
std::ranges::generate(present_semaphores, |
|
|
std::ranges::generate(present_semaphores, |
|
|
[this] { return device.GetLogical().CreateSemaphore(); }); |
|
|
[this] { return device.GetLogical().CreateSemaphore(); }); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void VKSwapchain::CreateImageViews() { |
|
|
|
|
|
|
|
|
void Swapchain::CreateImageViews() { |
|
|
VkImageViewCreateInfo ci{ |
|
|
VkImageViewCreateInfo ci{ |
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, |
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, |
|
|
.pNext = nullptr, |
|
|
.pNext = nullptr, |
|
|
@ -250,7 +250,7 @@ void VKSwapchain::CreateImageViews() { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void VKSwapchain::Destroy() { |
|
|
|
|
|
|
|
|
void Swapchain::Destroy() { |
|
|
frame_index = 0; |
|
|
frame_index = 0; |
|
|
present_semaphores.clear(); |
|
|
present_semaphores.clear(); |
|
|
framebuffers.clear(); |
|
|
framebuffers.clear(); |
|
|
@ -258,11 +258,11 @@ void VKSwapchain::Destroy() { |
|
|
swapchain.reset(); |
|
|
swapchain.reset(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool VKSwapchain::HasFpsUnlockChanged() const { |
|
|
|
|
|
|
|
|
bool Swapchain::HasFpsUnlockChanged() const { |
|
|
return current_fps_unlocked != Settings::values.disable_fps_limit.GetValue(); |
|
|
return current_fps_unlocked != Settings::values.disable_fps_limit.GetValue(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool VKSwapchain::NeedsPresentModeUpdate() const { |
|
|
|
|
|
|
|
|
bool Swapchain::NeedsPresentModeUpdate() const { |
|
|
// Mailbox present mode is the ideal for all scenarios. If it is not available,
|
|
|
// Mailbox present mode is the ideal for all scenarios. If it is not available,
|
|
|
// A different present mode is needed to support unlocked FPS above the monitor's refresh rate.
|
|
|
// A different present mode is needed to support unlocked FPS above the monitor's refresh rate.
|
|
|
return present_mode != VK_PRESENT_MODE_MAILBOX_KHR && HasFpsUnlockChanged(); |
|
|
return present_mode != VK_PRESENT_MODE_MAILBOX_KHR && HasFpsUnlockChanged(); |
|
|
|