UI: Add new UI upscaling fix for Native Scaling

This commit is contained in:
refractionpcsx2 2024-06-06 16:45:20 +01:00
parent 839a6daa63
commit 1d46ec2059
12 changed files with 1806 additions and 714 deletions

File diff suppressed because it is too large Load Diff

View File

@ -194,6 +194,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
// HW Upscaling Fixes
//////////////////////////////////////////////////////////////////////////
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.halfPixelOffset, "EmuCore/GS", "UserHacks_HalfPixelOffset", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.nativeScaling, "EmuCore/GS", "UserHacks_native_scaling", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.roundSprite, "EmuCore/GS", "UserHacks_round_sprite_offset", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.bilinearHack, "EmuCore/GS", "UserHacks_BilinearHack", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.textureOffsetX, "EmuCore/GS", "UserHacks_TCOffsetX", 0);
@ -1139,6 +1140,7 @@ void GraphicsSettingsWidget::resetManualHardwareFixes()
check_bool("EmuCore/GS", "UserHacks_EstimateTextureRegion", false);
check_bool("EmuCore/GS", "paltex", false);
check_int("EmuCore/GS", "UserHacks_HalfPixelOffset", 0);
check_int("EmuCore/GS", "UserHacks_native_scaling", static_cast<int>(GSNativeScaling::Off));
check_int("EmuCore/GS", "UserHacks_round_sprite_offset", 0);
check_int("EmuCore/GS", "UserHacks_TCOffsetX", 0);
check_int("EmuCore/GS", "UserHacks_TCOffsetY", 0);

View File

@ -1091,13 +1091,39 @@
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="nativeScalingLabel">
<property name="text">
<string>Native Scaling</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="nativeScaling">
<item>
<property name="text">
<string>Off</string>
</property>
</item>
<item>
<property name="text">
<string>Normal</string>
</property>
</item>
<item>
<property name="text">
<string>Aggressive</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="roundSpriteLabel">
<property name="text">
<string>Round Sprite:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<widget class="QComboBox" name="roundSprite">
<item>
<property name="text">
@ -1117,13 +1143,39 @@
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="bilinearHackLabel">
<property name="text">
<string>Bilinear Dirty Upscale:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="bilinearHack">
<item>
<property name="text">
<string>Automatic (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Force Bilinear</string>
</property>
</item>
<item>
<property name="text">
<string>Force Nearest</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="textureOffsetLabel">
<property name="text">
<string>Texture Offsets:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<layout class="QHBoxLayout" name="textureOffsetLayout" stretch="0,1,0,1">
<item>
<widget class="QLabel" name="textureOffsetXLabel">
@ -1155,7 +1207,7 @@
</item>
</layout>
</item>
<item row="4" column="0" colspan="2">
<item row="5" column="0" colspan="2">
<layout class="QGridLayout" name="upscalingFixesLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="alignSprite">
@ -1171,13 +1223,6 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="forceEvenSpritePosition">
<property name="text">
<string>Force Even Sprite Position</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="mergeSprite">
<property name="text">
@ -1185,34 +1230,15 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="forceEvenSpritePosition">
<property name="text">
<string>Force Even Sprite Position</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="bilinearHackLabel">
<property name="text">
<string>Bilinear Dirty Upscale:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="bilinearHack">
<item>
<property name="text">
<string>Automatic (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Force Bilinear</string>
</property>
</item>
<item>
<property name="text">
<string>Force Nearest</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="textureReplacementTab">

View File

@ -387,6 +387,14 @@ enum class GSHalfPixelOffset : u8
MaxCount
};
enum class GSNativeScaling : u8
{
Off,
Normal,
Aggressive,
MaxCount
};
// --------------------------------------------------------------------------------------
// TraceFiltersEE
// --------------------------------------------------------------------------------------
@ -690,6 +698,7 @@ struct Pcsx2Config
GSHWAutoFlushLevel UserHacks_AutoFlush = GSHWAutoFlushLevel::Disabled;
GSHalfPixelOffset UserHacks_HalfPixelOffset = GSHalfPixelOffset::Off;
s8 UserHacks_RoundSprite = 0;
GSNativeScaling UserHacks_NativeScaling = GSNativeScaling::Off;
s32 UserHacks_TCOffsetX = 0;
s32 UserHacks_TCOffsetY = 0;
u8 UserHacks_CPUSpriteRenderBW = 0;

View File

@ -179,6 +179,7 @@ The clamp modes are also numerically based.
* skipDrawStart [Value between `0` to `10000`] {0-10000} Default: Off (`0`)
* skipDrawEnd [Value between `0` to `10000`] {0-10000} Default: Off (`0`)
* halfPixelOffset [`0` or `1` or `2` or `3` or `4`] {Off, Normal Vertex, Special (Texture), Special (Texture Aggressive), Align to Native} Default: Off (`0`)
* nativeScaling [`0` or `1` or `2`] {Normal, Aggressive or Off} Default: Normal (`0`)
* nativePaletteDraw [`0` or `1`] {Off, On} Default: Off (`0`)
* roundSprite [`0` or `1` or `2`] {Off, Half or Full} Default: Off (`0`)

View File

@ -239,6 +239,11 @@
"minimum": 0,
"maximum": 4
},
"nativeScaling": {
"type": "integer",
"minimum": 0,
"maximum": 2
},
"roundSprite": {
"type": "integer",
"minimum": 0,

View File

@ -2625,7 +2625,7 @@ void GSRendererHW::Draw()
m_downscale_source = src->m_from_target->GetScale() > 1.0f;
}
else
m_downscale_source = false; //src->m_from_target->GetScale() > 1.0f; // Bad for GTA + Full Spectrum Warrior, good for Sacred Blaze + Parappa.
m_downscale_source = GSConfig.UserHacks_NativeScaling != GSNativeScaling::Aggressive ? false : src->m_from_target->GetScale() > 1.0f; // Bad for GTA + Full Spectrum Warrior, good for Sacred Blaze + Parappa.
}
else
m_downscale_source = false;
@ -7213,6 +7213,9 @@ int GSRendererHW::IsScalingDraw(GSTextureCache::Source* src, bool no_gaps)
if (is_downscale && draw_size.x >= PCRTCDisplays.GetResolution().x)
return 0;
if (GSConfig.UserHacks_NativeScaling == GSNativeScaling::Off)
return 0;
// Check if we're already downscaled and drawing in current size, try not to rescale it.
if (src && src->m_from_target && src->m_from_target->m_downscaled && std::abs(draw_size.x - tex_size.x) <= 1 && std::abs(draw_size.y - tex_size.y) <= 1)
return 1;

