GS/HW: Add a new option to attempt to reduce large texture sizes

For Snowblind games which use 1024x1024 textures and UVs.
This commit is contained in:
Stenzek 2023-02-15 21:51:34 +10:00 committed by refractionpcsx2
parent 4595c2feec
commit 43c6e321f5
10 changed files with 54 additions and 0 deletions

View File

@ -203,6 +203,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.textureInsideRt, "EmuCore/GS", "UserHacks_TextureInsideRt", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.readTCOnClose, "EmuCore/GS", "UserHacks_ReadTCOnClose", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.targetPartialInvalidation, "EmuCore/GS", "UserHacks_TargetPartialInvalidation", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.estimateTextureRegion, "EmuCore/GS", "UserHacks_EstimateTextureRegion", false);
//////////////////////////////////////////////////////////////////////////
// HW Upscaling Fixes
@ -549,6 +550,9 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
dialog->registerWidgetHelp(m_ui.targetPartialInvalidation, tr("Target Partial Invalidation"), tr("Unchecked"),
tr("Allows partial invalidation of render targets, which can fix graphical errors in some games. Texture Inside Render Target "
"automatically enables this option."));
dialog->registerWidgetHelp(m_ui.estimateTextureRegion, tr("Estimate Texture Region"), tr("Unchecked"),
tr("Attempts to reduce the texture size when games do not set it themselves (e.g. Snowblind games)."));
}
// Upscaling Fixes tab

View File

@ -1068,6 +1068,13 @@
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="estimateTextureRegion">
<property name="text">
<string>Estimate Texture Region</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>

View File

@ -672,6 +672,7 @@ struct Pcsx2Config
UserHacks_WildHack : 1,
UserHacks_TextureInsideRt : 1,
UserHacks_TargetPartialInvalidation : 1,
UserHacks_EstimateTextureRegion : 1,
FXAA : 1,
ShadeBoost : 1,
DumpGSData : 1,

View File

