mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-22 07:01:30 +00:00
[idd] postprocess: separate calibrated frame branches
This commit is contained in:
@@ -28,6 +28,7 @@ bool Frame::Same(const GraphCfg& left, const GraphCfg& right)
|
|||||||
left.srcWidth == right.srcWidth &&
|
left.srcWidth == right.srcWidth &&
|
||||||
left.srcHeight == right.srcHeight &&
|
left.srcHeight == right.srcHeight &&
|
||||||
Frame::Same(left.src, right.src) &&
|
Frame::Same(left.src, right.src) &&
|
||||||
|
left.transform == right.transform &&
|
||||||
left.width == right.width &&
|
left.width == right.width &&
|
||||||
left.height == right.height &&
|
left.height == right.height &&
|
||||||
Frame::Same(left.checkpoint, right.checkpoint);
|
Frame::Same(left.checkpoint, right.checkpoint);
|
||||||
@@ -141,60 +142,99 @@ unsigned CFrameGraph::Checkpoint(const FrameProfile& requested)
|
|||||||
{
|
{
|
||||||
const FrameProfile profile =
|
const FrameProfile profile =
|
||||||
Frame::Store(requested, FrameStorage::D3D12_TEXTURE);
|
Frame::Store(requested, FrameStorage::D3D12_TEXTURE);
|
||||||
|
FrameProfile current = m_cfg.src;
|
||||||
unsigned parent = 0;
|
unsigned parent = 0;
|
||||||
FrameOp op;
|
|
||||||
|
const D12ColorTransform * transform = m_cfg.transform.get();
|
||||||
|
if (transform && transform->matrixEnabled)
|
||||||
|
{
|
||||||
|
// The common matrix stage preserves the source signal. A transfer-domain
|
||||||
|
// LUT is applied after each branch has selected scRGB or HDR10.
|
||||||
|
if (current.signal == FrameSignal::SRGB &&
|
||||||
|
current.pixel == FramePixel::BGRA8)
|
||||||
|
current.pixel = FramePixel::RGBA8;
|
||||||
|
parent = AddNode(FrameOp::CAL, 0,
|
||||||
|
m_cfg.srcWidth, m_cfg.srcHeight, current);
|
||||||
|
if (parent == FRAME_GRAPH_ROOT)
|
||||||
|
return FRAME_GRAPH_ROOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Without calibration the established path filters linear scRGB before
|
||||||
|
// HDR10 encoding. This scale node is also shared by scRGB and HDR10 leaves.
|
||||||
|
const bool earlyScale = !transform &&
|
||||||
|
(m_cfg.srcWidth != m_cfg.width || m_cfg.srcHeight != m_cfg.height);
|
||||||
|
if (earlyScale)
|
||||||
|
{
|
||||||
|
parent = AddNode(FrameOp::SCALE, parent,
|
||||||
|
m_cfg.width, m_cfg.height, current);
|
||||||
|
if (parent == FRAME_GRAPH_ROOT)
|
||||||
|
return FRAME_GRAPH_ROOT;
|
||||||
|
}
|
||||||
|
|
||||||
switch (profile.signal)
|
switch (profile.signal)
|
||||||
{
|
{
|
||||||
case FrameSignal::SRGB:
|
case FrameSignal::SRGB:
|
||||||
op = FrameOp::SDR;
|
|
||||||
parent = AddNode(FrameOp::SDR, 0, m_cfg.width, m_cfg.height,
|
|
||||||
m_cfg.checkpoint);
|
|
||||||
if (parent == FRAME_GRAPH_ROOT)
|
|
||||||
return FRAME_GRAPH_ROOT;
|
|
||||||
if (Frame::Same(profile, m_cfg.checkpoint))
|
|
||||||
return parent;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FrameSignal::SCRGB_LINEAR:
|
case FrameSignal::SCRGB_LINEAR:
|
||||||
{
|
break;
|
||||||
op = FrameOp::SCRGB;
|
|
||||||
FrameProfile scRGB;
|
|
||||||
scRGB.storage = FrameStorage::D3D12_TEXTURE;
|
|
||||||
scRGB.pixel = FramePixel::RGBA16F;
|
|
||||||
scRGB.signal = FrameSignal::SCRGB_LINEAR;
|
|
||||||
return AddNode(
|
|
||||||
op, 0, m_cfg.width, m_cfg.height, scRGB);
|
|
||||||
}
|
|
||||||
|
|
||||||
case FrameSignal::PQ_BT2020:
|
case FrameSignal::PQ_BT2020:
|
||||||
op = FrameOp::HDR10;
|
|
||||||
if (m_cfg.src.signal == FrameSignal::SCRGB_LINEAR)
|
if (m_cfg.src.signal == FrameSignal::SCRGB_LINEAR)
|
||||||
{
|
{
|
||||||
FrameProfile scRGB;
|
const unsigned width = earlyScale ? m_cfg.width : m_cfg.srcWidth;
|
||||||
scRGB.storage = FrameStorage::D3D12_TEXTURE;
|
const unsigned height = earlyScale ? m_cfg.height : m_cfg.srcHeight;
|
||||||
scRGB.pixel = FramePixel::RGBA16F;
|
parent = AddNode(FrameOp::HDR10, parent,
|
||||||
scRGB.signal = FrameSignal::SCRGB_LINEAR;
|
width, height, profile);
|
||||||
parent = AddNode(
|
|
||||||
FrameOp::SCRGB, 0, m_cfg.width, m_cfg.height, scRGB);
|
|
||||||
if (parent == FRAME_GRAPH_ROOT)
|
if (parent == FRAME_GRAPH_ROOT)
|
||||||
return FRAME_GRAPH_ROOT;
|
return FRAME_GRAPH_ROOT;
|
||||||
}
|
current = profile;
|
||||||
else
|
|
||||||
{
|
|
||||||
parent = AddNode(FrameOp::HDR10, 0,
|
|
||||||
m_cfg.width, m_cfg.height, m_cfg.checkpoint);
|
|
||||||
if (parent == FRAME_GRAPH_ROOT)
|
|
||||||
return FRAME_GRAPH_ROOT;
|
|
||||||
if (Frame::Same(profile, m_cfg.checkpoint))
|
|
||||||
return parent;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return FRAME_GRAPH_ROOT;
|
return FRAME_GRAPH_ROOT;
|
||||||
}
|
}
|
||||||
return AddNode(
|
|
||||||
op, parent, m_cfg.width, m_cfg.height, profile);
|
if (transform && transform->lutEnabled)
|
||||||
|
{
|
||||||
|
if (current.signal == FrameSignal::SRGB &&
|
||||||
|
current.pixel == FramePixel::BGRA8)
|
||||||
|
current.pixel = FramePixel::RGBA8;
|
||||||
|
parent = AddNode(FrameOp::LUT, parent,
|
||||||
|
m_cfg.srcWidth, m_cfg.srcHeight, current);
|
||||||
|
if (parent == FRAME_GRAPH_ROOT)
|
||||||
|
return FRAME_GRAPH_ROOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!earlyScale &&
|
||||||
|
(m_cfg.srcWidth != m_cfg.width || m_cfg.srcHeight != m_cfg.height))
|
||||||
|
{
|
||||||
|
parent = AddNode(FrameOp::SCALE, parent,
|
||||||
|
m_cfg.width, m_cfg.height, current);
|
||||||
|
if (parent == FRAME_GRAPH_ROOT)
|
||||||
|
return FRAME_GRAPH_ROOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent != 0 && Frame::Same(current, profile))
|
||||||
|
return parent;
|
||||||
|
|
||||||
|
FrameOp op;
|
||||||
|
switch (profile.signal)
|
||||||
|
{
|
||||||
|
case FrameSignal::SRGB:
|
||||||
|
op = FrameOp::SDR;
|
||||||
|
break;
|
||||||
|
case FrameSignal::SCRGB_LINEAR:
|
||||||
|
op = FrameOp::SCRGB;
|
||||||
|
break;
|
||||||
|
case FrameSignal::PQ_BT2020:
|
||||||
|
op = FrameOp::HDR10;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FRAME_GRAPH_ROOT;
|
||||||
|
}
|
||||||
|
return AddNode(op, parent, m_cfg.width, m_cfg.height, profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFrameGraph::Add(BackendId id, uint32_t epoch, bool required,
|
bool CFrameGraph::Add(BackendId id, uint32_t epoch, bool required,
|
||||||
@@ -251,6 +291,26 @@ bool CFrameGraph::Same(const GraphCfg& cfg) const
|
|||||||
return m_sealed && Frame::Same(m_cfg, cfg);
|
return m_sealed && Frame::Same(m_cfg, cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CFrameGraph::Need(FrameOp op) const
|
||||||
|
{
|
||||||
|
if (!m_sealed || op == FrameOp::SRC)
|
||||||
|
return false;
|
||||||
|
for (unsigned i = 1; i < m_nodeCount; ++i)
|
||||||
|
if (m_nodes[i].op == op && m_nodes[i].refs)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFrameGraph::Want(FrameSignal signal) const
|
||||||
|
{
|
||||||
|
if (!m_sealed)
|
||||||
|
return false;
|
||||||
|
for (unsigned i = 0; i < m_leafCount; ++i)
|
||||||
|
if (m_leaves[i].cfg.profile.signal == signal)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool CFrameGraph::Desc(unsigned leaf, const FrameDesc& frame,
|
bool CFrameGraph::Desc(unsigned leaf, const FrameDesc& frame,
|
||||||
LeafDesc& desc) const
|
LeafDesc& desc) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,11 +31,14 @@
|
|||||||
static const unsigned FRAME_DAMAGE_MAX = 256;
|
static const unsigned FRAME_DAMAGE_MAX = 256;
|
||||||
static const unsigned FRAME_GRAPH_ROOT = UINT_MAX;
|
static const unsigned FRAME_GRAPH_ROOT = UINT_MAX;
|
||||||
static const unsigned FRAME_GRAPH_MAX_NODES =
|
static const unsigned FRAME_GRAPH_MAX_NODES =
|
||||||
1 + 2 * TRANSPORT_MAX_INSTANCES;
|
1 + 5 * TRANSPORT_MAX_INSTANCES;
|
||||||
|
|
||||||
enum class FrameOp : uint8_t
|
enum class FrameOp : uint8_t
|
||||||
{
|
{
|
||||||
SRC,
|
SRC,
|
||||||
|
CAL,
|
||||||
|
LUT,
|
||||||
|
SCALE,
|
||||||
SDR,
|
SDR,
|
||||||
SCRGB,
|
SCRGB,
|
||||||
HDR10,
|
HDR10,
|
||||||
@@ -50,14 +53,15 @@ enum class FrameDamage : uint8_t
|
|||||||
|
|
||||||
struct GraphCfg
|
struct GraphCfg
|
||||||
{
|
{
|
||||||
GpuMode mode = GpuMode::HARDWARE;
|
GpuMode mode = GpuMode::HARDWARE;
|
||||||
LUID adapter = {};
|
LUID adapter = {};
|
||||||
unsigned srcWidth = 0;
|
unsigned srcWidth = 0;
|
||||||
unsigned srcHeight = 0;
|
unsigned srcHeight = 0;
|
||||||
FrameProfile src;
|
FrameProfile src;
|
||||||
unsigned width = 0;
|
std::shared_ptr<const D12ColorTransform> transform;
|
||||||
unsigned height = 0;
|
unsigned width = 0;
|
||||||
FrameProfile checkpoint;
|
unsigned height = 0;
|
||||||
|
FrameProfile checkpoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Frame
|
namespace Frame
|
||||||
@@ -134,6 +138,8 @@ public:
|
|||||||
const FrameCfg& cfg);
|
const FrameCfg& cfg);
|
||||||
bool Seal();
|
bool Seal();
|
||||||
bool Same(const GraphCfg& cfg) const;
|
bool Same(const GraphCfg& cfg) const;
|
||||||
|
bool Want(FrameSignal signal) const;
|
||||||
|
bool Need(FrameOp op) const;
|
||||||
bool Desc(unsigned leaf, const FrameDesc& frame, LeafDesc& desc) const;
|
bool Desc(unsigned leaf, const FrameDesc& frame, LeafDesc& desc) const;
|
||||||
|
|
||||||
const GraphCfg& Cfg() const { return m_cfg; }
|
const GraphCfg& Cfg() const { return m_cfg; }
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ static bool MakeGraphCfg(const D12FrameFormat& source,
|
|||||||
cfg.srcWidth = source.width;
|
cfg.srcWidth = source.width;
|
||||||
cfg.srcHeight = source.height;
|
cfg.srcHeight = source.height;
|
||||||
cfg.src = src;
|
cfg.src = src;
|
||||||
|
cfg.transform = D12::Transform(source.colorTransform);
|
||||||
cfg.width = checkpoint.width;
|
cfg.width = checkpoint.width;
|
||||||
cfg.height = checkpoint.height;
|
cfg.height = checkpoint.height;
|
||||||
cfg.checkpoint = output;
|
cfg.checkpoint = output;
|
||||||
|
|||||||
@@ -170,6 +170,13 @@ PostProcessStatus CColorTransformEffect::SetFormat(
|
|||||||
if (!transform)
|
if (!transform)
|
||||||
return PostProcessStatus::BYPASS_EFFECT;
|
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;
|
DXGI_FORMAT dstFormat;
|
||||||
FrameType frameType;
|
FrameType frameType;
|
||||||
switch (src.desc.Format)
|
switch (src.desc.Format)
|
||||||
@@ -184,10 +191,12 @@ PostProcessStatus CColorTransformEffect::SetFormat(
|
|||||||
frameType = src.format;
|
frameType = src.format;
|
||||||
break;
|
break;
|
||||||
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
||||||
// The client wire format is HDR10. Perform the XYZ adjustment before
|
// The legacy chain targets HDR10 in this pass. A graph CAL node keeps
|
||||||
// the BT.2020 rotation, and its LUT after PQ encoding, in one pass.
|
// the linear scRGB signal so its HDR10 child remains independently
|
||||||
dstFormat = DXGI_FORMAT_R10G10B10A2_UNORM;
|
// selectable by transport demand.
|
||||||
frameType = FRAME_TYPE_RGBA10;
|
dstFormat = m_keepSignal ? DXGI_FORMAT_R16G16B16A16_FLOAT :
|
||||||
|
DXGI_FORMAT_R10G10B10A2_UNORM;
|
||||||
|
frameType = m_keepSignal ? FRAME_TYPE_RGBA16F : FRAME_TYPE_RGBA10;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DEBUG_ERROR("Unsupported color transform source format %u", src.desc.Format);
|
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,
|
std::memcpy(m_consts.matrix, transform->matrix,
|
||||||
sizeof(m_consts.matrix));
|
sizeof(m_consts.matrix));
|
||||||
m_consts.scalar = transform->scalar;
|
m_consts.scalar = transform->scalar;
|
||||||
m_consts.matrixEnabled = transform->matrixEnabled;
|
m_consts.matrixEnabled = matrixEnabled;
|
||||||
m_consts.lutEnabled = transform->lutEnabled;
|
m_consts.lutEnabled = lutEnabled;
|
||||||
m_consts.inputTransfer = src.hdrPQ ? TRANSFER_PQ :
|
const UINT inputTransfer = src.hdrPQ ? TRANSFER_PQ :
|
||||||
(src.hdr ? TRANSFER_LINEAR : TRANSFER_SRGB);
|
(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));
|
std::memcpy(m_lut, transform->lut, sizeof(m_lut));
|
||||||
m_uploadPending = true;
|
m_uploadPending = true;
|
||||||
@@ -225,7 +236,7 @@ PostProcessStatus CColorTransformEffect::SetFormat(
|
|||||||
dst.desc = desc;
|
dst.desc = desc;
|
||||||
dst.format = frameType;
|
dst.format = frameType;
|
||||||
if (src.hdr)
|
if (src.hdr)
|
||||||
dst.hdrPQ = true;
|
dst.hdrPQ = m_keepSignal ? src.hdrPQ : true;
|
||||||
return PostProcessStatus::SUCCESS;
|
return PostProcessStatus::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,13 @@
|
|||||||
|
|
||||||
#include "CComputeEffect.h"
|
#include "CComputeEffect.h"
|
||||||
|
|
||||||
|
enum class CalPart : uint8_t
|
||||||
|
{
|
||||||
|
ALL,
|
||||||
|
MATRIX,
|
||||||
|
LUT,
|
||||||
|
};
|
||||||
|
|
||||||
class CColorTransformEffect : public CComputeEffect
|
class CColorTransformEffect : public CComputeEffect
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -41,8 +48,14 @@ private:
|
|||||||
ComPtr<ID3D12Resource> m_lutBuffer;
|
ComPtr<ID3D12Resource> m_lutBuffer;
|
||||||
DXGI_FORMAT m_srcFormat = DXGI_FORMAT_UNKNOWN;
|
DXGI_FORMAT m_srcFormat = DXGI_FORMAT_UNKNOWN;
|
||||||
DXGI_FORMAT m_dstFormat = DXGI_FORMAT_UNKNOWN;
|
DXGI_FORMAT m_dstFormat = DXGI_FORMAT_UNKNOWN;
|
||||||
|
CalPart m_part;
|
||||||
|
bool m_keepSignal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
explicit CColorTransformEffect(CalPart part = CalPart::ALL,
|
||||||
|
bool keepSignal = false) :
|
||||||
|
m_part(part), m_keepSignal(keepSignal) {}
|
||||||
|
|
||||||
const char * GetName() const override { return "ColorTransform"; }
|
const char * GetName() const override { return "ColorTransform"; }
|
||||||
|
|
||||||
bool Init(const ComPtr<ID3D12Device3>& device);
|
bool Init(const ComPtr<ID3D12Device3>& device);
|
||||||
|
|||||||
@@ -96,7 +96,10 @@ const CDownsampleEffect::Rule * CDownsampleEffect::MatchRule(
|
|||||||
|
|
||||||
bool CDownsampleEffect::Init(const ComPtr<ID3D12Device3>& device, bool report)
|
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;
|
return false;
|
||||||
|
|
||||||
D3D12_STATIC_SAMPLER_DESC sampler = {};
|
D3D12_STATIC_SAMPLER_DESC sampler = {};
|
||||||
@@ -154,21 +157,30 @@ PostProcessStatus CDownsampleEffect::SetFormat(
|
|||||||
const ComPtr<ID3D12Device3>& device,
|
const ComPtr<ID3D12Device3>& device,
|
||||||
const D12FrameFormat& src, D12FrameFormat& dst)
|
const D12FrameFormat& src, D12FrameFormat& dst)
|
||||||
{
|
{
|
||||||
const Rule * rule = MatchRule((unsigned)src.desc.Width, src.desc.Height);
|
unsigned targetX = m_targetX;
|
||||||
if (!rule ||
|
unsigned targetY = m_targetY;
|
||||||
(rule->targetX == src.desc.Width && rule->targetY == src.desc.Height))
|
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;
|
return PostProcessStatus::BYPASS_EFFECT;
|
||||||
|
|
||||||
D3D12_RESOURCE_DESC desc = src.desc;
|
D3D12_RESOURCE_DESC desc = src.desc;
|
||||||
desc.Width = rule->targetX;
|
desc.Width = targetX;
|
||||||
desc.Height = rule->targetY;
|
desc.Height = targetY;
|
||||||
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
||||||
|
|
||||||
if (!CreateDefaultTexture(device, desc, m_dst))
|
if (!CreateDefaultTexture(device, desc, m_dst))
|
||||||
return PostProcessStatus::FAILED;
|
return PostProcessStatus::FAILED;
|
||||||
|
|
||||||
m_consts.width = (float)rule->targetX;
|
m_consts.width = (float)targetX;
|
||||||
m_consts.height = (float)rule->targetY;
|
m_consts.height = (float)targetY;
|
||||||
|
|
||||||
const HRESULT hr = Upload(m_constBuffer, &m_consts, sizeof(m_consts));
|
const HRESULT hr = Upload(m_constBuffer, &m_consts, sizeof(m_consts));
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
|||||||
@@ -43,18 +43,24 @@ private:
|
|||||||
float height;
|
float height;
|
||||||
} m_consts = {};
|
} m_consts = {};
|
||||||
|
|
||||||
std::vector<Rule> m_rules;
|
std::vector<Rule> m_rules;
|
||||||
ComPtr<ID3D12Resource> m_constBuffer;
|
ComPtr<ID3D12Resource> m_constBuffer;
|
||||||
DXGI_FORMAT m_format = DXGI_FORMAT_UNKNOWN;
|
DXGI_FORMAT m_format = DXGI_FORMAT_UNKNOWN;
|
||||||
double m_scaleX = 1.0;
|
double m_scaleX = 1.0;
|
||||||
double m_scaleY = 1.0;
|
double m_scaleY = 1.0;
|
||||||
unsigned m_width = 0;
|
unsigned m_width = 0;
|
||||||
unsigned m_height = 0;
|
unsigned m_height = 0;
|
||||||
|
unsigned m_targetX = 0;
|
||||||
|
unsigned m_targetY = 0;
|
||||||
|
|
||||||
bool ParseRules(const std::wstring& value, bool report);
|
bool ParseRules(const std::wstring& value, bool report);
|
||||||
const Rule * MatchRule(unsigned width, unsigned height) const;
|
const Rule * MatchRule(unsigned width, unsigned height) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
CDownsampleEffect() = default;
|
||||||
|
CDownsampleEffect(unsigned width, unsigned height) :
|
||||||
|
m_targetX(width), m_targetY(height) {}
|
||||||
|
|
||||||
const char * GetName() const override { return "Downsample"; }
|
const char * GetName() const override { return "Downsample"; }
|
||||||
|
|
||||||
bool Init(const ComPtr<ID3D12Device3>& device, bool report = true);
|
bool Init(const ComPtr<ID3D12Device3>& device, bool report = true);
|
||||||
|
|||||||
Reference in New Issue
Block a user