mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-29 17:15:40 +00:00
Merge pull request #1341 from ggrtk/hostdisplay-fixes
HostDisplay: Fix some scaling issues
This commit is contained in:
commit
b38e4b8ba7
|
@ -135,22 +135,23 @@ void HostDisplay::ClearSoftwareCursor()
|
||||||
m_cursor_texture_scale = 1.0f;
|
m_cursor_texture_scale = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32* out_left, s32* out_top, s32* out_width,
|
void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, float* out_left, float* out_top,
|
||||||
s32* out_height, s32* out_left_padding, s32* out_top_padding, float* out_scale,
|
float* out_width, float* out_height, float* out_left_padding,
|
||||||
float* out_y_scale, bool apply_aspect_ratio) const
|
float* out_top_padding, float* out_scale, float* out_x_scale,
|
||||||
|
bool apply_aspect_ratio /* = true */) const
|
||||||
{
|
{
|
||||||
const float y_scale =
|
const float x_scale =
|
||||||
apply_aspect_ratio ?
|
apply_aspect_ratio ?
|
||||||
((static_cast<float>(m_display_width) / static_cast<float>(m_display_height)) / m_display_aspect_ratio) :
|
(m_display_aspect_ratio / (static_cast<float>(m_display_width) / static_cast<float>(m_display_height))) :
|
||||||
1.0f;
|
1.0f;
|
||||||
const float display_width = static_cast<float>(m_display_width);
|
const float display_width = static_cast<float>(m_display_width) * x_scale;
|
||||||
const float display_height = static_cast<float>(m_display_height) * y_scale;
|
const float display_height = static_cast<float>(m_display_height);
|
||||||
const float active_left = static_cast<float>(m_display_active_left);
|
const float active_left = static_cast<float>(m_display_active_left) * x_scale;
|
||||||
const float active_top = static_cast<float>(m_display_active_top) * y_scale;
|
const float active_top = static_cast<float>(m_display_active_top);
|
||||||
const float active_width = static_cast<float>(m_display_active_width);
|
const float active_width = static_cast<float>(m_display_active_width) * x_scale;
|
||||||
const float active_height = static_cast<float>(m_display_active_height) * y_scale;
|
const float active_height = static_cast<float>(m_display_active_height);
|
||||||
if (out_y_scale)
|
if (out_x_scale)
|
||||||
*out_y_scale = y_scale;
|
*out_x_scale = x_scale;
|
||||||
|
|
||||||
// now fit it within the window
|
// now fit it within the window
|
||||||
const float window_ratio = static_cast<float>(window_width) / static_cast<float>(window_height);
|
const float window_ratio = static_cast<float>(window_width) / static_cast<float>(window_height);
|
||||||
|
@ -166,24 +167,25 @@ void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32* ou
|
||||||
if (out_left_padding)
|
if (out_left_padding)
|
||||||
{
|
{
|
||||||
if (m_display_integer_scaling)
|
if (m_display_integer_scaling)
|
||||||
*out_left_padding = std::max<s32>((window_width - static_cast<s32>(display_width * scale)) / 2, 0);
|
*out_left_padding = std::max<float>((static_cast<float>(window_width) - display_width * scale) / 2.0f, 0.0f);
|
||||||
else
|
else
|
||||||
*out_left_padding = 0;
|
*out_left_padding = 0.0f;
|
||||||
}
|
}
|
||||||
if (out_top_padding)
|
if (out_top_padding)
|
||||||
{
|
{
|
||||||
switch (m_display_alignment)
|
switch (m_display_alignment)
|
||||||
{
|
{
|
||||||
case Alignment::LeftOrTop:
|
case Alignment::LeftOrTop:
|
||||||
*out_top_padding = 0;
|
*out_top_padding = 0.0f;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Alignment::Center:
|
case Alignment::Center:
|
||||||
*out_top_padding = std::max<s32>((window_height - static_cast<s32>(display_height * scale)) / 2, 0);
|
*out_top_padding =
|
||||||
|
std::max<float>((static_cast<float>(window_height) - (display_height * scale)) / 2.0f, 0.0f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Alignment::RightOrBottom:
|
case Alignment::RightOrBottom:
|
||||||
*out_top_padding = std::max<s32>(window_height - static_cast<s32>(display_height * scale), 0);
|
*out_top_padding = std::max<float>(static_cast<float>(window_height) - (display_height * scale), 0.0f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,15 +202,16 @@ void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32* ou
|
||||||
switch (m_display_alignment)
|
switch (m_display_alignment)
|
||||||
{
|
{
|
||||||
case Alignment::LeftOrTop:
|
case Alignment::LeftOrTop:
|
||||||
*out_left_padding = 0;
|
*out_left_padding = 0.0f;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Alignment::Center:
|
case Alignment::Center:
|
||||||
*out_left_padding = std::max<s32>((window_width - static_cast<s32>(display_width * scale)) / 2, 0);
|
*out_left_padding =
|
||||||
|
std::max<float>((static_cast<float>(window_width) - (display_width * scale)) / 2.0f, 0.0f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Alignment::RightOrBottom:
|
case Alignment::RightOrBottom:
|
||||||
*out_left_padding = std::max<s32>(window_width - static_cast<s32>(display_width * scale), 0);
|
*out_left_padding = std::max<float>(static_cast<float>(window_width) - (display_width * scale), 0.0f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,16 +219,16 @@ void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32* ou
|
||||||
if (out_top_padding)
|
if (out_top_padding)
|
||||||
{
|
{
|
||||||
if (m_display_integer_scaling)
|
if (m_display_integer_scaling)
|
||||||
*out_top_padding = std::max<s32>((window_height - static_cast<s32>(display_height * scale)) / 2, 0);
|
*out_top_padding = std::max<float>((static_cast<float>(window_height) - (display_height * scale)) / 2.0f, 0.0f);
|
||||||
else
|
else
|
||||||
*out_top_padding = 0;
|
*out_top_padding = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_width = static_cast<s32>(active_width * scale);
|
*out_width = active_width * scale;
|
||||||
*out_height = static_cast<s32>(active_height * scale);
|
*out_height = active_height * scale;
|
||||||
*out_left = static_cast<s32>(active_left * scale);
|
*out_left = active_left * scale;
|
||||||
*out_top = static_cast<s32>(active_top * scale);
|
*out_top = active_top * scale;
|
||||||
if (out_scale)
|
if (out_scale)
|
||||||
*out_scale = scale;
|
*out_scale = scale;
|
||||||
}
|
}
|
||||||
|
@ -233,10 +236,12 @@ void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32* ou
|
||||||
std::tuple<s32, s32, s32, s32> HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32 top_margin,
|
std::tuple<s32, s32, s32, s32> HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32 top_margin,
|
||||||
bool apply_aspect_ratio /* = true */) const
|
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,
|
CalculateDrawRect(window_width, window_height - top_margin, &left, &top, &width, &height, &left_padding, &top_padding,
|
||||||
nullptr, nullptr, apply_aspect_ratio);
|
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<s32>(left + left_padding), static_cast<s32>(top + top_padding) + top_margin,
|
||||||
|
static_cast<s32>(width), static_cast<s32>(height));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<s32, s32, s32, s32> HostDisplay::CalculateSoftwareCursorDrawRect() const
|
std::tuple<s32, s32, s32, s32> HostDisplay::CalculateSoftwareCursorDrawRect() const
|
||||||
|
@ -262,18 +267,18 @@ std::tuple<float, float> HostDisplay::ConvertWindowCoordinatesToDisplayCoordinat
|
||||||
s32 window_width, s32 window_height,
|
s32 window_width, s32 window_height,
|
||||||
s32 top_margin) const
|
s32 top_margin) const
|
||||||
{
|
{
|
||||||
s32 left, top, width, height, left_padding, top_padding;
|
float 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,
|
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
|
// convert coordinates to active display region, then to full display region
|
||||||
const float scaled_display_x = static_cast<float>(window_x - (left_padding));
|
const float scaled_display_x = static_cast<float>(window_x) - left_padding;
|
||||||
const float scaled_display_y = static_cast<float>(window_y - (top_padding + top_margin));
|
const float scaled_display_y = static_cast<float>(window_y) - top_padding + static_cast<float>(top_margin);
|
||||||
|
|
||||||
// scale back to internal resolution
|
// scale back to internal resolution
|
||||||
const float display_x = scaled_display_x / scale;
|
const float display_x = scaled_display_x / scale / x_scale;
|
||||||
const float display_y = scaled_display_y / scale / y_scale;
|
const float display_y = scaled_display_y / scale;
|
||||||
|
|
||||||
return std::make_tuple(display_x, display_y);
|
return std::make_tuple(display_x, display_y);
|
||||||
}
|
}
|
||||||
|
@ -486,52 +491,29 @@ bool HostDisplay::WriteDisplayTextureToFile(std::string filename, bool full_reso
|
||||||
if (!m_display_texture_handle)
|
if (!m_display_texture_handle)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
apply_aspect_ratio = (m_display_aspect_ratio > 0) ? apply_aspect_ratio : false;
|
|
||||||
|
|
||||||
s32 resize_width = 0;
|
s32 resize_width = 0;
|
||||||
s32 resize_height = 0;
|
s32 resize_height = std::abs(m_display_texture_view_height);
|
||||||
if (apply_aspect_ratio && full_resolution)
|
if (apply_aspect_ratio)
|
||||||
{
|
{
|
||||||
if (m_display_aspect_ratio > 1.0f)
|
const float ss_width_scale = static_cast<float>(m_display_active_width) / static_cast<float>(m_display_width);
|
||||||
|
const float ss_height_scale = static_cast<float>(m_display_active_height) / static_cast<float>(m_display_height);
|
||||||
|
const float ss_aspect_ratio = m_display_aspect_ratio * ss_width_scale / ss_height_scale;
|
||||||
|
resize_width = static_cast<s32>(static_cast<float>(resize_height) * ss_aspect_ratio);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
resize_width = m_display_texture_view_width;
|
resize_width = m_display_texture_view_width;
|
||||||
resize_height = static_cast<s32>(static_cast<float>(resize_width) / m_display_aspect_ratio);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resize_height = std::abs(m_display_texture_view_height);
|
|
||||||
resize_width = static_cast<s32>(static_cast<float>(resize_height) * m_display_aspect_ratio);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (apply_aspect_ratio)
|
|
||||||
{
|
|
||||||
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<float>(m_display_texture_view_width) / static_cast<float>(std::abs(m_display_texture_view_height));
|
|
||||||
if (ratio > 1.0f)
|
|
||||||
{
|
|
||||||
resize_width = right - left;
|
|
||||||
resize_height = static_cast<s32>(static_cast<float>(resize_width) / ratio);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resize_height = bottom - top;
|
|
||||||
resize_width = static_cast<s32>(static_cast<float>(resize_height) * ratio);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resize_width < 0)
|
if (!full_resolution)
|
||||||
resize_width = 1;
|
{
|
||||||
if (resize_height < 0)
|
const s32 resolution_scale = std::abs(m_display_texture_view_height) / m_display_active_height;
|
||||||
resize_height = 1;
|
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);
|
const bool flip_y = (m_display_texture_view_height < 0);
|
||||||
s32 read_height = m_display_texture_view_height;
|
s32 read_height = m_display_texture_view_height;
|
||||||
|
|
|
@ -213,9 +213,9 @@ protected:
|
||||||
ALWAYS_INLINE bool HasSoftwareCursor() const { return static_cast<bool>(m_cursor_texture); }
|
ALWAYS_INLINE bool HasSoftwareCursor() const { return static_cast<bool>(m_cursor_texture); }
|
||||||
ALWAYS_INLINE bool HasDisplayTexture() const { return (m_display_texture_handle != nullptr); }
|
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,
|
void CalculateDrawRect(s32 window_width, s32 window_height, float* out_left, float* out_top, float* out_width,
|
||||||
s32* out_height, s32* out_left_padding, s32* out_top_padding, float* out_scale,
|
float* out_height, float* out_left_padding, float* 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<s32, s32, s32, s32> CalculateSoftwareCursorDrawRect() const;
|
std::tuple<s32, s32, s32, s32> CalculateSoftwareCursorDrawRect() const;
|
||||||
std::tuple<s32, s32, s32, s32> CalculateSoftwareCursorDrawRect(s32 cursor_x, s32 cursor_y) const;
|
std::tuple<s32, s32, s32, s32> CalculateSoftwareCursorDrawRect(s32 cursor_x, s32 cursor_y) const;
|
||||||
|
|
|
@ -1006,7 +1006,7 @@ void VulkanHostDisplay::ApplyPostProcessingChain(s32 final_left, s32 final_top,
|
||||||
Assert(pps.uniforms_size <= sizeof(buffer));
|
Assert(pps.uniforms_size <= sizeof(buffer));
|
||||||
m_post_processing_chain.GetShaderStage(i).FillUniformBuffer(
|
m_post_processing_chain.GetShaderStage(i).FillUniformBuffer(
|
||||||
buffer, texture_width, texture_height, texture_view_x, texture_view_y, texture_view_width, texture_view_height,
|
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,
|
vkCmdPushConstants(cmdbuffer, m_post_process_pipeline_layout,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, pps.uniforms_size, buffer);
|
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, pps.uniforms_size, buffer);
|
||||||
|
|
Loading…
Reference in a new issue