diff --git a/idd/LGIdd/LGIdd.vcxproj b/idd/LGIdd/LGIdd.vcxproj
index bec6dd07..010591c2 100644
--- a/idd/LGIdd/LGIdd.vcxproj
+++ b/idd/LGIdd/LGIdd.vcxproj
@@ -55,6 +55,7 @@
+
diff --git a/idd/LGIdd/LGIdd.vcxproj.filters b/idd/LGIdd/LGIdd.vcxproj.filters
index 8a83bf5c..32759f45 100644
--- a/idd/LGIdd/LGIdd.vcxproj.filters
+++ b/idd/LGIdd/LGIdd.vcxproj.filters
@@ -306,6 +306,9 @@
Post-processing
+
+ Post-processing
+
Post-processing\Effects
diff --git a/idd/LGIdd/capture/CFrameProcessorUtil.cpp b/idd/LGIdd/capture/CFrameProcessorUtil.cpp
index fa1b8726..78614817 100644
--- a/idd/LGIdd/capture/CFrameProcessorUtil.cpp
+++ b/idd/LGIdd/capture/CFrameProcessorUtil.cpp
@@ -41,39 +41,6 @@ bool CFrameProcessorUtil::FrameMetadataChanged(
previous.maxFrameAverageLightLevel != current.maxFrameAverageLightLevel));
}
-FrameType CFrameProcessorUtil::GetFrameType(DXGI_FORMAT format)
-{
- switch (format)
- {
- case DXGI_FORMAT_B8G8R8A8_UNORM : return FRAME_TYPE_BGRA;
- case DXGI_FORMAT_R8G8B8A8_UNORM : return FRAME_TYPE_RGBA;
- case DXGI_FORMAT_R10G10B10A2_UNORM : return FRAME_TYPE_RGBA10;
- case DXGI_FORMAT_R16G16B16A16_FLOAT: return FRAME_TYPE_RGBA16F;
- default : return FRAME_TYPE_INVALID;
- }
-}
-
-bool CFrameProcessorUtil::ResourceDescMatches(
- const D3D12_RESOURCE_DESC& left, const D3D12_RESOURCE_DESC& right,
- bool compareAlignment)
-{
- // GetDesc may report a resolved alignment when resource creation requested
- // automatic alignment, so callers comparing creation descriptors can omit
- // this allocation metadata.
- return
- left.Dimension == right.Dimension &&
- (!compareAlignment || left.Alignment == right.Alignment) &&
- left.Width == right.Width &&
- left.Height == right.Height &&
- left.DepthOrArraySize == right.DepthOrArraySize &&
- left.MipLevels == right.MipLevels &&
- left.Format == right.Format &&
- left.SampleDesc.Count == right.SampleDesc.Count &&
- left.SampleDesc.Quality == right.SampleDesc.Quality &&
- left.Layout == right.Layout &&
- left.Flags == right.Flags;
-}
-
static bool IsFullDamage(const RECT * dirtyRects, unsigned nbDirtyRects,
unsigned width, unsigned height)
{
diff --git a/idd/LGIdd/capture/CFrameProcessorUtil.h b/idd/LGIdd/capture/CFrameProcessorUtil.h
index eb740ac4..78d1a541 100644
--- a/idd/LGIdd/capture/CFrameProcessorUtil.h
+++ b/idd/LGIdd/capture/CFrameProcessorUtil.h
@@ -29,9 +29,6 @@ class CFrameProcessorUtil
public:
static bool FrameMetadataChanged(const D12FrameFormat& previous,
const D12FrameFormat& current);
- static FrameType GetFrameType(DXGI_FORMAT format);
- static bool ResourceDescMatches(const D3D12_RESOURCE_DESC& left,
- const D3D12_RESOURCE_DESC& right, bool compareAlignment = true);
static void ClipDirtyRects(RECT dirtyRects[], unsigned * nbDirtyRects,
unsigned width, unsigned height);
static bool BuildCopyDamage(const CPostProcessor& postProcessor,
diff --git a/idd/LGIdd/capture/CHardwareFrameProcessor.cpp b/idd/LGIdd/capture/CHardwareFrameProcessor.cpp
index da30244f..9ea16f49 100644
--- a/idd/LGIdd/capture/CHardwareFrameProcessor.cpp
+++ b/idd/LGIdd/capture/CHardwareFrameProcessor.cpp
@@ -290,8 +290,7 @@ bool CHardwareFrameProcessor::EnsureCandidateResource(
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
if (candidate.resource &&
- CFrameProcessorUtil::ResourceDescMatches(
- candidate.resource->GetDesc(), desc, false))
+ D12::Same(candidate.resource->GetDesc(), desc, D12::DescCmp::CREATE))
return true;
candidate.resource.Reset();
diff --git a/idd/LGIdd/capture/CSoftwareFrameProcessor.cpp b/idd/LGIdd/capture/CSoftwareFrameProcessor.cpp
index 2871561d..a4922956 100644
--- a/idd/LGIdd/capture/CSoftwareFrameProcessor.cpp
+++ b/idd/LGIdd/capture/CSoftwareFrameProcessor.cpp
@@ -263,8 +263,7 @@ bool CSoftwareFrameProcessor::EnsureProductResource(
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
if (product.resource &&
- CFrameProcessorUtil::ResourceDescMatches(
- product.resource->GetDesc(), desc, false))
+ D12::Same(product.resource->GetDesc(), desc, D12::DescCmp::CREATE))
return true;
product.resource.Reset();
diff --git a/idd/LGIdd/capture/CSwapChainProcessor.cpp b/idd/LGIdd/capture/CSwapChainProcessor.cpp
index b268af40..76ebee78 100644
--- a/idd/LGIdd/capture/CSwapChainProcessor.cpp
+++ b/idd/LGIdd/capture/CSwapChainProcessor.cpp
@@ -572,7 +572,7 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr acquiredBuffer
srcFormat.desc = srcDesc;
srcFormat.width = (unsigned)srcDesc.Width;
srcFormat.height = srcDesc.Height;
- srcFormat.format = CFrameProcessorUtil::GetFrameType(srcDesc.Format);
+ srcFormat.format = D12::Type(srcDesc.Format);
srcFormat.sdrWhiteLevel = sdrWhiteLevel;
srcFormat.colorTransform = m_control.GetColorTransform();
diff --git a/idd/LGIdd/postprocess/CPostProcessor.cpp b/idd/LGIdd/postprocess/CPostProcessor.cpp
index 3bb359bc..135b9258 100644
--- a/idd/LGIdd/postprocess/CPostProcessor.cpp
+++ b/idd/LGIdd/postprocess/CPostProcessor.cpp
@@ -27,7 +27,6 @@
#include "postprocess/effect/CHDR16to10Effect.h"
#include "postprocess/effect/CRGB24Effect.h"
-#include
#include
#include
@@ -71,18 +70,6 @@ bool IsIdentityColorTransform(const D12ColorTransform& transform)
return true;
}
-static void CopyHDRMetadata(D12FrameFormat& dst, const D12FrameFormat& src)
-{
- dst.hdrMetadata = src.hdrMetadata;
- dst.sdrWhiteLevel = src.sdrWhiteLevel;
- std::memcpy(dst.displayPrimary, src.displayPrimary, sizeof(dst.displayPrimary));
- std::memcpy(dst.whitePoint, src.whitePoint, sizeof(dst.whitePoint));
- dst.maxDisplayLuminance = src.maxDisplayLuminance;
- dst.minDisplayLuminance = src.minDisplayLuminance;
- dst.maxContentLightLevel = src.maxContentLightLevel;
- dst.maxFrameAverageLightLevel = src.maxFrameAverageLightLevel;
-}
-
bool CPostProcessor::Init(std::shared_ptr dx12Device,
bool enableEffects)
{
@@ -213,8 +200,8 @@ bool CPostProcessor::Configure(const D12FrameFormat& srcFormat,
{
// Static HDR metadata may change independently of the resource format.
// Propagate it without recreating resources or post-processing state.
- CopyHDRMetadata(m_srcFormat, srcFormat);
- CopyHDRMetadata(m_dstFormat, srcFormat);
+ D12::CopyHdr(m_srcFormat, srcFormat);
+ D12::CopyHdr(m_dstFormat, srcFormat);
return true;
}
diff --git a/idd/LGIdd/postprocess/D12FrameFormat.cpp b/idd/LGIdd/postprocess/D12FrameFormat.cpp
new file mode 100644
index 00000000..7172e031
--- /dev/null
+++ b/idd/LGIdd/postprocess/D12FrameFormat.cpp
@@ -0,0 +1,113 @@
+/**
+ * Looking Glass
+ * Copyright © 2017-2026 The Looking Glass Authors
+ * https://looking-glass.io
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "postprocess/D12FrameFormat.h"
+
+#include
+
+FrameType D12::Type(DXGI_FORMAT format)
+{
+ switch (format)
+ {
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ return FRAME_TYPE_BGRA;
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ return FRAME_TYPE_RGBA;
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ return FRAME_TYPE_RGBA10;
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ return FRAME_TYPE_RGBA16F;
+ default:
+ return FRAME_TYPE_INVALID;
+ }
+}
+
+void D12::CopyHdr(D12FrameFormat& dst, const D12FrameFormat& src)
+{
+ dst.hdrMetadata = src.hdrMetadata;
+ dst.sdrWhiteLevel = src.sdrWhiteLevel;
+ 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;
+}
+
+bool D12::Same(const D3D12_RESOURCE_DESC& left,
+ const D3D12_RESOURCE_DESC& right, DescCmp cmp)
+{
+ const bool alignment = cmp != DescCmp::CREATE &&
+ cmp != DescCmp::COPY && cmp != DescCmp::VIEW;
+ const bool layout = cmp != DescCmp::COPY;
+ const bool flags = cmp != DescCmp::COPY &&
+ cmp != DescCmp::NO_FLAGS && cmp != DescCmp::VIEW;
+ return
+ left.Dimension == right.Dimension &&
+ (!alignment || left.Alignment == right.Alignment) &&
+ left.Width == right.Width &&
+ left.Height == right.Height &&
+ left.DepthOrArraySize == right.DepthOrArraySize &&
+ left.MipLevels == right.MipLevels &&
+ left.Format == right.Format &&
+ left.SampleDesc.Count == right.SampleDesc.Count &&
+ left.SampleDesc.Quality == right.SampleDesc.Quality &&
+ (!layout || left.Layout == right.Layout) &&
+ (!flags || left.Flags == right.Flags);
+}
+
+bool D12::Same(const D12FrameFormat& left, const D12FrameFormat& right,
+ FormatCmp cmp)
+{
+ const DescCmp descCmp = cmp == FormatCmp::IMAGE ? DescCmp::CREATE :
+ (cmp == FormatCmp::NO_FLAGS ? DescCmp::NO_FLAGS : DescCmp::EXACT);
+ if (!Same(left.desc, right.desc, descCmp))
+ return false;
+
+ if (cmp == FormatCmp::IMAGE)
+ return
+ left.width == right.width &&
+ left.height == right.height &&
+ left.format == right.format &&
+ left.hdr == right.hdr &&
+ left.hdrPQ == right.hdrPQ;
+
+ return
+ left.dataWidth == right.dataWidth &&
+ left.dataHeight == right.dataHeight &&
+ left.pitch == right.pitch &&
+ left.width == right.width &&
+ left.height == right.height &&
+ left.format == right.format &&
+ left.hdr == right.hdr &&
+ left.hdrPQ == right.hdrPQ &&
+ left.hdrMetadata == right.hdrMetadata &&
+ left.sdrWhiteLevel == right.sdrWhiteLevel &&
+ left.colorTransform == right.colorTransform &&
+ memcmp(left.displayPrimary, right.displayPrimary,
+ sizeof(left.displayPrimary)) == 0 &&
+ memcmp(left.whitePoint, right.whitePoint,
+ sizeof(left.whitePoint)) == 0 &&
+
+ left.maxDisplayLuminance == right.maxDisplayLuminance &&
+ left.minDisplayLuminance == right.minDisplayLuminance &&
+ left.maxContentLightLevel == right.maxContentLightLevel &&
+ left.maxFrameAverageLightLevel == right.maxFrameAverageLightLevel;
+}
diff --git a/idd/LGIdd/postprocess/D12FrameFormat.h b/idd/LGIdd/postprocess/D12FrameFormat.h
index 0f5b2bb9..942d1551 100644
--- a/idd/LGIdd/postprocess/D12FrameFormat.h
+++ b/idd/LGIdd/postprocess/D12FrameFormat.h
@@ -68,3 +68,30 @@ struct D12FrameFormat
uint32_t maxContentLightLevel;
uint32_t maxFrameAverageLightLevel;
};
+
+namespace D12
+{
+ enum class DescCmp : uint8_t
+ {
+ EXACT,
+ CREATE,
+ COPY,
+ NO_FLAGS,
+ VIEW,
+ };
+
+ enum class FormatCmp : uint8_t
+ {
+ EXACT,
+ IMAGE,
+ NO_FLAGS,
+ };
+
+ FrameType Type(DXGI_FORMAT format);
+ void CopyHdr(D12FrameFormat& dst, const D12FrameFormat& src);
+ bool Same(const D3D12_RESOURCE_DESC& left,
+ const D3D12_RESOURCE_DESC& right,
+ DescCmp cmp = DescCmp::EXACT);
+ bool Same(const D12FrameFormat& left, const D12FrameFormat& right,
+ FormatCmp cmp = FormatCmp::EXACT);
+}
diff --git a/idd/LGIdd/postprocess/effect/CHDR16to10Effect.cpp b/idd/LGIdd/postprocess/effect/CHDR16to10Effect.cpp
index 3a0f60cd..d425b34c 100644
--- a/idd/LGIdd/postprocess/effect/CHDR16to10Effect.cpp
+++ b/idd/LGIdd/postprocess/effect/CHDR16to10Effect.cpp
@@ -134,14 +134,7 @@ PostProcessStatus CHDR16to10Effect::SetFormat(
// Gamut conversion changes the signal's container primaries to BT.2020, but
// does not change the mastering display chromaticities described by ST 2086.
- dst.hdrMetadata = src.hdrMetadata;
- 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;
- dst.sdrWhiteLevel = src.sdrWhiteLevel;
+ D12::CopyHdr(dst, src);
return PostProcessStatus::SUCCESS;
}