GPU: Make perspective-correct color interpolation toggleable

This commit is contained in:
Connor McLaughlin 2022-10-03 20:03:30 +10:00
parent 6af5a2486c
commit 971bba07d6
20 changed files with 145 additions and 80 deletions

View File

@ -109,6 +109,21 @@ DisableUpscaling = true
DisablePGXP = true DisablePGXP = true
# SCUS-94244 (Crash Bandicoot - Warped (USA))
[SCUS-94244]
DisablePGXPColorCorrection = true
# SCES-01420 (Crash Bandicoot 3 - Warped (Europe) (En,Fr,De,Es,It))
[SCES-01420]
DisablePGXPColorCorrection = true
# SCPS-10073 (Crash Bandicoot 3 - Buttobi! Sekai Isshuu (Japan))
[SCPS-10073]
DisablePGXPColorCorrection = true
# Pop'n Music 6 (Japan) (SLPM-87089) # Pop'n Music 6 (Japan) (SLPM-87089)
[SLPM-87089] [SLPM-87089]
ForceInterlacing = true ForceInterlacing = true

View File

@ -28,7 +28,7 @@ namespace GameDatabase {
enum : u32 enum : u32
{ {
GAME_DATABASE_CACHE_SIGNATURE = 0x45434C48, GAME_DATABASE_CACHE_SIGNATURE = 0x45434C48,
GAME_DATABASE_CACHE_VERSION = 1 GAME_DATABASE_CACHE_VERSION = 2,
}; };
static Entry* GetMutableEntry(const std::string_view& serial); static Entry* GetMutableEntry(const std::string_view& serial);
@ -56,7 +56,8 @@ std::array<std::pair<const char*, const char*>, static_cast<u32>(GameDatabase::T
{"DisableWidescreen", TRANSLATABLE("GameSettingsTrait", "Disable Widescreen")}, {"DisableWidescreen", TRANSLATABLE("GameSettingsTrait", "Disable Widescreen")},
{"DisablePGXP", TRANSLATABLE("GameSettingsTrait", "Disable PGXP")}, {"DisablePGXP", TRANSLATABLE("GameSettingsTrait", "Disable PGXP")},
{"DisablePGXPCulling", TRANSLATABLE("GameSettingsTrait", "Disable PGXP Culling")}, {"DisablePGXPCulling", TRANSLATABLE("GameSettingsTrait", "Disable PGXP Culling")},
{"DisablePGXPTextureCorrection", TRANSLATABLE("GameSettingsTrait", "Disable PGXP Texture Correction")}, {"DisablePGXPTextureCorrection", TRANSLATABLE("GameSettingsTrait", "Disable PGXP Perspective Correct Textures")},
{"DisablePGXPColorCorrection", TRANSLATABLE("GameSettingsTrait", "Disable PGXP Perspective Correct Colors")},
{"DisablePGXPDepthBuffer", TRANSLATABLE("GameSettingsTrait", "Disable PGXP Depth Buffer")}, {"DisablePGXPDepthBuffer", TRANSLATABLE("GameSettingsTrait", "Disable PGXP Depth Buffer")},
{"ForcePGXPVertexCache", TRANSLATABLE("GameSettingsTrait", "Force PGXP Vertex Cache")}, {"ForcePGXPVertexCache", TRANSLATABLE("GameSettingsTrait", "Force PGXP Vertex Cache")},
{"ForcePGXPCPUMode", TRANSLATABLE("GameSettingsTrait", "Force PGXP CPU Mode")}, {"ForcePGXPCPUMode", TRANSLATABLE("GameSettingsTrait", "Force PGXP CPU Mode")},
@ -364,12 +365,25 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes
{ {
Host::AddKeyedOSDMessage( Host::AddKeyedOSDMessage(
"gamedb_disable_pgxp_texture", "gamedb_disable_pgxp_texture",
Host::TranslateStdString("OSDMessage", "PGXP texture correction disabled by game settings."), osd_duration); Host::TranslateStdString("OSDMessage", "PGXP perspective corrected textures disabled by game settings."), osd_duration);
} }
settings.gpu_pgxp_texture_correction = false; settings.gpu_pgxp_texture_correction = false;
} }
if (HasTrait(Trait::DisablePGXPColorCorrection))
{
if (display_osd_messages && settings.gpu_pgxp_enable && settings.gpu_pgxp_texture_correction &&
settings.gpu_pgxp_color_correction)
{
Host::AddKeyedOSDMessage(
"gamedb_disable_pgxp_texture",
Host::TranslateStdString("OSDMessage", "PGXP perspective corrected colors disabled by game settings."), osd_duration);
}
settings.gpu_pgxp_color_correction = false;
}
if (HasTrait(Trait::ForcePGXPVertexCache)) if (HasTrait(Trait::ForcePGXPVertexCache))
{ {
if (display_osd_messages && settings.gpu_pgxp_enable && !settings.gpu_pgxp_vertex_cache) if (display_osd_messages && settings.gpu_pgxp_enable && !settings.gpu_pgxp_vertex_cache)

View File

@ -37,6 +37,7 @@ enum class Trait : u32
DisablePGXP, DisablePGXP,
DisablePGXPCulling, DisablePGXPCulling,
DisablePGXPTextureCorrection, DisablePGXPTextureCorrection,
DisablePGXPColorCorrection,
DisablePGXPDepthBuffer, DisablePGXPDepthBuffer,
ForcePGXPVertexCache, ForcePGXPVertexCache,
ForcePGXPCPUMode, ForcePGXPCPUMode,

View File

@ -30,6 +30,11 @@ ALWAYS_INLINE static bool ShouldUseUVLimits()
return g_settings.gpu_pgxp_enable || g_settings.gpu_texture_filter != GPUTextureFilter::Nearest; return g_settings.gpu_pgxp_enable || g_settings.gpu_texture_filter != GPUTextureFilter::Nearest;
} }
ALWAYS_INLINE static bool ShouldDisableColorPerspective()
{
return g_settings.gpu_pgxp_enable && g_settings.gpu_pgxp_texture_correction && !g_settings.gpu_pgxp_color_correction;
}
GPU_HW::GPU_HW() : GPU() GPU_HW::GPU_HW() : GPU()
{ {
m_vram_ptr = m_vram_shadow.data(); m_vram_ptr = m_vram_shadow.data();
@ -64,6 +69,7 @@ bool GPU_HW::Initialize()
m_using_uv_limits = ShouldUseUVLimits(); m_using_uv_limits = ShouldUseUVLimits();
m_chroma_smoothing = g_settings.gpu_24bit_chroma_smoothing; m_chroma_smoothing = g_settings.gpu_24bit_chroma_smoothing;
m_downsample_mode = GetDownsampleMode(m_resolution_scale); m_downsample_mode = GetDownsampleMode(m_resolution_scale);
m_disable_color_perspective = ShouldDisableColorPerspective();
if (m_multisamples != g_settings.gpu_multisamples) if (m_multisamples != g_settings.gpu_multisamples)
{ {
@ -140,6 +146,7 @@ void GPU_HW::UpdateHWSettings(bool* framebuffer_changed, bool* shaders_changed)
const bool per_sample_shading = g_settings.gpu_per_sample_shading && m_supports_per_sample_shading; const bool per_sample_shading = g_settings.gpu_per_sample_shading && m_supports_per_sample_shading;
const GPUDownsampleMode downsample_mode = GetDownsampleMode(resolution_scale); const GPUDownsampleMode downsample_mode = GetDownsampleMode(resolution_scale);
const bool use_uv_limits = ShouldUseUVLimits(); const bool use_uv_limits = ShouldUseUVLimits();
const bool disable_color_perspective = ShouldDisableColorPerspective();
*framebuffer_changed = *framebuffer_changed =
(m_resolution_scale != resolution_scale || m_multisamples != multisamples || m_downsample_mode != downsample_mode); (m_resolution_scale != resolution_scale || m_multisamples != multisamples || m_downsample_mode != downsample_mode);
@ -148,7 +155,8 @@ void GPU_HW::UpdateHWSettings(bool* framebuffer_changed, bool* shaders_changed)
m_true_color != g_settings.gpu_true_color || m_per_sample_shading != per_sample_shading || m_true_color != g_settings.gpu_true_color || m_per_sample_shading != per_sample_shading ||
m_scaled_dithering != g_settings.gpu_scaled_dithering || m_texture_filtering != g_settings.gpu_texture_filter || m_scaled_dithering != g_settings.gpu_scaled_dithering || m_texture_filtering != g_settings.gpu_texture_filter ||
m_using_uv_limits != use_uv_limits || m_chroma_smoothing != g_settings.gpu_24bit_chroma_smoothing || m_using_uv_limits != use_uv_limits || m_chroma_smoothing != g_settings.gpu_24bit_chroma_smoothing ||
m_downsample_mode != downsample_mode || m_pgxp_depth_buffer != g_settings.UsingPGXPDepthBuffer()); m_downsample_mode != downsample_mode || m_pgxp_depth_buffer != g_settings.UsingPGXPDepthBuffer() ||
m_disable_color_perspective != disable_color_perspective);
if (m_resolution_scale != resolution_scale) if (m_resolution_scale != resolution_scale)
{ {
@ -184,6 +192,7 @@ void GPU_HW::UpdateHWSettings(bool* framebuffer_changed, bool* shaders_changed)
m_using_uv_limits = use_uv_limits; m_using_uv_limits = use_uv_limits;
m_chroma_smoothing = g_settings.gpu_24bit_chroma_smoothing; m_chroma_smoothing = g_settings.gpu_24bit_chroma_smoothing;
m_downsample_mode = downsample_mode; m_downsample_mode = downsample_mode;
m_disable_color_perspective = disable_color_perspective;
if (!m_supports_dual_source_blend && TextureFilterRequiresDualSourceBlend(m_texture_filtering)) if (!m_supports_dual_source_blend && TextureFilterRequiresDualSourceBlend(m_texture_filtering))
m_texture_filtering = GPUTextureFilter::Nearest; m_texture_filtering = GPUTextureFilter::Nearest;

View File

@ -377,6 +377,7 @@ protected:
BitField<u8, bool, 3, 1> m_per_sample_shading; BitField<u8, bool, 3, 1> m_per_sample_shading;
BitField<u8, bool, 4, 1> m_scaled_dithering; BitField<u8, bool, 4, 1> m_scaled_dithering;
BitField<u8, bool, 5, 1> m_chroma_smoothing; BitField<u8, bool, 5, 1> m_chroma_smoothing;
BitField<u8, bool, 6, 1> m_disable_color_perspective;
u8 bits = 0; u8 bits = 0;
}; };

View File

@ -506,7 +506,7 @@ bool GPU_HW_D3D11::CompileShaders()
GPU_HW_ShaderGen shadergen(g_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading, GPU_HW_ShaderGen shadergen(g_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading,
m_true_color, m_scaled_dithering, m_texture_filtering, m_using_uv_limits, m_true_color, m_scaled_dithering, m_texture_filtering, m_using_uv_limits,
m_pgxp_depth_buffer, m_supports_dual_source_blend); m_pgxp_depth_buffer, m_disable_color_perspective, m_supports_dual_source_blend);
ShaderCompileProgressTracker progress("Compiling Shaders", ShaderCompileProgressTracker progress("Compiling Shaders",
1 + 1 + 2 + (4 * 9 * 2 * 2) + 1 + (2 * 2) + 4 + (2 * 3) + 1); 1 + 1 + 2 + (4 * 9 * 2 * 2) + 1 + (2 * 2) + 4 + (2 * 3) + 1);

View File

@ -416,7 +416,7 @@ bool GPU_HW_D3D12::CompilePipelines()
GPU_HW_ShaderGen shadergen(g_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading, GPU_HW_ShaderGen shadergen(g_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading,
m_true_color, m_scaled_dithering, m_texture_filtering, m_using_uv_limits, m_true_color, m_scaled_dithering, m_texture_filtering, m_using_uv_limits,
m_pgxp_depth_buffer, m_supports_dual_source_blend); m_pgxp_depth_buffer, m_disable_color_perspective, m_supports_dual_source_blend);
ShaderCompileProgressTracker progress("Compiling Pipelines", 2 + (4 * 9 * 2 * 2) + (2 * 4 * 5 * 9 * 2 * 2) + 1 + ShaderCompileProgressTracker progress("Compiling Pipelines", 2 + (4 * 9 * 2 * 2) + (2 * 4 * 5 * 9 * 2 * 2) + 1 +
(2 * 2) + 2 + 2 + 1 + 1 + (2 * 3) + 1); (2 * 2) + 2 + 2 + 1 + 1 + (2 * 3) + 1);

View File

@ -518,7 +518,7 @@ bool GPU_HW_OpenGL::CompilePrograms()
const bool use_binding_layout = GPU_HW_ShaderGen::UseGLSLBindingLayout(); const bool use_binding_layout = GPU_HW_ShaderGen::UseGLSLBindingLayout();
GPU_HW_ShaderGen shadergen(g_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading, GPU_HW_ShaderGen shadergen(g_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading,
m_true_color, m_scaled_dithering, m_texture_filtering, m_using_uv_limits, m_true_color, m_scaled_dithering, m_texture_filtering, m_using_uv_limits,
m_pgxp_depth_buffer, m_supports_dual_source_blend); m_pgxp_depth_buffer, m_disable_color_perspective, m_supports_dual_source_blend);
ShaderCompileProgressTracker progress("Compiling Programs", (4 * 9 * 2 * 2) + (2 * 3) + (2 * 2) + 1 + 1 + 1 + 1 + 1); ShaderCompileProgressTracker progress("Compiling Programs", (4 * 9 * 2 * 2) + (2 * 3) + (2 * 2) + 1 + 1 + 1 + 1 + 1);

View File

@ -5,11 +5,11 @@
GPU_HW_ShaderGen::GPU_HW_ShaderGen(RenderAPI render_api, u32 resolution_scale, u32 multisamples, GPU_HW_ShaderGen::GPU_HW_ShaderGen(RenderAPI render_api, u32 resolution_scale, u32 multisamples,
bool per_sample_shading, bool true_color, bool scaled_dithering, bool per_sample_shading, bool true_color, bool scaled_dithering,
GPUTextureFilter texture_filtering, bool uv_limits, bool pgxp_depth, GPUTextureFilter texture_filtering, bool uv_limits, bool pgxp_depth,
bool supports_dual_source_blend) bool disable_color_perspective, bool supports_dual_source_blend)
: ShaderGen(render_api, supports_dual_source_blend), m_resolution_scale(resolution_scale), : ShaderGen(render_api, supports_dual_source_blend), m_resolution_scale(resolution_scale),
m_multisamples(multisamples), m_per_sample_shading(per_sample_shading), m_true_color(true_color), m_multisamples(multisamples), m_per_sample_shading(per_sample_shading), m_true_color(true_color),
m_scaled_dithering(scaled_dithering), m_texture_filter(texture_filtering), m_uv_limits(uv_limits), m_scaled_dithering(scaled_dithering), m_texture_filter(texture_filtering), m_uv_limits(uv_limits),
m_pgxp_depth(pgxp_depth) m_pgxp_depth(pgxp_depth), m_disable_color_perspective(disable_color_perspective)
{ {
} }
@ -109,19 +109,19 @@ std::string GPU_HW_ShaderGen::GenerateBatchVertexShader(bool textured)
DeclareVertexEntryPoint( DeclareVertexEntryPoint(
ss, {"float4 a_pos", "float4 a_col0", "uint a_texcoord", "uint a_texpage", "float4 a_uv_limits"}, 1, 1, ss, {"float4 a_pos", "float4 a_col0", "uint a_texcoord", "uint a_texpage", "float4 a_uv_limits"}, 1, 1,
{{"nointerpolation", "uint4 v_texpage"}, {"nointerpolation", "float4 v_uv_limits"}}, false, "", UsingMSAA(), {{"nointerpolation", "uint4 v_texpage"}, {"nointerpolation", "float4 v_uv_limits"}}, false, "", UsingMSAA(),
UsingPerSampleShading()); UsingPerSampleShading(), m_disable_color_perspective);
} }
else else
{ {
DeclareVertexEntryPoint(ss, {"float4 a_pos", "float4 a_col0", "uint a_texcoord", "uint a_texpage"}, 1, 1, DeclareVertexEntryPoint(ss, {"float4 a_pos", "float4 a_col0", "uint a_texcoord", "uint a_texpage"}, 1, 1,
{{"nointerpolation", "uint4 v_texpage"}}, false, "", UsingMSAA(), {{"nointerpolation", "uint4 v_texpage"}}, false, "", UsingMSAA(), UsingPerSampleShading(),
UsingPerSampleShading()); m_disable_color_perspective);
} }
} }
else else
{ {
DeclareVertexEntryPoint(ss, {"float4 a_pos", "float4 a_col0"}, 1, 0, {}, false, "", UsingMSAA(), DeclareVertexEntryPoint(ss, {"float4 a_pos", "float4 a_col0"}, 1, 0, {}, false, "", UsingMSAA(),
UsingPerSampleShading()); UsingPerSampleShading(), m_disable_color_perspective);
} }
ss << R"( ss << R"(
@ -805,18 +805,20 @@ float4 SampleFromVRAM(uint4 texpage, float2 coords)
{ {
DeclareFragmentEntryPoint(ss, 1, 1, DeclareFragmentEntryPoint(ss, 1, 1,
{{"nointerpolation", "uint4 v_texpage"}, {"nointerpolation", "float4 v_uv_limits"}}, {{"nointerpolation", "uint4 v_texpage"}, {"nointerpolation", "float4 v_uv_limits"}},
true, use_dual_source ? 2 : 1, !m_pgxp_depth, UsingMSAA(), UsingPerSampleShading()); true, use_dual_source ? 2 : 1, !m_pgxp_depth, UsingMSAA(), UsingPerSampleShading(),
false, m_disable_color_perspective);
} }
else else
{ {
DeclareFragmentEntryPoint(ss, 1, 1, {{"nointerpolation", "uint4 v_texpage"}}, true, use_dual_source ? 2 : 1, DeclareFragmentEntryPoint(ss, 1, 1, {{"nointerpolation", "uint4 v_texpage"}}, true, use_dual_source ? 2 : 1,
!m_pgxp_depth, UsingMSAA(), UsingPerSampleShading()); !m_pgxp_depth, UsingMSAA(), UsingPerSampleShading(), false,
m_disable_color_perspective);
} }
} }
else else
{ {
DeclareFragmentEntryPoint(ss, 1, 0, {}, true, use_dual_source ? 2 : 1, !m_pgxp_depth, UsingMSAA(), DeclareFragmentEntryPoint(ss, 1, 0, {}, true, use_dual_source ? 2 : 1, !m_pgxp_depth, UsingMSAA(),
UsingPerSampleShading()); UsingPerSampleShading(), false, m_disable_color_perspective);
} }
ss << R"( ss << R"(

View File

@ -7,7 +7,7 @@ class GPU_HW_ShaderGen : public ShaderGen
public: public:
GPU_HW_ShaderGen(RenderAPI render_api, u32 resolution_scale, u32 multisamples, bool per_sample_shading, GPU_HW_ShaderGen(RenderAPI render_api, u32 resolution_scale, u32 multisamples, bool per_sample_shading,
bool true_color, bool scaled_dithering, GPUTextureFilter texture_filtering, bool uv_limits, bool true_color, bool scaled_dithering, GPUTextureFilter texture_filtering, bool uv_limits,
bool pgxp_depth, bool supports_dual_source_blend); bool pgxp_depth, bool disable_color_perspective, bool supports_dual_source_blend);
~GPU_HW_ShaderGen(); ~GPU_HW_ShaderGen();
std::string GenerateBatchVertexShader(bool textured); std::string GenerateBatchVertexShader(bool textured);
@ -42,4 +42,5 @@ private:
GPUTextureFilter m_texture_filter; GPUTextureFilter m_texture_filter;
bool m_uv_limits; bool m_uv_limits;
bool m_pgxp_depth; bool m_pgxp_depth;
bool m_disable_color_perspective;
}; };

