[idd/client/obs] hdr: wire up the SdrWhiteLevel from the capture

This commit is contained in:
Geoffrey McRae
2026-07-17 17:49:49 +10:00
parent 3b69e6bdf4
commit 2006fb640f
17 changed files with 111 additions and 66 deletions

View File

@@ -957,7 +957,8 @@ CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrame
m_lastHDRMaxDisplayLuminance != dstFormat.maxDisplayLuminance ||
m_lastHDRMinDisplayLuminance != dstFormat.minDisplayLuminance ||
m_lastHDRMaxContentLightLevel != dstFormat.maxContentLightLevel ||
m_lastHDRMaxFrameAverageLightLevel != dstFormat.maxFrameAverageLightLevel)
m_lastHDRMaxFrameAverageLightLevel != dstFormat.maxFrameAverageLightLevel ||
m_lastSDRWhiteLevel != dstFormat.sdrWhiteLevel)
{
++m_formatVer;
}
@@ -975,6 +976,7 @@ CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrame
m_lastHDRMinDisplayLuminance = dstFormat.minDisplayLuminance;
m_lastHDRMaxContentLightLevel = dstFormat.maxContentLightLevel;
m_lastHDRMaxFrameAverageLightLevel = dstFormat.maxFrameAverageLightLevel;
m_lastSDRWhiteLevel = dstFormat.sdrWhiteLevel;
if (++m_frameIndex == LGMP_Q_FRAME_LEN)
m_frameIndex = 0;
@@ -1012,6 +1014,7 @@ CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrame
fi->pitch = pitch;
// fi->offset is initialized at startup
fi->flags = flags;
fi->sdrWhiteLevel = dstFormat.sdrWhiteLevel;
fi->rotation = FRAME_ROT_0;
fi->type = dstFormat.format;

View File

@@ -129,6 +129,7 @@ private:
uint32_t m_lastHDRMinDisplayLuminance = 0;
uint32_t m_lastHDRMaxContentLightLevel = 0;
uint32_t m_lastHDRMaxFrameAverageLightLevel = 0;
uint32_t m_lastSDRWhiteLevel = 0;
bool m_lastHDRActive = false;
void QueryIddCxCapabilities();

View File

