GPU/ShaderGen: Added Hybrid Bilinear scaling (#3554)

Middle ground between Smooth Bilinear and Sharp Bilinear.
Smooth horizontally and sharp vertically like a raster scan.
pull/3555/head
Ariel Nogueira Kovaljski 2 months ago committed by GitHub
parent 78d22b8852
commit 1275eb1f9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -130,6 +130,9 @@ bool GPUPresenter::CompileDisplayPipelines(bool display, bool deinterlace, bool
case DisplayScalingMode::BilinearSharp:
fs = shadergen.GenerateDisplaySharpBilinearFragmentShader();
break;
case DisplayScalingMode::BilinearHybrid:
fs = shadergen.GenerateDisplayHybridBilinearFragmentShader();
break;
case DisplayScalingMode::BilinearSmooth:
case DisplayScalingMode::BilinearInteger:
@ -717,6 +720,7 @@ void GPUPresenter::DrawDisplay(const GSVector2i target_size, const GSVector2i fi
}
break;
case DisplayScalingMode::BilinearHybrid:
case DisplayScalingMode::BilinearSharp:
{
texture_filter_linear = true;

@ -74,6 +74,41 @@ std::string GPUShaderGen::GenerateDisplaySharpBilinearFragmentShader() const
return std::move(ss).str();
}
std::string GPUShaderGen::GenerateDisplayHybridBilinearFragmentShader() const
{
std::stringstream ss;
WriteHeader(ss);
WriteDisplayUniformBuffer(ss);
DeclareTexture(ss, "samp0", 0, false);
// Based on
// https://github.com/rsn8887/Sharp-Bilinear-Shaders/blob/master/Copy_To_RetroPie/shaders/sharp-bilinear-simple.glsl
// and
// https://30fps.net/pages/pixelart-scaling/
DeclareFragmentEntryPoint(ss, 0, 1);
ss << R"(
{
float2 scale = u_params.xy;
float2 region_range = u_params.zw;
float2 texel = v_tex0 * u_src_size.xy;
float2 texel_floored = floor(texel);
float2 s = frac(texel);
float f_x = s.x;
float center_dist_y = s.y - 0.5;
float f_y = (center_dist_y - clamp(center_dist_y, -region_range.y, region_range.y)) * scale.y + 0.5;
float2 f = float2(f_x, f_y);
float2 mod_texel = texel_floored + f;
o_col0 = float4(SAMPLE_TEXTURE(samp0, ClampUV(mod_texel * u_src_size.zw)).rgb, 1.0f);
})";
return std::move(ss).str();
}
std::string GPUShaderGen::GenerateDisplayLanczosFragmentShader() const
{
std::stringstream ss;

@ -13,6 +13,7 @@ public:
std::string GenerateDisplayFragmentShader(bool clamp_uv, bool nearest) const;
std::string GenerateDisplaySharpBilinearFragmentShader() const;
std::string GenerateDisplayHybridBilinearFragmentShader() const;
std::string GenerateDisplayLanczosFragmentShader() const;
std::string GenerateDeinterlaceWeaveFragmentShader() const;

@ -2032,12 +2032,13 @@ const char* Settings::GetForceVideoTimingDisplayName(ForceVideoTimingMode mode)
}
static constexpr const std::array s_display_scaling_names = {
"Nearest", "NearestInteger", "BilinearSmooth", "BilinearSharp", "BilinearInteger", "Lanczos",
"Nearest", "NearestInteger", "BilinearSmooth", "BilinearHybrid", "BilinearSharp", "BilinearInteger", "Lanczos",
};
static constexpr const std::array s_display_scaling_display_names = {
TRANSLATE_DISAMBIG_NOOP("Settings", "Nearest-Neighbor", "DisplayScalingMode"),
TRANSLATE_DISAMBIG_NOOP("Settings", "Nearest-Neighbor (Integer)", "DisplayScalingMode"),
TRANSLATE_DISAMBIG_NOOP("Settings", "Bilinear (Smooth)", "DisplayScalingMode"),
TRANSLATE_DISAMBIG_NOOP("Settings", "Bilinear (Hybrid)", "DisplayScalingMode"),
TRANSLATE_DISAMBIG_NOOP("Settings", "Bilinear (Sharp)", "DisplayScalingMode"),
TRANSLATE_DISAMBIG_NOOP("Settings", "Bilinear (Integer)", "DisplayScalingMode"),
TRANSLATE_DISAMBIG_NOOP("Settings", "Lanczos (Sharp)", "DisplayScalingMode"),

@ -198,6 +198,7 @@ enum class DisplayScalingMode : u8
Nearest,
NearestInteger,
BilinearSmooth,
BilinearHybrid,
BilinearSharp,
BilinearInteger,
Lanczos,

Loading…
Cancel
Save