add spline-1 filter
All checks were successful
eden-license / license-header (pull_request) Successful in 20s
All checks were successful
eden-license / license-header (pull_request) Successful in 20s
Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
f28fe360c3
commit
63d3b0cf53
11 changed files with 47 additions and 1 deletions
|
@ -166,7 +166,7 @@ ENUM(ResolutionSetup,
|
||||||
Res7X,
|
Res7X,
|
||||||
Res8X);
|
Res8X);
|
||||||
|
|
||||||
ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Gaussian, Lanczos, ScaleForce, Fsr, Area, MaxEnum);
|
ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Spline1, Gaussian, Lanczos, ScaleForce, Fsr, Area, MaxEnum);
|
||||||
|
|
||||||
ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum);
|
ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum);
|
||||||
|
|
||||||
|
|
|
@ -572,6 +572,7 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
|
||||||
PAIR(ScalingFilter, NearestNeighbor, tr("Nearest Neighbor")),
|
PAIR(ScalingFilter, NearestNeighbor, tr("Nearest Neighbor")),
|
||||||
PAIR(ScalingFilter, Bilinear, tr("Bilinear")),
|
PAIR(ScalingFilter, Bilinear, tr("Bilinear")),
|
||||||
PAIR(ScalingFilter, Bicubic, tr("Bicubic")),
|
PAIR(ScalingFilter, Bicubic, tr("Bicubic")),
|
||||||
|
PAIR(ScalingFilter, Spline1, tr("Spline-1")),
|
||||||
PAIR(ScalingFilter, Gaussian, tr("Gaussian")),
|
PAIR(ScalingFilter, Gaussian, tr("Gaussian")),
|
||||||
PAIR(ScalingFilter, Lanczos, tr("Lanczos")),
|
PAIR(ScalingFilter, Lanczos, tr("Lanczos")),
|
||||||
PAIR(ScalingFilter, ScaleForce, tr("ScaleForce")),
|
PAIR(ScalingFilter, ScaleForce, tr("ScaleForce")),
|
||||||
|
|
|
@ -38,6 +38,8 @@ static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map
|
||||||
{Settings::ScalingFilter::Bilinear,
|
{Settings::ScalingFilter::Bilinear,
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bilinear"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bilinear"))},
|
||||||
{Settings::ScalingFilter::Bicubic, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bicubic"))},
|
{Settings::ScalingFilter::Bicubic, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bicubic"))},
|
||||||
|
{Settings::ScalingFilter::Spline1,
|
||||||
|
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Spline-1"))},
|
||||||
{Settings::ScalingFilter::Gaussian,
|
{Settings::ScalingFilter::Gaussian,
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Gaussian"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Gaussian"))},
|
||||||
{Settings::ScalingFilter::Lanczos,
|
{Settings::ScalingFilter::Lanczos,
|
||||||
|
|
|
@ -46,6 +46,7 @@ set(SHADER_FILES
|
||||||
present_bicubic.frag
|
present_bicubic.frag
|
||||||
present_gaussian.frag
|
present_gaussian.frag
|
||||||
present_lanczos.frag
|
present_lanczos.frag
|
||||||
|
present_spline1.frag
|
||||||
queries_prefix_scan_sum.comp
|
queries_prefix_scan_sum.comp
|
||||||
queries_prefix_scan_sum_nosubgroups.comp
|
queries_prefix_scan_sum_nosubgroups.comp
|
||||||
resolve_conditional_render.comp
|
resolve_conditional_render.comp
|
||||||
|
|
24
src/video_core/host_shaders/present_spline1.frag
Normal file
24
src/video_core/host_shaders/present_spline1.frag
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
// Spline (smooth linear inerpolation) with 1 texel fetch (needs bilinear to work)
|
||||||
|
// Emulates bicubic without actually doing bicubic
|
||||||
|
// See https://iquilezles.org/articles/texture, unfortunely there are issues with the original
|
||||||
|
// where smoothstep "expansion" actually results in worse codegen (SPIRV-Opt does a direct conv to smoothstep)
|
||||||
|
// TODO: Numerical analysis - fract is sawtooth func and floor, reuse params? Perhaps - no need for precision
|
||||||
|
|
||||||
|
#version 460 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec2 frag_tex_coord;
|
||||||
|
layout (location = 0) out vec4 color;
|
||||||
|
layout (binding = 0) uniform sampler2D color_texture;
|
||||||
|
|
||||||
|
vec4 textureSpline1(sampler2D sam, vec2 uv) {
|
||||||
|
float r = float(textureSize(sam, 0).x);
|
||||||
|
vec2 x = fract(uv * r + 0.5);
|
||||||
|
return texture(sam, (floor(uv * r + 0.5) + smoothstep(0.0, 1.0, x) - 0.5) / r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
color = textureSpline1(color_texture, frag_tex_coord);
|
||||||
|
}
|
|
@ -89,6 +89,9 @@ void BlitScreen::CreateWindowAdapt() {
|
||||||
case Settings::ScalingFilter::Gaussian:
|
case Settings::ScalingFilter::Gaussian:
|
||||||
window_adapt = MakeGaussian(device);
|
window_adapt = MakeGaussian(device);
|
||||||
break;
|
break;
|
||||||
|
case Settings::ScalingFilter::Spline1:
|
||||||
|
window_adapt = MakeSpline1(device);
|
||||||
|
break;
|
||||||
case Settings::ScalingFilter::Lanczos:
|
case Settings::ScalingFilter::Lanczos:
|
||||||
window_adapt = MakeLanczos(device);
|
window_adapt = MakeLanczos(device);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -28,6 +28,11 @@ std::unique_ptr<WindowAdaptPass> MakeBilinear(const Device& device) {
|
||||||
HostShaders::OPENGL_PRESENT_FRAG);
|
HostShaders::OPENGL_PRESENT_FRAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<WindowAdaptPass> MakeSpline1(const Device& device) {
|
||||||
|
return std::make_unique<WindowAdaptPass>(device, CreateBilinearSampler(),
|
||||||
|
HostShaders::PRESENT_SPLINE1_FRAG);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device) {
|
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device) {
|
||||||
return std::make_unique<WindowAdaptPass>(device, CreateBilinearSampler(),
|
return std::make_unique<WindowAdaptPass>(device, CreateBilinearSampler(),
|
||||||
HostShaders::PRESENT_BICUBIC_FRAG);
|
HostShaders::PRESENT_BICUBIC_FRAG);
|
||||||
|
|
|
@ -18,6 +18,7 @@ std::unique_ptr<WindowAdaptPass> MakeNearestNeighbor(const Device& device);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeBilinear(const Device& device);
|
std::unique_ptr<WindowAdaptPass> MakeBilinear(const Device& device);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device);
|
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device);
|
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device);
|
||||||
|
std::unique_ptr<WindowAdaptPass> MakeSpline1(const Device& device);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeLanczos(const Device& device);
|
std::unique_ptr<WindowAdaptPass> MakeLanczos(const Device& device);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeScaleForce(const Device& device);
|
std::unique_ptr<WindowAdaptPass> MakeScaleForce(const Device& device);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeArea(const Device& device);
|
std::unique_ptr<WindowAdaptPass> MakeArea(const Device& device);
|
||||||
|
|
|
@ -46,6 +46,11 @@ std::unique_ptr<WindowAdaptPass> MakeBilinear(const Device& device, VkFormat fra
|
||||||
BuildShader(device, VULKAN_PRESENT_FRAG_SPV));
|
BuildShader(device, VULKAN_PRESENT_FRAG_SPV));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<WindowAdaptPass> MakeSpline1(const Device& device, VkFormat frame_format) {
|
||||||
|
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device),
|
||||||
|
BuildShader(device, PRESENT_SPLINE1_FRAG_SPV));
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device, VkFormat frame_format) {
|
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device, VkFormat frame_format) {
|
||||||
// No need for handrolled shader -- if the VK impl can do it for us ;)
|
// No need for handrolled shader -- if the VK impl can do it for us ;)
|
||||||
if (device.IsExtFilterCubicSupported())
|
if (device.IsExtFilterCubicSupported())
|
||||||
|
|
|
@ -18,6 +18,7 @@ class MemoryAllocator;
|
||||||
std::unique_ptr<WindowAdaptPass> MakeNearestNeighbor(const Device& device, VkFormat frame_format);
|
std::unique_ptr<WindowAdaptPass> MakeNearestNeighbor(const Device& device, VkFormat frame_format);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeBilinear(const Device& device, VkFormat frame_format);
|
std::unique_ptr<WindowAdaptPass> MakeBilinear(const Device& device, VkFormat frame_format);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device, VkFormat frame_format);
|
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device, VkFormat frame_format);
|
||||||
|
std::unique_ptr<WindowAdaptPass> MakeSpline1(const Device& device, VkFormat frame_format);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device, VkFormat frame_format);
|
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device, VkFormat frame_format);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeLanczos(const Device& device, VkFormat frame_format);
|
std::unique_ptr<WindowAdaptPass> MakeLanczos(const Device& device, VkFormat frame_format);
|
||||||
std::unique_ptr<WindowAdaptPass> MakeScaleForce(const Device& device, VkFormat frame_format);
|
std::unique_ptr<WindowAdaptPass> MakeScaleForce(const Device& device, VkFormat frame_format);
|
||||||
|
|
|
@ -43,6 +43,9 @@ void BlitScreen::SetWindowAdaptPass() {
|
||||||
case Settings::ScalingFilter::Bicubic:
|
case Settings::ScalingFilter::Bicubic:
|
||||||
window_adapt = MakeBicubic(device, swapchain_view_format);
|
window_adapt = MakeBicubic(device, swapchain_view_format);
|
||||||
break;
|
break;
|
||||||
|
case Settings::ScalingFilter::Spline1:
|
||||||
|
window_adapt = MakeSpline1(device, swapchain_view_format);
|
||||||
|
break;
|
||||||
case Settings::ScalingFilter::Gaussian:
|
case Settings::ScalingFilter::Gaussian:
|
||||||
window_adapt = MakeGaussian(device, swapchain_view_format);
|
window_adapt = MakeGaussian(device, swapchain_view_format);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue