[idd] postprocess: centralize frame format utilities

This commit is contained in:
Geoffrey McRae
2026-08-13 20:01:44 +10:00
parent 34835dd1af
commit 3d7df86a01
11 changed files with 150 additions and 64 deletions

View File

@@ -55,6 +55,7 @@
<ClCompile Include="d3d\CInteropResource.cpp" /> <ClCompile Include="d3d\CInteropResource.cpp" />
<ClCompile Include="d3d\CInteropResourcePool.cpp" /> <ClCompile Include="d3d\CInteropResourcePool.cpp" />
<ClCompile Include="postprocess\CPostProcessor.cpp" /> <ClCompile Include="postprocess\CPostProcessor.cpp" />
<ClCompile Include="postprocess\D12FrameFormat.cpp" />
<ClCompile Include="postprocess\effect\CColorTransformEffect.cpp" /> <ClCompile Include="postprocess\effect\CColorTransformEffect.cpp" />
<ClCompile Include="postprocess\effect\CComputeEffect.cpp" /> <ClCompile Include="postprocess\effect\CComputeEffect.cpp" />
<ClCompile Include="postprocess\effect\CDownsampleEffect.cpp" /> <ClCompile Include="postprocess\effect\CDownsampleEffect.cpp" />

View File

@@ -306,6 +306,9 @@
<ClCompile Include="postprocess\CPostProcessor.cpp"> <ClCompile Include="postprocess\CPostProcessor.cpp">
<Filter>Post-processing</Filter> <Filter>Post-processing</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="postprocess\D12FrameFormat.cpp">
<Filter>Post-processing</Filter>
</ClCompile>
<ClCompile Include="postprocess\effect\CColorTransformEffect.cpp"> <ClCompile Include="postprocess\effect\CColorTransformEffect.cpp">
<Filter>Post-processing\Effects</Filter> <Filter>Post-processing\Effects</Filter>
</ClCompile> </ClCompile>

View File

@@ -41,39 +41,6 @@ bool CFrameProcessorUtil::FrameMetadataChanged(
previous.maxFrameAverageLightLevel != current.maxFrameAverageLightLevel)); 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, static bool IsFullDamage(const RECT * dirtyRects, unsigned nbDirtyRects,
unsigned width, unsigned height) unsigned width, unsigned height)
{ {

View File

@@ -29,9 +29,6 @@ class CFrameProcessorUtil
public: public:
static bool FrameMetadataChanged(const D12FrameFormat& previous, static bool FrameMetadataChanged(const D12FrameFormat& previous,
const D12FrameFormat& current); 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, static void ClipDirtyRects(RECT dirtyRects[], unsigned * nbDirtyRects,
unsigned width, unsigned height); unsigned width, unsigned height);
static bool BuildCopyDamage(const CPostProcessor& postProcessor, static bool BuildCopyDamage(const CPostProcessor& postProcessor,

View File

@@ -290,8 +290,7 @@ bool CHardwareFrameProcessor::EnsureCandidateResource(
desc.Flags = D3D12_RESOURCE_FLAG_NONE; desc.Flags = D3D12_RESOURCE_FLAG_NONE;
if (candidate.resource && if (candidate.resource &&
CFrameProcessorUtil::ResourceDescMatches( D12::Same(candidate.resource->GetDesc(), desc, D12::DescCmp::CREATE))
candidate.resource->GetDesc(), desc, false))
return true; return true;
candidate.resource.Reset(); candidate.resource.Reset();

View File

@@ -263,8 +263,7 @@ bool CSoftwareFrameProcessor::EnsureProductResource(
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
if (product.resource && if (product.resource &&
CFrameProcessorUtil::ResourceDescMatches( D12::Same(product.resource->GetDesc(), desc, D12::DescCmp::CREATE))
product.resource->GetDesc(), desc, false))
return true; return true;
product.resource.Reset(); product.resource.Reset();

View File

@@ -572,7 +572,7 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer
srcFormat.desc = srcDesc; srcFormat.desc = srcDesc;
srcFormat.width = (unsigned)srcDesc.Width; srcFormat.width = (unsigned)srcDesc.Width;
srcFormat.height = srcDesc.Height; srcFormat.height = srcDesc.Height;
srcFormat.format = CFrameProcessorUtil::GetFrameType(srcDesc.Format); srcFormat.format = D12::Type(srcDesc.Format);
srcFormat.sdrWhiteLevel = sdrWhiteLevel; srcFormat.sdrWhiteLevel = sdrWhiteLevel;
srcFormat.colorTransform = m_control.GetColorTransform(); srcFormat.colorTransform = m_control.GetColorTransform();

View File

@@ -27,7 +27,6 @@
#include "postprocess/effect/CHDR16to10Effect.h" #include "postprocess/effect/CHDR16to10Effect.h"
#include "postprocess/effect/CRGB24Effect.h" #include "postprocess/effect/CRGB24Effect.h"
#include <cstring>
#include <limits> #include <limits>
#include <utility> #include <utility>
@@ -71,18 +70,6 @@ bool IsIdentityColorTransform(const D12ColorTransform& transform)
return true; 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<CD3D12Device> dx12Device, bool CPostProcessor::Init(std::shared_ptr<CD3D12Device> dx12Device,
bool enableEffects) bool enableEffects)
{ {
@@ -213,8 +200,8 @@ bool CPostProcessor::Configure(const D12FrameFormat& srcFormat,
{ {
// Static HDR metadata may change independently of the resource format. // Static HDR metadata may change independently of the resource format.
// Propagate it without recreating resources or post-processing state. // Propagate it without recreating resources or post-processing state.
CopyHDRMetadata(m_srcFormat, srcFormat); D12::CopyHdr(m_srcFormat, srcFormat);
CopyHDRMetadata(m_dstFormat, srcFormat); D12::CopyHdr(m_dstFormat, srcFormat);
return true; return true;
} }

View File

@@ -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 <cstring>
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;
}

View File

@@ -68,3 +68,30 @@ struct D12FrameFormat
uint32_t maxContentLightLevel; uint32_t maxContentLightLevel;
uint32_t maxFrameAverageLightLevel; 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);
}

View File

@@ -134,14 +134,7 @@ PostProcessStatus CHDR16to10Effect::SetFormat(
// Gamut conversion changes the signal's container primaries to BT.2020, but // Gamut conversion changes the signal's container primaries to BT.2020, but
// does not change the mastering display chromaticities described by ST 2086. // does not change the mastering display chromaticities described by ST 2086.
dst.hdrMetadata = src.hdrMetadata; D12::CopyHdr(dst, src);
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;
return PostProcessStatus::SUCCESS; return PostProcessStatus::SUCCESS;
} }