[idd] postprocess: separate calibrated frame branches

This commit is contained in:
Geoffrey McRae
2026-08-13 14:20:01 +10:00
parent 43d918b5f3
commit a8eb49fb17
7 changed files with 177 additions and 68 deletions

View File

@@ -170,6 +170,13 @@ PostProcessStatus CColorTransformEffect::SetFormat(
if (!transform)
return PostProcessStatus::BYPASS_EFFECT;
const bool matrixEnabled =
m_part != CalPart::LUT && transform->matrixEnabled;
const bool lutEnabled =
m_part != CalPart::MATRIX && transform->lutEnabled;
if (!matrixEnabled && !lutEnabled)
return PostProcessStatus::BYPASS_EFFECT;
DXGI_FORMAT dstFormat;
FrameType frameType;
switch (src.desc.Format)
@@ -184,10 +191,12 @@ PostProcessStatus CColorTransformEffect::SetFormat(
frameType = src.format;
break;
case DXGI_FORMAT_R16G16B16A16_FLOAT:
// The client wire format is HDR10. Perform the XYZ adjustment before
// the BT.2020 rotation, and its LUT after PQ encoding, in one pass.
dstFormat = DXGI_FORMAT_R10G10B10A2_UNORM;
frameType = FRAME_TYPE_RGBA10;
// The legacy chain targets HDR10 in this pass. A graph CAL node keeps
// the linear scRGB signal so its HDR10 child remains independently
// selectable by transport demand.
dstFormat = m_keepSignal ? DXGI_FORMAT_R16G16B16A16_FLOAT :
DXGI_FORMAT_R10G10B10A2_UNORM;
frameType = m_keepSignal ? FRAME_TYPE_RGBA16F : FRAME_TYPE_RGBA10;
break;
default:
DEBUG_ERROR("Unsupported color transform source format %u", src.desc.Format);
@@ -208,11 +217,13 @@ PostProcessStatus CColorTransformEffect::SetFormat(
std::memcpy(m_consts.matrix, transform->matrix,
sizeof(m_consts.matrix));
m_consts.scalar = transform->scalar;
m_consts.matrixEnabled = transform->matrixEnabled;
m_consts.lutEnabled = transform->lutEnabled;
m_consts.inputTransfer = src.hdrPQ ? TRANSFER_PQ :
m_consts.matrixEnabled = matrixEnabled;
m_consts.lutEnabled = lutEnabled;
const UINT inputTransfer = src.hdrPQ ? TRANSFER_PQ :
(src.hdr ? TRANSFER_LINEAR : TRANSFER_SRGB);
m_consts.outputTransfer = src.hdr ? TRANSFER_PQ : TRANSFER_SRGB;
m_consts.inputTransfer = inputTransfer;
m_consts.outputTransfer = m_keepSignal ? inputTransfer :
(src.hdr ? TRANSFER_PQ : TRANSFER_SRGB);
std::memcpy(m_lut, transform->lut, sizeof(m_lut));
m_uploadPending = true;
@@ -225,7 +236,7 @@ PostProcessStatus CColorTransformEffect::SetFormat(
dst.desc = desc;
dst.format = frameType;
if (src.hdr)
dst.hdrPQ = true;
dst.hdrPQ = m_keepSignal ? src.hdrPQ : true;
return PostProcessStatus::SUCCESS;
}

View File

@@ -22,6 +22,13 @@
#include "CComputeEffect.h"
enum class CalPart : uint8_t
{
ALL,
MATRIX,
LUT,
};
class CColorTransformEffect : public CComputeEffect
{
private:
@@ -41,8 +48,14 @@ private:
ComPtr<ID3D12Resource> m_lutBuffer;
DXGI_FORMAT m_srcFormat = DXGI_FORMAT_UNKNOWN;
DXGI_FORMAT m_dstFormat = DXGI_FORMAT_UNKNOWN;
CalPart m_part;
bool m_keepSignal;
public:
explicit CColorTransformEffect(CalPart part = CalPart::ALL,
bool keepSignal = false) :
m_part(part), m_keepSignal(keepSignal) {}
const char * GetName() const override { return "ColorTransform"; }
bool Init(const ComPtr<ID3D12Device3>& device);

View File

@@ -96,7 +96,10 @@ const CDownsampleEffect::Rule * CDownsampleEffect::MatchRule(
bool CDownsampleEffect::Init(const ComPtr<ID3D12Device3>& device, bool report)
{
if (!ParseRules(g_settings.ReadStringValue(L"Downsample"), report))
if ((!m_targetX && m_targetY) || (m_targetX && !m_targetY))
return false;
if (!m_targetX &&
!ParseRules(g_settings.ReadStringValue(L"Downsample"), report))
return false;
D3D12_STATIC_SAMPLER_DESC sampler = {};
@@ -154,21 +157,30 @@ PostProcessStatus CDownsampleEffect::SetFormat(
const ComPtr<ID3D12Device3>& device,
const D12FrameFormat& src, D12FrameFormat& dst)
{
const Rule * rule = MatchRule((unsigned)src.desc.Width, src.desc.Height);
if (!rule ||
(rule->targetX == src.desc.Width && rule->targetY == src.desc.Height))
unsigned targetX = m_targetX;
unsigned targetY = m_targetY;
if (!targetX || !targetY)
{
const Rule * rule =
MatchRule((unsigned)src.desc.Width, src.desc.Height);
if (!rule)
return PostProcessStatus::BYPASS_EFFECT;
targetX = rule->targetX;
targetY = rule->targetY;
}
if (targetX == src.desc.Width && targetY == src.desc.Height)
return PostProcessStatus::BYPASS_EFFECT;
D3D12_RESOURCE_DESC desc = src.desc;
desc.Width = rule->targetX;
desc.Height = rule->targetY;
desc.Width = targetX;
desc.Height = targetY;
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
if (!CreateDefaultTexture(device, desc, m_dst))
return PostProcessStatus::FAILED;
m_consts.width = (float)rule->targetX;
m_consts.height = (float)rule->targetY;
m_consts.width = (float)targetX;
m_consts.height = (float)targetY;
const HRESULT hr = Upload(m_constBuffer, &m_consts, sizeof(m_consts));
if (FAILED(hr))

View File

@@ -43,18 +43,24 @@ private:
float height;
} m_consts = {};
std::vector<Rule> m_rules;
ComPtr<ID3D12Resource> m_constBuffer;
DXGI_FORMAT m_format = DXGI_FORMAT_UNKNOWN;
double m_scaleX = 1.0;
double m_scaleY = 1.0;
unsigned m_width = 0;
unsigned m_height = 0;
std::vector<Rule> m_rules;
ComPtr<ID3D12Resource> m_constBuffer;
DXGI_FORMAT m_format = DXGI_FORMAT_UNKNOWN;
double m_scaleX = 1.0;
double m_scaleY = 1.0;
unsigned m_width = 0;
unsigned m_height = 0;
unsigned m_targetX = 0;
unsigned m_targetY = 0;
bool ParseRules(const std::wstring& value, bool report);
const Rule * MatchRule(unsigned width, unsigned height) const;
public:
CDownsampleEffect() = default;
CDownsampleEffect(unsigned width, unsigned height) :
m_targetX(width), m_targetY(height) {}
const char * GetName() const override { return "Downsample"; }
bool Init(const ComPtr<ID3D12Device3>& device, bool report = true);