mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-01-20 07:15:38 +00:00
GPU: Remove duplicate display params fields
And enable postfx when the DAC is turned off.
This commit is contained in:
parent
e4cb359625
commit
810ce1ce57
361
src/core/gpu.cpp
361
src/core/gpu.cpp
|
@ -578,7 +578,11 @@ float GPU::ComputeVerticalFrequency() const
|
||||||
|
|
||||||
float GPU::ComputeDisplayAspectRatio() const
|
float GPU::ComputeDisplayAspectRatio() const
|
||||||
{
|
{
|
||||||
if (g_settings.display_force_4_3_for_24bit && m_GPUSTAT.display_area_color_depth_24)
|
if (g_settings.debugging.show_vram)
|
||||||
|
{
|
||||||
|
return static_cast<float>(VRAM_WIDTH) / static_cast<float>(VRAM_HEIGHT);
|
||||||
|
}
|
||||||
|
else if (g_settings.display_force_4_3_for_24bit && m_GPUSTAT.display_area_color_depth_24)
|
||||||
{
|
{
|
||||||
return 4.0f / 3.0f;
|
return 4.0f / 3.0f;
|
||||||
}
|
}
|
||||||
|
@ -1916,36 +1920,14 @@ void GPU::SetDisplayTexture(GPUTexture* texture, s32 view_x, s32 view_y, s32 vie
|
||||||
m_display_texture_view_height = view_height;
|
m_display_texture_view_height = view_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU::SetDisplayTextureRect(s32 view_x, s32 view_y, s32 view_width, s32 view_height)
|
|
||||||
{
|
|
||||||
m_display_texture_view_x = view_x;
|
|
||||||
m_display_texture_view_y = view_y;
|
|
||||||
m_display_texture_view_width = view_width;
|
|
||||||
m_display_texture_view_height = view_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPU::SetDisplayParameters(s32 display_width, s32 display_height, s32 active_left, s32 active_top, s32 active_width,
|
|
||||||
s32 active_height, float display_aspect_ratio)
|
|
||||||
{
|
|
||||||
m_display_width = display_width;
|
|
||||||
m_display_height = display_height;
|
|
||||||
m_display_active_left = active_left;
|
|
||||||
m_display_active_top = active_top;
|
|
||||||
m_display_active_width = active_width;
|
|
||||||
m_display_active_height = active_height;
|
|
||||||
m_display_aspect_ratio = display_aspect_ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GPU::PresentDisplay()
|
bool GPU::PresentDisplay()
|
||||||
{
|
{
|
||||||
FlushRender();
|
FlushRender();
|
||||||
|
|
||||||
if (!HasDisplayTexture())
|
|
||||||
return g_gpu_device->BeginPresent(false);
|
|
||||||
|
|
||||||
const Common::Rectangle<s32> draw_rect =
|
const Common::Rectangle<s32> draw_rect =
|
||||||
CalculateDrawRect(g_gpu_device->GetWindowWidth(), g_gpu_device->GetWindowHeight());
|
m_display_texture ? CalculateDrawRect(g_gpu_device->GetWindowWidth(), g_gpu_device->GetWindowHeight()) :
|
||||||
return RenderDisplay(nullptr, draw_rect, true);
|
Common::Rectangle<s32>();
|
||||||
|
return RenderDisplay(nullptr, draw_rect, !g_settings.debugging.show_vram);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_rect, bool postfx)
|
bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_rect, bool postfx)
|
||||||
|
@ -1956,53 +1938,12 @@ bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_r
|
||||||
if (m_display_texture)
|
if (m_display_texture)
|
||||||
m_display_texture->MakeReadyForSampling();
|
m_display_texture->MakeReadyForSampling();
|
||||||
|
|
||||||
bool texture_filter_linear = false;
|
|
||||||
|
|
||||||
struct Uniforms
|
|
||||||
{
|
|
||||||
float src_rect[4];
|
|
||||||
float src_size[4];
|
|
||||||
float clamp_rect[4];
|
|
||||||
float params[4];
|
|
||||||
} uniforms;
|
|
||||||
std::memset(uniforms.params, 0, sizeof(uniforms.params));
|
|
||||||
|
|
||||||
switch (g_settings.display_scaling)
|
|
||||||
{
|
|
||||||
case DisplayScalingMode::Nearest:
|
|
||||||
case DisplayScalingMode::NearestInteger:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DisplayScalingMode::BilinearSmooth:
|
|
||||||
case DisplayScalingMode::BlinearInteger:
|
|
||||||
texture_filter_linear = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DisplayScalingMode::BilinearSharp:
|
|
||||||
{
|
|
||||||
texture_filter_linear = true;
|
|
||||||
uniforms.params[0] = std::max(
|
|
||||||
std::floor(static_cast<float>(draw_rect.GetWidth()) / static_cast<float>(m_display_texture_view_width)), 1.0f);
|
|
||||||
uniforms.params[1] = std::max(
|
|
||||||
std::floor(static_cast<float>(draw_rect.GetHeight()) / static_cast<float>(m_display_texture_view_height)),
|
|
||||||
1.0f);
|
|
||||||
uniforms.params[2] = 0.5f - 0.5f / uniforms.params[0];
|
|
||||||
uniforms.params[3] = 0.5f - 0.5f / uniforms.params[1];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
UnreachableCode();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const GPUTexture::Format hdformat = target ? target->GetFormat() : g_gpu_device->GetWindowFormat();
|
const GPUTexture::Format hdformat = target ? target->GetFormat() : g_gpu_device->GetWindowFormat();
|
||||||
const u32 target_width = target ? target->GetWidth() : g_gpu_device->GetWindowWidth();
|
const u32 target_width = target ? target->GetWidth() : g_gpu_device->GetWindowWidth();
|
||||||
const u32 target_height = target ? target->GetHeight() : g_gpu_device->GetWindowHeight();
|
const u32 target_height = target ? target->GetHeight() : g_gpu_device->GetWindowHeight();
|
||||||
const bool really_postfx =
|
const bool really_postfx = (postfx && PostProcessing::IsActive() && !g_gpu_device->GetWindowInfo().IsSurfaceless() &&
|
||||||
(postfx && HasDisplayTexture() && PostProcessing::IsActive() && !g_gpu_device->GetWindowInfo().IsSurfaceless() &&
|
hdformat != GPUTexture::Format::Unknown && target_width > 0 && target_height > 0 &&
|
||||||
hdformat != GPUTexture::Format::Unknown && target_width > 0 && target_height > 0 &&
|
PostProcessing::CheckTargets(hdformat, target_width, target_height));
|
||||||
PostProcessing::CheckTargets(hdformat, target_width, target_height));
|
|
||||||
const Common::Rectangle<s32> real_draw_rect =
|
const Common::Rectangle<s32> real_draw_rect =
|
||||||
g_gpu_device->UsesLowerLeftOrigin() ? GPUDevice::FlipToLowerLeft(draw_rect, target_height) : draw_rect;
|
g_gpu_device->UsesLowerLeftOrigin() ? GPUDevice::FlipToLowerLeft(draw_rect, target_height) : draw_rect;
|
||||||
if (really_postfx)
|
if (really_postfx)
|
||||||
|
@ -2018,50 +1959,94 @@ bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_r
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HasDisplayTexture())
|
if (m_display_texture)
|
||||||
return true;
|
{
|
||||||
|
bool texture_filter_linear = false;
|
||||||
|
|
||||||
g_gpu_device->SetPipeline(m_display_pipeline.get());
|
struct Uniforms
|
||||||
g_gpu_device->SetTextureSampler(
|
{
|
||||||
0, m_display_texture, texture_filter_linear ? g_gpu_device->GetLinearSampler() : g_gpu_device->GetNearestSampler());
|
float src_rect[4];
|
||||||
|
float src_size[4];
|
||||||
|
float clamp_rect[4];
|
||||||
|
float params[4];
|
||||||
|
} uniforms;
|
||||||
|
std::memset(uniforms.params, 0, sizeof(uniforms.params));
|
||||||
|
|
||||||
// For bilinear, clamp to 0.5/SIZE-0.5 to avoid bleeding from the adjacent texels in VRAM. This is because
|
switch (g_settings.display_scaling)
|
||||||
// 1.0 in UV space is not the bottom-right texel, but a mix of the bottom-right and wrapped/next texel.
|
{
|
||||||
const float rcp_width = 1.0f / static_cast<float>(m_display_texture->GetWidth());
|
case DisplayScalingMode::Nearest:
|
||||||
const float rcp_height = 1.0f / static_cast<float>(m_display_texture->GetHeight());
|
case DisplayScalingMode::NearestInteger:
|
||||||
uniforms.src_rect[0] = static_cast<float>(m_display_texture_view_x) * rcp_width;
|
break;
|
||||||
uniforms.src_rect[1] = static_cast<float>(m_display_texture_view_y) * rcp_height;
|
|
||||||
uniforms.src_rect[2] = static_cast<float>(m_display_texture_view_width) * rcp_width;
|
|
||||||
uniforms.src_rect[3] = static_cast<float>(m_display_texture_view_height) * rcp_height;
|
|
||||||
uniforms.clamp_rect[0] = (static_cast<float>(m_display_texture_view_x) + 0.5f) * rcp_width;
|
|
||||||
uniforms.clamp_rect[1] = (static_cast<float>(m_display_texture_view_y) + 0.5f) * rcp_height;
|
|
||||||
uniforms.clamp_rect[2] =
|
|
||||||
(static_cast<float>(m_display_texture_view_x + m_display_texture_view_width) - 0.5f) * rcp_width;
|
|
||||||
uniforms.clamp_rect[3] =
|
|
||||||
(static_cast<float>(m_display_texture_view_y + m_display_texture_view_height) - 0.5f) * rcp_height;
|
|
||||||
uniforms.src_size[0] = static_cast<float>(m_display_texture->GetWidth());
|
|
||||||
uniforms.src_size[1] = static_cast<float>(m_display_texture->GetHeight());
|
|
||||||
uniforms.src_size[2] = rcp_width;
|
|
||||||
uniforms.src_size[3] = rcp_height;
|
|
||||||
g_gpu_device->PushUniformBuffer(&uniforms, sizeof(uniforms));
|
|
||||||
|
|
||||||
g_gpu_device->SetViewportAndScissor(real_draw_rect.left, real_draw_rect.top, real_draw_rect.GetWidth(),
|
case DisplayScalingMode::BilinearSmooth:
|
||||||
real_draw_rect.GetHeight());
|
case DisplayScalingMode::BlinearInteger:
|
||||||
g_gpu_device->Draw(3, 0);
|
texture_filter_linear = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DisplayScalingMode::BilinearSharp:
|
||||||
|
{
|
||||||
|
texture_filter_linear = true;
|
||||||
|
uniforms.params[0] = std::max(
|
||||||
|
std::floor(static_cast<float>(draw_rect.GetWidth()) / static_cast<float>(m_display_texture_view_width)),
|
||||||
|
1.0f);
|
||||||
|
uniforms.params[1] = std::max(
|
||||||
|
std::floor(static_cast<float>(draw_rect.GetHeight()) / static_cast<float>(m_display_texture_view_height)),
|
||||||
|
1.0f);
|
||||||
|
uniforms.params[2] = 0.5f - 0.5f / uniforms.params[0];
|
||||||
|
uniforms.params[3] = 0.5f - 0.5f / uniforms.params[1];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
UnreachableCode();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_gpu_device->SetPipeline(m_display_pipeline.get());
|
||||||
|
g_gpu_device->SetTextureSampler(0, m_display_texture,
|
||||||
|
texture_filter_linear ? g_gpu_device->GetLinearSampler() :
|
||||||
|
g_gpu_device->GetNearestSampler());
|
||||||
|
|
||||||
|
// For bilinear, clamp to 0.5/SIZE-0.5 to avoid bleeding from the adjacent texels in VRAM. This is because
|
||||||
|
// 1.0 in UV space is not the bottom-right texel, but a mix of the bottom-right and wrapped/next texel.
|
||||||
|
const float rcp_width = 1.0f / static_cast<float>(m_display_texture->GetWidth());
|
||||||
|
const float rcp_height = 1.0f / static_cast<float>(m_display_texture->GetHeight());
|
||||||
|
uniforms.src_rect[0] = static_cast<float>(m_display_texture_view_x) * rcp_width;
|
||||||
|
uniforms.src_rect[1] = static_cast<float>(m_display_texture_view_y) * rcp_height;
|
||||||
|
uniforms.src_rect[2] = static_cast<float>(m_display_texture_view_width) * rcp_width;
|
||||||
|
uniforms.src_rect[3] = static_cast<float>(m_display_texture_view_height) * rcp_height;
|
||||||
|
uniforms.clamp_rect[0] = (static_cast<float>(m_display_texture_view_x) + 0.5f) * rcp_width;
|
||||||
|
uniforms.clamp_rect[1] = (static_cast<float>(m_display_texture_view_y) + 0.5f) * rcp_height;
|
||||||
|
uniforms.clamp_rect[2] =
|
||||||
|
(static_cast<float>(m_display_texture_view_x + m_display_texture_view_width) - 0.5f) * rcp_width;
|
||||||
|
uniforms.clamp_rect[3] =
|
||||||
|
(static_cast<float>(m_display_texture_view_y + m_display_texture_view_height) - 0.5f) * rcp_height;
|
||||||
|
uniforms.src_size[0] = static_cast<float>(m_display_texture->GetWidth());
|
||||||
|
uniforms.src_size[1] = static_cast<float>(m_display_texture->GetHeight());
|
||||||
|
uniforms.src_size[2] = rcp_width;
|
||||||
|
uniforms.src_size[3] = rcp_height;
|
||||||
|
g_gpu_device->PushUniformBuffer(&uniforms, sizeof(uniforms));
|
||||||
|
|
||||||
|
g_gpu_device->SetViewportAndScissor(real_draw_rect.left, real_draw_rect.top, real_draw_rect.GetWidth(),
|
||||||
|
real_draw_rect.GetHeight());
|
||||||
|
g_gpu_device->Draw(3, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (really_postfx)
|
if (really_postfx)
|
||||||
{
|
{
|
||||||
|
DebugAssert(!g_settings.debugging.show_vram);
|
||||||
|
|
||||||
// "original size" in postfx includes padding.
|
// "original size" in postfx includes padding.
|
||||||
const float upscale_x =
|
const float upscale_x =
|
||||||
static_cast<float>(m_display_texture_view_width) / static_cast<float>(m_display_active_width);
|
static_cast<float>(m_display_texture_view_width) / static_cast<float>(m_crtc_state.display_vram_width);
|
||||||
const float upscale_y =
|
const float upscale_y =
|
||||||
static_cast<float>(m_display_texture_view_height) / static_cast<float>(m_display_active_height);
|
static_cast<float>(m_display_texture_view_height) / static_cast<float>(m_crtc_state.display_vram_height);
|
||||||
const s32 orig_width = static_cast<s32>(std::ceil(m_display_width * upscale_x));
|
const s32 orig_width = static_cast<s32>(std::ceil(static_cast<float>(m_crtc_state.display_width) * upscale_x));
|
||||||
const s32 orig_height = static_cast<s32>(std::ceil(m_display_height * upscale_y));
|
const s32 orig_height = static_cast<s32>(std::ceil(static_cast<float>(m_crtc_state.display_height) * upscale_y));
|
||||||
|
|
||||||
return PostProcessing::Apply(target, real_draw_rect.left, real_draw_rect.top, real_draw_rect.GetWidth(),
|
return PostProcessing::Apply(target, real_draw_rect.left, real_draw_rect.top, real_draw_rect.GetWidth(),
|
||||||
real_draw_rect.GetHeight(), orig_width, orig_height, m_display_width,
|
real_draw_rect.GetHeight(), orig_width, orig_height, m_crtc_state.display_width,
|
||||||
m_display_height);
|
m_crtc_state.display_height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2077,17 +2062,20 @@ void GPU::DestroyDeinterlaceTextures()
|
||||||
m_current_deinterlace_buffer = 0;
|
m_current_deinterlace_buffer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPU::Deinterlace(GPUTexture* src, u32 x, u32 y, u32 width, u32 height, u32 field, u32 line_skip)
|
bool GPU::Deinterlace(u32 field, u32 line_skip)
|
||||||
{
|
{
|
||||||
|
GPUTexture* src = m_display_texture;
|
||||||
|
const u32 x = m_display_texture_view_x;
|
||||||
|
const u32 y = m_display_texture_view_y;
|
||||||
|
const u32 width = m_display_texture_view_width;
|
||||||
|
const u32 height = m_display_texture_view_height;
|
||||||
|
|
||||||
switch (g_settings.display_deinterlacing_mode)
|
switch (g_settings.display_deinterlacing_mode)
|
||||||
{
|
{
|
||||||
case DisplayDeinterlacingMode::Disabled:
|
case DisplayDeinterlacingMode::Disabled:
|
||||||
{
|
{
|
||||||
if (line_skip == 0)
|
if (line_skip == 0)
|
||||||
{
|
|
||||||
SetDisplayTexture(src, x, y, width, height);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
// Still have to extract the field.
|
// Still have to extract the field.
|
||||||
if (!DeinterlaceExtractField(0, src, x, y, width, height, line_skip)) [[unlikely]]
|
if (!DeinterlaceExtractField(0, src, x, y, width, height, line_skip)) [[unlikely]]
|
||||||
|
@ -2257,8 +2245,12 @@ bool GPU::DeinterlaceSetTargetSize(u32 width, u32 height, bool preserve)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPU::ApplyChromaSmoothing(GPUTexture* src, u32 x, u32 y, u32 width, u32 height)
|
bool GPU::ApplyChromaSmoothing()
|
||||||
{
|
{
|
||||||
|
const u32 x = m_display_texture_view_x;
|
||||||
|
const u32 y = m_display_texture_view_y;
|
||||||
|
const u32 width = m_display_texture_view_width;
|
||||||
|
const u32 height = m_display_texture_view_height;
|
||||||
if (!m_chroma_smoothing_texture || m_chroma_smoothing_texture->GetWidth() != width ||
|
if (!m_chroma_smoothing_texture || m_chroma_smoothing_texture->GetWidth() != width ||
|
||||||
m_chroma_smoothing_texture->GetHeight() != height)
|
m_chroma_smoothing_texture->GetHeight() != height)
|
||||||
{
|
{
|
||||||
|
@ -2274,11 +2266,11 @@ bool GPU::ApplyChromaSmoothing(GPUTexture* src, u32 x, u32 y, u32 width, u32 hei
|
||||||
|
|
||||||
GL_SCOPE_FMT("ApplyChromaSmoothing({{{},{}}}, {}x{})", x, y, width, height);
|
GL_SCOPE_FMT("ApplyChromaSmoothing({{{},{}}}, {}x{})", x, y, width, height);
|
||||||
|
|
||||||
src->MakeReadyForSampling();
|
m_display_texture->MakeReadyForSampling();
|
||||||
g_gpu_device->InvalidateRenderTarget(m_chroma_smoothing_texture.get());
|
g_gpu_device->InvalidateRenderTarget(m_chroma_smoothing_texture.get());
|
||||||
g_gpu_device->SetRenderTarget(m_chroma_smoothing_texture.get());
|
g_gpu_device->SetRenderTarget(m_chroma_smoothing_texture.get());
|
||||||
g_gpu_device->SetPipeline(m_chroma_smoothing_pipeline.get());
|
g_gpu_device->SetPipeline(m_chroma_smoothing_pipeline.get());
|
||||||
g_gpu_device->SetTextureSampler(0, src, g_gpu_device->GetNearestSampler());
|
g_gpu_device->SetTextureSampler(0, m_display_texture, g_gpu_device->GetNearestSampler());
|
||||||
const u32 uniforms[] = {x, y, width - 1, height - 1};
|
const u32 uniforms[] = {x, y, width - 1, height - 1};
|
||||||
g_gpu_device->PushUniformBuffer(uniforms, sizeof(uniforms));
|
g_gpu_device->PushUniformBuffer(uniforms, sizeof(uniforms));
|
||||||
g_gpu_device->SetViewportAndScissor(0, 0, width, height);
|
g_gpu_device->SetViewportAndScissor(0, 0, width, height);
|
||||||
|
@ -2289,68 +2281,70 @@ bool GPU::ApplyChromaSmoothing(GPUTexture* src, u32 x, u32 y, u32 width, u32 hei
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Rectangle<float> GPU::CalculateDrawRect(s32 window_width, s32 window_height, float* out_left_padding,
|
Common::Rectangle<s32> GPU::CalculateDrawRect(s32 window_width, s32 window_height,
|
||||||
float* out_top_padding, float* out_scale, float* out_x_scale,
|
bool apply_aspect_ratio /* = true */) const
|
||||||
bool apply_aspect_ratio /* = true */) const
|
|
||||||
{
|
{
|
||||||
const bool integer_scale = (g_settings.display_scaling == DisplayScalingMode::NearestInteger ||
|
const bool integer_scale = (g_settings.display_scaling == DisplayScalingMode::NearestInteger ||
|
||||||
g_settings.display_scaling == DisplayScalingMode::BlinearInteger);
|
g_settings.display_scaling == DisplayScalingMode::BlinearInteger);
|
||||||
|
const bool show_vram = g_settings.debugging.show_vram;
|
||||||
|
const float display_aspect_ratio = ComputeDisplayAspectRatio();
|
||||||
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);
|
||||||
|
const float crtc_display_width = static_cast<float>(show_vram ? VRAM_WIDTH : m_crtc_state.display_width);
|
||||||
|
const float crtc_display_height = static_cast<float>(show_vram ? VRAM_HEIGHT : m_crtc_state.display_height);
|
||||||
const float x_scale =
|
const float x_scale =
|
||||||
apply_aspect_ratio ?
|
apply_aspect_ratio ?
|
||||||
(m_display_aspect_ratio / (static_cast<float>(m_display_width) / static_cast<float>(m_display_height))) :
|
(display_aspect_ratio / (static_cast<float>(crtc_display_width) / static_cast<float>(crtc_display_height))) :
|
||||||
1.0f;
|
1.0f;
|
||||||
const float display_width = g_settings.display_stretch_vertically ? static_cast<float>(m_display_width) :
|
float display_width = crtc_display_width;
|
||||||
static_cast<float>(m_display_width) * x_scale;
|
float display_height = crtc_display_height;
|
||||||
const float display_height = g_settings.display_stretch_vertically ? static_cast<float>(m_display_height) / x_scale :
|
float active_left = static_cast<float>(show_vram ? 0 : m_crtc_state.display_origin_left);
|
||||||
static_cast<float>(m_display_height);
|
float active_top = static_cast<float>(show_vram ? 0 : m_crtc_state.display_origin_top);
|
||||||
const float active_left = g_settings.display_stretch_vertically ? static_cast<float>(m_display_active_left) :
|
float active_width = static_cast<float>(show_vram ? VRAM_WIDTH : m_crtc_state.display_vram_width);
|
||||||
static_cast<float>(m_display_active_left) * x_scale;
|
float active_height = static_cast<float>(show_vram ? VRAM_HEIGHT : m_crtc_state.display_vram_height);
|
||||||
const float active_top = g_settings.display_stretch_vertically ? static_cast<float>(m_display_active_top) / x_scale :
|
if (!g_settings.display_stretch_vertically)
|
||||||
static_cast<float>(m_display_active_top);
|
{
|
||||||
const float active_width = g_settings.display_stretch_vertically ?
|
display_width *= x_scale;
|
||||||
static_cast<float>(m_display_active_width) :
|
active_left *= x_scale;
|
||||||
static_cast<float>(m_display_active_width) * x_scale;
|
active_width *= x_scale;
|
||||||
const float active_height = g_settings.display_stretch_vertically ?
|
}
|
||||||
static_cast<float>(m_display_active_height) / x_scale :
|
else
|
||||||
static_cast<float>(m_display_active_height);
|
{
|
||||||
if (out_x_scale)
|
display_height /= x_scale;
|
||||||
*out_x_scale = x_scale;
|
active_top /= x_scale;
|
||||||
|
active_height /= x_scale;
|
||||||
|
}
|
||||||
|
|
||||||
// now fit it within the window
|
// now fit it within the window
|
||||||
float scale;
|
float scale;
|
||||||
|
float left_padding, top_padding;
|
||||||
if ((display_width / display_height) >= window_ratio)
|
if ((display_width / display_height) >= window_ratio)
|
||||||
{
|
{
|
||||||
// align in middle vertically
|
// align in middle vertically
|
||||||
scale = static_cast<float>(window_width) / display_width;
|
scale = static_cast<float>(window_width) / display_width;
|
||||||
if (integer_scale)
|
if (integer_scale)
|
||||||
|
{
|
||||||
scale = std::max(std::floor(scale), 1.0f);
|
scale = std::max(std::floor(scale), 1.0f);
|
||||||
|
left_padding = std::max<float>((static_cast<float>(window_width) - display_width * scale) / 2.0f, 0.0f);
|
||||||
if (out_left_padding)
|
|
||||||
{
|
|
||||||
if (integer_scale)
|
|
||||||
*out_left_padding = std::max<float>((static_cast<float>(window_width) - display_width * scale) / 2.0f, 0.0f);
|
|
||||||
else
|
|
||||||
*out_left_padding = 0.0f;
|
|
||||||
}
|
}
|
||||||
if (out_top_padding)
|
else
|
||||||
{
|
{
|
||||||
switch (g_settings.display_alignment)
|
left_padding = 0.0f;
|
||||||
{
|
}
|
||||||
case DisplayAlignment::RightOrBottom:
|
|
||||||
*out_top_padding = std::max<float>(static_cast<float>(window_height) - (display_height * scale), 0.0f);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DisplayAlignment::Center:
|
switch (g_settings.display_alignment)
|
||||||
*out_top_padding =
|
{
|
||||||
std::max<float>((static_cast<float>(window_height) - (display_height * scale)) / 2.0f, 0.0f);
|
case DisplayAlignment::RightOrBottom:
|
||||||
break;
|
top_padding = std::max<float>(static_cast<float>(window_height) - (display_height * scale), 0.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
case DisplayAlignment::LeftOrTop:
|
case DisplayAlignment::Center:
|
||||||
default:
|
top_padding = std::max<float>((static_cast<float>(window_height) - (display_height * scale)) / 2.0f, 0.0f);
|
||||||
*out_top_padding = 0.0f;
|
break;
|
||||||
break;
|
|
||||||
}
|
case DisplayAlignment::LeftOrTop:
|
||||||
|
default:
|
||||||
|
top_padding = 0.0f;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2358,55 +2352,36 @@ Common::Rectangle<float> GPU::CalculateDrawRect(s32 window_width, s32 window_hei
|
||||||
// align in middle horizontally
|
// align in middle horizontally
|
||||||
scale = static_cast<float>(window_height) / display_height;
|
scale = static_cast<float>(window_height) / display_height;
|
||||||
if (integer_scale)
|
if (integer_scale)
|
||||||
scale = std::max(std::floor(scale), 1.0f);
|
|
||||||
|
|
||||||
if (out_left_padding)
|
|
||||||
{
|
{
|
||||||
switch (g_settings.display_alignment)
|
scale = std::max(std::floor(scale), 1.0f);
|
||||||
{
|
top_padding = std::max<float>((static_cast<float>(window_height) - (display_height * scale)) / 2.0f, 0.0f);
|
||||||
case DisplayAlignment::RightOrBottom:
|
}
|
||||||
*out_left_padding = std::max<float>(static_cast<float>(window_width) - (display_width * scale), 0.0f);
|
else
|
||||||
break;
|
{
|
||||||
|
top_padding = 0.0f;
|
||||||
case DisplayAlignment::Center:
|
|
||||||
*out_left_padding =
|
|
||||||
std::max<float>((static_cast<float>(window_width) - (display_width * scale)) / 2.0f, 0.0f);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DisplayAlignment::LeftOrTop:
|
|
||||||
default:
|
|
||||||
*out_left_padding = 0.0f;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out_top_padding)
|
switch (g_settings.display_alignment)
|
||||||
{
|
{
|
||||||
if (integer_scale)
|
case DisplayAlignment::RightOrBottom:
|
||||||
*out_top_padding = std::max<float>((static_cast<float>(window_height) - (display_height * scale)) / 2.0f, 0.0f);
|
left_padding = std::max<float>(static_cast<float>(window_width) - (display_width * scale), 0.0f);
|
||||||
else
|
break;
|
||||||
*out_top_padding = 0.0f;
|
|
||||||
|
case DisplayAlignment::Center:
|
||||||
|
left_padding = std::max<float>((static_cast<float>(window_width) - (display_width * scale)) / 2.0f, 0.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DisplayAlignment::LeftOrTop:
|
||||||
|
default:
|
||||||
|
left_padding = 0.0f;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out_scale)
|
|
||||||
*out_scale = scale;
|
|
||||||
|
|
||||||
return Common::Rectangle<float>::FromExtents(active_left * scale, active_top * scale, active_width * scale,
|
|
||||||
active_height * scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
Common::Rectangle<s32> GPU::CalculateDrawRect(s32 window_width, s32 window_height,
|
|
||||||
bool apply_aspect_ratio /* = true */) const
|
|
||||||
{
|
|
||||||
float left_padding, top_padding;
|
|
||||||
const Common::Rectangle<float> draw_rc =
|
|
||||||
CalculateDrawRect(window_width, window_height, &left_padding, &top_padding, nullptr, nullptr, apply_aspect_ratio);
|
|
||||||
|
|
||||||
// TODO: This should be a float rectangle. But because GL is lame, it only has integer viewports...
|
// TODO: This should be a float rectangle. But because GL is lame, it only has integer viewports...
|
||||||
return Common::Rectangle<s32>::FromExtents(
|
return Common::Rectangle<s32>::FromExtents(
|
||||||
static_cast<s32>(draw_rc.left + left_padding), static_cast<s32>(draw_rc.top + top_padding),
|
static_cast<s32>(active_left * scale + left_padding), static_cast<s32>(active_top * scale + top_padding),
|
||||||
static_cast<s32>(draw_rc.GetWidth()), static_cast<s32>(draw_rc.GetHeight()));
|
static_cast<s32>(active_width * scale), static_cast<s32>(active_height * scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompressAndWriteTextureToFile(u32 width, u32 height, std::string filename, FileSystem::ManagedCFilePtr fp,
|
bool CompressAndWriteTextureToFile(u32 width, u32 height, std::string filename, FileSystem::ManagedCFilePtr fp,
|
||||||
|
@ -2632,7 +2607,7 @@ bool GPU::RenderScreenshotToFile(std::string filename, DisplayScreenshotMode mod
|
||||||
u32 height = g_gpu_device->GetWindowHeight();
|
u32 height = g_gpu_device->GetWindowHeight();
|
||||||
Common::Rectangle<s32> draw_rect = CalculateDrawRect(width, height);
|
Common::Rectangle<s32> draw_rect = CalculateDrawRect(width, height);
|
||||||
|
|
||||||
const bool internal_resolution = (mode != DisplayScreenshotMode::ScreenResolution);
|
const bool internal_resolution = (mode != DisplayScreenshotMode::ScreenResolution || g_settings.debugging.show_vram);
|
||||||
if (internal_resolution && m_display_texture_view_width != 0 && m_display_texture_view_height != 0)
|
if (internal_resolution && m_display_texture_view_width != 0 && m_display_texture_view_height != 0)
|
||||||
{
|
{
|
||||||
if (mode == DisplayScreenshotMode::InternalResolution)
|
if (mode == DisplayScreenshotMode::InternalResolution)
|
||||||
|
|
|
@ -194,7 +194,9 @@ public:
|
||||||
|
|
||||||
// Returns the video clock frequency.
|
// Returns the video clock frequency.
|
||||||
TickCount GetCRTCFrequency() const;
|
TickCount GetCRTCFrequency() const;
|
||||||
u16 GetCRTCDotClockDivider() const { return m_crtc_state.dot_clock_divider; }
|
ALWAYS_INLINE u16 GetCRTCDotClockDivider() const { return m_crtc_state.dot_clock_divider; }
|
||||||
|
ALWAYS_INLINE s32 GetCRTCDisplayWidth() const { return m_crtc_state.display_width; }
|
||||||
|
ALWAYS_INLINE s32 GetCRTCDisplayHeight() const { return m_crtc_state.display_height; }
|
||||||
|
|
||||||
// Dumps raw VRAM to a file.
|
// Dumps raw VRAM to a file.
|
||||||
bool DumpVRAMToFile(const char* filename);
|
bool DumpVRAMToFile(const char* filename);
|
||||||
|
@ -202,12 +204,6 @@ public:
|
||||||
// Ensures all buffered vertices are drawn.
|
// Ensures all buffered vertices are drawn.
|
||||||
virtual void FlushRender() = 0;
|
virtual void FlushRender() = 0;
|
||||||
|
|
||||||
ALWAYS_INLINE const void* GetDisplayTextureHandle() const { return m_display_texture; }
|
|
||||||
ALWAYS_INLINE s32 GetDisplayWidth() const { return m_display_width; }
|
|
||||||
ALWAYS_INLINE s32 GetDisplayHeight() const { return m_display_height; }
|
|
||||||
ALWAYS_INLINE float GetDisplayAspectRatio() const { return m_display_aspect_ratio; }
|
|
||||||
ALWAYS_INLINE bool HasDisplayTexture() const { return static_cast<bool>(m_display_texture); }
|
|
||||||
|
|
||||||
/// Helper function for computing the draw rectangle in a larger window.
|
/// Helper function for computing the draw rectangle in a larger window.
|
||||||
Common::Rectangle<s32> CalculateDrawRect(s32 window_width, s32 window_height, bool apply_aspect_ratio = true) const;
|
Common::Rectangle<s32> CalculateDrawRect(s32 window_width, s32 window_height, bool apply_aspect_ratio = true) const;
|
||||||
|
|
||||||
|
@ -607,29 +603,14 @@ protected:
|
||||||
|
|
||||||
void ClearDisplayTexture();
|
void ClearDisplayTexture();
|
||||||
void SetDisplayTexture(GPUTexture* texture, s32 view_x, s32 view_y, s32 view_width, s32 view_height);
|
void SetDisplayTexture(GPUTexture* texture, s32 view_x, s32 view_y, s32 view_width, s32 view_height);
|
||||||
void SetDisplayTextureRect(s32 view_x, s32 view_y, s32 view_width, s32 view_height);
|
|
||||||
void SetDisplayParameters(s32 display_width, s32 display_height, s32 active_left, s32 active_top, s32 active_width,
|
|
||||||
s32 active_height, float display_aspect_ratio);
|
|
||||||
|
|
||||||
Common::Rectangle<float> CalculateDrawRect(s32 window_width, s32 window_height, float* out_left_padding,
|
|
||||||
float* out_top_padding, float* out_scale, float* out_x_scale,
|
|
||||||
bool apply_aspect_ratio = true) const;
|
|
||||||
|
|
||||||
bool RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_rect, bool postfx);
|
bool RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_rect, bool postfx);
|
||||||
|
|
||||||
bool Deinterlace(GPUTexture* src, u32 x, u32 y, u32 width, u32 height, u32 field, u32 line_skip);
|
bool Deinterlace(u32 field, u32 line_skip);
|
||||||
bool DeinterlaceExtractField(u32 dst_bufidx, GPUTexture* src, u32 x, u32 y, u32 width, u32 height, u32 line_skip);
|
bool DeinterlaceExtractField(u32 dst_bufidx, GPUTexture* src, u32 x, u32 y, u32 width, u32 height, u32 line_skip);
|
||||||
bool DeinterlaceSetTargetSize(u32 width, u32 height, bool preserve);
|
bool DeinterlaceSetTargetSize(u32 width, u32 height, bool preserve);
|
||||||
void DestroyDeinterlaceTextures();
|
void DestroyDeinterlaceTextures();
|
||||||
bool ApplyChromaSmoothing(GPUTexture* src, u32 x, u32 y, u32 width, u32 height);
|
bool ApplyChromaSmoothing();
|
||||||
|
|
||||||
s32 m_display_width = 0;
|
|
||||||
s32 m_display_height = 0;
|
|
||||||
s32 m_display_active_left = 0;
|
|
||||||
s32 m_display_active_top = 0;
|
|
||||||
s32 m_display_active_width = 0;
|
|
||||||
s32 m_display_active_height = 0;
|
|
||||||
float m_display_aspect_ratio = 1.0f;
|
|
||||||
|
|
||||||
u32 m_current_deinterlace_buffer = 0;
|
u32 m_current_deinterlace_buffer = 0;
|
||||||
std::unique_ptr<GPUPipeline> m_deinterlace_pipeline;
|
std::unique_ptr<GPUPipeline> m_deinterlace_pipeline;
|
||||||
|
|
|
@ -3289,15 +3289,9 @@ void GPU_HW::UpdateDisplay()
|
||||||
SetDisplayTexture(m_vram_texture.get(), 0, 0, m_vram_texture->GetWidth(), m_vram_texture->GetHeight());
|
SetDisplayTexture(m_vram_texture.get(), 0, 0, m_vram_texture->GetWidth(), m_vram_texture->GetHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
|
|
||||||
static_cast<float>(VRAM_WIDTH) / static_cast<float>(VRAM_HEIGHT));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height, m_crtc_state.display_origin_left,
|
|
||||||
m_crtc_state.display_origin_top, m_crtc_state.display_vram_width,
|
|
||||||
m_crtc_state.display_vram_height, ComputeDisplayAspectRatio());
|
|
||||||
|
|
||||||
const bool interlaced = IsInterlacedDisplayEnabled();
|
const bool interlaced = IsInterlacedDisplayEnabled();
|
||||||
const u32 interlaced_field = GetInterlacedDisplayField();
|
const u32 interlaced_field = GetInterlacedDisplayField();
|
||||||
const u32 resolution_scale = m_GPUSTAT.display_area_color_depth_24 ? 1 : m_resolution_scale;
|
const u32 resolution_scale = m_GPUSTAT.display_area_color_depth_24 ? 1 : m_resolution_scale;
|
||||||
|
@ -3319,19 +3313,19 @@ void GPU_HW::UpdateDisplay()
|
||||||
(scaled_vram_offset_x + scaled_display_width) <= m_vram_texture->GetWidth() &&
|
(scaled_vram_offset_x + scaled_display_width) <= m_vram_texture->GetWidth() &&
|
||||||
(scaled_vram_offset_y + scaled_display_height) <= m_vram_texture->GetHeight())
|
(scaled_vram_offset_y + scaled_display_height) <= m_vram_texture->GetHeight())
|
||||||
{
|
{
|
||||||
|
SetDisplayTexture(m_vram_texture.get(), scaled_vram_offset_x, scaled_vram_offset_y, scaled_display_width,
|
||||||
|
read_height);
|
||||||
|
|
||||||
// Fast path if no copies are needed.
|
// Fast path if no copies are needed.
|
||||||
if (interlaced)
|
if (interlaced)
|
||||||
{
|
{
|
||||||
GL_INS("Deinterlace fast path");
|
GL_INS("Deinterlace fast path");
|
||||||
drew_anything = true;
|
drew_anything = true;
|
||||||
Deinterlace(m_vram_texture.get(), scaled_vram_offset_x, scaled_vram_offset_y, scaled_display_width, read_height,
|
Deinterlace(interlaced_field, line_skip);
|
||||||
interlaced_field, line_skip);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GL_INS("Direct display");
|
GL_INS("Direct display");
|
||||||
SetDisplayTexture(m_vram_texture.get(), scaled_vram_offset_x, scaled_vram_offset_y, scaled_display_width,
|
|
||||||
scaled_display_height);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3365,28 +3359,26 @@ void GPU_HW::UpdateDisplay()
|
||||||
m_vram_extract_texture->MakeReadyForSampling();
|
m_vram_extract_texture->MakeReadyForSampling();
|
||||||
drew_anything = true;
|
drew_anything = true;
|
||||||
|
|
||||||
|
SetDisplayTexture(m_vram_extract_texture.get(), 0, 0, scaled_display_width, read_height);
|
||||||
if (g_settings.gpu_24bit_chroma_smoothing)
|
if (g_settings.gpu_24bit_chroma_smoothing)
|
||||||
{
|
{
|
||||||
if (ApplyChromaSmoothing(m_vram_extract_texture.get(), 0, 0, scaled_display_width, read_height))
|
if (ApplyChromaSmoothing())
|
||||||
{
|
{
|
||||||
if (interlaced)
|
if (interlaced)
|
||||||
Deinterlace(m_display_texture, 0, 0, scaled_display_width, read_height, interlaced_field, 0);
|
Deinterlace(interlaced_field, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (interlaced)
|
if (interlaced)
|
||||||
Deinterlace(m_vram_extract_texture.get(), 0, 0, scaled_display_width, read_height, interlaced_field, 0);
|
Deinterlace(interlaced_field, 0);
|
||||||
else
|
|
||||||
SetDisplayTexture(m_vram_extract_texture.get(), 0, 0, scaled_display_width, read_height);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_downsample_mode != GPUDownsampleMode::Disabled && !m_GPUSTAT.display_area_color_depth_24)
|
if (m_downsample_mode != GPUDownsampleMode::Disabled && !m_GPUSTAT.display_area_color_depth_24)
|
||||||
{
|
{
|
||||||
DebugAssert(m_display_texture);
|
DebugAssert(m_display_texture);
|
||||||
DownsampleFramebuffer(m_display_texture, m_display_texture_view_x, m_display_texture_view_y,
|
DownsampleFramebuffer();
|
||||||
m_display_texture_view_width, m_display_texture_view_height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drew_anything)
|
if (drew_anything)
|
||||||
|
@ -3418,8 +3410,14 @@ void GPU_HW::UpdateDownsamplingLevels()
|
||||||
g_gpu_device->RecycleTexture(std::move(m_downsample_texture));
|
g_gpu_device->RecycleTexture(std::move(m_downsample_texture));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW::DownsampleFramebuffer(GPUTexture* source, u32 left, u32 top, u32 width, u32 height)
|
void GPU_HW::DownsampleFramebuffer()
|
||||||
{
|
{
|
||||||
|
GPUTexture* source = m_display_texture;
|
||||||
|
const u32 left = m_display_texture_view_x;
|
||||||
|
const u32 top = m_display_texture_view_y;
|
||||||
|
const u32 width = m_display_texture_view_width;
|
||||||
|
const u32 height = m_display_texture_view_height;
|
||||||
|
|
||||||
if (m_downsample_mode == GPUDownsampleMode::Adaptive)
|
if (m_downsample_mode == GPUDownsampleMode::Adaptive)
|
||||||
DownsampleFramebufferAdaptive(source, left, top, width, height);
|
DownsampleFramebufferAdaptive(source, left, top, width, height);
|
||||||
else
|
else
|
||||||
|
@ -3453,7 +3451,6 @@ void GPU_HW::DownsampleFramebufferAdaptive(GPUTexture* source, u32 left, u32 top
|
||||||
if (!m_downsample_texture || !level_texture || !weight_texture)
|
if (!m_downsample_texture || !level_texture || !weight_texture)
|
||||||
{
|
{
|
||||||
ERROR_LOG("Failed to create {}x{} RTs for adaptive downsampling", width, height);
|
ERROR_LOG("Failed to create {}x{} RTs for adaptive downsampling", width, height);
|
||||||
SetDisplayTexture(source, left, top, width, height);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3563,7 +3560,6 @@ void GPU_HW::DownsampleFramebufferBoxFilter(GPUTexture* source, u32 left, u32 to
|
||||||
if (!m_downsample_texture)
|
if (!m_downsample_texture)
|
||||||
{
|
{
|
||||||
ERROR_LOG("Failed to create {}x{} RT for box downsampling", width, height);
|
ERROR_LOG("Failed to create {}x{} RT for box downsampling", width, height);
|
||||||
SetDisplayTexture(source, left, top, width, height);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,8 @@ private:
|
||||||
void SetBatchSpriteMode(bool enabled);
|
void SetBatchSpriteMode(bool enabled);
|
||||||
|
|
||||||
void UpdateDownsamplingLevels();
|
void UpdateDownsamplingLevels();
|
||||||
void DownsampleFramebuffer(GPUTexture* source, u32 left, u32 top, u32 width, u32 height);
|
|
||||||
|
void DownsampleFramebuffer();
|
||||||
void DownsampleFramebufferAdaptive(GPUTexture* source, u32 left, u32 top, u32 width, u32 height);
|
void DownsampleFramebufferAdaptive(GPUTexture* source, u32 left, u32 top, u32 width, u32 height);
|
||||||
void DownsampleFramebufferBoxFilter(GPUTexture* source, u32 left, u32 top, u32 width, u32 height);
|
void DownsampleFramebufferBoxFilter(GPUTexture* source, u32 left, u32 top, u32 width, u32 height);
|
||||||
|
|
||||||
|
|
|
@ -465,10 +465,6 @@ void GPU_SW::UpdateDisplay()
|
||||||
|
|
||||||
if (!g_settings.debugging.show_vram)
|
if (!g_settings.debugging.show_vram)
|
||||||
{
|
{
|
||||||
SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height, m_crtc_state.display_origin_left,
|
|
||||||
m_crtc_state.display_origin_top, m_crtc_state.display_vram_width,
|
|
||||||
m_crtc_state.display_vram_height, ComputeDisplayAspectRatio());
|
|
||||||
|
|
||||||
if (IsDisplayDisabled())
|
if (IsDisplayDisabled())
|
||||||
{
|
{
|
||||||
ClearDisplayTexture();
|
ClearDisplayTexture();
|
||||||
|
@ -490,14 +486,15 @@ void GPU_SW::UpdateDisplay()
|
||||||
const u32 line_skip = m_GPUSTAT.vertical_resolution;
|
const u32 line_skip = m_GPUSTAT.vertical_resolution;
|
||||||
if (CopyOut(vram_offset_x, vram_offset_y, skip_x, read_width, read_height, line_skip, is_24bit))
|
if (CopyOut(vram_offset_x, vram_offset_y, skip_x, read_width, read_height, line_skip, is_24bit))
|
||||||
{
|
{
|
||||||
|
SetDisplayTexture(m_upload_texture.get(), 0, 0, read_width, read_height);
|
||||||
if (is_24bit && g_settings.gpu_24bit_chroma_smoothing)
|
if (is_24bit && g_settings.gpu_24bit_chroma_smoothing)
|
||||||
{
|
{
|
||||||
if (ApplyChromaSmoothing(m_upload_texture.get(), 0, 0, read_width, read_height))
|
if (ApplyChromaSmoothing())
|
||||||
Deinterlace(m_display_texture, 0, 0, read_width, read_height, field, 0);
|
Deinterlace(field, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Deinterlace(m_upload_texture.get(), 0, 0, read_width, read_height, field, 0);
|
Deinterlace(field, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -505,17 +502,14 @@ void GPU_SW::UpdateDisplay()
|
||||||
{
|
{
|
||||||
if (CopyOut(vram_offset_x, vram_offset_y, skip_x, read_width, read_height, 0, is_24bit))
|
if (CopyOut(vram_offset_x, vram_offset_y, skip_x, read_width, read_height, 0, is_24bit))
|
||||||
{
|
{
|
||||||
|
SetDisplayTexture(m_upload_texture.get(), 0, 0, read_width, read_height);
|
||||||
if (is_24bit && g_settings.gpu_24bit_chroma_smoothing)
|
if (is_24bit && g_settings.gpu_24bit_chroma_smoothing)
|
||||||
ApplyChromaSmoothing(m_upload_texture.get(), 0, 0, read_width, read_height);
|
ApplyChromaSmoothing();
|
||||||
else
|
|
||||||
SetDisplayTexture(m_upload_texture.get(), 0, 0, read_width, read_height);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
|
|
||||||
static_cast<float>(VRAM_WIDTH) / static_cast<float>(VRAM_HEIGHT));
|
|
||||||
if (CopyOut(0, 0, 0, VRAM_WIDTH, VRAM_HEIGHT, 0, false))
|
if (CopyOut(0, 0, 0, VRAM_WIDTH, VRAM_HEIGHT, 0, false))
|
||||||
SetDisplayTexture(m_upload_texture.get(), 0, 0, VRAM_WIDTH, VRAM_HEIGHT);
|
SetDisplayTexture(m_upload_texture.get(), 0, 0, VRAM_WIDTH, VRAM_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2661,7 +2661,7 @@ bool System::SaveStateToStream(ByteStream* state, Error* error, u32 screenshot_s
|
||||||
if (screenshot_size > 0)
|
if (screenshot_size > 0)
|
||||||
{
|
{
|
||||||
// assume this size is the width
|
// assume this size is the width
|
||||||
const float display_aspect_ratio = g_gpu->GetDisplayAspectRatio();
|
const float display_aspect_ratio = g_gpu->ComputeDisplayAspectRatio();
|
||||||
const u32 screenshot_width = screenshot_size;
|
const u32 screenshot_width = screenshot_size;
|
||||||
const u32 screenshot_height =
|
const u32 screenshot_height =
|
||||||
std::max(1u, static_cast<u32>(static_cast<float>(screenshot_width) /
|
std::max(1u, static_cast<u32>(static_cast<float>(screenshot_width) /
|
||||||
|
@ -5264,13 +5264,14 @@ void System::RequestDisplaySize(float scale /*= 0.0f*/)
|
||||||
if (scale == 0.0f)
|
if (scale == 0.0f)
|
||||||
scale = g_gpu->IsHardwareRenderer() ? static_cast<float>(g_settings.gpu_resolution_scale) : 1.0f;
|
scale = g_gpu->IsHardwareRenderer() ? static_cast<float>(g_settings.gpu_resolution_scale) : 1.0f;
|
||||||
|
|
||||||
const float y_scale = (static_cast<float>(g_gpu->GetDisplayWidth()) / static_cast<float>(g_gpu->GetDisplayHeight())) /
|
const float y_scale =
|
||||||
g_gpu->GetDisplayAspectRatio();
|
(static_cast<float>(g_gpu->GetCRTCDisplayWidth()) / static_cast<float>(g_gpu->GetCRTCDisplayHeight())) /
|
||||||
|
g_gpu->ComputeDisplayAspectRatio();
|
||||||
|
|
||||||
const u32 requested_width =
|
const u32 requested_width =
|
||||||
std::max<u32>(static_cast<u32>(std::ceil(static_cast<float>(g_gpu->GetDisplayWidth()) * scale)), 1);
|
std::max<u32>(static_cast<u32>(std::ceil(static_cast<float>(g_gpu->GetCRTCDisplayWidth()) * scale)), 1);
|
||||||
const u32 requested_height =
|
const u32 requested_height =
|
||||||
std::max<u32>(static_cast<u32>(std::ceil(static_cast<float>(g_gpu->GetDisplayHeight()) * y_scale * scale)), 1);
|
std::max<u32>(static_cast<u32>(std::ceil(static_cast<float>(g_gpu->GetCRTCDisplayHeight()) * y_scale * scale)), 1);
|
||||||
|
|
||||||
Host::RequestResizeHostDisplay(static_cast<s32>(requested_width), static_cast<s32>(requested_height));
|
Host::RequestResizeHostDisplay(static_cast<s32>(requested_width), static_cast<s32>(requested_height));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue