feat: 集成 RTX Video HDR (p1)

This commit is contained in:
Xu 2026-03-04 20:39:00 +08:00
commit fcd42fceb9
12 changed files with 255 additions and 28 deletions

View file

@ -731,9 +731,9 @@ bool CursorDrawer2::_ResolveCursorPixels(
HRESULT CursorDrawer2::_InitializeCursorTexture(_CursorInfo& cursorInfo) noexcept {
ID3D12Device5* device = _graphicsContext->GetDevice();
CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_UPLOAD);
D3D12_HEAP_FLAGS heapFlag = _graphicsContext->IsHeapFlagCreateNotZeroedSupported() ?
D3D12_HEAP_FLAG_CREATE_NOT_ZEROED : D3D12_HEAP_FLAG_NONE;
CD3DX12_HEAP_PROPERTIES heapProperties(D3D12_HEAP_TYPE_UPLOAD);
CD3DX12_RESOURCE_DESC texDesc = CD3DX12_RESOURCE_DESC::Tex2D(
cursorInfo.type == _CursorType::Color ? DXGI_FORMAT_R16G16B16A16_FLOAT :
@ -752,7 +752,7 @@ HRESULT CursorDrawer2::_InitializeCursorTexture(_CursorInfo& cursorInfo) noexcep
CD3DX12_RESOURCE_DESC bufferDesc = CD3DX12_RESOURCE_DESC::Buffer(textureSize);
HRESULT hr = device->CreateCommittedResource(
&heapProperties,
&heapProps,
heapFlag,
&bufferDesc,
D3D12_RESOURCE_STATE_GENERIC_READ,
@ -764,9 +764,9 @@ HRESULT CursorDrawer2::_InitializeCursorTexture(_CursorInfo& cursorInfo) noexcep
return hr;
}
heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
hr = device->CreateCommittedResource(
&heapProperties,
&heapProps,
heapFlag,
&texDesc,
D3D12_RESOURCE_STATE_COPY_DEST,

View file

@ -15,7 +15,7 @@ bool EffectsDrawer::Initialize(
Size rendererSize
) noexcept {
_graphicsContext = &graphicsContext;
_isScRGB = colorInfo.kind != winrt::AdvancedColorKind::StandardDynamicRange;
_colorInfo = colorInfo;
_inputSize = inputSize;
ID3D12Device5* device = graphicsContext.GetDevice();
@ -43,6 +43,15 @@ bool EffectsDrawer::Initialize(
_outputSize.height = std::lroundf(inputSize.height * fillScale);
}
if (colorInfo.kind == winrt::AdvancedColorKind::HighDynamicRange) {
_rtxTrueHdrDrawer.emplace();
HRESULT hr = _rtxTrueHdrDrawer->Initialize(graphicsContext, inputSize, colorInfo);
if (FAILED(hr)) {
Logger::Get().ComError("RtxTrueHdrDrawer::Initialize 失败", hr);
return false;
}
}
_catmullRomDrawer.emplace();
_catmullRomDrawer->Initialize(graphicsContext);
@ -90,6 +99,7 @@ HRESULT EffectsDrawer::Draw(
uint32_t frameIndex,
ID3D12Resource* /*inputResource*/,
ID3D12Resource* /*outputResource*/,
ID3D12DescriptorHeap* heap,
D3D12_GPU_DESCRIPTOR_HANDLE inputSrvHandle,
D3D12_GPU_DESCRIPTOR_HANDLE outputUavHandle
) noexcept {
@ -115,6 +125,14 @@ HRESULT EffectsDrawer::Draw(
commandList->EndQuery(_queryHeap.get(), D3D12_QUERY_TYPE_TIMESTAMP, queryHeapIndex);
if (_colorInfo.kind == winrt::AdvancedColorKind::HighDynamicRange) {
HRESULT hr = _rtxTrueHdrDrawer->Draw();
if (FAILED(hr)) {
return hr;
}
}
commandList->SetDescriptorHeaps(1, &heap);
_catmullRomDrawer->Draw(_inputSize, _outputSize, inputSrvHandle, outputUavHandle, false);
commandList->EndQuery(_queryHeap.get(), D3D12_QUERY_TYPE_TIMESTAMP, queryHeapIndex + 1);
@ -124,14 +142,16 @@ HRESULT EffectsDrawer::Draw(
return S_OK;
}
HRESULT EffectsDrawer::OnResized(Size rendererSize) noexcept {
void EffectsDrawer::OnResized(Size rendererSize) noexcept {
_outputSize = rendererSize;
return S_OK;
}
HRESULT EffectsDrawer::OnColorInfoChanged(const ColorInfo& colorInfo) noexcept {
_isScRGB = colorInfo.kind != winrt::AdvancedColorKind::StandardDynamicRange;
return S_OK;
void EffectsDrawer::OnColorInfoChanged(const ColorInfo& colorInfo) noexcept {
_colorInfo = colorInfo;
if (_rtxTrueHdrDrawer) {
_rtxTrueHdrDrawer->OnColorInfoChanged(colorInfo);
}
}
}

View file

@ -1,5 +1,6 @@
#pragma once
#include "CatmullRomDrawer.h"
#include "RtxTrueHdrDrawer.h"
#include "SmallVector.h"
namespace Magpie {
@ -21,6 +22,7 @@ public:
uint32_t frameIndex,
ID3D12Resource* inputResource,
ID3D12Resource* outputResource,
ID3D12DescriptorHeap* heap,
D3D12_GPU_DESCRIPTOR_HANDLE inputSrvHandle,
D3D12_GPU_DESCRIPTOR_HANDLE outputUavHandle
) noexcept;
@ -29,23 +31,24 @@ public:
return _outputSize;
}
HRESULT OnResized(Size rendererSize) noexcept;
void OnResized(Size rendererSize) noexcept;
HRESULT OnColorInfoChanged(const ColorInfo& colorInfo) noexcept;
void OnColorInfoChanged(const ColorInfo& colorInfo) noexcept;
private:
GraphicsContext* _graphicsContext = nullptr;
ColorInfo _colorInfo;
Size _inputSize{};
Size _outputSize{};
std::optional<RtxTrueHdrDrawer> _rtxTrueHdrDrawer;
std::optional<CatmullRomDrawer> _catmullRomDrawer;
winrt::com_ptr<ID3D12QueryHeap> _queryHeap;
winrt::com_ptr<ID3D12Resource> _queryResultBuffer;
UINT64 _timestampFrequency = 0;
bool _isScRGB = false;
bool _isFP16Supported = false;
};

View file

@ -117,11 +117,7 @@ void FrameProducer::OnResizedAsync(
return;
}
hr = _effectsDrawer.OnResized(rendererSize);
if (!_CheckResult(hr, "EffectsDrawer::OnResized 失败")) {
return;
}
_effectsDrawer.OnResized(rendererSize);
outputSize = _effectsDrawer.GetOutputSize();
hr = _frameRingBuffer.OnResized(outputSize);
@ -172,13 +168,13 @@ void FrameProducer::OnColorInfoChangedAsync(
return;
}
hr = _effectsDrawer.OnColorInfoChanged(colorInfo);
if (!_CheckResult(hr, "EffectsDrawer::OnColorInfoChanged 失败")) {
_effectsDrawer.OnColorInfoChanged(colorInfo);
hr = _frameRingBuffer.OnColorInfoChanged(colorInfo);
if (!_CheckResult(hr, "FrameRingBuffer::OnColorInfoChanged 失败")) {
return;
}
_frameRingBuffer.OnColorInfoChanged(colorInfo);
_CreateInputDescriptors();
_CreateOutputDescriptors();
@ -482,8 +478,7 @@ HRESULT FrameProducer::_Render() noexcept {
}
ID3D12GraphicsCommandList* commandList = _graphicsContext.GetCommandList();
commandList->SetDescriptorHeaps(1, &heap);
// 输出和输出纹理都处于 COMMON 状态,使用结束后也应处于此状态
ID3D12Resource* inputResource = _frameSource->GetOutput(frameSourceOutputIdx);
ID3D12Resource* outputResource = _frameRingBuffer.GetBuffer(frameRingBufferIdx);
@ -504,6 +499,7 @@ HRESULT FrameProducer::_Render() noexcept {
frameIndex,
inputResource,
outputResource,
heap,
CD3DX12_GPU_DESCRIPTOR_HANDLE(
heapGpuHandle, _inputSrvBaseIdx + frameSourceOutputIdx, descriptorSize),
CD3DX12_GPU_DESCRIPTOR_HANDLE(

View file

@ -35,7 +35,7 @@
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>S:\RTX_Video_SDK_v1.1.0\include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<FxCompile>
<ShaderModel>5.0</ShaderModel>
@ -74,6 +74,7 @@
<ClInclude Include="CursorHelper.h" />
<ClInclude Include="include\EffectInfo.h" />
<ClInclude Include="include\ShaderEffectParser.h" />
<ClInclude Include="RtxTrueHdrDrawer.h" />
<ClInclude Include="ShaderEffectCompilerService.h" />
<ClInclude Include="ShaderEffectDesc.h" />
<ClInclude Include="ShaderEffectDrawer.h" />
@ -133,6 +134,7 @@
<ClCompile Include="FrameProducer.cpp" />
<ClCompile Include="FrameSourceBase.cpp" />
<ClCompile Include="CursorHelper.cpp" />
<ClCompile Include="RtxTrueHdrDrawer.cpp" />
<ClCompile Include="ShaderEffectCompilerService.cpp" />
<ClCompile Include="ShaderEffectDrawer.cpp" />
<ClCompile Include="GDIFrameSource.cpp" />

View file

@ -198,6 +198,9 @@
<ClInclude Include="ColorHelper.h">
<Filter>Helpers</Filter>
</ClInclude>
<ClInclude Include="RtxTrueHdrDrawer.h">
<Filter>EffectDrawer</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ScalingRuntime.cpp" />
@ -332,6 +335,9 @@
<ClCompile Include="DynamicDescriptorHeap.cpp">
<Filter>Render</Filter>
</ClCompile>
<ClCompile Include="RtxTrueHdrDrawer.cpp">
<Filter>EffectDrawer</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<FxCompile Include="shaders\SimpleVS.hlsl">

View file

@ -13,8 +13,6 @@
namespace Magpie {
static constexpr float SCENE_REFERRED_SDR_WHITE_LEVEL = 80.0f;
Renderer2::Renderer2() noexcept {}
Renderer2::~Renderer2() noexcept {

View file

@ -0,0 +1,155 @@
#include "pch.h"
#include "RtxTrueHdrDrawer.h"
#include "GraphicsContext.h"
#include <nvsdk_ngx.h>
#include <nvsdk_ngx_defs_truehdr.h>
namespace Magpie {
RtxTrueHdrDrawer::~RtxTrueHdrDrawer() noexcept {
if (_trueHdrFeature) {
NVSDK_NGX_D3D12_ReleaseFeature(_trueHdrFeature);
}
if (_ngxParameters) {
NVSDK_NGX_D3D12_DestroyParameters(_ngxParameters);
}
if (_isNgxInitialized) {
NVSDK_NGX_D3D12_Shutdown1(_graphicsContext->GetDevice());
}
}
HRESULT RtxTrueHdrDrawer::Initialize(
GraphicsContext& graphicsContext,
Size inputSize,
const ColorInfo& colorInfo
) noexcept {
_graphicsContext = &graphicsContext;
_inputSize = inputSize;
_colorInfo = colorInfo;
NVSDK_NGX_Result status = NVSDK_NGX_D3D12_Init(0, L".", graphicsContext.GetDevice());
if (NVSDK_NGX_FAILED(status)) {
return E_FAIL;
}
_isNgxInitialized = true;
status = NVSDK_NGX_D3D12_GetCapabilityParameters(&_ngxParameters);
if (NVSDK_NGX_FAILED(status)) {
return E_FAIL;
}
int available = 0;
status = _ngxParameters->Get(NVSDK_NGX_Parameter_TrueHDR_Available, &available);
if (NVSDK_NGX_FAILED(status) || !available) {
return E_FAIL;
}
ID3D12Device5* device = graphicsContext.GetDevice();
CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_DEFAULT);
D3D12_HEAP_FLAGS heapFlag = _graphicsContext->IsHeapFlagCreateNotZeroedSupported() ?
D3D12_HEAP_FLAG_CREATE_NOT_ZEROED : D3D12_HEAP_FLAG_NONE;
CD3DX12_RESOURCE_DESC texDesc = CD3DX12_RESOURCE_DESC::Tex2D(
DXGI_FORMAT_R10G10B10A2_UNORM, inputSize.width, inputSize.height,
1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
HRESULT hr = device->CreateCommittedResource(
&heapProps, heapFlag, &texDesc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
nullptr, IID_PPV_ARGS(&_ngxInputResource));
if (FAILED(hr)) {
return hr;
}
texDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
hr = device->CreateCommittedResource(
&heapProps, heapFlag, &texDesc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
nullptr, IID_PPV_ARGS(&_ngxOutputResource));
if (FAILED(hr)) {
return hr;
}
hr = device->CreateCommittedResource(
&heapProps, heapFlag, &texDesc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
nullptr, IID_PPV_ARGS(&_colorFactorResource));
if (FAILED(hr)) {
return hr;
}
return S_OK;
}
HRESULT RtxTrueHdrDrawer::Draw() noexcept {
ID3D12GraphicsCommandList* commandList = _graphicsContext->GetCommandList();
if (!_trueHdrFeature) {
NVSDK_NGX_Result status = NVSDK_NGX_D3D12_CreateFeature(
commandList, NVSDK_NGX_Feature_TrueHDR, _ngxParameters, &_trueHdrFeature);
if (NVSDK_NGX_FAILED(status)) {
return E_FAIL;
}
NVSDK_NGX_Parameter_SetD3d12Resource(
_ngxParameters, NVSDK_NGX_Parameter_Input1, _ngxInputResource.get());
NVSDK_NGX_Parameter_SetD3d12Resource(
_ngxParameters, NVSDK_NGX_Parameter_Output, _ngxOutputResource.get());
NVSDK_NGX_Parameter_SetUI(_ngxParameters, NVSDK_NGX_Parameter_TrueHDR_InLeft, 0);
NVSDK_NGX_Parameter_SetUI(_ngxParameters, NVSDK_NGX_Parameter_TrueHDR_InTop, 0);
NVSDK_NGX_Parameter_SetUI(_ngxParameters, NVSDK_NGX_Parameter_TrueHDR_InRight, _inputSize.width);
NVSDK_NGX_Parameter_SetUI(_ngxParameters, NVSDK_NGX_Parameter_TrueHDR_InBottom, _inputSize.height);
NVSDK_NGX_Parameter_SetUI(_ngxParameters, NVSDK_NGX_Parameter_TrueHDR_OutLeft, 0);
NVSDK_NGX_Parameter_SetUI(_ngxParameters, NVSDK_NGX_Parameter_TrueHDR_OutTop, 0);
NVSDK_NGX_Parameter_SetUI(_ngxParameters, NVSDK_NGX_Parameter_TrueHDR_OutRight, _inputSize.width);
NVSDK_NGX_Parameter_SetUI(_ngxParameters, NVSDK_NGX_Parameter_TrueHDR_OutBottom, _inputSize.height);
NVSDK_NGX_Parameter_SetUI(_ngxParameters, NVSDK_NGX_Parameter_TrueHDR_Contrast, 100);
NVSDK_NGX_Parameter_SetUI(_ngxParameters, NVSDK_NGX_Parameter_TrueHDR_Saturation, 100);
NVSDK_NGX_Parameter_SetUI(_ngxParameters, NVSDK_NGX_Parameter_TrueHDR_MiddleGray, 50);
NVSDK_NGX_Parameter_SetUI(_ngxParameters, NVSDK_NGX_Parameter_TrueHDR_MaxLuminance,
(uint32_t)std::lroundf(_colorInfo.maxLuminance * SCENE_REFERRED_SDR_WHITE_LEVEL));
}
#ifdef _DEBUG
// 忽略 NGX 产生的调试层警告
winrt::com_ptr<ID3D12InfoQueue> infoQueue;
_graphicsContext->GetDevice()->QueryInterface(IID_PPV_ARGS(&infoQueue));
if (infoQueue) {
D3D12_MESSAGE_ID denyList[] = {
D3D12_MESSAGE_ID_CREATERESOURCE_STATE_IGNORED
};
D3D12_INFO_QUEUE_FILTER filter = {
.DenyList = {
.NumIDs = (UINT)std::size(denyList),
.pIDList = denyList
}
};
infoQueue->PushCopyOfStorageFilter();
infoQueue->AddStorageFilterEntries(&filter);
}
#endif
NVSDK_NGX_Result status = NVSDK_NGX_D3D12_EvaluateFeature(
commandList, _trueHdrFeature, _ngxParameters, nullptr);
if (NVSDK_NGX_FAILED(status)) {
return E_FAIL;
}
#ifdef _DEBUG
if (infoQueue) {
infoQueue->PopStorageFilter();
}
#endif
return S_OK;
}
void RtxTrueHdrDrawer::OnColorInfoChanged(const ColorInfo& colorInfo) noexcept {
_colorInfo = colorInfo;
if (_trueHdrFeature) {
NVSDK_NGX_Parameter_SetUI(_ngxParameters, NVSDK_NGX_Parameter_TrueHDR_MaxLuminance,
(uint32_t)std::lroundf(colorInfo.maxLuminance * SCENE_REFERRED_SDR_WHITE_LEVEL));
}
}
}

View file

@ -0,0 +1,43 @@
#pragma once
struct NVSDK_NGX_Parameter;
struct NVSDK_NGX_Handle;
namespace Magpie {
class GraphicsContext;
class RtxTrueHdrDrawer {
public:
~RtxTrueHdrDrawer() noexcept;
HRESULT Initialize(
GraphicsContext& graphicsContext,
Size inputSize,
const ColorInfo& colorInfo
) noexcept;
Size GetOutputSize() const noexcept {
return _inputSize;
}
HRESULT Draw() noexcept;
void OnColorInfoChanged(const ColorInfo& colorInfo) noexcept;
private:
GraphicsContext* _graphicsContext = nullptr;
Size _inputSize{};
ColorInfo _colorInfo;
winrt::com_ptr<ID3D12Resource> _ngxInputResource;
winrt::com_ptr<ID3D12Resource> _ngxOutputResource;
winrt::com_ptr<ID3D12Resource> _colorFactorResource;
NVSDK_NGX_Parameter* _ngxParameters = nullptr;
NVSDK_NGX_Handle* _trueHdrFeature = nullptr;
bool _isNgxInitialized = false;
};
}

View file

@ -69,6 +69,7 @@ namespace Magpie {
static constexpr uint32_t MAX_CAPTURE_DIRTY_RECT_COUNT = 4;
static constexpr uint32_t DUP_FRAME_DISPATCH_BLOCK_SIZE = 16;
static constexpr uint32_t SCENE_REFERRED_SDR_WHITE_LEVEL = 80;
enum class ComponentState {
NoError,

View file

@ -1,2 +1,2 @@
#define MP_SRGB
#include "CatmullRomCS.hlsl"
#include "CopyCS.hlsl"

View file

@ -98,7 +98,10 @@
<Link>
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
<SubSystem>Windows</SubSystem>
<AdditionalLibraryDirectories>S:\RTX_Video_SDK_v1.1.0\lib\Windows\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>Gdi32.lib;Dwmapi.lib;Shell32.lib;Ole32.lib;Imagehlp.lib;Comctl32.lib;Shlwapi.lib;Magnification.lib;bcp47mrm.lib;Shcore.lib;Uxtheme.lib;Taskschd.lib;Dcomp.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies Condition="'$(Configuration)' == 'Debug'">nvsdk_ngx_s_dbg.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies Condition="'$(Configuration)' == 'Release'">nvsdk_ngx_s.lib;%(AdditionalDependencies)</AdditionalDependencies>
<DelayLoadDLLs>d3dcompiler_47.dll;Magnification.dll;Imagehlp.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
</Link>
</ItemDefinitionGroup>