From 524a7d066bb4542e94824c832779f74c743d3e93 Mon Sep 17 00:00:00 2001 From: clsid2 <4704996+clsid2@users.noreply.github.com> Date: Tue, 14 May 2024 14:39:00 +0200 Subject: [PATCH] Add "SDR Display nits" setting for tonemapping HDR to SDR. --- Shaders/d3d11/ps_convert_pq_to_sdr.hlsl | 10 ++++---- Shaders/d3d11/ps_fixconvert_pq_to_sdr.hlsl | 10 ++++---- Shaders/d3d9/fixconvert_hlg_to_sdr.hlsl | 6 ++--- Shaders/d3d9/fixconvert_pq_to_sdr.hlsl | 6 ++--- Source/DX11VideoProcessor.cpp | 20 ++++++++++++---- Source/DX11VideoProcessor.h | 2 ++ Source/DX9VideoProcessor.cpp | 14 +++++++++-- Source/IVideoRenderer.h | 2 ++ Source/MpcVideoRenderer.rc | 15 +++++++----- Source/PropPage.cpp | 28 +++++++++++++++++++--- Source/Shaders.cpp | 10 ++++---- Source/Shaders.h | 1 + Source/VideoProcessor.h | 1 + Source/VideoRenderer.cpp | 5 ++++ Source/resource.h | 6 +++-- 15 files changed, 98 insertions(+), 38 deletions(-) diff --git a/Shaders/d3d11/ps_convert_pq_to_sdr.hlsl b/Shaders/d3d11/ps_convert_pq_to_sdr.hlsl index dca2ed26..fb7d2847 100644 --- a/Shaders/d3d11/ps_convert_pq_to_sdr.hlsl +++ b/Shaders/d3d11/ps_convert_pq_to_sdr.hlsl @@ -1,14 +1,16 @@ Texture2D tex : register(t0); SamplerState samp : register(s0); +cbuffer PS_COLOR_TRANSFORM : register(b0) +{ + float LuminanceScale; +}; + #include "../convert/conv_matrix.hlsl" #include "../convert/st2084.hlsl" #include "../convert/hdr_tone_mapping.hlsl" #include "../convert/colorspace_gamut_conversion.hlsl" -#define SRC_LUMINANCE_PEAK 10000.0 -#define DISPLAY_LUMINANCE_PEAK 125.0 - struct PS_INPUT { float4 Pos : SV_POSITION; @@ -21,7 +23,7 @@ float4 main(PS_INPUT input) : SV_Target // PQ to Linear color = saturate(color); - color = ST2084ToLinear(color, SRC_LUMINANCE_PEAK/DISPLAY_LUMINANCE_PEAK); + color = ST2084ToLinear(color, LuminanceScale); color.rgb = ToneMappingHable(color.rgb); color.rgb = Colorspace_Gamut_Conversion_2020_to_709(color.rgb); diff --git a/Shaders/d3d11/ps_fixconvert_pq_to_sdr.hlsl b/Shaders/d3d11/ps_fixconvert_pq_to_sdr.hlsl index c85b7bf9..9b4eefc9 100644 --- a/Shaders/d3d11/ps_fixconvert_pq_to_sdr.hlsl +++ b/Shaders/d3d11/ps_fixconvert_pq_to_sdr.hlsl @@ -1,6 +1,11 @@ Texture2D tex : register(t0); SamplerState samp : register(s0); +cbuffer PS_COLOR_TRANSFORM : register(b0) +{ + float LuminanceScale; +}; + #include "../convert/conv_matrix.hlsl" #include "../convert/st2084.hlsl" #include "../convert/hdr_tone_mapping.hlsl" @@ -8,9 +13,6 @@ SamplerState samp : register(s0); static const float4x4 fix_bt2020_matrix = mul(ycbcr2020nc_rgb, rgb_ycbcr709); -#define SRC_LUMINANCE_PEAK 10000.0 -#define DISPLAY_LUMINANCE_PEAK 125.0 - struct PS_INPUT { float4 Pos : SV_POSITION; @@ -26,7 +28,7 @@ float4 main(PS_INPUT input) : SV_Target // PQ to Linear color = saturate(color); - color = ST2084ToLinear(color, SRC_LUMINANCE_PEAK/DISPLAY_LUMINANCE_PEAK); + color = ST2084ToLinear(color, LuminanceScale); color.rgb = ToneMappingHable(color.rgb); color.rgb = Colorspace_Gamut_Conversion_2020_to_709(color.rgb); diff --git a/Shaders/d3d9/fixconvert_hlg_to_sdr.hlsl b/Shaders/d3d9/fixconvert_hlg_to_sdr.hlsl index f93e4291..06bd74f2 100644 --- a/Shaders/d3d9/fixconvert_hlg_to_sdr.hlsl +++ b/Shaders/d3d9/fixconvert_hlg_to_sdr.hlsl @@ -1,4 +1,5 @@ sampler s0 : register(s0); +float LuminanceScale : register(c0); #include "../convert/conv_matrix.hlsl" #include "../convert/hlg.hlsl" @@ -8,9 +9,6 @@ sampler s0 : register(s0); static const float4x4 fix_bt2020_matrix = mul(ycbcr2020nc_rgb, rgb_ycbcr709); -#define SRC_LUMINANCE_PEAK 10000.0 -#define DISPLAY_LUMINANCE_PEAK 125.0 - float4 main(float2 tex : TEXCOORD0) : COLOR { float4 color = tex2D(s0, tex); // original pixel @@ -25,7 +23,7 @@ float4 main(float2 tex : TEXCOORD0) : COLOR // PQ to Linear color = saturate(color); - color = ST2084ToLinear(color, SRC_LUMINANCE_PEAK/DISPLAY_LUMINANCE_PEAK); + color = ST2084ToLinear(color, LuminanceScale); color.rgb = ToneMappingHable(color.rgb); color.rgb = Colorspace_Gamut_Conversion_2020_to_709(color.rgb); diff --git a/Shaders/d3d9/fixconvert_pq_to_sdr.hlsl b/Shaders/d3d9/fixconvert_pq_to_sdr.hlsl index 77e7be12..53877ec7 100644 --- a/Shaders/d3d9/fixconvert_pq_to_sdr.hlsl +++ b/Shaders/d3d9/fixconvert_pq_to_sdr.hlsl @@ -1,4 +1,5 @@ sampler s0 : register(s0); +float LuminanceScale : register(c0); #include "../convert/conv_matrix.hlsl" #include "../convert/st2084.hlsl" @@ -7,9 +8,6 @@ sampler s0 : register(s0); static const float4x4 fix_bt2020_matrix = mul(ycbcr2020nc_rgb, rgb_ycbcr709); -#define SRC_LUMINANCE_PEAK 10000.0 -#define DISPLAY_LUMINANCE_PEAK 125.0 - float4 main(float2 tex : TEXCOORD0) : COLOR { float4 color = tex2D(s0, tex); // original pixel @@ -19,7 +17,7 @@ float4 main(float2 tex : TEXCOORD0) : COLOR // PQ to Linear color = saturate(color); - color = ST2084ToLinear(color, SRC_LUMINANCE_PEAK/DISPLAY_LUMINANCE_PEAK); + color = ST2084ToLinear(color, LuminanceScale); color.rgb = ToneMappingHable(color.rgb); color.rgb = Colorspace_Gamut_Conversion_2020_to_709(color.rgb); diff --git a/Source/DX11VideoProcessor.cpp b/Source/DX11VideoProcessor.cpp index 755799f2..ee197b98 100644 --- a/Source/DX11VideoProcessor.cpp +++ b/Source/DX11VideoProcessor.cpp @@ -398,8 +398,8 @@ CDX11VideoProcessor::CDX11VideoProcessor(CMpcVideoRenderer* pFilter, const Setti m_iHdrToggleDisplay = config.iHdrToggleDisplay; m_iHdrOsdBrightness = config.iHdrOsdBrightness; m_bConvertToSdr = config.bConvertToSdr; + m_iSDRDisplayNits = config.iSDRDisplayNits; m_bVPRTXVideoHDR = config.bVPRTXVideoHDR; - m_iVPSuperRes = config.iVPSuperRes; m_nCurrentAdapter = -1; @@ -697,6 +697,7 @@ void CDX11VideoProcessor::ReleaseDevice() m_strShaderY = nullptr; m_pPSFinalPass.Release(); + m_pCorrectionConstants.Release(); m_pPostScaleConstants.Release(); #if TEST_SHADER @@ -1700,6 +1701,7 @@ BOOL CDX11VideoProcessor::InitMediaType(const CMediaType* pmt) hr = InitializeD3D11VP(FmtParams, origW, origH); if (SUCCEEDED(hr)) { UINT resId = 0; + m_pCorrectionConstants.Release(); bool bTransFunc22 = m_srcExFmt.VideoTransferFunction == DXVA2_VideoTransFunc_22 || m_srcExFmt.VideoTransferFunction == DXVA2_VideoTransFunc_709 || m_srcExFmt.VideoTransferFunction == DXVA2_VideoTransFunc_240M; @@ -1707,6 +1709,11 @@ BOOL CDX11VideoProcessor::InitMediaType(const CMediaType* pmt) if (m_srcExFmt.VideoTransferFunction == MFVideoTransFunc_2084 && !(m_bHdrPassthroughSupport && m_bHdrPassthrough) && m_bConvertToSdr) { resId = m_D3D11VP.IsPqSupported() ? IDF_PS_11_CONVERT_PQ_TO_SDR : IDF_PS_11_FIXCONVERT_PQ_TO_SDR; m_strCorrection = L"PQ to SDR"; + + D3D11_BUFFER_DESC BufferDesc = { sizeof(FLOAT) * 4, D3D11_USAGE_DEFAULT, D3D11_BIND_CONSTANT_BUFFER, 0, 0, 0 }; + FLOAT CorrectionConstantsData[4] = { 10000.0f / m_iSDRDisplayNits, 0, 0, 0 }; + D3D11_SUBRESOURCE_DATA InitData = { &CorrectionConstantsData, 0, 0 }; + EXECUTE_ASSERT(S_OK == m_pDevice->CreateBuffer(&BufferDesc, &InitData, &m_pCorrectionConstants)); } else if (m_srcExFmt.VideoTransferFunction == MFVideoTransFunc_HLG) { if (m_bHdrPassthroughSupport && m_bHdrPassthrough) { @@ -2554,7 +2561,7 @@ HRESULT CDX11VideoProcessor::UpdateConvertColorShader() m_srcWidth, m_TexSrcVideo.desc.Width, m_TexSrcVideo.desc.Height, m_srcRect, m_srcParams, m_srcExFmt, pDOVIMetadata, - m_iChromaScaling, convertType, false, + m_iChromaScaling, convertType, false, 10000.0f / m_iSDRDisplayNits, &pShaderCode); if (S_OK == hr) { hr = m_pDevice->CreatePixelShader(pShaderCode->GetBufferPointer(), pShaderCode->GetBufferSize(), nullptr, &m_pPSConvertColor); @@ -2566,7 +2573,7 @@ HRESULT CDX11VideoProcessor::UpdateConvertColorShader() m_srcWidth, m_TexSrcVideo.desc.Width, m_TexSrcVideo.desc.Height, m_srcRect, m_srcParams, m_srcExFmt, pDOVIMetadata, - m_iChromaScaling, convertType, true, + m_iChromaScaling, convertType, true, 10000.0f / m_iSDRDisplayNits, &pShaderCode); if (S_OK == hr) { hr = m_pDevice->CreatePixelShader(pShaderCode->GetBufferPointer(), pShaderCode->GetBufferSize(), nullptr, &m_pPSConvertColorDeint); @@ -2923,7 +2930,7 @@ HRESULT CDX11VideoProcessor::Process(ID3D11Texture2D* pRenderTarget, const CRect if (m_pPSCorrection) { StepSetting(); - hr = TextureCopyRect(*pInputTexture, pRT, rect, rect, m_pPSCorrection, nullptr, 0, false); + hr = TextureCopyRect(*pInputTexture, pRT, rect, rect, m_pPSCorrection, m_pCorrectionConstants, 0, false); } if (m_pPostScaleShaders.size()) { @@ -3422,6 +3429,11 @@ void CDX11VideoProcessor::Configure(const Settings_t& config) changeRTXVideoHDR = true; } + if (config.iSDRDisplayNits != m_iSDRDisplayNits) { + m_iSDRDisplayNits = config.iSDRDisplayNits; + changeConvertShader = true; + } + if (!m_pFilter->GetActive()) { return; } diff --git a/Source/DX11VideoProcessor.h b/Source/DX11VideoProcessor.h index b1679763..4007b96e 100644 --- a/Source/DX11VideoProcessor.h +++ b/Source/DX11VideoProcessor.h @@ -79,6 +79,8 @@ class CDX11VideoProcessor // D3D11 Video Processor CD3D11VP m_D3D11VP; + + CComPtr m_pCorrectionConstants; CComPtr m_pPSCorrection; const wchar_t* m_strCorrection = nullptr; diff --git a/Source/DX9VideoProcessor.cpp b/Source/DX9VideoProcessor.cpp index 0948683f..a2365413 100644 --- a/Source/DX9VideoProcessor.cpp +++ b/Source/DX9VideoProcessor.cpp @@ -287,6 +287,7 @@ CDX9VideoProcessor::CDX9VideoProcessor(CMpcVideoRenderer* pFilter, const Setting m_bHdrPassthrough = false; m_iHdrToggleDisplay = false; m_bConvertToSdr = config.bConvertToSdr; + m_iSDRDisplayNits = config.iSDRDisplayNits; m_nCurrentAdapter = D3DADAPTER_DEFAULT; @@ -1995,6 +1996,11 @@ void CDX9VideoProcessor::Configure(const Settings_t& config) } } + if (config.iSDRDisplayNits != m_iSDRDisplayNits) { + m_iSDRDisplayNits = config.iSDRDisplayNits; + changeConvertShader = true; + } + if (!m_pFilter->GetActive()) { return; } @@ -2236,7 +2242,7 @@ HRESULT CDX9VideoProcessor::UpdateConvertColorShader() m_srcWidth, m_TexSrcVideo.Width, m_TexSrcVideo.Height, m_srcRect, m_srcParams, m_srcExFmt, pDOVIMetadata, - m_iChromaScaling, convertType, false, + m_iChromaScaling, convertType, false, 10000.0f / m_iSDRDisplayNits, &pShaderCode); if (S_OK == hr) { hr = m_pD3DDevEx->CreatePixelShader((const DWORD*)pShaderCode->GetBufferPointer(), &m_pPSConvertColor); @@ -2248,7 +2254,7 @@ HRESULT CDX9VideoProcessor::UpdateConvertColorShader() m_srcWidth, m_TexSrcVideo.Width, m_TexSrcVideo.Height, m_srcRect, m_srcParams, m_srcExFmt, pDOVIMetadata, - m_iChromaScaling, convertType, true, + m_iChromaScaling, convertType, true, 10000.0f / m_iSDRDisplayNits, &pShaderCode); if (S_OK == hr) { hr = m_pD3DDevEx->CreatePixelShader((const DWORD*)pShaderCode->GetBufferPointer(), &m_pPSConvertColorDeint); @@ -2660,6 +2666,10 @@ HRESULT CDX9VideoProcessor::Process(IDirect3DSurface9* pRenderTarget, const CRec if (m_pPSCorrection) { StepSetting(); + float fConstDataHDR[][4] = { + {10000.0f / m_iSDRDisplayNits, 0.0f, 0.0f, 0.0f} + }; + hr = m_pD3DDevEx->SetPixelShaderConstantF(0, (float*)fConstDataHDR, sizeof(fConstDataHDR) / sizeof(float[4])); hr = m_pD3DDevEx->SetPixelShader(m_pPSCorrection); hr = m_pD3DDevEx->SetRenderTarget(0, pRT); hr = TextureCopyRect(pInputTexture, rect, rect, D3DTEXF_POINT, 0, false); diff --git a/Source/IVideoRenderer.h b/Source/IVideoRenderer.h index 2cf647ed..4eaf7fee 100644 --- a/Source/IVideoRenderer.h +++ b/Source/IVideoRenderer.h @@ -111,6 +111,7 @@ struct Settings_t { int iHdrToggleDisplay; int iHdrOsdBrightness; bool bConvertToSdr; + int iSDRDisplayNits; Settings_t() { SetDefault(); @@ -153,6 +154,7 @@ struct Settings_t { } bConvertToSdr = true; iHdrOsdBrightness = 0; + iSDRDisplayNits = 125; } }; diff --git a/Source/MpcVideoRenderer.rc b/Source/MpcVideoRenderer.rc index 7c01614f..768e5f3b 100644 --- a/Source/MpcVideoRenderer.rc +++ b/Source/MpcVideoRenderer.rc @@ -84,7 +84,7 @@ BEGIN CONTROL "Use dithering",IDC_CHECK10,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,206,59,10 CONTROL "Use Blend deinterlacing for YUV 4:2:0",IDC_CHECK17, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,219,139,10 - GROUPBOX "HDR",IDC_STATIC,171,35,176,94 + GROUPBOX "HDR",IDC_STATIC,171,35,176,112 CONTROL "Prefer Dolby Vision over PQ and HLG",IDC_CHECK18,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,178,47,135,10 CONTROL "Passthrough to display",IDC_CHECK12,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,178,60,89,10 LTEXT " if not possible",IDC_STATIC4,178,73,48,8 @@ -93,12 +93,15 @@ BEGIN COMBOBOX IDC_COMBO7,232,98,110,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Subtitle and OSD brightness:",IDC_STATIC6,178,115,99,8 CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,279,114,63,12 - LTEXT "Swap effect:",IDC_STATIC3,178,134,43,8 - COMBOBOX IDC_COMBO4,266,131,76,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Use exclusive fullscreen",IDC_CHECK11,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,178,147,93,10 - CONTROL "Wait for VBlank before Present",IDC_CHECK15,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,178,160,117,10 + LTEXT "SDR display nits:",IDC_STATIC8,178,130,60,8 + EDITTEXT IDC_EDIT1,242,128,32,14,ES_AUTOHSCROLL | ES_READONLY + CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,274,128,11,14 + LTEXT "Swap effect:",IDC_STATIC3,178,153,43,8 + COMBOBOX IDC_COMBO4,266,150,76,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Use exclusive fullscreen",IDC_CHECK11,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,178,166,93,10 + CONTROL "Wait for VBlank before Present",IDC_CHECK15,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,178,179,117,10 CONTROL "Reinitialize device when changing display",IDC_CHECK16, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,178,173,151,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,178,192,151,10 PUSHBUTTON "Default",IDC_BUTTON1,305,211,37,14 EDITTEXT IDC_EDIT2,76,235,266,12,ES_READONLY | NOT WS_BORDER,WS_EX_RIGHT END diff --git a/Source/PropPage.cpp b/Source/PropPage.cpp index 3ae27e3a..7ab75209 100644 --- a/Source/PropPage.cpp +++ b/Source/PropPage.cpp @@ -104,6 +104,9 @@ void CVRMainPPage::SetControls() SendDlgItemMessageW(IDC_COMBO7, CB_SETCURSEL, m_SetsPP.iHdrToggleDisplay, 0); SendDlgItemMessageW(IDC_SLIDER1, TBM_SETPOS, 1, m_SetsPP.iHdrOsdBrightness); + SendDlgItemMessageW(IDC_SPIN1, UDM_SETRANGE, 0, MAKELONG(400, 25)); + SendDlgItemMessageW(IDC_SPIN1, UDM_SETPOS, 0, m_SetsPP.iSDRDisplayNits); + CheckDlgButton(IDC_CHECK6, m_SetsPP.bInterpolateAt50pct ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(IDC_CHECK10, m_SetsPP.bUseDither ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(IDC_CHECK17, m_SetsPP.bDeintBlend ? BST_CHECKED : BST_UNCHECKED); @@ -117,7 +120,6 @@ void CVRMainPPage::SetControls() SendDlgItemMessageW(IDC_COMBO5, CB_SETCURSEL, m_SetsPP.iChromaScaling, 0); SendDlgItemMessageW(IDC_COMBO2, CB_SETCURSEL, m_SetsPP.iUpscaling, 0); SendDlgItemMessageW(IDC_COMBO3, CB_SETCURSEL, m_SetsPP.iDownscaling, 0); - SendDlgItemMessageW(IDC_COMBO4, CB_SETCURSEL, m_SetsPP.iSwapEffect, 0); } @@ -147,6 +149,10 @@ void CVRMainPPage::EnableControls() GetDlgItem(IDC_COMBO8).EnableWindow(bEnable && m_SetsPP.bVPScaling); GetDlgItem(IDC_CHECK19).EnableWindow(bEnable && m_SetsPP.bHdrPassthrough); } + + GetDlgItem(IDC_STATIC8).EnableWindow(m_SetsPP.bConvertToSdr); + GetDlgItem(IDC_EDIT1).EnableWindow(m_SetsPP.bConvertToSdr); + GetDlgItem(IDC_SPIN1).EnableWindow(m_SetsPP.bConvertToSdr); } HRESULT CVRMainPPage::OnConnect(IUnknown *pUnk) @@ -257,8 +263,9 @@ INT_PTR CVRMainPPage::OnReceiveMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPAR if (uMsg == WM_COMMAND) { LRESULT lValue; const int nID = LOWORD(wParam); + int action = HIWORD(wParam); - if (HIWORD(wParam) == BN_CLICKED) { + if (action == BN_CLICKED) { if (nID == IDC_CHECK1) { m_SetsPP.bUseD3D11 = IsDlgButtonChecked(IDC_CHECK1) == BST_CHECKED; EnableControls(); @@ -345,6 +352,7 @@ INT_PTR CVRMainPPage::OnReceiveMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPAR } if (nID == IDC_CHECK14) { m_SetsPP.bConvertToSdr = IsDlgButtonChecked(IDC_CHECK14) == BST_CHECKED; + EnableControls(); SetDirty(); return (LRESULT)1; } @@ -363,7 +371,7 @@ INT_PTR CVRMainPPage::OnReceiveMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPAR } } - if (HIWORD(wParam) == CBN_SELCHANGE) { + if (action == CBN_SELCHANGE) { if (nID == IDC_COMBO6) { lValue = SendDlgItemMessageW(IDC_COMBO6, CB_GETCURSEL, 0, 0); if (lValue != m_SetsPP.iResizeStats) { @@ -432,6 +440,20 @@ INT_PTR CVRMainPPage::OnReceiveMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPAR } } } + + if (action == EN_CHANGE) { + if (nID == IDC_EDIT1) { + LRESULT lValue = SendDlgItemMessageW(IDC_SPIN1, UDM_GETPOS, 0, 0); + if (HIWORD(lValue) == 0) { // valid value + int newvalue = LOWORD(lValue); + if (newvalue != m_SetsPP.iSDRDisplayNits) { + m_SetsPP.iSDRDisplayNits = newvalue; + SetDirty(); + return (LRESULT)1; + } + } + } + } } else if (uMsg == WM_HSCROLL) { if ((HWND)lParam == GetDlgItem(IDC_SLIDER1)) { diff --git a/Source/Shaders.cpp b/Source/Shaders.cpp index 941a089a..f8a26326 100644 --- a/Source/Shaders.cpp +++ b/Source/Shaders.cpp @@ -563,6 +563,7 @@ HRESULT GetShaderConvertColor( const int chromaScaling, const int convertType, const bool blendDeinterlace, + const float LuminanceScale, ID3DBlob** ppCode) { DLog(L"GetShaderConvertColor() started for {} {}x{} extfmt:{:#010x} chroma:{}", fmtParams.str, texW, texH, exFmt.value, chromaScaling); @@ -789,14 +790,13 @@ HRESULT GetShaderConvertColor( "color = LinearToST2084(color, 1000.0);\n" ); } - code.append( - "#define SRC_LUMINANCE_PEAK 10000.0\n" - "#define DISPLAY_LUMINANCE_PEAK 125.0\n" + std::string hdrtmp = std::format( "color = saturate(color);\n" - "color = ST2084ToLinear(color, SRC_LUMINANCE_PEAK/DISPLAY_LUMINANCE_PEAK);\n" + "color = ST2084ToLinear(color, {});\n" "color.rgb = ToneMappingHable(color.rgb);\n" "color.rgb = mul(matrix_conv_prim, color.rgb);\n" - ); + , LuminanceScale); + code.append(hdrtmp); isLinear = true; } else if (bConvertHLGtoPQ) { diff --git a/Source/Shaders.h b/Source/Shaders.h index 364fca89..c4f83ee6 100644 --- a/Source/Shaders.h +++ b/Source/Shaders.h @@ -70,4 +70,5 @@ HRESULT GetShaderConvertColor( const int chromaScaling, const int convertType, const bool blendDeinterlace, + const float LuminanceScale, ID3DBlob** ppCode); diff --git a/Source/VideoProcessor.h b/Source/VideoProcessor.h index 95bed7fd..20589aa2 100644 --- a/Source/VideoProcessor.h +++ b/Source/VideoProcessor.h @@ -64,6 +64,7 @@ class CVideoProcessor int m_iHdrToggleDisplay = HDRTD_On; int m_iHdrOsdBrightness = 0; bool m_bConvertToSdr = true; + int m_iSDRDisplayNits = 125; bool m_bVPScalingUseShaders = false; diff --git a/Source/VideoRenderer.cpp b/Source/VideoRenderer.cpp index 55341ef7..ac1ca35a 100644 --- a/Source/VideoRenderer.cpp +++ b/Source/VideoRenderer.cpp @@ -59,6 +59,7 @@ #define OPT_HdrOsdBrightness L"HdrOsdBrightness" #define OPT_ConvertToSdr L"ConvertToSdr" #define OPT_UseD3DFullscreen L"UseD3DFullscreen" +#define OPT_DisplayNits L"DisplayNits" static std::atomic_int g_nInstance = 0; static const wchar_t g_szClassName[] = L"VRWindow"; @@ -243,6 +244,9 @@ CMpcVideoRenderer::CMpcVideoRenderer(LPUNKNOWN pUnk, HRESULT* phr) if (ERROR_SUCCESS == key.QueryDWORDValue(OPT_ConvertToSdr, dw)) { m_Sets.bConvertToSdr = !!dw; } + if (ERROR_SUCCESS == key.QueryDWORDValue(OPT_DisplayNits, dw)) { + m_Sets.iSDRDisplayNits = discard(dw, 125, 25, 400); + } } if (!IsWindows10OrGreater()) { @@ -1217,6 +1221,7 @@ STDMETHODIMP CMpcVideoRenderer::SaveSettings() key.SetDWORDValue(OPT_HdrToggleDisplay, m_Sets.iHdrToggleDisplay); key.SetDWORDValue(OPT_HdrOsdBrightness, m_Sets.iHdrOsdBrightness); key.SetDWORDValue(OPT_ConvertToSdr, m_Sets.bConvertToSdr); + key.SetDWORDValue(OPT_DisplayNits, m_Sets.iSDRDisplayNits); } return S_OK; diff --git a/Source/resource.h b/Source/resource.h index 0ef08082..9beb9139 100644 --- a/Source/resource.h +++ b/Source/resource.h @@ -95,6 +95,7 @@ #define IDC_STATIC5 1015 #define IDC_STATIC6 1016 #define IDC_STATIC7 1017 +#define IDC_STATIC8 1018 #define IDC_CHECK1 1021 #define IDC_CHECK2 1022 #define IDC_CHECK3 1023 @@ -124,14 +125,15 @@ #define IDC_COMBO8 1048 #define IDC_BUTTON1 1051 #define IDC_SLIDER1 1061 +#define IDC_SPIN1 1064 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 104 +#define _APS_NEXT_RESOURCE_VALUE 106 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1064 +#define _APS_NEXT_CONTROL_VALUE 1065 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif