Skip to content

Commit 58431b0

Browse files
D3D12: Implement ISuperResolution using DirectSR
1 parent c3e38ac commit 58431b0

14 files changed

+587
-53
lines changed

Graphics/Archiver/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ if(D3D11_SUPPORTED)
118118
endif()
119119

120120
if(D3D12_SUPPORTED)
121-
target_link_libraries(Diligent-Archiver-static PRIVATE Diligent-GraphicsEngineD3D12-static)
121+
target_link_libraries(Diligent-Archiver-static PRIVATE Diligent-GraphicsEngineD3D12-static DirectSR-Headers)
122122
target_include_directories(Diligent-Archiver-static PRIVATE ../GraphicsEngineD3D12/include)
123123
endif()
124124

Graphics/GraphicsEngineD3D12/CMakeLists.txt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@ cmake_minimum_required (VERSION 3.11)
22

33
project(Diligent-GraphicsEngineD3D12 CXX)
44

5+
include(../../BuildTools/CMake/BuildUtils.cmake)
6+
7+
# Fetch DirectSR headers and Agility SDK DLLs
8+
FetchContent_DeclareShallowGit(DirectSR-Headers
9+
GIT_REPOSITORY https://github.com/MikhailGorobets/DirectSR-Headers.git
10+
GIT_TAG dev
11+
)
12+
FetchContent_MakeAvailable(DirectSR-Headers)
13+
14+
515
set(INCLUDE
616
include/BottomLevelASD3D12Impl.hpp
717
include/BufferD3D12Impl.hpp
@@ -44,6 +54,7 @@ set(INCLUDE
4454
include/ShaderResourceCacheD3D12.hpp
4555
include/ShaderResourcesD3D12.hpp
4656
include/ShaderVariableManagerD3D12.hpp
57+
include/SuperResolutionD3D12Impl.hpp
4758
include/SwapChainD3D12Impl.hpp
4859
include/TextureD3D12Impl.hpp
4960
include/TextureViewD3D12Impl.hpp
@@ -108,6 +119,7 @@ set(SRC
108119
src/ShaderResourceCacheD3D12.cpp
109120
src/ShaderResourcesD3D12.cpp
110121
src/ShaderVariableManagerD3D12.cpp
122+
src/SuperResolutionD3D12Impl.cpp
111123
src/SwapChainD3D12Impl.cpp
112124
src/TextureD3D12Impl.cpp
113125
src/TextureViewD3D12Impl.cpp
@@ -119,7 +131,7 @@ set(DLL_SRC
119131
src/GraphicsEngineD3D12.def
120132
)
121133

122-
if(PLATFORM_WIN32)
134+
if(PLATFORM_WIN32 OR PLATFORM_UNIVERSAL_WINDOWS)
123135
list(APPEND INCLUDE include/D3D12Loader.hpp)
124136
list(APPEND SRC src/D3D12Loader.cpp)
125137
set(USE_D3D12_LOADER 1)
@@ -194,6 +206,7 @@ PRIVATE
194206
Diligent-GraphicsEngineNextGenBase
195207
Diligent-TargetPlatform
196208
Diligent-ShaderTools
209+
DirectSR-Headers
197210
dxgi.lib
198211
d3dcompiler.lib
199212
PUBLIC

Graphics/GraphicsEngineD3D12/include/D3D12Loader.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2022 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");
@@ -29,6 +29,7 @@
2929

3030
#include <d3d12.h>
3131

32+
3233
namespace Diligent
3334
{
3435

@@ -48,9 +49,15 @@ using D3D12SerializeRootSignatureProcType = HRESULT(WINAPI*)(
4849
_Out_ ID3DBlob** ppBlob,
4950
_Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorBlob);
5051

52+
using D3D12GetInterfaceProcType = HRESULT(WINAPI*)(
53+
_In_ REFCLSID rclsid,
54+
_In_ REFIID riid,
55+
_COM_Outptr_opt_ void** ppvDebug);
56+
5157
extern D3D12CreateDeviceProcType D3D12CreateDevice;
5258
extern D3D12GetDebugInterfaceProcType D3D12GetDebugInterface;
5359
extern D3D12SerializeRootSignatureProcType D3D12SerializeRootSignature;
60+
extern D3D12GetInterfaceProcType D3D12GetInterface;
5461

5562
HMODULE LoadD3D12Dll(const char* DLLPath = "d3d12.dll");
5663

Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ D3D12_COMMAND_LIST_TYPE QueueIdToD3D12CommandListType(HardwareQueueIndex Qu
114114
COMMAND_QUEUE_TYPE D3D12CommandListTypeToCmdQueueType(D3D12_COMMAND_LIST_TYPE ListType);
115115
D3D12_COMMAND_QUEUE_PRIORITY QueuePriorityToD3D12QueuePriority(QUEUE_PRIORITY Priority);
116116

117+
DSR_SUPERRES_CREATE_ENGINE_FLAGS SuperResolutionCreateFlagsToDSRFlags(SUPER_RESOLUTION_CREATE_FLAGS Flags);
118+
117119
static constexpr HardwareQueueIndex D3D12HWQueueIndex_Graphics{Uint8{0}};
118120
static constexpr HardwareQueueIndex D3D12HWQueueIndex_Compute{Uint8{1}};
119121
static constexpr HardwareQueueIndex D3D12HWQueueIndex_Copy{Uint8{2}};

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: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright 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 <vector>
37+
38+
39+
namespace Diligent
40+
{
41+
42+
class DeviceContextD3D12Impl;
43+
44+
/// Implementation of the ISuperResolution interface for Direct3D12 backend using DirectSR.
45+
class SuperResolutionD3D12Impl final : public DeviceObjectBase<ISuperResolution, RenderDeviceD3D12Impl, SuperResolutionDesc>
46+
{
47+
public:
48+
using TSRUpscalerBase = DeviceObjectBase<ISuperResolution, RenderDeviceD3D12Impl, SuperResolutionDesc>;
49+
50+
SuperResolutionD3D12Impl(IReferenceCounters* pRefCounters,
51+
RenderDeviceD3D12Impl* pDevice,
52+
const SuperResolutionDesc& Desc);
53+
54+
~SuperResolutionD3D12Impl();
55+
56+
IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_SuperResolution, TSRUpscalerBase)
57+
58+
/// Implementation of ISuperResolution::GetOptimalJitterPattern().
59+
virtual void DILIGENT_CALL_TYPE GetOptimalJitterPattern(Uint32 Index, float* pJitterX, float* pJitterY) const override final;
60+
61+
/// Encodes the upscaling operation.
62+
void Execute(DeviceContextD3D12Impl& Ctx, const ExecuteSuperResolutionAttribs& Attribs);
63+
64+
private:
65+
CComPtr<IDSRSuperResEngine> m_pDSREngine;
66+
std::vector<CComPtr<IDSRSuperResUpscaler>> m_DSRUpscalers;
67+
std::vector<DSR_FLOAT2> m_JitterPattern;
68+
};
69+
70+
} // namespace Diligent

Graphics/GraphicsEngineD3D12/include/pch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "WinHPreface.h"
3535

3636
#include <d3d12.h>
37+
#include <directsr.h>
3738
#include <atlbase.h>
3839

3940
#if USE_D3D12_LOADER

Graphics/GraphicsEngineD3D12/src/D3D12Loader.cpp

Lines changed: 24 additions & 25 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,42 @@ namespace Diligent
3939
D3D12CreateDeviceProcType D3D12CreateDevice;
4040
D3D12GetDebugInterfaceProcType D3D12GetDebugInterface;
4141
D3D12SerializeRootSignatureProcType D3D12SerializeRootSignature;
42+
D3D12GetInterfaceProcType D3D12GetInterface;
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)
49-
{
5058
return NULL;
51-
}
52-
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
6759
#else
68-
# error Unexpected platform
60+
HMODULE hModule = (HMODULE)-1;
6961
#endif
7062

71-
LOAD_D3D12_ENTRY_POINT(D3D12CreateDevice);
72-
LOAD_D3D12_ENTRY_POINT(D3D12GetDebugInterface);
73-
LOAD_D3D12_ENTRY_POINT(D3D12SerializeRootSignature);
74-
#undef LOAD_D3D12_ENTRY_POINT
63+
LOAD_D3D12_ENTRY_POINT(hModule, D3D12CreateDevice);
64+
LOAD_D3D12_ENTRY_POINT(hModule, D3D12GetDebugInterface);
65+
LOAD_D3D12_ENTRY_POINT(hModule, D3D12SerializeRootSignature);
66+
67+
// D3D12GetInterface is optional (available in newer SDK versions, required for DirectSR).
68+
// On Win32 it may be nullptr on older SDKs; on UWP it is not available in d3d12.lib.
69+
// All call sites handle nullptr gracefully (DirectSR features are disabled at runtime).
70+
#if PLATFORM_WIN32
71+
LOAD_D3D12_ENTRY_POINT(hModule, D3D12GetInterface);
72+
#endif
7573

7674
#if PLATFORM_WIN32
77-
if (!bAllEntriesLoaded)
75+
if (!D3D12CreateDevice || !D3D12GetDebugInterface || !D3D12SerializeRootSignature)
7876
{
77+
LOG_ERROR_MESSAGE("Failed to load one or more entry points from '", DLLPath, "' dll");
7978
FreeLibrary(hModule);
8079
return NULL;
8180
}

Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,4 +1019,16 @@ D3D12_SHADING_RATE_COMBINER ShadingRateCombinerToD3D12ShadingRateCombiner(SHADIN
10191019
#endif
10201020
}
10211021

1022+
DSR_SUPERRES_CREATE_ENGINE_FLAGS SuperResolutionCreateFlagsToDSRFlags(SUPER_RESOLUTION_CREATE_FLAGS Flags)
1023+
{
1024+
DSR_SUPERRES_CREATE_ENGINE_FLAGS DSRFlags = DSR_SUPERRES_CREATE_ENGINE_FLAG_NONE;
1025+
1026+
if (Flags & SUPER_RESOLUTION_CREATE_FLAG_AUTO_EXPOSURE)
1027+
DSRFlags |= DSR_SUPERRES_CREATE_ENGINE_FLAG_AUTO_EXPOSURE;
1028+
if (Flags & SUPER_RESOLUTION_CREATE_FLAG_ENABLE_SHARPENING)
1029+
DSRFlags |= DSR_SUPERRES_CREATE_ENGINE_FLAG_ENABLE_SHARPENING;
1030+
1031+
return DSRFlags;
1032+
}
1033+
10221034
} // namespace Diligent

Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp

Lines changed: 13 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,18 @@ 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+
// DirectSR submits its own command list(s) to the command queue
3360+
// We must flush the current command list first so that all rendering work producing the input resources (color, depth, motion vectors) is submitted to the GPU before DirectSR reads them.
3361+
TransitionOrVerifyTextureState(GetCmdContext(), *ClassPtrCast<TextureD3D12Impl>(Attribs.pOutputTextureView->GetTexture()), RESOURCE_STATE_TRANSITION_MODE_TRANSITION, RESOURCE_STATE_UNORDERED_ACCESS, "OutputTexture before DirectSR");
3362+
3363+
Flush();
3364+
pUpscalerD3D12->Execute(*this, Attribs);
3365+
3366+
TransitionOrVerifyTextureState(GetCmdContext(), *ClassPtrCast<TextureD3D12Impl>(Attribs.pOutputTextureView->GetTexture()), RESOURCE_STATE_TRANSITION_MODE_TRANSITION, RESOURCE_STATE_SHADER_RESOURCE, "OutputTexture after DirectSR");
33553367
}
33563368

33573369
} // namespace Diligent

0 commit comments

Comments
 (0)