GPU: Add downsample scale option
This commit is contained in:
parent
c0af478dfd
commit
585cf25ac4
|
@ -3907,6 +3907,17 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
||||||
"GPU", "DownsampleMode", Settings::DEFAULT_GPU_DOWNSAMPLE_MODE, &Settings::ParseDownsampleModeName,
|
"GPU", "DownsampleMode", Settings::DEFAULT_GPU_DOWNSAMPLE_MODE, &Settings::ParseDownsampleModeName,
|
||||||
&Settings::GetDownsampleModeName, &Settings::GetDownsampleModeDisplayName, GPUDownsampleMode::Count,
|
&Settings::GetDownsampleModeName, &Settings::GetDownsampleModeDisplayName, GPUDownsampleMode::Count,
|
||||||
(renderer != GPURenderer::Software));
|
(renderer != GPURenderer::Software));
|
||||||
|
if (Settings::ParseDownsampleModeName(
|
||||||
|
GetEffectiveStringSetting(bsi, "GPU", "DownsampleMode",
|
||||||
|
Settings::GetDownsampleModeName(Settings::DEFAULT_GPU_DOWNSAMPLE_MODE))
|
||||||
|
.c_str())
|
||||||
|
.value_or(Settings::DEFAULT_GPU_DOWNSAMPLE_MODE) == GPUDownsampleMode::Box)
|
||||||
|
{
|
||||||
|
DrawIntRangeSetting(bsi, FSUI_CSTR("Downsampling Display Scale"),
|
||||||
|
FSUI_CSTR("Selects the resolution scale that will be applied to the final image. 1x will "
|
||||||
|
"downsample to the original console resolution."),
|
||||||
|
"GPU", "DownsampleScale", 1, 1, GPU::MAX_RESOLUTION_SCALE, "%dx");
|
||||||
|
}
|
||||||
|
|
||||||
DrawEnumSetting(
|
DrawEnumSetting(
|
||||||
bsi, FSUI_CSTR("Scaling"),
|
bsi, FSUI_CSTR("Scaling"),
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "common/scoped_guard.h"
|
#include "common/scoped_guard.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
|
||||||
|
#include "IconsFontAwesome5.h"
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
@ -50,6 +51,14 @@ ALWAYS_INLINE static u32 GetMaxResolutionScale()
|
||||||
return g_gpu_device->GetMaxTextureSize() / VRAM_WIDTH;
|
return g_gpu_device->GetMaxTextureSize() / VRAM_WIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE_RELEASE static u32 GetBoxDownsampleScale()
|
||||||
|
{
|
||||||
|
u32 scale = std::min<u32>(g_settings.gpu_resolution_scale, g_settings.gpu_downsample_scale);
|
||||||
|
while ((g_settings.gpu_resolution_scale % scale) != 0)
|
||||||
|
scale--;
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE static bool ShouldUseUVLimits()
|
ALWAYS_INLINE static bool ShouldUseUVLimits()
|
||||||
{
|
{
|
||||||
// We only need UV limits if PGXP is enabled, or texture filtering is enabled.
|
// We only need UV limits if PGXP is enabled, or texture filtering is enabled.
|
||||||
|
@ -166,38 +175,7 @@ bool GPU_HW::Initialize()
|
||||||
m_wireframe_mode = g_settings.gpu_wireframe_mode;
|
m_wireframe_mode = g_settings.gpu_wireframe_mode;
|
||||||
m_disable_color_perspective = features.noperspective_interpolation && ShouldDisableColorPerspective();
|
m_disable_color_perspective = features.noperspective_interpolation && ShouldDisableColorPerspective();
|
||||||
|
|
||||||
if (m_multisamples != g_settings.gpu_multisamples)
|
CheckSettings();
|
||||||
{
|
|
||||||
Host::AddFormattedOSDMessage(Host::OSD_CRITICAL_ERROR_DURATION,
|
|
||||||
TRANSLATE("OSDMessage", "%ux MSAA is not supported, using %ux instead."),
|
|
||||||
g_settings.gpu_multisamples, m_multisamples);
|
|
||||||
}
|
|
||||||
if (!m_per_sample_shading && g_settings.gpu_per_sample_shading)
|
|
||||||
{
|
|
||||||
Host::AddOSDMessage(TRANSLATE_STR("OSDMessage", "SSAA is not supported, using MSAA instead."), 20.0f);
|
|
||||||
}
|
|
||||||
if (!features.dual_source_blend && TextureFilterRequiresDualSourceBlend(m_texture_filtering))
|
|
||||||
{
|
|
||||||
Host::AddFormattedOSDMessage(
|
|
||||||
Host::OSD_CRITICAL_ERROR_DURATION,
|
|
||||||
TRANSLATE("OSDMessage", "Texture filter '%s' is not supported with the current renderer."),
|
|
||||||
Settings::GetTextureFilterDisplayName(m_texture_filtering));
|
|
||||||
m_texture_filtering = GPUTextureFilter::Nearest;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!features.noperspective_interpolation && !ShouldDisableColorPerspective())
|
|
||||||
Log_WarningPrint("Disable color perspective not supported, but should be used.");
|
|
||||||
|
|
||||||
if (!features.geometry_shaders && m_wireframe_mode != GPUWireframeMode::Disabled)
|
|
||||||
{
|
|
||||||
Host::AddOSDMessage(
|
|
||||||
TRANSLATE("OSDMessage",
|
|
||||||
"Geometry shaders are not supported by your GPU, and are required for wireframe rendering."),
|
|
||||||
Host::OSD_CRITICAL_ERROR_DURATION);
|
|
||||||
m_wireframe_mode = GPUWireframeMode::Disabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pgxp_depth_buffer = g_settings.UsingPGXPDepthBuffer();
|
|
||||||
|
|
||||||
UpdateSoftwareRenderer(false);
|
UpdateSoftwareRenderer(false);
|
||||||
|
|
||||||
|
@ -316,14 +294,18 @@ void GPU_HW::UpdateSettings(const Settings& old_settings)
|
||||||
|
|
||||||
// TODO: Use old_settings
|
// TODO: Use old_settings
|
||||||
const bool framebuffer_changed =
|
const bool framebuffer_changed =
|
||||||
(m_resolution_scale != resolution_scale || m_multisamples != multisamples || m_downsample_mode != downsample_mode);
|
(m_resolution_scale != resolution_scale || m_multisamples != multisamples || m_downsample_mode != downsample_mode ||
|
||||||
|
(m_downsample_mode == GPUDownsampleMode::Box &&
|
||||||
|
g_settings.gpu_downsample_scale != old_settings.gpu_downsample_scale));
|
||||||
const bool shaders_changed =
|
const bool shaders_changed =
|
||||||
(m_resolution_scale != resolution_scale || m_multisamples != multisamples ||
|
(m_resolution_scale != resolution_scale || m_multisamples != multisamples ||
|
||||||
m_true_color != g_settings.gpu_true_color || m_per_sample_shading != per_sample_shading ||
|
m_true_color != g_settings.gpu_true_color || m_per_sample_shading != per_sample_shading ||
|
||||||
m_scaled_dithering != g_settings.gpu_scaled_dithering || m_texture_filtering != g_settings.gpu_texture_filter ||
|
m_scaled_dithering != g_settings.gpu_scaled_dithering || m_texture_filtering != g_settings.gpu_texture_filter ||
|
||||||
m_using_uv_limits != use_uv_limits || m_chroma_smoothing != g_settings.gpu_24bit_chroma_smoothing ||
|
m_using_uv_limits != use_uv_limits || m_chroma_smoothing != g_settings.gpu_24bit_chroma_smoothing ||
|
||||||
m_downsample_mode != downsample_mode || m_wireframe_mode != wireframe_mode ||
|
m_downsample_mode != downsample_mode ||
|
||||||
m_pgxp_depth_buffer != g_settings.UsingPGXPDepthBuffer() ||
|
(m_downsample_mode == GPUDownsampleMode::Box &&
|
||||||
|
g_settings.gpu_downsample_scale != old_settings.gpu_downsample_scale) ||
|
||||||
|
m_wireframe_mode != wireframe_mode || m_pgxp_depth_buffer != g_settings.UsingPGXPDepthBuffer() ||
|
||||||
m_disable_color_perspective != disable_color_perspective);
|
m_disable_color_perspective != disable_color_perspective);
|
||||||
|
|
||||||
if (m_resolution_scale != resolution_scale)
|
if (m_resolution_scale != resolution_scale)
|
||||||
|
@ -369,8 +351,7 @@ void GPU_HW::UpdateSettings(const Settings& old_settings)
|
||||||
m_wireframe_mode = wireframe_mode;
|
m_wireframe_mode = wireframe_mode;
|
||||||
m_disable_color_perspective = disable_color_perspective;
|
m_disable_color_perspective = disable_color_perspective;
|
||||||
|
|
||||||
if (!m_supports_dual_source_blend && TextureFilterRequiresDualSourceBlend(m_texture_filtering))
|
CheckSettings();
|
||||||
m_texture_filtering = GPUTextureFilter::Nearest;
|
|
||||||
|
|
||||||
if (m_pgxp_depth_buffer != g_settings.UsingPGXPDepthBuffer())
|
if (m_pgxp_depth_buffer != g_settings.UsingPGXPDepthBuffer())
|
||||||
{
|
{
|
||||||
|
@ -404,6 +385,72 @@ void GPU_HW::UpdateSettings(const Settings& old_settings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPU_HW::CheckSettings()
|
||||||
|
{
|
||||||
|
const GPUDevice::Features features = g_gpu_device->GetFeatures();
|
||||||
|
|
||||||
|
if (m_multisamples != g_settings.gpu_multisamples)
|
||||||
|
{
|
||||||
|
Host::AddIconOSDMessage("MSAAUnsupported", ICON_FA_PAINT_BRUSH,
|
||||||
|
fmt::format(TRANSLATE_FS("OSDMessage", "{}x MSAA is not supported, using {}x instead."),
|
||||||
|
g_settings.gpu_multisamples, m_multisamples),
|
||||||
|
Host::OSD_CRITICAL_ERROR_DURATION);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Host::RemoveKeyedOSDMessage("MSAAUnsupported");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_per_sample_shading && g_settings.gpu_per_sample_shading)
|
||||||
|
{
|
||||||
|
Host::AddOSDMessage(TRANSLATE_STR("OSDMessage", "SSAA is not supported, using MSAA instead."), 20.0f);
|
||||||
|
}
|
||||||
|
if (!features.dual_source_blend && TextureFilterRequiresDualSourceBlend(m_texture_filtering))
|
||||||
|
{
|
||||||
|
Host::AddFormattedOSDMessage(
|
||||||
|
Host::OSD_CRITICAL_ERROR_DURATION,
|
||||||
|
TRANSLATE("OSDMessage", "Texture filter '%s' is not supported with the current renderer."),
|
||||||
|
Settings::GetTextureFilterDisplayName(m_texture_filtering));
|
||||||
|
m_texture_filtering = GPUTextureFilter::Nearest;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!features.noperspective_interpolation && !ShouldDisableColorPerspective())
|
||||||
|
Log_WarningPrint("Disable color perspective not supported, but should be used.");
|
||||||
|
|
||||||
|
if (!features.geometry_shaders && m_wireframe_mode != GPUWireframeMode::Disabled)
|
||||||
|
{
|
||||||
|
Host::AddOSDMessage(
|
||||||
|
TRANSLATE("OSDMessage",
|
||||||
|
"Geometry shaders are not supported by your GPU, and are required for wireframe rendering."),
|
||||||
|
Host::OSD_CRITICAL_ERROR_DURATION);
|
||||||
|
m_wireframe_mode = GPUWireframeMode::Disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_downsample_mode == GPUDownsampleMode::Box)
|
||||||
|
{
|
||||||
|
const u32 scale = GetBoxDownsampleScale();
|
||||||
|
if (scale != g_settings.gpu_downsample_scale || scale == g_settings.gpu_resolution_scale)
|
||||||
|
{
|
||||||
|
Host::AddIconOSDMessage(
|
||||||
|
"BoxDownsampleUnsupported", ICON_FA_PAINT_BRUSH,
|
||||||
|
fmt::format(
|
||||||
|
TRANSLATE_FS("OSDMessage",
|
||||||
|
"Resolution scale {0}x is not divisible by downsample scale {1}x, using {2}x instead."),
|
||||||
|
g_settings.gpu_resolution_scale, g_settings.gpu_downsample_scale, scale),
|
||||||
|
Host::OSD_ERROR_DURATION);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Host::RemoveKeyedOSDMessage("BoxDownsampleUnsupported");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scale == g_settings.gpu_resolution_scale)
|
||||||
|
m_downsample_mode = GPUDownsampleMode::Disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pgxp_depth_buffer = g_settings.UsingPGXPDepthBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
u32 GPU_HW::CalculateResolutionScale() const
|
u32 GPU_HW::CalculateResolutionScale() const
|
||||||
{
|
{
|
||||||
const u32 max_resolution_scale = GetMaxResolutionScale();
|
const u32 max_resolution_scale = GetMaxResolutionScale();
|
||||||
|
@ -580,8 +627,10 @@ bool GPU_HW::CreateBuffers()
|
||||||
}
|
}
|
||||||
else if (m_downsample_mode == GPUDownsampleMode::Box)
|
else if (m_downsample_mode == GPUDownsampleMode::Box)
|
||||||
{
|
{
|
||||||
if (!(m_downsample_render_texture = g_gpu_device->CreateTexture(VRAM_WIDTH, VRAM_HEIGHT, 1, 1, 1,
|
const u32 downsample_scale = GetBoxDownsampleScale();
|
||||||
GPUTexture::Type::RenderTarget, VRAM_RT_FORMAT)) ||
|
if (!(m_downsample_render_texture =
|
||||||
|
g_gpu_device->CreateTexture(VRAM_WIDTH * downsample_scale, VRAM_HEIGHT * downsample_scale, 1, 1, 1,
|
||||||
|
GPUTexture::Type::RenderTarget, VRAM_RT_FORMAT)) ||
|
||||||
!(m_downsample_framebuffer = g_gpu_device->CreateFramebuffer(m_downsample_render_texture.get())))
|
!(m_downsample_framebuffer = g_gpu_device->CreateFramebuffer(m_downsample_render_texture.get())))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -1056,8 +1105,9 @@ bool GPU_HW::CompilePipelines()
|
||||||
}
|
}
|
||||||
else if (m_downsample_mode == GPUDownsampleMode::Box)
|
else if (m_downsample_mode == GPUDownsampleMode::Box)
|
||||||
{
|
{
|
||||||
std::unique_ptr<GPUShader> fs =
|
std::unique_ptr<GPUShader> fs = g_gpu_device->CreateShader(
|
||||||
g_gpu_device->CreateShader(GPUShaderStage::Fragment, shadergen.GenerateBoxSampleDownsampleFragmentShader());
|
GPUShaderStage::Fragment,
|
||||||
|
shadergen.GenerateBoxSampleDownsampleFragmentShader(m_resolution_scale / GetBoxDownsampleScale()));
|
||||||
if (!fs)
|
if (!fs)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -2642,10 +2692,11 @@ void GPU_HW::DownsampleFramebufferAdaptive(GPUTexture* source, u32 left, u32 top
|
||||||
|
|
||||||
void GPU_HW::DownsampleFramebufferBoxFilter(GPUTexture* source, u32 left, u32 top, u32 width, u32 height)
|
void GPU_HW::DownsampleFramebufferBoxFilter(GPUTexture* source, u32 left, u32 top, u32 width, u32 height)
|
||||||
{
|
{
|
||||||
const u32 ds_left = left / m_resolution_scale;
|
const u32 factor = m_resolution_scale / GetBoxDownsampleScale();
|
||||||
const u32 ds_top = top / m_resolution_scale;
|
const u32 ds_left = left / factor;
|
||||||
const u32 ds_width = width / m_resolution_scale;
|
const u32 ds_top = top / factor;
|
||||||
const u32 ds_height = height / m_resolution_scale;
|
const u32 ds_width = width / factor;
|
||||||
|
const u32 ds_height = height / factor;
|
||||||
|
|
||||||
source->MakeReadyForSampling();
|
source->MakeReadyForSampling();
|
||||||
|
|
||||||
|
|
|
@ -347,4 +347,5 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintSettingsToLog();
|
void PrintSettingsToLog();
|
||||||
|
void CheckSettings();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1558,24 +1558,26 @@ std::string GPU_HW_ShaderGen::GenerateAdaptiveDownsampleCompositeFragmentShader(
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GPU_HW_ShaderGen::GenerateBoxSampleDownsampleFragmentShader()
|
std::string GPU_HW_ShaderGen::GenerateBoxSampleDownsampleFragmentShader(u32 factor)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
WriteHeader(ss);
|
WriteHeader(ss);
|
||||||
WriteCommonFunctions(ss);
|
WriteCommonFunctions(ss);
|
||||||
DeclareTexture(ss, "samp0", 0, false);
|
DeclareTexture(ss, "samp0", 0, false);
|
||||||
|
|
||||||
|
ss << "#define FACTOR " << factor << "\n";
|
||||||
|
|
||||||
DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1, false, false, false, false);
|
DeclareFragmentEntryPoint(ss, 0, 1, {}, true, 1, false, false, false, false);
|
||||||
ss << R"(
|
ss << R"(
|
||||||
{
|
{
|
||||||
float3 color = float3(0.0, 0.0, 0.0);
|
float3 color = float3(0.0, 0.0, 0.0);
|
||||||
uint2 base_coords = uint2(v_pos.xy) * uint2(RESOLUTION_SCALE, RESOLUTION_SCALE);
|
uint2 base_coords = uint2(v_pos.xy) * uint2(FACTOR, FACTOR);
|
||||||
for (uint offset_x = 0u; offset_x < RESOLUTION_SCALE; offset_x++)
|
for (uint offset_x = 0u; offset_x < FACTOR; offset_x++)
|
||||||
{
|
{
|
||||||
for (uint offset_y = 0u; offset_y < RESOLUTION_SCALE; offset_y++)
|
for (uint offset_y = 0u; offset_y < FACTOR; offset_y++)
|
||||||
color += LOAD_TEXTURE(samp0, int2(base_coords + uint2(offset_x, offset_y)), 0).rgb;
|
color += LOAD_TEXTURE(samp0, int2(base_coords + uint2(offset_x, offset_y)), 0).rgb;
|
||||||
}
|
}
|
||||||
color /= float(RESOLUTION_SCALE * RESOLUTION_SCALE);
|
color /= float(FACTOR * FACTOR);
|
||||||
o_col0 = float4(color, 1.0);
|
o_col0 = float4(color, 1.0);
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
|
@ -30,7 +30,7 @@ public:
|
||||||
std::string GenerateAdaptiveDownsampleMipFragmentShader(bool first_pass);
|
std::string GenerateAdaptiveDownsampleMipFragmentShader(bool first_pass);
|
||||||
std::string GenerateAdaptiveDownsampleBlurFragmentShader();
|
std::string GenerateAdaptiveDownsampleBlurFragmentShader();
|
||||||
std::string GenerateAdaptiveDownsampleCompositeFragmentShader();
|
std::string GenerateAdaptiveDownsampleCompositeFragmentShader();
|
||||||
std::string GenerateBoxSampleDownsampleFragmentShader();
|
std::string GenerateBoxSampleDownsampleFragmentShader(u32 factor);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ALWAYS_INLINE bool UsingMSAA() const { return m_multisamples > 1; }
|
ALWAYS_INLINE bool UsingMSAA() const { return m_multisamples > 1; }
|
||||||
|
|
|
@ -225,6 +225,7 @@ void Settings::Load(SettingsInterface& si)
|
||||||
ParseDownsampleModeName(
|
ParseDownsampleModeName(
|
||||||
si.GetStringValue("GPU", "DownsampleMode", GetDownsampleModeName(DEFAULT_GPU_DOWNSAMPLE_MODE)).c_str())
|
si.GetStringValue("GPU", "DownsampleMode", GetDownsampleModeName(DEFAULT_GPU_DOWNSAMPLE_MODE)).c_str())
|
||||||
.value_or(DEFAULT_GPU_DOWNSAMPLE_MODE);
|
.value_or(DEFAULT_GPU_DOWNSAMPLE_MODE);
|
||||||
|
gpu_downsample_scale = static_cast<u8>(si.GetUIntValue("GPU", "DownsampleScale", 1));
|
||||||
gpu_wireframe_mode =
|
gpu_wireframe_mode =
|
||||||
ParseGPUWireframeMode(
|
ParseGPUWireframeMode(
|
||||||
si.GetStringValue("GPU", "WireframeMode", GetGPUWireframeModeName(DEFAULT_GPU_WIREFRAME_MODE)).c_str())
|
si.GetStringValue("GPU", "WireframeMode", GetGPUWireframeModeName(DEFAULT_GPU_WIREFRAME_MODE)).c_str())
|
||||||
|
@ -466,6 +467,7 @@ void Settings::Save(SettingsInterface& si) const
|
||||||
si.SetBoolValue("GPU", "ScaledDithering", gpu_scaled_dithering);
|
si.SetBoolValue("GPU", "ScaledDithering", gpu_scaled_dithering);
|
||||||
si.SetStringValue("GPU", "TextureFilter", GetTextureFilterName(gpu_texture_filter));
|
si.SetStringValue("GPU", "TextureFilter", GetTextureFilterName(gpu_texture_filter));
|
||||||
si.SetStringValue("GPU", "DownsampleMode", GetDownsampleModeName(gpu_downsample_mode));
|
si.SetStringValue("GPU", "DownsampleMode", GetDownsampleModeName(gpu_downsample_mode));
|
||||||
|
si.SetUIntValue("GPU", "DownsampleScale", gpu_downsample_scale);
|
||||||
si.SetStringValue("GPU", "WireframeMode", GetGPUWireframeModeName(gpu_wireframe_mode));
|
si.SetStringValue("GPU", "WireframeMode", GetGPUWireframeModeName(gpu_wireframe_mode));
|
||||||
si.SetBoolValue("GPU", "DisableInterlacing", gpu_disable_interlacing);
|
si.SetBoolValue("GPU", "DisableInterlacing", gpu_disable_interlacing);
|
||||||
si.SetBoolValue("GPU", "ForceNTSCTimings", gpu_force_ntsc_timings);
|
si.SetBoolValue("GPU", "ForceNTSCTimings", gpu_force_ntsc_timings);
|
||||||
|
|
|
@ -106,6 +106,7 @@ struct Settings
|
||||||
bool gpu_scaled_dithering = true;
|
bool gpu_scaled_dithering = true;
|
||||||
GPUTextureFilter gpu_texture_filter = DEFAULT_GPU_TEXTURE_FILTER;
|
GPUTextureFilter gpu_texture_filter = DEFAULT_GPU_TEXTURE_FILTER;
|
||||||
GPUDownsampleMode gpu_downsample_mode = DEFAULT_GPU_DOWNSAMPLE_MODE;
|
GPUDownsampleMode gpu_downsample_mode = DEFAULT_GPU_DOWNSAMPLE_MODE;
|
||||||
|
u8 gpu_downsample_scale = 1;
|
||||||
GPUWireframeMode gpu_wireframe_mode = DEFAULT_GPU_WIREFRAME_MODE;
|
GPUWireframeMode gpu_wireframe_mode = DEFAULT_GPU_WIREFRAME_MODE;
|
||||||
bool gpu_disable_interlacing = true;
|
bool gpu_disable_interlacing = true;
|
||||||
bool gpu_force_ntsc_timings = false;
|
bool gpu_force_ntsc_timings = false;
|
||||||
|
|
|
@ -3590,6 +3590,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
||||||
g_settings.gpu_force_ntsc_timings != old_settings.gpu_force_ntsc_timings ||
|
g_settings.gpu_force_ntsc_timings != old_settings.gpu_force_ntsc_timings ||
|
||||||
g_settings.gpu_24bit_chroma_smoothing != old_settings.gpu_24bit_chroma_smoothing ||
|
g_settings.gpu_24bit_chroma_smoothing != old_settings.gpu_24bit_chroma_smoothing ||
|
||||||
g_settings.gpu_downsample_mode != old_settings.gpu_downsample_mode ||
|
g_settings.gpu_downsample_mode != old_settings.gpu_downsample_mode ||
|
||||||
|
g_settings.gpu_downsample_scale != old_settings.gpu_downsample_scale ||
|
||||||
g_settings.gpu_wireframe_mode != old_settings.gpu_wireframe_mode ||
|
g_settings.gpu_wireframe_mode != old_settings.gpu_wireframe_mode ||
|
||||||
g_settings.display_crop_mode != old_settings.display_crop_mode ||
|
g_settings.display_crop_mode != old_settings.display_crop_mode ||
|
||||||
g_settings.display_aspect_ratio != old_settings.display_aspect_ratio ||
|
g_settings.display_aspect_ratio != old_settings.display_aspect_ratio ||
|
||||||
|
|
|
@ -20,6 +20,7 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsDialog* dialog, QWi
|
||||||
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuDownsampleMode, "GPU", "DownsampleMode",
|
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuDownsampleMode, "GPU", "DownsampleMode",
|
||||||
&Settings::ParseDownsampleModeName, &Settings::GetDownsampleModeName,
|
&Settings::ParseDownsampleModeName, &Settings::GetDownsampleModeName,
|
||||||
Settings::DEFAULT_GPU_DOWNSAMPLE_MODE);
|
Settings::DEFAULT_GPU_DOWNSAMPLE_MODE);
|
||||||
|
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.gpuDownsampleScale, "GPU", "DownsampleScale", 1);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.trueColor, "GPU", "TrueColor", false);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.trueColor, "GPU", "TrueColor", false);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.scaledDithering, "GPU", "ScaledDithering", false);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.scaledDithering, "GPU", "ScaledDithering", false);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableInterlacing, "GPU", "DisableInterlacing", true);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableInterlacing, "GPU", "DisableInterlacing", true);
|
||||||
|
@ -43,7 +44,10 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsDialog* dialog, QWi
|
||||||
|
|
||||||
connect(m_ui.resolutionScale, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
connect(m_ui.resolutionScale, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||||
&EnhancementSettingsWidget::updateScaledDitheringEnabled);
|
&EnhancementSettingsWidget::updateScaledDitheringEnabled);
|
||||||
|
connect(m_ui.gpuDownsampleMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||||
|
&EnhancementSettingsWidget::updateDownsampleScaleVisible);
|
||||||
connect(m_ui.trueColor, &QCheckBox::stateChanged, this, &EnhancementSettingsWidget::updateScaledDitheringEnabled);
|
connect(m_ui.trueColor, &QCheckBox::stateChanged, this, &EnhancementSettingsWidget::updateScaledDitheringEnabled);
|
||||||
|
updateDownsampleScaleVisible();
|
||||||
updateScaledDitheringEnabled();
|
updateScaledDitheringEnabled();
|
||||||
|
|
||||||
connect(m_ui.pgxpEnable, &QCheckBox::stateChanged, this, &EnhancementSettingsWidget::updatePGXPSettingsEnabled);
|
connect(m_ui.pgxpEnable, &QCheckBox::stateChanged, this, &EnhancementSettingsWidget::updatePGXPSettingsEnabled);
|
||||||
|
@ -55,6 +59,9 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsDialog* dialog, QWi
|
||||||
m_ui.gpuDownsampleMode, tr("Downsampling"), tr("Disabled"),
|
m_ui.gpuDownsampleMode, tr("Downsampling"), tr("Disabled"),
|
||||||
tr("Downsamples the rendered image prior to displaying it. Can improve overall image quality in mixed 2D/3D games, "
|
tr("Downsamples the rendered image prior to displaying it. Can improve overall image quality in mixed 2D/3D games, "
|
||||||
"but should be disabled for pure 3D games. Only applies to the hardware renderers."));
|
"but should be disabled for pure 3D games. Only applies to the hardware renderers."));
|
||||||
|
dialog->registerWidgetHelp(m_ui.gpuDownsampleScale, tr("Downsampling Display Scale"), tr("1x"),
|
||||||
|
tr("Selects the resolution scale that will be applied to the final image. 1x will "
|
||||||
|
"downsample to the original console resolution."));
|
||||||
dialog->registerWidgetHelp(
|
dialog->registerWidgetHelp(
|
||||||
m_ui.disableInterlacing, tr("Disable Interlacing (force progressive render/scan)"), tr("Unchecked"),
|
m_ui.disableInterlacing, tr("Disable Interlacing (force progressive render/scan)"), tr("Unchecked"),
|
||||||
tr(
|
tr(
|
||||||
|
@ -141,6 +148,29 @@ void EnhancementSettingsWidget::updateScaledDitheringEnabled()
|
||||||
m_ui.scaledDithering->setEnabled(allow_scaled_dithering);
|
m_ui.scaledDithering->setEnabled(allow_scaled_dithering);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EnhancementSettingsWidget::updateDownsampleScaleVisible()
|
||||||
|
{
|
||||||
|
const GPUDownsampleMode mode =
|
||||||
|
Settings::ParseDownsampleModeName(
|
||||||
|
m_dialog
|
||||||
|
->getEffectiveStringValue("GPU", "DownsampleMode",
|
||||||
|
Settings::GetDownsampleModeName(Settings::DEFAULT_GPU_DOWNSAMPLE_MODE))
|
||||||
|
.c_str())
|
||||||
|
.value_or(Settings::DEFAULT_GPU_DOWNSAMPLE_MODE);
|
||||||
|
|
||||||
|
const bool visible = (mode == GPUDownsampleMode::Box);
|
||||||
|
if (visible && m_ui.gpuDownsampleLayout->indexOf(m_ui.gpuDownsampleScale) < 0)
|
||||||
|
{
|
||||||
|
m_ui.gpuDownsampleScale->setVisible(true);
|
||||||
|
m_ui.gpuDownsampleLayout->addWidget(m_ui.gpuDownsampleScale, 0);
|
||||||
|
}
|
||||||
|
else if (!visible && m_ui.gpuDownsampleLayout->indexOf(m_ui.gpuDownsampleScale) >= 0)
|
||||||
|
{
|
||||||
|
m_ui.gpuDownsampleScale->setVisible(false);
|
||||||
|
m_ui.gpuDownsampleLayout->removeWidget(m_ui.gpuDownsampleScale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EnhancementSettingsWidget::setupAdditionalUi()
|
void EnhancementSettingsWidget::setupAdditionalUi()
|
||||||
{
|
{
|
||||||
QtUtils::FillComboBoxWithResolutionScales(m_ui.resolutionScale);
|
QtUtils::FillComboBoxWithResolutionScales(m_ui.resolutionScale);
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void updateScaledDitheringEnabled();
|
void updateScaledDitheringEnabled();
|
||||||
|
void updateDownsampleScaleVisible();
|
||||||
void updatePGXPSettingsEnabled();
|
void updatePGXPSettingsEnabled();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -88,7 +88,24 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QComboBox" name="gpuDownsampleMode"/>
|
<layout class="QHBoxLayout" name="gpuDownsampleLayout" stretch="1,0">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="gpuDownsampleMode"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="gpuDownsampleScale">
|
||||||
|
<property name="suffix">
|
||||||
|
<string>x</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>16</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
Loading…
Reference in New Issue