Skip to content

Commit 87d3fbd

Browse files
D3D12: Implement ISuperResolution using DirectSR
1 parent 6559b6c commit 87d3fbd

9 files changed

Lines changed: 461 additions & 31 deletions

Graphics/GraphicsEngineD3D12/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ set(INCLUDE
4444
include/ShaderResourceCacheD3D12.hpp
4545
include/ShaderResourcesD3D12.hpp
4646
include/ShaderVariableManagerD3D12.hpp
47+
include/SuperResolutionD3D12Impl.hpp
4748
include/SwapChainD3D12Impl.hpp
4849
include/TextureD3D12Impl.hpp
4950
include/TextureViewD3D12Impl.hpp
@@ -108,6 +109,7 @@ set(SRC
108109
src/ShaderResourceCacheD3D12.cpp
109110
src/ShaderResourcesD3D12.cpp
110111
src/ShaderVariableManagerD3D12.cpp
112+
src/SuperResolutionD3D12Impl.cpp
111113
src/SwapChainD3D12Impl.cpp
112114
src/TextureD3D12Impl.cpp
113115
src/TextureViewD3D12Impl.cpp

Graphics/GraphicsEngineD3D12/include/D3D12Loader.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#pragma once
2929

3030
#include <d3d12.h>
31+
#include <directsr.h>
3132

3233
namespace Diligent
3334
{
@@ -48,10 +49,16 @@ using D3D12SerializeRootSignatureProcType = HRESULT(WINAPI*)(
4849
_Out_ ID3DBlob** ppBlob,
4950
_Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorBlob);
5051

52+
using DSRCreateDeviceFactoryProcType = HRESULT(WINAPI*)(
53+
_In_ REFIID riid,
54+
_COM_Outptr_opt_ void** ppvFactory);
55+
5156
extern D3D12CreateDeviceProcType D3D12CreateDevice;
5257
extern D3D12GetDebugInterfaceProcType D3D12GetDebugInterface;
5358
extern D3D12SerializeRootSignatureProcType D3D12SerializeRootSignature;
59+
extern DSRCreateDeviceFactoryProcType DSRCreateDeviceFactory;
5460

5561
HMODULE LoadD3D12Dll(const char* DLLPath = "d3d12.dll");
62+
HMODULE LoadDirectSRDll(const char* DLLPath = "DirectSR.dll");
5663

5764
} // namespace Diligent

Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
#include "DXCompiler.hpp"
4848
#include "RootSignature.hpp"
4949

50+
#include <directsr.h>
51+
5052

5153
// The macros below are only defined in Win SDK 19041+ and are missing in 17763
5254
#ifndef D3D12_RAYTRACING_MAX_RAY_GENERATION_SHADER_THREADS
@@ -223,6 +225,8 @@ class RenderDeviceD3D12Impl final : public RenderDeviceNextGenBase<RenderDeviceD
223225

224226
RootSignatureCacheD3D12& GetRootSignatureCache() { return m_RootSignatureCache; }
225227

228+
IDSRDevice* GetDSRDevice() const { return m_pDSRDevice; }
229+
226230
DescriptorHeapAllocation AllocateDescriptors(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1);
227231
DescriptorHeapAllocation AllocateGPUDescriptors(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1);
228232

@@ -345,6 +349,8 @@ class RenderDeviceD3D12Impl final : public RenderDeviceNextGenBase<RenderDeviceD
345349

346350
bool m_IsPSOCacheSupported = false;
347351

352+
CComPtr<IDSRDevice> m_pDSRDevice;
353+
348354
#ifdef DILIGENT_DEVELOPMENT
349355
Uint32 m_MaxD3D12DeviceVersion = 0;
350356
#endif
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright 2019-2026 Diligent Graphics LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* In no event and under no legal theory, whether in tort (including negligence),
17+
* contract, or otherwise, unless required by applicable law (such as deliberate
18+
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
19+
* liable for any damages, including any direct, indirect, special, incidental,
20+
* or consequential damages of any character arising as a result of this License or
21+
* out of the use or inability to use the software (including but not limited to damages
22+
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23+
* all other commercial damages or losses), even if such Contributor has been advised
24+
* of the possibility of such damages.
25+
*/
26+
27+
#pragma once
28+
29+
/// \file
30+
/// Declaration of Diligent::SuperResolutionD3D12Impl class
31+
32+
#include "EngineD3D12ImplTraits.hpp"
33+
#include "DeviceObjectBase.hpp"
34+
#include "SuperResolution.h"
35+
36+
#include <directsr.h>
37+
38+
namespace Diligent
39+
{
40+
41+
/// Implementation of the ISuperResolution interface for Direct3D12 backend using DirectSR.
42+
class SuperResolutionD3D12Impl final : public DeviceObjectBase<ISuperResolution, RenderDeviceD3D12Impl, SuperResolutionDesc>
43+
{
44+
public:
45+
using TSRUpscalerBase = DeviceObjectBase<ISuperResolution, RenderDeviceD3D12Impl, SuperResolutionDesc>;
46+
47+
SuperResolutionD3D12Impl(IReferenceCounters* pRefCounters,
48+
RenderDeviceD3D12Impl* pDevice,
49+
const SuperResolutionDesc& Desc);
50+
51+
~SuperResolutionD3D12Impl();
52+
53+
IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_SuperResolution, TSRUpscalerBase)
54+
55+
/// Implementation of ISuperResolution::GetOptimalJitterPattern().
56+
virtual void DILIGENT_CALL_TYPE GetOptimalJitterPattern(Uint32 Index,
57+
float* pJitterX,
58+
float* pJitterY) const override final;
59+
60+
/// Encodes the upscaling operation into the given command list.
61+
void Execute(ID3D12GraphicsCommandList* pd3d12CmdList,
62+
const ExecuteSuperResolutionAttribs& Attribs);
63+
64+
private:
65+
CComPtr<IDSRSuperResEngine> m_pDSREngine;
66+
};
67+
68+
} // namespace Diligent

Graphics/GraphicsEngineD3D12/src/D3D12Loader.cpp

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2025 Diligent Graphics LLC
2+
* Copyright 2019-2026 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,43 +39,59 @@ namespace Diligent
3939
D3D12CreateDeviceProcType D3D12CreateDevice;
4040
D3D12GetDebugInterfaceProcType D3D12GetDebugInterface;
4141
D3D12SerializeRootSignatureProcType D3D12SerializeRootSignature;
42+
DSRCreateDeviceFactoryProcType DSRCreateDeviceFactory;
43+
44+
#if PLATFORM_WIN32
45+
# define LOAD_D3D12_ENTRY_POINT(hModule, Func) \
46+
Func = reinterpret_cast<Func##ProcType>(GetProcAddress(hModule, #Func))
47+
#elif PLATFORM_UNIVERSAL_WINDOWS
48+
# define LOAD_D3D12_ENTRY_POINT(hModule, Func) Func = ::Func
49+
#else
50+
# error Unexpected platform
51+
#endif
4252

4353
HMODULE LoadD3D12Dll(const char* DLLPath)
4454
{
4555
#if PLATFORM_WIN32
4656
HMODULE hModule = LoadLibraryA(DLLPath);
47-
4857
if (hModule == NULL)
58+
return NULL;
59+
#else
60+
HMODULE hModule = (HMODULE)-1;
61+
#endif
62+
63+
LOAD_D3D12_ENTRY_POINT(hModule, D3D12CreateDevice);
64+
LOAD_D3D12_ENTRY_POINT(hModule, D3D12GetDebugInterface);
65+
LOAD_D3D12_ENTRY_POINT(hModule, D3D12SerializeRootSignature);
66+
67+
#if PLATFORM_WIN32
68+
if (!D3D12CreateDevice || !D3D12GetDebugInterface || !D3D12SerializeRootSignature)
4969
{
70+
LOG_ERROR_MESSAGE("Failed to load one or more entry points from '", DLLPath, "' dll");
71+
FreeLibrary(hModule);
5072
return NULL;
5173
}
74+
#endif
5275

53-
bool bAllEntriesLoaded = true;
54-
# define LOAD_D3D12_ENTRY_POINT(Func) \
55-
do \
56-
{ \
57-
Func = (Func##ProcType)GetProcAddress(hModule, #Func); \
58-
if (Func == NULL) \
59-
{ \
60-
bAllEntriesLoaded = false; \
61-
LOG_ERROR_MESSAGE("Failed to loader '" #Func "' function from '", DLLPath, "' dll"); \
62-
} \
63-
} while (false)
64-
#elif PLATFORM_UNIVERSAL_WINDOWS
65-
HMODULE hModule = (HMODULE)-1;
66-
# define LOAD_D3D12_ENTRY_POINT(Func) Func = ::Func
76+
return hModule;
77+
}
78+
79+
HMODULE LoadDirectSRDll(const char* DLLPath)
80+
{
81+
#if PLATFORM_WIN32
82+
HMODULE hModule = LoadLibraryA(DLLPath);
83+
if (hModule == NULL)
84+
return NULL;
6785
#else
68-
# error Unexpected platform
86+
HMODULE hModule = (HMODULE)-1;
6987
#endif
7088

71-
LOAD_D3D12_ENTRY_POINT(D3D12CreateDevice);
72-
LOAD_D3D12_ENTRY_POINT(D3D12GetDebugInterface);
73-
LOAD_D3D12_ENTRY_POINT(D3D12SerializeRootSignature);
74-
#undef LOAD_D3D12_ENTRY_POINT
89+
LOAD_D3D12_ENTRY_POINT(hModule, DSRCreateDeviceFactory);
7590

7691
#if PLATFORM_WIN32
77-
if (!bAllEntriesLoaded)
92+
if (!DSRCreateDeviceFactory)
7893
{
94+
LOG_ERROR_MESSAGE("Failed to load 'DSRCreateDeviceFactory' function from '", DLLPath, "' dll");
7995
FreeLibrary(hModule);
8096
return NULL;
8197
}

Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "d3dx12_win.h"
4949
#include "D3D12DynamicHeap.hpp"
5050
#include "QueryManagerD3D12.hpp"
51+
#include "SuperResolutionD3D12Impl.hpp"
5152
#include "DXGITypeConversions.hpp"
5253

5354
#include "D3D12TileMappingHelper.hpp"
@@ -3351,7 +3352,15 @@ void DeviceContextD3D12Impl::BindSparseResourceMemory(const BindSparseResourceMe
33513352
void DeviceContextD3D12Impl::ExecuteSuperResolution(const ExecuteSuperResolutionAttribs& Attribs,
33523353
ISuperResolution* pUpscaler)
33533354
{
3354-
UNSUPPORTED("ExecuteSuperResolution is not supported in DirectX 12");
3355+
DEV_CHECK_ERR(pUpscaler != nullptr, "pUpscaler must not be null");
3356+
3357+
auto* pUpscalerD3D12 = ClassPtrCast<SuperResolutionD3D12Impl>(pUpscaler);
3358+
3359+
auto& CmdCtx = GetCmdContext();
3360+
CmdCtx.FlushResourceBarriers();
3361+
3362+
auto* pd3d12CmdList = CmdCtx.GetCommandList();
3363+
pUpscalerD3D12->Execute(pd3d12CmdList, Attribs);
33553364
}
33563365

33573366
} // namespace Diligent

Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2025 Diligent Graphics LLC
2+
* Copyright 2019-2026 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -165,7 +165,8 @@ class EngineFactoryD3D12Impl : public EngineFactoryD3DBase<IEngineFactoryD3D12,
165165

166166
private:
167167
#if USE_D3D12_LOADER
168-
HMODULE m_hD3D12Dll = NULL;
168+
HMODULE m_hD3D12Dll = NULL;
169+
HMODULE m_hDirectSRDll = NULL;
169170
std::string m_DllName;
170171
#endif
171172
};
@@ -193,6 +194,15 @@ bool EngineFactoryD3D12Impl::LoadD3D12(const char* DllName)
193194
}
194195
}
195196
}
197+
198+
if (m_hDirectSRDll == NULL)
199+
{
200+
m_hDirectSRDll = LoadDirectSRDll();
201+
if (m_hDirectSRDll == NULL)
202+
{
203+
LOG_INFO_MESSAGE("DirectSR.dll is not available. DirectSR super resolution will be disabled.");
204+
}
205+
}
196206
#endif
197207

198208
return true;
@@ -1106,6 +1116,73 @@ GraphicsAdapterInfo EngineFactoryD3D12Impl::GetGraphicsAdapterInfo(void*
11061116
ASSERT_SIZEOF(DrawCommandProps, 12, "Did you add a new member to DrawCommandProperties? Please initialize it here.");
11071117
}
11081118

1119+
// Super resolution properties (DirectSR)
1120+
if (DSRCreateDeviceFactory != nullptr)
1121+
{
1122+
CComPtr<IDSRDeviceFactory> pDSRFactory;
1123+
HRESULT hr = DSRCreateDeviceFactory(IID_PPV_ARGS(&pDSRFactory));
1124+
if (SUCCEEDED(hr) && pDSRFactory)
1125+
{
1126+
CComPtr<IDSRDevice> pDSRDevice;
1127+
hr = pDSRFactory->CreateDSRDevice(d3d12Device, 0, IID_PPV_ARGS(&pDSRDevice));
1128+
if (SUCCEEDED(hr) && pDSRDevice)
1129+
{
1130+
const UINT NumVariants = pDSRDevice->GetNumSuperResVariants();
1131+
if (NumVariants > 0)
1132+
{
1133+
Features.SuperResolution = DEVICE_FEATURE_STATE_ENABLED;
1134+
1135+
SuperResolutionProperties& SRProps{AdapterInfo.SuperResolution};
1136+
SRProps.NumUpscalers = 0;
1137+
1138+
for (UINT i = 0; i < NumVariants && SRProps.NumUpscalers < DILIGENT_MAX_SUPER_RESOLUTION_UPSCALERS; ++i)
1139+
{
1140+
DSR_SUPERRES_VARIANT_DESC VariantDesc = {};
1141+
hr = pDSRDevice->GetSuperResVariantInfo(i, &VariantDesc);
1142+
if (FAILED(hr))
1143+
continue;
1144+
1145+
SuperResolutionInfo& Info = SRProps.Upscalers[SRProps.NumUpscalers];
1146+
1147+
// Convert wide string name to narrow string
1148+
WideCharToMultiByte(CP_UTF8, 0, VariantDesc.FriendlyName, -1, Info.Name, sizeof(Info.Name) - 1, nullptr, nullptr);
1149+
Info.Name[sizeof(Info.Name) - 1] = '\0';
1150+
1151+
// Map variant GUID to VariantId
1152+
static_assert(sizeof(Info.VariantId) == sizeof(VariantDesc.VariantId), "GUID/INTERFACE_ID size mismatch");
1153+
memcpy(&Info.VariantId, &VariantDesc.VariantId, sizeof(Info.VariantId));
1154+
1155+
// Determine upscaler type and capabilities from DirectSR flags
1156+
if (VariantDesc.Flags & DSR_SUPERRES_VARIANT_FLAG_SUPPORTS_TEMPORAL_UPSCALING)
1157+
{
1158+
Info.Type = SUPER_RESOLUTION_UPSCALER_TYPE_TEMPORAL;
1159+
1160+
SUPER_RESOLUTION_TEMPORAL_CAP_FLAGS TemporalCaps = SUPER_RESOLUTION_TEMPORAL_CAP_FLAG_NATIVE;
1161+
1162+
if (VariantDesc.Flags & DSR_SUPERRES_VARIANT_FLAG_SUPPORTS_EXPOSURE_SCALE_TEXTURE)
1163+
TemporalCaps |= SUPER_RESOLUTION_TEMPORAL_CAP_FLAG_EXPOSURE_SCALE_TEXTURE;
1164+
if (VariantDesc.Flags & DSR_SUPERRES_VARIANT_FLAG_SUPPORTS_IGNORE_HISTORY_MASK)
1165+
TemporalCaps |= SUPER_RESOLUTION_TEMPORAL_CAP_FLAG_IGNORE_HISTORY_MASK;
1166+
if (VariantDesc.Flags & DSR_SUPERRES_VARIANT_FLAG_SUPPORTS_REACTIVE_MASK)
1167+
TemporalCaps |= SUPER_RESOLUTION_TEMPORAL_CAP_FLAG_REACTIVE_MASK;
1168+
if (VariantDesc.Flags & DSR_SUPERRES_VARIANT_FLAG_SUPPORTS_SHARPNESS)
1169+
TemporalCaps |= SUPER_RESOLUTION_TEMPORAL_CAP_FLAG_SHARPNESS;
1170+
1171+
Info.TemporalCapFlags = TemporalCaps;
1172+
}
1173+
else
1174+
{
1175+
Info.Type = SUPER_RESOLUTION_UPSCALER_TYPE_SPATIAL;
1176+
Info.SpatialCapFlags = SUPER_RESOLUTION_SPATIAL_CAP_FLAG_NATIVE;
1177+
}
1178+
1179+
SRProps.NumUpscalers++;
1180+
}
1181+
}
1182+
}
1183+
}
1184+
}
1185+
11091186
ASSERT_SIZEOF(DeviceFeatures, 48, "Did you add a new feature to DeviceFeatures? Please handle its status here.");
11101187

11111188
return AdapterInfo;

0 commit comments

Comments
 (0)