View File

@ -923,7 +923,7 @@ bool GPU_HW_Vulkan::CompilePipelines()
GPU_HW_ShaderGen shadergen(g_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading, GPU_HW_ShaderGen shadergen(g_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading,
m_true_color, m_scaled_dithering, m_texture_filtering, m_using_uv_limits, m_true_color, m_scaled_dithering, m_texture_filtering, m_using_uv_limits,
m_pgxp_depth_buffer, m_supports_dual_source_blend); m_pgxp_depth_buffer, m_disable_color_perspective, m_supports_dual_source_blend);
ShaderCompileProgressTracker progress("Compiling Pipelines", 2 + (4 * 9 * 2 * 2) + (3 * 4 * 5 * 9 * 2 * 2) + 1 + 2 + ShaderCompileProgressTracker progress("Compiling Pipelines", 2 + (4 * 9 * 2 * 2) + (3 * 4 * 5 * 9 * 2 * 2) + 1 + 2 +
(2 * 2) + 2 + 1 + 1 + (2 * 3) + 1); (2 * 2) + 2 + 1 + 1 + (2 * 3) + 1);

View File

@ -222,6 +222,7 @@ void Settings::Load(SettingsInterface& si)
gpu_pgxp_enable = si.GetBoolValue("GPU", "PGXPEnable", false); gpu_pgxp_enable = si.GetBoolValue("GPU", "PGXPEnable", false);
gpu_pgxp_culling = si.GetBoolValue("GPU", "PGXPCulling", true); gpu_pgxp_culling = si.GetBoolValue("GPU", "PGXPCulling", true);
gpu_pgxp_texture_correction = si.GetBoolValue("GPU", "PGXPTextureCorrection", true); gpu_pgxp_texture_correction = si.GetBoolValue("GPU", "PGXPTextureCorrection", true);
gpu_pgxp_color_correction = si.GetBoolValue("GPU", "PGXPColorCorrection", false);
gpu_pgxp_vertex_cache = si.GetBoolValue("GPU", "PGXPVertexCache", false); gpu_pgxp_vertex_cache = si.GetBoolValue("GPU", "PGXPVertexCache", false);
gpu_pgxp_cpu = si.GetBoolValue("GPU", "PGXPCPU", false); gpu_pgxp_cpu = si.GetBoolValue("GPU", "PGXPCPU", false);
gpu_pgxp_preserve_proj_fp = si.GetBoolValue("GPU", "PGXPPreserveProjFP", false); gpu_pgxp_preserve_proj_fp = si.GetBoolValue("GPU", "PGXPPreserveProjFP", false);
@ -437,6 +438,7 @@ void Settings::Save(SettingsInterface& si) const
si.SetBoolValue("GPU", "PGXPEnable", gpu_pgxp_enable); si.SetBoolValue("GPU", "PGXPEnable", gpu_pgxp_enable);
si.SetBoolValue("GPU", "PGXPCulling", gpu_pgxp_culling); si.SetBoolValue("GPU", "PGXPCulling", gpu_pgxp_culling);
si.SetBoolValue("GPU", "PGXPTextureCorrection", gpu_pgxp_texture_correction); si.SetBoolValue("GPU", "PGXPTextureCorrection", gpu_pgxp_texture_correction);
si.SetBoolValue("GPU", "PGXPColorCorrection", gpu_pgxp_color_correction);
si.SetBoolValue("GPU", "PGXPVertexCache", gpu_pgxp_vertex_cache); si.SetBoolValue("GPU", "PGXPVertexCache", gpu_pgxp_vertex_cache);
si.SetBoolValue("GPU", "PGXPCPU", gpu_pgxp_cpu); si.SetBoolValue("GPU", "PGXPCPU", gpu_pgxp_cpu);
si.SetBoolValue("GPU", "PGXPPreserveProjFP", gpu_pgxp_preserve_proj_fp); si.SetBoolValue("GPU", "PGXPPreserveProjFP", gpu_pgxp_preserve_proj_fp);

