mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-07-16 04:12:03 +00:00
[idd] add support to return HDR metadata to clients
This commit is contained in:
committed by
Geoffrey McRae
parent
11b3ac00a8
commit
0c653c1fb2
@@ -162,6 +162,15 @@ typedef struct KVMFRFrame
|
|||||||
uint32_t damageRectsCount; // the number of damage rectangles (zero for full-frame damage)
|
uint32_t damageRectsCount; // the number of damage rectangles (zero for full-frame damage)
|
||||||
FrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS];
|
FrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS];
|
||||||
KVMFRFrameFlags flags; // bit field combination of FRAME_FLAG_*
|
KVMFRFrameFlags flags; // bit field combination of FRAME_FLAG_*
|
||||||
|
|
||||||
|
// HDR static metadata (valid when FRAME_FLAG_HDR is set)
|
||||||
|
// Display color primaries in 0.00002 units (SMPTE ST 2086 format)
|
||||||
|
uint16_t hdrDisplayPrimary[3][2]; // Rx,Ry, Gx,Gy, Bx,By
|
||||||
|
uint16_t hdrWhitePoint[2]; // Wx, Wy
|
||||||
|
uint32_t hdrMaxDisplayLuminance; // Max mastering display luminance (0.0001 cd/m²)
|
||||||
|
uint32_t hdrMinDisplayLuminance; // Min mastering display luminance (0.0001 cd/m²)
|
||||||
|
uint32_t hdrMaxContentLightLevel; // MaxCLL (cd/m²)
|
||||||
|
uint32_t hdrMaxFrameAverageLightLevel; // MaxFALL (cd/m²)
|
||||||
}
|
}
|
||||||
KVMFRFrame;
|
KVMFRFrame;
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ static inline IDDCX_WIRE_BITS_PER_COMPONENT GetWireBitsPerComponent(bool hdr)
|
|||||||
IDDCX_WIRE_BITS_PER_COMPONENT bits = {};
|
IDDCX_WIRE_BITS_PER_COMPONENT bits = {};
|
||||||
bits.Rgb = IDDCX_BITS_PER_COMPONENT_8;
|
bits.Rgb = IDDCX_BITS_PER_COMPONENT_8;
|
||||||
if (hdr)
|
if (hdr)
|
||||||
bits.Rgb = (IDDCX_BITS_PER_COMPONENT)(bits.Rgb | IDDCX_BITS_PER_COMPONENT_10);
|
bits.Rgb = (IDDCX_BITS_PER_COMPONENT)(bits.Rgb |
|
||||||
|
IDDCX_BITS_PER_COMPONENT_10 | IDDCX_BITS_PER_COMPONENT_16);
|
||||||
bits.YCbCr444 = IDDCX_BITS_PER_COMPONENT_NONE;
|
bits.YCbCr444 = IDDCX_BITS_PER_COMPONENT_NONE;
|
||||||
bits.YCbCr422 = IDDCX_BITS_PER_COMPONENT_NONE;
|
bits.YCbCr422 = IDDCX_BITS_PER_COMPONENT_NONE;
|
||||||
bits.YCbCr420 = IDDCX_BITS_PER_COMPONENT_NONE;
|
bits.YCbCr420 = IDDCX_BITS_PER_COMPONENT_NONE;
|
||||||
@@ -829,6 +830,35 @@ CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrame
|
|||||||
++m_formatVer;
|
++m_formatVer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Detect HDR metadata changes that require a format version bump
|
||||||
|
// so the client knows to re-apply the HDR image description.
|
||||||
|
if (srcFormat.hdr)
|
||||||
|
{
|
||||||
|
if (!m_lastHDRActive ||
|
||||||
|
memcmp(m_lastHDRDisplayPrimary, srcFormat.displayPrimary, sizeof(m_lastHDRDisplayPrimary)) != 0 ||
|
||||||
|
memcmp(m_lastHDRWhitePoint , srcFormat.whitePoint , sizeof(m_lastHDRWhitePoint )) != 0 ||
|
||||||
|
m_lastHDRMaxDisplayLuminance != srcFormat.maxDisplayLuminance ||
|
||||||
|
m_lastHDRMinDisplayLuminance != srcFormat.minDisplayLuminance ||
|
||||||
|
m_lastHDRMaxContentLightLevel != srcFormat.maxContentLightLevel ||
|
||||||
|
m_lastHDRMaxFrameAverageLightLevel != srcFormat.maxFrameAverageLightLevel)
|
||||||
|
{
|
||||||
|
++m_formatVer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_lastHDRActive)
|
||||||
|
{
|
||||||
|
// HDR was turned off
|
||||||
|
++m_formatVer;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lastHDRActive = srcFormat.hdr;
|
||||||
|
memcpy(m_lastHDRDisplayPrimary, srcFormat.displayPrimary, sizeof(m_lastHDRDisplayPrimary));
|
||||||
|
memcpy(m_lastHDRWhitePoint , srcFormat.whitePoint , sizeof(m_lastHDRWhitePoint ));
|
||||||
|
m_lastHDRMaxDisplayLuminance = srcFormat.maxDisplayLuminance;
|
||||||
|
m_lastHDRMinDisplayLuminance = srcFormat.minDisplayLuminance;
|
||||||
|
m_lastHDRMaxContentLightLevel = srcFormat.maxContentLightLevel;
|
||||||
|
m_lastHDRMaxFrameAverageLightLevel = srcFormat.maxFrameAverageLightLevel;
|
||||||
|
|
||||||
if (++m_frameIndex == LGMP_Q_FRAME_LEN)
|
if (++m_frameIndex == LGMP_Q_FRAME_LEN)
|
||||||
m_frameIndex = 0;
|
m_frameIndex = 0;
|
||||||
|
|
||||||
@@ -850,9 +880,6 @@ CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrame
|
|||||||
(dstFormat.hdr ? FRAME_FLAG_HDR : 0) |
|
(dstFormat.hdr ? FRAME_FLAG_HDR : 0) |
|
||||||
(dstFormat.hdrPQ ? FRAME_FLAG_HDR_PQ : 0);
|
(dstFormat.hdrPQ ? FRAME_FLAG_HDR_PQ : 0);
|
||||||
|
|
||||||
if (dstFormat.format == FRAME_TYPE_RGBA16F)
|
|
||||||
flags |= FRAME_FLAG_HDR;
|
|
||||||
|
|
||||||
if (maxRows < dstFormat.desc.Height)
|
if (maxRows < dstFormat.desc.Height)
|
||||||
flags |= FRAME_FLAG_TRUNCATED;
|
flags |= FRAME_FLAG_TRUNCATED;
|
||||||
|
|
||||||
@@ -870,6 +897,18 @@ CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrame
|
|||||||
fi->flags = flags;
|
fi->flags = flags;
|
||||||
fi->rotation = FRAME_ROT_0;
|
fi->rotation = FRAME_ROT_0;
|
||||||
fi->type = dstFormat.format;
|
fi->type = dstFormat.format;
|
||||||
|
|
||||||
|
// Populate HDR metadata if the frame is HDR
|
||||||
|
if (flags & FRAME_FLAG_HDR)
|
||||||
|
{
|
||||||
|
memcpy(fi->hdrDisplayPrimary, srcFormat.displayPrimary, sizeof(fi->hdrDisplayPrimary));
|
||||||
|
memcpy(fi->hdrWhitePoint , srcFormat.whitePoint , sizeof(fi->hdrWhitePoint));
|
||||||
|
fi->hdrMaxDisplayLuminance = srcFormat.maxDisplayLuminance;
|
||||||
|
fi->hdrMinDisplayLuminance = srcFormat.minDisplayLuminance;
|
||||||
|
fi->hdrMaxContentLightLevel = srcFormat.maxContentLightLevel;
|
||||||
|
fi->hdrMaxFrameAverageLightLevel = srcFormat.maxFrameAverageLightLevel;
|
||||||
|
}
|
||||||
|
|
||||||
fi->damageRectsCount = 0;
|
fi->damageRectsCount = 0;
|
||||||
if (nbDirtyRects <= ARRAYSIZE(fi->damageRects))
|
if (nbDirtyRects <= ARRAYSIZE(fi->damageRects))
|
||||||
{
|
{
|
||||||
@@ -984,6 +1023,59 @@ void CIndirectDeviceContext::SendCursor(const IDARG_OUT_QUERY_HWCURSOR& info, co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CIndirectDeviceContext::SetHDRActive(const struct IDDCX_HDR_METADATA * hdrMeta)
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive(&m_hdrLock);
|
||||||
|
|
||||||
|
if (!hdrMeta)
|
||||||
|
{
|
||||||
|
m_hdrActive = false;
|
||||||
|
ReleaseSRWLockExclusive(&m_hdrLock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& hdr10 = hdrMeta->Hdr10;
|
||||||
|
|
||||||
|
m_hdrActive = true;
|
||||||
|
|
||||||
|
m_hdrDisplayPrimary[0][0] = hdr10.RedPrimary [0];
|
||||||
|
m_hdrDisplayPrimary[0][1] = hdr10.RedPrimary [1];
|
||||||
|
m_hdrDisplayPrimary[1][0] = hdr10.GreenPrimary[0];
|
||||||
|
m_hdrDisplayPrimary[1][1] = hdr10.GreenPrimary[1];
|
||||||
|
m_hdrDisplayPrimary[2][0] = hdr10.BluePrimary [0];
|
||||||
|
m_hdrDisplayPrimary[2][1] = hdr10.BluePrimary [1];
|
||||||
|
m_hdrWhitePoint [0] = hdr10.WhitePoint [0];
|
||||||
|
m_hdrWhitePoint [1] = hdr10.WhitePoint [1];
|
||||||
|
|
||||||
|
m_hdrMaxDisplayLuminance = hdr10.MaxMasteringLuminance;
|
||||||
|
m_hdrMinDisplayLuminance = hdr10.MinMasteringLuminance;
|
||||||
|
m_hdrMaxContentLightLevel = hdr10.MaxContentLightLevel;
|
||||||
|
m_hdrMaxFrameAverageLightLevel = hdr10.MaxFrameAverageLightLevel;
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&m_hdrLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CIndirectDeviceContext::GetHDRMetadata(D12FrameFormat & format) const
|
||||||
|
{
|
||||||
|
AcquireSRWLockShared(&m_hdrLock);
|
||||||
|
|
||||||
|
if (!m_hdrActive)
|
||||||
|
{
|
||||||
|
ReleaseSRWLockShared(&m_hdrLock);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(format.displayPrimary, m_hdrDisplayPrimary, sizeof(format.displayPrimary));
|
||||||
|
memcpy(format.whitePoint , m_hdrWhitePoint , sizeof(format.whitePoint ));
|
||||||
|
format.maxDisplayLuminance = m_hdrMaxDisplayLuminance;
|
||||||
|
format.minDisplayLuminance = m_hdrMinDisplayLuminance;
|
||||||
|
format.maxContentLightLevel = m_hdrMaxContentLightLevel;
|
||||||
|
format.maxFrameAverageLightLevel = m_hdrMaxFrameAverageLightLevel;
|
||||||
|
|
||||||
|
ReleaseSRWLockShared(&m_hdrLock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void CIndirectDeviceContext::ResendCursor() const
|
void CIndirectDeviceContext::ResendCursor() const
|
||||||
{
|
{
|
||||||
PLGMPMemory mem = m_pointerShape;
|
PLGMPMemory mem = m_pointerShape;
|
||||||
|
|||||||
@@ -90,6 +90,27 @@ private:
|
|||||||
UINT m_iddCxVersion = 0;
|
UINT m_iddCxVersion = 0;
|
||||||
bool m_canProcessFP16 = false;
|
bool m_canProcessFP16 = false;
|
||||||
|
|
||||||
|
// HDR state from EvtIddCxMonitorSetDefaultHdrMetadata (IddCx 1.10+)
|
||||||
|
// Protected by m_hdrLock - accessed from both the IDD callback thread
|
||||||
|
// (SetHDRActive) and the swap-chain thread (PrepareFrameBuffer, GetHDRMetadata).
|
||||||
|
mutable SRWLOCK m_hdrLock = SRWLOCK_INIT;
|
||||||
|
bool m_hdrActive = false;
|
||||||
|
uint16_t m_hdrDisplayPrimary[3][2] = {};
|
||||||
|
uint16_t m_hdrWhitePoint[2] = {};
|
||||||
|
uint32_t m_hdrMaxDisplayLuminance = 0;
|
||||||
|
uint32_t m_hdrMinDisplayLuminance = 0;
|
||||||
|
uint32_t m_hdrMaxContentLightLevel = 0;
|
||||||
|
uint32_t m_hdrMaxFrameAverageLightLevel = 0;
|
||||||
|
|
||||||
|
// Previous HDR metadata used to detect changes for formatVer bumps
|
||||||
|
uint16_t m_lastHDRDisplayPrimary[3][2] = {};
|
||||||
|
uint16_t m_lastHDRWhitePoint[2] = {};
|
||||||
|
uint32_t m_lastHDRMaxDisplayLuminance = 0;
|
||||||
|
uint32_t m_lastHDRMinDisplayLuminance = 0;
|
||||||
|
uint32_t m_lastHDRMaxContentLightLevel = 0;
|
||||||
|
uint32_t m_lastHDRMaxFrameAverageLightLevel = 0;
|
||||||
|
bool m_lastHDRActive = false;
|
||||||
|
|
||||||
void QueryIddCxCapabilities();
|
void QueryIddCxCapabilities();
|
||||||
bool CanUseIddCx110DDIs() const { return m_canProcessFP16; }
|
bool CanUseIddCx110DDIs() const { return m_canProcessFP16; }
|
||||||
|
|
||||||
@@ -156,6 +177,22 @@ public:
|
|||||||
|
|
||||||
void SendCursor(const IDARG_OUT_QUERY_HWCURSOR & info, const BYTE * data);
|
void SendCursor(const IDARG_OUT_QUERY_HWCURSOR & info, const BYTE * data);
|
||||||
|
|
||||||
|
// Tracks HDR state from EvtIddCxMonitorSetDefaultHdrMetadata
|
||||||
|
void SetHDRActive(const struct IDDCX_HDR_METADATA * hdrMeta);
|
||||||
|
|
||||||
|
// Returns true if the display is currently in HDR mode
|
||||||
|
bool IsHDRActive() const
|
||||||
|
{
|
||||||
|
AcquireSRWLockShared(&m_hdrLock);
|
||||||
|
bool result = m_hdrActive;
|
||||||
|
ReleaseSRWLockShared(&m_hdrLock);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copies current HDR metadata into the provided D12FrameFormat.
|
||||||
|
// Returns true if HDR is active and metadata was copied.
|
||||||
|
bool GetHDRMetadata(D12FrameFormat & format) const;
|
||||||
|
|
||||||
CIVSHMEM &GetIVSHMEM() { return m_ivshmem; }
|
CIVSHMEM &GetIVSHMEM() { return m_ivshmem; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,19 @@ struct D12FrameFormat
|
|||||||
FrameType format = FRAME_TYPE_INVALID;
|
FrameType format = FRAME_TYPE_INVALID;
|
||||||
bool hdr = false;
|
bool hdr = false;
|
||||||
bool hdrPQ = false;
|
bool hdrPQ = false;
|
||||||
|
|
||||||
|
// HDR static metadata (SMPTE ST 2086)
|
||||||
|
// Display color primaries in 0.00002 units (xy coordinates)
|
||||||
|
uint16_t displayPrimary[3][2];
|
||||||
|
// White point in 0.00002 units
|
||||||
|
uint16_t whitePoint[2];
|
||||||
|
// Max display luminance in 0.0001 cd/m² units
|
||||||
|
uint32_t maxDisplayLuminance;
|
||||||
|
// Min display luminance in 0.0001 cd/m² units
|
||||||
|
uint32_t minDisplayLuminance;
|
||||||
|
// MaxCLL and MaxFALL in cd/m²
|
||||||
|
uint32_t maxContentLightLevel;
|
||||||
|
uint32_t maxFrameAverageLightLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CPostProcessEffect
|
class CPostProcessEffect
|
||||||
|
|||||||
@@ -366,8 +366,51 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer
|
|||||||
srcFormat.width = (unsigned)srcDesc.Width;
|
srcFormat.width = (unsigned)srcDesc.Width;
|
||||||
srcFormat.height = srcDesc.Height;
|
srcFormat.height = srcDesc.Height;
|
||||||
srcFormat.format = GetFrameType(srcDesc.Format);
|
srcFormat.format = GetFrameType(srcDesc.Format);
|
||||||
srcFormat.hdr = srcDesc.Format == DXGI_FORMAT_R16G16B16A16_FLOAT;
|
|
||||||
srcFormat.hdrPQ = false;
|
// Determine HDR status from both format and color space.
|
||||||
|
// HDR metadata loading is handled inside each branch so the logic
|
||||||
|
// is self-contained: first identify the content type, then load the
|
||||||
|
// matching metadata.
|
||||||
|
if (srcDesc.Format == DXGI_FORMAT_R16G16B16A16_FLOAT)
|
||||||
|
{
|
||||||
|
// FP16 is HDR content (scRGB / linear, not PQ-curve).
|
||||||
|
// FP16 always carries HDR color data regardless of OS HDR mode,
|
||||||
|
// but metadata (primaries, luminances) may be unavailable.
|
||||||
|
srcFormat.hdr = true;
|
||||||
|
srcFormat.hdrPQ = false;
|
||||||
|
if (!m_devContext->GetHDRMetadata(srcFormat))
|
||||||
|
{
|
||||||
|
// No HDR metadata from the OS; provide reasonable defaults
|
||||||
|
// so downstream consumers have valid primaries and luminances.
|
||||||
|
// BT.709/sRGB primaries (in 0.00002 units):
|
||||||
|
srcFormat.displayPrimary[0][0] = 13250; // Rx
|
||||||
|
srcFormat.displayPrimary[0][1] = 34500; // Ry
|
||||||
|
srcFormat.displayPrimary[1][0] = 7500; // Gx
|
||||||
|
srcFormat.displayPrimary[1][1] = 30000; // Gy
|
||||||
|
srcFormat.displayPrimary[2][0] = 34000; // Bx
|
||||||
|
srcFormat.displayPrimary[2][1] = 16000; // By
|
||||||
|
// D65 white point (in 0.00002 units):
|
||||||
|
srcFormat.whitePoint[0] = 15635;
|
||||||
|
srcFormat.whitePoint[1] = 16450;
|
||||||
|
// 80 cd/m² display, 0.005 cd/m² black (in 0.0001 cd/m² units):
|
||||||
|
srcFormat.maxDisplayLuminance = 800000;
|
||||||
|
srcFormat.minDisplayLuminance = 50;
|
||||||
|
// Content light levels unknown:
|
||||||
|
srcFormat.maxContentLightLevel = 0;
|
||||||
|
srcFormat.maxFrameAverageLightLevel = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_devContext->CanProcessFP16() && m_devContext->IsHDRActive())
|
||||||
|
{
|
||||||
|
// Non-FP16 format (e.g., RGBA10) with OS HDR mode active.
|
||||||
|
// Windows applies the PQ (ST.2084) transfer function for non-FP16 HDR.
|
||||||
|
srcFormat.hdr = true;
|
||||||
|
srcFormat.hdrPQ = true;
|
||||||
|
|
||||||
|
// Load HDR metadata; if none is available the frame is not HDR.
|
||||||
|
if (!m_devContext->GetHDRMetadata(srcFormat))
|
||||||
|
srcFormat.hdr = false;
|
||||||
|
}
|
||||||
|
|
||||||
bool postProcessFormatChanged = false;
|
bool postProcessFormatChanged = false;
|
||||||
if (!m_postProcessor.Configure(srcFormat, &postProcessFormatChanged))
|
if (!m_postProcessor.Configure(srcFormat, &postProcessFormatChanged))
|
||||||
|
|||||||
@@ -165,8 +165,11 @@ NTSTATUS LGIddAdapterCommitModes2(IDDCX_ADAPTER adapter, const IDARG_IN_COMMITMO
|
|||||||
NTSTATUS LGIddMonitorSetDefaultHdrMetadata(IDDCX_MONITOR monitor,
|
NTSTATUS LGIddMonitorSetDefaultHdrMetadata(IDDCX_MONITOR monitor,
|
||||||
const IDARG_IN_MONITOR_SET_DEFAULT_HDR_METADATA* inArgs)
|
const IDARG_IN_MONITOR_SET_DEFAULT_HDR_METADATA* inArgs)
|
||||||
{
|
{
|
||||||
UNREFERENCED_PARAMETER(monitor);
|
auto* wrapper = WdfObjectGet_CIndirectMonitorContextWrapper(monitor);
|
||||||
UNREFERENCED_PARAMETER(inArgs);
|
auto* ctx = wrapper->context->GetDeviceContext();
|
||||||
|
|
||||||
|
ctx->SetHDRActive(inArgs->pHdrMetaData);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,14 +36,24 @@ bool CHDR16to10Effect::Init(const ComPtr<ID3D12Device3>& device)
|
|||||||
const char * shader =
|
const char * shader =
|
||||||
"cbuffer Constants : register(b0)\n"
|
"cbuffer Constants : register(b0)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float SDRWhiteLevel;\n"
|
" float ReferenceWhiteNits;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"Texture2D<float4> src : register(t0);\n"
|
"Texture2D<float4> src : register(t0);\n"
|
||||||
"RWTexture2D<float4> dst : register(u0);\n"
|
"RWTexture2D<float4> dst : register(u0);\n"
|
||||||
|
"static const float PQ_m1 = 0.1593017578125;\n"
|
||||||
|
"static const float PQ_m2 = 78.84375;\n"
|
||||||
|
"static const float PQ_c1 = 0.8359375;\n"
|
||||||
|
"static const float PQ_c2 = 18.8515625;\n"
|
||||||
|
"static const float PQ_c3 = 18.6875;\n"
|
||||||
"[numthreads(" POST_PROCESS_THREADS_STR ", " POST_PROCESS_THREADS_STR ", 1)]\n"
|
"[numthreads(" POST_PROCESS_THREADS_STR ", " POST_PROCESS_THREADS_STR ", 1)]\n"
|
||||||
"void main(uint3 dt : SV_DispatchThreadID)\n"
|
"void main(uint3 dt : SV_DispatchThreadID)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" dst[dt.xy] = float4(src[dt.xy].rgb * SDRWhiteLevel, src[dt.xy].a);\n"
|
" float3 linear = src[dt.xy].rgb * ReferenceWhiteNits;\n"
|
||||||
|
" // scRGB to PQ (ST.2084)\n"
|
||||||
|
" float3 Y = linear / 10000.0;\n"
|
||||||
|
" float3 Ym1 = pow(max(Y, 0.0), PQ_m1);\n"
|
||||||
|
" float3 pq = pow((PQ_c1 + PQ_c2 * Ym1) / (1.0 + PQ_c3 * Ym1), PQ_m2);\n"
|
||||||
|
" dst[dt.xy] = float4(pq, src[dt.xy].a);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
if (!InitCompute(device, ranges, ARRAYSIZE(ranges), nullptr, 0, shader))
|
if (!InitCompute(device, ranges, ARRAYSIZE(ranges), nullptr, 0, shader))
|
||||||
@@ -99,10 +109,20 @@ PostProcessStatus CHDR16to10Effect::SetFormat(
|
|||||||
m_threadsX = ((unsigned)desc.Width + (Threads - 1)) / Threads;
|
m_threadsX = ((unsigned)desc.Width + (Threads - 1)) / Threads;
|
||||||
m_threadsY = ((unsigned)desc.Height + (Threads - 1)) / Threads;
|
m_threadsY = ((unsigned)desc.Height + (Threads - 1)) / Threads;
|
||||||
|
|
||||||
dst.desc = desc;
|
dst.desc = desc;
|
||||||
dst.format = FRAME_TYPE_RGBA10;
|
dst.format = FRAME_TYPE_RGBA10;
|
||||||
dst.hdr = true;
|
dst.hdr = true;
|
||||||
dst.hdrPQ = false;
|
dst.hdrPQ = true;
|
||||||
|
|
||||||
|
// Explicitly propagate HDR static metadata so it survives post-processing.
|
||||||
|
// Do not rely on the caller's copy semantics in CPostProcessor::Configure().
|
||||||
|
memcpy(dst.displayPrimary, src.displayPrimary, sizeof(dst.displayPrimary));
|
||||||
|
memcpy(dst.whitePoint , src.whitePoint , sizeof(dst.whitePoint ));
|
||||||
|
dst.maxDisplayLuminance = src.maxDisplayLuminance;
|
||||||
|
dst.minDisplayLuminance = src.minDisplayLuminance;
|
||||||
|
dst.maxContentLightLevel = src.maxContentLightLevel;
|
||||||
|
dst.maxFrameAverageLightLevel = src.maxFrameAverageLightLevel;
|
||||||
|
|
||||||
return PostProcessStatus::SUCCESS;
|
return PostProcessStatus::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ class CHDR16to10Effect : public CComputeEffect
|
|||||||
private:
|
private:
|
||||||
struct Consts
|
struct Consts
|
||||||
{
|
{
|
||||||
float SDRWhiteLevel;
|
float ReferenceWhiteNits; // scRGB reference white in nits (typically 80)
|
||||||
} m_consts = { 1.0f };
|
} m_consts = { 80.0f };
|
||||||
ComPtr<ID3D12Resource> m_constBuffer;
|
ComPtr<ID3D12Resource> m_constBuffer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
Reference in New Issue
Block a user