From b8248440438485f6bc69145c78b85cf90c434f3a Mon Sep 17 00:00:00 2001 From: Albert Liu <45282415+ggrtk@users.noreply.github.com> Date: Sun, 20 Dec 2020 17:38:59 -0800 Subject: [PATCH 1/4] HostDisplay: Fix framebuffer screenshot scaling --- src/core/host_display.cpp | 57 ++++++++++++--------------------------- 1 file changed, 17 insertions(+), 40 deletions(-) diff --git a/src/core/host_display.cpp b/src/core/host_display.cpp index 1f4626bc8..47f67d2d8 100644 --- a/src/core/host_display.cpp +++ b/src/core/host_display.cpp @@ -486,52 +486,29 @@ bool HostDisplay::WriteDisplayTextureToFile(std::string filename, bool full_reso if (!m_display_texture_handle) return false; - apply_aspect_ratio = (m_display_aspect_ratio > 0) ? apply_aspect_ratio : false; - s32 resize_width = 0; - s32 resize_height = 0; - if (apply_aspect_ratio && full_resolution) + s32 resize_height = std::abs(m_display_texture_view_height); + if (apply_aspect_ratio) { - if (m_display_aspect_ratio > 1.0f) - { - resize_width = m_display_texture_view_width; - resize_height = static_cast(static_cast(resize_width) / m_display_aspect_ratio); - } - else - { - resize_height = std::abs(m_display_texture_view_height); - resize_width = static_cast(static_cast(resize_height) * m_display_aspect_ratio); - } + const float ss_width_scale = static_cast(m_display_active_width) / static_cast(m_display_width); + const float ss_height_scale = static_cast(m_display_active_height) / static_cast(m_display_height); + const float ss_aspect_ratio = m_display_aspect_ratio * ss_width_scale / ss_height_scale; + resize_width = static_cast(static_cast(resize_height) * ss_aspect_ratio); } - else if (apply_aspect_ratio) + else { - const auto [left, top, right, bottom] = - CalculateDrawRect(GetWindowWidth(), GetWindowHeight(), m_display_top_margin); - resize_width = right - left; - resize_height = bottom - top; - } - else if (!full_resolution) - { - const auto [left, top, right, bottom] = - CalculateDrawRect(GetWindowWidth(), GetWindowHeight(), m_display_top_margin); - const float ratio = - static_cast(m_display_texture_view_width) / static_cast(std::abs(m_display_texture_view_height)); - if (ratio > 1.0f) - { - resize_width = right - left; - resize_height = static_cast(static_cast(resize_width) / ratio); - } - else - { - resize_height = bottom - top; - resize_width = static_cast(static_cast(resize_height) * ratio); - } + resize_width = m_display_texture_view_width; } - if (resize_width < 0) - resize_width = 1; - if (resize_height < 0) - resize_height = 1; + if (!full_resolution) + { + const s32 resolution_scale = std::abs(m_display_texture_view_height) / m_display_active_height; + resize_height /= resolution_scale; + resize_width /= resolution_scale; + } + + if (resize_width <= 0 || resize_height <= 0) + return false; const bool flip_y = (m_display_texture_view_height < 0); s32 read_height = m_display_texture_view_height; From e0f3a4f17bdf48ee939a85f8432ec77e46df00cf Mon Sep 17 00:00:00 2001 From: Albert Liu <45282415+ggrtk@users.noreply.github.com> Date: Wed, 24 Jun 2020 05:32:55 -0700 Subject: [PATCH 2/4] HostDisplay: Calculate draw rectangle in terms of horizontal scale --- src/core/host_display.cpp | 30 +++++++++++++++--------------- src/core/host_display.h | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/core/host_display.cpp b/src/core/host_display.cpp index 47f67d2d8..91fc8650c 100644 --- a/src/core/host_display.cpp +++ b/src/core/host_display.cpp @@ -137,20 +137,20 @@ void HostDisplay::ClearSoftwareCursor() void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32* out_left, s32* out_top, s32* out_width, s32* out_height, s32* out_left_padding, s32* out_top_padding, float* out_scale, - float* out_y_scale, bool apply_aspect_ratio) const + float* out_x_scale, bool apply_aspect_ratio /* = true */) const { - const float y_scale = + const float x_scale = apply_aspect_ratio ? - ((static_cast(m_display_width) / static_cast(m_display_height)) / m_display_aspect_ratio) : + (m_display_aspect_ratio / (static_cast(m_display_width) / static_cast(m_display_height))) : 1.0f; - const float display_width = static_cast(m_display_width); - const float display_height = static_cast(m_display_height) * y_scale; - const float active_left = static_cast(m_display_active_left); - const float active_top = static_cast(m_display_active_top) * y_scale; - const float active_width = static_cast(m_display_active_width); - const float active_height = static_cast(m_display_active_height) * y_scale; - if (out_y_scale) - *out_y_scale = y_scale; + const float display_width = static_cast(m_display_width) * x_scale; + const float display_height = static_cast(m_display_height); + const float active_left = static_cast(m_display_active_left) * x_scale; + const float active_top = static_cast(m_display_active_top); + const float active_width = static_cast(m_display_active_width) * x_scale; + const float active_height = static_cast(m_display_active_height); + if (out_x_scale) + *out_x_scale = x_scale; // now fit it within the window const float window_ratio = static_cast(window_width) / static_cast(window_height); @@ -263,17 +263,17 @@ std::tuple HostDisplay::ConvertWindowCoordinatesToDisplayCoordinat s32 top_margin) const { s32 left, top, width, height, left_padding, top_padding; - float scale, y_scale; + float scale, x_scale; CalculateDrawRect(window_width, window_height - top_margin, &left, &top, &width, &height, &left_padding, &top_padding, - &scale, &y_scale); + &scale, &x_scale); // convert coordinates to active display region, then to full display region const float scaled_display_x = static_cast(window_x - (left_padding)); const float scaled_display_y = static_cast(window_y - (top_padding + top_margin)); // scale back to internal resolution - const float display_x = scaled_display_x / scale; - const float display_y = scaled_display_y / scale / y_scale; + const float display_x = scaled_display_x / scale / x_scale; + const float display_y = scaled_display_y / scale; return std::make_tuple(display_x, display_y); } diff --git a/src/core/host_display.h b/src/core/host_display.h index f141050a1..fa7989766 100644 --- a/src/core/host_display.h +++ b/src/core/host_display.h @@ -215,7 +215,7 @@ protected: void CalculateDrawRect(s32 window_width, s32 window_height, s32* out_left, s32* out_top, s32* out_width, s32* out_height, s32* out_left_padding, s32* out_top_padding, float* out_scale, - float* out_y_scale, bool apply_aspect_ratio = true) const; + float* out_x_scale, bool apply_aspect_ratio = true) const; std::tuple CalculateSoftwareCursorDrawRect() const; std::tuple CalculateSoftwareCursorDrawRect(s32 cursor_x, s32 cursor_y) const; From 11fbf260455faa054072df7bafb7065f1fce25ef Mon Sep 17 00:00:00 2001 From: Albert Liu <45282415+ggrtk@users.noreply.github.com> Date: Sat, 14 Nov 2020 17:23:22 -0800 Subject: [PATCH 3/4] HostDisplay: Use floats internally for draw rectangle calculation --- src/core/host_display.cpp | 49 +++++++++++++++++++++------------------ src/core/host_display.h | 4 ++-- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/core/host_display.cpp b/src/core/host_display.cpp index 91fc8650c..bac43529f 100644 --- a/src/core/host_display.cpp +++ b/src/core/host_display.cpp @@ -135,9 +135,10 @@ void HostDisplay::ClearSoftwareCursor() m_cursor_texture_scale = 1.0f; } -void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32* out_left, s32* out_top, s32* out_width, - s32* out_height, s32* out_left_padding, s32* out_top_padding, float* out_scale, - float* out_x_scale, bool apply_aspect_ratio /* = true */) const +void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, float* out_left, float* out_top, + float* out_width, float* out_height, float* out_left_padding, + float* out_top_padding, float* out_scale, float* out_x_scale, + bool apply_aspect_ratio /* = true */) const { const float x_scale = apply_aspect_ratio ? @@ -166,24 +167,25 @@ void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32* ou if (out_left_padding) { if (m_display_integer_scaling) - *out_left_padding = std::max((window_width - static_cast(display_width * scale)) / 2, 0); + *out_left_padding = std::max((static_cast(window_width) - display_width * scale) / 2.0f, 0.0f); else - *out_left_padding = 0; + *out_left_padding = 0.0f; } if (out_top_padding) { switch (m_display_alignment) { case Alignment::LeftOrTop: - *out_top_padding = 0; + *out_top_padding = 0.0f; break; case Alignment::Center: - *out_top_padding = std::max((window_height - static_cast(display_height * scale)) / 2, 0); + *out_top_padding = + std::max((static_cast(window_height) - (display_height * scale)) / 2.0f, 0.0f); break; case Alignment::RightOrBottom: - *out_top_padding = std::max(window_height - static_cast(display_height * scale), 0); + *out_top_padding = std::max(static_cast(window_height) - (display_height * scale), 0.0f); break; } } @@ -200,15 +202,16 @@ void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32* ou switch (m_display_alignment) { case Alignment::LeftOrTop: - *out_left_padding = 0; + *out_left_padding = 0.0f; break; case Alignment::Center: - *out_left_padding = std::max((window_width - static_cast(display_width * scale)) / 2, 0); + *out_left_padding = + std::max((static_cast(window_width) - (display_width * scale)) / 2.0f, 0.0f); break; case Alignment::RightOrBottom: - *out_left_padding = std::max(window_width - static_cast(display_width * scale), 0); + *out_left_padding = std::max(static_cast(window_width) - (display_width * scale), 0.0f); break; } } @@ -216,16 +219,16 @@ void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32* ou if (out_top_padding) { if (m_display_integer_scaling) - *out_top_padding = std::max((window_height - static_cast(display_height * scale)) / 2, 0); + *out_top_padding = std::max((static_cast(window_height) - (display_height * scale)) / 2.0f, 0.0f); else - *out_top_padding = 0; + *out_top_padding = 0.0f; } } - *out_width = static_cast(active_width * scale); - *out_height = static_cast(active_height * scale); - *out_left = static_cast(active_left * scale); - *out_top = static_cast(active_top * scale); + *out_width = active_width * scale; + *out_height = active_height * scale; + *out_left = active_left * scale; + *out_top = active_top * scale; if (out_scale) *out_scale = scale; } @@ -233,10 +236,12 @@ void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32* ou std::tuple HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32 top_margin, bool apply_aspect_ratio /* = true */) const { - s32 left, top, width, height, left_padding, top_padding; + float left, top, width, height, left_padding, top_padding; CalculateDrawRect(window_width, window_height - top_margin, &left, &top, &width, &height, &left_padding, &top_padding, nullptr, nullptr, apply_aspect_ratio); - return std::make_tuple(left + left_padding, top + top_padding + top_margin, width, height); + + return std::make_tuple(static_cast(left + left_padding), static_cast(top + top_padding) + top_margin, + static_cast(width), static_cast(height)); } std::tuple HostDisplay::CalculateSoftwareCursorDrawRect() const @@ -262,14 +267,14 @@ std::tuple HostDisplay::ConvertWindowCoordinatesToDisplayCoordinat s32 window_width, s32 window_height, s32 top_margin) const { - s32 left, top, width, height, left_padding, top_padding; + float left, top, width, height, left_padding, top_padding; float scale, x_scale; CalculateDrawRect(window_width, window_height - top_margin, &left, &top, &width, &height, &left_padding, &top_padding, &scale, &x_scale); // convert coordinates to active display region, then to full display region - const float scaled_display_x = static_cast(window_x - (left_padding)); - const float scaled_display_y = static_cast(window_y - (top_padding + top_margin)); + const float scaled_display_x = static_cast(window_x) - left_padding; + const float scaled_display_y = static_cast(window_y) - top_padding + static_cast(top_margin); // scale back to internal resolution const float display_x = scaled_display_x / scale / x_scale; diff --git a/src/core/host_display.h b/src/core/host_display.h index fa7989766..c4024ca5c 100644 --- a/src/core/host_display.h +++ b/src/core/host_display.h @@ -213,8 +213,8 @@ protected: ALWAYS_INLINE bool HasSoftwareCursor() const { return static_cast(m_cursor_texture); } ALWAYS_INLINE bool HasDisplayTexture() const { return (m_display_texture_handle != nullptr); } - void CalculateDrawRect(s32 window_width, s32 window_height, s32* out_left, s32* out_top, s32* out_width, - s32* out_height, s32* out_left_padding, s32* out_top_padding, float* out_scale, + void CalculateDrawRect(s32 window_width, s32 window_height, float* out_left, float* out_top, float* out_width, + float* out_height, float* out_left_padding, float* out_top_padding, float* out_scale, float* out_x_scale, bool apply_aspect_ratio = true) const; std::tuple CalculateSoftwareCursorDrawRect() const; From 1c1ca45e4e89d6c621d4c303a5c0c574842d354f Mon Sep 17 00:00:00 2001 From: Albert Liu <45282415+ggrtk@users.noreply.github.com> Date: Mon, 28 Dec 2020 23:42:20 -0800 Subject: [PATCH 4/4] VulkanHostDisplay: Fix post shader uniform buffer --- src/frontend-common/vulkan_host_display.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend-common/vulkan_host_display.cpp b/src/frontend-common/vulkan_host_display.cpp index 374b8a81c..da493d6d1 100644 --- a/src/frontend-common/vulkan_host_display.cpp +++ b/src/frontend-common/vulkan_host_display.cpp @@ -1006,7 +1006,7 @@ void VulkanHostDisplay::ApplyPostProcessingChain(s32 final_left, s32 final_top, Assert(pps.uniforms_size <= sizeof(buffer)); m_post_processing_chain.GetShaderStage(i).FillUniformBuffer( buffer, texture_width, texture_height, texture_view_x, texture_view_y, texture_view_width, texture_view_height, - texture_width, texture_width, 0.0f); + GetWindowWidth(), GetWindowHeight(), 0.0f); vkCmdPushConstants(cmdbuffer, m_post_process_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, pps.uniforms_size, buffer);