GPU: Add option to disable PGXP on 2D polygons

This commit is contained in:
Stenzek 2024-07-09 20:30:30 +10:00
parent f0e2d1a9fa
commit de27e5de92
No known key found for this signature in database
8 changed files with 89 additions and 26 deletions

View file

@ -4165,7 +4165,8 @@ void FullscreenUI::DrawDisplaySettingsPage()
bsi->GetOptionalSmallStringValue("GPU", "Adapter", game_settings ? std::nullopt : std::optional<const char*>("")); bsi->GetOptionalSmallStringValue("GPU", "Adapter", game_settings ? std::nullopt : std::optional<const char*>(""));
if (MenuButtonWithValue(FSUI_CSTR("GPU Adapter"), FSUI_CSTR("Selects the GPU to use for rendering."), if (MenuButtonWithValue(FSUI_CSTR("GPU Adapter"), FSUI_CSTR("Selects the GPU to use for rendering."),
current_adapter.has_value() ? (current_adapter->empty() ? FSUI_CSTR("Default") : current_adapter->c_str()) : current_adapter.has_value() ?
(current_adapter->empty() ? FSUI_CSTR("Default") : current_adapter->c_str()) :
FSUI_CSTR("Use Global Setting"))) FSUI_CSTR("Use Global Setting")))
{ {
ImGuiFullscreen::ChoiceDialogOptions options; ImGuiFullscreen::ChoiceDialogOptions options;
@ -4203,8 +4204,8 @@ void FullscreenUI::DrawDisplaySettingsPage()
OpenChoiceDialog(FSUI_ICONSTR(ICON_FA_TV, "GPU Adapter"), false, std::move(options), std::move(callback)); OpenChoiceDialog(FSUI_ICONSTR(ICON_FA_TV, "GPU Adapter"), false, std::move(options), std::move(callback));
} }
std::optional<SmallString> strvalue = bsi->GetOptionalSmallStringValue("GPU", "FullscreenMode", std::optional<SmallString> strvalue = bsi->GetOptionalSmallStringValue(
game_settings ? std::nullopt : std::optional<const char*>("")); "GPU", "FullscreenMode", game_settings ? std::nullopt : std::optional<const char*>(""));
if (MenuButtonWithValue( if (MenuButtonWithValue(
FSUI_CSTR("Fullscreen Resolution"), FSUI_CSTR("Selects the resolution to use in fullscreen modes."), FSUI_CSTR("Fullscreen Resolution"), FSUI_CSTR("Selects the resolution to use in fullscreen modes."),
@ -5152,6 +5153,10 @@ void FullscreenUI::DrawAdvancedSettingsPage()
DrawToggleSetting(bsi, FSUI_CSTR("Enable PGXP Vertex Cache"), DrawToggleSetting(bsi, FSUI_CSTR("Enable PGXP Vertex Cache"),
FSUI_CSTR("Uses screen positions to resolve PGXP data. May improve visuals in some games."), "GPU", FSUI_CSTR("Uses screen positions to resolve PGXP data. May improve visuals in some games."), "GPU",
"PGXPVertexCache", pgxp_enabled); "PGXPVertexCache", pgxp_enabled);
DrawToggleSetting(bsi, FSUI_CSTR("Disable PGXP on 2D Polygons"),
FSUI_CSTR("Uses native resolution coordinates for 2D polygons, instead of precise coordinates. Can "
"fix misaligned UI in some games, but otherwise should be left disabled."),
"GPU", "PGXPDisableOn2DPolygons", false, pgxp_enabled);
DrawFloatRangeSetting( DrawFloatRangeSetting(
bsi, FSUI_CSTR("PGXP Geometry Tolerance"), bsi, FSUI_CSTR("PGXP Geometry Tolerance"),
FSUI_CSTR("Sets a threshold for discarding precise values when exceeded. May help with glitches in some games."), FSUI_CSTR("Sets a threshold for discarding precise values when exceeded. May help with glitches in some games."),
@ -7354,6 +7359,7 @@ TRANSLATE_NOOP("FullscreenUI", "Device Settings");
TRANSLATE_NOOP("FullscreenUI", "Disable All Enhancements"); TRANSLATE_NOOP("FullscreenUI", "Disable All Enhancements");
TRANSLATE_NOOP("FullscreenUI", "Disable Interlacing"); TRANSLATE_NOOP("FullscreenUI", "Disable Interlacing");
TRANSLATE_NOOP("FullscreenUI", "Disable Mailbox Presentation"); TRANSLATE_NOOP("FullscreenUI", "Disable Mailbox Presentation");
TRANSLATE_NOOP("FullscreenUI", "Disable PGXP on 2D Polygons");
TRANSLATE_NOOP("FullscreenUI", "Disable Subdirectory Scanning"); TRANSLATE_NOOP("FullscreenUI", "Disable Subdirectory Scanning");
TRANSLATE_NOOP("FullscreenUI", "Disabled"); TRANSLATE_NOOP("FullscreenUI", "Disabled");
TRANSLATE_NOOP("FullscreenUI", "Disables dithering and uses the full 8 bits per channel of color information."); TRANSLATE_NOOP("FullscreenUI", "Disables dithering and uses the full 8 bits per channel of color information.");
@ -7793,6 +7799,7 @@ TRANSLATE_NOOP("FullscreenUI", "Uses a blit presentation model instead of flippi
TRANSLATE_NOOP("FullscreenUI", "Uses a light coloured theme instead of the default dark theme."); TRANSLATE_NOOP("FullscreenUI", "Uses a light coloured theme instead of the default dark theme.");
TRANSLATE_NOOP("FullscreenUI", "Uses a second thread for drawing graphics. Speed boost, and safe to use."); TRANSLATE_NOOP("FullscreenUI", "Uses a second thread for drawing graphics. Speed boost, and safe to use.");
TRANSLATE_NOOP("FullscreenUI", "Uses game-specific settings for controllers for this game."); TRANSLATE_NOOP("FullscreenUI", "Uses game-specific settings for controllers for this game.");
TRANSLATE_NOOP("FullscreenUI", "Uses native resolution coordinates for 2D polygons, instead of precise coordinates. Can fix misaligned UI in some games, but otherwise should be left disabled.");
TRANSLATE_NOOP("FullscreenUI", "Uses perspective-correct interpolation for colors, which can improve visuals in some games."); TRANSLATE_NOOP("FullscreenUI", "Uses perspective-correct interpolation for colors, which can improve visuals in some games.");
TRANSLATE_NOOP("FullscreenUI", "Uses perspective-correct interpolation for texture coordinates, straightening out warped textures."); TRANSLATE_NOOP("FullscreenUI", "Uses perspective-correct interpolation for texture coordinates, straightening out warped textures.");
TRANSLATE_NOOP("FullscreenUI", "Uses screen positions to resolve PGXP data. May improve visuals in some games."); TRANSLATE_NOOP("FullscreenUI", "Uses screen positions to resolve PGXP data. May improve visuals in some games.");

View file

@ -34,7 +34,7 @@ namespace GameDatabase {
enum : u32 enum : u32
{ {
GAME_DATABASE_CACHE_SIGNATURE = 0x45434C48, GAME_DATABASE_CACHE_SIGNATURE = 0x45434C48,
GAME_DATABASE_CACHE_VERSION = 9, GAME_DATABASE_CACHE_VERSION = 10,
}; };
static Entry* GetMutableEntry(std::string_view serial); static Entry* GetMutableEntry(std::string_view serial);
@ -77,6 +77,7 @@ static constexpr const std::array<const char*, static_cast<u32>(GameDatabase::Tr
"DisablePGXPColorCorrection", "DisablePGXPColorCorrection",
"DisablePGXPDepthBuffer", "DisablePGXPDepthBuffer",
"DisablePGXPPreserveProjFP", "DisablePGXPPreserveProjFP",
"DisablePGXPOn2DPolygons",
"ForcePGXPVertexCache", "ForcePGXPVertexCache",
"ForcePGXPCPUMode", "ForcePGXPCPUMode",
"ForceRecompilerMemoryExceptions", "ForceRecompilerMemoryExceptions",
@ -103,6 +104,7 @@ static constexpr const std::array<const char*, static_cast<u32>(GameDatabase::Tr
TRANSLATE_NOOP("GameDatabase", "Disable PGXP Color Correction"), TRANSLATE_NOOP("GameDatabase", "Disable PGXP Color Correction"),
TRANSLATE_NOOP("GameDatabase", "Disable PGXP Depth Buffer"), TRANSLATE_NOOP("GameDatabase", "Disable PGXP Depth Buffer"),
TRANSLATE_NOOP("GameDatabase", "Disable PGXP Preserve Projection Floating Point"), TRANSLATE_NOOP("GameDatabase", "Disable PGXP Preserve Projection Floating Point"),
TRANSLATE_NOOP("GameDatabase", "Disable PGXP on 2D Polygons"),
TRANSLATE_NOOP("GameDatabase", "Force PGXP Vertex Cache"), TRANSLATE_NOOP("GameDatabase", "Force PGXP Vertex Cache"),
TRANSLATE_NOOP("GameDatabase", "Force PGXP CPU Mode"), TRANSLATE_NOOP("GameDatabase", "Force PGXP CPU Mode"),
TRANSLATE_NOOP("GameDatabase", "Force Recompiler Memory Exceptions"), TRANSLATE_NOOP("GameDatabase", "Force Recompiler Memory Exceptions"),
@ -600,7 +602,7 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
osd_duration); osd_duration);
} }
settings.gpu_pgxp_vertex_cache = true; settings.gpu_pgxp_vertex_cache = settings.gpu_pgxp_enable;
} }
else if (settings.gpu_pgxp_enable && settings.gpu_pgxp_vertex_cache) else if (settings.gpu_pgxp_enable && settings.gpu_pgxp_vertex_cache)
{ {
@ -629,7 +631,7 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
#endif #endif
} }
settings.gpu_pgxp_cpu = true; settings.gpu_pgxp_cpu = settings.gpu_pgxp_enable;
} }
else if (settings.UsingPGXPCPUMode()) else if (settings.UsingPGXPCPUMode())
{ {
@ -652,6 +654,17 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
settings.gpu_pgxp_depth_buffer = false; settings.gpu_pgxp_depth_buffer = false;
} }
if (HasTrait(Trait::DisablePGXPOn2DPolygons))
{
if (display_osd_messages && settings.gpu_pgxp_enable && !settings.gpu_pgxp_disable_2d)
{
Host::AddIconOSDMessage("gamedb_disable_pgxp_2d", ICON_FA_MICROCHIP,
TRANSLATE_STR("OSDMessage", "PGXP disabled on 2D polygons by compatibility settings."),
osd_duration);
}
g_settings.gpu_pgxp_disable_2d = true;
}
if (HasTrait(Trait::ForceRecompilerMemoryExceptions)) if (HasTrait(Trait::ForceRecompilerMemoryExceptions))
{ {
WARNING_LOG("Memory exceptions for recompiler forced by compatibility settings."); WARNING_LOG("Memory exceptions for recompiler forced by compatibility settings.");

View file

@ -45,6 +45,7 @@ enum class Trait : u32
DisablePGXPColorCorrection, DisablePGXPColorCorrection,
DisablePGXPDepthBuffer, DisablePGXPDepthBuffer,
DisablePGXPPreserveProjFP, DisablePGXPPreserveProjFP,
DisablePGXPOn2DPolygons,
ForcePGXPVertexCache, ForcePGXPVertexCache,
ForcePGXPCPUMode, ForcePGXPCPUMode,
ForceRecompilerMemoryExceptions, ForceRecompilerMemoryExceptions,

View file

@ -2190,9 +2190,23 @@ void GPU_HW::LoadVertices()
if (!valid_w) if (!valid_w)
{ {
SetBatchDepthBuffer(false); SetBatchDepthBuffer(false);
if (g_settings.gpu_pgxp_disable_2d)
{
// NOTE: This reads uninitialized data, but it's okay, it doesn't get used.
for (size_t i = 0; i < vertices.size(); i++)
{
BatchVertex& v = vertices[i];
v.x = static_cast<float>(native_vertex_positions[i].x);
v.y = static_cast<float>(native_vertex_positions[i].y);
v.w = 1.0f;
}
}
else
{
for (BatchVertex& v : vertices) for (BatchVertex& v : vertices)
v.w = 1.0f; v.w = 1.0f;
} }
}
else if (m_pgxp_depth_buffer) else if (m_pgxp_depth_buffer)
{ {
SetBatchDepthBuffer(true); SetBatchDepthBuffer(true);

View file

@ -203,7 +203,8 @@ void Settings::Load(SettingsInterface& si)
si.GetStringValue("GPU", "TextureFilter", GetTextureFilterName(DEFAULT_GPU_TEXTURE_FILTER)).c_str()) si.GetStringValue("GPU", "TextureFilter", GetTextureFilterName(DEFAULT_GPU_TEXTURE_FILTER)).c_str())
.value_or(DEFAULT_GPU_TEXTURE_FILTER); .value_or(DEFAULT_GPU_TEXTURE_FILTER);
gpu_sprite_texture_filter = gpu_sprite_texture_filter =
ParseTextureFilterName(si.GetStringValue("GPU", "SpriteTextureFilter", GetTextureFilterName(gpu_texture_filter)).c_str()) ParseTextureFilterName(
si.GetStringValue("GPU", "SpriteTextureFilter", GetTextureFilterName(gpu_texture_filter)).c_str())
.value_or(gpu_texture_filter); .value_or(gpu_texture_filter);
gpu_line_detect_mode = gpu_line_detect_mode =
ParseLineDetectModeName( ParseLineDetectModeName(
@ -231,6 +232,7 @@ void Settings::Load(SettingsInterface& si)
gpu_pgxp_preserve_proj_fp = si.GetBoolValue("GPU", "PGXPPreserveProjFP", false); gpu_pgxp_preserve_proj_fp = si.GetBoolValue("GPU", "PGXPPreserveProjFP", false);
gpu_pgxp_tolerance = si.GetFloatValue("GPU", "PGXPTolerance", -1.0f); gpu_pgxp_tolerance = si.GetFloatValue("GPU", "PGXPTolerance", -1.0f);
gpu_pgxp_depth_buffer = si.GetBoolValue("GPU", "PGXPDepthBuffer", false); gpu_pgxp_depth_buffer = si.GetBoolValue("GPU", "PGXPDepthBuffer", false);
gpu_pgxp_disable_2d = si.GetBoolValue("GPU", "PGXPDisableOn2DPolygons", false);
SetPGXPDepthClearThreshold(si.GetFloatValue("GPU", "PGXPDepthClearThreshold", DEFAULT_GPU_PGXP_DEPTH_THRESHOLD)); SetPGXPDepthClearThreshold(si.GetFloatValue("GPU", "PGXPDepthClearThreshold", DEFAULT_GPU_PGXP_DEPTH_THRESHOLD));
display_deinterlacing_mode = display_deinterlacing_mode =
@ -521,6 +523,7 @@ void Settings::Save(SettingsInterface& si, bool ignore_base) const
si.SetBoolValue("GPU", "PGXPPreserveProjFP", gpu_pgxp_preserve_proj_fp); si.SetBoolValue("GPU", "PGXPPreserveProjFP", gpu_pgxp_preserve_proj_fp);
si.SetFloatValue("GPU", "PGXPTolerance", gpu_pgxp_tolerance); si.SetFloatValue("GPU", "PGXPTolerance", gpu_pgxp_tolerance);
si.SetBoolValue("GPU", "PGXPDepthBuffer", gpu_pgxp_depth_buffer); si.SetBoolValue("GPU", "PGXPDepthBuffer", gpu_pgxp_depth_buffer);
si.SetBoolValue("GPU", "PGXPDisableOn2DPolygons", gpu_pgxp_disable_2d);
si.SetFloatValue("GPU", "PGXPDepthClearThreshold", GetPGXPDepthClearThreshold()); si.SetFloatValue("GPU", "PGXPDepthClearThreshold", GetPGXPDepthClearThreshold());
si.SetStringValue("Display", "DeinterlacingMode", GetDisplayDeinterlacingModeName(display_deinterlacing_mode)); si.SetStringValue("Display", "DeinterlacingMode", GetDisplayDeinterlacingModeName(display_deinterlacing_mode));
@ -749,6 +752,17 @@ void Settings::FixIncompatibleSettings(bool display_osd_messages)
g_settings.gpu_pgxp_enable = false; g_settings.gpu_pgxp_enable = false;
} }
} }
else
{
g_settings.gpu_pgxp_culling = false;
g_settings.gpu_pgxp_texture_correction = false;
g_settings.gpu_pgxp_color_correction = false;
g_settings.gpu_pgxp_vertex_cache = false;
g_settings.gpu_pgxp_cpu = false;
g_settings.gpu_pgxp_preserve_proj_fp = false;
g_settings.gpu_pgxp_depth_buffer = false;
g_settings.gpu_pgxp_disable_2d = false;
}
#ifndef ENABLE_MMAP_FASTMEM #ifndef ENABLE_MMAP_FASTMEM
if (g_settings.cpu_fastmem_mode == CPUFastmemMode::MMap) if (g_settings.cpu_fastmem_mode == CPUFastmemMode::MMap)

View file

@ -135,6 +135,7 @@ struct Settings
bool gpu_pgxp_cpu : 1 = false; bool gpu_pgxp_cpu : 1 = false;
bool gpu_pgxp_preserve_proj_fp : 1 = false; bool gpu_pgxp_preserve_proj_fp : 1 = false;
bool gpu_pgxp_depth_buffer : 1 = false; bool gpu_pgxp_depth_buffer : 1 = false;
bool gpu_pgxp_disable_2d : 1 = false;
DisplayDeinterlacingMode display_deinterlacing_mode = DEFAULT_DISPLAY_DEINTERLACING_MODE; DisplayDeinterlacingMode display_deinterlacing_mode = DEFAULT_DISPLAY_DEINTERLACING_MODE;
DisplayCropMode display_crop_mode = DEFAULT_DISPLAY_CROP_MODE; DisplayCropMode display_crop_mode = DEFAULT_DISPLAY_CROP_MODE;
DisplayAspectRatio display_aspect_ratio = DEFAULT_DISPLAY_ASPECT_RATIO; DisplayAspectRatio display_aspect_ratio = DEFAULT_DISPLAY_ASPECT_RATIO;

View file

@ -133,6 +133,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpPreserveProjPrecision, "GPU", "PGXPPreserveProjFP", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpPreserveProjPrecision, "GPU", "PGXPPreserveProjFP", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpCPU, "GPU", "PGXPCPU", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpCPU, "GPU", "PGXPCPU", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpVertexCache, "GPU", "PGXPVertexCache", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpVertexCache, "GPU", "PGXPVertexCache", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpDisableOn2DPolygons, "GPU", "PGXPDisableOn2DPolygons",
false);
connect(m_ui.pgxpTextureCorrection, &QCheckBox::checkStateChanged, this, connect(m_ui.pgxpTextureCorrection, &QCheckBox::checkStateChanged, this,
&GraphicsSettingsWidget::updatePGXPSettingsEnabled); &GraphicsSettingsWidget::updatePGXPSettingsEnabled);
@ -388,6 +390,10 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
m_ui.pgxpVertexCache, tr("Vertex Cache"), tr("Unchecked"), m_ui.pgxpVertexCache, tr("Vertex Cache"), tr("Unchecked"),
tr("Uses screen-space vertex positions to obtain precise positions, instead of tracking memory accesses. Can " tr("Uses screen-space vertex positions to obtain precise positions, instead of tracking memory accesses. Can "
"provide PGXP compatibility for some games, but <strong>generally provides no benefit.</strong>")); "provide PGXP compatibility for some games, but <strong>generally provides no benefit.</strong>"));
dialog->registerWidgetHelp(m_ui.pgxpDisableOn2DPolygons, tr("Disable on 2D Polygons"), tr("Unchecked"),
tr("Uses native resolution coordinates for 2D polygons, instead of precise coordinates. "
"Can fix misaligned UI in some games, but otherwise should be left disabled. The game "
"database will enable this automatically when needed."));
// OSD Tab // OSD Tab