View File

@ -383,6 +383,7 @@ static const char* s_gs_hw_fix_names[] = {
"halfBottomOverride",
"halfPixelOffset",
"roundSprite",
"nativeScaling",
"texturePreloading",
"deinterlace",
"cpuSpriteRenderBW",
@ -638,6 +639,9 @@ bool GameDatabaseSchema::GameEntry::configMatchesHWFix(const Pcsx2Config::GSOpti
case GSHWFixId::RoundSprite:
return (config.UpscaleMultiplier <= 1.0f || config.UserHacks_RoundSprite == value);
case GSHWFixId::NativeScaling:
return (static_cast<int>(config.UserHacks_NativeScaling) == value);
case GSHWFixId::TexturePreloading:
return (static_cast<int>(config.TexturePreloading) <= value);
@ -810,6 +814,10 @@ void GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions&
config.UserHacks_RoundSprite = value;
break;
case GSHWFixId::NativeScaling:
config.UserHacks_NativeScaling = static_cast<GSNativeScaling>(value);
break;
case GSHWFixId::TexturePreloading:
{
if (value >= 0 && value <= static_cast<int>(TexturePreloadingLevel::Full))

View File

@ -68,6 +68,7 @@ namespace GameDatabaseSchema
HalfBottomOverride,
HalfPixelOffset,
RoundSprite,
NativeScaling,
TexturePreloading,
Deinterlace,
CPUSpriteRenderBW,

View File

@ -3730,6 +3730,11 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
FSUI_NSTR("Special (Texture - Aggressive)"),
FSUI_NSTR("Align To Native"),
};
static constexpr const char* s_native_scaling_options[] = {
FSUI_NSTR("Normal (Default)"),
FSUI_NSTR("Aggressive"),
FSUI_NSTR("Off"),
};
static constexpr const char* s_round_sprite_options[] = {
FSUI_NSTR("Off (Default)"),
FSUI_NSTR("Half"),
@ -3795,6 +3800,8 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
MenuHeading(FSUI_CSTR("Upscaling Fixes"));
DrawIntListSetting(bsi, FSUI_CSTR("Half Pixel Offset"), FSUI_CSTR("Adjusts vertices relative to upscaling."), "EmuCore/GS",
"UserHacks_HalfPixelOffset", 0, s_half_pixel_offset_options, std::size(s_half_pixel_offset_options), true);
DrawIntListSetting(bsi, FSUI_CSTR("Native Scaling"), FSUI_CSTR("Attempt to do rescaling at native resolution."), "EmuCore/GS",
"UserHacks_native_scaling", 0, s_native_scaling_options, std::size(s_native_scaling_options), true);
DrawIntListSetting(bsi, FSUI_CSTR("Round Sprite"), FSUI_CSTR("Adjusts sprite coordinates."), "EmuCore/GS",
"UserHacks_round_sprite_offset", 0, s_round_sprite_options, std::size(s_round_sprite_options), true);
DrawIntListSetting(bsi, FSUI_CSTR("Bilinear Upscale"),

View File

@ -392,6 +392,8 @@ __ri void ImGuiManager::DrawSettingsOverlay(float scale, float margin, float spa
APPEND("HPO={} ", static_cast<u32>(GSConfig.UserHacks_HalfPixelOffset));
if (GSConfig.UserHacks_RoundSprite > 0)
APPEND("RS={} ", GSConfig.UserHacks_RoundSprite);
if (GSConfig.UserHacks_NativeScaling > GSNativeScaling::Off)
APPEND("NS={} ", static_cast<unsigned>(GSConfig.UserHacks_NativeScaling));
if (GSConfig.UserHacks_TCOffsetX != 0 || GSConfig.UserHacks_TCOffsetY != 0)
APPEND("TCO={}/{} ", GSConfig.UserHacks_TCOffsetX, GSConfig.UserHacks_TCOffsetY);
if (GSConfig.UserHacks_CPUSpriteRenderBW != 0)

View File

@ -723,6 +723,7 @@ bool Pcsx2Config::GSOptions::OptionsAreEqual(const GSOptions& right) const
OpEqu(UserHacks_AutoFlush) &&
OpEqu(UserHacks_HalfPixelOffset) &&
OpEqu(UserHacks_RoundSprite) &&
OpEqu(UserHacks_NativeScaling) &&
OpEqu(UserHacks_TCOffsetX) &&
OpEqu(UserHacks_TCOffsetY) &&
OpEqu(UserHacks_CPUSpriteRenderBW) &&
@ -904,6 +905,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
SettingsWrapIntEnumEx(UserHacks_HalfPixelOffset, "UserHacks_HalfPixelOffset");
SettingsWrapBitfieldEx(UserHacks_RoundSprite, "UserHacks_round_sprite_offset");
SettingsWrapIntEnumEx(UserHacks_NativeScaling, "UserHacks_native_scaling");
SettingsWrapBitfieldEx(UserHacks_TCOffsetX, "UserHacks_TCOffsetX");
SettingsWrapBitfieldEx(UserHacks_TCOffsetY, "UserHacks_TCOffsetY");
SettingsWrapBitfieldEx(UserHacks_CPUSpriteRenderBW, "UserHacks_CPUSpriteRenderBW");
@ -960,6 +962,7 @@ void Pcsx2Config::GSOptions::MaskUserHacks()
UserHacks_DisableRenderFixes = false;
UserHacks_HalfPixelOffset = GSHalfPixelOffset::Off;
UserHacks_RoundSprite = 0;
UserHacks_NativeScaling = GSNativeScaling::Off;
UserHacks_AutoFlush = GSHWAutoFlushLevel::Disabled;
GPUPaletteConversion = false;
PreloadFrameWithGSData = false;
@ -992,6 +995,7 @@ void Pcsx2Config::GSOptions::MaskUpscalingHacks()
UserHacks_NativePaletteDraw = false;
UserHacks_HalfPixelOffset = GSHalfPixelOffset::Off;
UserHacks_RoundSprite = 0;
UserHacks_NativeScaling = GSNativeScaling::Off;
UserHacks_TCOffsetX = 0;
UserHacks_TCOffsetY = 0;
}