diff --git a/data/resources/database/gamesettings.ini b/data/resources/database/gamesettings.ini index 27e8c621d..528681898 100644 --- a/data/resources/database/gamesettings.ini +++ b/data/resources/database/gamesettings.ini @@ -109,6 +109,21 @@ DisableUpscaling = 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) [SLPM-87089] ForceInterlacing = true diff --git a/src/core/game_database.cpp b/src/core/game_database.cpp index 07c9f8688..1c573b3d0 100644 --- a/src/core/game_database.cpp +++ b/src/core/game_database.cpp @@ -28,7 +28,7 @@ namespace GameDatabase { enum : u32 { GAME_DATABASE_CACHE_SIGNATURE = 0x45434C48, - GAME_DATABASE_CACHE_VERSION = 1 + GAME_DATABASE_CACHE_VERSION = 2, }; static Entry* GetMutableEntry(const std::string_view& serial); @@ -56,7 +56,8 @@ std::array, static_cast(GameDatabase::T {"DisableWidescreen", TRANSLATABLE("GameSettingsTrait", "Disable Widescreen")}, {"DisablePGXP", TRANSLATABLE("GameSettingsTrait", "Disable PGXP")}, {"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")}, {"ForcePGXPVertexCache", TRANSLATABLE("GameSettingsTrait", "Force PGXP Vertex Cache")}, {"ForcePGXPCPUMode", TRANSLATABLE("GameSettingsTrait", "Force PGXP CPU Mode")}, @@ -364,12 +365,25 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes { Host::AddKeyedOSDMessage( "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; } + 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 (display_osd_messages && settings.gpu_pgxp_enable && !settings.gpu_pgxp_vertex_cache) diff --git a/src/core/game_database.h b/src/core/game_database.h index 6dbb88e90..bbfc894f8 100644 --- a/src/core/game_database.h +++ b/src/core/game_database.h @@ -37,6 +37,7 @@ enum class Trait : u32 DisablePGXP, DisablePGXPCulling, DisablePGXPTextureCorrection, + DisablePGXPColorCorrection, DisablePGXPDepthBuffer, ForcePGXPVertexCache, ForcePGXPCPUMode, diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index 84ecdfd09..41b4d9833 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -30,6 +30,11 @@ ALWAYS_INLINE static bool ShouldUseUVLimits() 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() { m_vram_ptr = m_vram_shadow.data(); @@ -64,6 +69,7 @@ bool GPU_HW::Initialize() m_using_uv_limits = ShouldUseUVLimits(); m_chroma_smoothing = g_settings.gpu_24bit_chroma_smoothing; m_downsample_mode = GetDownsampleMode(m_resolution_scale); + m_disable_color_perspective = ShouldDisableColorPerspective(); 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 GPUDownsampleMode downsample_mode = GetDownsampleMode(resolution_scale); const bool use_uv_limits = ShouldUseUVLimits(); + const bool disable_color_perspective = ShouldDisableColorPerspective(); *framebuffer_changed = (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_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_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) { @@ -184,6 +192,7 @@ void GPU_HW::UpdateHWSettings(bool* framebuffer_changed, bool* shaders_changed) m_using_uv_limits = use_uv_limits; m_chroma_smoothing = g_settings.gpu_24bit_chroma_smoothing; m_downsample_mode = downsample_mode; + m_disable_color_perspective = disable_color_perspective; if (!m_supports_dual_source_blend && TextureFilterRequiresDualSourceBlend(m_texture_filtering)) m_texture_filtering = GPUTextureFilter::Nearest; diff --git a/src/core/gpu_hw.h b/src/core/gpu_hw.h index bfd9d50a7..45d211557 100644 --- a/src/core/gpu_hw.h +++ b/src/core/gpu_hw.h @@ -377,6 +377,7 @@ protected: BitField m_per_sample_shading; BitField m_scaled_dithering; BitField m_chroma_smoothing; + BitField m_disable_color_perspective; u8 bits = 0; }; diff --git a/src/core/gpu_hw_d3d11.cpp b/src/core/gpu_hw_d3d11.cpp index b1d41d298..9007794e0 100644 --- a/src/core/gpu_hw_d3d11.cpp +++ b/src/core/gpu_hw_d3d11.cpp @@ -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, 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", 1 + 1 + 2 + (4 * 9 * 2 * 2) + 1 + (2 * 2) + 4 + (2 * 3) + 1); diff --git a/src/core/gpu_hw_d3d12.cpp b/src/core/gpu_hw_d3d12.cpp index e4228a72d..296b92f7e 100644 --- a/src/core/gpu_hw_d3d12.cpp +++ b/src/core/gpu_hw_d3d12.cpp @@ -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, 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 + (2 * 2) + 2 + 2 + 1 + 1 + (2 * 3) + 1); diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index 6010d7335..f85b5875b 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -518,7 +518,7 @@ bool GPU_HW_OpenGL::CompilePrograms() 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, 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); diff --git a/src/core/gpu_hw_shadergen.cpp b/src/core/gpu_hw_shadergen.cpp index ff4c1536b..7f5ad4ce9 100644 --- a/src/core/gpu_hw_shadergen.cpp +++ b/src/core/gpu_hw_shadergen.cpp @@ -5,11 +5,11 @@ GPU_HW_ShaderGen::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 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), 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_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( 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(), - UsingPerSampleShading()); + UsingPerSampleShading(), m_disable_color_perspective); } else { DeclareVertexEntryPoint(ss, {"float4 a_pos", "float4 a_col0", "uint a_texcoord", "uint a_texpage"}, 1, 1, - {{"nointerpolation", "uint4 v_texpage"}}, false, "", UsingMSAA(), - UsingPerSampleShading()); + {{"nointerpolation", "uint4 v_texpage"}}, false, "", UsingMSAA(), UsingPerSampleShading(), + m_disable_color_perspective); } } else { DeclareVertexEntryPoint(ss, {"float4 a_pos", "float4 a_col0"}, 1, 0, {}, false, "", UsingMSAA(), - UsingPerSampleShading()); + UsingPerSampleShading(), m_disable_color_perspective); } ss << R"( @@ -805,18 +805,20 @@ float4 SampleFromVRAM(uint4 texpage, float2 coords) { DeclareFragmentEntryPoint(ss, 1, 1, {{"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 { 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 { DeclareFragmentEntryPoint(ss, 1, 0, {}, true, use_dual_source ? 2 : 1, !m_pgxp_depth, UsingMSAA(), - UsingPerSampleShading()); + UsingPerSampleShading(), false, m_disable_color_perspective); } ss << R"( diff --git a/src/core/gpu_hw_shadergen.h b/src/core/gpu_hw_shadergen.h index 59639677a..de74fbbbb 100644 --- a/src/core/gpu_hw_shadergen.h +++ b/src/core/gpu_hw_shadergen.h @@ -7,7 +7,7 @@ class GPU_HW_ShaderGen : public ShaderGen public: 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 pgxp_depth, bool supports_dual_source_blend); + bool pgxp_depth, bool disable_color_perspective, bool supports_dual_source_blend); ~GPU_HW_ShaderGen(); std::string GenerateBatchVertexShader(bool textured); @@ -42,4 +42,5 @@ private: GPUTextureFilter m_texture_filter; bool m_uv_limits; bool m_pgxp_depth; + bool m_disable_color_perspective; }; diff --git a/src/core/gpu_hw_vulkan.cpp b/src/core/gpu_hw_vulkan.cpp index d9f65d4fa..6d8baf8e7 100644 --- a/src/core/gpu_hw_vulkan.cpp +++ b/src/core/gpu_hw_vulkan.cpp @@ -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, 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 + (2 * 2) + 2 + 1 + 1 + (2 * 3) + 1); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 7478dc6dd..8a394c395 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -222,6 +222,7 @@ void Settings::Load(SettingsInterface& si) gpu_pgxp_enable = si.GetBoolValue("GPU", "PGXPEnable", false); gpu_pgxp_culling = si.GetBoolValue("GPU", "PGXPCulling", 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_cpu = si.GetBoolValue("GPU", "PGXPCPU", 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", "PGXPCulling", gpu_pgxp_culling); 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", "PGXPCPU", gpu_pgxp_cpu); si.SetBoolValue("GPU", "PGXPPreserveProjFP", gpu_pgxp_preserve_proj_fp); diff --git a/src/core/settings.h b/src/core/settings.h index 8ae4aaf28..a9f95442e 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -108,6 +108,7 @@ struct Settings bool gpu_pgxp_enable = false; bool gpu_pgxp_culling = true; bool gpu_pgxp_texture_correction = true; + bool gpu_pgxp_color_correction = false; bool gpu_pgxp_vertex_cache = false; bool gpu_pgxp_cpu = false; bool gpu_pgxp_preserve_proj_fp = false; diff --git a/src/core/shadergen.cpp b/src/core/shadergen.cpp index 6c2d54734..c32a20013 100644 --- a/src/core/shadergen.cpp +++ b/src/core/shadergen.cpp @@ -11,8 +11,7 @@ Log_SetChannel(ShaderGen); ShaderGen::ShaderGen(RenderAPI render_api, bool supports_dual_source_blend) - : m_render_api(render_api), - m_glsl(render_api != RenderAPI::D3D11 && render_api != RenderAPI::D3D12), + : m_render_api(render_api), 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) { #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_binding_layout = (IsVulkan() || UseGLSLBindingLayout()); - + if (m_render_api == RenderAPI::OpenGL) { // 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( std::stringstream& ss, const std::initializer_list& attributes, u32 num_color_outputs, u32 num_texcoord_outputs, const std::initializer_list>& additional_outputs, - bool declare_vertex_id /* = false */, const char* output_block_suffix /* = "" */, - bool centroid_interpolation /* = false */, bool sample_interpolation /* = false */) + bool declare_vertex_id /* = false */, const char* output_block_suffix /* = "" */, bool msaa /* = false */, + bool ssaa /* = false */, bool noperspective_color /* = false */) { if (m_glsl) { @@ -377,7 +376,7 @@ void ShaderGen::DeclareVertexEntryPoint( 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()) ss << "layout(location = 0) "; @@ -398,7 +397,7 @@ void ShaderGen::DeclareVertexEntryPoint( } 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++) ss << qualifier << "out float4 v_col" << i << ";\n"; @@ -427,7 +426,7 @@ void ShaderGen::DeclareVertexEntryPoint( } else { - const char* qualifier = GetInterpolationQualifier(false, centroid_interpolation, sample_interpolation, true); + const char* qualifier = GetInterpolationQualifier(false, msaa, ssaa, true); ss << "void main(\n"; @@ -442,7 +441,8 @@ void ShaderGen::DeclareVertexEntryPoint( } 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++) 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, const std::initializer_list>& additional_inputs, bool declare_fragcoord /* = false */, u32 num_color_outputs /* = 1 */, bool depth_output /* = false */, - bool centroid_interpolation /* = false */, bool sample_interpolation /* = false */, - bool declare_sample_id /* = false */) + bool msaa /* = false */, bool ssaa /* = false */, bool declare_sample_id /* = false */, + bool noperspective_color /* = false */) { if (m_glsl) { 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()) ss << "layout(location = 0) "; ss << "in VertexData {\n"; 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++) ss << " " << qualifier << "float2 v_tex" << i << ";\n"; @@ -491,10 +491,10 @@ void ShaderGen::DeclareFragmentEntryPoint( } 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++) - 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++) ss << qualifier << "in float2 v_tex" << i << ";\n"; @@ -541,12 +541,13 @@ void ShaderGen::DeclareFragmentEntryPoint( } else { - const char* qualifier = GetInterpolationQualifier(false, centroid_interpolation, sample_interpolation, false); + const char* qualifier = GetInterpolationQualifier(false, msaa, ssaa, false); ss << "void main(\n"; 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++) ss << " " << qualifier << "in float2 v_tex" << i << " : TEXCOORD" << i << ",\n"; diff --git a/src/core/shadergen.h b/src/core/shadergen.h index f136adf43..d104bea81 100644 --- a/src/core/shadergen.h +++ b/src/core/shadergen.h @@ -39,11 +39,12 @@ protected: u32 num_color_outputs, u32 num_texcoord_outputs, const std::initializer_list>& additional_outputs, 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, const std::initializer_list>& additional_inputs, 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; bool m_glsl; diff --git a/src/core/system.cpp b/src/core/system.cpp index 11fa4bd64..a9bc21fff 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -3159,6 +3159,8 @@ void System::CheckForSettingsChanges(const Settings& old_settings) g_settings.display_crop_mode != old_settings.display_crop_mode || g_settings.display_aspect_ratio != old_settings.display_aspect_ratio || 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.display_active_start_offset != old_settings.display_active_start_offset || g_settings.display_active_end_offset != old_settings.display_active_end_offset || diff --git a/src/duckstation-qt/enhancementsettingswidget.cpp b/src/duckstation-qt/enhancementsettingswidget.cpp index a7563c874..3c35668d3 100644 --- a/src/duckstation-qt/enhancementsettingswidget.cpp +++ b/src/duckstation-qt/enhancementsettingswidget.cpp @@ -16,14 +16,10 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsDialog* dialog, QWi SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.resolutionScale, "GPU", "ResolutionScale", 1); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.trueColor, "GPU", "TrueColor", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.scaledDithering, "GPU", "ScaledDithering", false); - SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableInterlacing, "GPU", "DisableInterlacing", - true); - SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.forceNTSCTimings, "GPU", "ForceNTSCTimings", - false); - SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.force43For24Bit, "Display", "Force4_3For24Bit", - false); - SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.chromaSmoothingFor24Bit, "GPU", - "ChromaSmoothing24Bit", false); + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableInterlacing, "GPU", "DisableInterlacing", true); + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.forceNTSCTimings, "GPU", "ForceNTSCTimings", 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", &Settings::ParseTextureFilterName, &Settings::GetTextureFilterName, 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.pgxpCulling, "GPU", "PGXPCulling", true); - SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpTextureCorrection, "GPU", - "PGXPTextureCorrection", true); + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpTextureCorrection, "GPU", "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.pgxpPreserveProjPrecision, "GPU", - "PGXPPreserveProjFP", false); + SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpPreserveProjPrecision, "GPU", "PGXPPreserveProjFP", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpCPU, "GPU", "PGXPCPU", false); connect(m_ui.resolutionScale, QOverload::of(&QComboBox::currentIndexChanged), this, @@ -46,6 +41,7 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsDialog* dialog, QWi updateScaledDitheringEnabled(); connect(m_ui.pgxpEnable, &QCheckBox::stateChanged, this, &EnhancementSettingsWidget::updatePGXPSettingsEnabled); + connect(m_ui.pgxpTextureCorrection, &QCheckBox::stateChanged, this, &EnhancementSettingsWidget::updatePGXPSettingsEnabled); updatePGXPSettingsEnabled(); dialog->registerWidgetHelp( @@ -86,7 +82,8 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(SettingsDialog* dialog, QWi m_ui.textureFiltering, tr("Texture Filtering"), qApp->translate("GPUTextureFilter", Settings::GetTextureFilterDisplayName(GPUTextureFilter::Nearest)), tr("Smooths out the blockiness of magnified textures on 3D object by using filtering.
Will have a " - "greater effect on higher resolution scales. Only applies to the hardware renderers.
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.
The JINC2 and " + "especially xBR filtering modes are very demanding, and may not be worth the speed penalty.")); dialog->registerWidgetHelp( m_ui.widescreenHack, tr("Widescreen Hack"), tr("Unchecked"), 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"), tr("Increases the precision of polygon culling, reducing the number of holes in geometry. " "Requires geometry correction enabled.")); - dialog->registerWidgetHelp(m_ui.pgxpTextureCorrection, tr("Texture Correction"), tr("Checked"), - tr("Uses perspective-correct interpolation for texture coordinates and colors, " - "straightening out warped textures. Requires geometry correction enabled.")); + dialog->registerWidgetHelp(m_ui.pgxpTextureCorrection, tr("Perspective Correct Textures"), tr("Checked"), + tr("Uses perspective-correct interpolation for texture coordinates, straightening out " + "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( 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, " @@ -142,9 +143,11 @@ void EnhancementSettingsWidget::setupAdditionalUi() 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.pgxpTextureCorrection->setEnabled(enabled); + m_ui.pgxpColorCorrection->setEnabled(tc_enabled); m_ui.pgxpDepthBuffer->setEnabled(enabled); m_ui.pgxpPreserveProjPrecision->setEnabled(enabled); m_ui.pgxpCPU->setEnabled(enabled); diff --git a/src/duckstation-qt/enhancementsettingswidget.ui b/src/duckstation-qt/enhancementsettingswidget.ui index a639d088b..3c66643bd 100644 --- a/src/duckstation-qt/enhancementsettingswidget.ui +++ b/src/duckstation-qt/enhancementsettingswidget.ui @@ -7,7 +7,7 @@ 0 0 448 - 720 + 516 @@ -76,7 +76,7 @@ - Software Renderer Readbacks (run in parallel for VRAM->CPU transfers) + Software Renderer Readbacks (run in parallel for VRAM->CPU transfers) @@ -126,13 +126,6 @@ PGXP (Precision Geometry Transform Pipeline) - - - - Geometry Correction - - - @@ -143,28 +136,42 @@ - Texture Correction + Perspective Correct Textures - - + + - Preserve Projection Precision + Geometry Correction - + + + + CPU Mode (Very Slow) + + + + Depth Buffer (Low Compatibility) - - + + - CPU Mode (Very Slow) + Preserve Projection Precision + + + + + + + Perspective Correct Colors diff --git a/src/frontend-common/fullscreen_ui.cpp b/src/frontend-common/fullscreen_ui.cpp index 31f7af127..331877ee5 100644 --- a/src/frontend-common/fullscreen_ui.cpp +++ b/src/frontend-common/fullscreen_ui.cpp @@ -3448,21 +3448,24 @@ void FullscreenUI::DrawDisplaySettingsPage() const bool pgxp_enabled = GetEffectiveBoolSetting(bsi, "GPU", "PGXPEnable", false); const bool texture_correction_enabled = GetEffectiveBoolSetting(bsi, "GPU", "PGXPTextureCorrection", true); - DrawToggleSetting(bsi, "PGXP Texture Correction", - "Uses perspective-correct interpolation for texture coordinates and colors, straightening out " - "warped textures.", - "GPU", "PGXPTextureCorrection", true, pgxp_enabled); - DrawToggleSetting(bsi, "PGXP Culling Correction", + DrawToggleSetting( + bsi, "Perspective Correct Textures", + "Uses perspective-correct interpolation for texture coordinates, straightening out warped textures.", "GPU", + "PGXPTextureCorrection", true, pgxp_enabled); + 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", "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", "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", "PGXPDepthBuffer", false, pgxp_enabled && texture_correction_enabled); - DrawToggleSetting(bsi, "PGXP CPU Mode", "Uses PGXP for all instructions, not just memory operations.", "GPU", - "PGXPCPU", false, pgxp_enabled); + DrawToggleSetting(bsi, "CPU Mode", "Uses PGXP for all instructions, not just memory operations.", "GPU", "PGXPCPU", + false, pgxp_enabled); MenuHeading("Texture Replacements"); diff --git a/src/frontend-common/imgui_overlays.cpp b/src/frontend-common/imgui_overlays.cpp index b9350df89..f95dec611 100644 --- a/src/frontend-common/imgui_overlays.cpp +++ b/src/frontend-common/imgui_overlays.cpp @@ -292,6 +292,8 @@ void ImGuiManager::DrawEnhancementsOverlay() text.AppendString("/Cull"); if (g_settings.gpu_pgxp_texture_correction) text.AppendString("/Tex"); + if (g_settings.gpu_pgxp_color_correction) + text.AppendString("/Col"); if (g_settings.gpu_pgxp_vertex_cache) text.AppendString("/VC"); if (g_settings.gpu_pgxp_cpu)