mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
Allow resizing by default and recreate swapchain on resize (#763)
* Add `stretch to window` support * Address comment * Allow window resizing by default and recreate swapchain on resize --------- Co-authored-by: nmzik <Nmzik@mail.ru>
This commit is contained in:
@@ -279,6 +279,7 @@ public:
|
|||||||
|
|
||||||
void Create();
|
void Create();
|
||||||
void Recreate(bool surface_lost = false);
|
void Recreate(bool surface_lost = false);
|
||||||
|
[[nodiscard]] bool NeedsResize() const;
|
||||||
[[nodiscard]] Status AcquireNextImage();
|
[[nodiscard]] Status AcquireNextImage();
|
||||||
[[nodiscard]] bool PrepareSystemOverlay();
|
[[nodiscard]] bool PrepareSystemOverlay();
|
||||||
void RecordPresentCommands(CommandBuffer& command, VulkanImage& source,
|
void RecordPresentCommands(CommandBuffer& command, VulkanImage& source,
|
||||||
@@ -298,6 +299,8 @@ private:
|
|||||||
vk::SwapchainKHR m_handle = nullptr;
|
vk::SwapchainKHR m_handle = nullptr;
|
||||||
vk::Format m_format = vk::Format::eUndefined;
|
vk::Format m_format = vk::Format::eUndefined;
|
||||||
vk::Extent2D m_extent {};
|
vk::Extent2D m_extent {};
|
||||||
|
// Drawable pixel size observed when this swapchain was created.
|
||||||
|
vk::Extent2D m_window_extent {};
|
||||||
std::vector<vk::Image> m_images;
|
std::vector<vk::Image> m_images;
|
||||||
std::vector<vk::ImageView> m_image_views;
|
std::vector<vk::ImageView> m_image_views;
|
||||||
std::vector<vk::Semaphore> m_image_acquired;
|
std::vector<vk::Semaphore> m_image_acquired;
|
||||||
@@ -357,19 +360,25 @@ void Swapchain::Create() {
|
|||||||
EXIT_IF(graphics.device == nullptr);
|
EXIT_IF(graphics.device == nullptr);
|
||||||
EXIT_IF(m_window.surface == nullptr);
|
EXIT_IF(m_window.surface == nullptr);
|
||||||
|
|
||||||
Common::LockGuard lock(m_window.mutex);
|
// Capture the size before querying surface capabilities. If the window changes
|
||||||
EXIT_IF(graphics.screen_width == 0);
|
// during creation, the next presentation will detect the newer size.
|
||||||
EXIT_IF(graphics.screen_height == 0);
|
{
|
||||||
|
Common::LockGuard lock(m_window.mutex);
|
||||||
|
m_window_extent = {graphics.screen_width, graphics.screen_height};
|
||||||
|
}
|
||||||
|
EXIT_IF(m_window_extent.width == 0);
|
||||||
|
EXIT_IF(m_window_extent.height == 0);
|
||||||
|
m_window.RefreshSurfaceCapabilities();
|
||||||
const auto& surface = m_window.surface_capabilities;
|
const auto& surface = m_window.surface_capabilities;
|
||||||
EXIT_NOT_IMPLEMENTED(surface.formats.empty());
|
EXIT_NOT_IMPLEMENTED(surface.formats.empty());
|
||||||
|
|
||||||
m_extent = surface.capabilities.currentExtent;
|
m_extent = surface.capabilities.currentExtent;
|
||||||
if (m_extent.width == std::numeric_limits<uint32_t>::max()) {
|
if (m_extent.width == std::numeric_limits<uint32_t>::max()) {
|
||||||
m_extent.width =
|
m_extent.width =
|
||||||
std::clamp(graphics.screen_width, surface.capabilities.minImageExtent.width,
|
std::clamp(m_window_extent.width, surface.capabilities.minImageExtent.width,
|
||||||
surface.capabilities.maxImageExtent.width);
|
surface.capabilities.maxImageExtent.width);
|
||||||
m_extent.height =
|
m_extent.height =
|
||||||
std::clamp(graphics.screen_height, surface.capabilities.minImageExtent.height,
|
std::clamp(m_window_extent.height, surface.capabilities.minImageExtent.height,
|
||||||
surface.capabilities.maxImageExtent.height);
|
surface.capabilities.maxImageExtent.height);
|
||||||
}
|
}
|
||||||
uint32_t image_count = surface.capabilities.minImageCount + 1;
|
uint32_t image_count = surface.capabilities.minImageCount + 1;
|
||||||
@@ -473,8 +482,8 @@ void Swapchain::Create() {
|
|||||||
graphics.device.createSemaphore(&semaphore_info, nullptr, &m_render_complete[i]),
|
graphics.device.createSemaphore(&semaphore_info, nullptr, &m_render_complete[i]),
|
||||||
"create swapchain render-complete semaphore");
|
"create swapchain render-complete semaphore");
|
||||||
}
|
}
|
||||||
m_image_index = static_cast<uint32_t>(-1);
|
m_image_index = static_cast<uint32_t>(-1);
|
||||||
m_frame_index = 0;
|
m_frame_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Swapchain::~Swapchain() {
|
Swapchain::~Swapchain() {
|
||||||
@@ -515,11 +524,12 @@ void Swapchain::Destroy() {
|
|||||||
graphics.device.destroySwapchainKHR(m_handle, nullptr);
|
graphics.device.destroySwapchainKHR(m_handle, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_handle = nullptr;
|
m_handle = nullptr;
|
||||||
m_format = vk::Format::eUndefined;
|
m_format = vk::Format::eUndefined;
|
||||||
m_extent = {};
|
m_extent = {};
|
||||||
m_image_index = static_cast<uint32_t>(-1);
|
m_window_extent = {};
|
||||||
m_frame_index = 0;
|
m_image_index = static_cast<uint32_t>(-1);
|
||||||
|
m_frame_index = 0;
|
||||||
m_images.clear();
|
m_images.clear();
|
||||||
m_image_views.clear();
|
m_image_views.clear();
|
||||||
m_image_acquired.clear();
|
m_image_acquired.clear();
|
||||||
@@ -539,10 +549,15 @@ void Swapchain::Recreate(bool surface_lost) {
|
|||||||
m_window.RecreateSurface();
|
m_window.RecreateSurface();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
m_window.RefreshSurfaceCapabilities();
|
|
||||||
Create();
|
Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Swapchain::NeedsResize() const {
|
||||||
|
Common::LockGuard lock(m_window.mutex);
|
||||||
|
return m_window_extent.width != m_window.graphic_ctx.screen_width ||
|
||||||
|
m_window_extent.height != m_window.graphic_ctx.screen_height;
|
||||||
|
}
|
||||||
|
|
||||||
Swapchain::Status Swapchain::AcquireNextImage() {
|
Swapchain::Status Swapchain::AcquireNextImage() {
|
||||||
EXIT_IF(m_handle == nullptr || m_frame_index >= m_image_acquired.size());
|
EXIT_IF(m_handle == nullptr || m_frame_index >= m_image_acquired.size());
|
||||||
m_image_index = static_cast<uint32_t>(-1);
|
m_image_index = static_cast<uint32_t>(-1);
|
||||||
@@ -768,6 +783,10 @@ void Presenter::Present(Frame& frame, bool reuse) {
|
|||||||
|
|
||||||
const auto overlay_visual = GetSystemOverlayVisualState();
|
const auto overlay_visual = GetSystemOverlayVisualState();
|
||||||
auto& swapchain = m_impl->swapchain;
|
auto& swapchain = m_impl->swapchain;
|
||||||
|
// Some window systems keep presenting an old swapchain after a resize.
|
||||||
|
if (swapchain.NeedsResize()) {
|
||||||
|
m_impl->RecoverSwapchain(Swapchain::Status::Recreate);
|
||||||
|
}
|
||||||
for (uint32_t attempt = 0; attempt < 2; attempt++) {
|
for (uint32_t attempt = 0; attempt < 2; attempt++) {
|
||||||
auto status = swapchain.AcquireNextImage();
|
auto status = swapchain.AcquireNextImage();
|
||||||
if (status != Swapchain::Status::Success) {
|
if (status != Swapchain::Status::Success) {
|
||||||
|
|||||||
@@ -783,14 +783,13 @@ static void WindowCreate(WindowContext& context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDL_SetWindowPosition(context.window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
SDL_SetWindowPosition(context.window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||||
SDL_SetWindowResizable(context.window, false);
|
|
||||||
HostInputInit(context.window);
|
HostInputInit(context.window);
|
||||||
InitializeSystemOverlayInput(context.window);
|
InitializeSystemOverlayInput(context.window);
|
||||||
context.UpdateIcon();
|
context.UpdateIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t WindowContext::InitialWindowFlags(bool fullscreen) noexcept {
|
uint32_t WindowContext::InitialWindowFlags(bool fullscreen) noexcept {
|
||||||
auto flags = static_cast<uint32_t>(SDL_WINDOW_VULKAN);
|
auto flags = static_cast<uint32_t>(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE);
|
||||||
if (fullscreen) {
|
if (fullscreen) {
|
||||||
flags |= static_cast<uint32_t>(SDL_WINDOW_FULLSCREEN);
|
flags |= static_cast<uint32_t>(SDL_WINDOW_FULLSCREEN);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user