View file

@ -525,13 +525,6 @@
</item> </item>
<item row="2" column="0" colspan="2"> <item row="2" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="pgxpTextureCorrection">
<property name="text">
<string>Perspective Correct Textures</string>
</property>
</widget>
</item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QCheckBox" name="pgxpColorCorrection"> <widget class="QCheckBox" name="pgxpColorCorrection">
<property name="text"> <property name="text">
@ -539,17 +532,17 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="2" column="1">
<widget class="QCheckBox" name="pgxpCulling"> <widget class="QCheckBox" name="pgxpVertexCache">
<property name="text"> <property name="text">
<string>Culling Correction</string> <string>Vertex Cache</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="0" column="0">
<widget class="QCheckBox" name="pgxpPreserveProjPrecision"> <widget class="QCheckBox" name="pgxpTextureCorrection">
<property name="text"> <property name="text">
<string>Preserve Projection Precision</string> <string>Perspective Correct Textures</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -560,10 +553,24 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="1" column="1">
<widget class="QCheckBox" name="pgxpVertexCache"> <widget class="QCheckBox" name="pgxpPreserveProjPrecision">
<property name="text"> <property name="text">
<string>Vertex Cache</string> <string>Preserve Projection Precision</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="pgxpCulling">
<property name="text">
<string>Culling Correction</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="pgxpDisableOn2DPolygons">
<property name="text">
<string>Disable on 2D Polygons</string>
</property> </property>
</widget> </widget>
</item> </item>