@ -176,6 +176,11 @@
"minimum": 0,
"maximum": 1
},
"estimateTextureRegion": {
"type": "integer",
"minimum": 0,
"maximum": 1
},
"mipmap": {
"type": "integer",
"minimum": 0,

View File

@ -3203,6 +3203,9 @@ void FullscreenUI::DrawGraphicsSettingsPage()
DrawToggleSetting(bsi, "Read Targets When Closing",
"Flushes all targets in the texture cache back to local memory when shutting down.", "EmuCore/GS",
"UserHacks_ReadTCOnClose", false, manual_hw_fixes);
DrawToggleSetting(bsi, "Estimate Texture Region",
"Attempts to reduce the texture size when games do not set it themselves (e.g. Snowblind games).", "EmuCore/GS",
"UserHacks_EstimateTextureRegion", false, manual_hw_fixes);
MenuHeading("Upscaling Fixes");
DrawIntListSetting(bsi, "Half-Pixel Offset", "Adjusts vertices relative to upscaling.", "EmuCore/GS",

View File

@ -1636,6 +1636,27 @@ void GSRendererHW::Draw()
tmm = GetTextureMinMax(TEX0, MIP_CLAMP, m_vt.IsLinear());
// Snowblind games set TW/TH to 1024, and use UVs for smaller textures inside that.
// Such textures usually contain junk in local memory, so try to make them smaller based on UVs.
// We can only do this for UVs, because ST repeat won't be correct.
if (GSConfig.UserHacks_EstimateTextureRegion && // enabled
(PRIM->FST || (MIP_CLAMP.WMS == CLAMP_CLAMP && MIP_CLAMP.WMT == CLAMP_CLAMP)) && // UV or ST with clamp
TEX0.TW >= 9 && TEX0.TH >= 9 && // 512x512
MIP_CLAMP.WMS < CLAMP_REGION_CLAMP && MIP_CLAMP.WMT < CLAMP_REGION_CLAMP && // not using custom region
((m_vt.m_max.t >= GSVector4(512.0f)).mask() & 0x3) == 0) // If the UVs actually are large, don't optimize.
{
// Clamp to the UVs of the texture. We could align this to something, but it ends up working better to just duplicate
// for different sizes in the hash cache, rather than hashing more and duplicating based on local memory.
const GSVector4i maxt(m_vt.m_max.t + GSVector4(m_vt.IsLinear() ? 0.5f : 0.0f));
MIP_CLAMP.WMS = CLAMP_REGION_CLAMP;
MIP_CLAMP.WMT = CLAMP_REGION_CLAMP;
MIP_CLAMP.MINU = 0;
MIP_CLAMP.MAXU = (maxt.x - 1) >> m_lod.x;
MIP_CLAMP.MINV = 0;
MIP_CLAMP.MAXV = (maxt.y - 1) >> m_lod.x;
}
m_src = tex_psm.depth ? m_tc->LookupDepthSource(TEX0, env.TEXA, MIP_CLAMP, tmm.coverage) :
m_tc->LookupSource(TEX0, env.TEXA, MIP_CLAMP, tmm.coverage, (GSConfig.HWMipmap >= HWMipmapLevel::Basic || GSConfig.TriFilter == TriFiltering::Forced) ? &hash_lod_range : nullptr);
}

View File

@ -352,6 +352,7 @@ static const char* s_gs_hw_fix_names[] = {
"alignSprite",
"mergeSprite",
"wildArmsHack",
"estimateTextureRegion",
"mipmap",
"trilinearFiltering",
"skipDrawStart",
@ -580,6 +581,9 @@ bool GameDatabaseSchema::GameEntry::configMatchesHWFix(const Pcsx2Config::GSOpti
case GSHWFixId::WildArmsHack:
return (config.UpscaleMultiplier <= 1.0f || static_cast<int>(config.UserHacks_WildHack) == value);
case GSHWFixId::EstimateTextureRegion:
return (static_cast<int>(config.UserHacks_EstimateTextureRegion) == value);
case GSHWFixId::Mipmap:
return (config.HWMipmap == HWMipmapLevel::Automatic || static_cast<int>(config.HWMipmap) == value);
@ -702,6 +706,10 @@ u32 GameDatabaseSchema::GameEntry::applyGSHardwareFixes(Pcsx2Config::GSOptions&
config.UserHacks_WildHack = (value > 0);
break;
case GSHWFixId::EstimateTextureRegion:
config.UserHacks_EstimateTextureRegion = (value > 0);
break;
case GSHWFixId::Mipmap:
{
if (value >= 0 && value <= static_cast<int>(HWMipmapLevel::Full))

View File

@ -72,6 +72,7 @@ namespace GameDatabaseSchema
AlignSprite,
MergeSprite,
WildArmsHack,
EstimateTextureRegion,
// integer settings
Mipmap,

View File

@ -649,6 +649,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
GSSettingBoolEx(UserHacks_WildHack, "UserHacks_WildHack");
GSSettingBoolEx(UserHacks_TextureInsideRt, "UserHacks_TextureInsideRt");
GSSettingBoolEx(UserHacks_TargetPartialInvalidation, "UserHacks_TargetPartialInvalidation");
GSSettingBoolEx(UserHacks_EstimateTextureRegion, "UserHacks_EstimateTextureRegion");
GSSettingBoolEx(FXAA, "fxaa");
GSSettingBool(ShadeBoost);
GSSettingBoolEx(DumpGSData, "dump");
@ -776,6 +777,7 @@ void Pcsx2Config::GSOptions::MaskUserHacks()
UserHacks_ReadTCOnClose = false;
UserHacks_TextureInsideRt = false;
UserHacks_TargetPartialInvalidation = false;
UserHacks_EstimateTextureRegion = false;
UserHacks_TCOffsetX = 0;
UserHacks_TCOffsetY = 0;
UserHacks_CPUSpriteRenderBW = 0;

View File

@ -1997,6 +1997,8 @@ void VMManager::WarnAboutUnsafeSettings()
messages += ICON_FA_EXCLAMATION_CIRCLE " GPU Palette Conversion is enabled, this may reduce performance.\n";
if (EmuConfig.GS.TexturePreloading != TexturePreloadingLevel::Full)
messages += ICON_FA_EXCLAMATION_CIRCLE " Texture Preloading is not Full, this may reduce performance.\n";
if (EmuConfig.GS.UserHacks_EstimateTextureRegion)
messages += ICON_FA_EXCLAMATION_CIRCLE " Estimate texture region is enabled, this may reduce performance.\n";
if (!messages.empty())
{