@@ -66,14 +66,15 @@ bool CPostProcessor::Configure(const D12FrameFormat& srcFormat, bool * formatCha
if (formatChanged)
*formatChanged = false;
if (srcFormat.desc.Width == m_srcFormat.desc.Width &&
srcFormat.desc.Height == m_srcFormat.desc.Height &&
srcFormat.desc.Format == m_srcFormat.desc.Format &&
srcFormat.format == m_srcFormat.format &&
srcFormat.width == m_srcFormat.width &&
srcFormat.height == m_srcFormat.height &&
srcFormat.hdr == m_srcFormat.hdr &&
srcFormat.hdrPQ == m_srcFormat.hdrPQ)
if (srcFormat.desc.Width == m_srcFormat.desc.Width &&
srcFormat.desc.Height == m_srcFormat.desc.Height &&
srcFormat.desc.Format == m_srcFormat.desc.Format &&
srcFormat.format == m_srcFormat.format &&
srcFormat.width == m_srcFormat.width &&
srcFormat.height == m_srcFormat.height &&
srcFormat.hdr == m_srcFormat.hdr &&
srcFormat.hdrPQ == m_srcFormat.hdrPQ &&
srcFormat.sdrWhiteLevel == m_srcFormat.sdrWhiteLevel)
return true;
D12FrameFormat oldDst = m_dstFormat;
@@ -105,14 +106,15 @@ bool CPostProcessor::Configure(const D12FrameFormat& srcFormat, bool * formatCha
m_dstFormat = cur;
if (formatChanged)
*formatChanged = oldDst.desc.Width != m_dstFormat.desc.Width ||
oldDst.desc.Height != m_dstFormat.desc.Height ||
oldDst.desc.Format != m_dstFormat.desc.Format ||
oldDst.format != m_dstFormat.format ||
oldDst.width != m_dstFormat.width ||
oldDst.height != m_dstFormat.height ||
oldDst.hdr != m_dstFormat.hdr ||
oldDst.hdrPQ != m_dstFormat.hdrPQ;
*formatChanged = oldDst.desc.Width != m_dstFormat.desc.Width ||
oldDst.desc.Height != m_dstFormat.desc.Height ||
oldDst.desc.Format != m_dstFormat.desc.Format ||
oldDst.format != m_dstFormat.format ||
oldDst.width != m_dstFormat.width ||
oldDst.height != m_dstFormat.height ||
oldDst.hdr != m_dstFormat.hdr ||
oldDst.hdrPQ != m_dstFormat.hdrPQ ||
oldDst.sdrWhiteLevel != m_dstFormat.sdrWhiteLevel;
return true;
}

View File

@@ -21,6 +21,7 @@
struct CD3D12Device;
extern "C" {
#include "common/KVMFR.h"
#include "common/types.h"
}
@@ -41,6 +42,7 @@ struct D12FrameFormat
FrameType format = FRAME_TYPE_INVALID;
bool hdr = false;
bool hdrPQ = false;
uint32_t sdrWhiteLevel = KVMFR_SDR_WHITE_LEVEL_DEFAULT;
// HDR static metadata (SMPTE ST 2086)
// Display color primaries in 0.00002 units (xy coordinates)

View File

@@ -165,6 +165,7 @@ bool CSwapChainProcessor::SwapChainThreadCore()
// Only the buffer2 acquisition path (IddCx 1.10+) reports it; on the legacy
// path HDR is not available, so default to SDR.
DXGI_COLOR_SPACE_TYPE colorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
UINT sdrWhiteLevel = KVMFR_SDR_WHITE_LEVEL_DEFAULT;
#ifdef HAS_IDDCX_110
if (m_devContext->CanProcessFP16())
@@ -179,10 +180,11 @@ bool CSwapChainProcessor::SwapChainThreadCore()
hr = IddCxSwapChainReleaseAndAcquireBuffer2(m_hSwapChain, &acquireIn, &buffer);
if (SUCCEEDED(hr))
{
frameNumber = buffer.MetaData.PresentationFrameNumber;
frameNumber = buffer.MetaData.PresentationFrameNumber;
dirtyRectCount = buffer.MetaData.DirtyRectCount;
surface = buffer.MetaData.pSurface;
colorSpace = buffer.MetaData.SurfaceColorSpace;
surface = buffer.MetaData.pSurface;
colorSpace = buffer.MetaData.SurfaceColorSpace;
sdrWhiteLevel = buffer.MetaData.SdrWhiteLevel;
}
}
else
@@ -222,7 +224,7 @@ bool CSwapChainProcessor::SwapChainThreadCore()
if (frameNumber != lastFrameNumber)
{
lastFrameNumber = frameNumber;
SwapChainNewFrame(surface, dirtyRectCount, colorSpace);
SwapChainNewFrame(surface, dirtyRectCount, colorSpace, sdrWhiteLevel);
// report that all GPU processing for this frame has been queued
hr = IddCxSwapChainFinishedProcessingFrame(m_hSwapChain);
@@ -334,7 +336,7 @@ static FrameType GetFrameType(DXGI_FORMAT format)
}
bool CSwapChainProcessor::SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer, unsigned dirtyRectCount,
DXGI_COLOR_SPACE_TYPE colorSpace)
DXGI_COLOR_SPACE_TYPE colorSpace, UINT sdrWhiteLevel)
{
ComPtr<ID3D11Texture2D> texture;
HRESULT hr = acquiredBuffer.As(&texture);
@@ -382,10 +384,11 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer
D3D12_RESOURCE_DESC srcDesc = srcRes->GetRes()->GetDesc();
D12FrameFormat srcFormat = {};
srcFormat.desc = srcDesc;
srcFormat.width = (unsigned)srcDesc.Width;
srcFormat.height = srcDesc.Height;
srcFormat.format = GetFrameType(srcDesc.Format);
srcFormat.desc = srcDesc;
srcFormat.width = (unsigned)srcDesc.Width;
srcFormat.height = srcDesc.Height;
srcFormat.format = GetFrameType(srcDesc.Format);
srcFormat.sdrWhiteLevel = sdrWhiteLevel;
switch (colorSpace)
{

View File

@@ -71,7 +71,7 @@ private:
static void CompletionFunction(
CD3D12CommandQueue * queue, bool result, void * param1, void * param2);
bool SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer, unsigned dirtyRectCount,
DXGI_COLOR_SPACE_TYPE colorSpace);
DXGI_COLOR_SPACE_TYPE colorSpace, UINT sdrWhiteLevel);
public:
CSwapChainProcessor(IDDCX_MONITOR monitor, CIndirectDeviceContext * devContext, IDDCX_SWAPCHAIN hSwapChain,

View File

@@ -140,6 +140,7 @@ PostProcessStatus CHDR16to10Effect::SetFormat(
dst.minDisplayLuminance = src.minDisplayLuminance;
dst.maxContentLightLevel = src.maxContentLightLevel;
dst.maxFrameAverageLightLevel = src.maxFrameAverageLightLevel;
dst.sdrWhiteLevel = src.sdrWhiteLevel;
return PostProcessStatus::SUCCESS;
}