View File

@ -108,6 +108,7 @@ struct Settings
bool gpu_pgxp_enable = false; bool gpu_pgxp_enable = false;
bool gpu_pgxp_culling = true; bool gpu_pgxp_culling = true;
bool gpu_pgxp_texture_correction = true; bool gpu_pgxp_texture_correction = true;
bool gpu_pgxp_color_correction = false;
bool gpu_pgxp_vertex_cache = false; bool gpu_pgxp_vertex_cache = false;
bool gpu_pgxp_cpu = false; bool gpu_pgxp_cpu = false;
bool gpu_pgxp_preserve_proj_fp = false; bool gpu_pgxp_preserve_proj_fp = false;

View File

@ -11,8 +11,7 @@
Log_SetChannel(ShaderGen); Log_SetChannel(ShaderGen);
ShaderGen::ShaderGen(RenderAPI render_api, bool supports_dual_source_blend) ShaderGen::ShaderGen(RenderAPI render_api, bool supports_dual_source_blend)
: m_render_api(render_api), : m_render_api(render_api), m_glsl(render_api != RenderAPI::D3D11 && render_api != RenderAPI::D3D12),
m_glsl(render_api != RenderAPI::D3D11 && render_api != RenderAPI::D3D12),
m_supports_dual_source_blend(supports_dual_source_blend), m_use_glsl_interface_blocks(false) m_supports_dual_source_blend(supports_dual_source_blend), m_use_glsl_interface_blocks(false)
{ {
#if defined(WITH_OPENGL) || defined(WITH_VULKAN) #if defined(WITH_OPENGL) || defined(WITH_VULKAN)
@ -24,7 +23,7 @@ ShaderGen::ShaderGen(RenderAPI render_api, bool supports_dual_source_blend)
m_use_glsl_interface_blocks = (IsVulkan() || GLAD_GL_ES_VERSION_3_2 || GLAD_GL_VERSION_3_2); m_use_glsl_interface_blocks = (IsVulkan() || GLAD_GL_ES_VERSION_3_2 || GLAD_GL_VERSION_3_2);
m_use_glsl_binding_layout = (IsVulkan() || UseGLSLBindingLayout()); m_use_glsl_binding_layout = (IsVulkan() || UseGLSLBindingLayout());
if (m_render_api == RenderAPI::OpenGL) if (m_render_api == RenderAPI::OpenGL)
{ {
// SSAA with interface blocks is broken on AMD's OpenGL driver. // SSAA with interface blocks is broken on AMD's OpenGL driver.
@ -355,8 +354,8 @@ const char* ShaderGen::GetInterpolationQualifier(bool interface_block, bool cent
void ShaderGen::DeclareVertexEntryPoint( void ShaderGen::DeclareVertexEntryPoint(
std::stringstream& ss, const std::initializer_list<const char*>& attributes, u32 num_color_outputs, std::stringstream& ss, const std::initializer_list<const char*>& attributes, u32 num_color_outputs,
u32 num_texcoord_outputs, const std::initializer_list<std::pair<const char*, const char*>>& additional_outputs, u32 num_texcoord_outputs, const std::initializer_list<std::pair<const char*, const char*>>& additional_outputs,
bool declare_vertex_id /* = false */, const char* output_block_suffix /* = "" */, bool declare_vertex_id /* = false */, const char* output_block_suffix /* = "" */, bool msaa /* = false */,
bool centroid_interpolation /* = false */, bool sample_interpolation /* = false */) bool ssaa /* = false */, bool noperspective_color /* = false */)
{ {
if (m_glsl) if (m_glsl)
{ {
@ -377,7 +376,7 @@ void ShaderGen::DeclareVertexEntryPoint(
if (m_use_glsl_interface_blocks) if (m_use_glsl_interface_blocks)
{ {
const char* qualifier = GetInterpolationQualifier(true, centroid_interpolation, sample_interpolation, true); const char* qualifier = GetInterpolationQualifier(true, msaa, ssaa, true);
if (IsVulkan()) if (IsVulkan())
ss << "layout(location = 0) "; ss << "layout(location = 0) ";
@ -398,7 +397,7 @@ void ShaderGen::DeclareVertexEntryPoint(
} }
else else
{ {
const char* qualifier = GetInterpolationQualifier(false, centroid_interpolation, sample_interpolation, true); const char* qualifier = GetInterpolationQualifier(false, msaa, ssaa, true);
for (u32 i = 0; i < num_color_outputs; i++) for (u32 i = 0; i < num_color_outputs; i++)
ss << qualifier << "out float4 v_col" << i << ";\n"; ss << qualifier << "out float4 v_col" << i << ";\n";
@ -427,7 +426,7 @@ void ShaderGen::DeclareVertexEntryPoint(
} }
else else
{ {
const char* qualifier = GetInterpolationQualifier(false, centroid_interpolation, sample_interpolation, true); const char* qualifier = GetInterpolationQualifier(false, msaa, ssaa, true);
ss << "void main(\n"; ss << "void main(\n";
@ -442,7 +441,8 @@ void ShaderGen::DeclareVertexEntryPoint(
} }
for (u32 i = 0; i < num_color_outputs; i++) for (u32 i = 0; i < num_color_outputs; i++)
ss << " " << qualifier << "out float4 v_col" << i << " : COLOR" << i << ",\n"; ss << " " << qualifier << (noperspective_color ? "noperspective " : "") << "out float4 v_col" << i << " : COLOR"
<< i << ",\n";
for (u32 i = 0; i < num_texcoord_outputs; i++) for (u32 i = 0; i < num_texcoord_outputs; i++)
ss << " " << qualifier << "out float2 v_tex" << i << " : TEXCOORD" << i << ",\n"; ss << " " << qualifier << "out float2 v_tex" << i << " : TEXCOORD" << i << ",\n";
@ -463,21 +463,21 @@ void ShaderGen::DeclareFragmentEntryPoint(
std::stringstream& ss, u32 num_color_inputs, u32 num_texcoord_inputs, std::stringstream& ss, u32 num_color_inputs, u32 num_texcoord_inputs,
const std::initializer_list<std::pair<const char*, const char*>>& additional_inputs, const std::initializer_list<std::pair<const char*, const char*>>& additional_inputs,
bool declare_fragcoord /* = false */, u32 num_color_outputs /* = 1 */, bool depth_output /* = false */, bool declare_fragcoord /* = false */, u32 num_color_outputs /* = 1 */, bool depth_output /* = false */,
bool centroid_interpolation /* = false */, bool sample_interpolation /* = false */, bool msaa /* = false */, bool ssaa /* = false */, bool declare_sample_id /* = false */,
bool declare_sample_id /* = false */) bool noperspective_color /* = false */)
{ {
if (m_glsl) if (m_glsl)
{ {
if (m_use_glsl_interface_blocks) if (m_use_glsl_interface_blocks)
{ {
const char* qualifier = GetInterpolationQualifier(true, centroid_interpolation, sample_interpolation, false); const char* qualifier = GetInterpolationQualifier(true, msaa, ssaa, false);
if (IsVulkan()) if (IsVulkan())
ss << "layout(location = 0) "; ss << "layout(location = 0) ";
ss << "in VertexData {\n"; ss << "in VertexData {\n";
for (u32 i = 0; i < num_color_inputs; i++) for (u32 i = 0; i < num_color_inputs; i++)
ss << " " << qualifier << "float4 v_col" << i << ";\n"; ss << " " << qualifier << (noperspective_color ? "noperspective " : "") << "float4 v_col" << i << ";\n";
for (u32 i = 0; i < num_texcoord_inputs; i++) for (u32 i = 0; i < num_texcoord_inputs; i++)
ss << " " << qualifier << "float2 v_tex" << i << ";\n"; ss << " " << qualifier << "float2 v_tex" << i << ";\n";
@ -491,10 +491,10 @@ void ShaderGen::DeclareFragmentEntryPoint(
} }
else else
{ {
const char* qualifier = GetInterpolationQualifier(false, centroid_interpolation, sample_interpolation, false); const char* qualifier = GetInterpolationQualifier(false, msaa, ssaa, false);
for (u32 i = 0; i < num_color_inputs; i++) for (u32 i = 0; i < num_color_inputs; i++)
ss << qualifier << "in float4 v_col" << i << ";\n"; ss << qualifier << (noperspective_color ? "noperspective " : "") << "in float4 v_col" << i << ";\n";
for (u32 i = 0; i < num_texcoord_inputs; i++) for (u32 i = 0; i < num_texcoord_inputs; i++)
ss << qualifier << "in float2 v_tex" << i << ";\n"; ss << qualifier << "in float2 v_tex" << i << ";\n";
@ -541,12 +541,13 @@ void ShaderGen::DeclareFragmentEntryPoint(
} }
else else
{ {
const char* qualifier = GetInterpolationQualifier(false, centroid_interpolation, sample_interpolation, false); const char* qualifier = GetInterpolationQualifier(false, msaa, ssaa, false);
ss << "void main(\n"; ss << "void main(\n";
for (u32 i = 0; i < num_color_inputs; i++) for (u32 i = 0; i < num_color_inputs; i++)
ss << " " << qualifier << "in float4 v_col" << i << " : COLOR" << i << ",\n"; ss << " " << qualifier << (noperspective_color ? "noperspective " : "") << "in float4 v_col" << i << " : COLOR"
<< i << ",\n";
for (u32 i = 0; i < num_texcoord_inputs; i++) for (u32 i = 0; i < num_texcoord_inputs; i++)
ss << " " << qualifier << "in float2 v_tex" << i << " : TEXCOORD" << i << ",\n"; ss << " " << qualifier << "in float2 v_tex" << i << " : TEXCOORD" << i << ",\n";

View File

@ -39,11 +39,12 @@ protected:
u32 num_color_outputs, u32 num_texcoord_outputs, u32 num_color_outputs, u32 num_texcoord_outputs,
const std::initializer_list<std::pair<const char*, const char*>>& additional_outputs, const std::initializer_list<std::pair<const char*, const char*>>& additional_outputs,
bool declare_vertex_id = false, const char* output_block_suffix = "", bool msaa = false, bool declare_vertex_id = false, const char* output_block_suffix = "", bool msaa = false,
bool ssaa = false); bool ssaa = false, bool noperspective_color = false);
void DeclareFragmentEntryPoint(std::stringstream& ss, u32 num_color_inputs, u32 num_texcoord_inputs, void DeclareFragmentEntryPoint(std::stringstream& ss, u32 num_color_inputs, u32 num_texcoord_inputs,
const std::initializer_list<std::pair<const char*, const char*>>& additional_inputs, const std::initializer_list<std::pair<const char*, const char*>>& additional_inputs,
bool declare_fragcoord = false, u32 num_color_outputs = 1, bool depth_output = false, bool declare_fragcoord = false, u32 num_color_outputs = 1, bool depth_output = false,
bool msaa = false, bool ssaa = false, bool declare_sample_id = false); bool msaa = false, bool ssaa = false, bool declare_sample_id = false,
bool noperspective_color = false);
RenderAPI m_render_api; RenderAPI m_render_api;
bool m_glsl; bool m_glsl;

View File

@ -3159,6 +3159,8 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
g_settings.display_crop_mode != old_settings.display_crop_mode || g_settings.display_crop_mode != old_settings.display_crop_mode ||
g_settings.display_aspect_ratio != old_settings.display_aspect_ratio || g_settings.display_aspect_ratio != old_settings.display_aspect_ratio ||
g_settings.gpu_pgxp_enable != old_settings.gpu_pgxp_enable || g_settings.gpu_pgxp_enable != old_settings.gpu_pgxp_enable ||
g_settings.gpu_pgxp_texture_correction != old_settings.gpu_pgxp_texture_correction ||
g_settings.gpu_pgxp_color_correction != old_settings.gpu_pgxp_color_correction ||
g_settings.gpu_pgxp_depth_buffer != old_settings.gpu_pgxp_depth_buffer || g_settings.gpu_pgxp_depth_buffer != old_settings.gpu_pgxp_depth_buffer ||
g_settings.display_active_start_offset != old_settings.display_active_start_offset || g_settings.display_active_start_offset != old_settings.display_active_start_offset ||
g_settings.display_active_end_offset != old_settings.display_active_end_offset || g_settings.display_active_end_offset != old_settings.display_active_end_offset ||

View File

@ -16,14 +16,10 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsDialog* dialog, QWi
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.resolutionScale, "GPU", "ResolutionScale", 1); SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.resolutionScale, "GPU", "ResolutionScale", 1);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.trueColor, "GPU", "TrueColor", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.trueColor, "GPU", "TrueColor", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.scaledDithering, "GPU", "ScaledDithering", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.scaledDithering, "GPU", "ScaledDithering", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableInterlacing, "GPU", "DisableInterlacing", SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableInterlacing, "GPU", "DisableInterlacing", true);
true); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.forceNTSCTimings, "GPU", "ForceNTSCTimings", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.forceNTSCTimings, "GPU", "ForceNTSCTimings", SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.force43For24Bit, "Display", "Force4_3For24Bit", false);
false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chromaSmoothingFor24Bit, "GPU", "ChromaSmoothing24Bit", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.force43For24Bit, "Display", "Force4_3For24Bit",
false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chromaSmoothingFor24Bit, "GPU",
"ChromaSmoothing24Bit", false);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.textureFiltering, "GPU", "TextureFilter", SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.textureFiltering, "GPU", "TextureFilter",
&Settings::ParseTextureFilterName, &Settings::GetTextureFilterName, &Settings::ParseTextureFilterName, &Settings::GetTextureFilterName,
Settings::DEFAULT_GPU_TEXTURE_FILTER); Settings::DEFAULT_GPU_TEXTURE_FILTER);
@ -33,11 +29,10 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsDialog* dialog, QWi
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpEnable, "GPU", "PGXPEnable", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpEnable, "GPU", "PGXPEnable", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpCulling, "GPU", "PGXPCulling", true); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpCulling, "GPU", "PGXPCulling", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpTextureCorrection, "GPU", SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpTextureCorrection, "GPU", "PGXPTextureCorrection", true);
"PGXPTextureCorrection", true); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpColorCorrection, "GPU", "PGXPColorCorrection", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpDepthBuffer, "GPU", "PGXPDepthBuffer", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpDepthBuffer, "GPU", "PGXPDepthBuffer", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpPreserveProjPrecision, "GPU", SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpPreserveProjPrecision, "GPU", "PGXPPreserveProjFP", false);
"PGXPPreserveProjFP", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpCPU, "GPU", "PGXPCPU", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpCPU, "GPU", "PGXPCPU", false);
connect(m_ui.resolutionScale, QOverload<int>::of(&QComboBox::currentIndexChanged), this, connect(m_ui.resolutionScale, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
@ -46,6 +41,7 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsDialog* dialog, QWi
updateScaledDitheringEnabled(); updateScaledDitheringEnabled();
connect(m_ui.pgxpEnable, &QCheckBox::stateChanged, this, &EnhancementSettingsWidget::updatePGXPSettingsEnabled); connect(m_ui.pgxpEnable, &QCheckBox::stateChanged, this, &EnhancementSettingsWidget::updatePGXPSettingsEnabled);
connect(m_ui.pgxpTextureCorrection, &QCheckBox::stateChanged, this, &EnhancementSettingsWidget::updatePGXPSettingsEnabled);
updatePGXPSettingsEnabled(); updatePGXPSettingsEnabled();
dialog->registerWidgetHelp( dialog->registerWidgetHelp(
@ -86,7 +82,8 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsDialog* dialog, QWi
m_ui.textureFiltering, tr("Texture Filtering"), m_ui.textureFiltering, tr("Texture Filtering"),
qApp->translate("GPUTextureFilter", Settings::GetTextureFilterDisplayName(GPUTextureFilter::Nearest)), qApp->translate("GPUTextureFilter", Settings::GetTextureFilterDisplayName(GPUTextureFilter::Nearest)),
tr("Smooths out the blockiness of magnified textures on 3D object by using filtering. <br>Will have a " tr("Smooths out the blockiness of magnified textures on 3D object by using filtering. <br>Will have a "
"greater effect on higher resolution scales. Only applies to the hardware renderers. <br>The JINC2 and especially xBR filtering modes are very demanding, and may not be worth the speed penalty.")); "greater effect on higher resolution scales. Only applies to the hardware renderers. <br>The JINC2 and "
"especially xBR filtering modes are very demanding, and may not be worth the speed penalty."));
dialog->registerWidgetHelp( dialog->registerWidgetHelp(
m_ui.widescreenHack, tr("Widescreen Hack"), tr("Unchecked"), m_ui.widescreenHack, tr("Widescreen Hack"), tr("Unchecked"),
tr("Scales vertex positions in screen-space to a widescreen aspect ratio, essentially " tr("Scales vertex positions in screen-space to a widescreen aspect ratio, essentially "
@ -104,9 +101,13 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsDialog* dialog, QWi
dialog->registerWidgetHelp(m_ui.pgxpCulling, tr("Culling Correction"), tr("Checked"), dialog->registerWidgetHelp(m_ui.pgxpCulling, tr("Culling Correction"), tr("Checked"),
tr("Increases the precision of polygon culling, reducing the number of holes in geometry. " tr("Increases the precision of polygon culling, reducing the number of holes in geometry. "
"Requires geometry correction enabled.")); "Requires geometry correction enabled."));
dialog->registerWidgetHelp(m_ui.pgxpTextureCorrection, tr("Texture Correction"), tr("Checked"), dialog->registerWidgetHelp(m_ui.pgxpTextureCorrection, tr("Perspective Correct Textures"), tr("Checked"),
tr("Uses perspective-correct interpolation for texture coordinates and colors, " tr("Uses perspective-correct interpolation for texture coordinates, straightening out "
"straightening out warped textures. Requires geometry correction enabled.")); "warped textures. Requires geometry correction enabled."));
dialog->registerWidgetHelp(
m_ui.pgxpColorCorrection, tr("Perspective Correct Colors"), tr("Unchecked"),
tr("Uses perspective-correct interpolation for vertex colors, which can improve visuals in some games, but cause "
"rendering errors in others. Requires geometry correction enabled."));
dialog->registerWidgetHelp( dialog->registerWidgetHelp(
m_ui.pgxpDepthBuffer, tr("Depth Buffer (Low Compatibility)"), tr("Unchecked"), m_ui.pgxpDepthBuffer, tr("Depth Buffer (Low Compatibility)"), tr("Unchecked"),
tr("Attempts to reduce polygon Z-fighting by testing pixels against the depth values from PGXP. Low compatibility, " tr("Attempts to reduce polygon Z-fighting by testing pixels against the depth values from PGXP. Low compatibility, "
@ -142,9 +143,11 @@ void EnhancementSettingsWidget::setupAdditionalUi()
void EnhancementSettingsWidget::updatePGXPSettingsEnabled() void EnhancementSettingsWidget::updatePGXPSettingsEnabled()
{ {
const bool enabled = m_ui.pgxpEnable->isChecked(); const bool enabled = m_dialog->getEffectiveBoolValue("GPU", "PGXPEnable", false);
const bool tc_enabled = enabled && m_dialog->getEffectiveBoolValue("GPU", "PGXPTextureCorrection", true);
m_ui.pgxpCulling->setEnabled(enabled); m_ui.pgxpCulling->setEnabled(enabled);
m_ui.pgxpTextureCorrection->setEnabled(enabled); m_ui.pgxpTextureCorrection->setEnabled(enabled);
m_ui.pgxpColorCorrection->setEnabled(tc_enabled);
m_ui.pgxpDepthBuffer->setEnabled(enabled); m_ui.pgxpDepthBuffer->setEnabled(enabled);
m_ui.pgxpPreserveProjPrecision->setEnabled(enabled); m_ui.pgxpPreserveProjPrecision->setEnabled(enabled);
m_ui.pgxpCPU->setEnabled(enabled); m_ui.pgxpCPU->setEnabled(enabled);

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>448</width> <width>448</width>
<height>720</height> <height>516</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -76,7 +76,7 @@
<item row="6" column="0" colspan="2"> <item row="6" column="0" colspan="2">
<widget class="QCheckBox" name="useSoftwareRendererForReadbacks"> <widget class="QCheckBox" name="useSoftwareRendererForReadbacks">
<property name="text"> <property name="text">
<string>Software Renderer Readbacks (run in parallel for VRAM->CPU transfers)</string> <string>Software Renderer Readbacks (run in parallel for VRAM-&gt;CPU transfers)</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -126,13 +126,6 @@
<string>PGXP (Precision Geometry Transform Pipeline)</string> <string>PGXP (Precision Geometry Transform Pipeline)</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="pgxpEnable">
<property name="text">
<string>Geometry Correction</string>
</property>
</widget>
</item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QCheckBox" name="pgxpCulling"> <widget class="QCheckBox" name="pgxpCulling">
<property name="text"> <property name="text">
@ -143,28 +136,42 @@
<item row="1" column="0"> <item row="1" column="0">
<widget class="QCheckBox" name="pgxpTextureCorrection"> <widget class="QCheckBox" name="pgxpTextureCorrection">
<property name="text"> <property name="text">
<string>Texture Correction</string> <string>Perspective Correct Textures</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="pgxpEnable">
<property name="text"> <property name="text">
<string>Preserve Projection Precision</string> <string>Geometry Correction</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="3" column="0">
<widget class="QCheckBox" name="pgxpCPU">
<property name="text">
<string>CPU Mode (Very Slow)</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="pgxpDepthBuffer"> <widget class="QCheckBox" name="pgxpDepthBuffer">
<property name="text"> <property name="text">
<string>Depth Buffer (Low Compatibility)</string> <string>Depth Buffer (Low Compatibility)</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="0">
<widget class="QCheckBox" name="pgxpCPU"> <widget class="QCheckBox" name="pgxpPreserveProjPrecision">
<property name="text"> <property name="text">
<string>CPU Mode (Very Slow)</string> <string>Preserve Projection Precision</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="pgxpColorCorrection">
<property name="text">
<string>Perspective Correct Colors</string>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -3448,21 +3448,24 @@ void FullscreenUI::DrawDisplaySettingsPage()
const bool pgxp_enabled = GetEffectiveBoolSetting(bsi, "GPU", "PGXPEnable", false); const bool pgxp_enabled = GetEffectiveBoolSetting(bsi, "GPU", "PGXPEnable", false);
const bool texture_correction_enabled = GetEffectiveBoolSetting(bsi, "GPU", "PGXPTextureCorrection", true); const bool texture_correction_enabled = GetEffectiveBoolSetting(bsi, "GPU", "PGXPTextureCorrection", true);
DrawToggleSetting(bsi, "PGXP Texture Correction", DrawToggleSetting(
"Uses perspective-correct interpolation for texture coordinates and colors, straightening out " bsi, "Perspective Correct Textures",
"warped textures.", "Uses perspective-correct interpolation for texture coordinates, straightening out warped textures.", "GPU",
"GPU", "PGXPTextureCorrection", true, pgxp_enabled); "PGXPTextureCorrection", true, pgxp_enabled);
DrawToggleSetting(bsi, "PGXP Culling Correction", DrawToggleSetting(bsi, "Perspective Correct Colors",
"Uses perspective-correct interpolation for colors, which can improve visuals in some games.",
"GPU", "PGXPColorCorrection", false, pgxp_enabled);
DrawToggleSetting(bsi, "Culling Correction",
"Increases the precision of polygon culling, reducing the number of holes in geometry.", "GPU", "Increases the precision of polygon culling, reducing the number of holes in geometry.", "GPU",
"PGXPCulling", true, pgxp_enabled); "PGXPCulling", true, pgxp_enabled);
DrawToggleSetting(bsi, "PGXP Preserve Projection Precision", DrawToggleSetting(bsi, "Preserve Projection Precision",
"Adds additional precision to PGXP data post-projection. May improve visuals in some games.", "GPU", "Adds additional precision to PGXP data post-projection. May improve visuals in some games.", "GPU",
"PGXPPreserveProjFP", false, pgxp_enabled); "PGXPPreserveProjFP", false, pgxp_enabled);
DrawToggleSetting(bsi, "PGXP Depth Buffer", DrawToggleSetting(bsi, "Depth Buffer",
"Reduces polygon Z-fighting through depth testing. Low compatibility with games.", "GPU", "Reduces polygon Z-fighting through depth testing. Low compatibility with games.", "GPU",
"PGXPDepthBuffer", false, pgxp_enabled && texture_correction_enabled); "PGXPDepthBuffer", false, pgxp_enabled && texture_correction_enabled);
DrawToggleSetting(bsi, "PGXP CPU Mode", "Uses PGXP for all instructions, not just memory operations.", "GPU", DrawToggleSetting(bsi, "CPU Mode", "Uses PGXP for all instructions, not just memory operations.", "GPU", "PGXPCPU",
"PGXPCPU", false, pgxp_enabled); false, pgxp_enabled);
MenuHeading("Texture Replacements"); MenuHeading("Texture Replacements");

View File

@ -292,6 +292,8 @@ void ImGuiManager::DrawEnhancementsOverlay()
text.AppendString("/Cull"); text.AppendString("/Cull");
if (g_settings.gpu_pgxp_texture_correction) if (g_settings.gpu_pgxp_texture_correction)
text.AppendString("/Tex"); text.AppendString("/Tex");
if (g_settings.gpu_pgxp_color_correction)
text.AppendString("/Col");
if (g_settings.gpu_pgxp_vertex_cache) if (g_settings.gpu_pgxp_vertex_cache)
text.AppendString("/VC"); text.AppendString("/VC");
if (g_settings.gpu_pgxp_cpu) if (g_settings.gpu_pgxp_cpu)