diff --git a/data/resources/gamedb.yaml b/data/resources/gamedb.yaml index d9c876929..172089a13 100644 --- a/data/resources/gamedb.yaml +++ b/data/resources/gamedb.yaml @@ -3231,7 +3231,7 @@ SCPS-10126: - AnalogController - DigitalController traits: - - ForceAccurateBlending # Requires 16-bit blend precision + - ForceShaderBlending # Requires 16-bit blend precision - DisableTrueColor # to fix screen flicker. metadata: publisher: "Sony" @@ -3257,7 +3257,7 @@ SLES-04108: - AnalogController - DigitalController traits: - - ForceAccurateBlending # Requires 16-bit blend precision + - ForceShaderBlending # Requires 16-bit blend precision - DisableTrueColor # to fix screen flicker. metadata: publisher: "Vivendi Universal Games, Inc" @@ -72945,7 +72945,7 @@ SLUS-01244: - AnalogController - DigitalController traits: - - ForceAccurateBlending # Requires 16-bit blend precision + - ForceShaderBlending # Requires 16-bit blend precision - DisableTrueColor # to fix transparency in menu backgrounds. metadata: publisher: "The 3DO Company" diff --git a/src/core/fullscreen_ui.cpp b/src/core/fullscreen_ui.cpp index 1724bbe92..994daac1b 100644 --- a/src/core/fullscreen_ui.cpp +++ b/src/core/fullscreen_ui.cpp @@ -5025,7 +5025,6 @@ void FullscreenUI::DrawGraphicsSettingsPage() OpenChoiceDialog(FSUI_ICONSTR(ICON_FA_MICROCHIP, "GPU Adapter"), false, std::move(options), std::move(callback)); } - const bool true_color_enabled = (is_hardware && GetEffectiveBoolSetting(bsi, "GPU", "TrueColor", false)); const bool pgxp_enabled = (is_hardware && GetEffectiveBoolSetting(bsi, "GPU", "PGXPEnable", false)); const bool texture_correction_enabled = (pgxp_enabled && GetEffectiveBoolSetting(bsi, "GPU", "PGXPTextureCorrection", true)); @@ -5066,6 +5065,13 @@ void FullscreenUI::DrawGraphicsSettingsPage() FSUI_CSTR("Smooths out the blockiness of magnified textures on 2D objects."), "GPU", "SpriteTextureFilter", Settings::DEFAULT_GPU_TEXTURE_FILTER, &Settings::ParseTextureFilterName, &Settings::GetTextureFilterName, &Settings::GetTextureFilterDisplayName, GPUTextureFilter::Count); + + DrawEnumSetting(bsi, FSUI_ICONSTR(ICON_FA_TINT_SLASH, "Dithering"), + FSUI_CSTR("Controls how dithering is applied in the emulated GPU. True Color disables dithering " + "and produces the nicest looking gradients."), + "GPU", "DitheringMode", Settings::DEFAULT_GPU_DITHERING_MODE, &Settings::ParseGPUDitheringModeName, + &Settings::GetGPUDitheringModeName, &Settings::GetGPUDitheringModeDisplayName, + GPUDitheringMode::MaxCount); } DrawEnumSetting(bsi, FSUI_ICONSTR(ICON_FA_SHAPES, "Aspect Ratio"), @@ -5094,13 +5100,6 @@ void FullscreenUI::DrawGraphicsSettingsPage() "Display", "Scaling", Settings::DEFAULT_DISPLAY_SCALING, &Settings::ParseDisplayScaling, &Settings::GetDisplayScalingName, &Settings::GetDisplayScalingDisplayName, DisplayScalingMode::Count); - if (is_hardware) - { - DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_PALETTE, "True Color Rendering"), - FSUI_CSTR("Disables dithering and uses the full 8 bits per channel of color information."), "GPU", - "TrueColor", true); - } - DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_EXCHANGE_ALT, "Widescreen Rendering"), FSUI_CSTR("Increases the field of view from 4:3 to the chosen display aspect ratio in 3D games."), "GPU", "WidescreenHack", false); @@ -5220,22 +5219,11 @@ void FullscreenUI::DrawGraphicsSettingsPage() &Settings::GetGPUWireframeModeName, &Settings::GetGPUWireframeModeDisplayName, GPUWireframeMode::Count); - DrawToggleSetting( - bsi, FSUI_ICONSTR(ICON_FA_TINT_SLASH, "Scaled Dithering"), - FSUI_CSTR("Scales the dithering pattern with the internal rendering resolution, making it less noticeable. " - "Usually safe to enable."), - "GPU", "ScaledDithering", true, !true_color_enabled && resolution_scale > 1); - DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_TINT_SLASH, "Scaled Interlacing"), FSUI_CSTR("Scales line skipping in interlaced rendering to the internal resolution, making it " "less noticeable. Usually safe to enable."), "GPU", "ScaledInterlacing", true, resolution_scale > 1); - DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_FILL, "Accurate Blending"), - FSUI_CSTR("Forces blending to be done in the shader at 16-bit precision, when not using true " - "color. Non-trivial performance impact, and unnecessary for most games."), - "GPU", "AccurateBlending", false, !true_color_enabled); - const GPUTextureFilter texture_filtering = Settings::ParseTextureFilterName( GetEffectiveTinyStringSetting(bsi, "GPU", "TextureFilter", @@ -8835,7 +8823,6 @@ TRANSLATE_NOOP("FullscreenUI", "AMOLED"); TRANSLATE_NOOP("FullscreenUI", "About"); TRANSLATE_NOOP("FullscreenUI", "About DuckStation"); TRANSLATE_NOOP("FullscreenUI", "Account"); -TRANSLATE_NOOP("FullscreenUI", "Accurate Blending"); TRANSLATE_NOOP("FullscreenUI", "Achievement Notifications"); TRANSLATE_NOOP("FullscreenUI", "Achievement Unlock/Count"); TRANSLATE_NOOP("FullscreenUI", "Achievements"); @@ -8939,6 +8926,7 @@ TRANSLATE_NOOP("FullscreenUI", "Controller preset '{}' loaded."); TRANSLATE_NOOP("FullscreenUI", "Controller preset '{}' saved."); TRANSLATE_NOOP("FullscreenUI", "Controller settings reset to default."); TRANSLATE_NOOP("FullscreenUI", "Controls"); +TRANSLATE_NOOP("FullscreenUI", "Controls how dithering is applied in the emulated GPU. True Color disables dithering and produces the nicest looking gradients."); TRANSLATE_NOOP("FullscreenUI", "Controls the volume of the audio played on the host when fast forwarding."); TRANSLATE_NOOP("FullscreenUI", "Controls the volume of the audio played on the host."); TRANSLATE_NOOP("FullscreenUI", "Copies the current global settings to this game."); @@ -8999,13 +8987,13 @@ TRANSLATE_NOOP("FullscreenUI", "Disable Mailbox Presentation"); TRANSLATE_NOOP("FullscreenUI", "Disable Subdirectory Scanning"); TRANSLATE_NOOP("FullscreenUI", "Disable on 2D Polygons"); TRANSLATE_NOOP("FullscreenUI", "Disabled"); -TRANSLATE_NOOP("FullscreenUI", "Disables dithering and uses the full 8 bits per channel of color information."); TRANSLATE_NOOP("FullscreenUI", "Disc {} | {}"); TRANSLATE_NOOP("FullscreenUI", "Discord Server"); TRANSLATE_NOOP("FullscreenUI", "Display Area"); TRANSLATE_NOOP("FullscreenUI", "Displays DualShock/DualSense button icons in the footer and input binding, instead of Xbox buttons."); TRANSLATE_NOOP("FullscreenUI", "Displays popup messages on events such as achievement unlocks and leaderboard submissions."); TRANSLATE_NOOP("FullscreenUI", "Displays popup messages when starting, submitting, or failing a leaderboard challenge."); +TRANSLATE_NOOP("FullscreenUI", "Dithering"); TRANSLATE_NOOP("FullscreenUI", "Double-Click Toggles Fullscreen"); TRANSLATE_NOOP("FullscreenUI", "Download Covers"); TRANSLATE_NOOP("FullscreenUI", "Downloads covers from a user-specified URL template."); @@ -9086,7 +9074,6 @@ TRANSLATE_NOOP("FullscreenUI", "File Size: %u MB (%u MB on disk)"); TRANSLATE_NOOP("FullscreenUI", "File Title"); TRANSLATE_NOOP("FullscreenUI", "Force 4:3 For FMVs"); TRANSLATE_NOOP("FullscreenUI", "Forces a full rescan of all games previously identified."); -TRANSLATE_NOOP("FullscreenUI", "Forces blending to be done in the shader at 16-bit precision, when not using true color. Non-trivial performance impact, and unnecessary for most games."); TRANSLATE_NOOP("FullscreenUI", "Forces texture upload tracking to be enabled regardless of whether it is needed."); TRANSLATE_NOOP("FullscreenUI", "Forces the use of FIFO over Mailbox presentation, i.e. double buffering instead of triple buffering. Usually results in worse frame pacing."); TRANSLATE_NOOP("FullscreenUI", "Forcibly mutes both CD-DA and XA audio from the CD-ROM. Can be used to disable background music in some games."); @@ -9334,11 +9321,9 @@ TRANSLATE_NOOP("FullscreenUI", "Save State Compression"); TRANSLATE_NOOP("FullscreenUI", "Save State On Shutdown"); TRANSLATE_NOOP("FullscreenUI", "Saved {:%c}"); TRANSLATE_NOOP("FullscreenUI", "Saves state periodically so you can rewind any mistakes while playing."); -TRANSLATE_NOOP("FullscreenUI", "Scaled Dithering"); TRANSLATE_NOOP("FullscreenUI", "Scaled Interlacing"); TRANSLATE_NOOP("FullscreenUI", "Scales internal VRAM resolution by the specified multiplier. Some games require 1x VRAM resolution."); TRANSLATE_NOOP("FullscreenUI", "Scales line skipping in interlaced rendering to the internal resolution, making it less noticeable. Usually safe to enable."); -TRANSLATE_NOOP("FullscreenUI", "Scales the dithering pattern with the internal rendering resolution, making it less noticeable. Usually safe to enable."); TRANSLATE_NOOP("FullscreenUI", "Scaling"); TRANSLATE_NOOP("FullscreenUI", "Scan For New Games"); TRANSLATE_NOOP("FullscreenUI", "Scanning Subdirectories"); @@ -9473,7 +9458,6 @@ TRANSLATE_NOOP("FullscreenUI", "Toggle Fullscreen"); TRANSLATE_NOOP("FullscreenUI", "Toggle every %d frames"); TRANSLATE_NOOP("FullscreenUI", "Toggles the macro when the button is pressed, instead of held."); TRANSLATE_NOOP("FullscreenUI", "Trigger"); -TRANSLATE_NOOP("FullscreenUI", "True Color Rendering"); TRANSLATE_NOOP("FullscreenUI", "Turbo Speed"); TRANSLATE_NOOP("FullscreenUI", "Type"); TRANSLATE_NOOP("FullscreenUI", "UI Language"); diff --git a/src/core/game_database.cpp b/src/core/game_database.cpp index 88cd91835..f3e056234 100644 --- a/src/core/game_database.cpp +++ b/src/core/game_database.cpp @@ -79,7 +79,7 @@ static constexpr const std::array(Trait::MaxCou "ForceSoftwareRenderer", "ForceSoftwareRendererForReadbacks", "ForceRoundTextureCoordinates", - "ForceAccurateBlending", + "ForceShaderBlending", "ForceDeinterlacing", "ForceFullBoot", "DisableAutoAnalogMode", @@ -109,7 +109,7 @@ static constexpr const std::array(Trait::MaxCou TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Software Renderer", "GameDatabase::Trait"), TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Software Renderer For Readbacks", "GameDatabase::Trait"), TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Round Texture Coordinates", "GameDatabase::Trait"), - TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Accurate Blending", "GameDatabase::Trait"), + TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Shader Blending", "GameDatabase::Trait"), TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Deinterlacing", "GameDatabase::Trait"), TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Force Full Boot", "GameDatabase::Trait"), TRANSLATE_DISAMBIG_NOOP("GameDatabase", "Disable Automatic Analog Mode", "GameDatabase::Trait"), @@ -489,14 +489,6 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes settings.gpu_force_round_texcoords = true; } - if (HasTrait(Trait::ForceAccurateBlending)) - { - if (display_osd_messages && !settings.IsUsingSoftwareRenderer() && !settings.gpu_accurate_blending) - APPEND_MESSAGE(TRANSLATE_SV("GameDatabase", "Accurate blending enabled.")); - - settings.gpu_accurate_blending = true; - } - if (HasTrait(Trait::ForceDeinterlacing)) { const DisplayDeinterlacingMode new_mode = display_deinterlacing_mode.value_or( @@ -527,12 +519,32 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes } } - if (HasTrait(Trait::DisableTrueColor)) + if (HasTrait(Trait::DisableTrueColor) || HasTrait(Trait::DisableScaledDithering) || + HasTrait(Trait::ForceShaderBlending)) { - if (display_osd_messages && settings.gpu_true_color) - APPEND_MESSAGE(TRANSLATE_SV("GameDatabase", "True color disabled.")); + // Note: The order these are applied matters. + const GPUDitheringMode old_mode = settings.gpu_dithering_mode; + if (HasTrait(Trait::DisableTrueColor) && settings.IsUsingTrueColor()) + { + settings.gpu_dithering_mode = GPUDitheringMode::Scaled; + } + if (HasTrait(Trait::DisableScaledDithering) && settings.IsUsingDithering()) + { + settings.gpu_dithering_mode = + (settings.IsUsingShaderBlending() ? GPUDitheringMode::UnscaledShaderBlend : GPUDitheringMode::Unscaled); + } + if (HasTrait(Trait::ForceShaderBlending) && settings.IsUsingDithering() && !settings.IsUsingShaderBlending()) + { + settings.gpu_dithering_mode = (settings.gpu_dithering_mode == GPUDitheringMode::Scaled) ? + GPUDitheringMode::ScaledShaderBlend : + GPUDitheringMode::UnscaledShaderBlend; + } - settings.gpu_true_color = false; + if (display_osd_messages && settings.gpu_dithering_mode != old_mode) + { + APPEND_MESSAGE_FMT(TRANSLATE_FS("GameDatabase", "Dithering set to {}."), + Settings::GetGPUDitheringModeDisplayName(settings.gpu_dithering_mode)); + } } if (HasTrait(Trait::DisableUpscaling)) @@ -565,14 +577,6 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes settings.gpu_sprite_texture_filter = GPUTextureFilter::Nearest; } - if (HasTrait(Trait::DisableScaledDithering)) - { - if (display_osd_messages && settings.gpu_scaled_dithering) - APPEND_MESSAGE(TRANSLATE_SV("GameDatabase", "Scaled dithering disabled.")); - - settings.gpu_scaled_dithering = false; - } - if (HasTrait(Trait::DisableScaledInterlacing)) { if (display_osd_messages && settings.gpu_scaled_interlacing && diff --git a/src/core/game_database.h b/src/core/game_database.h index 456b3605e..95b4a702f 100644 --- a/src/core/game_database.h +++ b/src/core/game_database.h @@ -37,7 +37,7 @@ enum class Trait : u32 ForceSoftwareRenderer, ForceSoftwareRendererForReadbacks, ForceRoundUpscaledTextureCoordinates, - ForceAccurateBlending, + ForceShaderBlending, ForceDeinterlacing, ForceFullBoot, DisableAutoAnalogMode, diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index 8c667a1ed..6a2e1d105 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -261,7 +261,7 @@ bool GPU_HW::Initialize(bool upload_vram, Error* error) m_wireframe_mode = g_gpu_settings.gpu_wireframe_mode; m_supports_dual_source_blend = features.dual_source_blend; m_supports_framebuffer_fetch = features.framebuffer_fetch; - m_true_color = g_gpu_settings.gpu_true_color; + m_true_color = g_gpu_settings.IsUsingTrueColor(); m_pgxp_depth_buffer = g_gpu_settings.UsingPGXPDepthBuffer(); m_clamp_uvs = ShouldClampUVs(m_texture_filtering) || ShouldClampUVs(m_sprite_texture_filtering); m_compute_uv_range = m_clamp_uvs; @@ -446,22 +446,21 @@ bool GPU_HW::UpdateSettings(const GPUSettings& old_settings, Error* error) const u8 resolution_scale = Truncate8(CalculateResolutionScale()); const u8 multisamples = Truncate8(std::min(g_gpu_settings.gpu_multisamples, g_gpu_device->GetMaxMultisamples())); const bool clamp_uvs = ShouldClampUVs(m_texture_filtering) || ShouldClampUVs(m_sprite_texture_filtering); - const bool framebuffer_changed = - (m_resolution_scale != resolution_scale || m_multisamples != multisamples || - g_gpu_settings.IsUsingAccurateBlending() != old_settings.IsUsingAccurateBlending() || - m_pgxp_depth_buffer != g_gpu_settings.UsingPGXPDepthBuffer() || - (!old_settings.gpu_texture_cache && g_gpu_settings.gpu_texture_cache)); + const bool framebuffer_changed = (m_resolution_scale != resolution_scale || m_multisamples != multisamples || + g_gpu_settings.IsUsingShaderBlending() != old_settings.IsUsingShaderBlending() || + m_pgxp_depth_buffer != g_gpu_settings.UsingPGXPDepthBuffer() || + (!old_settings.gpu_texture_cache && g_gpu_settings.gpu_texture_cache)); const bool shaders_changed = ((m_resolution_scale > 1) != (resolution_scale > 1) || m_multisamples != multisamples || - m_true_color != g_gpu_settings.gpu_true_color || + m_true_color != g_gpu_settings.IsUsingTrueColor() || (old_settings.display_deinterlacing_mode == DisplayDeinterlacingMode::Progressive) != (g_gpu_settings.display_deinterlacing_mode == DisplayDeinterlacingMode::Progressive) || (multisamples > 1 && g_gpu_settings.gpu_per_sample_shading != old_settings.gpu_per_sample_shading) || - (resolution_scale > 1 && (g_gpu_settings.gpu_scaled_dithering != old_settings.gpu_scaled_dithering || + (resolution_scale > 1 && (g_gpu_settings.IsUsingScaledDithering() != old_settings.IsUsingScaledDithering() || g_gpu_settings.gpu_scaled_interlacing != old_settings.gpu_scaled_interlacing)) || (resolution_scale > 1 && g_gpu_settings.gpu_texture_filter == GPUTextureFilter::Nearest && g_gpu_settings.gpu_force_round_texcoords != old_settings.gpu_force_round_texcoords) || - g_gpu_settings.IsUsingAccurateBlending() != old_settings.IsUsingAccurateBlending() || + g_gpu_settings.IsUsingShaderBlending() != old_settings.IsUsingShaderBlending() || m_texture_filtering != g_gpu_settings.gpu_texture_filter || m_sprite_texture_filtering != g_gpu_settings.gpu_sprite_texture_filter || m_clamp_uvs != clamp_uvs || (features.geometry_shaders && g_gpu_settings.gpu_wireframe_mode != old_settings.gpu_wireframe_mode) || @@ -522,7 +521,7 @@ bool GPU_HW::UpdateSettings(const GPUSettings& old_settings, Error* error) m_line_detect_mode = (m_resolution_scale > 1) ? g_gpu_settings.gpu_line_detect_mode : GPULineDetectMode::Disabled; m_downsample_mode = GetDownsampleMode(resolution_scale); m_wireframe_mode = g_gpu_settings.gpu_wireframe_mode; - m_true_color = g_gpu_settings.gpu_true_color; + m_true_color = g_gpu_settings.IsUsingTrueColor(); m_clamp_uvs = clamp_uvs; m_compute_uv_range = m_clamp_uvs; m_allow_sprite_mode = ShouldAllowSpriteMode(resolution_scale, m_texture_filtering, m_sprite_texture_filtering); @@ -660,23 +659,23 @@ void GPU_HW::CheckSettings() m_allow_sprite_mode = ShouldAllowSpriteMode(m_resolution_scale, m_texture_filtering, m_sprite_texture_filtering); } - if (g_gpu_settings.IsUsingAccurateBlending() && !m_supports_framebuffer_fetch && !features.feedback_loops && + if (g_gpu_settings.IsUsingShaderBlending() && !m_supports_framebuffer_fetch && !features.feedback_loops && !features.raster_order_views) { // m_allow_shader_blend/m_prefer_shader_blend will be cleared in pipeline compile. Host::AddIconOSDMessage( "AccurateBlendingUnsupported", ICON_EMOJI_WARNING, - TRANSLATE_STR("GPU_HW", "Accurate blending is not supported by your current GPU.\nIt requires framebuffer fetch, " + TRANSLATE_STR("GPU_HW", "Shader blending is not supported by your current GPU.\nIt requires framebuffer fetch, " "feedback loops, or rasterizer order views."), Host::OSD_WARNING_DURATION); } else if (IsUsingMultisampling() && !features.framebuffer_fetch && - ((g_gpu_settings.IsUsingAccurateBlending() && features.raster_order_views) || + ((g_gpu_settings.IsUsingShaderBlending() && features.raster_order_views) || (m_pgxp_depth_buffer && features.raster_order_views && !features.feedback_loops))) { Host::AddIconOSDMessage( "AccurateBlendingUnsupported", ICON_EMOJI_WARNING, - TRANSLATE_STR("GPU_HW", "Multisample anti-aliasing is not supported when using ROV blending."), + TRANSLATE_STR("GPU_HW", "Multisample anti-aliasing is not supported when using shader blending."), Host::OSD_WARNING_DURATION); m_multisamples = 1; } @@ -846,8 +845,7 @@ void GPU_HW::PrintSettingsToLog() (g_gpu_settings.gpu_per_sample_shading && g_gpu_device->GetFeatures().per_sample_shading) ? " (per sample shading)" : ""); - INFO_LOG("Dithering: {}", m_true_color ? "Disabled" : "Enabled", - (!m_true_color && g_gpu_settings.gpu_scaled_dithering)); + INFO_LOG("Dithering: {}", Settings::GetGPUDitheringModeDisplayName(g_gpu_settings.gpu_dithering_mode)); INFO_LOG("Deinterlacing: {}{}", Settings::GetDisplayDeinterlacingModeDisplayName(g_gpu_settings.display_deinterlacing_mode), (m_resolution_scale > 1 && g_gpu_settings.gpu_scaled_interlacing) ? " (scaled)" : ""); @@ -1054,8 +1052,8 @@ bool GPU_HW::CompilePipelines(Error* error) const bool per_sample_shading = (msaa && g_gpu_settings.gpu_per_sample_shading && features.per_sample_shading); const bool force_round_texcoords = (upscaled && m_texture_filtering == GPUTextureFilter::Nearest && g_gpu_settings.gpu_force_round_texcoords); - const bool true_color = g_gpu_settings.gpu_true_color; - const bool scaled_dithering = (!m_true_color && upscaled && g_gpu_settings.gpu_scaled_dithering); + const bool true_color = g_gpu_settings.IsUsingTrueColor(); + const bool scaled_dithering = (!m_true_color && upscaled && g_gpu_settings.IsUsingScaledDithering()); const bool scaled_interlacing = (upscaled && g_gpu_settings.gpu_scaled_interlacing); const bool disable_color_perspective = (features.noperspective_interpolation && ShouldDisableColorPerspective()); const bool needs_page_texture = m_use_texture_cache; @@ -1069,10 +1067,10 @@ bool GPU_HW::CompilePipelines(Error* error) // Abuse the depth buffer for the mask bit when it's free (FBFetch), or PGXP depth buffering is enabled. m_allow_shader_blend = features.framebuffer_fetch || ((features.feedback_loops || features.raster_order_views) && - (m_pgxp_depth_buffer || g_gpu_settings.IsUsingAccurateBlending() || + (m_pgxp_depth_buffer || g_gpu_settings.IsUsingShaderBlending() || (!m_supports_dual_source_blend && (IsBlendedTextureFiltering(m_texture_filtering) || IsBlendedTextureFiltering(m_sprite_texture_filtering))))); - m_prefer_shader_blend = (m_allow_shader_blend && g_gpu_settings.IsUsingAccurateBlending()); + m_prefer_shader_blend = (m_allow_shader_blend && g_gpu_settings.IsUsingShaderBlending()); m_use_rov_for_shader_blend = (m_allow_shader_blend && !features.framebuffer_fetch && features.raster_order_views && (m_prefer_shader_blend || !features.feedback_loops)); m_write_mask_as_depth = (!m_pgxp_depth_buffer && !features.framebuffer_fetch && !m_prefer_shader_blend); diff --git a/src/core/imgui_overlays.cpp b/src/core/imgui_overlays.cpp index 4eb33669b..4a842d1c6 100644 --- a/src/core/imgui_overlays.cpp +++ b/src/core/imgui_overlays.cpp @@ -508,8 +508,8 @@ void ImGuiManager::DrawEnhancementsOverlay(const GPUBackend* gpu) text.append_format(" {}x{}", g_gpu_settings.gpu_multisamples, g_gpu_settings.gpu_per_sample_shading ? "SSAA" : "MSAA"); } - if (g_gpu_settings.gpu_true_color) - text.append(" TrueCol"); + if (g_gpu_settings.gpu_dithering_mode != GPUDitheringMode::Unscaled) + text.append_format(" DT={}", Settings::GetGPUDitheringModeName(g_gpu_settings.gpu_dithering_mode)); text.append_format(" DI={}", Settings::GetDisplayDeinterlacingModeName(g_gpu_settings.display_deinterlacing_mode)); if (g_settings.gpu_force_video_timing == ForceVideoTimingMode::NTSC && System::GetRegion() == ConsoleRegion::PAL) text.append(" PAL60"); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 729a106bd..6e889af5d 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -229,11 +229,8 @@ void Settings::Load(const SettingsInterface& si, const SettingsInterface& contro gpu_use_thread = si.GetBoolValue("GPU", "UseThread", true); gpu_max_queued_frames = static_cast(si.GetUIntValue("GPU", "MaxQueuedFrames", DEFAULT_GPU_MAX_QUEUED_FRAMES)); gpu_use_software_renderer_for_readbacks = si.GetBoolValue("GPU", "UseSoftwareRendererForReadbacks", false); - gpu_true_color = si.GetBoolValue("GPU", "TrueColor", true); - gpu_scaled_dithering = si.GetBoolValue("GPU", "ScaledDithering", true); gpu_scaled_interlacing = si.GetBoolValue("GPU", "ScaledInterlacing", true); gpu_force_round_texcoords = si.GetBoolValue("GPU", "ForceRoundTextureCoordinates", false); - gpu_accurate_blending = si.GetBoolValue("GPU", "AccurateBlending", false); gpu_texture_filter = ParseTextureFilterName( si.GetStringValue("GPU", "TextureFilter", GetTextureFilterName(DEFAULT_GPU_TEXTURE_FILTER)).c_str()) @@ -242,6 +239,10 @@ void Settings::Load(const SettingsInterface& si, const SettingsInterface& contro ParseTextureFilterName( si.GetStringValue("GPU", "SpriteTextureFilter", GetTextureFilterName(DEFAULT_GPU_TEXTURE_FILTER)).c_str()) .value_or(DEFAULT_GPU_TEXTURE_FILTER); + gpu_dithering_mode = + ParseGPUDitheringModeName( + si.GetStringValue("GPU", "DitheringMode", GetGPUDitheringModeName(DEFAULT_GPU_DITHERING_MODE)).c_str()) + .value_or(DEFAULT_GPU_DITHERING_MODE); gpu_line_detect_mode = ParseLineDetectModeName( si.GetStringValue("GPU", "LineDetectMode", GetLineDetectModeName(DEFAULT_GPU_LINE_DETECT_MODE)).c_str()) @@ -587,13 +588,11 @@ void Settings::Save(SettingsInterface& si, bool ignore_base) const si.SetUIntValue("GPU", "MaxQueuedFrames", gpu_max_queued_frames); si.SetBoolValue("GPU", "UseThread", gpu_use_thread); si.SetBoolValue("GPU", "UseSoftwareRendererForReadbacks", gpu_use_software_renderer_for_readbacks); - si.SetBoolValue("GPU", "TrueColor", gpu_true_color); - si.SetBoolValue("GPU", "ScaledDithering", gpu_scaled_dithering); si.SetBoolValue("GPU", "ScaledInterlacing", gpu_scaled_interlacing); si.SetBoolValue("GPU", "ForceRoundTextureCoordinates", gpu_force_round_texcoords); - si.SetBoolValue("GPU", "AccurateBlending", gpu_accurate_blending); si.SetStringValue("GPU", "TextureFilter", GetTextureFilterName(gpu_texture_filter)); si.SetStringValue("GPU", "SpriteTextureFilter", GetTextureFilterName(gpu_sprite_texture_filter)); + si.SetStringValue("GPU", "DitheringMode", GetGPUDitheringModeName(gpu_dithering_mode)); si.SetStringValue("GPU", "LineDetectMode", GetLineDetectModeName(gpu_line_detect_mode)); si.SetStringValue("GPU", "DownsampleMode", GetDownsampleModeName(gpu_downsample_mode)); si.SetUIntValue("GPU", "DownsampleScale", gpu_downsample_scale); @@ -991,12 +990,11 @@ void Settings::FixIncompatibleSettings(const SettingsInterface& si, bool display g_settings.gpu_multisamples = 1; g_settings.gpu_automatic_resolution_scale = false; g_settings.gpu_per_sample_shading = false; - g_settings.gpu_true_color = false; - g_settings.gpu_scaled_dithering = false; g_settings.gpu_scaled_interlacing = false; g_settings.gpu_force_round_texcoords = false; g_settings.gpu_texture_filter = GPUTextureFilter::Nearest; g_settings.gpu_sprite_texture_filter = GPUTextureFilter::Nearest; + g_settings.gpu_dithering_mode = GPUDitheringMode::Unscaled; g_settings.gpu_line_detect_mode = GPULineDetectMode::Disabled; g_settings.gpu_force_video_timing = ForceVideoTimingMode::Disabled; g_settings.gpu_widescreen_hack = false; @@ -1558,6 +1556,44 @@ const char* Settings::GetTextureFilterDisplayName(GPUTextureFilter filter) "GPUTextureFilter"); } +static constexpr const std::array s_gpu_dithering_mode_names = { + "Unscaled", "UnscaledShaderBlend", "Scaled", "ScaledShaderBlend", "TrueColor", +}; +static constexpr const std::array s_gpu_dithering_mode_display_names = { + TRANSLATE_DISAMBIG_NOOP("Settings", "Unscaled", "GPUDitheringMode"), + TRANSLATE_DISAMBIG_NOOP("Settings", "Unscaled (Shader Blending)", "GPUDitheringMode"), + TRANSLATE_DISAMBIG_NOOP("Settings", "Scaled", "GPUDitheringMode"), + TRANSLATE_DISAMBIG_NOOP("Settings", "Scaled (Shader Blending)", "GPUDitheringMode"), + TRANSLATE_DISAMBIG_NOOP("Settings", "True Color", "GPUDitheringMode"), +}; +static_assert(s_gpu_dithering_mode_names.size() == static_cast(GPUDitheringMode::MaxCount)); +static_assert(s_gpu_dithering_mode_display_names.size() == static_cast(GPUDitheringMode::MaxCount)); + +std::optional Settings::ParseGPUDitheringModeName(const char* str) +{ + int index = 0; + for (const char* name : s_gpu_dithering_mode_names) + { + if (StringUtil::Strcasecmp(name, str) == 0) + return static_cast(index); + + index++; + } + + return std::nullopt; +} + +const char* Settings::GetGPUDitheringModeName(GPUDitheringMode mode) +{ + return s_gpu_dithering_mode_names[static_cast(mode)]; +} + +const char* Settings::GetGPUDitheringModeDisplayName(GPUDitheringMode mode) +{ + return Host::TranslateToCString("Settings", s_gpu_dithering_mode_display_names[static_cast(mode)], + "GPUDitheringMode"); +} + static constexpr const std::array s_line_detect_mode_names = { "Disabled", "Quads", diff --git a/src/core/settings.h b/src/core/settings.h index e47ab761f..71f289fef 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -69,6 +69,7 @@ struct GPUSettings ForceVideoTimingMode gpu_force_video_timing = DEFAULT_FORCE_VIDEO_TIMING_MODE; GPUTextureFilter gpu_texture_filter = DEFAULT_GPU_TEXTURE_FILTER; GPUTextureFilter gpu_sprite_texture_filter = DEFAULT_GPU_TEXTURE_FILTER; + GPUDitheringMode gpu_dithering_mode = DEFAULT_GPU_DITHERING_MODE; GPULineDetectMode gpu_line_detect_mode = DEFAULT_GPU_LINE_DETECT_MODE; GPUDownsampleMode gpu_downsample_mode = DEFAULT_GPU_DOWNSAMPLE_MODE; u8 gpu_downsample_scale = 1; @@ -104,11 +105,8 @@ struct GPUSettings bool gpu_disable_compressed_textures : 1 = false; bool gpu_automatic_resolution_scale : 1 = false; bool gpu_per_sample_shading : 1 = false; - bool gpu_true_color : 1 = true; - bool gpu_scaled_dithering : 1 = true; bool gpu_scaled_interlacing : 1 = true; bool gpu_force_round_texcoords : 1 = false; - bool gpu_accurate_blending : 1 = false; bool gpu_widescreen_hack : 1 = false; bool gpu_texture_cache : 1 = false; bool gpu_show_vram : 1 = false; @@ -214,7 +212,18 @@ struct GPUSettings void SetPGXPDepthClearThreshold(float value); ALWAYS_INLINE bool IsUsingSoftwareRenderer() const { return (gpu_renderer == GPURenderer::Software); } - ALWAYS_INLINE bool IsUsingAccurateBlending() const { return (gpu_accurate_blending && !gpu_true_color); } + ALWAYS_INLINE bool IsUsingTrueColor() const { return (gpu_dithering_mode == GPUDitheringMode::TrueColor); } + ALWAYS_INLINE bool IsUsingDithering() const { return (gpu_dithering_mode < GPUDitheringMode::TrueColor); } + ALWAYS_INLINE bool IsUsingShaderBlending() const + { + return (gpu_dithering_mode == GPUDitheringMode::UnscaledShaderBlend || + gpu_dithering_mode == GPUDitheringMode::ScaledShaderBlend); + } + ALWAYS_INLINE bool IsUsingScaledDithering() const + { + return (gpu_dithering_mode == GPUDitheringMode::Scaled || + gpu_dithering_mode == GPUDitheringMode::ScaledShaderBlend); + } ALWAYS_INLINE bool IsUsingIntegerDisplayScaling() const { return (display_scaling == DisplayScalingMode::NearestInteger || @@ -226,6 +235,7 @@ struct GPUSettings static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::Automatic; static constexpr GPUTextureFilter DEFAULT_GPU_TEXTURE_FILTER = GPUTextureFilter::Nearest; + static constexpr GPUDitheringMode DEFAULT_GPU_DITHERING_MODE = GPUDitheringMode::TrueColor; static constexpr GPULineDetectMode DEFAULT_GPU_LINE_DETECT_MODE = GPULineDetectMode::Disabled; static constexpr GPUDownsampleMode DEFAULT_GPU_DOWNSAMPLE_MODE = GPUDownsampleMode::Disabled; static constexpr GPUWireframeMode DEFAULT_GPU_WIREFRAME_MODE = GPUWireframeMode::Disabled; @@ -474,6 +484,10 @@ struct Settings : public GPUSettings static const char* GetTextureFilterName(GPUTextureFilter filter); static const char* GetTextureFilterDisplayName(GPUTextureFilter filter); + static std::optional ParseGPUDitheringModeName(const char* str); + static const char* GetGPUDitheringModeName(GPUDitheringMode mode); + static const char* GetGPUDitheringModeDisplayName(GPUDitheringMode mode); + static std::optional ParseLineDetectModeName(const char* str); static const char* GetLineDetectModeName(GPULineDetectMode filter); static const char* GetLineDetectModeDisplayName(GPULineDetectMode filter); diff --git a/src/core/system.cpp b/src/core/system.cpp index 5b69e87c1..8bc16268e 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -4471,13 +4471,11 @@ void System::CheckForSettingsChanges(const Settings& old_settings) g_settings.gpu_max_queued_frames != old_settings.gpu_max_queued_frames || g_settings.gpu_use_software_renderer_for_readbacks != old_settings.gpu_use_software_renderer_for_readbacks || - g_settings.gpu_true_color != old_settings.gpu_true_color || - g_settings.gpu_scaled_dithering != old_settings.gpu_scaled_dithering || g_settings.gpu_scaled_interlacing != old_settings.gpu_scaled_interlacing || g_settings.gpu_force_round_texcoords != old_settings.gpu_force_round_texcoords || - g_settings.gpu_accurate_blending != old_settings.gpu_accurate_blending || g_settings.gpu_texture_filter != old_settings.gpu_texture_filter || g_settings.gpu_sprite_texture_filter != old_settings.gpu_sprite_texture_filter || + g_settings.gpu_dithering_mode != old_settings.gpu_dithering_mode || g_settings.gpu_line_detect_mode != old_settings.gpu_line_detect_mode || g_settings.gpu_downsample_mode != old_settings.gpu_downsample_mode || g_settings.gpu_downsample_scale != old_settings.gpu_downsample_scale || @@ -4847,8 +4845,8 @@ void System::WarnAboutUnsafeSettings() APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Resolution scale set to 1x.")); if (g_settings.gpu_multisamples != 1) APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Multisample anti-aliasing disabled.")); - if (g_settings.gpu_true_color) - APPEND_SUBMESSAGE(TRANSLATE_SV("System", "True color disabled.")); + if (g_settings.gpu_dithering_mode != GPUDitheringMode::Unscaled) + APPEND_SUBMESSAGE(TRANSLATE_SV("System", "Dithering set to unscaled.")); if (g_settings.gpu_texture_filter != GPUTextureFilter::Nearest || g_settings.gpu_sprite_texture_filter != GPUTextureFilter::Nearest) { diff --git a/src/core/types.h b/src/core/types.h index b168d51b7..c20769e76 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -100,6 +100,17 @@ enum class GPUTextureFilter : u8 Count }; +enum class GPUDitheringMode : u8 +{ + Unscaled, + UnscaledShaderBlend, + Scaled, + ScaledShaderBlend, + TrueColor, + + MaxCount, +}; + enum class GPUDownsampleMode : u8 { Disabled, diff --git a/src/duckstation-qt/graphicssettingswidget.cpp b/src/duckstation-qt/graphicssettingswidget.cpp index b111eff7c..51275877e 100644 --- a/src/duckstation-qt/graphicssettingswidget.cpp +++ b/src/duckstation-qt/graphicssettingswidget.cpp @@ -64,6 +64,9 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget* SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.spriteTextureFiltering, "GPU", "SpriteTextureFilter", &Settings::ParseTextureFilterName, &Settings::GetTextureFilterName, Settings::DEFAULT_GPU_TEXTURE_FILTER); + SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuDitheringMode, "GPU", "DitheringMode", + &Settings::ParseGPUDitheringModeName, &Settings::GetGPUDitheringModeName, + Settings::DEFAULT_GPU_DITHERING_MODE); SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.gpuDownsampleMode, "GPU", "DownsampleMode", &Settings::ParseDownsampleModeName, &Settings::GetDownsampleModeName, Settings::DEFAULT_GPU_DOWNSAMPLE_MODE); @@ -85,7 +88,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget* &Settings::ParseDisplayScaling, &Settings::GetDisplayScalingName, Settings::DEFAULT_DISPLAY_SCALING); SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.gpuDownsampleScale, "GPU", "DownsampleScale", 1); - SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.trueColor, "GPU", "TrueColor", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpEnable, "GPU", "PGXPEnable", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.pgxpDepthBuffer, "GPU", "PGXPDepthBuffer", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.force43For24Bit, "Display", "Force4_3For24Bit", false); @@ -99,7 +101,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget* &GraphicsSettingsWidget::onAspectRatioChanged); connect(m_ui.gpuDownsampleMode, QOverload::of(&QComboBox::currentIndexChanged), this, &GraphicsSettingsWidget::onDownsampleModeChanged); - connect(m_ui.trueColor, &QCheckBox::checkStateChanged, this, &GraphicsSettingsWidget::onTrueColorChanged); connect(m_ui.pgxpEnable, &QCheckBox::checkStateChanged, this, &GraphicsSettingsWidget::updatePGXPSettingsEnabled); SettingWidgetBinder::SetAvailability(m_ui.renderer, @@ -110,7 +111,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget* !m_dialog->hasGameTrait(GameDatabase::Trait::DisableTextureFiltering)); SettingWidgetBinder::SetAvailability(m_ui.spriteTextureFiltering, !m_dialog->hasGameTrait(GameDatabase::Trait::DisableTextureFiltering)); - SettingWidgetBinder::SetAvailability(m_ui.trueColor, !m_dialog->hasGameTrait(GameDatabase::Trait::DisableTrueColor)); SettingWidgetBinder::SetAvailability(m_ui.pgxpEnable, !m_dialog->hasGameTrait(GameDatabase::Trait::DisablePGXP)); SettingWidgetBinder::SetAvailability(m_ui.widescreenHack, !m_dialog->hasGameTrait(GameDatabase::Trait::DisableWidescreen)); @@ -144,16 +144,12 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget* SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.maxQueuedFrames, "GPU", "MaxQueuedFrames", Settings::DEFAULT_GPU_MAX_QUEUED_FRAMES); connect(m_ui.gpuThread, &QCheckBox::checkStateChanged, this, &GraphicsSettingsWidget::onGPUThreadChanged); - SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.scaledDithering, "GPU", "ScaledDithering", true); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.scaledInterlacing, "GPU", "ScaledInterlacing", true); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useSoftwareRendererForReadbacks, "GPU", "UseSoftwareRendererForReadbacks", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.forceRoundedTexcoords, "GPU", "ForceRoundTextureCoordinates", false); - SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.accurateBlending, "GPU", "AccurateBlending", false); - SettingWidgetBinder::SetAvailability(m_ui.scaledDithering, - !m_dialog->hasGameTrait(GameDatabase::Trait::DisableScaledDithering)); SettingWidgetBinder::SetAvailability(m_ui.scaledInterlacing, !m_dialog->hasGameTrait(GameDatabase::Trait::DisableScaledInterlacing)); @@ -375,6 +371,13 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget* QString::fromUtf8(Settings::GetTextureFilterDisplayName(Settings::DEFAULT_GPU_TEXTURE_FILTER)), tr("Smooths out the blockiness of magnified textures on 2D objects by using filtering. This filter only applies to " "sprites and other 2D elements, such as the HUD.")); + dialog->registerWidgetHelp( + m_ui.gpuDitheringMode, tr("Dithering"), + QString::fromUtf8(Settings::GetGPUDitheringModeDisplayName(Settings::DEFAULT_GPU_DITHERING_MODE)), + tr("Controls how dithering is applied in the emulated GPU. True Color disables dithering and produces the nicest " + "looking gradients. Scaled options make the dither pattern less noticeable at higher resolutions. Shader " + "Blending options perform blending in software, and are more accurate but have a significant " + "performance penalty.")); dialog->registerWidgetHelp( m_ui.displayAspectRatio, tr("Aspect Ratio"), QString::fromUtf8(Settings::GetDisplayAspectRatioDisplayName(Settings::DEFAULT_DISPLAY_ASPECT_RATIO)), @@ -394,13 +397,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget* dialog->registerWidgetHelp( m_ui.displayScaling, tr("Scaling"), tr("Bilinear (Smooth)"), tr("Determines how the emulated console's output is upscaled or downscaled to your monitor's resolution.")); - dialog->registerWidgetHelp( - m_ui.trueColor, tr("True Color Rendering"), tr("Checked"), - tr("Forces the precision of colours output to the console's framebuffer to use the full 8 bits of precision per " - "channel. This produces nicer looking gradients at the cost of making some colours look slightly different. " - "Disabling the option also enables dithering, which makes the transition between colours less sharp by applying " - "a pattern around those pixels. Most games are compatible with this option, but there is a number which aren't " - "and will have broken effects with it enabled.")); dialog->registerWidgetHelp( m_ui.widescreenHack, tr("Widescreen Rendering"), tr("Unchecked"), tr("Scales vertex positions in screen-space to a widescreen aspect ratio, essentially " @@ -458,10 +454,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget* dialog->registerWidgetHelp(m_ui.gpuThread, tr("Threaded Rendering"), tr("Checked"), tr("Uses a second thread for drawing graphics. Provides a significant speed improvement " "particularly with the software renderer, and is safe to use.")); - dialog->registerWidgetHelp( - m_ui.scaledDithering, tr("Scaled Dithering"), tr("Checked"), - tr("Scales the dither pattern to the resolution scale of the emulated GPU. This makes the dither pattern much less " - "obvious at higher resolutions. Usually safe to enable.")); dialog->registerWidgetHelp(m_ui.scaledInterlacing, tr("Scaled Interlacing"), tr("Checked"), tr("Scales line skipping in interlaced rendering to the internal resolution. This makes " "the combing less obvious at higher resolutions. Usually safe to enable.")); @@ -473,10 +465,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget* m_ui.forceRoundedTexcoords, tr("Round Upscaled Texture Coordinates"), tr("Unchecked"), tr("Rounds texture coordinates instead of flooring when upscaling. Can fix misaligned textures in some games, but " "break others, and is incompatible with texture filtering.")); - dialog->registerWidgetHelp( - m_ui.accurateBlending, tr("Accurate Blending"), tr("Unchecked"), - tr("Forces blending to be done in the shader at 16-bit precision, when not using true color. Very few games " - "actually require this, and there is a non-trivial performance cost.")); // PGXP Tab @@ -692,6 +680,12 @@ void GraphicsSettingsWidget::setupAdditionalUi() QString::fromUtf8(Settings::GetTextureFilterDisplayName(static_cast(i)))); } + for (u32 i = 0; i < static_cast(GPUDitheringMode::MaxCount); i++) + { + m_ui.gpuDitheringMode->addItem( + QString::fromUtf8(Settings::GetGPUDitheringModeDisplayName(static_cast(i)))); + } + for (u32 i = 0; i < static_cast(GPUDownsampleMode::Count); i++) { m_ui.gpuDownsampleMode->addItem( @@ -836,18 +830,18 @@ void GraphicsSettingsWidget::updateRendererDependentOptions() m_ui.gpuDownsampleLabel->setEnabled(is_hardware); m_ui.gpuDownsampleMode->setEnabled(is_hardware); m_ui.gpuDownsampleScale->setEnabled(is_hardware); - m_ui.trueColor->setEnabled(is_hardware && !m_dialog->hasGameTrait(GameDatabase::Trait::DisableTrueColor)); + m_ui.gpuDitheringModeLabel->setEnabled(is_hardware); + m_ui.gpuDitheringMode->setEnabled(is_hardware); m_ui.pgxpEnable->setEnabled(is_hardware && !m_dialog->hasGameTrait(GameDatabase::Trait::DisablePGXP)); m_ui.gpuLineDetectMode->setEnabled(is_hardware); m_ui.gpuLineDetectModeLabel->setEnabled(is_hardware); m_ui.gpuWireframeMode->setEnabled(is_hardware); m_ui.gpuWireframeModeLabel->setEnabled(is_hardware); - m_ui.scaledDithering->setEnabled(is_hardware && !m_dialog->hasGameTrait(GameDatabase::Trait::DisableScaledDithering)); - m_ui.scaledInterlacing->setEnabled(is_hardware && !m_dialog->hasGameTrait(GameDatabase::Trait::DisableScaledInterlacing)); + m_ui.scaledInterlacing->setEnabled(is_hardware && + !m_dialog->hasGameTrait(GameDatabase::Trait::DisableScaledInterlacing)); m_ui.useSoftwareRendererForReadbacks->setEnabled(is_hardware); m_ui.forceRoundedTexcoords->setEnabled(is_hardware); - m_ui.accurateBlending->setEnabled(is_hardware); m_ui.tabs->setTabEnabled(TAB_INDEX_TEXTURE_REPLACEMENTS, is_hardware); @@ -878,7 +872,7 @@ void GraphicsSettingsWidget::populateGPUAdaptersAndResolutions(RenderAPI render_ { m_ui.adapter->disconnect(); m_ui.adapter->clear(); - m_ui.adapter->addItem(tr("(Default)"), QVariant(QString())); + m_ui.adapter->addItem(tr("Default"), QVariant(QString())); const std::string current_adapter_name = m_dialog->getEffectiveStringValue("GPU", "Adapter", ""); for (const GPUDevice::AdapterInfo& adapter : m_adapters) @@ -1079,18 +1073,6 @@ void GraphicsSettingsWidget::updateResolutionDependentOptions() .c_str()) .value_or(Settings::DEFAULT_GPU_TEXTURE_FILTER); m_ui.forceRoundedTexcoords->setEnabled(is_hardware && scale > 1 && texture_filtering == GPUTextureFilter::Nearest); - onTrueColorChanged(); -} - -void GraphicsSettingsWidget::onTrueColorChanged() -{ - const bool is_hardware = (getEffectiveRenderer() != GPURenderer::Software); - const int resolution_scale = m_dialog->getEffectiveIntValue("GPU", "ResolutionScale", 1); - const bool true_color = m_dialog->getEffectiveBoolValue("GPU", "TrueColor", false); - const bool allow_scaled_dithering = - (resolution_scale != 1 && !true_color && !m_dialog->hasGameTrait(GameDatabase::Trait::DisableScaledDithering)); - m_ui.scaledDithering->setEnabled(is_hardware && allow_scaled_dithering); - m_ui.accurateBlending->setEnabled(is_hardware && !true_color); } void GraphicsSettingsWidget::onDownsampleModeChanged() diff --git a/src/duckstation-qt/graphicssettingswidget.h b/src/duckstation-qt/graphicssettingswidget.h index d85cbcc2e..a42bfa16d 100644 --- a/src/duckstation-qt/graphicssettingswidget.h +++ b/src/duckstation-qt/graphicssettingswidget.h @@ -32,7 +32,6 @@ private Q_SLOTS: void onAspectRatioChanged(); void updateResolutionDependentOptions(); - void onTrueColorChanged(); void onDownsampleModeChanged(); void onMediaCaptureBackendChanged(); diff --git a/src/duckstation-qt/graphicssettingswidget.ui b/src/duckstation-qt/graphicssettingswidget.ui index 883a745c2..dca0a0134 100644 --- a/src/duckstation-qt/graphicssettingswidget.ui +++ b/src/duckstation-qt/graphicssettingswidget.ui @@ -7,7 +7,7 @@ 0 0 655 - 526 + 538 @@ -146,14 +146,14 @@ - + Aspect Ratio: - + @@ -187,6 +187,16 @@ + + + + Dithering: + + + + + + @@ -197,35 +207,28 @@ - + + + + Crop: - - - - + Scaling: - + - + - - - - Widescreen Rendering - - - @@ -233,6 +236,13 @@ + + + + PGXP Depth Buffer (Low Compatibility) + + + @@ -240,13 +250,6 @@ - - - - True Color Rendering - - - @@ -254,10 +257,10 @@ - - + + - PGXP Depth Buffer (Low Compatibility) + Widescreen Rendering @@ -411,24 +414,17 @@ - - - - Round Upscaled Texture Coordinates - - - - + - Scaled Dithering + Scaled Interlacing - + - Accurate Blending + Round Upscaled Texture Coordinates @@ -457,13 +453,6 @@ - - - - Scaled Interlacing - - - diff --git a/src/duckstation-qt/setupwizarddialog.cpp b/src/duckstation-qt/setupwizarddialog.cpp index cfe3702b9..536a3a574 100644 --- a/src/duckstation-qt/setupwizarddialog.cpp +++ b/src/duckstation-qt/setupwizarddialog.cpp @@ -554,6 +554,19 @@ void SetupWizardDialog::setupGraphicsPage(bool initial) &Settings::ParseTextureFilterName, &Settings::GetTextureFilterName, Settings::DEFAULT_GPU_TEXTURE_FILTER); + m_ui.gpuDitheringMode->disconnect(); + m_ui.gpuDitheringMode->clear(); + + for (u32 i = 0; i < static_cast(GPUDitheringMode::MaxCount); i++) + { + m_ui.gpuDitheringMode->addItem( + QString::fromUtf8(Settings::GetGPUDitheringModeDisplayName(static_cast(i)))); + } + + SettingWidgetBinder::BindWidgetToEnumSetting(nullptr, m_ui.gpuDitheringMode, "GPU", "DitheringMode", + &Settings::ParseGPUDitheringModeName, &Settings::GetGPUDitheringModeName, + Settings::DEFAULT_GPU_DITHERING_MODE); + m_ui.displayAspectRatio->disconnect(); m_ui.displayAspectRatio->clear(); diff --git a/src/duckstation-qt/setupwizarddialog.ui b/src/duckstation-qt/setupwizarddialog.ui index ce47b53a5..77be3d9ca 100644 --- a/src/duckstation-qt/setupwizarddialog.ui +++ b/src/duckstation-qt/setupwizarddialog.ui @@ -792,14 +792,14 @@ - + Aspect Ratio: - + @@ -833,27 +833,27 @@ - + Crop: - + - + Scaling: - + - + @@ -871,6 +871,16 @@ + + + + Dithering: + + + + + +