updated gui with output scaling and fsr sharpness options

This commit is contained in:
KojoZero 2026-05-26 20:57:51 -07:00
parent 1f8c5418ac
commit 7bf5442a1c
10 changed files with 256 additions and 31 deletions

View file

@ -47,6 +47,8 @@ foreach(KEY IN ITEMS
"turbo_limit"
"texture_filter"
"antialiasing_filter"
"output_scaling"
"fsr_sharpness"
"texture_sampling"
"delay_game_render_thread_us"
"layout_option"

View file

@ -718,6 +718,8 @@ void QtConfig::ReadRendererValues() {
ReadGlobalSetting(Settings::values.texture_filter);
ReadGlobalSetting(Settings::values.antialiasing_filter);
ReadGlobalSetting(Settings::values.output_scaling);
ReadGlobalSetting(Settings::values.fsr_sharpness);
ReadGlobalSetting(Settings::values.texture_sampling);
ReadGlobalSetting(Settings::values.delay_game_render_thread_us);
@ -1263,6 +1265,8 @@ void QtConfig::SaveRendererValues() {
WriteGlobalSetting(Settings::values.texture_filter);
WriteGlobalSetting(Settings::values.antialiasing_filter);
WriteGlobalSetting(Settings::values.output_scaling);
WriteGlobalSetting(Settings::values.fsr_sharpness);
WriteGlobalSetting(Settings::values.texture_sampling);
WriteGlobalSetting(Settings::values.delay_game_render_thread_us);

View file

@ -27,6 +27,8 @@ ConfigureEnhancements::ConfigureEnhancements(QWidget* parent)
updateShaders(static_cast<Settings::StereoRenderOption>(currentIndex));
});
connect(ui->fsr_sharpness_slider, &QSlider::valueChanged, this,
&ConfigureEnhancements::SetFSRSharpnessIndicatorText);
ui->toggle_preload_textures->setEnabled(ui->toggle_custom_textures->isChecked());
ui->toggle_async_custom_loading->setEnabled(ui->toggle_custom_textures->isChecked());
connect(ui->toggle_custom_textures, &QCheckBox::toggled, this, [this] {
@ -35,12 +37,18 @@ ConfigureEnhancements::ConfigureEnhancements(QWidget* parent)
if (!ui->toggle_preload_textures->isEnabled())
ui->toggle_preload_textures->setChecked(false);
});
connect(ui->output_scaling_combobox, &QComboBox::currentIndexChanged, this, &ConfigureEnhancements::SetFSRSharpnessEnabled);
}
ConfigureEnhancements::~ConfigureEnhancements() = default;
void ConfigureEnhancements::SetConfiguration() {
const s32 volume =
static_cast<s32>(Settings::values.fsr_sharpness.GetValue() * 100);
ui->fsr_sharpness_slider->setValue(volume);
SetFSRSharpnessIndicatorText(ui->fsr_sharpness_slider->sliderPosition());
if (!Settings::IsConfiguringGlobal()) {
ConfigurationShared::SetPerGameSetting(ui->resolution_factor_combobox,
&Settings::values.resolution_factor);
@ -52,6 +60,10 @@ void ConfigureEnhancements::SetConfiguration() {
&Settings::values.antialiasing_filter);
ConfigurationShared::SetHighlight(ui->widget_antialiasing_filter,
!Settings::values.antialiasing_filter.UsingGlobal());
ConfigurationShared::SetPerGameSetting(ui->output_scaling_combobox,
&Settings::values.output_scaling);
ConfigurationShared::SetHighlight(ui->widget_output_scaling,
!Settings::values.output_scaling.UsingGlobal());
} else {
ui->resolution_factor_combobox->setCurrentIndex(
Settings::values.resolution_factor.GetValue());
@ -59,8 +71,10 @@ void ConfigureEnhancements::SetConfiguration() {
static_cast<int>(Settings::values.texture_filter.GetValue()));
ui->antialiasing_filter_combobox->setCurrentIndex(
static_cast<int>(Settings::values.antialiasing_filter.GetValue()));
ui->output_scaling_combobox->setCurrentIndex(
static_cast<int>(Settings::values.output_scaling.GetValue()));
}
ui->fsr_sharpness_slider->setEnabled(ui->output_scaling_combobox->currentIndex() == 3);
ui->render_3d_combobox->setCurrentIndex(
static_cast<int>(Settings::values.render_3d.GetValue()));
ui->swap_eyes_3d->setChecked(Settings::values.swap_eyes_3d.GetValue());
@ -68,7 +82,6 @@ void ConfigureEnhancements::SetConfiguration() {
ui->mono_rendering_eye->setCurrentIndex(
static_cast<int>(Settings::values.mono_render_option.GetValue()));
updateShaders(Settings::values.render_3d.GetValue());
ui->toggle_linear_filter->setChecked(Settings::values.filter_mode.GetValue());
ui->use_integer_scaling->setChecked(Settings::values.use_integer_scaling.GetValue());
ui->toggle_dump_textures->setChecked(Settings::values.dump_textures.GetValue());
ui->toggle_custom_textures->setChecked(Settings::values.custom_textures.GetValue());
@ -77,6 +90,13 @@ void ConfigureEnhancements::SetConfiguration() {
ui->disable_right_eye_render->setChecked(Settings::values.disable_right_eye_render.GetValue());
}
void ConfigureEnhancements::SetFSRSharpnessIndicatorText(int percentage) {
ui->fsr_sharpness_indicator->setText(tr("%1%", "FSR Sharpness (e.g. 50%)").arg(percentage));
}
void ConfigureEnhancements::SetFSRSharpnessEnabled(int output) {
ui->fsr_sharpness_slider->setEnabled(output == 3);
}
void ConfigureEnhancements::updateShaders(Settings::StereoRenderOption stereo_option) {
ui->shader_combobox->clear();
ui->shader_combobox->setEnabled(true);
@ -132,14 +152,14 @@ void ConfigureEnhancements::ApplyConfiguration() {
}
Settings::values.disable_right_eye_render = ui->disable_right_eye_render->isChecked();
ConfigurationShared::ApplyPerGameSetting(&Settings::values.filter_mode,
ui->toggle_linear_filter, linear_filter);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_integer_scaling,
ui->use_integer_scaling, use_integer_scaling);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.texture_filter,
ui->texture_filter_combobox);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.antialiasing_filter,
ui->antialiasing_filter_combobox);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.output_scaling,
ui->output_scaling_combobox);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.dump_textures,
ui->toggle_dump_textures, dump_textures);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.custom_textures,
@ -159,7 +179,7 @@ void ConfigureEnhancements::SetupPerGameUI() {
ui->widget_resolution->setEnabled(Settings::values.resolution_factor.UsingGlobal());
ui->widget_texture_filter->setEnabled(Settings::values.texture_filter.UsingGlobal());
ui->widget_antialiasing_filter->setEnabled(Settings::values.antialiasing_filter.UsingGlobal());
ui->toggle_linear_filter->setEnabled(Settings::values.filter_mode.UsingGlobal());
ui->widget_output_scaling->setEnabled(Settings::values.output_scaling.UsingGlobal());
ui->use_integer_scaling->setEnabled(Settings::values.use_integer_scaling.UsingGlobal());
ui->toggle_dump_textures->setEnabled(Settings::values.dump_textures.UsingGlobal());
ui->toggle_custom_textures->setEnabled(Settings::values.custom_textures.UsingGlobal());
@ -177,8 +197,6 @@ void ConfigureEnhancements::SetupPerGameUI() {
ui->widget_shader->setVisible(false);
ConfigurationShared::SetColoredTristate(ui->toggle_linear_filter, Settings::values.filter_mode,
linear_filter);
ConfigurationShared::SetColoredTristate(
ui->use_integer_scaling, Settings::values.use_integer_scaling, use_integer_scaling);
ConfigurationShared::SetColoredTristate(ui->toggle_dump_textures,
@ -205,4 +223,8 @@ void ConfigureEnhancements::SetupPerGameUI() {
ConfigurationShared::SetColoredComboBox(
ui->antialiasing_filter_combobox, ui->widget_antialiasing_filter,
static_cast<int>(Settings::values.antialiasing_filter.GetValue(true)));
ConfigurationShared::SetColoredComboBox(
ui->output_scaling_combobox, ui->widget_output_scaling,
static_cast<int>(Settings::values.output_scaling.GetValue(true)));
}

View file

@ -36,7 +36,8 @@ public:
private:
void updateShaders(Settings::StereoRenderOption stereo_option);
void updateTextureFilter(int index);
void SetFSRSharpnessIndicatorText(int percentage);
void SetFSRSharpnessEnabled(int output);
std::unique_ptr<Ui::ConfigureEnhancements> ui;
ConfigurationShared::CheckState linear_filter;
ConfigurationShared::CheckState use_integer_scaling;

View file

@ -121,10 +121,184 @@
</widget>
</item>
<item>
<widget class="QCheckBox" name="toggle_linear_filter">
<property name="text">
<string>Enable Linear Filtering</string>
<widget class="QWidget" name="widget_output_scaling" native="true">
<property name="enabled">
<bool>true</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="output_scaling_label">
<property name="text">
<string>Output Scaling</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="output_scaling_combobox">
<item>
<property name="text">
<string>Nearest</string>
</property>
</item>
<item>
<property name="text">
<string>Bilinear</string>
</property>
</item>
<item>
<property name="text">
<string>Adaptive</string>
</property>
</item>
<item>
<property name="text">
<string>AMD FidelityFX Super Resolution 1</string>
</property>
</item>
<item>
<property name="text">
<string>Sharp Bilinear</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_fsr_sharpness" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_16">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="widget_fsr_sharpness_1" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_17">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="fsr_sharpness_label">
<property name="text">
<string>FSR Sharpness</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Policy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_fsr_sharpness_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_18">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSlider" name="fsr_sharpness_slider">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>5</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="fsr_sharpness_indicator">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>0 %</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
@ -457,7 +631,6 @@
</widget>
<tabstops>
<tabstop>resolution_factor_combobox</tabstop>
<tabstop>toggle_linear_filter</tabstop>
<tabstop>shader_combobox</tabstop>
<tabstop>texture_filter_combobox</tabstop>
<tabstop>antialiasing_filter_combobox</tabstop>

View file

@ -69,6 +69,23 @@ std::string_view GetAntialiasingFilterName(AntiAliasingFilter filter) {
return "Invalid";
}
}
std::string_view GetOutputScalingName(OutputScaling scaling) {
switch (scaling) {
case OutputScaling::Nearest:
return "Nearest";
case OutputScaling::Bilinear:
return "Bilinear";
case OutputScaling::Adaptive:
return "Adaptive";
case OutputScaling::FSR:
return "AMD FidelityFX Super Resolution 1";
case OutputScaling::SharpBilinear:
return "Sharp Bilinear";
default:
return "Invalid";
}
}
std::string_view GetTextureSamplingName(TextureSampling sampling) {
switch (sampling) {
case TextureSampling::GameControlled:
@ -116,6 +133,7 @@ void LogSettings() {
log_setting("Renderer_FilterMode", values.filter_mode.GetValue());
log_setting("Renderer_TextureFilter", GetTextureFilterName(values.texture_filter.GetValue()));
log_setting("Renderer_AntialiasingFilter", GetAntialiasingFilterName(values.antialiasing_filter.GetValue()));
log_setting("Renderer_OutputScaling", GetOutputScalingName(values.output_scaling.GetValue()));
log_setting("Renderer_TextureSampling",
GetTextureSamplingName(values.texture_sampling.GetValue()));
log_setting("Renderer_DelayGameRenderThreasUs", values.delay_game_render_thread_us.GetValue());
@ -227,6 +245,8 @@ void RestoreGlobalState(bool is_powered_on) {
values.frame_limit.SetGlobal(true);
values.texture_filter.SetGlobal(true);
values.antialiasing_filter.SetGlobal(true);
values.output_scaling.SetGlobal(true);
values.fsr_sharpness.SetGlobal(true);
values.texture_sampling.SetGlobal(true);
values.delay_game_render_thread_us.SetGlobal(true);
values.layout_option.SetGlobal(true);

View file

@ -118,6 +118,14 @@ enum class AntiAliasingFilter : u32 {
SMAA = 2,
};
enum class OutputScaling : u32 {
Nearest = 0,
Bilinear = 1,
Adaptive = 2,
FSR = 3,
SharpBilinear = 4,
};
enum class TextureSampling : u32 {
GameControlled = 0,
NearestNeighbor = 1,
@ -545,6 +553,8 @@ struct Values {
SwitchableSetting<double, true> turbo_limit{200, 0, 1000, Keys::turbo_limit};
SwitchableSetting<TextureFilter> texture_filter{TextureFilter::NoFilter, Keys::texture_filter};
SwitchableSetting<AntiAliasingFilter> antialiasing_filter{AntiAliasingFilter::None, Keys::antialiasing_filter};
SwitchableSetting<OutputScaling> output_scaling{OutputScaling::Adaptive, Keys::output_scaling};
SwitchableSetting<float, true> fsr_sharpness{0.8f, 0.f, 1.f, Keys::fsr_sharpness};
SwitchableSetting<TextureSampling> texture_sampling{TextureSampling::GameControlled,
Keys::texture_sampling};
SwitchableSetting<u16, true> delay_game_render_thread_us{0, 0, 16000,

View file

@ -664,12 +664,8 @@ void RendererOpenGL::DrawSingleScreen(const ScreenInfo& screen_info, float scree
// Texture Width and Height when correctly rotated to landscape
bool isDownsampling = false;
int scalingMode; //0 is Nearest Neighbor, 1 is Gamma Corrected Bilinear, 2 is High Quality Scaling (Upsampling via Gamma Corrected Bilinear, Downsampling is Gamma Corrected Area Sampling)
if (Settings::values.filter_mode.GetValue()){
scalingMode = 2;
} else {
scalingMode = 0;
}
int scalingMode; //0 is Nearest Neighbor, 1 is Gamma Corrected Bilinear, 2 is Adaptive (Bilinear/Area), 3 is FSR, 4 is Sharp Bilinear
scalingMode = static_cast<int>(Settings::values.output_scaling.GetValue());
int antialiasingMode = static_cast<int>(Settings::values.antialiasing_filter.GetValue()); //0 is none, 1 is FXAA, 2 is SMAA
if (orientation == Layout::DisplayOrientation::Landscape || orientation == Layout::DisplayOrientation::LandscapeFlipped) {
if (textureWidth > screenWidth){
@ -918,7 +914,7 @@ void RendererOpenGL::DrawSingleScreen(const ScreenInfo& screen_info, float scree
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(rotate_vertices), rotate_vertices.data());
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
if (scalingMode == 2){
if (scalingMode >= 2){
if (isDownsampling){
//Output
state.draw.read_framebuffer = originalReadFramebuffer;
@ -1047,7 +1043,8 @@ void RendererOpenGL::DrawSingleScreenStereo(const ScreenInfo& screen_info_l,
}
const u32 scale_factor = GetResolutionScaleFactor();
const GLuint sampler = samplers[Settings::values.filter_mode.GetValue()].handle;
int scalingMode = static_cast<int>(Settings::values.output_scaling.GetValue());
const GLuint sampler = samplers[scalingMode > 0 ? 1 : 0].handle;
glUniform4f(uniform_i_resolution,
static_cast<float>(screen_info_l.texture.width * scale_factor),
static_cast<float>(screen_info_l.texture.height * scale_factor),

View file

@ -418,8 +418,8 @@ void RendererVulkan::PrepareTextureDraw(TextureInfo framebufferTexture, vk::Fram
}
void RendererVulkan::PrepareDraw(Frame* frame, const Layout::FramebufferLayout& layout, std::vector<u32> screenids) {
const auto sampler = present_samplers[Settings::values.filter_mode.GetValue()];
void RendererVulkan::PrepareDraw(Frame* frame, const Layout::FramebufferLayout& layout, std::vector<u32> screenids, int filterMode) {
const auto sampler = present_samplers[filterMode];
const auto present_set = present_heap.Commit();
for (u32 i = 0; i < screenids.size(); i++) {
update_queue.AddImageSampler(present_set, i, 0, screen_infos[screenids[i]].image_view,
@ -1099,7 +1099,7 @@ void RendererVulkan::DrawSingleScreen(u32 screen_id, float screenLeft, float scr
const ScreenInfo& screen_info = screen_infos[screen_id];
const auto& texcoords = screen_info.texcoords;
std::vector<u32> screenids = {screen_id};
PrepareDraw(currentFrame, currentFramebufferLayout, screenids);
PrepareDraw(currentFrame, currentFramebufferLayout, screenids, 1);
// Apply the initial default opacity value; Needed to avoid flickering
if (applyingOpacity){
@ -1125,12 +1125,8 @@ void RendererVulkan::DrawSingleScreen(u32 screen_id, float screenLeft, float scr
// Texture Width and Height when correctly rotated to landscape
bool isDownsampling = false;
int scalingMode; //0 is Nearest Neighbor, 1 is Gamma Corrected Bilinear, 2 is High Quality Scaling (Upsampling via Gamma Corrected Bilinear, Downsampling is Gamma Corrected Area Sampling)
if (Settings::values.filter_mode.GetValue()){
scalingMode = 2;
} else {
scalingMode = 0;
}
int scalingMode; //0 is Nearest Neighbor, 1 is Gamma Corrected Bilinear, 2 is Adaptive (Bilinear/Area), 3 is FSR, 4 is Sharp Bilinear
scalingMode = static_cast<int>(Settings::values.output_scaling.GetValue());
int antialiasingMode = static_cast<int>(Settings::values.antialiasing_filter.GetValue()); //0 is none, 1 is FXAA, 2 is SMAA
if (orientation == Layout::DisplayOrientation::Landscape || orientation == Layout::DisplayOrientation::LandscapeFlipped) {
if (textureWidth > screenWidth){
@ -1278,7 +1274,7 @@ void RendererVulkan::DrawSingleScreenStereo(u32 screen_id_l, u32 screen_id_r, fl
const ScreenInfo& screen_info_l = screen_infos[screen_id_l];
const auto& texcoords = screen_info_l.texcoords;
std::vector<u32> screenids = {screen_id_l, screen_id_r};
PrepareDraw(currentFrame, currentFramebufferLayout, screenids);
PrepareDraw(currentFrame, currentFramebufferLayout, screenids, 1);
// Apply the initial default opacity value; Needed to avoid flickering
if (applyingOpacity){

View file

@ -98,7 +98,7 @@ private:
void RenderScreenshot();
void RenderScreenshotWithStagingCopy();
bool TryRenderScreenshotWithHostMemory();
void PrepareDraw(Frame* frame, const Layout::FramebufferLayout& layout, std::vector<u32> screenids);
void PrepareDraw(Frame* frame, const Layout::FramebufferLayout& layout, std::vector<u32> screenids, int filterMode);
void PrepareTextureDraw(TextureInfo framebufferTexture, vk::Framebuffer framebuffer, vk::Pipeline shaderPipeline, std::vector<TextureInfo> texturesToSample, int filterMode);
void RenderToWindow(PresentWindow& window, const Layout::FramebufferLayout& layout,
bool flipped);