aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthexai <58434170+thexai@users.noreply.github.com>2020-10-31 08:38:42 +0100
committerthexai <58434170+thexai@users.noreply.github.com>2020-11-04 12:14:57 +0100
commit4033af79d7888b7801d27bd972a3b649a3022210 (patch)
treec24d730f7b313a22754748104b8967a502d666b6
parent50a89a7b208f15a653622811b833807ba2c29c8e (diff)
Tone mapping: Add new tone map methods "ACES Filmic" and "Hable"
-rw-r--r--addons/resource.language.en_gb/resources/strings.po14
-rw-r--r--system/keymaps/keyboard.xml1
-rw-r--r--system/shaders/output_d3d.fx103
-rw-r--r--xbmc/Application.cpp13
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp69
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h6
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp14
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h1
-rw-r--r--xbmc/cores/VideoSettings.h6
-rw-r--r--xbmc/input/actions/ActionIDs.h2
-rw-r--r--xbmc/input/actions/ActionTranslator.cpp3
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoSettings.cpp3
12 files changed, 195 insertions, 40 deletions
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
index 7241d0cc9f..2bce2babdc 100644
--- a/addons/resource.language.en_gb/resources/strings.po
+++ b/addons/resource.language.en_gb/resources/strings.po
@@ -20549,7 +20549,19 @@ msgctxt "#36556"
msgid "Tone mapping parameter"
msgstr ""
-#empty strings from id 36557 to 36559
+#. label of a setting, tone mapping method
+#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp
+msgctxt "#36557"
+msgid "ACES Filmic"
+msgstr ""
+
+#. label of a setting, tone mapping method
+#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp
+msgctxt "#36558"
+msgid "Hable"
+msgstr ""
+
+#empty string with id 36559
#: system/settings/settings.xml
msgctxt "#36560"
diff --git a/system/keymaps/keyboard.xml b/system/keymaps/keyboard.xml
index 5cb986f1b6..694b6b10cc 100644
--- a/system/keymaps/keyboard.xml
+++ b/system/keymaps/keyboard.xml
@@ -398,6 +398,7 @@
<minus mod="ctrl">VolAmpDown</minus>
<b mod="ctrl">CreateBookmark</b>
<b mod="alt">CreateEpisodeBookmark</b>
+ <f11 mod="alt">CycleToneMapMethod</f11>
</keyboard>
</FullscreenVideo>
<FullscreenGame>
diff --git a/system/shaders/output_d3d.fx b/system/shaders/output_d3d.fx
index 06233b692f..6a251b0723 100644
--- a/system/shaders/output_d3d.fx
+++ b/system/shaders/output_d3d.fx
@@ -41,58 +41,113 @@ SamplerState DitherSampler : IMMUTABLE
Filter = MIN_MAG_MIP_POINT;
};
#endif
-#if defined(KODI_TONE_MAPPING)
+#if (defined(KODI_TONE_MAPPING_ACES) || defined(KODI_TONE_MAPPING_HABLE) || defined(KODI_HLG_TO_PQ))
+const float ST2084_m1 = 2610.0f / (4096.0f * 4.0f);
+const float ST2084_m2 = (2523.0f / 4096.0f) * 128.0f;
+const float ST2084_c1 = 3424.0f / 4096.0f;
+const float ST2084_c2 = (2413.0f / 4096.0f) * 32.0f;
+const float ST2084_c3 = (2392.0f / 4096.0f) * 32.0f;
+#endif
+#if defined(KODI_TONE_MAPPING_REINHARD)
float g_toneP1;
float3 g_coefsDst;
+float g_luminance;
+
+float reinhard(float x)
+{
+ return x * (1.0f + x / (g_toneP1 * g_toneP1)) / (1.0f + x);
+}
+#endif
+#if defined(KODI_TONE_MAPPING_ACES)
+float g_luminance;
+float g_toneP1;
-float tonemap(float val)
+float3 aces(float3 x)
{
- return val * (1 + val/(g_toneP1*g_toneP1))/(1 + val);
+ const float A = 2.51f;
+ const float B = 0.03f;
+ const float C = 2.43f;
+ const float D = 0.59f;
+ const float E = 0.14f;
+ return (x * (A * x + B)) / (x * (C * x + D) + E);
+}
+#endif
+#if defined(KODI_TONE_MAPPING_HABLE)
+float g_luminance;
+float g_toneP1;
+
+float3 hable(float3 x)
+{
+ const float A = 0.15f;
+ const float B = 0.5f;
+ const float C = 0.1f;
+ const float D = 0.2f;
+ const float E = 0.02f;
+ const float F = 0.3f;
+ return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;
+}
+#endif
+#if (defined(KODI_TONE_MAPPING_ACES) || defined(KODI_TONE_MAPPING_HABLE))
+float3 inversePQ(float3 x)
+{
+ x = pow(max(x, 0.0f), 1.0f / ST2084_m2);
+ x = max(x - ST2084_c1, 0.0f) / (ST2084_c2 - ST2084_c3 * x);
+ x = pow(x, 1.0f / ST2084_m1);
+ return x;
}
#endif
#if defined(KODI_HLG_TO_PQ)
float inverseHLG(float x)
{
- const float B67_a = 0.17883277;
- const float B67_b = 0.28466892;
- const float B67_c = 0.55991073;
- const float B67_inv_r2 = 4.0;
- if (x <= 0.5)
+ const float B67_a = 0.17883277f;
+ const float B67_b = 0.28466892f;
+ const float B67_c = 0.55991073f;
+ const float B67_inv_r2 = 4.0f;
+ if (x <= 0.5f)
x = x * x * B67_inv_r2;
else
x = exp((x - B67_c) / B67_a) + B67_b;
return x;
}
-float4 tranferPQ(float4 color)
+float3 tranferPQ(float3 x)
{
- const float ST2084_m1 = 2610.0 / (4096.0 * 4.0);
- const float ST2084_m2 = (2523.0 / 4096.0) * 128.0;
- const float ST2084_c1 = 3424.0 / 4096.0;
- const float ST2084_c2 = (2413.0 / 4096.0) * 32.0;
- const float ST2084_c3 = (2392.0 / 4096.0) * 32.0;
- color = pow(color / 1000.0, ST2084_m1);
- color = (ST2084_c1 + ST2084_c2 * color) / (1 + ST2084_c3 * color);
- color = pow(color, ST2084_m2);
- return color;
+ x = pow(x / 1000.0f, ST2084_m1);
+ x = (ST2084_c1 + ST2084_c2 * x) / (1.0f + ST2084_c3 * x);
+ x = pow(x, ST2084_m2);
+ return x;
}
#endif
float4 output4(float4 color, float2 uv)
{
-#if defined(KODI_TONE_MAPPING)
+#if defined(KODI_TONE_MAPPING_REINHARD)
float luma = dot(color.rgb, g_coefsDst);
- color.rgb *= tonemap(luma) / luma;
+ color.rgb *= reinhard(luma) / luma;
+#endif
+#if defined(KODI_TONE_MAPPING_ACES)
+ color.rgb = inversePQ(color.rgb);
+ color.rgb *= (10000.0f / g_luminance) * (2.0f / g_toneP1);
+ color.rgb = aces(color.rgb);
+ color.rgb *= (1.24f / g_toneP1);
+ color.rgb = pow(color.rgb, 0.27f);
+#endif
+#if defined(KODI_TONE_MAPPING_HABLE)
+ color.rgb = inversePQ(color.rgb);
+ color.rgb *= g_toneP1;
+ float wp = g_luminance / 100.0f;
+ color.rgb = hable(color.rgb * wp) / hable(wp);
+ color.rgb = pow(color.rgb, 1.0f / 2.2f);
#endif
#if defined(KODI_HLG_TO_PQ)
color.r = inverseHLG(color.r);
color.g = inverseHLG(color.g);
color.b = inverseHLG(color.b);
- float3 ootf_2020 = float3(0.2627, 0.6780, 0.0593);
- float ootf_ys = 2000.0 * dot(ootf_2020, color);
- color = color * pow(ootf_ys, 0.200);
- color = tranferPQ(color);
+ float3 ootf_2020 = float3(0.2627f, 0.6780f, 0.0593f);
+ float ootf_ys = 2000.0f * dot(ootf_2020, color.rgb);
+ color.rgb *= pow(ootf_ys, 0.2f);
+ color.rgb = tranferPQ(color.rgb);
#endif
#if defined(KODI_3DLUT)
half3 scale = m_LUTParams.x;
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
index f14d1c3627..fb4978c27c 100644
--- a/xbmc/Application.cpp
+++ b/xbmc/Application.cpp
@@ -1659,6 +1659,19 @@ bool CApplication::OnAction(const CAction &action)
}
return true;
}
+ // Tone Mapping : switch to next tone map method
+ if (action.GetID() == ACTION_CYCLE_TONEMAP_METHOD)
+ {
+ if (m_appPlayer.IsPlayingVideo())
+ {
+ CVideoSettings vs = m_appPlayer.GetVideoSettings();
+ vs.m_ToneMapMethod++;
+ if (vs.m_ToneMapMethod >= VS_TONEMAPMETHOD_MAX)
+ vs.m_ToneMapMethod = VS_TONEMAPMETHOD_OFF + 1;
+ m_appPlayer.SetVideoSettings(vs);
+ }
+ return true;
+ }
// built in functions : execute the built-in
if (action.GetID() == ACTION_BUILT_IN_FUNCTION)
{
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp
index 95de271561..3c2d472ab8 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp
@@ -185,7 +185,7 @@ void COutputShader::ApplyEffectParameters(CD3DEffect &effect, unsigned sourceWid
effect.SetResources("m_ditherMatrix", m_pDitherView.GetAddressOf(), 1);
effect.SetFloatArray("m_ditherParams", ditherParams, 3);
}
- if (m_toneMapping)
+ if (m_toneMapping && m_toneMappingMethod == VS_TONEMAPMETHOD_REINHARD)
{
const float def_param = log10(100.0f) / log10(600.0f); // 600 nits --> 0.72
float param = def_param;
@@ -208,6 +208,49 @@ void COutputShader::ApplyEffectParameters(CD3DEffect &effect, unsigned sourceWid
effect.SetScalar("g_toneP1", param);
effect.SetFloatArray("g_coefsDst", coefs, 3);
}
+ else if (m_toneMapping && m_toneMappingMethod == VS_TONEMAPMETHOD_ACES)
+ {
+ effect.SetScalar("g_luminance", GetLuminanceValue());
+ effect.SetScalar("g_toneP1", m_toneMappingParam);
+ }
+ else if (m_toneMapping && m_toneMappingMethod == VS_TONEMAPMETHOD_HABLE)
+ {
+ float lumin = GetLuminanceValue();
+ float param = (10000.0f / lumin) * (2.0f / m_toneMappingParam);
+ effect.SetScalar("g_luminance", lumin);
+ effect.SetScalar("g_toneP1", param);
+ }
+}
+
+float COutputShader::GetLuminanceValue() const
+{
+ float lum1 = 400.0f; // default for bad quality HDR-PQ sources (with no metadata)
+ float lum2 = lum1;
+ float lum3 = lum1;
+
+ if (m_hasLightMetadata)
+ {
+ uint16_t lum = m_displayMetadata.max_luminance.num / m_displayMetadata.max_luminance.den;
+ if (m_lightMetadata.MaxCLL >= lum)
+ {
+ lum1 = static_cast<float>(lum);
+ lum2 = static_cast<float>(m_lightMetadata.MaxCLL);
+ }
+ else
+ {
+ lum1 = static_cast<float>(m_lightMetadata.MaxCLL);
+ lum2 = static_cast<float>(lum);
+ }
+ lum3 = static_cast<float>(m_lightMetadata.MaxFALL);
+ lum1 = (lum1 * 0.5f) + (lum2 * 0.2f) + (lum3 * 0.3f);
+ }
+ else if (m_hasDisplayMetadata && m_displayMetadata.has_luminance)
+ {
+ uint16_t lum = m_displayMetadata.max_luminance.num / m_displayMetadata.max_luminance.den;
+ lum1 = static_cast<float>(lum);
+ }
+
+ return lum1;
}
void COutputShader::GetDefines(DefinesMap& map) const
@@ -220,9 +263,17 @@ void COutputShader::GetDefines(DefinesMap& map) const
{
map["KODI_DITHER"] = "";
}
- if (m_toneMapping)
+ if (m_toneMapping && m_toneMappingMethod == VS_TONEMAPMETHOD_REINHARD)
{
- map["KODI_TONE_MAPPING"] = "";
+ map["KODI_TONE_MAPPING_REINHARD"] = "";
+ }
+ else if (m_toneMapping && m_toneMappingMethod == VS_TONEMAPMETHOD_ACES)
+ {
+ map["KODI_TONE_MAPPING_ACES"] = "";
+ }
+ else if (m_toneMapping && m_toneMappingMethod == VS_TONEMAPMETHOD_HABLE)
+ {
+ map["KODI_TONE_MAPPING_HABLE"] = "";
}
if (m_useHLGtoPQ)
{
@@ -230,12 +281,14 @@ void COutputShader::GetDefines(DefinesMap& map) const
}
}
-bool COutputShader::Create(bool useLUT, bool useDithering, int ditherDepth, bool toneMapping, bool HLGtoPQ)
+bool COutputShader::Create(
+ bool useLUT, bool useDithering, int ditherDepth, bool toneMapping, int toneMethod, bool HLGtoPQ)
{
m_useLut = useLUT;
m_ditherDepth = ditherDepth;
- m_toneMapping = toneMapping && !DX::Windowing()->IsHDROutput();
+ m_toneMapping = toneMapping;
m_useHLGtoPQ = HLGtoPQ;
+ m_toneMappingMethod = toneMethod;
CWinShader::CreateVertexBuffer(4, sizeof(Vertex));
@@ -298,6 +351,12 @@ void COutputShader::SetDisplayMetadata(bool hasDisplayMetadata, AVMasteringDispl
m_lightMetadata = lightMetadata;
}
+void COutputShader::SetToneMapParam(int method, float param)
+{
+ m_toneMappingMethod = method;
+ m_toneMappingParam = param;
+}
+
bool COutputShader::CreateLUTView(int lutSize, uint16_t* lutData, bool isRGB, ID3D11ShaderResourceView** ppLUTView)
{
if (!lutSize || !lutData)
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h
index 5ab850aafa..2864d8310f 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h
@@ -60,7 +60,7 @@ public:
void ApplyEffectParameters(CD3DEffect &effect, unsigned sourceWidth, unsigned sourceHeight);
void GetDefines(DefinesMap &map) const;
- bool Create(bool useLUT, bool useDithering, int ditherDepth, bool toneMapping, bool HLGtoPQ);
+ bool Create(bool useLUT, bool useDithering, int ditherDepth, bool toneMapping, int toneMethod, bool HLGtoPQ);
void Render(CD3DTexture& sourceTexture, CRect sourceRect, const CPoint points[4]
, CD3DTexture& target, unsigned range = 0, float contrast = 0.5f, float brightness = 0.5f);
void Render(CD3DTexture& sourceTexture, CRect sourceRect, CRect destRect
@@ -68,7 +68,7 @@ public:
void SetLUT(int lutSize, ID3D11ShaderResourceView *pLUTView);
void SetDisplayMetadata(bool hasDisplayMetadata, AVMasteringDisplayMetadata displayMetadata,
bool hasLightMetadata, AVContentLightMetadata lightMetadata);
- void SetToneMapParam(float param) { m_toneMappingParam = param; }
+ void SetToneMapParam(int method, float param);
static bool CreateLUTView(int lutSize, uint16_t* lutData, bool isRGB, ID3D11ShaderResourceView** ppLUTView);
@@ -83,6 +83,7 @@ private:
void PrepareParameters(unsigned sourceWidth, unsigned sourceHeight, CRect sourceRect, const CPoint points[4]);
void SetShaderParameters(CD3DTexture &sourceTexture, unsigned range, float contrast, float brightness);
void CreateDitherView();
+ float GetLuminanceValue() const;
bool m_useLut = false;
bool m_useDithering = false;
@@ -95,6 +96,7 @@ private:
unsigned m_sourceHeight = 0;
int m_lutSize = 0;
int m_ditherDepth = 0;
+ int m_toneMappingMethod = VS_TONEMAPMETHOD_REINHARD;
float m_toneMappingParam = 1.0f;
CRect m_sourceRect = {};
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp
index 0dbec67ac9..b888859b43 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp
@@ -247,7 +247,7 @@ void CRendererBase::Render(CD3DTexture& target, const CRect& sourceRect, const C
if (UseToneMapping())
{
m_outputShader->SetDisplayMetadata(buf->hasDisplayMetadata, buf->displayMetadata, buf->hasLightMetadata, buf->lightMetadata);
- m_outputShader->SetToneMapParam(m_videoSettings.m_ToneMapParam);
+ m_outputShader->SetToneMapParam(m_toneMapMethod, m_videoSettings.m_ToneMapParam);
}
FinalOutput(m_IntermediateTarget, target, source, dest);
@@ -407,7 +407,8 @@ void CRendererBase::UpdateVideoFilters()
if (!m_outputShader)
{
m_outputShader = std::make_shared<COutputShader>();
- if (!m_outputShader->Create(m_cmsOn, m_useDithering, m_ditherDepth, UseToneMapping(), m_useHLGtoPQ))
+ if (!m_outputShader->Create(m_cmsOn, m_useDithering, m_ditherDepth, m_toneMapping,
+ m_toneMapMethod, m_useHLGtoPQ))
{
CLog::LogF(LOGDEBUG, "unable to create output shader.");
m_outputShader.reset();
@@ -422,20 +423,21 @@ void CRendererBase::UpdateVideoFilters()
void CRendererBase::CheckVideoParameters()
{
CRenderBuffer* buf = m_renderBuffers[m_iBufferIndex];
+ int method = m_videoSettings.m_ToneMapMethod;
bool isHDRPQ = (buf->color_transfer == AVCOL_TRC_SMPTE2084 && buf->primaries == AVCOL_PRI_BT2020);
- // HDR_TYPE::HDR_NONE_SDR is equivalent to !DX::Windowing()->IsHDROutput() using local variable
- bool toneMap = (isHDRPQ && m_HdrType == HDR_TYPE::HDR_NONE_SDR &&
- m_videoSettings.m_ToneMapMethod != VS_TONEMAPMETHOD_OFF);
+ bool toneMap = (isHDRPQ && m_HdrType == HDR_TYPE::HDR_NONE_SDR && method != VS_TONEMAPMETHOD_OFF);
bool hlg = (m_HdrType == HDR_TYPE::HDR_HLG);
- if (toneMap != m_toneMapping || m_cmsOn != m_colorManager->IsEnabled() || hlg != m_useHLGtoPQ)
+ if (toneMap != m_toneMapping || m_cmsOn != m_colorManager->IsEnabled() || hlg != m_useHLGtoPQ ||
+ method != m_toneMapMethod)
{
m_toneMapping = toneMap;
m_cmsOn = m_colorManager->IsEnabled();
m_useHLGtoPQ = hlg;
+ m_toneMapMethod = method;
m_outputShader.reset();
OnOutputReset();
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h
index 3dc074c385..c7a1ff8ac2 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h
@@ -158,6 +158,7 @@ protected:
bool m_cmsOn = false;
bool m_clutLoaded = false;
bool m_useHLGtoPQ = false;
+ int m_toneMapMethod = 0;
int m_iBufferIndex = 0;
int m_iNumBuffers = 0;
diff --git a/xbmc/cores/VideoSettings.h b/xbmc/cores/VideoSettings.h
index 687c84a530..ba7efeb797 100644
--- a/xbmc/cores/VideoSettings.h
+++ b/xbmc/cores/VideoSettings.h
@@ -60,8 +60,10 @@ enum ESCALINGMETHOD
enum ETONEMAPMETHOD
{
- VS_TONEMAPMETHOD_OFF=0,
- VS_TONEMAPMETHOD_REINHARD,
+ VS_TONEMAPMETHOD_OFF = 0,
+ VS_TONEMAPMETHOD_REINHARD = 1,
+ VS_TONEMAPMETHOD_ACES = 2,
+ VS_TONEMAPMETHOD_HABLE = 3,
VS_TONEMAPMETHOD_MAX
};
diff --git a/xbmc/input/actions/ActionIDs.h b/xbmc/input/actions/ActionIDs.h
index 0a3ffd37cf..01233668f9 100644
--- a/xbmc/input/actions/ActionIDs.h
+++ b/xbmc/input/actions/ActionIDs.h
@@ -430,6 +430,8 @@
#define ACTION_HDR_TOGGLE 260 //!< Toggle display HDR on/off
+#define ACTION_CYCLE_TONEMAP_METHOD 261 //!< Switch to next tonemap method
+
// Voice actions
#define ACTION_VOICE_RECOGNIZE 300
diff --git a/xbmc/input/actions/ActionTranslator.cpp b/xbmc/input/actions/ActionTranslator.cpp
index 877bd3b9ab..774d225d6e 100644
--- a/xbmc/input/actions/ActionTranslator.cpp
+++ b/xbmc/input/actions/ActionTranslator.cpp
@@ -204,6 +204,9 @@ static const std::map<ActionName, ActionID> ActionMappings = {
// HDR display support
{"hdrtoggle", ACTION_HDR_TOGGLE},
+ // Tone mapping
+ {"cycletonemapmethod", ACTION_CYCLE_TONEMAP_METHOD},
+
// PVR actions
{"channelup", ACTION_CHANNEL_UP},
{"channeldown", ACTION_CHANNEL_DOWN},
diff --git a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp
index 3eb6957b4d..e3f99a54d4 100644
--- a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp
@@ -412,6 +412,9 @@ void CGUIDialogVideoSettings::InitializeSettings()
entries.clear();
entries.push_back(TranslatableIntegerSettingOption(36554, VS_TONEMAPMETHOD_OFF));
entries.push_back(TranslatableIntegerSettingOption(36555, VS_TONEMAPMETHOD_REINHARD));
+ entries.push_back(TranslatableIntegerSettingOption(36557, VS_TONEMAPMETHOD_ACES));
+ entries.push_back(TranslatableIntegerSettingOption(36558, VS_TONEMAPMETHOD_HABLE));
+
AddSpinner(groupVideo, SETTING_VIDEO_TONEMAP_METHOD, 36553, SettingLevel::Basic,
videoSettings.m_ToneMapMethod, entries, false, visible);
AddSlider(groupVideo, SETTING_VIDEO_TONEMAP_PARAM, 36556, SettingLevel::Basic,