Add Use Display Peak Luminance

If checked, display peak will always be used. Works even across different devices if ini is saved on the cloud. Or game is changed between different displays.
This commit is contained in:
jasaaved 2026-03-19 02:08:24 -07:00
parent 077969b97e
commit fff8338c8b
4 changed files with 46 additions and 5 deletions

View File

@ -3,6 +3,11 @@
/*
[configuration]
[OptionBool]
GUIName = Use Display Peak Luminance
OptionName = USE_DISPLAY_PEAK_LUMINANCE
DefaultValue = 0
[OptionRangeFloat]
GUIName = HDR Display Max Nits
OptionName = HDR_DISPLAY_MAX_NITS
@ -54,7 +59,13 @@ void main()
// Find the color luminance (it works better than average)
float sdr_ratio = luminance(color.rgb);
const float auto_hdr_max_white = max(HDR_DISPLAY_MAX_NITS / (hdr_paper_white_nits / hdr_sdr_white_nits), hdr_sdr_white_nits) / hdr_sdr_white_nits;
// When "Use Display Peak Luminance" is enabled, use the peak luminance reported by the display
// (only available on DirectX 11/12). Falls back to the manual slider on other APIs or if
// no display data is available.
const float display_max_nits = (OptionEnabled(USE_DISPLAY_PEAK_LUMINANCE) && hdr_max_luminance_nits > 0.0)
? hdr_max_luminance_nits
: HDR_DISPLAY_MAX_NITS;
const float auto_hdr_max_white = max(display_max_nits / (hdr_paper_white_nits / hdr_sdr_white_nits), hdr_sdr_white_nits) / hdr_sdr_white_nits;
if (sdr_ratio > AUTO_HDR_SHOULDER_START_ALPHA && AUTO_HDR_SHOULDER_START_ALPHA < 1.0)
{
const float auto_hdr_shoulder_ratio = 1.0 - (max(1.0 - sdr_ratio, 0.0) / (1.0 - AUTO_HDR_SHOULDER_START_ALPHA));

View File

@ -120,6 +120,12 @@ void PostProcessingConfigWindow::Create()
m_tabs->insertTab(0, general, tr("General"));
}
// Apply initial enabled state for options controlled by USE_DISPLAY_PEAK_LUMINANCE
const auto use_peak_it = m_config_map.find("USE_DISPLAY_PEAK_LUMINANCE");
const auto max_nits_it = m_config_map.find("HDR_DISPLAY_MAX_NITS");
if (use_peak_it != m_config_map.end() && max_nits_it != m_config_map.end())
max_nits_it->second->SetEnabled(!use_peak_it->second->GetCheckboxValue());
m_buttons = new QDialogButtonBox(QDialogButtonBox::Ok);
auto* layout = new QVBoxLayout(this);
@ -150,8 +156,16 @@ PostProcessingConfigWindow::CreateDependentTab(const std::unique_ptr<ConfigGroup
void PostProcessingConfigWindow::UpdateBool(ConfigGroup* const config_group, const bool state)
{
m_post_processor->SetOptionb(config_group->GetOptionName(), state);
m_post_processor->SaveOptionsConfiguration();
config_group->EnableSuboptions(state);
if (config_group->GetOptionName() == "USE_DISPLAY_PEAK_LUMINANCE")
{
const auto it = m_config_map.find("HDR_DISPLAY_MAX_NITS");
if (it != m_config_map.end())
it->second->SetEnabled(!state);
}
}
void PostProcessingConfigWindow::UpdateInteger(ConfigGroup* const config_group, const int value)
@ -346,6 +360,14 @@ u32 PostProcessingConfigWindow::ConfigGroup::AddFloat(PostProcessingConfigWindow
return row + 1;
}
void PostProcessingConfigWindow::ConfigGroup::SetEnabled(const bool state)
{
for (auto& slider : m_sliders)
slider->setEnabled(state);
for (auto& value_box : m_value_boxes)
value_box->setEnabled(state);
}
void PostProcessingConfigWindow::ConfigGroup::EnableSuboptions(const bool state)
{
for (auto& it : m_subgroups)

View File

@ -46,6 +46,7 @@ private:
const std::vector<std::unique_ptr<ConfigGroup>>& GetSubGroups() const noexcept;
u32 AddWidgets(PostProcessingConfigWindow* parent, QGridLayout* grid, u32 row);
void EnableSuboptions(bool state);
void SetEnabled(bool state);
int GetCheckboxValue() const;
int GetSliderValue(size_t index) const;
void SetSliderText(size_t index, const QString& text);

View File

@ -259,7 +259,6 @@ void PostProcessingConfiguration::LoadOptionsConfiguration()
Common::IniFile ini;
ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX));
std::string section = m_current_shader + "-options";
bool needs_save = false;
// We already expect all the options to be marked as "dirty" when we reach here
for (auto& it : m_options)
@ -305,15 +304,23 @@ void PostProcessingConfiguration::LoadOptionsConfiguration()
queried_value.imbue(std::locale("C"));
queried_value << g_backend_info.hdr_max_luminance_nits;
ini.GetOrCreateSection(section)->Set(it.second.m_option_name, queried_value.str());
needs_save = true;
ini.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX));
}
}
break;
}
}
if (needs_save)
ini.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX));
// If USE_DISPLAY_PEAK_LUMINANCE is checked and we have queried data, sync the slider to the
// queried value so it reflects what the shader is actually using.
const auto use_display_peak = m_options.find("USE_DISPLAY_PEAK_LUMINANCE");
const auto max_nits_option = m_options.find("HDR_DISPLAY_MAX_NITS");
if (use_display_peak != m_options.end() && max_nits_option != m_options.end() &&
use_display_peak->second.m_bool_value && g_backend_info.hdr_max_luminance_nits > 0.f)
{
max_nits_option->second.m_float_values[0] = g_backend_info.hdr_max_luminance_nits;
max_nits_option->second.m_dirty = true;
}
}
void PostProcessingConfiguration::SaveOptionsConfiguration()