GPU: Add Disable Upscaled Direct Textures option

Needed for games like Fear Effect which use FMV/16-bit backgrounds.

Probably others, feel free to suggest/add them.
pull/3799/head
Stenzek 1 week ago
parent 024face27d
commit 28ea031c40
No known key found for this signature in database

@ -4806,6 +4806,12 @@ void FullscreenUI::DrawGraphicsSettingsPage()
"less noticeable. Usually safe to enable."),
"GPU", "ScaledInterlacing", true, resolution_scale > 1);
DrawToggleSetting(
bsi, FSUI_ICONVSTR(ICON_FA_IMAGE, "Disable Upscaled Direct Textures"),
FSUI_VSTR("Samples 16-bit direct-color textures at native resolution when upscaling. This can fix filtering of "
"FMVs/backgrounds in some games, but may reduce the quality of render-to-texture effects."),
"GPU", "DisableUpscaledDirectTextures", false, resolution_scale > 1);
DrawToggleSetting(bsi, FSUI_ICONVSTR(ICON_FA_SWATCHBOOK, "Texture Modulation Cropping (\"Old/v0\" GPU)"),
FSUI_VSTR("Crops vertex colours to 5:5:5 before modulating with the texture colour, which "
"typically results in more visible banding."),

@ -273,6 +273,7 @@ TRANSLATE_NOOP("FullscreenUI", "Disable Mailbox Presentation");
TRANSLATE_NOOP("FullscreenUI", "Disable Speedup on MDEC");
TRANSLATE_NOOP("FullscreenUI", "Disable Subdirectory Scanning");
TRANSLATE_NOOP("FullscreenUI", "Disable Textures");
TRANSLATE_NOOP("FullscreenUI", "Disable Upscaled Direct Textures");
TRANSLATE_NOOP("FullscreenUI", "Disable Vertex Lighting");
TRANSLATE_NOOP("FullscreenUI", "Disable Window Resizing");
TRANSLATE_NOOP("FullscreenUI", "Disable on 2D Polygons");
@ -678,6 +679,7 @@ TRANSLATE_NOOP("FullscreenUI", "Runs the software renderer in parallel for VRAM
TRANSLATE_NOOP("FullscreenUI", "SDL DualSense Player LED");
TRANSLATE_NOOP("FullscreenUI", "SDL DualShock 4 / DualSense Enhanced Mode");
TRANSLATE_NOOP("FullscreenUI", "Safe Mode");
TRANSLATE_NOOP("FullscreenUI", "Samples 16-bit direct-color textures at native resolution when upscaling. This can fix filtering of FMVs/backgrounds in some games, but may reduce the quality of render-to-texture effects.");
TRANSLATE_NOOP("FullscreenUI", "Save");
TRANSLATE_NOOP("FullscreenUI", "Save Controller Preset");
TRANSLATE_NOOP("FullscreenUI", "Save Locations");

@ -151,6 +151,7 @@ static constexpr const std::array s_trait_names = {
"ForceRecompilerICache",
"ForceCDROMSubQSkew",
"IsLibCryptProtected",
"DisableUpscaledDirectTextures",
};
static_assert(s_trait_names.size() == static_cast<size_t>(Trait::MaxCount));
@ -189,6 +190,7 @@ static constexpr const std::array s_trait_display_names = {
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Recompiler ICache", "GameDatabase::Trait"),
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force CD-ROM SubQ Skew", "GameDatabase::Trait"),
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Is LibCrypt Protected", "GameDatabase::Trait"),
TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Disable Upscaled Direct Textures", "GameDatabase::Trait"),
};
static_assert(s_trait_display_names.size() == static_cast<size_t>(Trait::MaxCount));
@ -681,6 +683,11 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
settings.gpu_force_round_texcoords = true;
}
if (HasTrait(Trait::DisableUpscaledDirectTextures))
{
settings.gpu_disable_upscaled_direct_textures = true;
}
if (HasTrait(Trait::ForceDeinterlacing))
{
const DisplayDeinterlacingMode new_mode = display_deinterlacing_mode.value_or(

@ -68,6 +68,7 @@ enum class Trait : u32
ForceRecompilerICache,
ForceCDROMSubQSkew,
IsLibCryptProtected,
DisableUpscaledDirectTextures,
MaxCount
};

@ -527,6 +527,8 @@ bool GPU_HW::UpdateSettings(const GPUSettings& old_settings, Error* error)
g_gpu_settings.gpu_scaled_interlacing != old_settings.gpu_scaled_interlacing)) ||
(resolution_scale > 1 && g_gpu_settings.gpu_texture_filter == GPUTextureFilter::Nearest &&
g_gpu_settings.gpu_force_round_texcoords != old_settings.gpu_force_round_texcoords) ||
(resolution_scale > 1 &&
g_gpu_settings.gpu_disable_upscaled_direct_textures != old_settings.gpu_disable_upscaled_direct_textures) ||
g_gpu_settings.gpu_modulation_crop != old_settings.gpu_modulation_crop ||
g_gpu_settings.IsUsingShaderBlending() != old_settings.IsUsingShaderBlending() ||
m_texture_filtering != g_gpu_settings.gpu_texture_filter ||
@ -915,6 +917,8 @@ void GPU_HW::PrintSettingsToLog()
(m_resolution_scale > 1 && g_gpu_settings.gpu_scaled_interlacing) ? " (scaled)" : "");
INFO_LOG("Force round texture coordinates: {}",
(m_resolution_scale > 1 && g_gpu_settings.gpu_force_round_texcoords) ? "Enabled" : "Disabled");
INFO_LOG("Disable upscaled direct textures: {}",
(m_resolution_scale > 1 && g_gpu_settings.gpu_disable_upscaled_direct_textures) ? "Enabled" : "Disabled");
INFO_LOG("Texture Filtering: {}/{}", Settings::GetTextureFilterDisplayName(m_texture_filtering),
Settings::GetTextureFilterDisplayName(m_sprite_texture_filtering));
INFO_LOG("Dual-source blending: {}", m_supports_dual_source_blend ? "Supported" : "Not supported");
@ -1277,6 +1281,7 @@ bool GPU_HW::CompilePipelines(Error* error)
const bool per_sample_shading = (msaa && g_gpu_settings.gpu_per_sample_shading && features.per_sample_shading);
const bool force_round_texcoords =
(upscaled && m_texture_filtering == GPUTextureFilter::Nearest && g_gpu_settings.gpu_force_round_texcoords);
const bool disable_upscaled_direct_textures = (upscaled && g_gpu_settings.gpu_disable_upscaled_direct_textures);
const bool modulation_crop = g_gpu_settings.gpu_modulation_crop;
const bool true_color = g_gpu_settings.IsUsingTrueColor();
const bool scaled_dithering = (!m_true_color && upscaled && g_gpu_settings.IsUsingScaledDithering());
@ -1380,6 +1385,7 @@ bool GPU_HW::CompilePipelines(Error* error)
vssel.per_sample_shading = per_sample_shading;
vssel.pgxp_depth = m_pgxp_depth_buffer;
vssel.disable_color_perspective = disable_color_perspective;
vssel.disable_upscaled_direct_textures = disable_upscaled_direct_textures;
for (u8 textured = 0; textured < 2; textured++)
{
vssel.textured = (textured != 0);
@ -1430,6 +1436,7 @@ bool GPU_HW::CompilePipelines(Error* error)
fssel.true_color = true_color;
fssel.disable_color_perspective = disable_color_perspective;
fssel.write_mask_as_depth = m_write_mask_as_depth;
fssel.disable_upscaled_direct_textures = disable_upscaled_direct_textures;
for (u8 depth_test = 0; depth_test < 2; depth_test++)
{

@ -81,6 +81,7 @@ std::string GPU_HW_ShaderGen::GenerateBatchVertexShader(const BatchVertexShaderS
DefineMacro(ss, "PAGE_TEXTURE", sel.page_texture);
DefineMacro(ss, "UV_LIMITS", sel.uv_limits);
DefineMacro(ss, "FORCE_ROUND_TEXCOORDS", sel.force_round_texcoords);
DefineMacro(ss, "DISABLE_UPSCALED_DIRECT_TEXTURES", sel.disable_upscaled_direct_textures);
DefineMacro(ss, "PGXP_DEPTH", sel.pgxp_depth);
DefineMacro(ss, "UPSCALED", sel.upscaled);
@ -159,7 +160,7 @@ std::string GPU_HW_ShaderGen::GenerateBatchVertexShader(const BatchVertexShaderS
v_col0 = a_col0;
#if TEXTURED
v_tex0 = float2(uint2(a_texcoord & 0xFFFFu, a_texcoord >> 16));
#if !PALETTE && !PAGE_TEXTURE
#if !PALETTE && !PAGE_TEXTURE && !DISABLE_UPSCALED_DIRECT_TEXTURES
v_tex0 *= u_resolution_scale;
#endif
@ -180,7 +181,7 @@ std::string GPU_HW_ShaderGen::GenerateBatchVertexShader(const BatchVertexShaderS
// Add 0.5 to the upper bounds when upscaling, to work around interpolation differences.
// Limited to force-round-texcoord hack, to avoid breaking other games.
v_uv_limits.zw += 0.5;
#elif !PAGE_TEXTURE && !PALETTE
#elif !PAGE_TEXTURE && !PALETTE && !DISABLE_UPSCALED_DIRECT_TEXTURES
// Treat coordinates as being in upscaled space, and extend the UV range to all "upscaled"
// pixels. This means 1-pixel-high polygon-based framebuffer effects won't be downsampled.
// (e.g. Mega Man Legends 2 haze effect)
@ -2200,6 +2201,7 @@ std::string GPU_HW_ShaderGen::GenerateBatchFragmentShader(const BatchFragmentSha
DefineMacro(ss, "USE_DUAL_SOURCE", use_dual_source);
DefineMacro(ss, "WRITE_MASK_AS_DEPTH", sel.write_mask_as_depth);
DefineMacro(ss, "FORCE_ROUND_TEXCOORDS", sel.force_round_texcoords);
DefineMacro(ss, "DISABLE_UPSCALED_DIRECT_TEXTURES", sel.disable_upscaled_direct_textures);
DefineMacro(ss, "UPSCALED", sel.upscaled);
// Used for converting to normalized coordinates for sampling.
@ -2356,6 +2358,12 @@ float4 SampleFromVRAM(TEXPAGE_VALUE texpage, DECLARE_UV_LIMITS(float2 coords, fl
uint2 icoord = ApplyTextureWindow(FloatToIntegerCoords(DECLARE_UV_LIMITS(coords, uv_limits)));
uint2 vicoord = (texpage.xy + icoord) & uint2(1023, 511);
return LOAD_TEXTURE(samp0, int2(vicoord), 0);
#elif DISABLE_UPSCALED_DIRECT_TEXTURES
// Treat direct textures as native resolution, so filtering offsets move to adjacent native texels instead of
// duplicated upscaled texels.
uint2 icoord = ApplyTextureWindow(FloatToIntegerCoords(DECLARE_UV_LIMITS(coords, uv_limits)));
uint2 vicoord = (texpage.xy + icoord) & uint2(1023, 511);
return SAMPLE_TEXTURE_LEVEL(samp0, float2(vicoord) * RCP_VRAM_SIZE, 0.0);
#else
// Coordinates are already upscaled, we need to downscale them to apply the texture
// window, then re-upscale/offset. We can't round here, because it could result in

@ -22,6 +22,7 @@ public:
bool force_round_texcoords : 1;
bool pgxp_depth : 1;
bool disable_color_perspective : 1;
bool disable_upscaled_direct_textures : 1;
};
struct BatchFragmentShaderSelector
@ -49,6 +50,7 @@ public:
bool use_rov_depth : 1;
bool rov_depth_test : 1;
bool rov_depth_write : 1;
bool disable_upscaled_direct_textures : 1;
};
public:

@ -325,6 +325,7 @@ void Settings::Load(const SettingsInterface& si, const SettingsInterface& contro
gpu_use_software_renderer_for_memory_states = si.GetBoolValue("GPU", "UseSoftwareRendererForMemoryStates", false);
gpu_scaled_interlacing = si.GetBoolValue("GPU", "ScaledInterlacing", true);
gpu_force_round_texcoords = si.GetBoolValue("GPU", "ForceRoundTextureCoordinates", false);
gpu_disable_upscaled_direct_textures = si.GetBoolValue("GPU", "DisableUpscaledDirectTextures", false);
gpu_texture_filter = ParseTextureFilterName(si.GetStringViewValue("GPU", "TextureFilter",
GetTextureFilterName(DEFAULT_GPU_TEXTURE_FILTER)))
.value_or(DEFAULT_GPU_TEXTURE_FILTER);
@ -734,6 +735,7 @@ void Settings::Save(SettingsInterface& si, bool for_copy) const
si.SetBoolValue("GPU", "UseSoftwareRendererForMemoryStates", gpu_use_software_renderer_for_memory_states);
si.SetBoolValue("GPU", "ScaledInterlacing", gpu_scaled_interlacing);
si.SetBoolValue("GPU", "ForceRoundTextureCoordinates", gpu_force_round_texcoords);
si.SetBoolValue("GPU", "DisableUpscaledDirectTextures", gpu_disable_upscaled_direct_textures);
si.SetStringValue("GPU", "TextureFilter", GetTextureFilterName(gpu_texture_filter));
si.SetStringValue("GPU", "SpriteTextureFilter", GetTextureFilterName(gpu_sprite_texture_filter));
si.SetStringValue("GPU", "DitheringMode", GetGPUDitheringModeName(gpu_dithering_mode));
@ -1148,6 +1150,7 @@ void Settings::ApplySettingRestrictions()
gpu_per_sample_shading = false;
gpu_scaled_interlacing = false;
gpu_force_round_texcoords = false;
gpu_disable_upscaled_direct_textures = false;
gpu_texture_filter = GPUTextureFilter::Nearest;
gpu_sprite_texture_filter = GPUTextureFilter::Nearest;
gpu_dithering_mode = GPUDitheringMode::Unscaled;

@ -78,6 +78,7 @@ struct GPUSettings
bool gpu_per_sample_shading : 1 = false;
bool gpu_scaled_interlacing : 1 = true;
bool gpu_force_round_texcoords : 1 = false;
bool gpu_disable_upscaled_direct_textures : 1 = false;
bool gpu_widescreen_rendering : 1 = false;
bool gpu_widescreen_hack : 1 = false;
bool gpu_modulation_crop : 1 = false;

@ -5,7 +5,7 @@
#include "common/types.h"
inline constexpr u32 SHADER_CACHE_VERSION = 39;
inline constexpr u32 SHADER_CACHE_VERSION = 40;
// Used to tag opaque keys.
enum class ShaderCacheKeyType : u16

@ -4658,6 +4658,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
old_settings.gpu_use_software_renderer_for_memory_states ||
g_settings.gpu_scaled_interlacing != old_settings.gpu_scaled_interlacing ||
g_settings.gpu_force_round_texcoords != old_settings.gpu_force_round_texcoords ||
g_settings.gpu_disable_upscaled_direct_textures != old_settings.gpu_disable_upscaled_direct_textures ||
g_settings.gpu_texture_filter != old_settings.gpu_texture_filter ||
g_settings.gpu_sprite_texture_filter != old_settings.gpu_sprite_texture_filter ||
g_settings.gpu_dithering_mode != old_settings.gpu_dithering_mode ||

@ -178,6 +178,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
Settings::DEFAULT_GPU_MAX_QUEUED_FRAMES);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.modulationCrop, "GPU", "EnableModulationCrop", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.scaledInterlacing, "GPU", "ScaledInterlacing", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableUpscaledDirectTextures, "GPU",
"DisableUpscaledDirectTextures", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useSoftwareRendererForReadbacks, "GPU",
"UseSoftwareRendererForReadbacks", false);
@ -192,6 +194,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
m_dialog->hasGameTrait(GameDatabase::Trait::ForceSoftwareRendererForReadbacks));
SettingWidgetBinder::SetForceEnabled(
m_ui.forceRoundedTexcoords, m_dialog->hasGameTrait(GameDatabase::Trait::ForceRoundUpscaledTextureCoordinates));
SettingWidgetBinder::SetForceEnabled(m_ui.disableUpscaledDirectTextures,
m_dialog->hasGameTrait(GameDatabase::Trait::DisableUpscaledDirectTextures));
// PGXP Tab
@ -461,6 +465,10 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
dialog->registerWidgetHelp(m_ui.scaledInterlacing, tr("Scaled Interlacing"), tr("Checked"),
tr("Scales line skipping in interlaced rendering to the internal resolution. This makes "
"the combing less obvious at higher resolutions. Usually safe to enable."));
dialog->registerWidgetHelp(
m_ui.disableUpscaledDirectTextures, tr("Disable Upscaled Direct Textures"), tr("Unchecked"),
tr("Samples 16-bit direct-color textures at native resolution when upscaling. This can fix filtering of "
"FMVs/backgrounds in some games, but may reduce the quality of render-to-texture effects."));
dialog->registerWidgetHelp(
m_ui.useSoftwareRendererForReadbacks, tr("Software Renderer Readbacks"), tr("Unchecked"),
tr("Runs the software renderer in parallel for VRAM readbacks. On some systems, this may result in greater "
@ -1022,6 +1030,8 @@ void GraphicsSettingsWidget::updateResolutionDependentOptions()
m_ui.forceRoundedTexcoords->setEnabled(
is_hardware && scale != 1 && texture_filtering == GPUTextureFilter::Nearest &&
!m_dialog->hasGameTrait(GameDatabase::Trait::ForceRoundUpscaledTextureCoordinates));
m_ui.disableUpscaledDirectTextures->setEnabled(
is_hardware && scale != 1 && !m_dialog->hasGameTrait(GameDatabase::Trait::DisableUpscaledDirectTextures));
m_ui.resolutionScaleWarningIcon->setVisible(scale != 1 && !pgxp_enabled);
}

@ -607,6 +607,13 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="disableUpscaledDirectTextures">
<property name="text">
<string>Disable Upscaled Direct Textures</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>

Loading…
Cancel
Save