Browse Source

Merge pull request #107 from godlikepanos/dlss

DLSS support
Panagiotis Christopoulos Charitos 3 years ago
parent
commit
3a7c6bd628
100 changed files with 4564 additions and 581 deletions
  1. 1 1
      .clang-format
  2. 17 0
      .github/workflows/Linux.yml
  3. 16 2
      .github/workflows/Windows.yml
  4. 4 0
      .gitignore
  5. 0 0
      .gitmodules
  6. 1 0
      AnKi/Config.h.cmake
  7. 1 0
      AnKi/Gr.h
  8. 34 3
      AnKi/Gr/CMakeLists.txt
  9. 17 0
      AnKi/Gr/CommandBuffer.h
  10. 5 1
      AnKi/Gr/Common.h
  11. 6 1
      AnKi/Gr/Enums.h
  12. 1 0
      AnKi/Gr/GrManager.h
  13. 1 0
      AnKi/Gr/GrObject.h
  14. 78 0
      AnKi/Gr/GrUpscaler.h
  15. 9 0
      AnKi/Gr/RenderGraph.h
  16. 2 0
      AnKi/Gr/Utils/InstantiationMacros.h
  17. 10 0
      AnKi/Gr/Vulkan/CommandBuffer.cpp
  18. 104 2
      AnKi/Gr/Vulkan/CommandBufferImpl.cpp
  19. 11 0
      AnKi/Gr/Vulkan/CommandBufferImpl.h
  20. 3 0
      AnKi/Gr/Vulkan/Common.h
  21. 2 0
      AnKi/Gr/Vulkan/GrManager.cpp
  22. 21 0
      AnKi/Gr/Vulkan/GrManagerImpl.cpp
  23. 6 0
      AnKi/Gr/Vulkan/GrManagerImpl.h
  24. 24 0
      AnKi/Gr/Vulkan/GrUpscaler.cpp
  25. 178 0
      AnKi/Gr/Vulkan/GrUpscalerImpl.cpp
  26. 77 0
      AnKi/Gr/Vulkan/GrUpscalerImpl.h
  27. 1 1
      AnKi/Gr/Vulkan/ShaderImpl.cpp
  28. 1 0
      AnKi/Gr/Vulkan/TextureImpl.cpp
  29. 1 1
      AnKi/Gr/Vulkan/TextureImpl.h
  30. 1 0
      AnKi/Gr/Vulkan/VulkanObject.cpp
  31. 5 0
      AnKi/Importer/TinyExr.cpp
  32. 55 165
      AnKi/Math/Mat.h
  33. 1 1
      AnKi/Renderer/Bloom.cpp
  34. 1 1
      AnKi/Renderer/CMakeLists.txt
  35. 3 2
      AnKi/Renderer/ConfigVars.defs.h
  36. 1 1
      AnKi/Renderer/Dbg.cpp
  37. 21 11
      AnKi/Renderer/DownscaleBlur.cpp
  38. 20 20
      AnKi/Renderer/Drawer.cpp
  39. 21 7
      AnKi/Renderer/Drawer.h
  40. 2 2
      AnKi/Renderer/FinalComposite.cpp
  41. 9 5
      AnKi/Renderer/ForwardShading.cpp
  42. 16 13
      AnKi/Renderer/GBuffer.cpp
  43. 25 12
      AnKi/Renderer/IndirectDiffuseProbes.cpp
  44. 1 1
      AnKi/Renderer/LensFlare.cpp
  45. 27 14
      AnKi/Renderer/ProbeReflections.cpp
  46. 2 2
      AnKi/Renderer/RenderQueue.h
  47. 58 47
      AnKi/Renderer/Renderer.cpp
  48. 2 5
      AnKi/Renderer/Renderer.h
  49. 269 68
      AnKi/Renderer/Scale.cpp
  50. 57 19
      AnKi/Renderer/Scale.h
  51. 11 6
      AnKi/Renderer/ShadowMapping.cpp
  52. 1 1
      AnKi/Renderer/TemporalAA.cpp
  53. 6 1
      AnKi/Renderer/TemporalAA.h
  54. 14 29
      AnKi/Renderer/Tonemapping.cpp
  55. 7 4
      AnKi/Renderer/Tonemapping.h
  56. 2 2
      AnKi/Scene/Components/FrustumComponent.cpp
  57. 2 2
      AnKi/Scene/Components/FrustumComponent.h
  58. 3 3
      AnKi/Scene/DebugDrawer.cpp
  59. 2 2
      AnKi/Scene/DebugDrawer.h
  60. 27 19
      AnKi/Scene/Visibility.cpp
  61. 1 1
      AnKi/ShaderCompiler/ShaderProgramDump.cpp
  62. 1 1
      AnKi/ShaderCompiler/ShaderProgramReflection.cpp
  63. 4 5
      AnKi/Shaders/Bloom.glsl
  64. 1 1
      AnKi/Shaders/DownscaleBlur.glsl
  65. 4 2
      AnKi/Shaders/GBufferCommon.glsl
  66. 10 8
      AnKi/Shaders/GBufferGeneric.ankiprog
  67. 13 14
      AnKi/Shaders/Include/ClusteredShadingTypes.h
  68. 2 1
      AnKi/Shaders/Include/MaterialTypes.h
  69. 1 2
      AnKi/Shaders/TemporalAA.glsl
  70. 55 0
      AnKi/Shaders/Tonemap.glsl
  71. 8 0
      AnKi/Shaders/TonemapCompute.ankiprog
  72. 12 0
      AnKi/Shaders/TonemapRaster.ankiprog
  73. 3 4
      AnKi/Shaders/TonemappingAverageLuminance.ankiprog
  74. 15 9
      AnKi/Shaders/TonemappingResources.glsl
  75. 1 2
      AnKi/Shaders/VolumetricLightingAccumulation.ankiprog
  76. 6 3
      AnKi/Util/Logger.cpp
  77. 39 35
      AnKi/Util/SparseArray.inl.h
  78. 1 0
      AnKi/Util/StdTypes.h
  79. 40 10
      CMakeLists.txt
  80. 4 4
      Tests/Math/Math.cpp
  81. 0 1
      Tests/Util/Filesystem.cpp
  82. 1 1
      Tests/Util/SparseArray.cpp
  83. 29 0
      ThirdParty/DlssSdk/CMakeLists.txt
  84. 408 0
      ThirdParty/DlssSdk/sdk/LICENSE.txt
  85. 15 0
      ThirdParty/DlssSdk/sdk/README.md
  86. 439 0
      ThirdParty/DlssSdk/sdk/include/nvsdk_ngx.h
  87. 610 0
      ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_defs.h
  88. 630 0
      ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_helpers.h
  89. 319 0
      ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_helpers_vk.h
  90. 124 0
      ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_params.h
  91. 464 0
      ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_vk.h
  92. BIN
      ThirdParty/DlssSdk/sdk/lib/Linux_x86_64/libnvsdk_ngx.a
  93. BIN
      ThirdParty/DlssSdk/sdk/lib/Linux_x86_64/rel/libnvidia-ngx-dlss.so.2.4.0
  94. BIN
      ThirdParty/DlssSdk/sdk/lib/Windows_x86_64/dev/nvngx_dlss.dll
  95. BIN
      ThirdParty/DlssSdk/sdk/lib/Windows_x86_64/rel/nvngx_dlss.dll
  96. BIN
      ThirdParty/DlssSdk/sdk/lib/Windows_x86_64/x86_64/nvsdk_ngx_d.lib
  97. BIN
      ThirdParty/DlssSdk/sdk/lib/Windows_x86_64/x86_64/nvsdk_ngx_d_dbg.lib
  98. BIN
      ThirdParty/DlssSdk/sdk/lib/Windows_x86_64/x86_64/nvsdk_ngx_d_dbg_iterator0.lib
  99. BIN
      ThirdParty/DlssSdk/sdk/lib/Windows_x86_64/x86_64/nvsdk_ngx_d_dbg_iterator1.lib
  100. BIN
      ThirdParty/DlssSdk/sdk/lib/Windows_x86_64/x86_64/nvsdk_ngx_d_iterator1.lib

+ 1 - 1
.clang-format

@@ -124,7 +124,7 @@ PenaltyReturnTypeOnItsOwnLine: 60
 PenaltyIndentedWhitespace: 0
 PenaltyIndentedWhitespace: 0
 PointerAlignment: Left
 PointerAlignment: Left
 ReflowComments:  true
 ReflowComments:  true
-SortIncludes:    true
+SortIncludes:    false
 SortJavaStaticImport: Before
 SortJavaStaticImport: Before
 SortUsingDeclarations: false
 SortUsingDeclarations: false
 SpaceAfterCStyleCast: false
 SpaceAfterCStyleCast: false

+ 17 - 0
.github/workflows/Linux.yml

@@ -92,3 +92,20 @@ jobs:
 
 
     - name: Build
     - name: Build
       run: cmake --build ${{github.workspace}}/build --config Release
       run: cmake --build ${{github.workspace}}/build --config Release
+
+  DLSS:
+    name: "DLSS"
+    runs-on: ubuntu-latest
+
+    steps:
+    - name: Install dependencies
+      run: sudo apt install libx11-dev libx11-xcb-dev clang gcc
+
+    - name: Clone
+      uses: actions/checkout@v2
+
+    - name: Configure CMake
+      run: cmake -B ${{github.workspace}}/build -DANKI_BUILD_TESTS=OFF -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Release -DANKI_EXTRA_CHECKS=ON -DANKI_DLSS=ON
+
+    - name: Build
+      run: cmake --build ${{github.workspace}}/build --config Release --target Sponza

+ 16 - 2
.github/workflows/Windows.yml

@@ -20,7 +20,7 @@ jobs:
 
 
     - name: Build
     - name: Build
       run: cmake --build ${{github.workspace}}/build --config Debug
       run: cmake --build ${{github.workspace}}/build --config Debug
-      
+
   Release:
   Release:
     name: "Release"
     name: "Release"
     runs-on: windows-latest
     runs-on: windows-latest
@@ -30,7 +30,21 @@ jobs:
       uses: actions/checkout@v2
       uses: actions/checkout@v2
 
 
     - name: Configure CMake
     - name: Configure CMake
-      run: cmake -B ${{github.workspace}}/build -DANKI_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug -DANKI_EXTRA_CHECKS=OFF
+      run: cmake -B ${{github.workspace}}/build -DANKI_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release -DANKI_EXTRA_CHECKS=OFF
 
 
     - name: Build
     - name: Build
       run: cmake --build ${{github.workspace}}/build --config Release
       run: cmake --build ${{github.workspace}}/build --config Release
+
+  DLSS:
+    name: "DLSS"
+    runs-on: windows-latest
+
+    steps:
+    - name: Clone
+      uses: actions/checkout@v2
+
+    - name: Configure CMake
+      run: cmake -B ${{github.workspace}}/build -DANKI_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DANKI_EXTRA_CHECKS=OFF -DANKI_DLSS=ON
+
+    - name: Build
+      run: cmake --build ${{github.workspace}}/build --config Release --target Sponza

+ 4 - 0
.gitignore

@@ -1,3 +1,7 @@
 build*/*
 build*/*
 out/*
 out/*
 .*
 .*
+CMakeSettings.json
+*.TMP
+AndroidProject_*
+*diff*

+ 0 - 0
.gitmodules


+ 1 - 0
AnKi/Config.h.cmake

@@ -23,6 +23,7 @@
 #define ANKI_TESTS ${ANKI_TESTS}
 #define ANKI_TESTS ${ANKI_TESTS}
 #define ANKI_ENABLE_TRACE ${_ANKI_ENABLE_TRACE}
 #define ANKI_ENABLE_TRACE ${_ANKI_ENABLE_TRACE}
 #define ANKI_SOURCE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
 #define ANKI_SOURCE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+#define ANKI_DLSS ${_ANKI_DLSS_ENABLED}
 
 
 // Compiler
 // Compiler
 #if defined(__clang__)
 #if defined(__clang__)

+ 1 - 0
AnKi/Gr.h

@@ -19,6 +19,7 @@
 #include <AnKi/Gr/AccelerationStructure.h>
 #include <AnKi/Gr/AccelerationStructure.h>
 #include <AnKi/Gr/GrManager.h>
 #include <AnKi/Gr/GrManager.h>
 #include <AnKi/Gr/RenderGraph.h>
 #include <AnKi/Gr/RenderGraph.h>
+#include <AnKi/Gr/GrUpscaler.h>
 
 
 #include <AnKi/Gr/Utils/FrameGpuAllocator.h>
 #include <AnKi/Gr/Utils/FrameGpuAllocator.h>
 #include <AnKi/Gr/Utils/Functions.h>
 #include <AnKi/Gr/Utils/Functions.h>

+ 34 - 3
AnKi/Gr/CMakeLists.txt

@@ -29,6 +29,7 @@ set(common_headers
 	Texture.h
 	Texture.h
 	TextureView.h
 	TextureView.h
 	TimestampQuery.h
 	TimestampQuery.h
+	GrUpscaler.h
 	Utils/FrameGpuAllocator.h
 	Utils/FrameGpuAllocator.h
 	Utils/Functions.h
 	Utils/Functions.h
 	Utils/InstantiationMacros.h)
 	Utils/InstantiationMacros.h)
@@ -72,7 +73,9 @@ if(VULKAN)
 		Vulkan/TimestampQuery.cpp
 		Vulkan/TimestampQuery.cpp
 		Vulkan/TimestampQueryImpl.cpp
 		Vulkan/TimestampQueryImpl.cpp
 		Vulkan/VulkanObject.cpp
 		Vulkan/VulkanObject.cpp
-		Vulkan/FrameGarbageCollector.cpp)
+		Vulkan/FrameGarbageCollector.cpp
+		Vulkan/GrUpscaler.cpp
+		Vulkan/GrUpscalerImpl.cpp)
 
 
 	set(backend_headers
 	set(backend_headers
 		Vulkan/AccelerationStructureImpl.h
 		Vulkan/AccelerationStructureImpl.h
@@ -109,7 +112,8 @@ if(VULKAN)
 		Vulkan/TextureImpl.h
 		Vulkan/TextureImpl.h
 		Vulkan/TextureViewImpl.h
 		Vulkan/TextureViewImpl.h
 		Vulkan/TimestampQueryImpl.h
 		Vulkan/TimestampQueryImpl.h
-		Vulkan/VulkanObject.h)
+		Vulkan/VulkanObject.h
+		Vulkan/GrUpscalerImpl.h)
 
 
 	if(ANKI_HEADLESS)
 	if(ANKI_HEADLESS)
 		set(backend_sources ${backend_sources} "Vulkan/GrManagerImplHeadless.cpp")
 		set(backend_sources ${backend_sources} "Vulkan/GrManagerImplHeadless.cpp")
@@ -127,6 +131,33 @@ add_library(AnKiGrCommon ${common_sources} ${common_headers})
 target_compile_definitions(AnKiGrCommon PRIVATE -DANKI_SOURCE_FILE)
 target_compile_definitions(AnKiGrCommon PRIVATE -DANKI_SOURCE_FILE)
 target_link_libraries(AnKiGrCommon AnKiUtil) # Only depend on Util
 target_link_libraries(AnKiGrCommon AnKiUtil) # Only depend on Util
 
 
+if(ANKI_DLSS)
+	set(extra_libs AnKiNgx)
+endif()
+
 add_library(AnKiGr ${backend_sources} ${backend_headers})
 add_library(AnKiGr ${backend_sources} ${backend_headers})
 target_compile_definitions(AnKiGr PRIVATE -DANKI_SOURCE_FILE)
 target_compile_definitions(AnKiGr PRIVATE -DANKI_SOURCE_FILE)
-target_link_libraries(AnKiGr AnKiCore AnKiSpirvCross AnKiGrCommon)
+target_link_libraries(AnKiGr AnKiCore AnKiSpirvCross AnKiGrCommon ${extra_libs})
+
+# Copy DLSS files to Bin
+if(ANKI_DLSS)
+	get_target_property(lib_type AnKiNgx TYPE)
+	if("${lib_type}" STREQUAL "SHARED_LIBRARY")
+		get_target_property(ANKINGX_DLL AnKiNgx IMPORTED_LOCATION)
+		add_custom_command(
+			TARGET AnKiGr
+			COMMENT "Dependant DLLs copy ${ANKINGX_DLL} ${CMAKE_BINARY_DIR}/Bin"
+			COMMAND ${CMAKE_COMMAND} -E copy_if_different "${ANKINGX_DLL}" "${CMAKE_BINARY_DIR}/Bin")
+	else()
+		get_property(__NGX_DLLS_LIST TARGET AnKiNgx PROPERTY ANKINGX_EXTRA_DLLS)
+		foreach(dll_path ${__NGX_DLLS_LIST})
+			file(GLOB dll_files "${dll_path}")
+			foreach(dll_file ${dll_files})
+				add_custom_command(
+				TARGET AnKiGr
+				COMMENT "NGX DLL copy ${dll_file} ${CMAKE_BINARY_DIR}/Bin\n"
+				COMMAND ${CMAKE_COMMAND} -E copy_if_different "${dll_file}" "${CMAKE_BINARY_DIR}/Bin")
+			endforeach()
+		endforeach()
+	endif()
+endif()

+ 17 - 0
AnKi/Gr/CommandBuffer.h

@@ -9,6 +9,7 @@
 #include <AnKi/Gr/Framebuffer.h>
 #include <AnKi/Gr/Framebuffer.h>
 #include <AnKi/Util/Functions.h>
 #include <AnKi/Util/Functions.h>
 #include <AnKi/Util/WeakArray.h>
 #include <AnKi/Util/WeakArray.h>
+#include <AnKi/Math.h>
 
 
 namespace anki {
 namespace anki {
 
 
@@ -409,6 +410,22 @@ public:
 
 
 	/// Build the acceleration structure.
 	/// Build the acceleration structure.
 	void buildAccelerationStructure(const AccelerationStructurePtr& as);
 	void buildAccelerationStructure(const AccelerationStructurePtr& as);
+
+	/// Do upscaling by an external upscaler
+	/// @param[in] upscaler the upscaler to use for upscaling
+	/// @param[in] inColor Source LowRes RenderTarget.
+	/// @param[out] outUpscaledColor Destination HighRes RenderTarget
+	/// @param[in] motionVectors Motion Vectors
+	/// @param[in] depth Depth attachment
+	/// @param[in] exposure 1x1 Texture containing exposure
+	/// @param[in] resetAccumulation Whether to clean or not any temporal history
+	/// @param[in] jitterOffset Jittering offset that was applied during the generation of sourceTexture
+	/// @param[in] motionVectorsScale Any scale factor that might need to be applied to the motionVectorsTexture (i.e UV
+	///                               space to Pixel space conversion)
+	void upscale(const GrUpscalerPtr& upscaler, const TextureViewPtr& inColor, const TextureViewPtr& outUpscaledColor,
+				 const TextureViewPtr& motionVectors, const TextureViewPtr& depth, const TextureViewPtr& exposure,
+				 const Bool resetAccumulation, const Vec2& jitterOffset, const Vec2& motionVectorsScale);
+
 	/// @}
 	/// @}
 
 
 	/// @name Sync
 	/// @name Sync

+ 5 - 1
AnKi/Gr/Common.h

@@ -27,7 +27,7 @@ class ShaderInitInfo;
 class ShaderProgramInitInfo;
 class ShaderProgramInitInfo;
 class CommandBufferInitInfo;
 class CommandBufferInitInfo;
 class AccelerationStructureInitInfo;
 class AccelerationStructureInitInfo;
-
+class GrUpscalerInitInfo;
 /// @addtogroup graphics
 /// @addtogroup graphics
 /// @{
 /// @{
 
 
@@ -73,6 +73,7 @@ ANKI_GR_CLASS(ShaderProgram)
 ANKI_GR_CLASS(Fence)
 ANKI_GR_CLASS(Fence)
 ANKI_GR_CLASS(RenderGraph)
 ANKI_GR_CLASS(RenderGraph)
 ANKI_GR_CLASS(AccelerationStructure)
 ANKI_GR_CLASS(AccelerationStructure)
+ANKI_GR_CLASS(GrUpscaler)
 
 
 #undef ANKI_GR_CLASS
 #undef ANKI_GR_CLASS
 
 
@@ -182,6 +183,9 @@ public:
 
 
 	/// Supports or not 24bit, 48bit or 96bit texture formats.
 	/// Supports or not 24bit, 48bit or 96bit texture formats.
 	Bool m_unalignedBbpTextureFormats = false;
 	Bool m_unalignedBbpTextureFormats = false;
+
+	/// DLSS.
+	Bool m_dlss = false;
 };
 };
 ANKI_END_PACKED_STRUCT
 ANKI_END_PACKED_STRUCT
 
 

+ 6 - 1
AnKi/Gr/Enums.h

@@ -240,7 +240,12 @@ enum class TextureUsageBit : U32
 	ALL_READ = ALL_SAMPLED | IMAGE_GEOMETRY_READ | IMAGE_FRAGMENT_READ | IMAGE_COMPUTE_READ | IMAGE_TRACE_RAYS_READ
 	ALL_READ = ALL_SAMPLED | IMAGE_GEOMETRY_READ | IMAGE_FRAGMENT_READ | IMAGE_COMPUTE_READ | IMAGE_TRACE_RAYS_READ
 			   | FRAMEBUFFER_ATTACHMENT_READ | FRAMEBUFFER_SHADING_RATE | PRESENT | GENERATE_MIPMAPS,
 			   | FRAMEBUFFER_ATTACHMENT_READ | FRAMEBUFFER_SHADING_RATE | PRESENT | GENERATE_MIPMAPS,
 	ALL_WRITE = IMAGE_GEOMETRY_WRITE | IMAGE_FRAGMENT_WRITE | IMAGE_COMPUTE_WRITE | IMAGE_TRACE_RAYS_WRITE
 	ALL_WRITE = IMAGE_GEOMETRY_WRITE | IMAGE_FRAGMENT_WRITE | IMAGE_COMPUTE_WRITE | IMAGE_TRACE_RAYS_WRITE
-				| FRAMEBUFFER_ATTACHMENT_WRITE | TRANSFER_DESTINATION | GENERATE_MIPMAPS
+				| FRAMEBUFFER_ATTACHMENT_WRITE | TRANSFER_DESTINATION | GENERATE_MIPMAPS,
+
+	/// Make GR upscaling usage equal to ALL_IMAGE to force GENERAL layout because who knows.
+	ALL_GR_UPSCALING = ALL_IMAGE,
+	ALL_GR_UPSCALING_READ = ALL_GR_UPSCALING & ALL_READ,
+	ALL_GR_UPSCALING_WRITE = ALL_GR_UPSCALING & ALL_WRITE,
 };
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(TextureUsageBit)
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(TextureUsageBit)
 
 

+ 1 - 0
AnKi/Gr/GrManager.h

@@ -83,6 +83,7 @@ public:
 	[[nodiscard]] OcclusionQueryPtr newOcclusionQuery();
 	[[nodiscard]] OcclusionQueryPtr newOcclusionQuery();
 	[[nodiscard]] TimestampQueryPtr newTimestampQuery();
 	[[nodiscard]] TimestampQueryPtr newTimestampQuery();
 	[[nodiscard]] RenderGraphPtr newRenderGraph();
 	[[nodiscard]] RenderGraphPtr newRenderGraph();
+	[[nodiscard]] GrUpscalerPtr newGrUpscaler(const GrUpscalerInitInfo& init);
 	[[nodiscard]] AccelerationStructurePtr newAccelerationStructure(const AccelerationStructureInitInfo& init);
 	[[nodiscard]] AccelerationStructurePtr newAccelerationStructure(const AccelerationStructureInitInfo& init);
 	/// @}
 	/// @}
 
 

+ 1 - 0
AnKi/Gr/GrObject.h

@@ -29,6 +29,7 @@ enum class GrObjectType : U8
 	FENCE,
 	FENCE,
 	RENDER_GRAPH,
 	RENDER_GRAPH,
 	ACCELERATION_STRUCTURE,
 	ACCELERATION_STRUCTURE,
+	GR_UPSCALER,
 
 
 	COUNT,
 	COUNT,
 	FIRST = 0
 	FIRST = 0

+ 78 - 0
AnKi/Gr/GrUpscaler.h

@@ -0,0 +1,78 @@
+// Copyright (C) 2009-2022, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/GrObject.h>
+#include <AnKi/Math.h>
+#include <AnKi/Util/WeakArray.h>
+
+namespace anki {
+
+/// @addtogroup graphics
+/// @{
+
+/// Different upscalers supported internally by GrUpscaler
+enum class GrUpscalerType : U8
+{
+	DLSS_2 = 0,
+	COUNT
+};
+
+/// Quality preset to be used by the upscaler if available
+enum class GrUpscalerQualityMode : U8
+{
+	PERFORMANCE,
+	BALANCED,
+	QUALITY,
+
+	COUNT
+};
+ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(GrUpscalerQualityMode)
+
+/// Initialization structure for the upscaler
+class GrUpscalerInitInfo : public GrBaseInitInfo
+{
+public:
+	UVec2 m_sourceTextureResolution = UVec2(0u);
+	UVec2 m_targetTextureResolution = UVec2(0u);
+	GrUpscalerType m_upscalerType = GrUpscalerType::COUNT;
+	GrUpscalerQualityMode m_qualityMode = GrUpscalerQualityMode::PERFORMANCE;
+};
+
+class GrUpscaler : public GrObject
+{
+	ANKI_GR_OBJECT
+
+public:
+	static constexpr GrObjectType CLASS_TYPE = GrObjectType::GR_UPSCALER;
+
+	GrUpscalerType getUpscalerType() const
+	{
+		ANKI_ASSERT(m_upscalerType != GrUpscalerType::COUNT);
+		return m_upscalerType;
+	}
+
+protected:
+	GrUpscalerType m_upscalerType = GrUpscalerType::COUNT;
+
+	/// Construct.
+	GrUpscaler(GrManager* manager, CString name)
+		: GrObject(manager, CLASS_TYPE, name)
+	{
+	}
+
+	/// Destroy.
+	~GrUpscaler()
+	{
+	}
+
+private:
+	/// Allocate and initialize a new instance.
+	[[nodiscard]] static GrUpscaler* newInstance(GrManager* manager, const GrUpscalerInitInfo& initInfo);
+};
+/// @}
+
+} // end namespace anki

+ 9 - 0
AnKi/Gr/RenderGraph.h

@@ -127,6 +127,15 @@ public:
 	void getRenderTargetState(RenderTargetHandle handle, const TextureSubresourceInfo& subresource,
 	void getRenderTargetState(RenderTargetHandle handle, const TextureSubresourceInfo& subresource,
 							  TexturePtr& tex) const;
 							  TexturePtr& tex) const;
 
 
+	/// Create a whole texture view from a handle
+	TextureViewPtr createTextureView(RenderTargetHandle handle)
+	{
+		TexturePtr tex = getTexture(handle);
+		TextureViewInitInfo viewInit(tex, "TmpRenderGraph"); // Use the whole texture
+		getRenderTargetState(handle, viewInit, tex);
+		return m_commandBuffer->getManager().newTextureView(viewInit);
+	}
+
 	/// Convenience method.
 	/// Convenience method.
 	void bindTextureAndSampler(U32 set, U32 binding, RenderTargetHandle handle,
 	void bindTextureAndSampler(U32 set, U32 binding, RenderTargetHandle handle,
 							   const TextureSubresourceInfo& subresource, const SamplerPtr& sampler)
 							   const TextureSubresourceInfo& subresource, const SamplerPtr& sampler)

+ 2 - 0
AnKi/Gr/Utils/InstantiationMacros.h

@@ -28,3 +28,5 @@ ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT(TextureView)
 ANKI_INSTANTIATE_GR_OBJECT(TextureView)
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
 ANKI_INSTANTIATE_GR_OBJECT(AccelerationStructure)
 ANKI_INSTANTIATE_GR_OBJECT(AccelerationStructure)
+ANKI_INSTANTIATE_GR_OBJECT_DELIMITER()
+ANKI_INSTANTIATE_GR_OBJECT(GrUpscaler)

+ 10 - 0
AnKi/Gr/Vulkan/CommandBuffer.cpp

@@ -362,6 +362,16 @@ void CommandBuffer::buildAccelerationStructure(const AccelerationStructurePtr& a
 	self.buildAccelerationStructureInternal(as);
 	self.buildAccelerationStructureInternal(as);
 }
 }
 
 
+void CommandBuffer::upscale(const GrUpscalerPtr& upscaler, const TextureViewPtr& inColor,
+							const TextureViewPtr& outUpscaledColor, const TextureViewPtr& motionVectors,
+							const TextureViewPtr& depth, const TextureViewPtr& exposure, const Bool resetAccumulation,
+							const Vec2& jitterOffset, const Vec2& motionVectorsScale)
+{
+	ANKI_VK_SELF(CommandBufferImpl);
+	self.upscaleInternal(upscaler, inColor, outUpscaledColor, motionVectors, depth, exposure, resetAccumulation,
+						 jitterOffset, motionVectorsScale);
+}
+
 void CommandBuffer::setTextureBarrier(const TexturePtr& tex, TextureUsageBit prevUsage, TextureUsageBit nextUsage,
 void CommandBuffer::setTextureBarrier(const TexturePtr& tex, TextureUsageBit prevUsage, TextureUsageBit nextUsage,
 									  const TextureSubresourceInfo& subresource)
 									  const TextureSubresourceInfo& subresource)
 {
 {

+ 104 - 2
AnKi/Gr/Vulkan/CommandBufferImpl.cpp

@@ -6,10 +6,17 @@
 #include <AnKi/Gr/Vulkan/CommandBufferImpl.h>
 #include <AnKi/Gr/Vulkan/CommandBufferImpl.h>
 #include <AnKi/Gr/GrManager.h>
 #include <AnKi/Gr/GrManager.h>
 #include <AnKi/Gr/Vulkan/GrManagerImpl.h>
 #include <AnKi/Gr/Vulkan/GrManagerImpl.h>
-
 #include <AnKi/Gr/Framebuffer.h>
 #include <AnKi/Gr/Framebuffer.h>
-#include <AnKi/Gr/Vulkan/FramebufferImpl.h>
+#include <AnKi/Gr/Vulkan/GrUpscalerImpl.h>
 #include <AnKi/Gr/Vulkan/AccelerationStructureImpl.h>
 #include <AnKi/Gr/Vulkan/AccelerationStructureImpl.h>
+#include <AnKi/Gr/Vulkan/FramebufferImpl.h>
+
+#if ANKI_DLSS
+#	include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx.h>
+#	include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_helpers.h>
+#	include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_vk.h>
+#	include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_helpers_vk.h>
+#endif
 
 
 #include <algorithm>
 #include <algorithm>
 
 
@@ -786,4 +793,99 @@ void CommandBufferImpl::buildAccelerationStructureInternal(const AccelerationStr
 	m_microCmdb->pushObjectRef(scratchBuff);
 	m_microCmdb->pushObjectRef(scratchBuff);
 }
 }
 
 
+#if ANKI_DLSS
+/// Utility function to get the NGX's resource structure for a texture
+/// @param[in] tex the texture to generate the NVSDK_NGX_Resource_VK from
+static NVSDK_NGX_Resource_VK getNGXResourceFromAnkiTexture(const TextureViewImpl& view)
+{
+	const TextureImpl& tex = view.getTextureImpl();
+
+	const VkImageView imageView = view.getHandle();
+	const VkFormat format = tex.m_vkFormat;
+	const VkImage image = tex.m_imageHandle;
+	const VkImageSubresourceRange subresourceRange = view.getVkImageSubresourceRange();
+	const Bool isUAV = !!(tex.m_vkUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT);
+
+	// TODO Not sure if I should pass the width,height of the image or the view
+	return NVSDK_NGX_Create_ImageView_Resource_VK(imageView, image, subresourceRange, format, tex.getWidth(),
+												  tex.getHeight(), isUAV);
+}
+#endif
+
+void CommandBufferImpl::upscaleInternal(const GrUpscalerPtr& upscaler, const TextureViewPtr& inColor,
+										const TextureViewPtr& outUpscaledColor, const TextureViewPtr& motionVectors,
+										const TextureViewPtr& depth, const TextureViewPtr& exposure,
+										const Bool resetAccumulation, const Vec2& jitterOffset,
+										const Vec2& motionVectorsScale)
+{
+#if ANKI_DLSS
+	ANKI_ASSERT(getGrManagerImpl().getDeviceCapabilities().m_dlss);
+	ANKI_ASSERT(upscaler->getUpscalerType() == GrUpscalerType::DLSS_2);
+
+	commandCommon();
+	flushBatches(CommandBufferCommandType::ANY_OTHER_COMMAND);
+
+	const GrUpscalerImpl& upscalerImpl = static_cast<const GrUpscalerImpl&>(*upscaler);
+
+	const TextureViewImpl& srcViewImpl = static_cast<const TextureViewImpl&>(*inColor);
+	const TextureViewImpl& dstViewImpl = static_cast<const TextureViewImpl&>(*outUpscaledColor);
+	const TextureViewImpl& mvViewImpl = static_cast<const TextureViewImpl&>(*motionVectors);
+	const TextureViewImpl& depthViewImpl = static_cast<const TextureViewImpl&>(*depth);
+	const TextureViewImpl& exposureViewImpl = static_cast<const TextureViewImpl&>(*exposure);
+
+	NVSDK_NGX_Resource_VK srcResVk = getNGXResourceFromAnkiTexture(srcViewImpl);
+	NVSDK_NGX_Resource_VK dstResVk = getNGXResourceFromAnkiTexture(dstViewImpl);
+	NVSDK_NGX_Resource_VK mvResVk = getNGXResourceFromAnkiTexture(mvViewImpl);
+	NVSDK_NGX_Resource_VK depthResVk = getNGXResourceFromAnkiTexture(depthViewImpl);
+	NVSDK_NGX_Resource_VK exposureResVk = getNGXResourceFromAnkiTexture(exposureViewImpl);
+
+	const U32 mipLevel = srcViewImpl.getSubresource().m_firstMipmap;
+	const NVSDK_NGX_Coordinates renderingOffset = {0, 0};
+	const NVSDK_NGX_Dimensions renderingSize = {srcViewImpl.getTextureImpl().getWidth() >> mipLevel,
+												srcViewImpl.getTextureImpl().getHeight() >> mipLevel};
+
+	NVSDK_NGX_VK_DLSS_Eval_Params vkDlssEvalParams;
+	memset(&vkDlssEvalParams, 0, sizeof(vkDlssEvalParams));
+	vkDlssEvalParams.Feature.pInColor = &srcResVk;
+	vkDlssEvalParams.Feature.pInOutput = &dstResVk;
+	vkDlssEvalParams.pInDepth = &depthResVk;
+	vkDlssEvalParams.pInMotionVectors = &mvResVk;
+	vkDlssEvalParams.pInExposureTexture = &exposureResVk;
+	vkDlssEvalParams.InJitterOffsetX = jitterOffset.x();
+	vkDlssEvalParams.InJitterOffsetY = jitterOffset.y();
+	vkDlssEvalParams.InReset = resetAccumulation;
+	vkDlssEvalParams.InMVScaleX = motionVectorsScale.x();
+	vkDlssEvalParams.InMVScaleY = motionVectorsScale.y();
+	vkDlssEvalParams.InColorSubrectBase = renderingOffset;
+	vkDlssEvalParams.InDepthSubrectBase = renderingOffset;
+	vkDlssEvalParams.InTranslucencySubrectBase = renderingOffset;
+	vkDlssEvalParams.InMVSubrectBase = renderingOffset;
+	vkDlssEvalParams.InRenderSubrectDimensions = renderingSize;
+
+	getGrManagerImpl().beginMarker(m_handle, "DLSS");
+	NVSDK_NGX_Parameter* dlssParameters = &upscalerImpl.getParameters();
+	NVSDK_NGX_Handle* dlssFeature = &upscalerImpl.getFeature();
+	const NVSDK_NGX_Result result =
+		NGX_VULKAN_EVALUATE_DLSS_EXT(m_handle, dlssFeature, dlssParameters, &vkDlssEvalParams);
+	getGrManagerImpl().endMarker(m_handle);
+
+	if(NVSDK_NGX_FAILED(result))
+	{
+		ANKI_VK_LOGF("Failed to NVSDK_NGX_VULKAN_EvaluateFeature for DLSS, code = 0x%08x, info: %ls", result,
+					 GetNGXResultAsString(result));
+	}
+#else
+	ANKI_ASSERT(0 && "Not supported");
+	(void)upscaler;
+	(void)inColor;
+	(void)outUpscaledColor;
+	(void)motionVectors;
+	(void)depth;
+	(void)exposure;
+	(void)resetAccumulation;
+	(void)jitterOffset;
+	(void)motionVectorsScale;
+#endif
+}
+
 } // end namespace anki
 } // end namespace anki

+ 11 - 0
AnKi/Gr/Vulkan/CommandBufferImpl.h

@@ -330,6 +330,12 @@ public:
 
 
 	void pushSecondLevelCommandBufferInternal(const CommandBufferPtr& cmdb);
 	void pushSecondLevelCommandBufferInternal(const CommandBufferPtr& cmdb);
 
 
+	// To enable using Anki's commandbuffers for external workloads
+	void beginRecordingExt()
+	{
+		commandCommon();
+	}
+
 	void endRecording();
 	void endRecording();
 
 
 	void setTextureBarrierInternal(const TexturePtr& tex, TextureUsageBit prevUsage, TextureUsageBit nextUsage,
 	void setTextureBarrierInternal(const TexturePtr& tex, TextureUsageBit prevUsage, TextureUsageBit nextUsage,
@@ -393,6 +399,11 @@ public:
 
 
 	void buildAccelerationStructureInternal(const AccelerationStructurePtr& as);
 	void buildAccelerationStructureInternal(const AccelerationStructurePtr& as);
 
 
+	void upscaleInternal(const GrUpscalerPtr& upscaler, const TextureViewPtr& inColor,
+						 const TextureViewPtr& outUpscaledColor, const TextureViewPtr& motionVectors,
+						 const TextureViewPtr& depth, const TextureViewPtr& exposure, const Bool resetAccumulation,
+						 const Vec2& jitterOffset, const Vec2& motionVectorsScale);
+
 	void setPushConstantsInternal(const void* data, U32 dataSize);
 	void setPushConstantsInternal(const void* data, U32 dataSize);
 
 
 	void setRasterizationOrderInternal(RasterizationOrder order);
 	void setRasterizationOrderInternal(RasterizationOrder order);

+ 3 - 0
AnKi/Gr/Vulkan/Common.h

@@ -88,6 +88,9 @@ enum class VulkanExtensions : U32
 	KHR_FRAGMENT_SHADING_RATE = 1 << 23,
 	KHR_FRAGMENT_SHADING_RATE = 1 << 23,
 	EXT_ASTC_DECODE_MODE = 1 << 24,
 	EXT_ASTC_DECODE_MODE = 1 << 24,
 	EXT_TEXTURE_COMPRESSION_ASTC_HDR = 1 << 25,
 	EXT_TEXTURE_COMPRESSION_ASTC_HDR = 1 << 25,
+	NVX_BINARY_IMPORT = 1 << 26,
+	NVX_IMAGE_VIEW_HANDLE = 1 << 27,
+	KHR_PUSH_DESCRIPTOR = 1 << 28
 };
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(VulkanExtensions)
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(VulkanExtensions)
 
 

+ 2 - 0
AnKi/Gr/Vulkan/GrManager.cpp

@@ -18,6 +18,7 @@
 #include <AnKi/Gr/TimestampQuery.h>
 #include <AnKi/Gr/TimestampQuery.h>
 #include <AnKi/Gr/RenderGraph.h>
 #include <AnKi/Gr/RenderGraph.h>
 #include <AnKi/Gr/AccelerationStructure.h>
 #include <AnKi/Gr/AccelerationStructure.h>
+#include <AnKi/Gr/GrUpscaler.h>
 
 
 namespace anki {
 namespace anki {
 
 
@@ -139,6 +140,7 @@ ANKI_NEW_GR_OBJECT_NO_INIT_INFO(OcclusionQuery)
 ANKI_NEW_GR_OBJECT_NO_INIT_INFO(TimestampQuery)
 ANKI_NEW_GR_OBJECT_NO_INIT_INFO(TimestampQuery)
 ANKI_NEW_GR_OBJECT_NO_INIT_INFO(RenderGraph)
 ANKI_NEW_GR_OBJECT_NO_INIT_INFO(RenderGraph)
 ANKI_NEW_GR_OBJECT(AccelerationStructure)
 ANKI_NEW_GR_OBJECT(AccelerationStructure)
+ANKI_NEW_GR_OBJECT(GrUpscaler)
 
 
 #undef ANKI_NEW_GR_OBJECT
 #undef ANKI_NEW_GR_OBJECT
 #undef ANKI_NEW_GR_OBJECT_NO_INIT_INFO
 #undef ANKI_NEW_GR_OBJECT_NO_INIT_INFO

+ 21 - 0
AnKi/Gr/Vulkan/GrManagerImpl.cpp

@@ -15,6 +15,9 @@
 
 
 namespace anki {
 namespace anki {
 
 
+// DLSS related
+#define ANKI_VK_NVX_BINARY_IMPORT "VK_NVX_binary_import"
+
 GrManagerImpl::~GrManagerImpl()
 GrManagerImpl::~GrManagerImpl()
 {
 {
 	ANKI_VK_LOGI("Destroying Vulkan backend");
 	ANKI_VK_LOGI("Destroying Vulkan backend");
@@ -544,6 +547,9 @@ Error GrManagerImpl::initInstance()
 	}
 	}
 #endif
 #endif
 
 
+	// DLSS checks
+	m_capabilities.m_dlss = ANKI_DLSS && m_capabilities.m_gpuVendor == GpuVendor::NVIDIA;
+
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 
@@ -755,6 +761,21 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 				m_extensions |= VulkanExtensions::EXT_TEXTURE_COMPRESSION_ASTC_HDR;
 				m_extensions |= VulkanExtensions::EXT_TEXTURE_COMPRESSION_ASTC_HDR;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
 			}
+			else if(m_capabilities.m_dlss && extensionName == VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)
+			{
+				m_extensions |= VulkanExtensions::KHR_PUSH_DESCRIPTOR;
+				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
+			}
+			else if(m_capabilities.m_dlss && extensionName == ANKI_VK_NVX_BINARY_IMPORT)
+			{
+				m_extensions |= VulkanExtensions::NVX_BINARY_IMPORT;
+				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
+			}
+			else if(m_capabilities.m_dlss && extensionName == VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME)
+			{
+				m_extensions |= VulkanExtensions::NVX_IMAGE_VIEW_HANDLE;
+				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
+			}
 		}
 		}
 
 
 		ANKI_VK_LOGI("Will enable the following device extensions:");
 		ANKI_VK_LOGI("Will enable the following device extensions:");

+ 6 - 0
AnKi/Gr/Vulkan/GrManagerImpl.h

@@ -81,6 +81,12 @@ public:
 		return m_physicalDevice;
 		return m_physicalDevice;
 	}
 	}
 
 
+	VkInstance getInstance() const
+	{
+		ANKI_ASSERT(m_instance);
+		return m_instance;
+	}
+
 	/// @name object_creation
 	/// @name object_creation
 	/// @{
 	/// @{
 
 

+ 24 - 0
AnKi/Gr/Vulkan/GrUpscaler.cpp

@@ -0,0 +1,24 @@
+// Copyright (C) 2009-2022, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/GrUpscaler.h>
+#include <AnKi/Gr/GrManager.h>
+#include <AnKi/Gr/Vulkan/GrUpscalerImpl.h>
+
+namespace anki {
+
+GrUpscaler* GrUpscaler::newInstance(GrManager* manager, const GrUpscalerInitInfo& initInfo)
+{
+	GrUpscalerImpl* impl = manager->getAllocator().newInstance<GrUpscalerImpl>(manager, initInfo.getName());
+	const Error err = impl->initInternal(initInfo);
+	if(err)
+	{
+		manager->getAllocator().deleteInstance(impl);
+		impl = nullptr;
+	}
+	return impl;
+}
+
+} // end namespace anki

+ 178 - 0
AnKi/Gr/Vulkan/GrUpscalerImpl.cpp

@@ -0,0 +1,178 @@
+// Copyright (C) 2009-2022, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/Vulkan/GrUpscalerImpl.h>
+#include <AnKi/Gr/Vulkan/GrManagerImpl.h>
+#include <AnKi/Gr/CommandBuffer.h>
+#include <AnKi/Gr/Fence.h>
+#include <AnKi/Gr/Vulkan/CommandBufferImpl.h>
+
+// Ngx specific
+#if ANKI_DLSS
+#	include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx.h>
+#	include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_helpers.h>
+#	include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_vk.h>
+#	include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_helpers_vk.h>
+#endif
+
+namespace anki {
+
+GrUpscalerImpl::~GrUpscalerImpl()
+{
+#if ANKI_DLSS
+	if(m_upscalerType == GrUpscalerType::DLSS_2)
+	{
+		destroyDlss();
+	}
+#endif
+}
+
+Error GrUpscalerImpl::initInternal(const GrUpscalerInitInfo& initInfo)
+{
+	m_upscalerType = initInfo.m_upscalerType;
+
+#if ANKI_DLSS
+	ANKI_ASSERT(initInfo.m_upscalerType == GrUpscalerType::DLSS_2);
+	ANKI_CHECK(initDlss(initInfo));
+#else
+	ANKI_ASSERT(!"Not supported");
+#endif
+
+	return Error::NONE;
+}
+
+// ==== DLSS ====
+#if ANKI_DLSS
+
+#	define ANKI_NGX_CHECK(x_) \
+		do \
+		{ \
+			const NVSDK_NGX_Result result = x_; \
+			if(NVSDK_NGX_FAILED(result)) \
+			{ \
+				ANKI_VK_LOGE("DLSS failed to initialize %ls", GetNGXResultAsString(result)); \
+				return Error::FUNCTION_FAILED; \
+			} \
+		} while(0)
+
+static NVSDK_NGX_PerfQuality_Value getDlssQualityModeToNVQualityMode(GrUpscalerQualityMode mode)
+{
+	static Array<NVSDK_NGX_PerfQuality_Value, U32(GrUpscalerQualityMode::COUNT)> nvQualityModes = {
+		NVSDK_NGX_PerfQuality_Value_MaxPerf, NVSDK_NGX_PerfQuality_Value_Balanced,
+		NVSDK_NGX_PerfQuality_Value_MaxQuality};
+
+	return nvQualityModes[mode];
+}
+
+Error GrUpscalerImpl::initDlss(const GrUpscalerInitInfo& initInfo)
+{
+	const VkDevice vkdevice = getGrManagerImpl().getDevice();
+	const VkPhysicalDevice vkphysicaldevice = getGrManagerImpl().getPhysicalDevice();
+	const VkInstance vkinstance = getGrManagerImpl().getInstance();
+	const U32 ngxAppId = 231313132; // Something random
+	const WChar* appLogs = L"./";
+	ANKI_NGX_CHECK(NVSDK_NGX_VULKAN_Init(ngxAppId, appLogs, vkinstance, vkphysicaldevice, vkdevice));
+	m_ngxInitialized = true;
+
+	ANKI_NGX_CHECK(NVSDK_NGX_VULKAN_GetCapabilityParameters(&m_ngxParameters));
+	ANKI_ASSERT(m_ngxParameters);
+
+	// Currently, the SDK and this sample are not in sync.  The sample is a bit forward looking,
+	// in this case.  This will likely be resolved very shortly, and therefore, the code below
+	// should be thought of as needed for a smooth user experience.
+#	if defined(NVSDK_NGX_Parameter_SuperSampling_NeedsUpdatedDriver) \
+		&& defined(NVSDK_NGX_Parameter_SuperSampling_MinDriverVersionMajor) \
+		&& defined(NVSDK_NGX_Parameter_SuperSampling_MinDriverVersionMinor)
+
+	// If NGX Successfully initialized then it should set those flags in return
+	I32 needsUpdatedDriver = 0;
+	ANKI_NGX_CHECK(m_ngxParameters->Get(NVSDK_NGX_Parameter_SuperSampling_NeedsUpdatedDriver, &needsUpdatedDriver));
+
+	if(needsUpdatedDriver)
+	{
+		ANKI_VK_LOGE("DLSS cannot be loaded due to outdated driver");
+		return Error::FUNCTION_FAILED;
+	}
+#	endif
+
+	I32 dlssAvailable = 0;
+	ANKI_NGX_CHECK(m_ngxParameters->Get(NVSDK_NGX_Parameter_SuperSampling_Available, &dlssAvailable));
+	if(!dlssAvailable)
+	{
+		ANKI_VK_LOGE("NVIDIA DLSS not available on this hardware/platform");
+		return Error::FUNCTION_FAILED;
+	}
+
+	// Create the feature
+	ANKI_CHECK(createDlssFeature(initInfo.m_sourceTextureResolution, initInfo.m_targetTextureResolution,
+								 initInfo.m_qualityMode));
+
+	return Error::NONE;
+}
+
+Error GrUpscalerImpl::createDlssFeature(const UVec2& srcRes, const UVec2& dstRes, const GrUpscalerQualityMode quality)
+{
+	NVSDK_NGX_PerfQuality_Value nvQuality = getDlssQualityModeToNVQualityMode(quality);
+	F32 sharpness; // Deprecared in newer DLSS
+	ANKI_NGX_CHECK(NGX_DLSS_GET_OPTIMAL_SETTINGS(
+		m_ngxParameters, dstRes.x(), dstRes.y(), nvQuality, &m_recommendedSettings.m_optimalRenderSize.x(),
+		&m_recommendedSettings.m_optimalRenderSize.y(), &m_recommendedSettings.m_dynamicMaximumRenderSize.x(),
+		&m_recommendedSettings.m_dynamicMaximumRenderSize.y(), &m_recommendedSettings.m_dynamicMinimumRenderSize.x(),
+		&m_recommendedSettings.m_dynamicMinimumRenderSize.y(), &sharpness));
+
+	// Next create features	(See NVSDK_NGX_DLSS_Feature_Flags in nvsdk_ngx_defs.h)
+	const I32 dlssCreateFeatureFlags =
+		NVSDK_NGX_DLSS_Feature_Flags_MVLowRes | NVSDK_NGX_DLSS_Feature_Flags_IsHDR; // TODO
+
+	NVSDK_NGX_DLSS_Create_Params dlssCreateParams;
+	memset(&dlssCreateParams, 0, sizeof(dlssCreateParams));
+	dlssCreateParams.Feature.InWidth = srcRes.x();
+	dlssCreateParams.Feature.InHeight = srcRes.y();
+	dlssCreateParams.Feature.InTargetWidth = dstRes.x();
+	dlssCreateParams.Feature.InTargetHeight = dstRes.y();
+	dlssCreateParams.Feature.InPerfQualityValue = nvQuality;
+	dlssCreateParams.InFeatureCreateFlags = dlssCreateFeatureFlags;
+
+	// Create the feature with a tmp CmdBuffer
+	CommandBufferInitInfo cmdbinit;
+	cmdbinit.m_flags = CommandBufferFlag::GENERAL_WORK | CommandBufferFlag::SMALL_BATCH;
+	CommandBufferPtr cmdb = getManager().newCommandBuffer(cmdbinit);
+	CommandBufferImpl& cmdbImpl = static_cast<CommandBufferImpl&>(*cmdb);
+
+	cmdbImpl.beginRecordingExt();
+	const U32 creationNodeMask = 1;
+	const U32 visibilityNodeMask = 1;
+	ANKI_NGX_CHECK(NGX_VULKAN_CREATE_DLSS_EXT(cmdbImpl.getHandle(), creationNodeMask, visibilityNodeMask,
+											  &m_dlssFeature, m_ngxParameters, &dlssCreateParams));
+	FencePtr fence;
+	cmdb->flush({}, &fence);
+	fence->clientWait(60.0_sec);
+
+	return Error::NONE;
+}
+
+void GrUpscalerImpl::destroyDlss()
+{
+	if(m_dlssFeature)
+	{
+		NVSDK_NGX_VULKAN_ReleaseFeature(m_dlssFeature);
+		m_dlssFeature = nullptr;
+	}
+
+	if(m_ngxParameters)
+	{
+		NVSDK_NGX_VULKAN_DestroyParameters(m_ngxParameters);
+		m_ngxParameters = nullptr;
+	}
+
+	if(m_ngxInitialized)
+	{
+		NVSDK_NGX_VULKAN_Shutdown();
+		m_ngxInitialized = false;
+	}
+}
+#endif // ANKI_DLSS
+
+} // end namespace anki

+ 77 - 0
AnKi/Gr/Vulkan/GrUpscalerImpl.h

@@ -0,0 +1,77 @@
+// Copyright (C) 2009-2022, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/GrUpscaler.h>
+#include <AnKi/Gr/Vulkan/VulkanObject.h>
+#include <AnKi/Gr/Vulkan/GpuMemoryManager.h>
+
+// Ngx Sdk forward declarations
+struct NVSDK_NGX_Parameter;
+struct NVSDK_NGX_Handle;
+
+namespace anki {
+
+/// @addtogroup vulkan
+/// @{
+
+class DLSSRecommendedSettings
+{
+public:
+	UVec2 m_optimalRenderSize = UVec2(MAX_U32);
+	UVec2 m_dynamicMaximumRenderSize = UVec2(MAX_U32);
+	UVec2 m_dynamicMinimumRenderSize = UVec2(MAX_U32);
+};
+
+class GrUpscalerImpl final : public GrUpscaler, public VulkanObject<GrUpscaler, GrUpscalerImpl>
+{
+public:
+	GrUpscalerImpl(GrManager* manager, CString name)
+		: GrUpscaler(manager, name)
+	{
+	}
+
+	~GrUpscalerImpl();
+
+	Error initInternal(const GrUpscalerInitInfo& initInfo);
+
+	/// @name DLSS data accessors
+	/// @{
+#if ANKI_DLSS
+	NVSDK_NGX_Parameter& getParameters() const
+	{
+		return *m_ngxParameters;
+	}
+
+	NVSDK_NGX_Handle& getFeature() const
+	{
+		return *m_dlssFeature;
+	}
+
+	const DLSSRecommendedSettings& getRecommendedSettings() const
+	{
+		return m_recommendedSettings;
+	}
+#endif
+	/// @}
+
+private:
+#if ANKI_DLSS
+	NVSDK_NGX_Parameter* m_ngxParameters = nullptr;
+	NVSDK_NGX_Handle* m_dlssFeature = nullptr;
+	DLSSRecommendedSettings m_recommendedSettings;
+	Bool m_ngxInitialized = false;
+
+	Error initDlss(const GrUpscalerInitInfo& initInfo);
+
+	void destroyDlss();
+
+	Error createDlssFeature(const UVec2& srcRes, const UVec2& dstRes, const GrUpscalerQualityMode mode);
+#endif
+};
+/// @}
+
+} // end namespace anki

+ 1 - 1
AnKi/Gr/Vulkan/ShaderImpl.cpp

@@ -6,7 +6,7 @@
 #include <AnKi/Gr/Vulkan/ShaderImpl.h>
 #include <AnKi/Gr/Vulkan/ShaderImpl.h>
 #include <AnKi/Gr/Vulkan/GrManagerImpl.h>
 #include <AnKi/Gr/Vulkan/GrManagerImpl.h>
 #include <AnKi/Gr/Utils/Functions.h>
 #include <AnKi/Gr/Utils/Functions.h>
-#include <SprivCross/spirv_cross.hpp>
+#include <SpirvCross/spirv_cross.hpp>
 
 
 #define ANKI_DUMP_SHADERS 0
 #define ANKI_DUMP_SHADERS 0
 
 

+ 1 - 0
AnKi/Gr/Vulkan/TextureImpl.cpp

@@ -277,6 +277,7 @@ Error TextureImpl::initImage(const TextureInitInfo& init)
 	ci.samples = VK_SAMPLE_COUNT_1_BIT;
 	ci.samples = VK_SAMPLE_COUNT_1_BIT;
 	ci.tiling = VK_IMAGE_TILING_OPTIMAL;
 	ci.tiling = VK_IMAGE_TILING_OPTIMAL;
 	ci.usage = convertTextureUsage(init.m_usage, init.m_format);
 	ci.usage = convertTextureUsage(init.m_usage, init.m_format);
+	m_vkUsageFlags = ci.usage;
 	ci.queueFamilyIndexCount = getGrManagerImpl().getQueueFamilies().getSize();
 	ci.queueFamilyIndexCount = getGrManagerImpl().getQueueFamilies().getSize();
 	ci.pQueueFamilyIndices = &getGrManagerImpl().getQueueFamilies()[0];
 	ci.pQueueFamilyIndices = &getGrManagerImpl().getQueueFamilies()[0];
 	ci.sharingMode = (ci.queueFamilyIndexCount > 1) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
 	ci.sharingMode = (ci.queueFamilyIndexCount > 1) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;

+ 1 - 1
AnKi/Gr/Vulkan/TextureImpl.h

@@ -84,7 +84,7 @@ public:
 	GpuMemoryHandle m_memHandle;
 	GpuMemoryHandle m_memHandle;
 
 
 	VkFormat m_vkFormat = VK_FORMAT_UNDEFINED;
 	VkFormat m_vkFormat = VK_FORMAT_UNDEFINED;
-
+	VkImageUsageFlags m_vkUsageFlags = 0;
 	VkImageViewCreateInfo m_viewCreateInfoTemplate;
 	VkImageViewCreateInfo m_viewCreateInfoTemplate;
 	VkImageViewASTCDecodeModeEXT m_astcDecodeMode;
 	VkImageViewASTCDecodeModeEXT m_astcDecodeMode;
 
 

+ 1 - 0
AnKi/Gr/Vulkan/VulkanObject.cpp

@@ -18,6 +18,7 @@
 #include <AnKi/Gr/Vulkan/TimestampQueryImpl.h>
 #include <AnKi/Gr/Vulkan/TimestampQueryImpl.h>
 #include <AnKi/Gr/Vulkan/FenceImpl.h>
 #include <AnKi/Gr/Vulkan/FenceImpl.h>
 #include <AnKi/Gr/Vulkan/AccelerationStructureImpl.h>
 #include <AnKi/Gr/Vulkan/AccelerationStructureImpl.h>
+#include <AnKi/Gr/Vulkan/GrUpscalerImpl.h>
 
 
 namespace anki {
 namespace anki {
 
 

+ 5 - 0
AnKi/Importer/TinyExr.cpp

@@ -15,10 +15,15 @@
 #	pragma GCC diagnostic ignored "-Wunused-function"
 #	pragma GCC diagnostic ignored "-Wunused-function"
 #	pragma GCC diagnostic ignored "-Wconversion"
 #	pragma GCC diagnostic ignored "-Wconversion"
 #	pragma GCC diagnostic ignored "-Wunused-variable"
 #	pragma GCC diagnostic ignored "-Wunused-variable"
+#elif ANKI_COMPILER_MSVC
+#	pragma warning(push)
+#	pragma warning(disable : 4018 4389 4189 4505 4706)
 #endif
 #endif
 
 
 #include <ThirdParty/TinyExr/tinyexr.h>
 #include <ThirdParty/TinyExr/tinyexr.h>
 
 
 #if ANKI_COMPILER_GCC_COMPATIBLE
 #if ANKI_COMPILER_GCC_COMPATIBLE
 #	pragma GCC diagnostic pop
 #	pragma GCC diagnostic pop
+#elif ANKI_COMPILER_MSVC
+#	pragma warning(pop)
 #endif
 #endif

+ 55 - 165
AnKi/Math/Mat.h

@@ -36,8 +36,8 @@ public:
 	using RowVec = TVec<T, I>;
 	using RowVec = TVec<T, I>;
 	using ColumnVec = TVec<T, J>;
 	using ColumnVec = TVec<T, J>;
 
 
-	static constexpr U ROW_SIZE = J; ///< Number of rows
-	static constexpr U COLUMN_SIZE = I; ///< Number of columns
+	static constexpr U ROW_COUNT = J; ///< Number of rows
+	static constexpr U COLUMN_COUNT = I; ///< Number of columns
 	static constexpr U SIZE = J * I; ///< Number of total elements
 	static constexpr U SIZE = J * I; ///< Number of total elements
 	static constexpr Bool HAS_SIMD = I == 4 && std::is_same<T, F32>::value && ANKI_ENABLE_SIMD;
 	static constexpr Bool HAS_SIMD = I == 4 && std::is_same<T, F32>::value && ANKI_ENABLE_SIMD;
 	static constexpr Bool HAS_MAT4_SIMD = J == 4 && I == 4 && std::is_same<T, F32>::value && ANKI_ENABLE_SIMD;
 	static constexpr Bool HAS_MAT4_SIMD = J == 4 && I == 4 && std::is_same<T, F32>::value && ANKI_ENABLE_SIMD;
@@ -50,46 +50,21 @@ public:
 	}
 	}
 
 
 	/// Copy.
 	/// Copy.
-	TMat(ANKI_ENABLE_ARG(const TMat&, !HAS_SIMD) b)
+	TMat(const TMat& b)
 	{
 	{
-		for(U i = 0; i < N; i++)
-		{
-			m_arr1[i] = b.m_arr1[i];
-		}
-	}
-
-	/// Copy.
-	TMat(ANKI_ENABLE_ARG(const TMat&, HAS_SIMD) b)
-	{
-		for(U i = 0; i < J; i++)
-		{
-			m_simd[i] = b.m_simd[i];
-		}
-	}
-
-	ANKI_ENABLE_METHOD(!HAS_SIMD)
-	explicit TMat(const T f)
-	{
-		for(T& x : m_arr1)
+		for(U i = 0; i < ROW_COUNT; i++)
 		{
 		{
-			x = f;
+			m_rows[i] = b.m_rows[i];
 		}
 		}
 	}
 	}
 
 
-#if ANKI_ENABLE_SIMD
-	ANKI_ENABLE_METHOD(HAS_SIMD)
 	explicit TMat(const T f)
 	explicit TMat(const T f)
 	{
 	{
-		for(U i = 0; i < J; i++)
+		for(U i = 0; i < ROW_COUNT; i++)
 		{
 		{
-#	if ANKI_SIMD_SSE
-			m_simd[i] = _mm_set1_ps(f);
-#	else
-			m_simd[i] = {f, f, f, f};
-#	endif
+			m_rows[i] = RowVec(f);
 		}
 		}
 	}
 	}
-#endif
 
 
 	explicit TMat(const T arr[])
 	explicit TMat(const T arr[])
 	{
 	{
@@ -182,6 +157,16 @@ public:
 	{
 	{
 	}
 	}
 
 
+	/// Set a 4x4 matrix using a 3x4 for the first 3 rows and a vec4 for the 4rth row.
+	ANKI_ENABLE_METHOD(J == 4 && I == 4)
+	explicit TMat(const TMat<T, 3, 4>& m3, const TVec<T, 4>& row3)
+	{
+		setRow(0, m3.getRow(0));
+		setRow(1, m3.getRow(1));
+		setRow(2, m3.getRow(2));
+		setRow(3, row3);
+	}
+
 	// 3x4 specific constructors
 	// 3x4 specific constructors
 
 
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
@@ -287,132 +272,52 @@ public:
 	/// @{
 	/// @{
 
 
 	/// Copy.
 	/// Copy.
-	TMat& operator=(ANKI_ENABLE_ARG(const TMat&, !HAS_SIMD) b)
-	{
-		for(U n = 0; n < N; n++)
-		{
-			m_arr1[n] = b.m_arr1[n];
-		}
-		return *this;
-	}
-
-	/// Copy.
-	TMat& operator=(ANKI_ENABLE_ARG(const TMat&, HAS_SIMD) b)
+	TMat& operator=(const TMat& b)
 	{
 	{
-		for(U i = 0; i < J; i++)
+		for(U i = 0; i < ROW_COUNT; ++i)
 		{
 		{
-			m_simd[i] = b.m_simd[i];
+			m_rows[i] = b.m_rows[i];
 		}
 		}
 		return *this;
 		return *this;
 	}
 	}
 
 
-	ANKI_ENABLE_METHOD(!HAS_SIMD)
-	TMat operator+(const TMat& b) const
-	{
-		TMat c;
-		for(U n = 0; n < N; n++)
-		{
-			c.m_arr1[n] = m_arr1[n] + b.m_arr1[n];
-		}
-		return c;
-	}
-
-#if ANKI_ENABLE_SIMD
-	ANKI_ENABLE_METHOD(HAS_SIMD)
 	TMat operator+(const TMat& b) const
 	TMat operator+(const TMat& b) const
 	{
 	{
 		TMat c;
 		TMat c;
-		for(U i = 0; i < J; i++)
+		for(U i = 0; i < ROW_COUNT; ++i)
 		{
 		{
-#	if ANKI_SIMD_SSE
-			c.m_simd[i] = _mm_add_ps(m_simd[i], b.m_simd[i]);
-#	else
-			c.m_simd[i] = m_simd[i] + b.m_simd[i];
-#	endif
+			c.m_rows[i] = m_rows[i] + b.m_rows[i];
 		}
 		}
 		return c;
 		return c;
 	}
 	}
-#endif
 
 
-	ANKI_ENABLE_METHOD(!HAS_SIMD)
-	TMat& operator+=(const TMat& b)
-	{
-		for(U n = 0; n < N; n++)
-		{
-			m_arr1[n] += b.m_arr1[n];
-		}
-		return *this;
-	}
-
-#if ANKI_ENABLE_SIMD
-	ANKI_ENABLE_METHOD(HAS_SIMD)
 	TMat& operator+=(const TMat& b)
 	TMat& operator+=(const TMat& b)
 	{
 	{
-		for(U i = 0; i < J; i++)
+		for(U i = 0; i < ROW_COUNT; ++i)
 		{
 		{
-#	if ANKI_SIMD_SSE
-			m_simd[i] = _mm_add_ps(m_simd[i], b.m_simd[i]);
-#	else
-			m_simd[i] += b.m_simd[i];
-#	endif
+			m_rows[i] += b.m_rows[i];
 		}
 		}
 		return *this;
 		return *this;
 	}
 	}
-#endif
 
 
-	ANKI_ENABLE_METHOD(!HAS_SIMD)
-	TMat operator-(const TMat& b) const
-	{
-		TMat c;
-		for(U n = 0; n < N; n++)
-		{
-			c.m_arr1[n] = m_arr1[n] - b.m_arr1[n];
-		}
-		return c;
-	}
-
-#if ANKI_ENABLE_SIMD
-	ANKI_ENABLE_METHOD(HAS_SIMD)
 	TMat operator-(const TMat& b) const
 	TMat operator-(const TMat& b) const
 	{
 	{
 		TMat c;
 		TMat c;
-		for(U i = 0; i < J; i++)
+		for(U i = 0; i < ROW_COUNT; ++i)
 		{
 		{
-#	if ANKI_SIMD_SSE
-			c.m_simd[i] = _mm_sub_ps(m_simd[i], b.m_simd[i]);
-#	else
-			c.m_simd[i] = m_simd[i] - b.m_simd[i];
-#	endif
+			c.m_rows[i] = m_rows[i] - b.m_rows[i];
 		}
 		}
 		return c;
 		return c;
 	}
 	}
-#endif
 
 
-	ANKI_ENABLE_METHOD(!HAS_SIMD)
-	TMat& operator-=(const TMat& b)
-	{
-		for(U n = 0; n < N; n++)
-		{
-			m_arr1[n] -= b.m_arr1[n];
-		}
-		return *this;
-	}
-
-#if ANKI_ENABLE_SIMD
-	ANKI_ENABLE_METHOD(HAS_SIMD)
 	TMat& operator-=(const TMat& b)
 	TMat& operator-=(const TMat& b)
 	{
 	{
-		for(U i = 0; i < J; i++)
+		for(U i = 0; i < ROW_COUNT; ++i)
 		{
 		{
-#	if ANKI_SIMD_SSE
-			m_simd[i] = _mm_sub_ps(m_simd[i], b.m_simd[i]);
-#	else
-			m_simd[i] -= b.m_simd[i];
-#	endif
+			m_rows[i] -= b.m_rows[i];
 		}
 		}
 		return *this;
 		return *this;
 	}
 	}
-#endif
 
 
 	ANKI_ENABLE_METHOD(J == I && !HAS_MAT4_SIMD)
 	ANKI_ENABLE_METHOD(J == I && !HAS_MAT4_SIMD)
 	TMat operator*(const TMat& b) const
 	TMat operator*(const TMat& b) const
@@ -510,18 +415,18 @@ public:
 	TMat operator+(const T f) const
 	TMat operator+(const T f) const
 	{
 	{
 		TMat out;
 		TMat out;
-		for(U i = 0; i < N; i++)
+		for(U i = 0; i < ROW_COUNT; ++i)
 		{
 		{
-			out.m_arr1[i] = m_arr1[i] + f;
+			out.m_rows[i] = m_rows[i] + f;
 		}
 		}
 		return out;
 		return out;
 	}
 	}
 
 
 	TMat& operator+=(const T f)
 	TMat& operator+=(const T f)
 	{
 	{
-		for(U i = 0; i < N; i++)
+		for(U i = 0; i < ROW_COUNT; ++i)
 		{
 		{
-			m_arr1[i] += f;
+			m_rows[i] += f;
 		}
 		}
 		return *this;
 		return *this;
 	}
 	}
@@ -529,18 +434,18 @@ public:
 	TMat operator-(const T f) const
 	TMat operator-(const T f) const
 	{
 	{
 		TMat out;
 		TMat out;
-		for(U i = 0; i < N; i++)
+		for(U i = 0; i < ROW_COUNT; ++i)
 		{
 		{
-			out.m_arr1[i] = m_arr1[i] - f;
+			out.m_rows[i] = m_rows[i] - f;
 		}
 		}
 		return out;
 		return out;
 	}
 	}
 
 
 	TMat& operator-=(const T f)
 	TMat& operator-=(const T f)
 	{
 	{
-		for(U i = 0; i < N; i++)
+		for(U i = 0; i < ROW_COUNT; ++i)
 		{
 		{
-			m_arr1[i] -= f;
+			m_rows[i] -= f;
 		}
 		}
 		return *this;
 		return *this;
 	}
 	}
@@ -548,18 +453,18 @@ public:
 	TMat operator*(const T f) const
 	TMat operator*(const T f) const
 	{
 	{
 		TMat out;
 		TMat out;
-		for(U i = 0; i < N; i++)
+		for(U i = 0; i < ROW_COUNT; ++i)
 		{
 		{
-			out.m_arr1[i] = m_arr1[i] * f;
+			out.m_rows[i] = m_rows[i] * f;
 		}
 		}
 		return out;
 		return out;
 	}
 	}
 
 
 	TMat& operator*=(const T f)
 	TMat& operator*=(const T f)
 	{
 	{
-		for(U i = 0; i < N; i++)
+		for(U i = 0; i < ROW_COUNT; ++i)
 		{
 		{
-			m_arr1[i] *= f;
+			m_rows[i] *= f;
 		}
 		}
 		return *this;
 		return *this;
 	}
 	}
@@ -568,9 +473,9 @@ public:
 	{
 	{
 		ANKI_ASSERT(f != T(0));
 		ANKI_ASSERT(f != T(0));
 		TMat out;
 		TMat out;
-		for(U i = 0; i < N; i++)
+		for(U i = 0; i < ROW_COUNT; ++i)
 		{
 		{
-			out.m_arr1[i] = m_arr1[i] / f;
+			out.m_rows[i] = m_rows[i] / f;
 		}
 		}
 		return out;
 		return out;
 	}
 	}
@@ -578,9 +483,9 @@ public:
 	TMat& operator/=(const T f)
 	TMat& operator/=(const T f)
 	{
 	{
 		ANKI_ASSERT(f != T(0));
 		ANKI_ASSERT(f != T(0));
-		for(U i = 0; i < N; i++)
+		for(U i = 0; i < ROW_COUNT; ++i)
 		{
 		{
-			m_arr1[i] /= f;
+			m_rows[i] /= f;
 		}
 		}
 		return *this;
 		return *this;
 	}
 	}
@@ -628,19 +533,9 @@ public:
 
 
 	/// @name Other
 	/// @name Other
 	/// @{
 	/// @{
-	ANKI_ENABLE_METHOD(!HAS_SIMD)
 	void setRow(const U j, const RowVec& v)
 	void setRow(const U j, const RowVec& v)
 	{
 	{
-		for(U i = 0; i < I; i++)
-		{
-			m_arr2[j][i] = v[i];
-		}
-	}
-
-	ANKI_ENABLE_METHOD(HAS_SIMD)
-	void setRow(const U j, const RowVec& v)
-	{
-		m_simd[j] = v.getSimd();
+		m_rows[j] = v;
 	}
 	}
 
 
 	void setRows(const RowVec& a, const RowVec& b, const RowVec& c)
 	void setRows(const RowVec& a, const RowVec& b, const RowVec& c)
@@ -657,14 +552,9 @@ public:
 		setRow(3, d);
 		setRow(3, d);
 	}
 	}
 
 
-	RowVec getRow(const U j) const
+	const RowVec& getRow(const U j) const
 	{
 	{
-		RowVec out;
-		for(U i = 0; i < I; i++)
-		{
-			out[i] = m_arr2[j][i];
-		}
-		return out;
+		return m_rows[j];
 	}
 	}
 
 
 	void getRows(RowVec& a, RowVec& b, RowVec& c) const
 	void getRows(RowVec& a, RowVec& b, RowVec& c) const
@@ -674,9 +564,9 @@ public:
 		c = getRow(2);
 		c = getRow(2);
 	}
 	}
 
 
+	ANKI_ENABLE_METHOD(J > 3)
 	void getRows(RowVec& a, RowVec& b, RowVec& c, RowVec& d) const
 	void getRows(RowVec& a, RowVec& b, RowVec& c, RowVec& d) const
 	{
 	{
-		static_assert(J > 3, "Wrong matrix");
 		getRows(a, b, c);
 		getRows(a, b, c);
 		d = getRow(3);
 		d = getRow(3);
 	}
 	}
@@ -696,9 +586,9 @@ public:
 		setColumn(2, c);
 		setColumn(2, c);
 	}
 	}
 
 
+	ANKI_ENABLE_METHOD(I > 3)
 	void setColumns(const ColumnVec& a, const ColumnVec& b, const ColumnVec& c, const ColumnVec& d)
 	void setColumns(const ColumnVec& a, const ColumnVec& b, const ColumnVec& c, const ColumnVec& d)
 	{
 	{
-		static_assert(I > 3, "Check column number");
 		setColumns(a, b, c);
 		setColumns(a, b, c);
 		setColumn(3, d);
 		setColumn(3, d);
 	}
 	}
@@ -720,9 +610,9 @@ public:
 		c = getColumn(2);
 		c = getColumn(2);
 	}
 	}
 
 
+	ANKI_ENABLE_METHOD(I > 3)
 	void getColumns(ColumnVec& a, ColumnVec& b, ColumnVec& c, ColumnVec& d) const
 	void getColumns(ColumnVec& a, ColumnVec& b, ColumnVec& c, ColumnVec& d) const
 	{
 	{
-		static_assert(I > 3, "Check column number");
 		getColumns(a, b, c);
 		getColumns(a, b, c);
 		d = getColumn(3);
 		d = getColumn(3);
 	}
 	}
@@ -814,8 +704,7 @@ public:
 		m(2, 2) = T(1);
 		m(2, 2) = T(1);
 	}
 	}
 
 
-	/// It rotates "this" in the axis defined by the rotation AND not the
-	/// world axis
+	/// It rotates "this" in the axis defined by the rotation AND not the world axis.
 	void rotateXAxis(const T rad)
 	void rotateXAxis(const T rad)
 	{
 	{
 		TMat& m = *this;
 		TMat& m = *this;
@@ -1008,7 +897,7 @@ public:
 
 
 	void setTranslationPart(const ColumnVec& v)
 	void setTranslationPart(const ColumnVec& v)
 	{
 	{
-		if(ROW_SIZE == 4)
+		if(ROW_COUNT == 4)
 		{
 		{
 			ANKI_ASSERT(isZero<T>(v[3] - T(1)) && "w should be 1");
 			ANKI_ASSERT(isZero<T>(v[3] - T(1)) && "w should be 1");
 		}
 		}
@@ -1578,11 +1467,12 @@ protected:
 	/// @{
 	/// @{
 	union
 	union
 	{
 	{
-		Array<T, N> m_arr1;
-		Array2d<T, J, I> m_arr2;
 		T m_carr1[N]; ///< For easier debugging with gdb
 		T m_carr1[N]; ///< For easier debugging with gdb
 		T m_carr2[J][I]; ///< For easier debugging with gdb
 		T m_carr2[J][I]; ///< For easier debugging with gdb
+		Array<T, N> m_arr1;
+		Array2d<T, J, I> m_arr2;
 		SimdArray m_simd;
 		SimdArray m_simd;
+		Array<RowVec, J> m_rows;
 	};
 	};
 	/// @}
 	/// @}
 };
 };

+ 1 - 1
AnKi/Renderer/Bloom.cpp

@@ -147,7 +147,7 @@ void Bloom::populateRenderGraph(RenderingContext& ctx)
 			const Vec4 uniforms(getConfig().getRBloomThreshold(), getConfig().getRBloomScale(), 0.0f, 0.0f);
 			const Vec4 uniforms(getConfig().getRBloomThreshold(), getConfig().getRBloomScale(), 0.0f, 0.0f);
 			cmdb->setPushConstants(&uniforms, sizeof(uniforms));
 			cmdb->setPushConstants(&uniforms, sizeof(uniforms));
 
 
-			rgraphCtx.bindStorageBuffer(0, 2, m_r->getTonemapping().getAverageLuminanceBuffer());
+			rgraphCtx.bindImage(0, 2, m_r->getTonemapping().getRt());
 
 
 			if(getConfig().getRPreferCompute())
 			if(getConfig().getRPreferCompute())
 			{
 			{

+ 1 - 1
AnKi/Renderer/CMakeLists.txt

@@ -2,4 +2,4 @@ file(GLOB_RECURSE sources *.cpp)
 file(GLOB_RECURSE headers *.h)
 file(GLOB_RECURSE headers *.h)
 add_library(AnKiRenderer ${sources} ${headers})
 add_library(AnKiRenderer ${sources} ${headers})
 target_compile_definitions(AnKiRenderer PRIVATE -DANKI_SOURCE_FILE)
 target_compile_definitions(AnKiRenderer PRIVATE -DANKI_SOURCE_FILE)
-target_link_libraries(AnKiRenderer AnKiGr AnKiResource AnKiUi)
+target_link_libraries(AnKiRenderer AnKiGr AnKiResource AnKiUi)

+ 3 - 2
AnKi/Renderer/ConfigVars.defs.h

@@ -88,5 +88,6 @@ ANKI_CONFIG_VAR_BOOL(RRtShadowsSvgf, false, "Enable or not RT shadows SVGF")
 ANKI_CONFIG_VAR_U8(RRtShadowsSvgfAtrousPassCount, 3, 1, 20, "Number of atrous passes of SVGF")
 ANKI_CONFIG_VAR_U8(RRtShadowsSvgfAtrousPassCount, 3, 1, 20, "Number of atrous passes of SVGF")
 ANKI_CONFIG_VAR_U32(RRtShadowsRaysPerPixel, 1, 1, 8, "Number of shadow rays per pixel")
 ANKI_CONFIG_VAR_U32(RRtShadowsRaysPerPixel, 1, 1, 8, "Number of shadow rays per pixel")
 
 
-ANKI_CONFIG_VAR_U8(RFsr, 1, 0, 2, "0: Use bilinear, 1: FSR low quality, 2: FSR high quality")
-ANKI_CONFIG_VAR_BOOL(RSharpen, true, "Sharpen the image")
+ANKI_CONFIG_VAR_U8(RFsrQuality, 1, 0, 2, "0: Use bilinear, 1: FSR low quality, 2: FSR high quality")
+ANKI_CONFIG_VAR_U8(RDlssQuality, 2, 0, 3, "0: Disabled, 1: Performance, 2: Balanced, 3: Quality")
+ANKI_CONFIG_VAR_F32(RSharpness, ((ANKI_PLATFORM_MOBILE) ? 0.0f : 0.8f), 0.0f, 1.0f, "Sharpen the image. It's a factor")

+ 1 - 1
AnKi/Renderer/Dbg.cpp

@@ -67,7 +67,7 @@ void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 	dctx.m_viewMatrix = ctx.m_renderQueue->m_viewMatrix;
 	dctx.m_viewMatrix = ctx.m_renderQueue->m_viewMatrix;
 	dctx.m_viewProjectionMatrix = ctx.m_renderQueue->m_viewProjectionMatrix;
 	dctx.m_viewProjectionMatrix = ctx.m_renderQueue->m_viewProjectionMatrix;
 	dctx.m_projectionMatrix = ctx.m_renderQueue->m_projectionMatrix;
 	dctx.m_projectionMatrix = ctx.m_renderQueue->m_projectionMatrix;
-	dctx.m_cameraTransform = ctx.m_renderQueue->m_viewMatrix.getInverse();
+	dctx.m_cameraTransform = ctx.m_renderQueue->m_cameraTransform;
 	dctx.m_stagingGpuAllocator = &m_r->getStagingGpuMemory();
 	dctx.m_stagingGpuAllocator = &m_r->getStagingGpuMemory();
 	dctx.m_frameAllocator = ctx.m_tempAllocator;
 	dctx.m_frameAllocator = ctx.m_tempAllocator;
 	dctx.m_commandBuffer = cmdb;
 	dctx.m_commandBuffer = cmdb;

+ 21 - 11
AnKi/Renderer/DownscaleBlur.cpp

@@ -89,6 +89,8 @@ void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
 	// Create passes
 	// Create passes
 	static const Array<CString, 8> passNames = {"DownBlur #0",  "Down/Blur #1", "Down/Blur #2", "Down/Blur #3",
 	static const Array<CString, 8> passNames = {"DownBlur #0",  "Down/Blur #1", "Down/Blur #2", "Down/Blur #3",
 												"Down/Blur #4", "Down/Blur #5", "Down/Blur #6", "Down/Blur #7"};
 												"Down/Blur #4", "Down/Blur #5", "Down/Blur #6", "Down/Blur #7"};
+	const RenderTargetHandle inRt =
+		(m_r->getScale().hasUpscaledHdrRt()) ? m_r->getScale().getUpscaledHdrRt() : m_r->getScale().getTonemappedRt();
 	if(getConfig().getRPreferCompute())
 	if(getConfig().getRPreferCompute())
 	{
 	{
 		for(U32 i = 0; i < m_passCount; ++i)
 		for(U32 i = 0; i < m_passCount; ++i)
@@ -106,15 +108,18 @@ void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
 				sampleSubresource.m_firstMipmap = i - 1;
 				sampleSubresource.m_firstMipmap = i - 1;
 				renderSubresource.m_firstMipmap = i;
 				renderSubresource.m_firstMipmap = i;
 
 
-				pass.newDependency({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE, renderSubresource});
-				pass.newDependency({m_runCtx.m_rt, TextureUsageBit::SAMPLED_COMPUTE, sampleSubresource});
+				pass.newDependency(
+					RenderPassDependency(m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE, renderSubresource));
+				pass.newDependency(
+					RenderPassDependency(m_runCtx.m_rt, TextureUsageBit::SAMPLED_COMPUTE, sampleSubresource));
 			}
 			}
 			else
 			else
 			{
 			{
 				TextureSubresourceInfo renderSubresource;
 				TextureSubresourceInfo renderSubresource;
 
 
-				pass.newDependency({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE, renderSubresource});
-				pass.newDependency({m_r->getScale().getRt(), TextureUsageBit::SAMPLED_COMPUTE});
+				pass.newDependency(
+					RenderPassDependency(m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE, renderSubresource));
+				pass.newDependency(RenderPassDependency(inRt, TextureUsageBit::SAMPLED_COMPUTE));
 			}
 			}
 		}
 		}
 	}
 	}
@@ -136,15 +141,18 @@ void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
 				sampleSubresource.m_firstMipmap = i - 1;
 				sampleSubresource.m_firstMipmap = i - 1;
 				renderSubresource.m_firstMipmap = i;
 				renderSubresource.m_firstMipmap = i;
 
 
-				pass.newDependency({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, renderSubresource});
-				pass.newDependency({m_runCtx.m_rt, TextureUsageBit::SAMPLED_FRAGMENT, sampleSubresource});
+				pass.newDependency(RenderPassDependency(m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
+														renderSubresource));
+				pass.newDependency(
+					RenderPassDependency(m_runCtx.m_rt, TextureUsageBit::SAMPLED_FRAGMENT, sampleSubresource));
 			}
 			}
 			else
 			else
 			{
 			{
 				TextureSubresourceInfo renderSubresource;
 				TextureSubresourceInfo renderSubresource;
 
 
-				pass.newDependency({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, renderSubresource});
-				pass.newDependency({m_r->getScale().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+				pass.newDependency(RenderPassDependency(m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
+														renderSubresource));
+				pass.newDependency(RenderPassDependency(inRt, TextureUsageBit::SAMPLED_FRAGMENT));
 			}
 			}
 		}
 		}
 	}
 	}
@@ -169,12 +177,14 @@ void DownscaleBlur::run(U32 passIdx, RenderPassWorkContext& rgraphCtx)
 	}
 	}
 	else
 	else
 	{
 	{
-		rgraphCtx.bindColorTexture(0, 1, m_r->getScale().getRt());
+		const RenderTargetHandle inRt = (m_r->getScale().hasUpscaledHdrRt()) ? m_r->getScale().getUpscaledHdrRt()
+																			 : m_r->getScale().getTonemappedRt();
+		rgraphCtx.bindColorTexture(0, 1, inRt);
 	}
 	}
 
 
-	rgraphCtx.bindUniformBuffer(0, 2, m_r->getTonemapping().getAverageLuminanceBuffer());
+	rgraphCtx.bindImage(0, 2, m_r->getTonemapping().getRt());
 
 
-	const Bool revertTonemap = passIdx == 0;
+	const Bool revertTonemap = passIdx == 0 && !m_r->getScale().hasUpscaledHdrRt();
 	const UVec4 fbSize(vpWidth, vpHeight, revertTonemap, 0);
 	const UVec4 fbSize(vpWidth, vpHeight, revertTonemap, 0);
 	cmdb->setPushConstants(&fbSize, sizeof(fbSize));
 	cmdb->setPushConstants(&fbSize, sizeof(fbSize));
 
 

+ 20 - 20
AnKi/Renderer/Drawer.cpp

@@ -14,7 +14,7 @@
 namespace anki {
 namespace anki {
 
 
 /// Drawer's context
 /// Drawer's context
-class DrawContext
+class RenderableDrawer::Context
 {
 {
 public:
 public:
 	RenderQueueDrawContext m_queueCtx;
 	RenderQueueDrawContext m_queueCtx;
@@ -39,10 +39,9 @@ RenderableDrawer::~RenderableDrawer()
 {
 {
 }
 }
 
 
-void RenderableDrawer::drawRange(RenderingTechnique technique, const Mat4& viewMat, const Mat4& viewProjMat,
-								 const Mat4& prevViewProjMat, CommandBufferPtr cmdb, SamplerPtr sampler,
-								 const RenderableQueueElement* begin, const RenderableQueueElement* end, U32 minLod,
-								 U32 maxLod)
+void RenderableDrawer::drawRange(RenderingTechnique technique, const RenderableDrawerArguments& args,
+								 const RenderableQueueElement* begin, const RenderableQueueElement* end,
+								 CommandBufferPtr& cmdb)
 {
 {
 	ANKI_ASSERT(begin && end && begin < end);
 	ANKI_ASSERT(begin && end && begin < end);
 
 
@@ -52,10 +51,11 @@ void RenderableDrawer::drawRange(RenderingTechnique technique, const Mat4& viewM
 		MaterialGlobalUniforms* globalUniforms =
 		MaterialGlobalUniforms* globalUniforms =
 			static_cast<MaterialGlobalUniforms*>(m_r->getStagingGpuMemory().allocateFrame(
 			static_cast<MaterialGlobalUniforms*>(m_r->getStagingGpuMemory().allocateFrame(
 				sizeof(MaterialGlobalUniforms), StagingGpuMemoryType::UNIFORM, globalUniformsToken));
 				sizeof(MaterialGlobalUniforms), StagingGpuMemoryType::UNIFORM, globalUniformsToken));
-		globalUniforms->m_viewProjectionMatrix = viewProjMat;
 
 
-		globalUniforms->m_viewMatrix = Mat3x4(viewMat);
-		globalUniforms->m_cameraTransform = Mat3x4(viewMat.getInverse());
+		globalUniforms->m_viewProjectionMatrix = args.m_viewProjectionMatrix;
+		globalUniforms->m_previousViewProjectionMatrix = args.m_previousViewProjectionMatrix;
+		globalUniforms->m_viewMatrix = args.m_viewMatrix;
+		globalUniforms->m_cameraTransform = args.m_cameraTransform;
 
 
 		cmdb->bindUniformBuffer(MATERIAL_SET_GLOBAL, MATERIAL_BINDING_GLOBAL_UNIFORMS, globalUniformsToken.m_buffer,
 		cmdb->bindUniformBuffer(MATERIAL_SET_GLOBAL, MATERIAL_BINDING_GLOBAL_UNIFORMS, globalUniformsToken.m_buffer,
 								globalUniformsToken.m_offset, globalUniformsToken.m_range);
 								globalUniformsToken.m_offset, globalUniformsToken.m_range);
@@ -63,24 +63,24 @@ void RenderableDrawer::drawRange(RenderingTechnique technique, const Mat4& viewM
 
 
 	// More globals
 	// More globals
 	cmdb->bindAllBindless(MATERIAL_SET_BINDLESS);
 	cmdb->bindAllBindless(MATERIAL_SET_BINDLESS);
-	cmdb->bindSampler(MATERIAL_SET_GLOBAL, MATERIAL_BINDING_TRILINEAR_REPEAT_SAMPLER, sampler);
+	cmdb->bindSampler(MATERIAL_SET_GLOBAL, MATERIAL_BINDING_TRILINEAR_REPEAT_SAMPLER, args.m_sampler);
 
 
 	// Set a few things
 	// Set a few things
-	DrawContext ctx;
-	ctx.m_queueCtx.m_viewMatrix = viewMat;
-	ctx.m_queueCtx.m_viewProjectionMatrix = viewProjMat;
+	Context ctx;
+	ctx.m_queueCtx.m_viewMatrix = args.m_viewMatrix;
+	ctx.m_queueCtx.m_viewProjectionMatrix = args.m_viewProjectionMatrix;
 	ctx.m_queueCtx.m_projectionMatrix = Mat4::getIdentity(); // TODO
 	ctx.m_queueCtx.m_projectionMatrix = Mat4::getIdentity(); // TODO
-	ctx.m_queueCtx.m_previousViewProjectionMatrix = prevViewProjMat;
-	ctx.m_queueCtx.m_cameraTransform = ctx.m_queueCtx.m_viewMatrix.getInverse();
+	ctx.m_queueCtx.m_previousViewProjectionMatrix = args.m_previousViewProjectionMatrix;
+	ctx.m_queueCtx.m_cameraTransform = args.m_cameraTransform;
 	ctx.m_queueCtx.m_stagingGpuAllocator = &m_r->getStagingGpuMemory();
 	ctx.m_queueCtx.m_stagingGpuAllocator = &m_r->getStagingGpuMemory();
 	ctx.m_queueCtx.m_commandBuffer = cmdb;
 	ctx.m_queueCtx.m_commandBuffer = cmdb;
 	ctx.m_queueCtx.m_key = RenderingKey(technique, 0, 1, false, false);
 	ctx.m_queueCtx.m_key = RenderingKey(technique, 0, 1, false, false);
 	ctx.m_queueCtx.m_debugDraw = false;
 	ctx.m_queueCtx.m_debugDraw = false;
-	ctx.m_queueCtx.m_sampler = sampler;
+	ctx.m_queueCtx.m_sampler = args.m_sampler;
 
 
-	ANKI_ASSERT(minLod < MAX_LOD_COUNT && maxLod < MAX_LOD_COUNT);
-	ctx.m_minLod = U8(minLod);
-	ctx.m_maxLod = U8(maxLod);
+	ANKI_ASSERT(args.m_minLod < MAX_LOD_COUNT && args.m_maxLod < MAX_LOD_COUNT && args.m_minLod <= args.m_maxLod);
+	ctx.m_minLod = U8(args.m_minLod);
+	ctx.m_maxLod = U8(args.m_maxLod);
 
 
 	for(; begin != end; ++begin)
 	for(; begin != end; ++begin)
 	{
 	{
@@ -93,7 +93,7 @@ void RenderableDrawer::drawRange(RenderingTechnique technique, const Mat4& viewM
 	flushDrawcall(ctx);
 	flushDrawcall(ctx);
 }
 }
 
 
-void RenderableDrawer::flushDrawcall(DrawContext& ctx)
+void RenderableDrawer::flushDrawcall(Context& ctx)
 {
 {
 	ctx.m_queueCtx.m_key.setLod(ctx.m_cachedRenderElementLods[0]);
 	ctx.m_queueCtx.m_key.setLod(ctx.m_cachedRenderElementLods[0]);
 	ctx.m_queueCtx.m_key.setInstanceCount(ctx.m_cachedRenderElementCount);
 	ctx.m_queueCtx.m_key.setInstanceCount(ctx.m_cachedRenderElementCount);
@@ -109,7 +109,7 @@ void RenderableDrawer::flushDrawcall(DrawContext& ctx)
 	ctx.m_cachedRenderElementCount = 0;
 	ctx.m_cachedRenderElementCount = 0;
 }
 }
 
 
-void RenderableDrawer::drawSingle(DrawContext& ctx)
+void RenderableDrawer::drawSingle(Context& ctx)
 {
 {
 	if(ctx.m_cachedRenderElementCount == MAX_INSTANCE_COUNT)
 	if(ctx.m_cachedRenderElementCount == MAX_INSTANCE_COUNT)
 	{
 	{

+ 21 - 7
AnKi/Renderer/Drawer.h

@@ -13,11 +13,25 @@ namespace anki {
 
 
 // Forward
 // Forward
 class Renderer;
 class Renderer;
-class DrawContext;
 
 
 /// @addtogroup renderer
 /// @addtogroup renderer
 /// @{
 /// @{
 
 
+/// @memberof RenderableDrawer.
+class RenderableDrawerArguments
+{
+public:
+	// The matrices are whatever the drawing needs. Sometimes they contain jittering and sometimes they don't.
+	Mat3x4 m_viewMatrix;
+	Mat3x4 m_cameraTransform;
+	Mat4 m_viewProjectionMatrix;
+	Mat4 m_previousViewProjectionMatrix;
+
+	SamplerPtr m_sampler;
+	U32 m_minLod = 0;
+	U32 m_maxLod = MAX_LOD_COUNT - 1;
+};
+
 /// It uses the render queue to batch and render.
 /// It uses the render queue to batch and render.
 class RenderableDrawer
 class RenderableDrawer
 {
 {
@@ -31,17 +45,17 @@ public:
 
 
 	~RenderableDrawer();
 	~RenderableDrawer();
 
 
-	void drawRange(RenderingTechnique technique, const Mat4& viewMat, const Mat4& viewProjMat,
-				   const Mat4& prevViewProjMat, CommandBufferPtr cmdb, SamplerPtr sampler,
-				   const RenderableQueueElement* begin, const RenderableQueueElement* end, U32 minLod = 0,
-				   U32 maxLod = MAX_LOD_COUNT - 1);
+	void drawRange(RenderingTechnique technique, const RenderableDrawerArguments& args,
+				   const RenderableQueueElement* begin, const RenderableQueueElement* end, CommandBufferPtr& cmdb);
 
 
 private:
 private:
+	class Context;
+
 	Renderer* m_r;
 	Renderer* m_r;
 
 
-	void flushDrawcall(DrawContext& ctx);
+	void flushDrawcall(Context& ctx);
 
 
-	void drawSingle(DrawContext& ctx);
+	void drawSingle(Context& ctx);
 };
 };
 /// @}
 /// @}
 
 

+ 2 - 2
AnKi/Renderer/FinalComposite.cpp

@@ -107,7 +107,7 @@ void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 		pass.newDependency(RenderPassDependency(m_r->getDbg().getRt(), TextureUsageBit::SAMPLED_FRAGMENT));
 		pass.newDependency(RenderPassDependency(m_r->getDbg().getRt(), TextureUsageBit::SAMPLED_FRAGMENT));
 	}
 	}
 
 
-	pass.newDependency(RenderPassDependency(m_r->getScale().getRt(), TextureUsageBit::SAMPLED_FRAGMENT));
+	pass.newDependency(RenderPassDependency(m_r->getScale().getTonemappedRt(), TextureUsageBit::SAMPLED_FRAGMENT));
 	pass.newDependency(RenderPassDependency(m_r->getBloom().getRt(), TextureUsageBit::SAMPLED_FRAGMENT));
 	pass.newDependency(RenderPassDependency(m_r->getBloom().getRt(), TextureUsageBit::SAMPLED_FRAGMENT));
 	pass.newDependency(
 	pass.newDependency(
 		RenderPassDependency(m_r->getMotionVectors().getMotionVectorsRt(), TextureUsageBit::SAMPLED_FRAGMENT));
 		RenderPassDependency(m_r->getMotionVectors().getMotionVectorsRt(), TextureUsageBit::SAMPLED_FRAGMENT));
@@ -153,7 +153,7 @@ void FinalComposite::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx
 		cmdb->bindSampler(0, 1, m_r->getSamplers().m_trilinearClamp);
 		cmdb->bindSampler(0, 1, m_r->getSamplers().m_trilinearClamp);
 		cmdb->bindSampler(0, 2, m_r->getSamplers().m_trilinearRepeat);
 		cmdb->bindSampler(0, 2, m_r->getSamplers().m_trilinearRepeat);
 
 
-		rgraphCtx.bindColorTexture(0, 3, m_r->getScale().getRt());
+		rgraphCtx.bindColorTexture(0, 3, m_r->getScale().getTonemappedRt());
 
 
 		rgraphCtx.bindColorTexture(0, 4, m_r->getBloom().getRt());
 		rgraphCtx.bindColorTexture(0, 4, m_r->getBloom().getRt());
 		cmdb->bindTexture(0, 5, m_lut->getTextureView());
 		cmdb->bindTexture(0, 5, m_lut->getTextureView());

+ 9 - 5
AnKi/Renderer/ForwardShading.cpp

@@ -49,13 +49,17 @@ void ForwardShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgr
 								   m_r->getShadowMapping().getShadowmapRt());
 								   m_r->getShadowMapping().getShadowmapRt());
 		bindStorage(cmdb, set, MATERIAL_BINDING_CLUSTERS, rsrc.m_clustersToken);
 		bindStorage(cmdb, set, MATERIAL_BINDING_CLUSTERS, rsrc.m_clustersToken);
 
 
+		RenderableDrawerArguments args;
+		args.m_viewMatrix = ctx.m_matrices.m_view;
+		args.m_cameraTransform = ctx.m_matrices.m_cameraTransform;
+		args.m_viewProjectionMatrix = ctx.m_matrices.m_viewProjectionJitter;
+		args.m_previousViewProjectionMatrix = ctx.m_prevMatrices.m_viewProjectionJitter; // Not sure about that
+		args.m_sampler = m_r->getSamplers().m_trilinearRepeatAnisoResolutionScalingBias;
+
 		// Start drawing
 		// Start drawing
-		m_r->getSceneDrawer().drawRange(RenderingTechnique::FORWARD, ctx.m_matrices.m_view,
-										ctx.m_matrices.m_viewProjectionJitter,
-										ctx.m_prevMatrices.m_viewProjectionJitter, cmdb,
-										m_r->getSamplers().m_trilinearRepeatAnisoResolutionScalingBias,
+		m_r->getSceneDrawer().drawRange(RenderingTechnique::FORWARD, args,
 										ctx.m_renderQueue->m_forwardShadingRenderables.getBegin() + start,
 										ctx.m_renderQueue->m_forwardShadingRenderables.getBegin() + start,
-										ctx.m_renderQueue->m_forwardShadingRenderables.getBegin() + end);
+										ctx.m_renderQueue->m_forwardShadingRenderables.getBegin() + end, cmdb);
 
 
 		// Restore state
 		// Restore state
 		cmdb->setDepthWrite(true);
 		cmdb->setDepthWrite(true);

+ 16 - 13
AnKi/Renderer/GBuffer.cpp

@@ -7,6 +7,7 @@
 #include <AnKi/Renderer/Renderer.h>
 #include <AnKi/Renderer/Renderer.h>
 #include <AnKi/Renderer/RenderQueue.h>
 #include <AnKi/Renderer/RenderQueue.h>
 #include <AnKi/Renderer/VrsSriGeneration.h>
 #include <AnKi/Renderer/VrsSriGeneration.h>
+#include <AnKi/Renderer/Scale.h>
 #include <AnKi/Util/Logger.h>
 #include <AnKi/Util/Logger.h>
 #include <AnKi/Util/Tracer.h>
 #include <AnKi/Util/Tracer.h>
 #include <AnKi/Core/ConfigSet.h>
 #include <AnKi/Core/ConfigSet.h>
@@ -37,9 +38,10 @@ Error GBuffer::initInternal()
 	static const Array<const char*, 2> depthRtNames = {{"GBuffer depth #0", "GBuffer depth #1"}};
 	static const Array<const char*, 2> depthRtNames = {{"GBuffer depth #0", "GBuffer depth #1"}};
 	for(U32 i = 0; i < 2; ++i)
 	for(U32 i = 0; i < 2; ++i)
 	{
 	{
-		TextureInitInfo texinit = m_r->create2DRenderTargetInitInfo(
-			m_r->getInternalResolution().x(), m_r->getInternalResolution().y(), m_r->getDepthNoStencilFormat(),
-			TextureUsageBit::ALL_SAMPLED | TextureUsageBit::ALL_FRAMEBUFFER_ATTACHMENT, depthRtNames[i]);
+		const TextureUsageBit usage = TextureUsageBit::ALL_SAMPLED | TextureUsageBit::ALL_FRAMEBUFFER_ATTACHMENT;
+		TextureInitInfo texinit =
+			m_r->create2DRenderTargetInitInfo(m_r->getInternalResolution().x(), m_r->getInternalResolution().y(),
+											  m_r->getDepthNoStencilFormat(), usage, depthRtNames[i]);
 
 
 		m_depthRts[i] = m_r->createAndClearRenderTarget(texinit, TextureUsageBit::SAMPLED_FRAGMENT);
 		m_depthRts[i] = m_r->createAndClearRenderTarget(texinit, TextureUsageBit::SAMPLED_FRAGMENT);
 	}
 	}
@@ -118,6 +120,13 @@ void GBuffer::runInThread(const RenderingContext& ctx, RenderPassWorkContext& rg
 		cmdb->setVrsRate(VrsRate::_1x1);
 		cmdb->setVrsRate(VrsRate::_1x1);
 	}
 	}
 
 
+	RenderableDrawerArguments args;
+	args.m_viewMatrix = ctx.m_matrices.m_view;
+	args.m_cameraTransform = ctx.m_matrices.m_cameraTransform;
+	args.m_viewProjectionMatrix = ctx.m_matrices.m_viewProjectionJitter;
+	args.m_previousViewProjectionMatrix = ctx.m_matrices.m_jitter * ctx.m_prevMatrices.m_viewProjection;
+	args.m_sampler = m_r->getSamplers().m_trilinearRepeatAnisoResolutionScalingBias;
+
 	// First do early Z (if needed)
 	// First do early Z (if needed)
 	if(earlyZStart < earlyZEnd)
 	if(earlyZStart < earlyZEnd)
 	{
 	{
@@ -127,12 +136,9 @@ void GBuffer::runInThread(const RenderingContext& ctx, RenderPassWorkContext& rg
 		}
 		}
 
 
 		ANKI_ASSERT(earlyZStart < earlyZEnd && earlyZEnd <= I32(earlyZCount));
 		ANKI_ASSERT(earlyZStart < earlyZEnd && earlyZEnd <= I32(earlyZCount));
-		m_r->getSceneDrawer().drawRange(RenderingTechnique::GBUFFER_EARLY_Z, ctx.m_matrices.m_view,
-										ctx.m_matrices.m_viewProjectionJitter,
-										ctx.m_matrices.m_jitter * ctx.m_prevMatrices.m_viewProjection, cmdb,
-										m_r->getSamplers().m_trilinearRepeatAnisoResolutionScalingBias,
+		m_r->getSceneDrawer().drawRange(RenderingTechnique::GBUFFER_EARLY_Z, args,
 										ctx.m_renderQueue->m_earlyZRenderables.getBegin() + earlyZStart,
 										ctx.m_renderQueue->m_earlyZRenderables.getBegin() + earlyZStart,
-										ctx.m_renderQueue->m_earlyZRenderables.getBegin() + earlyZEnd);
+										ctx.m_renderQueue->m_earlyZRenderables.getBegin() + earlyZEnd, cmdb);
 
 
 		// Restore state for the color write
 		// Restore state for the color write
 		if(colorStart < colorEnd)
 		if(colorStart < colorEnd)
@@ -150,12 +156,9 @@ void GBuffer::runInThread(const RenderingContext& ctx, RenderPassWorkContext& rg
 		cmdb->setDepthCompareOperation(CompareOperation::LESS_EQUAL);
 		cmdb->setDepthCompareOperation(CompareOperation::LESS_EQUAL);
 
 
 		ANKI_ASSERT(colorStart < colorEnd && colorEnd <= I32(ctx.m_renderQueue->m_renderables.getSize()));
 		ANKI_ASSERT(colorStart < colorEnd && colorEnd <= I32(ctx.m_renderQueue->m_renderables.getSize()));
-		m_r->getSceneDrawer().drawRange(RenderingTechnique::GBUFFER, ctx.m_matrices.m_view,
-										ctx.m_matrices.m_viewProjectionJitter,
-										ctx.m_matrices.m_jitter * ctx.m_prevMatrices.m_viewProjection, cmdb,
-										m_r->getSamplers().m_trilinearRepeatAnisoResolutionScalingBias,
+		m_r->getSceneDrawer().drawRange(RenderingTechnique::GBUFFER, args,
 										ctx.m_renderQueue->m_renderables.getBegin() + colorStart,
 										ctx.m_renderQueue->m_renderables.getBegin() + colorStart,
-										ctx.m_renderQueue->m_renderables.getBegin() + colorEnd);
+										ctx.m_renderQueue->m_renderables.getBegin() + colorEnd, cmdb);
 	}
 	}
 }
 }
 
 

+ 25 - 12
AnKi/Renderer/IndirectDiffuseProbes.cpp

@@ -569,11 +569,18 @@ void IndirectDiffuseProbes::runGBufferInThread(RenderPassWorkContext& rgraphCtx,
 			const RenderQueue& rqueue = *probe.m_renderQueues[faceIdx];
 			const RenderQueue& rqueue = *probe.m_renderQueues[faceIdx];
 
 
 			ANKI_ASSERT(localStart >= 0 && localEnd <= faceDrawcallCount);
 			ANKI_ASSERT(localStart >= 0 && localEnd <= faceDrawcallCount);
-			m_r->getSceneDrawer().drawRange(
-				RenderingTechnique::GBUFFER, rqueue.m_viewMatrix, rqueue.m_viewProjectionMatrix,
-				Mat4::getIdentity(), // Don't care about prev mats since we don't care about velocity
-				cmdb, m_r->getSamplers().m_trilinearRepeat, rqueue.m_renderables.getBegin() + localStart,
-				rqueue.m_renderables.getBegin() + localEnd, MAX_LOD_COUNT - 1, MAX_LOD_COUNT - 1);
+
+			RenderableDrawerArguments args;
+			args.m_viewMatrix = rqueue.m_viewMatrix;
+			args.m_cameraTransform = Mat3x4::getIdentity(); // Don't care
+			args.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
+			args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
+			args.m_sampler = m_r->getSamplers().m_trilinearRepeat;
+			args.m_minLod = args.m_maxLod = MAX_LOD_COUNT - 1;
+
+			m_r->getSceneDrawer().drawRange(RenderingTechnique::GBUFFER, args,
+											rqueue.m_renderables.getBegin() + localStart,
+											rqueue.m_renderables.getBegin() + localEnd, cmdb);
 		}
 		}
 
 
 		drawcallCount += faceDrawcallCount;
 		drawcallCount += faceDrawcallCount;
@@ -620,12 +627,18 @@ void IndirectDiffuseProbes::runShadowmappingInThread(RenderPassWorkContext& rgra
 			cmdb->setScissor(rez * faceIdx, 0, rez, rez);
 			cmdb->setScissor(rez * faceIdx, 0, rez, rez);
 
 
 			ANKI_ASSERT(localStart >= 0 && localEnd <= faceDrawcallCount);
 			ANKI_ASSERT(localStart >= 0 && localEnd <= faceDrawcallCount);
-			m_r->getSceneDrawer().drawRange(
-				RenderingTechnique::SHADOW, cascadeRenderQueue.m_viewMatrix, cascadeRenderQueue.m_viewProjectionMatrix,
-				Mat4::getIdentity(), // Don't care about prev matrices here
-				cmdb, m_r->getSamplers().m_trilinearRepeatAniso,
-				cascadeRenderQueue.m_renderables.getBegin() + localStart,
-				cascadeRenderQueue.m_renderables.getBegin() + localEnd, MAX_LOD_COUNT - 1, MAX_LOD_COUNT - 1);
+
+			RenderableDrawerArguments args;
+			args.m_viewMatrix = cascadeRenderQueue.m_viewMatrix;
+			args.m_cameraTransform = Mat3x4::getIdentity(); // Don't care
+			args.m_viewProjectionMatrix = cascadeRenderQueue.m_viewProjectionMatrix;
+			args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
+			args.m_sampler = m_r->getSamplers().m_trilinearRepeatAniso;
+			args.m_maxLod = args.m_minLod = MAX_LOD_COUNT - 1;
+
+			m_r->getSceneDrawer().drawRange(RenderingTechnique::SHADOW, args,
+											cascadeRenderQueue.m_renderables.getBegin() + localStart,
+											cascadeRenderQueue.m_renderables.getBegin() + localEnd, cmdb);
 		}
 		}
 	}
 	}
 
 
@@ -654,7 +667,7 @@ void IndirectDiffuseProbes::runLightShading(RenderPassWorkContext& rgraphCtx, In
 		TraditionalDeferredLightShadingDrawInfo dsInfo;
 		TraditionalDeferredLightShadingDrawInfo dsInfo;
 		dsInfo.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
 		dsInfo.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
 		dsInfo.m_invViewProjectionMatrix = rqueue.m_viewProjectionMatrix.getInverse();
 		dsInfo.m_invViewProjectionMatrix = rqueue.m_viewProjectionMatrix.getInverse();
-		dsInfo.m_cameraPosWSpace = rqueue.m_cameraTransform.getTranslationPart();
+		dsInfo.m_cameraPosWSpace = rqueue.m_cameraTransform.getTranslationPart().xyz1();
 		dsInfo.m_viewport = UVec4(faceIdx * m_tileSize, 0, m_tileSize, m_tileSize);
 		dsInfo.m_viewport = UVec4(faceIdx * m_tileSize, 0, m_tileSize, m_tileSize);
 		dsInfo.m_gbufferTexCoordsScale = Vec2(1.0f / F32(m_tileSize * 6), 1.0f / F32(m_tileSize));
 		dsInfo.m_gbufferTexCoordsScale = Vec2(1.0f / F32(m_tileSize * 6), 1.0f / F32(m_tileSize));
 		dsInfo.m_gbufferTexCoordsBias = Vec2(0.0f, 0.0f);
 		dsInfo.m_gbufferTexCoordsBias = Vec2(0.0f, 0.0f);

+ 1 - 1
AnKi/Renderer/LensFlare.cpp

@@ -150,7 +150,7 @@ void LensFlare::runDrawFlares(const RenderingContext& ctx, CommandBufferPtr& cmd
 
 
 		// Compute position
 		// Compute position
 		Vec4 lfPos = Vec4(flareEl.m_worldPosition, 1.0);
 		Vec4 lfPos = Vec4(flareEl.m_worldPosition, 1.0);
-		Vec4 posClip = ctx.m_renderQueue->m_viewProjectionMatrix * lfPos;
+		Vec4 posClip = ctx.m_matrices.m_viewProjectionJitter * lfPos;
 
 
 		/*if(posClip.x() > posClip.w() || posClip.x() < -posClip.w() || posClip.y() > posClip.w()
 		/*if(posClip.x() > posClip.w() || posClip.x() < -posClip.w() || posClip.y() > posClip.w()
 			|| posClip.y() < -posClip.w())
 			|| posClip.y() < -posClip.w())

+ 27 - 14
AnKi/Renderer/ProbeReflections.cpp

@@ -326,7 +326,7 @@ void ProbeReflections::runGBuffer(RenderPassWorkContext& rgraphCtx)
 	ANKI_ASSERT(m_ctx.m_probe);
 	ANKI_ASSERT(m_ctx.m_probe);
 	ANKI_TRACE_SCOPED_EVENT(R_CUBE_REFL);
 	ANKI_TRACE_SCOPED_EVENT(R_CUBE_REFL);
 	const ReflectionProbeQueueElement& probe = *m_ctx.m_probe;
 	const ReflectionProbeQueueElement& probe = *m_ctx.m_probe;
-	const CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
+	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
 
 	I32 start, end;
 	I32 start, end;
 	U32 startu, endu;
 	U32 startu, endu;
@@ -350,11 +350,18 @@ void ProbeReflections::runGBuffer(RenderPassWorkContext& rgraphCtx)
 
 
 			const RenderQueue& rqueue = *probe.m_renderQueues[faceIdx];
 			const RenderQueue& rqueue = *probe.m_renderQueues[faceIdx];
 			ANKI_ASSERT(localStart >= 0 && localEnd <= faceDrawcallCount);
 			ANKI_ASSERT(localStart >= 0 && localEnd <= faceDrawcallCount);
-			m_r->getSceneDrawer().drawRange(
-				RenderingTechnique::GBUFFER, rqueue.m_viewMatrix, rqueue.m_viewProjectionMatrix,
-				Mat4::getIdentity(), // Don't care about prev mats
-				cmdb, m_r->getSamplers().m_trilinearRepeat, rqueue.m_renderables.getBegin() + localStart,
-				rqueue.m_renderables.getBegin() + localEnd, MAX_LOD_COUNT - 1, MAX_LOD_COUNT - 1);
+
+			RenderableDrawerArguments args;
+			args.m_viewMatrix = rqueue.m_viewMatrix;
+			args.m_cameraTransform = rqueue.m_cameraTransform;
+			args.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
+			args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care about prev mats
+			args.m_sampler = m_r->getSamplers().m_trilinearRepeat;
+			args.m_minLod = args.m_maxLod = MAX_LOD_COUNT - 1;
+
+			m_r->getSceneDrawer().drawRange(RenderingTechnique::GBUFFER, args,
+											rqueue.m_renderables.getBegin() + localStart,
+											rqueue.m_renderables.getBegin() + localEnd, cmdb);
 		}
 		}
 	}
 	}
 
 
@@ -377,7 +384,7 @@ void ProbeReflections::runLightShading(U32 faceIdx, const RenderingContext& rctx
 	TraditionalDeferredLightShadingDrawInfo dsInfo;
 	TraditionalDeferredLightShadingDrawInfo dsInfo;
 	dsInfo.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
 	dsInfo.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
 	dsInfo.m_invViewProjectionMatrix = rqueue.m_viewProjectionMatrix.getInverse();
 	dsInfo.m_invViewProjectionMatrix = rqueue.m_viewProjectionMatrix.getInverse();
-	dsInfo.m_cameraPosWSpace = rqueue.m_cameraTransform.getTranslationPart();
+	dsInfo.m_cameraPosWSpace = rqueue.m_cameraTransform.getTranslationPart().xyz1();
 	dsInfo.m_viewport = UVec4(0, 0, m_lightShading.m_tileSize, m_lightShading.m_tileSize);
 	dsInfo.m_viewport = UVec4(0, 0, m_lightShading.m_tileSize, m_lightShading.m_tileSize);
 	dsInfo.m_gbufferTexCoordsScale =
 	dsInfo.m_gbufferTexCoordsScale =
 		Vec2(1.0f / F32(m_lightShading.m_tileSize * 6), 1.0f / F32(m_lightShading.m_tileSize));
 		Vec2(1.0f / F32(m_lightShading.m_tileSize * 6), 1.0f / F32(m_lightShading.m_tileSize));
@@ -696,7 +703,7 @@ void ProbeReflections::runShadowMapping(RenderPassWorkContext& rgraphCtx)
 	start = I32(startu);
 	start = I32(startu);
 	end = I32(endu);
 	end = I32(endu);
 
 
-	const CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
+	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	cmdb->setPolygonOffset(1.0f, 1.0f);
 	cmdb->setPolygonOffset(1.0f, 1.0f);
 
 
 	I32 drawcallCount = 0;
 	I32 drawcallCount = 0;
@@ -720,12 +727,18 @@ void ProbeReflections::runShadowMapping(RenderPassWorkContext& rgraphCtx)
 			cmdb->setScissor(rez * faceIdx, 0, rez, rez);
 			cmdb->setScissor(rez * faceIdx, 0, rez, rez);
 
 
 			ANKI_ASSERT(localStart >= 0 && localEnd <= faceDrawcallCount);
 			ANKI_ASSERT(localStart >= 0 && localEnd <= faceDrawcallCount);
-			m_r->getSceneDrawer().drawRange(
-				RenderingTechnique::SHADOW, cascadeRenderQueue.m_viewMatrix, cascadeRenderQueue.m_viewProjectionMatrix,
-				Mat4::getIdentity(), // Don't care about prev matrices here
-				cmdb, m_r->getSamplers().m_trilinearRepeatAniso,
-				cascadeRenderQueue.m_renderables.getBegin() + localStart,
-				cascadeRenderQueue.m_renderables.getBegin() + localEnd, MAX_LOD_COUNT - 1, MAX_LOD_COUNT - 1);
+
+			RenderableDrawerArguments args;
+			args.m_viewMatrix = cascadeRenderQueue.m_viewMatrix;
+			args.m_cameraTransform = Mat3x4::getIdentity(); // Don't care
+			args.m_viewProjectionMatrix = cascadeRenderQueue.m_viewProjectionMatrix;
+			args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
+			args.m_sampler = m_r->getSamplers().m_trilinearRepeatAniso;
+			args.m_minLod = args.m_maxLod = MAX_LOD_COUNT - 1;
+
+			m_r->getSceneDrawer().drawRange(RenderingTechnique::SHADOW, args,
+											cascadeRenderQueue.m_renderables.getBegin() + localStart,
+											cascadeRenderQueue.m_renderables.getBegin() + localEnd, cmdb);
 		}
 		}
 	}
 	}
 }
 }

+ 2 - 2
AnKi/Renderer/RenderQueue.h

@@ -19,8 +19,8 @@ namespace anki {
 class RenderingMatrices
 class RenderingMatrices
 {
 {
 public:
 public:
-	Mat4 m_cameraTransform;
-	Mat4 m_viewMatrix;
+	Mat3x4 m_cameraTransform;
+	Mat3x4 m_viewMatrix;
 	Mat4 m_projectionMatrix;
 	Mat4 m_projectionMatrix;
 	Mat4 m_viewProjectionMatrix;
 	Mat4 m_viewProjectionMatrix;
 	Mat4 m_previousViewProjectionMatrix;
 	Mat4 m_previousViewProjectionMatrix;

+ 58 - 47
AnKi/Renderer/Renderer.cpp

@@ -45,6 +45,39 @@
 
 
 namespace anki {
 namespace anki {
 
 
+/// Generate a Halton jitter in [-0.5, 0.5]
+static Vec2 generateJitter(U32 frame)
+{
+	// Halton jitter
+	Vec2 result(0.0f);
+
+	constexpr U32 baseX = 2;
+	U32 index = frame + 1;
+	F32 invBase = 1.0f / baseX;
+	F32 fraction = invBase;
+	while(index > 0)
+	{
+		result.x() += (index % baseX) * fraction;
+		index /= baseX;
+		fraction *= invBase;
+	}
+
+	constexpr U32 baseY = 3;
+	index = frame + 1;
+	invBase = 1.0f / baseY;
+	fraction = invBase;
+	while(index > 0)
+	{
+		result.y() += (index % baseY) * fraction;
+		index /= baseY;
+		fraction *= invBase;
+	}
+
+	result.x() -= 0.5f;
+	result.y() -= 0.5f;
+	return result;
+}
+
 Renderer::Renderer()
 Renderer::Renderer()
 	: m_sceneDrawer(this)
 	: m_sceneDrawer(this)
 {
 {
@@ -152,6 +185,9 @@ Error Renderer::initInternal(UVec2 swapchainResolution)
 	m_vrsSriGeneration.reset(m_alloc.newInstance<VrsSriGeneration>(this));
 	m_vrsSriGeneration.reset(m_alloc.newInstance<VrsSriGeneration>(this));
 	ANKI_CHECK(m_vrsSriGeneration->init());
 	ANKI_CHECK(m_vrsSriGeneration->init());
 
 
+	m_scale.reset(m_alloc.newInstance<Scale>(this));
+	ANKI_CHECK(m_scale->init());
+
 	m_gbuffer.reset(m_alloc.newInstance<GBuffer>(this));
 	m_gbuffer.reset(m_alloc.newInstance<GBuffer>(this));
 	ANKI_CHECK(m_gbuffer->init());
 	ANKI_CHECK(m_gbuffer->init());
 
 
@@ -200,9 +236,6 @@ Error Renderer::initInternal(UVec2 swapchainResolution)
 	m_uiStage.reset(m_alloc.newInstance<UiStage>(this));
 	m_uiStage.reset(m_alloc.newInstance<UiStage>(this));
 	ANKI_CHECK(m_uiStage->init());
 	ANKI_CHECK(m_uiStage->init());
 
 
-	m_scale.reset(m_alloc.newInstance<Scale>(this));
-	ANKI_CHECK(m_scale->init());
-
 	m_indirectDiffuse.reset(m_alloc.newInstance<IndirectDiffuse>(this));
 	m_indirectDiffuse.reset(m_alloc.newInstance<IndirectDiffuse>(this));
 	ANKI_CHECK(m_indirectDiffuse->init());
 	ANKI_CHECK(m_indirectDiffuse->init());
 
 
@@ -244,53 +277,23 @@ Error Renderer::initInternal(UVec2 swapchainResolution)
 		sinit.m_anisotropyLevel = m_config->getRTextureAnisotropy();
 		sinit.m_anisotropyLevel = m_config->getRTextureAnisotropy();
 		m_samplers.m_trilinearRepeatAniso = m_gr->newSampler(sinit);
 		m_samplers.m_trilinearRepeatAniso = m_gr->newSampler(sinit);
 
 
-		const F32 scalingMipBias = log2(F32(m_internalResolution.x()) / F32(m_postProcessResolution.x()));
+		F32 scalingMipBias = log2(F32(m_internalResolution.x()) / F32(m_postProcessResolution.x()));
+		if(getScale().getUsingGrUpscaler())
+		{
+			// DLSS wants more bias
+			scalingMipBias -= 1.0f;
+		}
+
 		sinit.m_lodBias = scalingMipBias;
 		sinit.m_lodBias = scalingMipBias;
 		m_samplers.m_trilinearRepeatAnisoResolutionScalingBias = m_gr->newSampler(sinit);
 		m_samplers.m_trilinearRepeatAnisoResolutionScalingBias = m_gr->newSampler(sinit);
 	}
 	}
 
 
-	initJitteredMats();
-
-	return Error::NONE;
-}
-
-void Renderer::initJitteredMats()
-{
-	static const Array<Vec2, 16> SAMPLE_LOCS_16 = {
-		{Vec2(-8.0, 0.0), Vec2(-6.0, -4.0), Vec2(-3.0, -2.0), Vec2(-2.0, -6.0), Vec2(1.0, -1.0), Vec2(2.0, -5.0),
-		 Vec2(6.0, -7.0), Vec2(5.0, -3.0), Vec2(4.0, 1.0), Vec2(7.0, 4.0), Vec2(3.0, 5.0), Vec2(0.0, 7.0),
-		 Vec2(-1.0, 3.0), Vec2(-4.0, 6.0), Vec2(-7.0, 8.0), Vec2(-5.0, 2.0)}};
-
-	for(U i = 0; i < 16; ++i)
+	for(U32 i = 0; i < m_jitterOffsets.getSize(); ++i)
 	{
 	{
-		Vec2 texSize(1.0f / Vec2(F32(m_internalResolution.x()), F32(m_internalResolution.y()))); // Texel size
-		texSize *= 2.0f; // Move it to NDC
-
-		Vec2 S = SAMPLE_LOCS_16[i] / 8.0f; // In [-1, 1]
-
-		Vec2 subSample = S * texSize; // In [-texSize, texSize]
-		subSample *= 0.5f; // In [-texSize / 2, texSize / 2]
-
-		m_jitteredMats16x[i] = Mat4::getIdentity();
-		m_jitteredMats16x[i].setTranslationPart(Vec4(subSample, 0.0, 1.0));
+		m_jitterOffsets[i] = generateJitter(i);
 	}
 	}
 
 
-	static const Array<Vec2, 8> SAMPLE_LOCS_8 = {Vec2(-7.0, 1.0), Vec2(-5.0, -5.0), Vec2(-1.0, -3.0), Vec2(3.0, -7.0),
-												 Vec2(5.0, -1.0), Vec2(7.0, 7.0),   Vec2(1.0, 3.0),   Vec2(-3.0, 5.0)};
-
-	for(U i = 0; i < 8; ++i)
-	{
-		Vec2 texSize(1.0f / Vec2(F32(m_internalResolution.x()), F32(m_internalResolution.y()))); // Texel size
-		texSize *= 2.0f; // Move it to NDC
-
-		Vec2 S = SAMPLE_LOCS_8[i] / 8.0f; // In [-1, 1]
-
-		Vec2 subSample = S * texSize; // In [-texSize, texSize]
-		subSample *= 0.5f; // In [-texSize / 2, texSize / 2]
-
-		m_jitteredMats8x[i] = Mat4::getIdentity();
-		m_jitteredMats8x[i].setTranslationPart(Vec4(subSample, 0.0, 1.0));
-	}
+	return Error::NONE;
 }
 }
 
 
 Error Renderer::populateRenderGraph(RenderingContext& ctx)
 Error Renderer::populateRenderGraph(RenderingContext& ctx)
@@ -302,13 +305,18 @@ Error Renderer::populateRenderGraph(RenderingContext& ctx)
 	ctx.m_matrices.m_projection = ctx.m_renderQueue->m_projectionMatrix;
 	ctx.m_matrices.m_projection = ctx.m_renderQueue->m_projectionMatrix;
 	ctx.m_matrices.m_viewProjection = ctx.m_renderQueue->m_viewProjectionMatrix;
 	ctx.m_matrices.m_viewProjection = ctx.m_renderQueue->m_viewProjectionMatrix;
 
 
-	ctx.m_matrices.m_jitter = m_jitteredMats8x[m_frameCount & (m_jitteredMats8x.getSize() - 1)];
+	Vec2 jitter = m_jitterOffsets[m_frameCount & (m_jitterOffsets.getSize() - 1)]; // In [-0.5, 0.5]
+	const Vec2 ndcPixelSize = 2.0f / Vec2(m_internalResolution);
+	jitter *= ndcPixelSize;
+	ctx.m_matrices.m_jitter = Mat4::getIdentity();
+	ctx.m_matrices.m_jitter.setTranslationPart(Vec4(jitter, 0.0f, 1.0f));
+
 	ctx.m_matrices.m_projectionJitter = ctx.m_matrices.m_jitter * ctx.m_matrices.m_projection;
 	ctx.m_matrices.m_projectionJitter = ctx.m_matrices.m_jitter * ctx.m_matrices.m_projection;
-	ctx.m_matrices.m_viewProjectionJitter = ctx.m_matrices.m_projectionJitter * ctx.m_matrices.m_view;
+	ctx.m_matrices.m_viewProjectionJitter =
+		ctx.m_matrices.m_projectionJitter * Mat4(ctx.m_matrices.m_view, Vec4(0.0f, 0.0f, 0.0f, 1.0f));
 	ctx.m_matrices.m_invertedViewProjectionJitter = ctx.m_matrices.m_viewProjectionJitter.getInverse();
 	ctx.m_matrices.m_invertedViewProjectionJitter = ctx.m_matrices.m_viewProjectionJitter.getInverse();
 	ctx.m_matrices.m_invertedViewProjection = ctx.m_matrices.m_viewProjection.getInverse();
 	ctx.m_matrices.m_invertedViewProjection = ctx.m_matrices.m_viewProjection.getInverse();
 	ctx.m_matrices.m_invertedProjectionJitter = ctx.m_matrices.m_projectionJitter.getInverse();
 	ctx.m_matrices.m_invertedProjectionJitter = ctx.m_matrices.m_projectionJitter.getInverse();
-	ctx.m_matrices.m_invertedView = ctx.m_matrices.m_view.getInverse();
 
 
 	ctx.m_matrices.m_reprojection =
 	ctx.m_matrices.m_reprojection =
 		ctx.m_matrices.m_jitter * ctx.m_prevMatrices.m_viewProjection * ctx.m_matrices.m_invertedViewProjectionJitter;
 		ctx.m_matrices.m_jitter * ctx.m_prevMatrices.m_viewProjection * ctx.m_matrices.m_invertedViewProjectionJitter;
@@ -362,7 +370,10 @@ Error Renderer::populateRenderGraph(RenderingContext& ctx)
 	m_indirectSpecular->populateRenderGraph(ctx);
 	m_indirectSpecular->populateRenderGraph(ctx);
 	m_indirectDiffuse->populateRenderGraph(ctx);
 	m_indirectDiffuse->populateRenderGraph(ctx);
 	m_lightShading->populateRenderGraph(ctx);
 	m_lightShading->populateRenderGraph(ctx);
-	m_temporalAA->populateRenderGraph(ctx);
+	if(!getScale().getUsingGrUpscaler())
+	{
+		m_temporalAA->populateRenderGraph(ctx);
+	}
 	m_vrsSriGeneration->populateRenderGraph(ctx);
 	m_vrsSriGeneration->populateRenderGraph(ctx);
 	m_scale->populateRenderGraph(ctx);
 	m_scale->populateRenderGraph(ctx);
 	m_downscaleBlur->populateRenderGraph(ctx);
 	m_downscaleBlur->populateRenderGraph(ctx);

+ 2 - 5
AnKi/Renderer/Renderer.h

@@ -260,8 +260,7 @@ private:
 
 
 	CommonMatrices m_prevMatrices;
 	CommonMatrices m_prevMatrices;
 
 
-	Array<Mat4, 16> m_jitteredMats16x;
-	Array<Mat4, 8> m_jitteredMats8x;
+	Array<Vec2, 64> m_jitterOffsets;
 
 
 	TextureViewPtr m_dummyTexView2d;
 	TextureViewPtr m_dummyTexView2d;
 	TextureViewPtr m_dummyTexView3d;
 	TextureViewPtr m_dummyTexView3d;
@@ -281,9 +280,7 @@ private:
 	String m_currentDebugRtName;
 	String m_currentDebugRtName;
 
 
 	Error initInternal(UVec2 swapchainSize);
 	Error initInternal(UVec2 swapchainSize);
-
-	void initJitteredMats();
-}; // namespace anki
+};
 /// @}
 /// @}
 
 
 } // end namespace anki
 } // end namespace anki

+ 269 - 68
AnKi/Renderer/Scale.cpp

@@ -8,6 +8,11 @@
 #include <AnKi/Renderer/TemporalAA.h>
 #include <AnKi/Renderer/TemporalAA.h>
 #include <AnKi/Core/ConfigSet.h>
 #include <AnKi/Core/ConfigSet.h>
 
 
+#include <AnKi/Renderer/LightShading.h>
+#include <AnKi/Renderer/MotionVectors.h>
+#include <AnKi/Renderer/GBuffer.h>
+#include <AnKi/Renderer/Tonemapping.h>
+
 #if ANKI_COMPILER_GCC_COMPATIBLE
 #if ANKI_COMPILER_GCC_COMPATIBLE
 #	pragma GCC diagnostic push
 #	pragma GCC diagnostic push
 #	pragma GCC diagnostic ignored "-Wunused-function"
 #	pragma GCC diagnostic ignored "-Wunused-function"
@@ -33,57 +38,86 @@ Scale::~Scale()
 
 
 Error Scale::init()
 Error Scale::init()
 {
 {
-	ANKI_R_LOGV("Initializing scale");
-
 	const Bool needsScaling = m_r->getPostProcessResolution() != m_r->getInternalResolution();
 	const Bool needsScaling = m_r->getPostProcessResolution() != m_r->getInternalResolution();
-	const Bool needsSharpening = getConfig().getRSharpen();
+	const Bool needsSharpening = getConfig().getRSharpness() > 0.0f;
 	if(!needsScaling && !needsSharpening)
 	if(!needsScaling && !needsSharpening)
 	{
 	{
 		return Error::NONE;
 		return Error::NONE;
 	}
 	}
 
 
 	const Bool preferCompute = getConfig().getRPreferCompute();
 	const Bool preferCompute = getConfig().getRPreferCompute();
-	const U32 fsrQuality = getConfig().getRFsr();
-	m_fsr = fsrQuality != 0;
+	const U32 dlssQuality = getConfig().getRDlssQuality();
+	const U32 fsrQuality = getConfig().getRFsrQuality();
 
 
-	// Program
 	if(needsScaling)
 	if(needsScaling)
 	{
 	{
-		CString shaderFname;
-		if(m_fsr && preferCompute)
-		{
-			shaderFname = "ShaderBinaries/FsrCompute.ankiprogbin";
-		}
-		else if(m_fsr)
+		if(dlssQuality > 0 && getGrManager().getDeviceCapabilities().m_dlss)
 		{
 		{
-			shaderFname = "ShaderBinaries/FsrRaster.ankiprogbin";
+			m_upscalingMethod = UpscalingMethod::GR;
 		}
 		}
-		else if(preferCompute)
+		else if(fsrQuality > 0)
 		{
 		{
-			shaderFname = "ShaderBinaries/BlitCompute.ankiprogbin";
+			m_upscalingMethod = UpscalingMethod::FSR;
 		}
 		}
 		else
 		else
 		{
 		{
-			shaderFname = "ShaderBinaries/BlitRaster.ankiprogbin";
+			m_upscalingMethod = UpscalingMethod::BILINEAR;
 		}
 		}
+	}
+	else
+	{
+		m_upscalingMethod = UpscalingMethod::NONE;
+	}
+
+	m_sharpenMethod = (needsSharpening) ? SharpenMethod::RCAS : SharpenMethod::NONE;
+	m_neeedsTonemapping = (m_upscalingMethod == UpscalingMethod::GR); // Because GR upscaling spits HDR
+
+	static const Array<const Char*, U32(UpscalingMethod::COUNT)> upscalingMethodNames = {"none", "bilinear", "FSR 1.0",
+																						 "DLSS 2"};
+	static const Array<const Char*, U32(SharpenMethod::COUNT)> sharpenMethodNames = {"none", "RCAS"};
+
+	ANKI_R_LOGV("Initializing upscaling. Upscaling method %s, sharpenning method %s",
+				upscalingMethodNames[U32(m_upscalingMethod)], sharpenMethodNames[U32(m_sharpenMethod)]);
+
+	// Scale programs
+	if(m_upscalingMethod == UpscalingMethod::BILINEAR)
+	{
+		const CString shaderFname =
+			(preferCompute) ? "ShaderBinaries/BlitCompute.ankiprogbin" : "ShaderBinaries/BlitRaster.ankiprogbin";
 
 
 		ANKI_CHECK(getResourceManager().loadResource(shaderFname, m_scaleProg));
 		ANKI_CHECK(getResourceManager().loadResource(shaderFname, m_scaleProg));
+
 		const ShaderProgramResourceVariant* variant;
 		const ShaderProgramResourceVariant* variant;
-		if(m_fsr)
-		{
-			ShaderProgramResourceVariantInitInfo variantInitInfo(m_scaleProg);
-			variantInitInfo.addMutation("SHARPEN", 0);
-			variantInitInfo.addMutation("FSR_QUALITY", fsrQuality - 1);
-			m_scaleProg->getOrCreateVariant(variantInitInfo, variant);
-		}
-		else
-		{
-			m_scaleProg->getOrCreateVariant(variant);
-		}
+		m_scaleProg->getOrCreateVariant(variant);
 		m_scaleGrProg = variant->getProgram();
 		m_scaleGrProg = variant->getProgram();
 	}
 	}
+	else if(m_upscalingMethod == UpscalingMethod::FSR)
+	{
+		const CString shaderFname =
+			(preferCompute) ? "ShaderBinaries/FsrCompute.ankiprogbin" : "ShaderBinaries/FsrRaster.ankiprogbin";
+
+		ANKI_CHECK(getResourceManager().loadResource(shaderFname, m_scaleProg));
 
 
-	if(needsSharpening)
+		ShaderProgramResourceVariantInitInfo variantInitInfo(m_scaleProg);
+		variantInitInfo.addMutation("SHARPEN", 0);
+		variantInitInfo.addMutation("FSR_QUALITY", fsrQuality - 1);
+		const ShaderProgramResourceVariant* variant;
+		m_scaleProg->getOrCreateVariant(variantInitInfo, variant);
+		m_scaleGrProg = variant->getProgram();
+	}
+	else if(m_upscalingMethod == UpscalingMethod::GR)
+	{
+		GrUpscalerInitInfo inf;
+		inf.m_sourceTextureResolution = m_r->getInternalResolution();
+		inf.m_targetTextureResolution = m_r->getPostProcessResolution();
+		inf.m_upscalerType = GrUpscalerType::DLSS_2;
+		inf.m_qualityMode = GrUpscalerQualityMode(dlssQuality - 1);
+
+		m_grUpscaler = getGrManager().newGrUpscaler(inf);
+	}
+
+	// Sharpen programs
+	if(m_sharpenMethod == SharpenMethod::RCAS)
 	{
 	{
 		ANKI_CHECK(getResourceManager().loadResource((preferCompute) ? "ShaderBinaries/FsrCompute.ankiprogbin"
 		ANKI_CHECK(getResourceManager().loadResource((preferCompute) ? "ShaderBinaries/FsrCompute.ankiprogbin"
 																	 : "ShaderBinaries/FsrRaster.ankiprogbin",
 																	 : "ShaderBinaries/FsrRaster.ankiprogbin",
@@ -96,13 +130,45 @@ Error Scale::init()
 		m_sharpenGrProg = variant->getProgram();
 		m_sharpenGrProg = variant->getProgram();
 	}
 	}
 
 
+	// Tonemapping programs
+	if(m_neeedsTonemapping)
+	{
+		ANKI_CHECK(getResourceManager().loadResource((preferCompute) ? "ShaderBinaries/TonemapCompute.ankiprogbin"
+																	 : "ShaderBinaries/TonemapRaster.ankiprogbin",
+													 m_tonemapProg));
+		const ShaderProgramResourceVariant* variant;
+		m_tonemapProg->getOrCreateVariant(variant);
+		m_tonemapGrProg = variant->getProgram();
+	}
+
 	// Descriptors
 	// Descriptors
-	m_rtDesc = m_r->create2DRenderTargetDescription(
-		m_r->getPostProcessResolution().x(), m_r->getPostProcessResolution().y(),
-		(getGrManager().getDeviceCapabilities().m_unalignedBbpTextureFormats) ? Format::R8G8B8_UNORM
-																			  : Format::R8G8B8A8_UNORM,
-		"Scaled");
-	m_rtDesc.bake();
+	Format format;
+	if(m_upscalingMethod == UpscalingMethod::GR)
+	{
+		format = m_r->getHdrFormat();
+	}
+	else if(getGrManager().getDeviceCapabilities().m_unalignedBbpTextureFormats)
+	{
+		format = Format::R8G8B8_UNORM;
+	}
+	else
+	{
+		format = Format::R8G8B8A8_UNORM;
+	}
+
+	m_upscaleAndSharpenRtDescr = m_r->create2DRenderTargetDescription(
+		m_r->getPostProcessResolution().x(), m_r->getPostProcessResolution().y(), format, "Scaling");
+	m_upscaleAndSharpenRtDescr.bake();
+
+	if(m_neeedsTonemapping)
+	{
+		const Format fmt = (getGrManager().getDeviceCapabilities().m_unalignedBbpTextureFormats)
+							   ? Format::R8G8B8_UNORM
+							   : Format::R8G8B8A8_UNORM;
+		m_tonemapedRtDescr = m_r->create2DRenderTargetDescription(
+			m_r->getPostProcessResolution().x(), m_r->getPostProcessResolution().y(), fmt, "Tonemapped");
+		m_tonemapedRtDescr.bake();
+	}
 
 
 	m_fbDescr.m_colorAttachmentCount = 1;
 	m_fbDescr.m_colorAttachmentCount = 1;
 	m_fbDescr.bake();
 	m_fbDescr.bake();
@@ -112,93 +178,166 @@ Error Scale::init()
 
 
 void Scale::populateRenderGraph(RenderingContext& ctx)
 void Scale::populateRenderGraph(RenderingContext& ctx)
 {
 {
-	if(!doScaling() && !doSharpening())
+	if(m_upscalingMethod == UpscalingMethod::NONE && m_sharpenMethod == SharpenMethod::NONE)
 	{
 	{
-		m_runCtx.m_scaledRt = m_r->getTemporalAA().getRt();
-		m_runCtx.m_sharpenedRt = m_r->getTemporalAA().getRt();
+		m_runCtx.m_upscaledTonemappedRt = m_r->getTemporalAA().getTonemappedRt();
+		m_runCtx.m_upscaledHdrRt = m_r->getTemporalAA().getHdrRt();
+		m_runCtx.m_sharpenedRt = m_r->getTemporalAA().getTonemappedRt();
+		m_runCtx.m_tonemappedRt = m_r->getTemporalAA().getTonemappedRt();
 		return;
 		return;
 	}
 	}
 
 
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 	const Bool preferCompute = getConfig().getRPreferCompute();
 	const Bool preferCompute = getConfig().getRPreferCompute();
 
 
-	if(doScaling())
+	// Step 1: Upscaling
+	if(m_upscalingMethod == UpscalingMethod::GR)
 	{
 	{
-		m_runCtx.m_scaledRt = rgraph.newRenderTarget(m_rtDesc);
+		m_runCtx.m_upscaledHdrRt = rgraph.newRenderTarget(m_upscaleAndSharpenRtDescr);
+		m_runCtx.m_upscaledTonemappedRt = {};
+
+		ComputeRenderPassDescription& pass = ctx.m_renderGraphDescr.newComputeRenderPass("DLSS");
+
+		// DLSS says input textures in sampled state and out as storage image
+		const TextureUsageBit readUsage = TextureUsageBit::ALL_SAMPLED & TextureUsageBit::ALL_COMPUTE;
+		const TextureUsageBit writeUsage = TextureUsageBit::ALL_IMAGE & TextureUsageBit::ALL_COMPUTE;
+
+		pass.newDependency(RenderPassDependency(m_r->getLightShading().getRt(), readUsage));
+		pass.newDependency(RenderPassDependency(m_r->getMotionVectors().getMotionVectorsRt(), readUsage));
+		pass.newDependency(RenderPassDependency(m_r->getGBuffer().getDepthRt(), readUsage,
+												TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)));
+		pass.newDependency(RenderPassDependency(m_runCtx.m_upscaledHdrRt, writeUsage));
+
+		pass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
+			runGrUpscaling(ctx, rgraphCtx);
+		});
+	}
+	else if(m_upscalingMethod == UpscalingMethod::FSR || m_upscalingMethod == UpscalingMethod::BILINEAR)
+	{
+		m_runCtx.m_upscaledTonemappedRt = rgraph.newRenderTarget(m_upscaleAndSharpenRtDescr);
+		m_runCtx.m_upscaledHdrRt = {};
+		const RenderTargetHandle inRt = m_r->getTemporalAA().getTonemappedRt();
+		const RenderTargetHandle outRt = m_runCtx.m_upscaledTonemappedRt;
 
 
 		if(preferCompute)
 		if(preferCompute)
 		{
 		{
 			ComputeRenderPassDescription& pass = ctx.m_renderGraphDescr.newComputeRenderPass("Scale");
 			ComputeRenderPassDescription& pass = ctx.m_renderGraphDescr.newComputeRenderPass("Scale");
-			pass.newDependency(RenderPassDependency(m_r->getTemporalAA().getRt(), TextureUsageBit::SAMPLED_COMPUTE));
-			pass.newDependency(RenderPassDependency(m_runCtx.m_scaledRt, TextureUsageBit::IMAGE_COMPUTE_WRITE));
+			pass.newDependency(RenderPassDependency(inRt, TextureUsageBit::SAMPLED_COMPUTE));
+			pass.newDependency(RenderPassDependency(outRt, TextureUsageBit::IMAGE_COMPUTE_WRITE));
 
 
 			pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
 			pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
-				runScaling(rgraphCtx);
+				runFsrOrBilinearScaling(rgraphCtx);
 			});
 			});
 		}
 		}
 		else
 		else
 		{
 		{
 			GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Scale");
 			GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Scale");
-			pass.setFramebufferInfo(m_fbDescr, {m_runCtx.m_scaledRt});
+			pass.setFramebufferInfo(m_fbDescr, {outRt});
+			pass.newDependency(RenderPassDependency(inRt, TextureUsageBit::SAMPLED_FRAGMENT));
+			pass.newDependency(RenderPassDependency(outRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE));
+
+			pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
+				runFsrOrBilinearScaling(rgraphCtx);
+			});
+		}
+	}
+	else
+	{
+		ANKI_ASSERT(m_upscalingMethod == UpscalingMethod::NONE);
+		// Pretend that it got scaled
+		m_runCtx.m_upscaledTonemappedRt = m_r->getTemporalAA().getTonemappedRt();
+		m_runCtx.m_upscaledHdrRt = m_r->getTemporalAA().getHdrRt();
+	}
+
+	// Step 2: Tonemapping
+	if(m_neeedsTonemapping)
+	{
+		m_runCtx.m_tonemappedRt = rgraph.newRenderTarget(m_tonemapedRtDescr);
+		const RenderTargetHandle inRt = m_runCtx.m_upscaledHdrRt;
+		const RenderTargetHandle outRt = m_runCtx.m_tonemappedRt;
+
+		if(preferCompute)
+		{
+			ComputeRenderPassDescription& pass = ctx.m_renderGraphDescr.newComputeRenderPass("Tonemap");
+			pass.newDependency(RenderPassDependency(inRt, TextureUsageBit::SAMPLED_COMPUTE));
+			pass.newDependency(RenderPassDependency(outRt, TextureUsageBit::IMAGE_COMPUTE_WRITE));
 
 
-			pass.newDependency(RenderPassDependency(m_r->getTemporalAA().getRt(), TextureUsageBit::SAMPLED_FRAGMENT));
-			pass.newDependency(
-				RenderPassDependency(m_runCtx.m_scaledRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE));
+			pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
+				runTonemapping(rgraphCtx);
+			});
+		}
+		else
+		{
+			GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Sharpen");
+			pass.setFramebufferInfo(m_fbDescr, {outRt});
+			pass.newDependency(RenderPassDependency(inRt, TextureUsageBit::SAMPLED_FRAGMENT));
+			pass.newDependency(RenderPassDependency(outRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE));
 
 
 			pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
 			pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
-				runScaling(rgraphCtx);
+				runTonemapping(rgraphCtx);
 			});
 			});
 		}
 		}
 	}
 	}
+	else
+	{
+		m_runCtx.m_tonemappedRt = m_runCtx.m_upscaledTonemappedRt;
+	}
 
 
-	if(doSharpening())
+	// Step 3: Sharpenning
+	if(m_sharpenMethod == SharpenMethod::RCAS)
 	{
 	{
-		m_runCtx.m_sharpenedRt = rgraph.newRenderTarget(m_rtDesc);
+		m_runCtx.m_sharpenedRt = rgraph.newRenderTarget(m_upscaleAndSharpenRtDescr);
+		const RenderTargetHandle inRt = m_runCtx.m_tonemappedRt;
+		const RenderTargetHandle outRt = m_runCtx.m_sharpenedRt;
 
 
 		if(preferCompute)
 		if(preferCompute)
 		{
 		{
 			ComputeRenderPassDescription& pass = ctx.m_renderGraphDescr.newComputeRenderPass("Sharpen");
 			ComputeRenderPassDescription& pass = ctx.m_renderGraphDescr.newComputeRenderPass("Sharpen");
-			pass.newDependency(RenderPassDependency((!doScaling()) ? m_r->getTemporalAA().getRt() : m_runCtx.m_scaledRt,
-													TextureUsageBit::SAMPLED_COMPUTE));
-			pass.newDependency(RenderPassDependency(m_runCtx.m_sharpenedRt, TextureUsageBit::IMAGE_COMPUTE_WRITE));
+			pass.newDependency(RenderPassDependency(inRt, TextureUsageBit::SAMPLED_COMPUTE));
+			pass.newDependency(RenderPassDependency(outRt, TextureUsageBit::IMAGE_COMPUTE_WRITE));
 
 
 			pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
 			pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
-				runSharpening(rgraphCtx);
+				runRcasSharpening(rgraphCtx);
 			});
 			});
 		}
 		}
 		else
 		else
 		{
 		{
 			GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Sharpen");
 			GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Sharpen");
-			pass.setFramebufferInfo(m_fbDescr, {m_runCtx.m_sharpenedRt});
-
-			pass.newDependency(RenderPassDependency((!doScaling()) ? m_r->getTemporalAA().getRt() : m_runCtx.m_scaledRt,
-													TextureUsageBit::SAMPLED_FRAGMENT));
-			pass.newDependency(
-				RenderPassDependency(m_runCtx.m_sharpenedRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE));
+			pass.setFramebufferInfo(m_fbDescr, {outRt});
+			pass.newDependency(RenderPassDependency(inRt, TextureUsageBit::SAMPLED_FRAGMENT));
+			pass.newDependency(RenderPassDependency(outRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE));
 
 
 			pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
 			pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
-				runSharpening(rgraphCtx);
+				runRcasSharpening(rgraphCtx);
 			});
 			});
 		}
 		}
 	}
 	}
+	else
+	{
+		ANKI_ASSERT(m_sharpenMethod == SharpenMethod::NONE);
+		// Pretend that it's sharpened
+		m_runCtx.m_sharpenedRt = m_runCtx.m_tonemappedRt;
+	}
 }
 }
 
 
-void Scale::runScaling(RenderPassWorkContext& rgraphCtx)
+void Scale::runFsrOrBilinearScaling(RenderPassWorkContext& rgraphCtx)
 {
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	const Bool preferCompute = getConfig().getRPreferCompute();
 	const Bool preferCompute = getConfig().getRPreferCompute();
+	const RenderTargetHandle inRt = m_r->getTemporalAA().getTonemappedRt();
+	const RenderTargetHandle outRt = m_runCtx.m_upscaledTonemappedRt;
 
 
 	cmdb->bindShaderProgram(m_scaleGrProg);
 	cmdb->bindShaderProgram(m_scaleGrProg);
 
 
 	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
 	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
-	rgraphCtx.bindColorTexture(0, 1, m_r->getTemporalAA().getRt());
+	rgraphCtx.bindColorTexture(0, 1, inRt);
 
 
 	if(preferCompute)
 	if(preferCompute)
 	{
 	{
-		rgraphCtx.bindImage(0, 2, m_runCtx.m_scaledRt);
+		rgraphCtx.bindImage(0, 2, outRt);
 	}
 	}
 
 
-	if(m_fsr)
+	if(m_upscalingMethod == UpscalingMethod::FSR)
 	{
 	{
 		class
 		class
 		{
 		{
@@ -245,19 +384,21 @@ void Scale::runScaling(RenderPassWorkContext& rgraphCtx)
 	}
 	}
 }
 }
 
 
-void Scale::runSharpening(RenderPassWorkContext& rgraphCtx)
+void Scale::runRcasSharpening(RenderPassWorkContext& rgraphCtx)
 {
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	const Bool preferCompute = getConfig().getRPreferCompute();
 	const Bool preferCompute = getConfig().getRPreferCompute();
+	const RenderTargetHandle inRt = m_runCtx.m_tonemappedRt;
+	const RenderTargetHandle outRt = m_runCtx.m_sharpenedRt;
 
 
 	cmdb->bindShaderProgram(m_sharpenGrProg);
 	cmdb->bindShaderProgram(m_sharpenGrProg);
 
 
 	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
 	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
-	rgraphCtx.bindColorTexture(0, 1, (!doScaling()) ? m_r->getTemporalAA().getRt() : m_runCtx.m_scaledRt);
+	rgraphCtx.bindColorTexture(0, 1, inRt);
 
 
 	if(preferCompute)
 	if(preferCompute)
 	{
 	{
-		rgraphCtx.bindImage(0, 2, m_runCtx.m_sharpenedRt);
+		rgraphCtx.bindImage(0, 2, outRt);
 	}
 	}
 
 
 	class
 	class
@@ -271,7 +412,10 @@ void Scale::runSharpening(RenderPassWorkContext& rgraphCtx)
 		UVec2 m_padding;
 		UVec2 m_padding;
 	} pc;
 	} pc;
 
 
-	FsrRcasCon(&pc.m_fsrConsts0[0], 0.2f);
+	F32 sharpness = getConfig().getRSharpness(); // [0, 1]
+	sharpness *= 3.0f; // [0, 3]
+	sharpness = 3.0f - sharpness; // [3, 0], RCAS translates 0 to max sharpness
+	FsrRcasCon(&pc.m_fsrConsts0[0], sharpness);
 
 
 	pc.m_viewportSize = m_r->getPostProcessResolution();
 	pc.m_viewportSize = m_r->getPostProcessResolution();
 
 
@@ -288,4 +432,61 @@ void Scale::runSharpening(RenderPassWorkContext& rgraphCtx)
 	}
 	}
 }
 }
 
 
+void Scale::runGrUpscaling(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
+{
+	const Vec2 srcRes(m_r->getInternalResolution());
+	const Bool reset = m_r->getFrameCount() == 0;
+	const Vec2 mvScale = srcRes; // UV space to Pixel space factor
+	// In [-texSize / 2, texSize / 2] -> sub-pixel space {-0.5, 0.5}
+	const Vec2 jitterOffset = ctx.m_matrices.m_jitter.getTranslationPart().xy() * srcRes * 0.5f;
+
+	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
+
+	TextureViewPtr srcView = rgraphCtx.createTextureView(m_r->getLightShading().getRt());
+	TextureViewPtr motionVectorsView = rgraphCtx.createTextureView(m_r->getMotionVectors().getMotionVectorsRt());
+	TextureViewPtr depthView = rgraphCtx.createTextureView(m_r->getGBuffer().getDepthRt());
+	TextureViewPtr exposureView = rgraphCtx.createTextureView(m_r->getTonemapping().getRt());
+	TextureViewPtr dstView = rgraphCtx.createTextureView(m_runCtx.m_upscaledHdrRt);
+
+	cmdb->upscale(m_grUpscaler, srcView, dstView, motionVectorsView, depthView, exposureView, reset, jitterOffset,
+				  mvScale);
+}
+
+void Scale::runTonemapping(RenderPassWorkContext& rgraphCtx)
+{
+	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
+	const Bool preferCompute = getConfig().getRPreferCompute();
+	const RenderTargetHandle inRt = m_runCtx.m_upscaledHdrRt;
+	const RenderTargetHandle outRt = m_runCtx.m_tonemappedRt;
+
+	cmdb->bindShaderProgram(m_tonemapGrProg);
+
+	cmdb->bindSampler(0, 0, m_r->getSamplers().m_nearestNearestClamp);
+	rgraphCtx.bindColorTexture(0, 1, inRt);
+
+	rgraphCtx.bindImage(0, 2, m_r->getTonemapping().getRt());
+
+	class
+	{
+	public:
+		Vec2 m_viewportSizeOverOne;
+		UVec2 m_viewportSize;
+	} pc;
+	pc.m_viewportSizeOverOne = 1.0f / Vec2(m_r->getPostProcessResolution());
+	pc.m_viewportSize = m_r->getPostProcessResolution();
+	cmdb->setPushConstants(&pc, sizeof(pc));
+
+	if(preferCompute)
+	{
+		rgraphCtx.bindImage(0, 3, outRt);
+
+		dispatchPPCompute(cmdb, 8, 8, m_r->getPostProcessResolution().x(), m_r->getPostProcessResolution().y());
+	}
+	else
+	{
+		cmdb->setViewport(0, 0, m_r->getPostProcessResolution().x(), m_r->getPostProcessResolution().y());
+		cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3);
+	}
+}
+
 } // end namespace anki
 } // end namespace anki

+ 57 - 19
AnKi/Renderer/Scale.h

@@ -12,7 +12,7 @@ namespace anki {
 /// @addtogroup renderer
 /// @addtogroup renderer
 /// @{
 /// @{
 
 
-/// Upscale or downscale pass.
+/// Upscales, sharpens and in some cases tonemaps.
 class Scale : public RendererObject
 class Scale : public RendererObject
 {
 {
 public:
 public:
@@ -27,9 +27,28 @@ public:
 
 
 	void populateRenderGraph(RenderingContext& ctx);
 	void populateRenderGraph(RenderingContext& ctx);
 
 
-	RenderTargetHandle getRt() const
+	/// This is the tonemapped, upscaled and sharpened RT.
+	RenderTargetHandle getTonemappedRt() const
 	{
 	{
-		return (doSharpening()) ? m_runCtx.m_sharpenedRt : m_runCtx.m_scaledRt;
+		return m_runCtx.m_sharpenedRt;
+	}
+
+	/// This is the HDR upscaled RT. It's available if hasUscaledHdrRt() returns true.
+	RenderTargetHandle getUpscaledHdrRt() const
+	{
+		ANKI_ASSERT(hasUpscaledHdrRt());
+		return m_runCtx.m_upscaledHdrRt;
+	}
+
+	/// @see getUpscaledHdrRt.
+	Bool hasUpscaledHdrRt() const
+	{
+		return m_runCtx.m_upscaledHdrRt.isValid();
+	}
+
+	Bool getUsingGrUpscaler() const
+	{
+		return m_grUpscaler.isCreated();
 	}
 	}
 
 
 private:
 private:
@@ -37,31 +56,50 @@ private:
 	ShaderProgramPtr m_scaleGrProg;
 	ShaderProgramPtr m_scaleGrProg;
 	ShaderProgramResourcePtr m_sharpenProg;
 	ShaderProgramResourcePtr m_sharpenProg;
 	ShaderProgramPtr m_sharpenGrProg;
 	ShaderProgramPtr m_sharpenGrProg;
+	ShaderProgramResourcePtr m_tonemapProg;
+	ShaderProgramPtr m_tonemapGrProg;
 
 
-	FramebufferDescription m_fbDescr;
-	RenderTargetDescription m_rtDesc;
+	GrUpscalerPtr m_grUpscaler;
 
 
-	Bool m_fsr = false;
+	FramebufferDescription m_fbDescr;
+	RenderTargetDescription m_upscaleAndSharpenRtDescr;
+	RenderTargetDescription m_tonemapedRtDescr;
 
 
-	class
+	enum class UpscalingMethod : U8
 	{
 	{
-	public:
-		RenderTargetHandle m_scaledRt;
-		RenderTargetHandle m_sharpenedRt;
-	} m_runCtx;
+		NONE,
+		BILINEAR,
+		FSR,
+		GR,
+		COUNT
+	};
 
 
-	void runScaling(RenderPassWorkContext& rgraphCtx);
-	void runSharpening(RenderPassWorkContext& rgraphCtx);
+	UpscalingMethod m_upscalingMethod = UpscalingMethod::NONE;
 
 
-	Bool doSharpening() const
+	enum class SharpenMethod : U8
 	{
 	{
-		return m_sharpenProg.isCreated();
-	}
+		NONE,
+		RCAS,
+		COUNT
+	};
+
+	SharpenMethod m_sharpenMethod = SharpenMethod::NONE;
+
+	Bool m_neeedsTonemapping = false;
 
 
-	Bool doScaling() const
+	class
 	{
 	{
-		return m_scaleProg.isCreated();
-	}
+	public:
+		RenderTargetHandle m_upscaledTonemappedRt;
+		RenderTargetHandle m_upscaledHdrRt;
+		RenderTargetHandle m_tonemappedRt;
+		RenderTargetHandle m_sharpenedRt; ///< It's tonemaped.
+	} m_runCtx;
+
+	void runFsrOrBilinearScaling(RenderPassWorkContext& rgraphCtx);
+	void runRcasSharpening(RenderPassWorkContext& rgraphCtx);
+	void runGrUpscaling(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
+	void runTonemapping(RenderPassWorkContext& rgraphCtx);
 };
 };
 /// @}
 /// @}
 
 

+ 11 - 6
AnKi/Renderer/ShadowMapping.cpp

@@ -221,14 +221,19 @@ void ShadowMapping::runShadowMapping(RenderPassWorkContext& rgraphCtx)
 		cmdb->setViewport(work.m_viewport[0], work.m_viewport[1], work.m_viewport[2], work.m_viewport[3]);
 		cmdb->setViewport(work.m_viewport[0], work.m_viewport[1], work.m_viewport[2], work.m_viewport[3]);
 		cmdb->setScissor(work.m_viewport[0], work.m_viewport[1], work.m_viewport[2], work.m_viewport[3]);
 		cmdb->setScissor(work.m_viewport[0], work.m_viewport[1], work.m_viewport[2], work.m_viewport[3]);
 
 
-		m_r->getSceneDrawer().drawRange(RenderingTechnique::SHADOW, work.m_renderQueue->m_viewMatrix,
-										work.m_renderQueue->m_viewProjectionMatrix,
-										Mat4::getIdentity(), // Don't care about prev matrices here
-										cmdb, m_r->getSamplers().m_trilinearRepeatAniso,
+		RenderableDrawerArguments args;
+		args.m_viewMatrix = work.m_renderQueue->m_viewMatrix;
+		args.m_cameraTransform = Mat3x4::getIdentity(); // Don't care
+		args.m_viewProjectionMatrix = work.m_renderQueue->m_viewProjectionMatrix;
+		args.m_previousViewProjectionMatrix = Mat4::getIdentity(); // Don't care
+		args.m_sampler = m_r->getSamplers().m_trilinearRepeatAniso;
+		args.m_minLod = args.m_maxLod = work.m_renderQueueElementsLod;
+
+		m_r->getSceneDrawer().drawRange(RenderingTechnique::SHADOW, args,
 										work.m_renderQueue->m_renderables.getBegin() + work.m_firstRenderableElement,
 										work.m_renderQueue->m_renderables.getBegin() + work.m_firstRenderableElement,
 										work.m_renderQueue->m_renderables.getBegin() + work.m_firstRenderableElement
 										work.m_renderQueue->m_renderables.getBegin() + work.m_firstRenderableElement
 											+ work.m_renderableElementCount,
 											+ work.m_renderableElementCount,
-										work.m_renderQueueElementsLod, work.m_renderQueueElementsLod);
+										cmdb);
 	}
 	}
 }
 }
 
 
@@ -708,7 +713,7 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 
 
 		// Allocate tiles
 		// Allocate tiles
 		U32 faceIdx = 0;
 		U32 faceIdx = 0;
-		TileAllocatorResult subResult;
+		TileAllocatorResult subResult = TileAllocatorResult::ALLOCATION_FAILED;
 		UVec4 atlasViewport;
 		UVec4 atlasViewport;
 		UVec4 scratchViewport;
 		UVec4 scratchViewport;
 		const U32 localDrawcallCount = light.m_shadowRenderQueue->m_renderables.getSize();
 		const U32 localDrawcallCount = light.m_shadowRenderQueue->m_renderables.getSize();

+ 1 - 1
AnKi/Renderer/TemporalAA.cpp

@@ -153,7 +153,7 @@ void TemporalAA::populateRenderGraph(RenderingContext& ctx)
 		rgraphCtx.bindColorTexture(0, 2, m_r->getLightShading().getRt());
 		rgraphCtx.bindColorTexture(0, 2, m_r->getLightShading().getRt());
 		rgraphCtx.bindColorTexture(0, 3, m_runCtx.m_historyRt);
 		rgraphCtx.bindColorTexture(0, 3, m_runCtx.m_historyRt);
 		rgraphCtx.bindColorTexture(0, 4, m_r->getMotionVectors().getMotionVectorsRt());
 		rgraphCtx.bindColorTexture(0, 4, m_r->getMotionVectors().getMotionVectorsRt());
-		rgraphCtx.bindUniformBuffer(0, 5, m_r->getTonemapping().getAverageLuminanceBuffer());
+		rgraphCtx.bindImage(0, 5, m_r->getTonemapping().getRt());
 
 
 		if(getConfig().getRPreferCompute())
 		if(getConfig().getRPreferCompute())
 		{
 		{

+ 6 - 1
AnKi/Renderer/TemporalAA.h

@@ -25,11 +25,16 @@ public:
 	void populateRenderGraph(RenderingContext& ctx);
 	void populateRenderGraph(RenderingContext& ctx);
 
 
 	/// Result is tonemaped.
 	/// Result is tonemaped.
-	RenderTargetHandle getRt() const
+	RenderTargetHandle getTonemappedRt() const
 	{
 	{
 		return m_runCtx.m_tonemappedRt;
 		return m_runCtx.m_tonemappedRt;
 	}
 	}
 
 
+	RenderTargetHandle getHdrRt() const
+	{
+		return m_runCtx.m_renderRt;
+	}
+
 private:
 private:
 	Array<TexturePtr, 2> m_rtTextures;
 	Array<TexturePtr, 2> m_rtTextures;
 	Array<Bool, 2> m_rtTexturesImportedOnce = {};
 	Array<Bool, 2> m_rtTexturesImportedOnce = {};

+ 14 - 29
AnKi/Renderer/Tonemapping.cpp

@@ -38,36 +38,24 @@ Error Tonemapping::initInternal()
 	m_prog->getOrCreateVariant(variantInitInfo, variant);
 	m_prog->getOrCreateVariant(variantInitInfo, variant);
 	m_grProg = variant->getProgram();
 	m_grProg = variant->getProgram();
 
 
-	// Create buffer
-	m_luminanceBuff = getGrManager().newBuffer(BufferInitInfo(
-		sizeof(Vec4), BufferUsageBit::ALL_STORAGE | BufferUsageBit::ALL_UNIFORM | BufferUsageBit::TRANSFER_DESTINATION,
-		BufferMapAccessBit::NONE, "AvgLum"));
-
-	CommandBufferInitInfo cmdbinit;
-	cmdbinit.m_flags = CommandBufferFlag::SMALL_BATCH | CommandBufferFlag::GENERAL_WORK;
-	CommandBufferPtr cmdb = getGrManager().newCommandBuffer(cmdbinit);
-
-	TransferGpuAllocatorHandle handle;
-	ANKI_CHECK(m_r->getResourceManager().getTransferGpuAllocator().allocate(sizeof(Vec4), handle));
-	void* data = handle.getMappedMemory();
-
-	*static_cast<Vec4*>(data) = Vec4(0.5);
-	cmdb->copyBufferToBuffer(handle.getBuffer(), handle.getOffset(), m_luminanceBuff, 0, handle.getRange());
-
-	FencePtr fence;
-	cmdb->flush({}, &fence);
-
-	m_r->getResourceManager().getTransferGpuAllocator().release(handle, fence);
+	// Create exposure texture.
+	// WARNING: Use it only as IMAGE and nothing else. It will not be tracked by the rendergraph. No tracking means no
+	// automatic image transitions
+	const TextureUsageBit usage = TextureUsageBit::ALL_IMAGE;
+	const TextureInitInfo texinit =
+		m_r->create2DRenderTargetInitInfo(1, 1, Format::R16G16_SFLOAT, usage, "ExposureAndAvgLum1x1");
+	ClearValue clearValue;
+	clearValue.m_colorf = {0.5f, 0.5f, 0.5f, 0.5f};
+	m_exposureAndAvgLuminance1x1 = m_r->createAndClearRenderTarget(texinit, TextureUsageBit::ALL_IMAGE, clearValue);
 
 
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 
 void Tonemapping::importRenderTargets(RenderingContext& ctx)
 void Tonemapping::importRenderTargets(RenderingContext& ctx)
 {
 {
-	// Computation of the AVG luminance will run first in the frame and it will use the m_luminanceBuff as storage
-	// read/write. To skip the barrier import it as read/write as well.
-	m_runCtx.m_buffHandle = ctx.m_renderGraphDescr.importBuffer(
-		m_luminanceBuff, BufferUsageBit::STORAGE_COMPUTE_READ | BufferUsageBit::STORAGE_COMPUTE_WRITE);
+	// Just import it. It will not be used in resource tracking
+	m_runCtx.m_exposureLuminanceHandle =
+		ctx.m_renderGraphDescr.importRenderTarget(m_exposureAndAvgLuminance1x1, TextureUsageBit::ALL_IMAGE);
 }
 }
 
 
 void Tonemapping::populateRenderGraph(RenderingContext& ctx)
 void Tonemapping::populateRenderGraph(RenderingContext& ctx)
@@ -75,13 +63,13 @@ void Tonemapping::populateRenderGraph(RenderingContext& ctx)
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 
 	// Create the pass
 	// Create the pass
-	ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("Avg lum");
+	ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("AvgLuminance");
 
 
 	pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
 	pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
 		CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 		CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
 
 		cmdb->bindShaderProgram(m_grProg);
 		cmdb->bindShaderProgram(m_grProg);
-		rgraphCtx.bindStorageBuffer(0, 1, m_runCtx.m_buffHandle);
+		rgraphCtx.bindImage(0, 1, m_runCtx.m_exposureLuminanceHandle);
 
 
 		TextureSubresourceInfo inputTexSubresource;
 		TextureSubresourceInfo inputTexSubresource;
 		inputTexSubresource.m_firstMipmap = m_inputTexMip;
 		inputTexSubresource.m_firstMipmap = m_inputTexMip;
@@ -90,9 +78,6 @@ void Tonemapping::populateRenderGraph(RenderingContext& ctx)
 		cmdb->dispatchCompute(1, 1, 1);
 		cmdb->dispatchCompute(1, 1, 1);
 	});
 	});
 
 
-	pass.newDependency(
-		{m_runCtx.m_buffHandle, BufferUsageBit::STORAGE_COMPUTE_READ | BufferUsageBit::STORAGE_COMPUTE_WRITE});
-
 	TextureSubresourceInfo inputTexSubresource;
 	TextureSubresourceInfo inputTexSubresource;
 	inputTexSubresource.m_firstMipmap = m_inputTexMip;
 	inputTexSubresource.m_firstMipmap = m_inputTexMip;
 	pass.newDependency({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE, inputTexSubresource});
 	pass.newDependency({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE, inputTexSubresource});

+ 7 - 4
AnKi/Renderer/Tonemapping.h

@@ -28,9 +28,10 @@ public:
 	/// Populate the rendergraph.
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);
 	void populateRenderGraph(RenderingContext& ctx);
 
 
-	BufferHandle getAverageLuminanceBuffer() const
+	/// @copydoc m_exposureAndAvgLuminance1x1
+	RenderTargetHandle getRt() const
 	{
 	{
-		return m_runCtx.m_buffHandle;
+		return m_runCtx.m_exposureLuminanceHandle;
 	}
 	}
 
 
 private:
 private:
@@ -38,12 +39,14 @@ private:
 	ShaderProgramPtr m_grProg;
 	ShaderProgramPtr m_grProg;
 	U32 m_inputTexMip;
 	U32 m_inputTexMip;
 
 
-	BufferPtr m_luminanceBuff;
+	/// This is a 1x1 2 component texture where R is the exposure and G the average luminance. It's not tracked in
+	/// rendergraph depedencies. We don't care to track it because it affects the eye adaptation.
+	TexturePtr m_exposureAndAvgLuminance1x1;
 
 
 	class
 	class
 	{
 	{
 	public:
 	public:
-		BufferHandle m_buffHandle;
+		RenderTargetHandle m_exposureLuminanceHandle;
 	} m_runCtx;
 	} m_runCtx;
 
 
 	Error initInternal();
 	Error initInternal();

+ 2 - 2
AnKi/Scene/Components/FrustumComponent.cpp

@@ -96,13 +96,13 @@ Bool FrustumComponent::updateInternal()
 	if(m_trfMarkedForUpdate)
 	if(m_trfMarkedForUpdate)
 	{
 	{
 		updated = true;
 		updated = true;
-		m_viewMat = Mat4(m_trf.getInverse());
+		m_viewMat = Mat3x4(m_trf.getInverse());
 	}
 	}
 
 
 	// Updates that are affected by transform & shape updates
 	// Updates that are affected by transform & shape updates
 	if(updated)
 	if(updated)
 	{
 	{
-		m_viewProjMat = m_projMat * m_viewMat;
+		m_viewProjMat = m_projMat * Mat4(m_viewMat, Vec4(0.0f, 0.0f, 0.0f, 1.0f));
 		m_shapeMarkedForUpdate = false;
 		m_shapeMarkedForUpdate = false;
 		m_trfMarkedForUpdate = false;
 		m_trfMarkedForUpdate = false;
 
 

+ 2 - 2
AnKi/Scene/Components/FrustumComponent.h

@@ -237,7 +237,7 @@ public:
 		return m_projMat;
 		return m_projMat;
 	}
 	}
 
 
-	const Mat4& getViewMatrix() const
+	const Mat3x4& getViewMatrix() const
 	{
 	{
 		return m_viewMat;
 		return m_viewMat;
 	}
 	}
@@ -414,7 +414,7 @@ private:
 
 
 	Transform m_trf = Transform::getIdentity();
 	Transform m_trf = Transform::getIdentity();
 	Mat4 m_projMat = Mat4::getIdentity(); ///< Projection matrix
 	Mat4 m_projMat = Mat4::getIdentity(); ///< Projection matrix
-	Mat4 m_viewMat = Mat4::getIdentity(); ///< View matrix
+	Mat3x4 m_viewMat = Mat3x4::getIdentity(); ///< View matrix
 	Mat4 m_viewProjMat = Mat4::getIdentity(); ///< View projection matrix
 	Mat4 m_viewProjMat = Mat4::getIdentity(); ///< View projection matrix
 	Mat4 m_prevViewProjMat = Mat4::getIdentity();
 	Mat4 m_prevViewProjMat = Mat4::getIdentity();
 
 

+ 3 - 3
AnKi/Scene/DebugDrawer.cpp

@@ -218,7 +218,7 @@ void DebugDrawer2::drawLines(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 l
 	cmdb->drawArrays(PrimitiveTopology::LINES, linePositions.getSize(), mvps.getSize());
 	cmdb->drawArrays(PrimitiveTopology::LINES, linePositions.getSize(), mvps.getSize());
 }
 }
 
 
-void DebugDrawer2::drawBillboardTextures(const Mat4& projMat, const Mat4& viewMat, ConstWeakArray<Vec3> positions,
+void DebugDrawer2::drawBillboardTextures(const Mat4& projMat, const Mat3x4& viewMat, ConstWeakArray<Vec3> positions,
 										 const Vec4& color, Bool ditherFailedDepth, TextureViewPtr tex,
 										 const Vec4& color, Bool ditherFailedDepth, TextureViewPtr tex,
 										 SamplerPtr sampler, Vec2 billboardSize,
 										 SamplerPtr sampler, Vec2 billboardSize,
 										 StagingGpuMemoryPool& stagingGpuAllocator, CommandBufferPtr& cmdb) const
 										 StagingGpuMemoryPool& stagingGpuAllocator, CommandBufferPtr& cmdb) const
@@ -246,7 +246,7 @@ void DebugDrawer2::drawBillboardTextures(const Mat4& projMat, const Mat4& viewMa
 	Mat4* pmvps = static_cast<Mat4*>(stagingGpuAllocator.allocateFrame(
 	Mat4* pmvps = static_cast<Mat4*>(stagingGpuAllocator.allocateFrame(
 		sizeof(Mat4) * positions.getSize() + sizeof(Vec4), StagingGpuMemoryType::UNIFORM, unisToken));
 		sizeof(Mat4) * positions.getSize() + sizeof(Vec4), StagingGpuMemoryType::UNIFORM, unisToken));
 
 
-	const Mat4 camTrf = viewMat.getInverse();
+	const Mat4 camTrf = Mat4(viewMat, Vec4(0.0f, 0.0f, 0.0f, 1.0f)).getInverse();
 	const Vec3 zAxis = camTrf.getZAxis().xyz().getNormalized();
 	const Vec3 zAxis = camTrf.getZAxis().xyz().getNormalized();
 	Vec3 yAxis = Vec3(0.0f, 1.0f, 0.0f);
 	Vec3 yAxis = Vec3(0.0f, 1.0f, 0.0f);
 	const Vec3 xAxis = yAxis.cross(zAxis).getNormalized();
 	const Vec3 xAxis = yAxis.cross(zAxis).getNormalized();
@@ -260,7 +260,7 @@ void DebugDrawer2::drawBillboardTextures(const Mat4& projMat, const Mat4& viewMa
 		scale(0, 0) *= billboardSize.x();
 		scale(0, 0) *= billboardSize.x();
 		scale(1, 1) *= billboardSize.y();
 		scale(1, 1) *= billboardSize.y();
 
 
-		*pmvps = projMat * viewMat * Mat4(pos.xyz1(), rot * scale, 1.0f);
+		*pmvps = projMat * Mat4(viewMat, Vec4(0.0f, 0.0f, 0.0f, 1.0f)) * Mat4(pos.xyz1(), rot * scale, 1.0f);
 		++pmvps;
 		++pmvps;
 	}
 	}
 
 

+ 2 - 2
AnKi/Scene/DebugDrawer.h

@@ -58,12 +58,12 @@ public:
 		drawLines(ConstWeakArray<Mat4>(&mvp, 1), color, lineSize, ditherFailedDepth, points, stagingGpuAllocator, cmdb);
 		drawLines(ConstWeakArray<Mat4>(&mvp, 1), color, lineSize, ditherFailedDepth, points, stagingGpuAllocator, cmdb);
 	}
 	}
 
 
-	void drawBillboardTextures(const Mat4& projMat, const Mat4& viewMat, ConstWeakArray<Vec3> positions,
+	void drawBillboardTextures(const Mat4& projMat, const Mat3x4& viewMat, ConstWeakArray<Vec3> positions,
 							   const Vec4& color, Bool ditherFailedDepth, TextureViewPtr tex, SamplerPtr sampler,
 							   const Vec4& color, Bool ditherFailedDepth, TextureViewPtr tex, SamplerPtr sampler,
 							   Vec2 billboardSize, StagingGpuMemoryPool& stagingGpuAllocator,
 							   Vec2 billboardSize, StagingGpuMemoryPool& stagingGpuAllocator,
 							   CommandBufferPtr& cmdb) const;
 							   CommandBufferPtr& cmdb) const;
 
 
-	void drawBillboardTexture(const Mat4& projMat, const Mat4& viewMat, Vec3 position, const Vec4& color,
+	void drawBillboardTexture(const Mat4& projMat, const Mat3x4& viewMat, Vec3 position, const Vec4& color,
 							  Bool ditherFailedDepth, TextureViewPtr tex, SamplerPtr sampler, Vec2 billboardSize,
 							  Bool ditherFailedDepth, TextureViewPtr tex, SamplerPtr sampler, Vec2 billboardSize,
 							  StagingGpuMemoryPool& stagingGpuAllocator, CommandBufferPtr& cmdb) const
 							  StagingGpuMemoryPool& stagingGpuAllocator, CommandBufferPtr& cmdb) const
 	{
 	{

+ 27 - 19
AnKi/Scene/Visibility.cpp

@@ -72,6 +72,14 @@ static Bool spatialInsideFrustum(const FrustumComponent& frc, const SpatialCompo
 	}
 	}
 }
 }
 
 
+/// Used to silent warnings
+template<typename TComponent>
+Bool getComponent(SceneNode& node, TComponent*& comp)
+{
+	comp = node.tryGetFirstComponentOfType<TComponent>();
+	return comp != nullptr;
+}
+
 void VisibilityContext::submitNewWork(const FrustumComponent& frc, const FrustumComponent& primaryFrustum,
 void VisibilityContext::submitNewWork(const FrustumComponent& frc, const FrustumComponent& primaryFrustum,
 									  RenderQueue& rqueue, ThreadHive& hive)
 									  RenderQueue& rqueue, ThreadHive& hive)
 {
 {
@@ -83,7 +91,7 @@ void VisibilityContext::submitNewWork(const FrustumComponent& frc, const Frustum
 		return;
 		return;
 	}
 	}
 
 
-	rqueue.m_cameraTransform = Mat4(frc.getWorldTransform());
+	rqueue.m_cameraTransform = Mat3x4(frc.getWorldTransform());
 	rqueue.m_viewMatrix = frc.getViewMatrix();
 	rqueue.m_viewMatrix = frc.getViewMatrix();
 	rqueue.m_projectionMatrix = frc.getProjectionMatrix();
 	rqueue.m_projectionMatrix = frc.getProjectionMatrix();
 	rqueue.m_viewProjectionMatrix = frc.getViewProjectionMatrix();
 	rqueue.m_viewProjectionMatrix = frc.getViewProjectionMatrix();
@@ -181,7 +189,8 @@ void FillRasterizerWithCoverageTask::fill()
 	// Init the rasterizer
 	// Init the rasterizer
 	m_frcCtx->m_r = alloc.newInstance<SoftwareRasterizer>();
 	m_frcCtx->m_r = alloc.newInstance<SoftwareRasterizer>();
 	m_frcCtx->m_r->init(alloc);
 	m_frcCtx->m_r->init(alloc);
-	m_frcCtx->m_r->prepare(m_frcCtx->m_frc->getViewMatrix(), m_frcCtx->m_frc->getProjectionMatrix(), width, height);
+	m_frcCtx->m_r->prepare(Mat4(m_frcCtx->m_frc->getViewMatrix(), Vec4(0.0f, 0.0f, 0.0f, 1.0f)),
+						   m_frcCtx->m_frc->getProjectionMatrix(), width, height);
 
 
 	// Do the work
 	// Do the work
 	m_frcCtx->m_r->fillDepthBuffer(depthBuff);
 	m_frcCtx->m_r->fillDepthBuffer(depthBuff);
@@ -289,51 +298,50 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 
 
 		const RenderComponent* rc = nullptr;
 		const RenderComponent* rc = nullptr;
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::RENDER_COMPONENTS)
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::RENDER_COMPONENTS)
-					&& (rc = node.tryGetFirstComponentOfType<RenderComponent>());
+					&& getComponent(node, rc);
 
 
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::SHADOW_CASTERS)
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::SHADOW_CASTERS)
-					&& (rc = node.tryGetFirstComponentOfType<RenderComponent>())
-					&& !!(rc->getFlags() & RenderComponentFlag::CASTS_SHADOW);
+					&& getComponent(node, rc) && !!(rc->getFlags() & RenderComponentFlag::CASTS_SHADOW);
 
 
 		const RenderComponent* rtRc = nullptr;
 		const RenderComponent* rtRc = nullptr;
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::ALL_RAY_TRACING)
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::ALL_RAY_TRACING)
-					&& (rtRc = node.tryGetFirstComponentOfType<RenderComponent>()) && rtRc->getSupportsRayTracing();
+					&& getComponent(node, rtRc) && rtRc->getSupportsRayTracing();
 
 
 		const LightComponent* lc = nullptr;
 		const LightComponent* lc = nullptr;
-		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::LIGHT_COMPONENTS)
-					&& (lc = node.tryGetFirstComponentOfType<LightComponent>());
+		wantNode |=
+			!!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::LIGHT_COMPONENTS) && getComponent(node, lc);
 
 
 		const LensFlareComponent* lfc = nullptr;
 		const LensFlareComponent* lfc = nullptr;
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::LENS_FLARE_COMPONENTS)
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::LENS_FLARE_COMPONENTS)
-					&& (lfc = node.tryGetFirstComponentOfType<LensFlareComponent>());
+					&& getComponent(node, lfc);
 
 
 		const ReflectionProbeComponent* reflc = nullptr;
 		const ReflectionProbeComponent* reflc = nullptr;
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::REFLECTION_PROBES)
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::REFLECTION_PROBES)
-					&& (reflc = node.tryGetFirstComponentOfType<ReflectionProbeComponent>());
+					&& getComponent(node, reflc);
 
 
 		DecalComponent* decalc = nullptr;
 		DecalComponent* decalc = nullptr;
-		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::DECALS)
-					&& (decalc = node.tryGetFirstComponentOfType<DecalComponent>());
+		wantNode |=
+			!!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::DECALS) && getComponent(node, decalc);
 
 
 		const FogDensityComponent* fogc = nullptr;
 		const FogDensityComponent* fogc = nullptr;
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::FOG_DENSITY_COMPONENTS)
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::FOG_DENSITY_COMPONENTS)
-					&& (fogc = node.tryGetFirstComponentOfType<FogDensityComponent>());
+					&& getComponent(node, fogc);
 
 
 		GlobalIlluminationProbeComponent* giprobec = nullptr;
 		GlobalIlluminationProbeComponent* giprobec = nullptr;
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::GLOBAL_ILLUMINATION_PROBES)
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::GLOBAL_ILLUMINATION_PROBES)
-					&& (giprobec = node.tryGetFirstComponentOfType<GlobalIlluminationProbeComponent>());
+					&& getComponent(node, giprobec);
 
 
 		GenericGpuComputeJobComponent* computec = nullptr;
 		GenericGpuComputeJobComponent* computec = nullptr;
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::GENERIC_COMPUTE_JOB_COMPONENTS)
 		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::GENERIC_COMPUTE_JOB_COMPONENTS)
-					&& (computec = node.tryGetFirstComponentOfType<GenericGpuComputeJobComponent>());
+					&& getComponent(node, computec);
 
 
 		UiComponent* uic = nullptr;
 		UiComponent* uic = nullptr;
-		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::UI_COMPONENTS)
-					&& (uic = node.tryGetFirstComponentOfType<UiComponent>());
+		wantNode |=
+			!!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::UI_COMPONENTS) && getComponent(node, uic);
 
 
 		SkyboxComponent* skyboxc = nullptr;
 		SkyboxComponent* skyboxc = nullptr;
-		wantNode |= !!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::SKYBOX)
-					&& (skyboxc = node.tryGetFirstComponentOfType<SkyboxComponent>());
+		wantNode |=
+			!!(enabledVisibilityTests & FrustumComponentVisibilityTestFlag::SKYBOX) && getComponent(node, skyboxc);
 
 
 		if(ANKI_UNLIKELY(!wantNode))
 		if(ANKI_UNLIKELY(!wantNode))
 		{
 		{

+ 1 - 1
AnKi/ShaderCompiler/ShaderProgramDump.cpp

@@ -6,7 +6,7 @@
 #include <AnKi/ShaderCompiler/ShaderProgramDump.h>
 #include <AnKi/ShaderCompiler/ShaderProgramDump.h>
 #include <AnKi/Util/Serializer.h>
 #include <AnKi/Util/Serializer.h>
 #include <AnKi/Util/StringList.h>
 #include <AnKi/Util/StringList.h>
-#include <SprivCross/spirv_glsl.hpp>
+#include <SpirvCross/spirv_glsl.hpp>
 
 
 namespace anki {
 namespace anki {
 
 

+ 1 - 1
AnKi/ShaderCompiler/ShaderProgramReflection.cpp

@@ -5,7 +5,7 @@
 
 
 #include <AnKi/ShaderCompiler/ShaderProgramReflection.h>
 #include <AnKi/ShaderCompiler/ShaderProgramReflection.h>
 #include <AnKi/Gr/Utils/Functions.h>
 #include <AnKi/Gr/Utils/Functions.h>
-#include <SprivCross/spirv_glsl.hpp>
+#include <SpirvCross/spirv_glsl.hpp>
 
 
 namespace anki {
 namespace anki {
 
 

+ 4 - 5
AnKi/Shaders/Bloom.glsl

@@ -16,10 +16,9 @@ layout(push_constant) uniform b_pc
 	Vec4 u_thresholdScalePad2;
 	Vec4 u_thresholdScalePad2;
 };
 };
 
 
-layout(set = 0, binding = 2, std140) readonly buffer b_avgLum
-{
-	ANKI_RP Vec4 u_averageLuminancePad3;
-};
+const U32 TONEMAPPING_SET = 0u;
+const U32 TONEMAPPING_BINDING = 2u;
+#include <AnKi/Shaders/TonemappingResources.glsl>
 
 
 #if defined(ANKI_COMPUTE_SHADER)
 #if defined(ANKI_COMPUTE_SHADER)
 const UVec2 WORKGROUP_SIZE = UVec2(16, 16);
 const UVec2 WORKGROUP_SIZE = UVec2(16, 16);
@@ -51,7 +50,7 @@ void main()
 	color += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, IVec2(-1, +1)).rgb * weight;
 	color += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, IVec2(-1, +1)).rgb * weight;
 	color += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, IVec2(+1, -1)).rgb * weight;
 	color += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, IVec2(+1, -1)).rgb * weight;
 
 
-	color = tonemap(color, u_averageLuminancePad3.x, u_thresholdScalePad2.x) * u_thresholdScalePad2.y;
+	color = tonemap(color, readExposureAndAverageLuminance().y, u_thresholdScalePad2.x) * u_thresholdScalePad2.y;
 
 
 #if defined(ANKI_COMPUTE_SHADER)
 #if defined(ANKI_COMPUTE_SHADER)
 	imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy), Vec4(color, 0.0));
 	imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy), Vec4(color, 0.0));

+ 1 - 1
AnKi/Shaders/DownscaleBlur.glsl

@@ -55,7 +55,7 @@ void main()
 	{
 	{
 		out_color = saturate(out_color);
 		out_color = saturate(out_color);
 		out_color = sRgbToLinear(out_color);
 		out_color = sRgbToLinear(out_color);
-		out_color = invertTonemap(out_color, u_exposureThreshold0);
+		out_color = invertTonemap(out_color, readExposureAndAverageLuminance().x);
 	}
 	}
 
 
 #if defined(ANKI_COMPUTE_SHADER)
 #if defined(ANKI_COMPUTE_SHADER)

+ 4 - 2
AnKi/Shaders/GBufferCommon.glsl

@@ -62,7 +62,8 @@ layout(location = 6) out Vec3 out_normalTangentSpace;
 #		endif
 #		endif
 
 
 #		if ANKI_VELOCITY || ANKI_BONES
 #		if ANKI_VELOCITY || ANKI_BONES
-layout(location = 7) out Vec2 out_velocity;
+layout(location = 7) out Vec3 out_prevClipXyw;
+layout(location = 8) out Vec3 out_crntClipXyw;
 #		endif
 #		endif
 #	endif // ANKI_TECHNIQUE == RENDERING_TECHNIQUE_GBUFFER
 #	endif // ANKI_TECHNIQUE == RENDERING_TECHNIQUE_GBUFFER
 
 
@@ -89,7 +90,8 @@ layout(location = 6) in Vec3 in_normalTangentSpace;
 #		endif
 #		endif
 
 
 #		if ANKI_VELOCITY || ANKI_BONES
 #		if ANKI_VELOCITY || ANKI_BONES
-layout(location = 7) in Vec2 in_velocity;
+layout(location = 7) in Vec3 in_prevClipXyw;
+layout(location = 8) in Vec3 in_crntClipXyw;
 #		endif
 #		endif
 #	endif // ANKI_TECHNIQUE == RENDERING_TECHNIQUE_GBUFFER
 #	endif // ANKI_TECHNIQUE == RENDERING_TECHNIQUE_GBUFFER
 
 

+ 10 - 8
AnKi/Shaders/GBufferGeneric.ankiprog

@@ -164,19 +164,17 @@ void velocity()
 	const Vec3 prevLocalPos = g_prevPosition;
 	const Vec3 prevLocalPos = g_prevPosition;
 
 
 #	if ANKI_VELOCITY
 #	if ANKI_VELOCITY
+	// Object is also moving
 	const Mat3x4 trf = u_renderableGpuViews[gl_InstanceIndex].m_previousWorldTransform;
 	const Mat3x4 trf = u_renderableGpuViews[gl_InstanceIndex].m_previousWorldTransform;
 #	else
 #	else
+	// Object is a skin that is not moving
 	const Mat3x4 trf = u_renderableGpuViews[gl_InstanceIndex].m_worldTransform;
 	const Mat3x4 trf = u_renderableGpuViews[gl_InstanceIndex].m_worldTransform;
 #	endif
 #	endif
 
 
-	const Vec4 v4 = u_globalUniforms.m_viewProjectionMatrix * Vec4(trf * Vec4(prevLocalPos, 1.0), 1.0);
+	const Vec4 v4 = u_globalUniforms.m_previousViewProjectionMatrix * Vec4(trf * Vec4(prevLocalPos, 1.0), 1.0);
 
 
-	const Vec2 prevNdc = v4.xy / v4.w;
-
-	const Vec2 crntNdc = gl_Position.xy / gl_Position.w;
-
-	// It's NDC_TO_UV(prevNdc) - NDC_TO_UV(crntNdc) or:
-	out_velocity = (prevNdc - crntNdc) * 0.5;
+	out_prevClipXyw = v4.xyw;
+	out_crntClipXyw = gl_Position.xyw;
 }
 }
 #endif
 #endif
 
 
@@ -361,7 +359,11 @@ void main()
 #	endif
 #	endif
 
 
 #	if ANKI_VELOCITY || ANKI_BONES
 #	if ANKI_VELOCITY || ANKI_BONES
-	const Vec2 velocity = in_velocity;
+	const Vec2 prevNdc = in_prevClipXyw.xy / in_prevClipXyw.z;
+	const Vec2 crntNdc = in_crntClipXyw.xy / in_crntClipXyw.z;
+
+	// It's NDC_TO_UV(prevNdc) - NDC_TO_UV(crntNdc) or:
+	const Vec2 velocity = (prevNdc - crntNdc) * 0.5;
 #	else
 #	else
 	const Vec2 velocity = Vec2(1.0);
 	const Vec2 velocity = Vec2(1.0);
 #	endif
 #	endif

+ 13 - 14
AnKi/Shaders/Include/ClusteredShadingTypes.h

@@ -189,25 +189,24 @@ ANKI_SHADER_STATIC_ASSERT(sizeof(GlobalIlluminationProbe) == _ANKI_SIZEOF_Global
 /// Common matrices.
 /// Common matrices.
 struct CommonMatrices
 struct CommonMatrices
 {
 {
-	Mat4 m_cameraTransform ANKI_CPP_CODE(= Mat4::getIdentity());
-	Mat4 m_view ANKI_CPP_CODE(= Mat4::getIdentity());
-	Mat4 m_projection ANKI_CPP_CODE(= Mat4::getIdentity());
-	Mat4 m_viewProjection ANKI_CPP_CODE(= Mat4::getIdentity());
+	Mat3x4 m_cameraTransform;
+	Mat3x4 m_view;
+	Mat4 m_projection;
+	Mat4 m_viewProjection;
 
 
-	Mat4 m_jitter ANKI_CPP_CODE(= Mat4::getIdentity());
-	Mat4 m_projectionJitter ANKI_CPP_CODE(= Mat4::getIdentity());
-	Mat4 m_viewProjectionJitter ANKI_CPP_CODE(= Mat4::getIdentity());
+	Mat4 m_jitter;
+	Mat4 m_projectionJitter;
+	Mat4 m_viewProjectionJitter;
 
 
-	Mat4 m_invertedViewProjectionJitter ANKI_CPP_CODE(= Mat4::getIdentity()); ///< To unproject in world space.
-	Mat4 m_invertedViewProjection ANKI_CPP_CODE(= Mat4::getIdentity());
-	Mat4 m_invertedProjectionJitter ANKI_CPP_CODE(= Mat4::getIdentity()); ///< To unproject in view space.
-	Mat4 m_invertedView ANKI_CPP_CODE(= Mat4::getIdentity());
+	Mat4 m_invertedViewProjectionJitter; ///< To unproject in world space.
+	Mat4 m_invertedViewProjection;
+	Mat4 m_invertedProjectionJitter; ///< To unproject in view space.
 
 
 	/// It's being used to reproject a clip space position of the current frame to the previous frame. Its value should
 	/// It's being used to reproject a clip space position of the current frame to the previous frame. Its value should
 	/// be m_jitter * m_prevFrame.m_viewProjection * m_invertedViewProjectionJitter. At first it unprojects the current
 	/// be m_jitter * m_prevFrame.m_viewProjection * m_invertedViewProjectionJitter. At first it unprojects the current
 	/// position to world space, all fine here. Then it projects to the previous frame as if the previous frame was
 	/// position to world space, all fine here. Then it projects to the previous frame as if the previous frame was
 	/// using the current frame's jitter matrix.
 	/// using the current frame's jitter matrix.
-	Mat4 m_reprojection ANKI_CPP_CODE(= Mat4::getIdentity());
+	Mat4 m_reprojection;
 
 
 	/// To unproject to view space. Jitter not considered.
 	/// To unproject to view space. Jitter not considered.
 	/// @code
 	/// @code
@@ -215,9 +214,9 @@ struct CommonMatrices
 	/// const Vec2 xy = ndc * m_unprojectionParameters.xy * z;
 	/// const Vec2 xy = ndc * m_unprojectionParameters.xy * z;
 	/// pos = Vec3(xy, z);
 	/// pos = Vec3(xy, z);
 	/// @endcode
 	/// @endcode
-	Vec4 m_unprojectionParameters ANKI_CPP_CODE(= Vec4(0.0f));
+	Vec4 m_unprojectionParameters;
 };
 };
-const U32 _ANKI_SIZEOF_CommonMatrices = 12u * ANKI_SIZEOF(Mat4) + 1u * ANKI_SIZEOF(Vec4);
+const U32 _ANKI_SIZEOF_CommonMatrices = 43u * ANKI_SIZEOF(Vec4);
 ANKI_SHADER_STATIC_ASSERT(sizeof(CommonMatrices) == _ANKI_SIZEOF_CommonMatrices);
 ANKI_SHADER_STATIC_ASSERT(sizeof(CommonMatrices) == _ANKI_SIZEOF_CommonMatrices);
 
 
 /// Common uniforms for light shading passes.
 /// Common uniforms for light shading passes.

+ 2 - 1
AnKi/Shaders/Include/MaterialTypes.h

@@ -13,10 +13,11 @@ ANKI_BEGIN_NAMESPACE
 struct MaterialGlobalUniforms
 struct MaterialGlobalUniforms
 {
 {
 	Mat4 m_viewProjectionMatrix;
 	Mat4 m_viewProjectionMatrix;
+	Mat4 m_previousViewProjectionMatrix;
 	Mat3x4 m_viewMatrix;
 	Mat3x4 m_viewMatrix;
 	Mat3x4 m_cameraTransform;
 	Mat3x4 m_cameraTransform;
 };
 };
-ANKI_SHADER_STATIC_ASSERT(sizeof(MaterialGlobalUniforms) == 10 * sizeof(Vec4));
+ANKI_SHADER_STATIC_ASSERT(sizeof(MaterialGlobalUniforms) == 14 * sizeof(Vec4));
 
 
 const U32 MATERIAL_SET_BINDLESS = 0u;
 const U32 MATERIAL_SET_BINDLESS = 0u;
 const U32 MATERIAL_SET_GLOBAL = 1u;
 const U32 MATERIAL_SET_GLOBAL = 1u;

+ 1 - 2
AnKi/Shaders/TemporalAA.glsl

@@ -110,8 +110,7 @@ void main()
 #if YCBCR
 #if YCBCR
 	outColor = yCbCrToRgb(outColor);
 	outColor = yCbCrToRgb(outColor);
 #endif
 #endif
-
-	const Vec3 tonemapped = linearToSRgb(tonemap(outColor, u_exposureThreshold0));
+	const Vec3 tonemapped = linearToSRgb(tonemap(outColor, readExposureAndAverageLuminance().x));
 #if defined(ANKI_COMPUTE_SHADER)
 #if defined(ANKI_COMPUTE_SHADER)
 	imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy), Vec4(outColor, 0.0));
 	imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy), Vec4(outColor, 0.0));
 	imageStore(u_tonemappedImg, IVec2(gl_GlobalInvocationID.xy), Vec4(tonemapped, 0.0));
 	imageStore(u_tonemappedImg, IVec2(gl_GlobalInvocationID.xy), Vec4(tonemapped, 0.0));

+ 55 - 0
AnKi/Shaders/Tonemap.glsl

@@ -0,0 +1,55 @@
+// Copyright (C) 2009-2022, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+// Does tonemapping
+
+#include <AnKi/Shaders/Functions.glsl>
+#include <AnKi/Shaders/TonemappingFunctions.glsl>
+
+layout(set = 0, binding = 0) uniform sampler u_nearestAnyClampSampler;
+layout(set = 0, binding = 1) uniform ANKI_RP texture2D u_inputRt;
+
+const U32 TONEMAPPING_SET = 0u;
+const U32 TONEMAPPING_BINDING = 2u;
+#include <AnKi/Shaders/TonemappingResources.glsl>
+
+#if defined(ANKI_COMPUTE_SHADER)
+layout(set = 0, binding = 3) writeonly uniform image2D u_outImg;
+
+const UVec2 WORKGROUP_SIZE = UVec2(8, 8);
+layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = 1) in;
+#else
+layout(location = 0) in Vec2 in_uv;
+layout(location = 0) out Vec3 out_color;
+#endif
+
+layout(push_constant, std140) uniform b_pc
+{
+	Vec2 u_viewportSizeOverOne;
+	UVec2 u_viewportSize;
+};
+
+void main()
+{
+#if defined(ANKI_COMPUTE_SHADER)
+	if(skipOutOfBoundsInvocations(WORKGROUP_SIZE, u_viewportSize))
+	{
+		return;
+	}
+
+	const Vec2 uv = (Vec2(gl_GlobalInvocationID.xy) + 0.5f) * u_viewportSizeOverOne;
+#else
+	const Vec2 uv = in_uv;
+#endif
+
+	const ANKI_RP Vec3 hdr = textureLod(u_inputRt, u_nearestAnyClampSampler, uv, 0.0f).rgb;
+	const Vec3 tonemapped = linearToSRgb(tonemap(hdr, readExposureAndAverageLuminance().x));
+
+#if defined(ANKI_COMPUTE_SHADER)
+	imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy), Vec4(tonemapped, 0.0));
+#else
+	out_color = tonemapped;
+#endif
+}

+ 8 - 0
AnKi/Shaders/TonemapCompute.ankiprog

@@ -0,0 +1,8 @@
+// Copyright (C) 2009-2022, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma anki start comp
+#include <AnKi/Shaders/Tonemap.glsl>
+#pragma anki end

+ 12 - 0
AnKi/Shaders/TonemapRaster.ankiprog

@@ -0,0 +1,12 @@
+// Copyright (C) 2009-2022, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma anki start vert
+#include <AnKi/Shaders/QuadVert.glsl>
+#pragma anki end
+
+#pragma anki start frag
+#include <AnKi/Shaders/Tonemap.glsl>
+#pragma anki end

+ 3 - 4
AnKi/Shaders/TonemappingAverageLuminance.ankiprog

@@ -19,7 +19,7 @@ const UVec2 PIXELS_PER_TILE = ALIGNED_INPUT_TEX_SIZE / WORKGROUP_SIZE;
 
 
 layout(set = 0, binding = 0) uniform ANKI_RP texture2D u_tex;
 layout(set = 0, binding = 0) uniform ANKI_RP texture2D u_tex;
 
 
-#define TONEMAPPING_RESOURCE_AS_BUFFER 1
+#define TONEMAPPING_RESOURCE_AS_WRITE_IMAGE 1
 #define TONEMAPPING_SET 0
 #define TONEMAPPING_SET 0
 #define TONEMAPPING_BINDING 1
 #define TONEMAPPING_BINDING 1
 #include <AnKi/Shaders/TonemappingResources.glsl>
 #include <AnKi/Shaders/TonemappingResources.glsl>
@@ -85,7 +85,7 @@ void main()
 #endif
 #endif
 
 
 #if 1
 #if 1
-		const F32 prevLum = u_averageLuminance;
+		const F32 prevLum = readExposureAndAverageLuminance().y;
 
 
 		// Lerp between previous and new L value
 		// Lerp between previous and new L value
 		const F32 INTERPOLATION_FACTOR = 0.05;
 		const F32 INTERPOLATION_FACTOR = 0.05;
@@ -97,8 +97,7 @@ void main()
 		// This is a workaround because sometimes the avg lum becomes nan
 		// This is a workaround because sometimes the avg lum becomes nan
 		finalAvgLum = clamp(finalAvgLum, EPSILON, MAX_F32);
 		finalAvgLum = clamp(finalAvgLum, EPSILON, MAX_F32);
 
 
-		u_averageLuminance = finalAvgLum;
-		u_exposureThreshold0 = computeExposure(u_averageLuminance, 0.0);
+		writeExposureAndAverageLuminance(computeExposure(finalAvgLum, 0.0), finalAvgLum);
 	}
 	}
 }
 }
 #pragma anki end
 #pragma anki end

+ 15 - 9
AnKi/Shaders/TonemappingResources.glsl

@@ -9,18 +9,24 @@
 
 
 #include <AnKi/Shaders/Common.glsl>
 #include <AnKi/Shaders/Common.glsl>
 
 
-#ifndef TONEMAPPING_RESOURCE_AS_BUFFER
-#	define TONEMAPPING_RESOURCE_AS_BUFFER 0
+#if !defined(TONEMAPPING_RESOURCE_AS_WRITE_IMAGE)
+#	define TONEMAPPING_RESOURCE_AS_WRITE_IMAGE 0
 #endif
 #endif
 
 
-#if TONEMAPPING_RESOURCE_AS_BUFFER
-layout(std140, set = TONEMAPPING_SET, binding = TONEMAPPING_BINDING) buffer b_tonemapping
+#if TONEMAPPING_RESOURCE_AS_WRITE_IMAGE
+layout(set = 0, binding = TONEMAPPING_BINDING) ANKI_RP uniform coherent image2D u_tonemappingImage;
 #else
 #else
-layout(std140, set = TONEMAPPING_SET, binding = TONEMAPPING_BINDING) uniform b_tonemapping
+layout(set = 0, binding = TONEMAPPING_BINDING) ANKI_RP uniform readonly image2D u_tonemappingImage;
 #endif
 #endif
+
+#if TONEMAPPING_RESOURCE_AS_WRITE_IMAGE
+void writeExposureAndAverageLuminance(ANKI_RP F32 exposure, ANKI_RP F32 avgLuminance)
 {
 {
-	Vec4 u_averageLuminanceExposurePad2;
-};
+	imageStore(u_tonemappingImage, IVec2(0), Vec4(exposure, avgLuminance, 0.0f, 0.0f));
+}
+#endif
 
 
-#define u_averageLuminance u_averageLuminanceExposurePad2.x
-#define u_exposureThreshold0 u_averageLuminanceExposurePad2.y
+ANKI_RP Vec2 readExposureAndAverageLuminance()
+{
+	return imageLoad(u_tonemappingImage, IVec2(0)).xy;
+}

+ 1 - 2
AnKi/Shaders/VolumetricLightingAccumulation.ankiprog

@@ -71,8 +71,7 @@ Vec3 worldPosInsideClusterAndZViewSpace(Vec3 relativePos, out F32 negativeZViewS
 	const Vec2 xyViewSpace = UV_TO_NDC(uv) * u_clusteredShading.m_matrices.m_unprojectionParameters.xy * zViewSpace;
 	const Vec2 xyViewSpace = UV_TO_NDC(uv) * u_clusteredShading.m_matrices.m_unprojectionParameters.xy * zViewSpace;
 
 
 	// Get the final world pos
 	// Get the final world pos
-	const Vec4 worldPos4 = u_clusteredShading.m_matrices.m_invertedView * Vec4(xyViewSpace, zViewSpace, 1.0);
-	const Vec3 worldPos = worldPos4.xyz;
+	const Vec3 worldPos = u_clusteredShading.m_matrices.m_cameraTransform * Vec4(xyViewSpace, zViewSpace, 1.0);
 
 
 	return worldPos;
 	return worldPos;
 }
 }

+ 6 - 3
AnKi/Util/Logger.cpp

@@ -180,21 +180,24 @@ void Logger::defaultSystemMessageHandler(void*, const LoggerMessageInfo& info)
 			info.m_tid, endTerminalColor, terminalColor, info.m_msg, info.m_file, info.m_line, info.m_func,
 			info.m_tid, endTerminalColor, terminalColor, info.m_msg, info.m_file, info.m_line, info.m_func,
 			endTerminalColor);
 			endTerminalColor);
 #elif ANKI_OS_WINDOWS
 #elif ANKI_OS_WINDOWS
-	WORD attribs = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
+	WORD attribs = 0;
 	FILE* out = NULL;
 	FILE* out = NULL;
 	switch(info.m_type)
 	switch(info.m_type)
 	{
 	{
 	case LoggerMessageType::NORMAL:
 	case LoggerMessageType::NORMAL:
-	case LoggerMessageType::VERBOSE:
 		attribs |= FOREGROUND_GREEN;
 		attribs |= FOREGROUND_GREEN;
 		out = stdout;
 		out = stdout;
 		break;
 		break;
+	case LoggerMessageType::VERBOSE:
+		attribs |= FOREGROUND_BLUE;
+		out = stdout;
+		break;
 	case LoggerMessageType::ERROR:
 	case LoggerMessageType::ERROR:
 		attribs |= FOREGROUND_RED;
 		attribs |= FOREGROUND_RED;
 		out = stderr;
 		out = stderr;
 		break;
 		break;
 	case LoggerMessageType::WARNING:
 	case LoggerMessageType::WARNING:
-		attribs |= FOREGROUND_RED;
+		attribs |= FOREGROUND_RED | FOREGROUND_GREEN;
 		out = stderr;
 		out = stderr;
 		break;
 		break;
 	case LoggerMessageType::FATAL:
 	case LoggerMessageType::FATAL:

+ 39 - 35
AnKi/Util/SparseArray.inl.h

@@ -63,54 +63,58 @@ template<typename T, typename TIndex>
 template<typename TAlloc>
 template<typename TAlloc>
 TIndex SparseArray<T, TIndex>::insert(TAlloc& alloc, Index idx, Value& val)
 TIndex SparseArray<T, TIndex>::insert(TAlloc& alloc, Index idx, Value& val)
 {
 {
-start:
-	const Index desiredPos = mod(idx);
-	const Index endPos = mod(desiredPos + m_probeCount);
-	Index pos = desiredPos;
-
-	while(pos != endPos)
+	while(true)
 	{
 	{
-		Metadata& meta = m_metadata[pos];
-		Value& crntVal = m_elements[pos];
+		const Index desiredPos = mod(idx);
+		const Index endPos = mod(desiredPos + m_probeCount);
+		Index pos = desiredPos;
 
 
-		if(!meta.m_alive)
+		while(pos != endPos)
 		{
 		{
-			// Empty slot was found, construct in-place
+			Metadata& meta = m_metadata[pos];
+			Value& crntVal = m_elements[pos];
 
 
-			meta.m_alive = true;
-			meta.m_idx = idx;
-			alloc.construct(&crntVal, std::move(val));
+			if(!meta.m_alive)
+			{
+				// Empty slot was found, construct in-place
 
 
-			return 1;
-		}
-		else if(meta.m_idx == idx)
-		{
-			// Same index was found, replace
+				meta.m_alive = true;
+				meta.m_idx = idx;
+				alloc.construct(&crntVal, std::move(val));
+
+				return 1;
+			}
+			else if(meta.m_idx == idx)
+			{
+				// Same index was found, replace
+
+				meta.m_idx = idx;
+				destroyElement(crntVal);
+				alloc.construct(&crntVal, std::move(val));
+
+				return 0;
+			}
 
 
-			meta.m_idx = idx;
-			destroyElement(crntVal);
-			alloc.construct(&crntVal, std::move(val));
+			// Do the robin-hood
+			const Index otherDesiredPos = mod(meta.m_idx);
+			if(distanceFromDesired(pos, otherDesiredPos) < distanceFromDesired(pos, desiredPos))
+			{
+				// Swap
+				std::swap(val, crntVal);
+				std::swap(idx, meta.m_idx);
+				break;
+			}
 
 
-			return 0;
+			pos = mod(pos + 1u);
 		}
 		}
 
 
-		// Do the robin-hood
-		const Index otherDesiredPos = mod(meta.m_idx);
-		if(distanceFromDesired(pos, otherDesiredPos) < distanceFromDesired(pos, desiredPos))
+		if(pos == endPos)
 		{
 		{
-			// Swap
-			std::swap(val, crntVal);
-			std::swap(idx, meta.m_idx);
-			goto start;
+			// Didn't found an empty place, need to grow and try again
+			grow(alloc);
 		}
 		}
-
-		pos = mod(pos + 1u);
 	}
 	}
 
 
-	// Didn't found an empty place, need to grow and try again
-	grow(alloc);
-	goto start;
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 0
AnKi/Util/StdTypes.h

@@ -74,6 +74,7 @@ static_assert(sizeof(bool) == 1, "Wrong size for bool");
 
 
 using Bool32 = I32;
 using Bool32 = I32;
 using Char = char;
 using Char = char;
+using WChar = wchar_t;
 
 
 using Second = F64; ///< The base time unit is second.
 using Second = F64; ///< The base time unit is second.
 constexpr Second MAX_SECOND = MAX_F64;
 constexpr Second MAX_SECOND = MAX_F64;

+ 40 - 10
CMakeLists.txt

@@ -63,18 +63,31 @@ else()
 	message(FATAL_ERROR "Unknown system")
 	message(FATAL_ERROR "Unknown system")
 endif()
 endif()
 
 
-if(${CMAKE_C_COMPILER_ID} MATCHES "GNU" OR ${CMAKE_C_COMPILER_ID} MATCHES "Clang")
+# Indentify compiler
+set(GCC FALSE)
+set(CLANG FALSE)
+set(CLANG_WINDOWS FALSE)
+
+if(${CMAKE_C_COMPILER_ID} MATCHES "GNU")
 	set(GCC TRUE)
 	set(GCC TRUE)
-else()
-	set(GCC FALSE)
+	message("++ Compiler identified as GCC")
 endif()
 endif()
 
 
 if(${CMAKE_C_COMPILER_ID} MATCHES "Clang")
 if(${CMAKE_C_COMPILER_ID} MATCHES "Clang")
+	message("++ Compiler identified as Clang")
 	set(CLANG TRUE)
 	set(CLANG TRUE)
-else()
-	set(CLANG FALSE)
+	if(WINDOWS)
+		# It's clang for windows
+		message("++ Compiler identified as Clang for Windows")
+		set(CLANG_WINDOWS TRUE)
+	endif()
 endif()
 endif()
 
 
+if(MSVC)
+	message("++ Compiler identified as MSVC")
+endif()
+
+# Identify the target system
 set(X86 FALSE)
 set(X86 FALSE)
 set(ARM FALSE)
 set(ARM FALSE)
 if(GCC OR CLANG)
 if(GCC OR CLANG)
@@ -82,10 +95,10 @@ if(GCC OR CLANG)
 
 
 	if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch" OR ${target_arch} MATCHES "aarch")
 	if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch" OR ${target_arch} MATCHES "aarch")
 		set(ARM TRUE)
 		set(ARM TRUE)
-	elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86")
+	elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86.*" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "AMD64.*")
 		set(X86 TRUE)
 		set(X86 TRUE)
 	else()
 	else()
-		message(FATAL_ERROR "Couldn't find the target architecture from: ${target_arch}")
+		message(FATAL_ERROR "Couldn't find the target architecture from: ${target_arch} or ${CMAKE_SYSTEM_PROCESSOR}")
 	endif()
 	endif()
 elseif(MSVC)
 elseif(MSVC)
 	set(X86 TRUE)
 	set(X86 TRUE)
@@ -127,6 +140,7 @@ option(ANKI_ADDRESS_SANITIZER "Enable address sanitizer (-fsanitize=address)" OF
 option(ANKI_HEADLESS "Build a headless application" OFF)
 option(ANKI_HEADLESS "Build a headless application" OFF)
 option(ANKI_SHADER_FULL_PRECISION "Build shaders with full precision" OFF)
 option(ANKI_SHADER_FULL_PRECISION "Build shaders with full precision" OFF)
 set(ANKI_OVERRIDE_SHADER_COMPILER "" CACHE FILEPATH "Set the ShaderCompiler to be used to compile all shaders")
 set(ANKI_OVERRIDE_SHADER_COMPILER "" CACHE FILEPATH "Set the ShaderCompiler to be used to compile all shaders")
+option(ANKI_DLSS "Integrate DLSS if supported" OFF)
 
 
 # Take a wild guess on the windowing system
 # Take a wild guess on the windowing system
 if(ANKI_HEADLESS)
 if(ANKI_HEADLESS)
@@ -173,9 +187,13 @@ add_definitions(
 
 
 if(NOT MSVC)
 if(NOT MSVC)
 	# When building AnKi define this special flag
 	# When building AnKi define this special flag
-	add_compile_options(-fPIC -fno-exceptions)
+	if(NOT CLANG_WINDOWS)
+		add_compile_options(-fPIC)
+	endif()
 
 
-	if(GCC AND NOT CLANG)
+	add_compile_options(-fno-exceptions)
+
+	if(GCC)
 		add_compile_options(-static-libstdc++)
 		add_compile_options(-static-libstdc++)
 	endif()
 	endif()
 
 
@@ -248,7 +266,7 @@ endif()
 ################################################################################
 ################################################################################
 # Thirdparty                                                                   #
 # Thirdparty                                                                   #
 ################################################################################
 ################################################################################
-set(ANKI_EXTERN_SUB_DIRS TinyXml2 Lua ZLib Bullet ImGui MeshOptimizer SprivCross)
+set(ANKI_EXTERN_SUB_DIRS TinyXml2 Lua ZLib Bullet ImGui MeshOptimizer SpirvCross)
 
 
 # Bullet config
 # Bullet config
 option(BUILD_BULLET2_DEMOS OFF)
 option(BUILD_BULLET2_DEMOS OFF)
@@ -296,6 +314,14 @@ if(ANDROID)
 	add_subdirectory(ThirdParty/HwcPipe)
 	add_subdirectory(ThirdParty/HwcPipe)
 endif()
 endif()
 
 
+# DLSS
+if(ANKI_DLSS)
+	add_subdirectory(ThirdParty/DlssSdk)
+	set(_ANKI_DLSS_ENABLED 1)
+else()
+	set(_ANKI_DLSS_ENABLED 0)
+endif()
+
 ################################################################################
 ################################################################################
 # AnKi                                                                         #
 # AnKi                                                                         #
 ################################################################################
 ################################################################################
@@ -405,6 +431,10 @@ if(LINUX)
 	endif()
 	endif()
 endif()
 endif()
 
 
+if(ANKI_DLSS)
+	set(THIRD_PARTY_LIBS ${THIRD_PARTY_LIBS} AnKiNgx)
+endif()
+
 # AnKi compiler flags (Mainly warnings)
 # AnKi compiler flags (Mainly warnings)
 if(NOT MSVC)
 if(NOT MSVC)
 	add_compile_options(
 	add_compile_options(

+ 4 - 4
Tests/Math/Math.cpp

@@ -253,9 +253,9 @@ void transpose()
 	Mat a = getNonEmptyMat<Mat>();
 	Mat a = getNonEmptyMat<Mat>();
 	Mat b = a.getTransposed();
 	Mat b = a.getTransposed();
 
 
-	for(U j = 0; j < Mat::ROW_SIZE; j++)
+	for(U j = 0; j < Mat::ROW_COUNT; j++)
 	{
 	{
-		for(U i = 0; i < Mat::COLUMN_SIZE; i++)
+		for(U i = 0; i < Mat::COLUMN_COUNT; i++)
 		{
 		{
 			ANKI_TEST_EXPECT_EQ(a(j, i), b(i, j));
 			ANKI_TEST_EXPECT_EQ(a(j, i), b(i, j));
 		}
 		}
@@ -286,10 +286,10 @@ void matVecMul()
 
 
 	VecOut out = m * v;
 	VecOut out = m * v;
 	VecOut out1;
 	VecOut out1;
-	for(U j = 0; j < Mat::ROW_SIZE; j++)
+	for(U j = 0; j < Mat::ROW_COUNT; j++)
 	{
 	{
 		T sum = 0;
 		T sum = 0;
-		for(U i = 0; i < Mat::COLUMN_SIZE; i++)
+		for(U i = 0; i < Mat::COLUMN_COUNT; i++)
 		{
 		{
 			sum += m(j, i) * v[j];
 			sum += m(j, i) * v[j];
 		}
 		}

+ 0 - 1
Tests/Util/Filesystem.cpp

@@ -47,7 +47,6 @@ ANKI_TEST(Util, Directory)
 	ANKI_TEST_EXPECT_EQ(fileExists("./dir/rid/tmp"), true);
 	ANKI_TEST_EXPECT_EQ(fileExists("./dir/rid/tmp"), true);
 
 
 	ANKI_TEST_EXPECT_NO_ERR(removeDirectory("./dir", alloc));
 	ANKI_TEST_EXPECT_NO_ERR(removeDirectory("./dir", alloc));
-	return;
 	ANKI_TEST_EXPECT_EQ(fileExists("./dir/rid/tmp"), false);
 	ANKI_TEST_EXPECT_EQ(fileExists("./dir/rid/tmp"), false);
 	ANKI_TEST_EXPECT_EQ(directoryExists("./dir/rid"), false);
 	ANKI_TEST_EXPECT_EQ(directoryExists("./dir/rid"), false);
 	ANKI_TEST_EXPECT_EQ(directoryExists("./dir"), false);
 	ANKI_TEST_EXPECT_EQ(directoryExists("./dir"), false);

+ 1 - 1
Tests/Util/SparseArray.cpp

@@ -343,7 +343,7 @@ ANKI_TEST(Util, SparseArrayBench)
 			int v;
 			int v;
 			do
 			do
 			{
 			{
-				v = rand();
+				v = int(getRandom());
 			} while(tmpMap.find(v) != tmpMap.end() && v != 0);
 			} while(tmpMap.find(v) != tmpMap.end() && v != 0);
 			tmpMap[v] = 1;
 			tmpMap[v] = 1;
 
 

+ 29 - 0
ThirdParty/DlssSdk/CMakeLists.txt

@@ -0,0 +1,29 @@
+# Create AnKiNgx. Inspired by the DLSS example
+if(ANKI_DLSS)
+	set(NGX_SDK_ROOT "${CMAKE_CURRENT_LIST_DIR}/sdk")
+	# Only Linux and Windows support working with Nvidia SDK (NGX)
+	if(WINDOWS)
+		add_library(AnKiNgx IMPORTED SHARED GLOBAL)
+		set_property(TARGET AnKiNgx APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+		set_property(TARGET AnKiNgx APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
+		set_target_properties(AnKiNgx PROPERTIES IMPORTED_IMPLIB_DEBUG ${NGX_SDK_ROOT}/lib/Windows_x86_64/x86_64/nvsdk_ngx_d_dbg_iterator0.lib)
+		set_target_properties(AnKiNgx PROPERTIES IMPORTED_IMPLIB_RELEASE ${NGX_SDK_ROOT}/lib/Windows_x86_64/x86_64/nvsdk_ngx_d.lib)
+		set_target_properties(AnKiNgx PROPERTIES
+			MAP_IMPORTED_CONFIG_MINSIZEREL Release
+			MAP_IMPORTED_CONFIG_RELWITHDEBINFO Release
+		)
+		set_target_properties(AnKiNgx PROPERTIES IMPORTED_LOCATION
+			"${NGX_SDK_ROOT}/lib/Windows_x86_64/$<IF:$<CONFIG:Debug>,dev,rel>/nvngx_dlss.dll")
+	elseif(LINUX)
+		add_library(AnKiNgx IMPORTED STATIC GLOBAL)
+		set_property(TARGET AnKiNgx APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
+		set_property(TARGET AnKiNgx APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+		set_property(TARGET AnKiNgx PROPERTY IMPORTED_LOCATION ${NGX_SDK_ROOT}/lib/Linux_x86_64/libnvsdk_ngx.a)
+		# set the list of DLLs that need copying to target folder of application
+		set(__NGX_DLLS_LIST "${NGX_SDK_ROOT}/lib/Linux_x86_64/rel/libnvidia-ngx-*.so.*")
+	else()
+		message(FATAL_ERROR "Trying to use NGX for invalid platform")
+	endif()
+
+	set_property(TARGET AnKiNgx APPEND PROPERTY ANKINGX_EXTRA_DLLS "${__NGX_DLLS_LIST}")
+endif()

+ 408 - 0
ThirdParty/DlssSdk/sdk/LICENSE.txt

@@ -0,0 +1,408 @@
+NVIDIA RTX SDKs LICENSE
+
+This license is a legal agreement between you and NVIDIA Corporation ("NVIDIA")
+and governs the use of the NVIDIA RTX software development kits, including the
+DLSS SDK, NGX SDK, RTXGI SDK, RTXDI SDK and/or NRD SDK, if and when made
+available to you under this license (in each case, the "SDK"). This license can
+be accepted only by an adult of legal age of majority in the country in which
+the SDK is used. If you are under the legal age of majority, you must ask your
+parent or legal guardian to consent to this license. If you are entering this
+license on behalf of a company or other legal entity, you represent that you
+have legal authority and "you" will mean the entity you represent. By using the
+SDK, you affirm that you have reached the legal age of majority, you accept the
+terms of this license, and you take legal and financial responsibility for the
+actions of your permitted users. 
+
+You agree to use the SDK only for purposes that are permitted by (a) this
+license, and (b) any applicable law, regulation or generally accepted practices
+or guidelines in the relevant jurisdictions.
+
+1. LICENSE. Subject to the terms of this license and the terms in the supplement
+attached, NVIDIA hereby grants you a non-exclusive, non-transferable license,
+without the right to sublicense (except as expressly provided in this license)
+to: 
+
+(a) Install and use the SDK,
+
+(b) Modify and create derivative works of sample source code delivered in the
+SDK, and
+
+(c) Distribute any software and materials within the SDK, other than developer
+tools provided for your internal use, as incorporated in object code format into
+a software application subject to the distribution requirements indicated in
+this license.
+
+2. DISTRIBUTION REQUIREMENTS. These are the distribution requirements for you to
+exercise the grants above:
+
+(a) An application must have material additional functionality, beyond the
+included portions of the SDK. 
+
+(b) The following notice shall be included in modifications and derivative works
+of source code distributed: "This software contains source code provided by
+NVIDIA Corporation." 
+
+(c) You agree to distribute the SDK subject to the terms at least as protective
+as the terms of this license, including (without limitation) terms relating to
+the license grant, license restrictions and protection of NVIDIA's intellectual
+property rights. Additionally, you agree that you will protect the privacy,
+security and legal rights of your application users. 
+
+(d) You agree to notify NVIDIA in writing of any known or suspected distribution
+or use of the SDK not in compliance with the requirements of this license, and
+to enforce the terms of your agreements with respect to the distributed portions
+of the SDK. 
+
+3. AUTHORIZED USERS. You may allow employees and contractors of your entity or
+of your subsidiary(ies) to access and use the SDK from your secure network to
+perform work on your behalf. If you are an academic institution you may allow
+users enrolled or employed by the academic institution to access and use the SDK
+from your secure network. You are responsible for the compliance with the terms
+of this license by your authorized users. 
+
+4. LIMITATIONS. Your license to use the SDK is restricted as follows:
+
+(a) You may not reverse engineer, decompile or disassemble, or remove copyright
+or other proprietary notices from any portion of the SDK or copies of the SDK. 
+
+(b) Except as expressly provided in this license, you may not copy, sell, rent,
+sublicense, transfer, distribute, modify, or create derivative works of any
+portion of the SDK. For clarity, you may not distribute or sublicense the SDK as
+a stand-alone product.
+
+(c) Unless you have an agreement with NVIDIA for this purpose, you may not
+indicate that an application created with the SDK is sponsored or endorsed by
+NVIDIA.
+
+(d) You may not bypass, disable, or circumvent any technical limitation,
+encryption, security, digital rights management or authentication mechanism in
+the SDK. 
+
+(e) You may not use the SDK in any manner that would cause it to become subject
+to an open source software license. As examples, licenses that require as a
+condition of use, modification, and/or distribution that the SDK be: (i)
+disclosed or distributed in source code form; (ii) licensed for the purpose of
+making derivative works; or (iii) redistributable at no charge.
+
+(f) Unless you have an agreement with NVIDIA for this purpose, you may not use
+the SDK with any system or application where the use or failure of the system or
+application can reasonably be expected to threaten or result in personal injury,
+death, or catastrophic loss. Examples include use in avionics, navigation,
+military, medical, life support or other life critical applications. NVIDIA does
+not design, test or manufacture the SDK for these critical uses and NVIDIA shall
+not be liable to you or any third party, in whole or in part, for any claims or
+damages arising from such uses. 
+
+(g) You agree to defend, indemnify and hold harmless NVIDIA and its affiliates,
+and their respective employees, contractors, agents, officers and directors,
+from and against any and all claims, damages, obligations, losses, liabilities,
+costs or debt, fines, restitutions and expenses (including but not limited to
+attorney's fees and costs incident to establishing the right of indemnification)
+arising out of or related to your use of the SDK outside of the scope of this
+license, or not in compliance with its terms. 
+
+5. UPDATES. NVIDIA may, at its option, make available patches, workarounds or
+other updates to this SDK. Unless the updates are provided with their separate
+governing terms, they are deemed part of the SDK licensed to you as provided in
+this license. You agree that the form and content of the SDK that NVIDIA
+provides may change without prior notice to you. While NVIDIA generally
+maintains compatibility between versions, NVIDIA may in some cases make changes
+that introduce incompatibilities in future versions of the SDK.
+
+6. PRE-RELEASE VERSIONS. SDK versions identified as alpha, beta, preview, early
+access or otherwise as pre-release may not be fully functional, may contain
+errors or design flaws, and may have reduced or different security, privacy,
+availability, and reliability standards relative to commercial versions of
+NVIDIA software and materials. You may use a pre-release SDK version at your own
+risk, understanding that these versions are not intended for use in production
+or business-critical systems. NVIDIA may choose not to make available a
+commercial version of any pre-release SDK. NVIDIA may also choose to abandon
+development and terminate the availability of a pre-release SDK at any time
+without liability.
+
+7. THIRD-PARTY COMPONENTS. The SDK may include third-party components with
+separate legal notices or terms as may be described in proprietary notices
+accompanying the SDK. If and to the extent there is a conflict between the terms
+in this license and the third-party license terms, the third-party terms control
+only to the extent necessary to resolve the conflict. 
+
+8. OWNERSHIP. 
+
+8.1 NVIDIA reserves all rights, title and interest in and to the SDK not
+expressly granted to you under this license. NVIDIA and its suppliers hold all
+rights, title and interest in and to the SDK, including their respective
+intellectual property rights. The SDK is copyrighted and protected by the laws
+of the United States and other countries, and international treaty provisions.
+
+8.2 Subject to the rights of NVIDIA and its suppliers in the SDK, you hold all
+rights, title and interest in and to your applications and your derivative works
+of the sample source code delivered in the SDK including their respective
+intellectual property rights. 
+ 
+9. FEEDBACK. You may, but are not obligated to, provide Feedback to NVIDIA.
+"Feedback" means all suggestions, fixes, modifications, feature requests or
+other feedback regarding the SDK. Feedback, even if designated as confidential
+by you, shall not create any confidentiality obligation for NVIDIA. NVIDIA and
+its designees have a perpetual, non-exclusive, worldwide, irrevocable license to
+use, reproduce, publicly display, modify, create derivative works of, license,
+sublicense, and otherwise distribute and exploit Feedback as NVIDIA sees fit
+without payment and without obligation or restriction of any kind on account of
+intellectual property rights or otherwise.
+
+10. NO WARRANTIES. THE SDK IS PROVIDED AS-IS. TO THE MAXIMUM EXTENT PERMITTED BY
+APPLICABLE LAW NVIDIA AND ITS AFFILIATES EXPRESSLY DISCLAIM ALL WARRANTIES OF
+ANY KIND OR NATURE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT
+LIMITED TO, WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR A
+PARTICULAR PURPOSE. NVIDIA DOES NOT WARRANT THAT THE SDK WILL MEET YOUR
+REQUIREMENTS OR THAT THE OPERATION THEREOF WILL BE UNINTERRUPTED OR ERROR-FREE,
+OR THAT ALL ERRORS WILL BE CORRECTED. 
+
+11. LIMITATIONS OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW
+NVIDIA AND ITS AFFILIATES SHALL NOT BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+PUNITIVE OR CONSEQUENTIAL DAMAGES, OR FOR ANY LOST PROFITS, PROJECT DELAYS, LOSS
+OF USE, LOSS OF DATA OR LOSS OF GOODWILL, OR THE COSTS OF PROCURING SUBSTITUTE
+PRODUCTS, ARISING OUT OF OR IN CONNECTION WITH THIS LICENSE OR THE USE OR
+PERFORMANCE OF THE SDK, WHETHER SUCH LIABILITY ARISES FROM ANY CLAIM BASED UPON
+BREACH OF CONTRACT, BREACH OF WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCT
+LIABILITY OR ANY OTHER CAUSE OF ACTION OR THEORY OF LIABILITY, EVEN IF NVIDIA
+HAS PREVIOUSLY BEEN ADVISED OF, OR COULD REASONABLY HAVE FORESEEN, THE
+POSSIBILITY OF SUCH DAMAGES. IN NO EVENT WILL NVIDIA'S AND ITS AFFILIATES TOTAL
+CUMULATIVE LIABILITY UNDER OR ARISING OUT OF THIS LICENSE EXCEED US$10.00. THE
+NATURE OF THE LIABILITY OR THE NUMBER OF CLAIMS OR SUITS SHALL NOT ENLARGE OR
+EXTEND THIS LIMIT. 
+
+12. TERMINATION. Your rights under this license will terminate automatically
+without notice from NVIDIA if you fail to comply with any term and condition of
+this license or if you commence or participate in any legal proceeding against
+NVIDIA with respect to the SDK. NVIDIA may terminate this license with advance
+written notice to you, if NVIDIA decides to no longer provide the SDK in a
+country or, in NVIDIA's sole discretion, the continued use of it is no longer
+commercially viable. Upon any termination of this license, you agree to promptly
+discontinue use of the SDK and destroy all copies in your possession or control.
+Your prior distributions in accordance with this license are not affected by the
+termination of this license. All provisions of this license will survive
+termination, except for the license granted to you. 
+
+13. APPLICABLE LAW. This license will be governed in all respects by the laws of
+the United States and of the State of Delaware, without regard to the conflicts
+of laws principles. The United Nations Convention on Contracts for the
+International Sale of Goods is specifically disclaimed. You agree to all terms
+of this license in the English language. The state or federal courts residing in
+Santa Clara County, California shall have exclusive jurisdiction over any
+dispute or claim arising out of this license. Notwithstanding this, you agree
+that NVIDIA shall still be allowed to apply for injunctive remedies or urgent
+legal relief in any jurisdiction. 
+
+14. NO ASSIGNMENT. This license and your rights and obligations thereunder may
+not be assigned by you by any means or operation of law without NVIDIA's
+permission. Any attempted assignment not approved by NVIDIA in writing shall be
+void and of no effect. NVIDIA may assign, delegate or transfer this license and
+its rights and obligations, and if to a non-affiliate you will be notified.
+ 
+15. EXPORT. The SDK is subject to United States export laws and regulations. You
+agree to comply with all applicable U.S. and international export laws,
+including the Export Administration Regulations (EAR) administered by the U.S.
+Department of Commerce and economic sanctions administered by the U.S.
+Department of Treasury's Office of Foreign Assets Control (OFAC). These laws
+include restrictions on destinations, end-users and end-use. By accepting this
+license, you confirm that you are not currently residing in a country or region
+currently embargoed by the U.S. and that you are not otherwise prohibited from
+receiving the SDK.
+
+16. GOVERNMENT USE. The SDK is, and shall be treated as being, "Commercial
+Items" as that term is defined at 48 CFR § 2.101, consisting of "commercial
+computer software" and "commercial computer software documentation",
+respectively, as such terms are used in, respectively, 48 CFR § 12.212 and 48
+CFR §§ 227.7202 & 252.227-7014(a)(1). Use, duplication or disclosure by the U.S.
+Government or a U.S. Government subcontractor is subject to the restrictions in
+this license pursuant to 48 CFR § 12.212 or 48 CFR § 227.7202. In no event shall
+the US Government user acquire rights in the SDK beyond those specified in 48
+C.F.R. 52.227-19(b)(1)-(2). 
+
+17. NOTICES. You agree that any notices that NVIDIA sends you electronically,
+such as via email, will satisfy any legal communication requirements. Please
+direct your legal notices or other correspondence to NVIDIA Corporation, 2788
+San Tomas Expressway, Santa Clara, California 95051, United States of America,
+Attention: Legal Department.
+
+18. ENTIRE AGREEMENT. This license is the final, complete and exclusive
+agreement between the parties relating to the subject matter of this license and
+supersedes all prior or contemporaneous understandings and agreements relating
+to this subject matter, whether oral or written. If any court of competent
+jurisdiction determines that any provision of this license is illegal, invalid
+or unenforceable, the remaining provisions will remain in full force and effect.
+Any amendment or waiver under this license shall be in writing and signed by
+representatives of both parties.
+
+19. LICENSING. If the distribution terms in this license are not suitable for
+your organization, or for any questions regarding this license, please contact
+NVIDIA at [email protected].
+
+(v. April 12, 2021)
+
+
+
+NVIDIA RTX SUPPLEMENT TO SOFTWARE LICENSE AGREEMENT FOR NVIDIA SOFTWARE
+DEVELOPMENT KITS
+
+The terms in this supplement govern your use of the NVIDIA RTX SDKs, including
+the DLSS SDK, NGX SDK, RTXGI SDK, RTXDI SDK and/or NRD SDK, if and when made
+available to you (in each case, the "SDK") under the terms of your license
+agreement ("Agreement") as modified by this supplement. Capitalized terms used
+but not defined below have the meaning assigned to them in the Agreement.
+
+This supplement is an exhibit to the Agreement and is incorporated as an
+integral part of the Agreement. In the event of conflict between the terms in
+this supplement and the terms in the Agreement, the terms in this supplement
+govern. 
+
+1. Interoperability. Your applications that incorporate, or are based on, the
+SDK must be fully interoperable with compatible GPU hardware products designed
+by NVIDIA or its affiliates. Further, the DLSS SDK and NGX SDK are licensed for
+you to develop applications only for their use in systems with NVIDIA GPUs.
+
+2. Limitations for the DLSS SDK and NGX SDK. Your applications that incorporate,
+or are based on, the DLSS SDK or NGX SDK may be deployed in a cloud service that
+runs on systems that consume NVIDIA vGPU software, and any other cloud service
+use of such SDKs or their functionality is outside of the scope of the
+Agreement. For the purpose of this section, cloud services include application
+service providers or service bureaus, operators of hosted/virtual system
+environments, or hosting, time sharing or providing any other type of service to
+others. 
+
+3. Notification for the DLSS SDK and NGX SDK. You are required to notify NVIDIA
+prior to commercial release of an application (including a plug-in to a
+commercial application) that incorporates, or is based on, the DLSS SDK or NGX
+SDK. Please send notifications to: https://developer.nvidia.com/sw-notification
+and provide the following information in the email: company name, publisher and
+developer name, NVIDIA SDK used, application name, platform (i.e. PC, Linux),
+scheduled ship date, and weblink to product/video. 
+
+4. Audio and Video Encoders and Decoders. You acknowledge and agree that it is
+your sole responsibility to obtain any additional third-party licenses required
+to make, have made, use, have used, sell, import, and offer for sale your
+products or services that include or incorporate any third-party software and
+content relating to audio and/or video encoders and decoders from, including but
+not limited to, Microsoft, Thomson, Fraunhofer IIS, Sisvel S.p.A., MPEG-LA, and
+Coding Technologies. NVIDIA does not grant to you under this Agreement any
+necessary patent or other rights with respect to any audio and/or video encoders
+and decoders. 
+
+5. DLSS SDK Terms. By installing or using the DLSS SDK you agree that NVIDIA can
+make over-the-air updates of DLSS in systems that have DLSS installed, including
+(without limitation) for quality, stability or performance improvements or to
+support new hardware. If you publicly release a DLSS integration in an end user
+game or application that presents material stability, performance, image
+quality, or other technical issues impacting the user experience, you will work
+to quickly address the integration issues. In the case issues are not addressed,
+NVIDIA reserves the right, as a last resort, to temporarily disable the DLSS
+integration until the issues can be fixed.
+
+6. Marketing.
+
+6.1 Marketing Activities. Your license to the SDK(s) under the Agreement is
+subject to your compliance with the following marketing terms:
+
+(a) Identification by You in the DLSS SDK or NGX SDK. During the term of the
+Agreement, NVIDIA agrees that you may identify NVIDIA on your websites, printed
+collateral, trade-show displays and other retail packaging materials, as the
+supplier of the DLSS SDK or NGX SDK for the applications that were developed
+with use of such SDKs, provided that all such references to NVIDIA will be
+subject to NVIDIA's prior review and written approval, which will not be
+unreasonably withheld or delayed. 
+
+(b) NVIDIA Trademark Placement in Applications with the DLSS SDK or NGX SDK. 
+For applications that incorporate the DLSS SDK or NGX SDK or portions thereof,
+you must attribute the use of the applicable SDK and include the NVIDIA Marks
+on splash screens, in the about box of the application (if present), and in
+credits for game applications.
+
+(c) NVIDIA Trademark Placement in Applications with a licensed SDK, other than
+the DLSS SDK or NGX SDK. For applications that incorporates and/or makes use of
+a licensed SDK, other than the DLSS SDK or NGX SDK, you must attribute the use
+of the applicable SDK and include the NVIDIA Marks on the credit screen for
+applications that have such credit screen, or where a credit screen is not
+present prominently in end user documentation for the application. d)
+Identification by NVIDIA in the DLSS SDK or NGX SDK. You agree that NVIDIA may
+identify you on NVIDIA's websites, printed collateral, trade-show displays, and
+other retail packaging materials as an individual or entity that produces
+products and services which incorporate the DLSS SDK or NGX SDK as applicable.
+To the extent that you provide NVIDIA with input or usage requests with regard
+to the use of your logo or materials, NVIDIA will use commercially reasonable
+efforts to comply with such requests. For the avoidance of doubt, NVIDIA's
+rights pursuant to this section shall survive any expiration or termination of
+the Agreement with respect to existing applications which incorporate the DLSS
+SDK or NGX SDK.
+
+(e) Applications Marketing Material in the DLSS SDK or NGX SDK. You may provide
+NVIDIA with screenshots, imagery, and video footage of applications
+representative of your use of the NVIDIA DLSS SDK or NGX SDKs in your
+application (collectively, "Assets"). You hereby grant to NVIDIA the right to
+create and display self-promotional demo materials using the Assets, and after
+release of the application to the public to distribute, sub-license, and use
+the Assets to promote and market the NVIDIA RTX SDKs. To the extent you
+provide NVIDIA with input or usage requests with regard to the use of your logo
+or materials, NVIDIA will use commercially reasonable efforts to comply with
+such requests. For the avoidance of doubt, NVIDIA's rights pursuant to this
+section shall survive any termination of the Agreement with respect to
+applications which incorporate the NVIDIA RTX SDK.
+
+6.2 Trademark Ownership and Licenses. Trademarks are owned and licenses as
+follows:
+
+(a) Ownership of Trademarks. Each party owns the trademarks, logos, and trade
+names (collectively "Marks") for their respective products or services,
+including without limitation in applications, and the NVIDIA RTX SDKs. Each
+party agrees to use the Marks of the other only as permitted in this exhibit.
+
+(b) Trademark License to NVIDIA. You grant to NVIDIA a non-exclusive, non-sub
+licensable, non-transferable (except as set forth in the assignment provision
+of the Agreement), worldwide license to refer to you and your applications, and
+to use your Marks on NVIDIA's marketing materials and on NVIDIA's website
+(subject to any reasonable conditions of you) solely for NVIDIA's marketing
+activities set forth in this exhibit Sections (d)-(e) above. NVIDIA will
+follow your specifications for your Marks as to style, color, and typeface as
+reasonably provided to NVIDIA.
+
+(c) Trademark License to You. NVIDIA grants to you a non-exclusive, non-sub
+licensable, non-transferable (except as set forth in the assignment provision
+of the Agreement), worldwide license, subject to the terms of this exhibit and
+the Agreement, to use NVIDIA RTX™, NVIDIA GeForce RTX™ in combination with
+GeForce products, and/or NVIDIA Quadro RTX™ in combination with Quadro
+products (collectively, the "NVIDIA Marks") on your marketing materials and on
+your website (subject to any reasonable conditions of NVIDIA) solely for your
+marketing activities set forth in this exhibit Sections 6.1 (a)-(c) above. For
+the avoidance of doubt, you will not and will not permit others to use any
+NVIDIA Mark for any other goods or services, or in a way that tarnishes,
+degrades, disparages or reflects adversely any of the NVIDIA Marks or NVIDIA's
+business or reputation, or that dilutes or otherwise harms the value,
+reputation or distinctiveness of or NVIDIA's goodwill in any NVIDIA Mark. In
+addition to the termination rights set forth in the Agreement, NVIDIA may
+terminate this trademark license at any time upon written notice to you. You
+will follow NVIDIA's use guidelines and specifications for NVIDIA's Marks as to
+style, color and typeface as provided in NVIDIA Marks and submit a sample of
+each proposed use of NVIDIA's Marks at least ten (10) business days prior to
+the desired implementation of such use to obtain NVIDIA's prior written
+approval (which approval will not be unreasonably withheld or delayed. Use of
+NVIDIA marks is not authorized until NVIDIA provides written approval. All
+goodwill associated with use of NVIDIA Marks will inure to the sole benefit of
+NVIDIA.
+
+6.3 Use Guidelines. Use of the NVIDIA Marks is subject to the following
+guidelines:
+
+(a) Business Practices. You covenant that you will: (a) conduct business with
+respect to NVIDIA's products in a manner that reflects favorably at all times
+on the good name, goodwill and reputation of such products; (b) avoid
+deceptive, misleading or unethical practices that are detrimental to NVIDIA,
+its customers, or end users; (c) make no false or misleading representations
+with regard to NVIDIA or its products; and (d) not publish or employ or
+cooperate in the publication or employment of any misleading or deceptive
+advertising or promotional materials.
+
+(b) No Combination Marks or Similar Marks. You agree not to (a) combine NVIDIA
+Marks with any other content without NVIDIA's prior written approval, or (b)
+use any other trademark, trade name, or other designation of source which
+creates a likelihood of confusion with NVIDIA Marks.
+
+(v. April 12, 2021)

+ 15 - 0
ThirdParty/DlssSdk/sdk/README.md

@@ -0,0 +1,15 @@
+# DLSS
+Public repo for NVIDIA RTX DLSS SDK. 
+The DLSS Sample app is included only in the releases. 
+
+## NVIDIA Image Scaling SDK
+The NVIDIA Image Scaling SDK provides a single spatial scaling and sharpening algorithm for cross-platform support. It contains compute shaders that can be integrated with DX11, DX12, and Vulkan. For more information visit https://github.com/NVIDIAGameWorks/NVIDIAImageScaling.
+
+To get the NVIDIA Image Scaling SDK submodule use the following command
+```
+$ git clone --recurse-submodules https://github.com/NVIDIA/DLSS.git
+```
+or if you already have clonned the DLSS repository and didn't use --recurse-submodules
+```
+git submodule update --init --recursive
+```

+ 439 - 0
ThirdParty/DlssSdk/sdk/include/nvsdk_ngx.h

@@ -0,0 +1,439 @@
+/*
+* Copyright (c) 2018 NVIDIA CORPORATION.  All rights reserved.
+*
+* NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+* rights in and to this software, related documentation and any modifications thereto.
+* Any use, reproduction, disclosure or distribution of this software and related
+* documentation without an express license agreement from NVIDIA Corporation is strictly
+* prohibited.
+*
+* TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS*
+* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
+* INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
+* SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT
+* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF
+* BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
+* INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGES.
+*/
+
+/*
+*  HOW TO USE:
+*
+*  IMPORTANT: FOR DLSS/DLISP PLEASE SEE THE PROGRAMMING GUIDE
+* 
+*  IMPORTANT: Methods in this library are NOT thread safe. It is up to the
+*  client to ensure that thread safety is enforced as needed.
+*  
+*  1) Call NVSDK_CONV NVSDK_NGX_D3D11/D3D12/CUDA_Init and pass your app Id
+*     and other parameters. This will initialize SDK or return an error code
+*     if SDK cannot run on target machine. Depending on error user might
+*     need to update drivers. Please note that application Id is provided
+*     by NVIDIA so if you do not have one please contact us.
+* 
+*  2) Call NVSDK_NGX_D3D11/D3D12/CUDA_GetCapabilityParameters to obtain pointer
+*     to interface used to pass parameters to SDK. Interface instance is 
+*     allocated and released by SDK so there is no need to do any memory 
+*     management on client side.
+*    
+*  3) Set key parameters for the feature you want to use. For example, 
+*     width and height are required for all features and they can be
+*     set like this: 
+*         Params->Set(NVSDK_NGX_Parameter_Width,MY_WIDTH);
+*         Params->Set(NVSDK_NGX_Parameter_Height,MY_HEIGHT);
+*
+*     You can also provide hints like NVSDK_NGX_Parameter_Hint_HDR to tell
+*     SDK that it should expect HDR color space is needed. Please refer to 
+*     samples since different features need different parameters and hints.
+*
+*  4) Call NVSDK_NGX_D3D11/D3D12/CUDA_GetScratchBufferSize to obtain size of
+*     the scratch buffer needed by specific feature. This D3D or CUDA buffer
+*     should be allocated by client and passed as:
+*        Params->Set(NVSDK_NGX_Parameter_Scratch,MY_SCRATCH_POINTER)
+*        Params->Set(NVSDK_NGX_Parameter_Scratch_SizeInBytes,MY_SCRATCH_SIZE_IN_BYTES)
+*     NOTE: Returned size can be 0 if feature does not use any scratch buffer.
+*     It is OK to use bigger buffer or reuse buffers across features as long
+*     as minimum size requirement is met.
+*
+*  5) Call NVSDK_NGX_D3D11/D3D12/CUDA_CreateFeature to create feature you need.
+*     On success SDK will return a handle which must be used in any successive 
+*     calls to SDK which require feature handle. SDK will use all parameters
+*     and hints provided by client to generate feature. If feature with the same
+*     parameters already exists and error code will be returned.
+*
+*  6) Call NVSDK_NGX_D3D11/D3D12/CUDA_EvaluateFeature to invoke execution of
+*     specific feature. Before feature can be evaluated input parameters must
+*     be specified (like for example color/albedo buffer, motion vectors etc)
+* 
+*  6) Call NVSDK_NGX_D3D11/D3D12/CUDA_ReleaseFeature when feature is no longer
+*     needed. After this call feature handle becomes invalid and cannot be used.
+* 
+*  7) Call NVSDK_NGX_D3D11/D3D12/CUDA_Shutdown when SDK is no longer needed to
+*     release all resources.
+
+*  Contact: [email protected]
+*/
+
+
+#ifndef NVSDK_NGX_H
+#define NVSDK_NGX_H
+
+#include <stddef.h> // For size_t
+
+#include "nvsdk_ngx_defs.h"
+#include "nvsdk_ngx_params.h"
+#ifndef __cplusplus
+#include <stdbool.h> 
+#include <wchar.h> 
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct IUnknown IUnknown;
+
+typedef struct ID3D11Device              ID3D11Device;
+typedef struct ID3D11Resource            ID3D11Resource;
+typedef struct ID3D11DeviceContext       ID3D11DeviceContext;
+typedef struct D3D11_TEXTURE2D_DESC      D3D11_TEXTURE2D_DESC;
+typedef struct D3D11_BUFFER_DESC         D3D11_BUFFER_DESC;
+typedef struct ID3D11Buffer              ID3D11Buffer;
+typedef struct ID3D11Texture2D           ID3D11Texture2D;
+
+typedef struct ID3D12Device              ID3D12Device;
+typedef struct ID3D12Resource            ID3D12Resource;
+typedef struct ID3D12GraphicsCommandList ID3D12GraphicsCommandList;
+typedef struct D3D12_RESOURCE_DESC       D3D12_RESOURCE_DESC;
+typedef struct CD3DX12_HEAP_PROPERTIES   CD3DX12_HEAP_PROPERTIES;
+
+typedef void (NVSDK_CONV *PFN_NVSDK_NGX_D3D12_ResourceAllocCallback)(D3D12_RESOURCE_DESC *InDesc, int InState, CD3DX12_HEAP_PROPERTIES *InHeap, ID3D12Resource **OutResource);
+typedef void (NVSDK_CONV *PFN_NVSDK_NGX_D3D11_BufferAllocCallback)(D3D11_BUFFER_DESC *InDesc, ID3D11Buffer **OutResource);
+typedef void (NVSDK_CONV *PFN_NVSDK_NGX_D3D11_Tex2DAllocCallback)(D3D11_TEXTURE2D_DESC *InDesc, ID3D11Texture2D **OutResource);
+typedef void (NVSDK_CONV *PFN_NVSDK_NGX_ResourceReleaseCallback)(IUnknown *InResource);
+
+typedef unsigned long long CUtexObject;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_Init
+// -------------------------------------
+// 
+// InApplicationId:
+//      Unique Id provided by NVIDIA
+//
+// InApplicationDataPath:
+//      Folder to store logs and other temporary files (write access required),
+//      Normally this would be a location in Documents or ProgramData.
+//
+// InDevice: [d3d11/12 only]
+//      DirectX device to use
+//
+// InFeatureInfo:
+//      Contains information common to all features, presently only a list of all paths 
+//      feature dlls can be located in, other than the default path - application directory.
+//
+// DESCRIPTION:
+//      Initializes new SDK instance.
+//
+#ifdef __cplusplus
+NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_D3D11_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D11Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
+NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_D3D12_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D12Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
+NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_CUDA_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
+#else
+NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_D3D11_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D11Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
+NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_D3D12_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D12Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
+NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_CUDA_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_Init_with_ProjectID
+// -------------------------------------
+// 
+// InProjectId:
+//      Unique Id provided by the rendering engine used
+//
+// InEngineType:
+//      Rendering engine used by the application / plugin.
+//      Use NVSDK_NGX_ENGINE_TYPE_CUSTOM if the specific engine type is not supported explicitly
+//
+// InEngineVersion:
+//      Version number of the rendering engine used by the application / plugin.
+//
+// InApplicationDataPath:
+//      Folder to store logs and other temporary files (write access required),
+//      Normally this would be a location in Documents or ProgramData.
+//
+// InDevice: [d3d11/12 only]
+//      DirectX device to use
+//
+// InFeatureInfo:
+//      Contains information common to all features, presently only a list of all paths 
+//      feature dlls can be located in, other than the default path - application directory.
+//
+// DESCRIPTION:
+//      Initializes new SDK instance.
+//
+#ifdef __cplusplus
+NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_D3D11_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, ID3D11Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
+NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_D3D12_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, ID3D12Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
+NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_CUDA_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
+#else
+NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_D3D11_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, ID3D11Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
+NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_D3D12_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, ID3D12Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
+NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_CUDA_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_Shutdown
+// -------------------------------------
+// 
+// DESCRIPTION:
+//      Shuts down the current SDK instance and releases all resources.
+//      Shutdown1(Device) only affects specified device
+//      Shutdown1(nullptr) = Shutdown() and shuts down all devices
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Shutdown(void);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Shutdown1(ID3D11Device *InDevice);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_Shutdown(void);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_Shutdown1(ID3D12Device *InDevice);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Shutdown(void);
+
+#ifdef NGX_ENABLE_DEPRECATED_GET_PARAMETERS
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_GetParameters
+// ----------------------------------------------------------
+//
+// OutParameters:
+//      Parameters interface used to set any parameter needed by the SDK
+//
+// DESCRIPTION:
+//      This interface allows simple parameter setup using named fields.
+//      For example one can set width by calling Set(NVSDK_NGX_Parameter_Denoiser_Width,100) or
+//      provide CUDA buffer pointer by calling Set(NVSDK_NGX_Parameter_Denoiser_Color,cudaBuffer)
+//      For more details please see sample code. Please note that allocated memory
+//      will be freed by NGX so free/delete operator should NOT be called.
+//      Parameter maps output by NVSDK_NGX_GetParameters are also pre-populated
+//      with NGX capabilities and available features.
+//      Unlike with NVSDK_NGX_AllocateParameters, parameter maps output by NVSDK_NGX_GetParameters
+//      have their lifetimes managed by NGX, and must not
+//      be destroyed by the app using NVSDK_NGX_DestroyParameters.
+//      NVSDK_NGX_GetParameters is deprecated and apps should move to using
+//      NVSDK_NGX_AllocateParameters and NVSDK_NGX_GetCapabilityParameters when possible.
+//      Nevertheless, due to the possibility that the user will be using an older driver version,
+//      NVSDK_NGX_GetParameters may still be used as a fallback if NVSDK_NGX_AllocateParameters
+//      or NVSDK_NGX_GetCapabilityParameters return NVSDK_NGX_Result_FAIL_OutOfDate.
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_GetParameters(NVSDK_NGX_Parameter **OutParameters);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_GetParameters(NVSDK_NGX_Parameter **OutParameters);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_GetParameters(NVSDK_NGX_Parameter **OutParameters);
+#endif // NGX_ENABLE_DEPRECATED_GET_PARAMETERS
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_AllocateParameters
+// ----------------------------------------------------------
+//
+// OutParameters:
+//      Parameters interface used to set any parameter needed by the SDK
+//
+// DESCRIPTION:
+//      This interface allows allocating a simple parameter setup using named fields, whose
+//      lifetime the app must manage.
+//      For example one can set width by calling Set(NVSDK_NGX_Parameter_Denoiser_Width,100) or
+//      provide CUDA buffer pointer by calling Set(NVSDK_NGX_Parameter_Denoiser_Color,cudaBuffer)
+//      For more details please see sample code.
+//      Parameter maps output by NVSDK_NGX_AllocateParameters must NOT be freed using
+//      the free/delete operator; to free a parameter map 
+//      output by NVSDK_NGX_AllocateParameters, NVSDK_NGX_DestroyParameters should be used.
+//      Unlike with NVSDK_NGX_GetParameters, parameter maps allocated with NVSDK_NGX_AllocateParameters
+//      must be destroyed by the app using NVSDK_NGX_DestroyParameters.
+//      Also unlike with NVSDK_NGX_GetParameters, parameter maps output by NVSDK_NGX_AllocateParameters
+//      do not come pre-populated with NGX capabilities and available features.
+//      To create a new parameter map pre-populated with such information, NVSDK_NGX_GetCapabilityParameters
+//      should be used.
+//      This function may return NVSDK_NGX_Result_FAIL_OutOfDate if an older driver, which
+//      does not support this API call is being used. In such a case, NVSDK_NGX_GetParameters
+//      may be used as a fallback.
+//      This function may only be called after a successful call into NVSDK_NGX_Init.
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_AllocateParameters(NVSDK_NGX_Parameter** OutParameters);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_AllocateParameters(NVSDK_NGX_Parameter** OutParameters);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_AllocateParameters(NVSDK_NGX_Parameter** OutParameters);
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_GetCapabilityParameters
+// ----------------------------------------------------------
+//
+// OutParameters:
+//      The parameters interface populated with NGX and feature capabilities
+//
+// DESCRIPTION:
+//      This interface allows the app to create a new parameter map
+//      pre-populated with NGX capabilities and available features.
+//      The output parameter map can also be used for any purpose
+//      parameter maps output by NVSDK_NGX_AllocateParameters can be used for
+//      but it is not recommended to use NVSDK_NGX_GetCapabilityParameters
+//      unless querying NGX capabilities and available features
+//      due to the overhead associated with pre-populating the parameter map.
+//      Parameter maps output by NVSDK_NGX_GetCapabilityParameters must NOT be freed using
+//      the free/delete operator; to free a parameter map
+//      output by NVSDK_NGX_GetCapabilityParameters, NVSDK_NGX_DestroyParameters should be used.
+//      Unlike with NVSDK_NGX_GetParameters, parameter maps allocated with NVSDK_NGX_GetCapabilityParameters
+//      must be destroyed by the app using NVSDK_NGX_DestroyParameters.
+//      This function may return NVSDK_NGX_Result_FAIL_OutOfDate if an older driver, which
+//      does not support this API call is being used. This function may only be called
+//      after a successful call into NVSDK_NGX_Init.
+//      If NVSDK_NGX_GetCapabilityParameters fails with NVSDK_NGX_Result_FAIL_OutOfDate,
+//      NVSDK_NGX_GetParameters may be used as a fallback, to get a parameter map pre-populated
+//      with NGX capabilities and available features.
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters);
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_DestroyParameters
+// ----------------------------------------------------------
+//
+// InParameters:
+//      The parameters interface to be destroyed
+//
+// DESCRIPTION:
+//      This interface allows the app to destroy the parameter map passed in. Once
+//      NVSDK_NGX_DestroyParameters is called on a parameter map, it
+//      must not be used again.
+//      NVSDK_NGX_DestroyParameters must not be called on any parameter map returned
+//      by NVSDK_NGX_GetParameters; NGX will manage the lifetime of those
+//      parameter maps.
+//      This function may return NVSDK_NGX_Result_FAIL_OutOfDate if an older driver, which
+//      does not support this API call is being used. This function may only be called
+//      after a successful call into NVSDK_NGX_Init.
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_DestroyParameters(NVSDK_NGX_Parameter* InParameters);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_DestroyParameters(NVSDK_NGX_Parameter* InParameters);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_DestroyParameters(NVSDK_NGX_Parameter* InParameters);
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_GetScratchBufferSize
+// ----------------------------------------------------------
+//
+// InFeatureId:
+//      AI feature in question
+//
+// InParameters:
+//      Parameters used by the feature to help estimate scratch buffer size
+//
+// OutSizeInBytes:
+//      Number of bytes needed for the scratch buffer for the specified feature.
+//
+// DESCRIPTION:
+//      SDK needs a buffer of a certain size provided by the client in
+//      order to initialize AI feature. Once feature is no longer
+//      needed buffer can be released. It is safe to reuse the same
+//      scratch buffer for different features as long as minimum size
+//      requirement is met for all features. Please note that some
+//      features might not need a scratch buffer so return size of 0
+//      is completely valid.
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter *InParameters, size_t *OutSizeInBytes);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter *InParameters, size_t *OutSizeInBytes);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter *InParameters, size_t *OutSizeInBytes);
+
+/////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_CreateFeature
+// -------------------------------------
+//
+// InCmdList:[d3d12 only]
+//      Command list to use to execute GPU commands. Must be:
+//      - Open and recording 
+//      - With node mask including the device provided in NVSDK_NGX_D3D12_Init
+//      - Execute on non-copy command queue.
+// InDevCtx: [d3d11 only]
+//      Device context to use to execute GPU commands
+//
+// InFeatureID:
+//      AI feature to initialize
+//
+// InParameters:
+//      List of parameters 
+// 
+// OutHandle:
+//      Handle which uniquely identifies the feature. If feature with
+//      provided parameters already exists the "already exists" error code is returned.
+//
+// DESCRIPTION:
+//      Each feature needs to be created before it can be used. 
+//      Refer to the sample code to find out which input parameters
+//      are needed to create specific feature.
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_CreateFeature(ID3D11DeviceContext *InDevCtx, NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsCommandList *InCmdList, NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_CreateFeature(NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
+
+/////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_Release
+// -------------------------------------
+// 
+// InHandle:
+//      Handle to feature to be released
+//
+// DESCRIPTION:
+//      Releases feature with a given handle.
+//      Handles are not reference counted so
+//      after this call it is invalid to use provided handle.
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_ReleaseFeature(NVSDK_NGX_Handle *InHandle);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_ReleaseFeature(NVSDK_NGX_Handle *InHandle);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_ReleaseFeature(NVSDK_NGX_Handle *InHandle);
+
+/////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_EvaluateFeature
+// -------------------------------------
+//
+// InCmdList:[d3d12 only]
+//      Command list to use to execute GPU commands. Must be:
+//      - Open and recording 
+//      - With node mask including the device provided in NVSDK_NGX_D3D12_Init
+//      - Execute on non-copy command queue.
+// InDevCtx: [d3d11 only]
+//      Device context to use to execute GPU commands
+//
+// InFeatureHandle:
+//      Handle representing feature to be evaluated
+// 
+// InParameters:
+//      List of parameters required to evaluate feature
+//
+// InCallback:
+//      Optional callback for features which might take longer
+//      to execture. If specified SDK will call it with progress
+//      values in range 0.0f - 1.0f
+//
+// DESCRIPTION:
+//      Evaluates given feature using the provided parameters and
+//      pre-trained NN. Please note that for most features
+//      it can be benefitials to pass as many input buffers and parameters
+//      as possible (for example provide all render targets like color, albedo, normals, depth etc)
+//
+
+#ifdef __cplusplus
+typedef void (NVSDK_CONV *PFN_NVSDK_NGX_ProgressCallback)(float InCurrentProgress, bool &OutShouldCancel);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_EvaluateFeature(ID3D11DeviceContext *InDevCtx, const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback = NULL);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCommandList *InCmdList, const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback = NULL);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_EvaluateFeature(const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback = NULL);
+#endif
+
+typedef void (NVSDK_CONV *PFN_NVSDK_NGX_ProgressCallback_C)(float InCurrentProgress, bool *OutShouldCancel);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_EvaluateFeature_C(ID3D11DeviceContext *InDevCtx, const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback_C InCallback);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_EvaluateFeature_C(ID3D12GraphicsCommandList *InCmdList, const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback_C InCallback);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_EvaluateFeature_C(const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback_C InCallback);
+
+// NGX return-code conversion-to-string utility only as a helper for debugging/logging - not for official use.
+const wchar_t* NVSDK_CONV GetNGXResultAsString(NVSDK_NGX_Result InNGXResult);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // #define NVSDK_NGX_H

+ 610 - 0
ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_defs.h

@@ -0,0 +1,610 @@
+/*
+* Copyright (c) 2018 NVIDIA CORPORATION.  All rights reserved.
+*
+* NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+* rights in and to this software, related documentation and any modifications thereto.
+* Any use, reproduction, disclosure or distribution of this software and related
+* documentation without an express license agreement from NVIDIA Corporation is strictly
+* prohibited.
+*
+* TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS*
+* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
+* INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
+* SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT
+* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF
+* BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
+* INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGES.
+*/
+
+#ifndef NVSDK_NGX_DEFS_H
+#define NVSDK_NGX_DEFS_H
+#pragma once
+
+#ifndef __cplusplus
+#include <stddef.h> // For size_t
+#include <stdbool.h> 
+#include <wchar.h> 
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef __cplusplus
+#if defined(NVSDK_NGX) && defined(NV_WINDOWS)
+#define NVSDK_NGX_API extern "C" __declspec(dllexport)
+#else
+#define NVSDK_NGX_API extern "C"
+#endif
+#else
+#if defined(NVSDK_NGX) && defined(NV_WINDOWS)
+#define NVSDK_NGX_API __declspec(dllexport)
+#else
+#define NVSDK_NGX_API 
+#endif
+#endif
+
+#ifdef __GNUC__
+#define NVSDK_CONV
+#else
+#define NVSDK_CONV __cdecl
+#endif
+
+#define NVSDK_NGX_ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0]))
+    
+//  Version Notes:
+//      Version 0x0000014:
+//          * Added a logging callback that the app may pass in on init
+//          * Added ability for the app to override the logging level
+//      Version 0x0000015:
+//          * Support multiple GPUs (bug 3270533)
+#define NVSDK_NGX_VERSION_API_MACRO 0x0000014  // NGX_VERSION_DOT 1.4.0
+
+typedef struct NVSDK_NGX_FeatureCommonInfo_Internal NVSDK_NGX_FeatureCommonInfo_Internal;
+
+typedef enum NVSDK_NGX_Version { NVSDK_NGX_Version_API = NVSDK_NGX_VERSION_API_MACRO } NVSDK_NGX_Version;
+
+typedef enum NVSDK_NGX_Result
+{
+    NVSDK_NGX_Result_Success = 0x1,
+
+    NVSDK_NGX_Result_Fail = 0xBAD00000,
+
+    // Feature is not supported on current hardware
+    NVSDK_NGX_Result_FAIL_FeatureNotSupported = NVSDK_NGX_Result_Fail | 1,
+
+    // Platform error - for example - check d3d12 debug layer log for more information
+    NVSDK_NGX_Result_FAIL_PlatformError = NVSDK_NGX_Result_Fail | 2,
+
+    // Feature with given parameters already exists
+    NVSDK_NGX_Result_FAIL_FeatureAlreadyExists = NVSDK_NGX_Result_Fail | 3,
+
+    // Feature with provided handle does not exist
+    NVSDK_NGX_Result_FAIL_FeatureNotFound = NVSDK_NGX_Result_Fail | 4,
+
+    // Invalid parameter was provided
+    NVSDK_NGX_Result_FAIL_InvalidParameter = NVSDK_NGX_Result_Fail | 5,
+
+    // Provided buffer is too small, please use size provided by NVSDK_NGX_GetScratchBufferSize
+    NVSDK_NGX_Result_FAIL_ScratchBufferTooSmall = NVSDK_NGX_Result_Fail | 6,
+
+    // SDK was not initialized properly
+    NVSDK_NGX_Result_FAIL_NotInitialized = NVSDK_NGX_Result_Fail | 7,
+
+    //  Unsupported format used for input/output buffers
+    NVSDK_NGX_Result_FAIL_UnsupportedInputFormat = NVSDK_NGX_Result_Fail | 8,
+
+    // Feature input/output needs RW access (UAV) (d3d11/d3d12 specific)
+    NVSDK_NGX_Result_FAIL_RWFlagMissing = NVSDK_NGX_Result_Fail | 9,
+
+    // Feature was created with specific input but none is provided at evaluation
+    NVSDK_NGX_Result_FAIL_MissingInput = NVSDK_NGX_Result_Fail | 10,
+
+    // Feature is not available on the system
+    NVSDK_NGX_Result_FAIL_UnableToInitializeFeature = NVSDK_NGX_Result_Fail | 11,
+
+    // NGX system libraries are old and need an update
+    NVSDK_NGX_Result_FAIL_OutOfDate = NVSDK_NGX_Result_Fail | 12,
+
+    // Feature requires more GPU memory than it is available on system
+    NVSDK_NGX_Result_FAIL_OutOfGPUMemory = NVSDK_NGX_Result_Fail | 13,
+
+    // Format used in input buffer(s) is not supported by feature
+    NVSDK_NGX_Result_FAIL_UnsupportedFormat = NVSDK_NGX_Result_Fail | 14,
+
+    // Path provided in InApplicationDataPath cannot be written to
+    NVSDK_NGX_Result_FAIL_UnableToWriteToAppDataPath = NVSDK_NGX_Result_Fail | 15,
+
+    // Unsupported parameter was provided (e.g. specific scaling factor is unsupported)
+    NVSDK_NGX_Result_FAIL_UnsupportedParameter = NVSDK_NGX_Result_Fail | 16,
+
+    // The feature or application was denied (contact NVIDIA for further details)
+    NVSDK_NGX_Result_FAIL_Denied = NVSDK_NGX_Result_Fail | 17
+} NVSDK_NGX_Result;
+
+#define NVSDK_NGX_SUCCEED(value) (((value) & 0xFFF00000) != NVSDK_NGX_Result_Fail)
+#define NVSDK_NGX_FAILED(value) (((value) & 0xFFF00000) == NVSDK_NGX_Result_Fail)
+
+typedef enum NVSDK_NGX_Feature
+{
+    NVSDK_NGX_Feature_Reserved0,
+
+    NVSDK_NGX_Feature_SuperSampling,
+
+    NVSDK_NGX_Feature_InPainting,
+
+    NVSDK_NGX_Feature_ImageSuperResolution,
+
+    NVSDK_NGX_Feature_SlowMotion,
+
+    NVSDK_NGX_Feature_VideoSuperResolution,
+
+    NVSDK_NGX_Feature_Reserved1,
+
+    NVSDK_NGX_Feature_Reserved2,
+
+    NVSDK_NGX_Feature_Reserved3,
+
+    NVSDK_NGX_Feature_ImageSignalProcessing,
+
+    NVSDK_NGX_Feature_DeepResolve,
+
+    NVSDK_NGX_Feature_Reserved4,
+
+    // New features go here
+    NVSDK_NGX_Feature_Count,
+
+    // These members are not strictly NGX features, but are 
+    // components of the NGX system, and it may sometimes
+    // be useful to identify them using the same enum
+    NVSDK_NGX_Feature_Reserved_SDK = 32764,
+
+    NVSDK_NGX_Feature_Reserved_Core,
+
+    NVSDK_NGX_Feature_Reserved_Unknown
+} NVSDK_NGX_Feature;
+
+//TODO create grayscale format (R32F?)
+typedef enum NVSDK_NGX_Buffer_Format
+{
+    NVSDK_NGX_Buffer_Format_Unknown,
+    NVSDK_NGX_Buffer_Format_RGB8UI,
+    NVSDK_NGX_Buffer_Format_RGB16F,
+    NVSDK_NGX_Buffer_Format_RGB32F,
+    NVSDK_NGX_Buffer_Format_RGBA8UI,
+    NVSDK_NGX_Buffer_Format_RGBA16F,
+    NVSDK_NGX_Buffer_Format_RGBA32F,
+} NVSDK_NGX_Buffer_Format;
+
+typedef enum NVSDK_NGX_PerfQuality_Value
+{
+    NVSDK_NGX_PerfQuality_Value_MaxPerf,
+    NVSDK_NGX_PerfQuality_Value_Balanced,
+    NVSDK_NGX_PerfQuality_Value_MaxQuality,
+    // Extended PerfQuality modes
+    NVSDK_NGX_PerfQuality_Value_UltraPerformance,
+    NVSDK_NGX_PerfQuality_Value_UltraQuality,
+} NVSDK_NGX_PerfQuality_Value;
+
+typedef enum NVSDK_NGX_RTX_Value
+{
+    NVSDK_NGX_RTX_Value_Off,
+    NVSDK_NGX_RTX_Value_On,
+} NVSDK_NGX_RTX_Value;
+
+typedef enum NVSDK_NGX_DLSS_Mode
+{
+    NVSDK_NGX_DLSS_Mode_Off,        // use existing in-engine AA + upscale solution
+    NVSDK_NGX_DLSS_Mode_DLSS_DLISP,
+    NVSDK_NGX_DLSS_Mode_DLISP_Only, // use existing in-engine AA solution
+    NVSDK_NGX_DLSS_Mode_DLSS,       // DLSS will apply AA and upsample at the same time
+} NVSDK_NGX_DLSS_Mode;
+
+typedef struct NVSDK_NGX_Handle { unsigned int Id; } NVSDK_NGX_Handle;
+
+typedef enum NSDK_NGX_GPU_Arch
+{
+    NVSDK_NGX_GPU_Arch_NotSupported = 0,
+
+    // Match NvAPI's NV_GPU_ARCHITECTURE_ID values for GV100 and TU100 for
+    // backwards compatibility with snippets built against NvAPI
+    NVSDK_NGX_GPU_Arch_Volta        = 0x0140,
+    NVSDK_NGX_GPU_Arch_Turing       = 0x0160,
+
+    // Presumably something newer
+    NVSDK_NGX_GPU_Arch_Unknown      = 0x7FFFFFF
+} NVSDK_NGX_GPU_Arch;
+
+typedef enum NVSDK_NGX_DLSS_Feature_Flags
+{
+    NVSDK_NGX_DLSS_Feature_Flags_IsInvalid      = 1 << 31,
+
+    NVSDK_NGX_DLSS_Feature_Flags_None           = 0,
+    NVSDK_NGX_DLSS_Feature_Flags_IsHDR          = 1 << 0,
+    NVSDK_NGX_DLSS_Feature_Flags_MVLowRes       = 1 << 1,
+    NVSDK_NGX_DLSS_Feature_Flags_MVJittered     = 1 << 2,
+    NVSDK_NGX_DLSS_Feature_Flags_DepthInverted  = 1 << 3,
+    NVSDK_NGX_DLSS_Feature_Flags_Reserved_0     = 1 << 4,
+    NVSDK_NGX_DLSS_Feature_Flags_DoSharpening   = 1 << 5,
+    NVSDK_NGX_DLSS_Feature_Flags_AutoExposure   = 1 << 6,
+} NVSDK_NGX_DLSS_Feature_Flags;
+
+typedef enum NVSDK_NGX_ToneMapperType
+{
+    NVSDK_NGX_TONEMAPPER_STRING = 0,
+    NVSDK_NGX_TONEMAPPER_REINHARD,
+    NVSDK_NGX_TONEMAPPER_ONEOVERLUMA,
+    NVSDK_NGX_TONEMAPPER_ACES,
+    NVSDK_NGX_TONEMAPPERTYPE_NUM
+} NVSDK_NGX_ToneMapperType;
+
+typedef enum NVSDK_NGX_GBufferType
+{
+    NVSDK_NGX_GBUFFER_ALBEDO = 0,
+    NVSDK_NGX_GBUFFER_ROUGHNESS,
+    NVSDK_NGX_GBUFFER_METALLIC,
+    NVSDK_NGX_GBUFFER_SPECULAR,
+    NVSDK_NGX_GBUFFER_SUBSURFACE,
+    NVSDK_NGX_GBUFFER_NORMALS,
+    NVSDK_NGX_GBUFFER_SHADINGMODELID,  /* unique identifier for drawn object or how the object is drawn */
+    NVSDK_NGX_GBUFFER_MATERIALID, /* unique identifier for material */
+    NVSDK_NGX_GBUFFER_SPECULAR_ALBEDO,
+    NVSDK_NGX_GBUFFER_INDIRECT_ALBEDO,
+    NVSDK_NGX_GBUFFER_SPECULAR_MVEC,
+    NVSDK_NGX_GBUFFER_DISOCCL_MASK,
+    NVSDK_NGX_GBUFFERTYPE_NUM = 16
+} NVSDK_NGX_GBufferType;
+
+typedef struct NVSDK_NGX_Coordinates
+{
+    unsigned int X;
+    unsigned int Y;
+} NVSDK_NGX_Coordinates;
+
+typedef struct NVSDK_NGX_Dimensions
+{
+    unsigned int Width;
+    unsigned int Height;
+} NVSDK_NGX_Dimensions;
+
+typedef struct NVSDK_NGX_PathListInfo
+{
+#ifdef NV_WINDOWS
+    wchar_t **Path;
+#else //NV_WINDOWS
+    char **Path;
+#endif //NV_WINDOWS
+    // Path-list length
+    unsigned int Length;
+} NVSDK_NGX_PathListInfo;
+
+typedef enum NVSDK_NGX_Logging_Level
+{
+    NVSDK_NGX_LOGGING_LEVEL_OFF = 0,
+    NVSDK_NGX_LOGGING_LEVEL_ON,
+    NVSDK_NGX_LOGGING_LEVEL_VERBOSE,
+    NVSDK_NGX_LOGGING_LEVEL_NUM
+} NVSDK_NGX_Logging_Level;
+
+// A logging callback provided by the app to allow piping log lines back to the app.
+// Please take careful note of the signature and calling convention.
+// The callback must be able to be called from any thread.
+// It must also be fully thread-safe and any number of threads may call into it concurrently. 
+// It must fully process message by the time it returns, and there is no guarantee that
+// message will still be valid or allocated after it returns.
+// message will be a null-terminated string and may contain multibyte characters.
+#if defined(__GNUC__) || defined(__clang__)
+typedef void NVSDK_CONV(*NVSDK_NGX_AppLogCallback)(const char* message, NVSDK_NGX_Logging_Level loggingLevel, NVSDK_NGX_Feature sourceComponent);
+#else
+typedef void(NVSDK_CONV* NVSDK_NGX_AppLogCallback)(const char* message, NVSDK_NGX_Logging_Level loggingLevel, NVSDK_NGX_Feature sourceComponent);
+#endif
+
+typedef struct NGSDK_NGX_LoggingInfo
+{
+    // Fields below were introduced in SDK version 0x0000014
+
+    // App-provided logging callback
+    NVSDK_NGX_AppLogCallback LoggingCallback;
+
+    // The minimum logging level to use. If this is higher
+    // than the logging level otherwise configured, this will override
+    // that logging level. Otherwise, that logging level will be used.
+    NVSDK_NGX_Logging_Level MinimumLoggingLevel;
+
+    // Whether or not to disable writing log lines to sinks other than the app log callback. This
+    // may be useful if the app provides a logging callback. LoggingCallback must be non-null and point
+    // to a valid logging callback if this is set to true.
+    bool DisableOtherLoggingSinks;
+
+} NGSDK_NGX_LoggingInfo;
+
+typedef struct NVSDK_NGX_FeatureCommonInfo
+{
+    // List of all paths in descending order of search sequence to locate a feature dll in, other than the default path - application folder.
+    NVSDK_NGX_PathListInfo PathListInfo;
+    // Used internally by NGX
+    NVSDK_NGX_FeatureCommonInfo_Internal* InternalData; // Introduced in SDK version 0x0000013
+
+    // Fields below were introduced in SDK version 0x0000014
+
+    NGSDK_NGX_LoggingInfo LoggingInfo;
+} NVSDK_NGX_FeatureCommonInfo;
+
+typedef enum NVSDK_NGX_Resource_VK_Type
+{
+    NVSDK_NGX_RESOURCE_VK_TYPE_VK_IMAGEVIEW,
+    NVSDK_NGX_RESOURCE_VK_TYPE_VK_BUFFER
+} NVSDK_NGX_Resource_VK_Type;
+
+typedef enum NVSDK_NGX_Opt_Level
+{
+    NVSDK_NGX_OPT_LEVEL_UNDEFINED = 0,
+    NVSDK_NGX_OPT_LEVEL_DEBUG = 20,
+    NVSDK_NGX_OPT_LEVEL_DEVELOP = 30,
+    NVSDK_NGX_OPT_LEVEL_RELEASE = 40
+} NVSDK_NGX_Opt_Level;
+
+typedef enum NVSDK_NGX_EngineType
+{
+    NVSDK_NGX_ENGINE_TYPE_CUSTOM = 0,
+    NVSDK_NGX_ENGINE_TYPE_UNREAL,
+    NVSDK_NGX_ENGINE_TYPE_UNITY,
+    NVSDK_NGX_ENGINE_TYPE_OMNIVERSE,
+    NVSDK_NGX_ENGINE_COUNT
+} NVSDK_NGX_EngineType;
+
+// Read-only parameters provided by NGX
+#define NVSDK_NGX_EParameter_Reserved00                           "#\x00"
+#define NVSDK_NGX_EParameter_SuperSampling_Available              "#\x01"
+#define NVSDK_NGX_EParameter_InPainting_Available                 "#\x02"
+#define NVSDK_NGX_EParameter_ImageSuperResolution_Available       "#\x03"
+#define NVSDK_NGX_EParameter_SlowMotion_Available                 "#\x04"
+#define NVSDK_NGX_EParameter_VideoSuperResolution_Available       "#\x05"
+#define NVSDK_NGX_EParameter_Reserved06                           "#\x06"
+#define NVSDK_NGX_EParameter_Reserved07                           "#\x07"
+#define NVSDK_NGX_EParameter_Reserved08                           "#\x08"
+#define NVSDK_NGX_EParameter_ImageSignalProcessing_Available      "#\x09"
+#define NVSDK_NGX_EParameter_ImageSuperResolution_ScaleFactor_2_1 "#\x0a"
+#define NVSDK_NGX_EParameter_ImageSuperResolution_ScaleFactor_3_1 "#\x0b"
+#define NVSDK_NGX_EParameter_ImageSuperResolution_ScaleFactor_3_2 "#\x0c"
+#define NVSDK_NGX_EParameter_ImageSuperResolution_ScaleFactor_4_3 "#\x0d"
+#define NVSDK_NGX_EParameter_NumFrames           "#\x0e"
+#define NVSDK_NGX_EParameter_Scale               "#\x0f"
+#define NVSDK_NGX_EParameter_Width               "#\x10"
+#define NVSDK_NGX_EParameter_Height              "#\x11"
+#define NVSDK_NGX_EParameter_OutWidth            "#\x12"
+#define NVSDK_NGX_EParameter_OutHeight           "#\x13"
+#define NVSDK_NGX_EParameter_Sharpness           "#\x14"
+#define NVSDK_NGX_EParameter_Scratch             "#\x15"
+#define NVSDK_NGX_EParameter_Scratch_SizeInBytes "#\x16"
+#define NVSDK_NGX_EParameter_EvaluationNode      "#\x17" // valid since API 0x13 (replaced a deprecated param)
+#define NVSDK_NGX_EParameter_Input1              "#\x18"
+#define NVSDK_NGX_EParameter_Input1_Format       "#\x19"
+#define NVSDK_NGX_EParameter_Input1_SizeInBytes  "#\x1a"
+#define NVSDK_NGX_EParameter_Input2              "#\x1b"
+#define NVSDK_NGX_EParameter_Input2_Format       "#\x1c"
+#define NVSDK_NGX_EParameter_Input2_SizeInBytes  "#\x1d"
+#define NVSDK_NGX_EParameter_Color               "#\x1e"
+#define NVSDK_NGX_EParameter_Color_Format        "#\x1f"
+#define NVSDK_NGX_EParameter_Color_SizeInBytes   "#\x20"
+#define NVSDK_NGX_EParameter_Albedo              "#\x21"
+#define NVSDK_NGX_EParameter_Output              "#\x22"
+#define NVSDK_NGX_EParameter_Output_Format       "#\x23"
+#define NVSDK_NGX_EParameter_Output_SizeInBytes  "#\x24"
+#define NVSDK_NGX_EParameter_Reset               "#\x25"
+#define NVSDK_NGX_EParameter_BlendFactor         "#\x26"
+#define NVSDK_NGX_EParameter_MotionVectors       "#\x27"
+#define NVSDK_NGX_EParameter_Rect_X              "#\x28"
+#define NVSDK_NGX_EParameter_Rect_Y              "#\x29"
+#define NVSDK_NGX_EParameter_Rect_W              "#\x2a"
+#define NVSDK_NGX_EParameter_Rect_H              "#\x2b"
+#define NVSDK_NGX_EParameter_MV_Scale_X          "#\x2c"
+#define NVSDK_NGX_EParameter_MV_Scale_Y          "#\x2d"
+#define NVSDK_NGX_EParameter_Model               "#\x2e"
+#define NVSDK_NGX_EParameter_Format              "#\x2f"
+#define NVSDK_NGX_EParameter_SizeInBytes         "#\x30"
+#define NVSDK_NGX_EParameter_ResourceAllocCallback      "#\x31"
+#define NVSDK_NGX_EParameter_BufferAllocCallback        "#\x32"
+#define NVSDK_NGX_EParameter_Tex2DAllocCallback         "#\x33"
+#define NVSDK_NGX_EParameter_ResourceReleaseCallback    "#\x34"
+#define NVSDK_NGX_EParameter_CreationNodeMask           "#\x35"
+#define NVSDK_NGX_EParameter_VisibilityNodeMask         "#\x36"
+#define NVSDK_NGX_EParameter_PreviousOutput             "#\x37"
+#define NVSDK_NGX_EParameter_MV_Offset_X                 "#\x38"
+#define NVSDK_NGX_EParameter_MV_Offset_Y                 "#\x39"
+#define NVSDK_NGX_EParameter_Hint_UseFireflySwatter      "#\x3a"
+#define NVSDK_NGX_EParameter_Resource_Width              "#\x3b"
+#define NVSDK_NGX_EParameter_Resource_Height             "#\x3c"
+#define NVSDK_NGX_EParameter_Depth                       "#\x3d"
+#define NVSDK_NGX_EParameter_DLSSOptimalSettingsCallback "#\x3e"
+#define NVSDK_NGX_EParameter_PerfQualityValue            "#\x3f"
+#define NVSDK_NGX_EParameter_RTXValue                    "#\x40"
+#define NVSDK_NGX_EParameter_DLSSMode                    "#\x41"
+#define NVSDK_NGX_EParameter_DeepResolve_Available       "#\x42"
+#define NVSDK_NGX_EParameter_Deprecated_43               "#\x43"
+#define NVSDK_NGX_EParameter_OptLevel                    "#\x44"
+#define NVSDK_NGX_EParameter_IsDevSnippetBranch          "#\x45"
+
+#define NVSDK_NGX_Parameter_OptLevel "Snippet.OptLevel"
+#define NVSDK_NGX_Parameter_IsDevSnippetBranch "Snippet.IsDevBranch"
+#define NVSDK_NGX_Parameter_SuperSampling_ScaleFactor  "SuperSampling.ScaleFactor"
+#define NVSDK_NGX_Parameter_ImageSignalProcessing_ScaleFactor "ImageSignalProcessing.ScaleFactor"
+#define NVSDK_NGX_Parameter_SuperSampling_Available "SuperSampling.Available"
+#define NVSDK_NGX_Parameter_InPainting_Available "InPainting.Available"
+#define NVSDK_NGX_Parameter_ImageSuperResolution_Available "ImageSuperResolution.Available"
+#define NVSDK_NGX_Parameter_SlowMotion_Available "SlowMotion.Available"
+#define NVSDK_NGX_Parameter_VideoSuperResolution_Available "VideoSuperResolution.Available"
+#define NVSDK_NGX_Parameter_ImageSignalProcessing_Available "ImageSignalProcessing.Available"
+#define NVSDK_NGX_Parameter_DeepResolve_Available "DeepResolve.Available"
+#define NVSDK_NGX_Parameter_SuperSampling_NeedsUpdatedDriver            "SuperSampling.NeedsUpdatedDriver"
+#define NVSDK_NGX_Parameter_InPainting_NeedsUpdatedDriver               "InPainting.NeedsUpdatedDriver"
+#define NVSDK_NGX_Parameter_ImageSuperResolution_NeedsUpdatedDriver     "ImageSuperResolution.NeedsUpdatedDriver"
+#define NVSDK_NGX_Parameter_SlowMotion_NeedsUpdatedDriver               "SlowMotion.NeedsUpdatedDriver"
+#define NVSDK_NGX_Parameter_VideoSuperResolution_NeedsUpdatedDriver     "VideoSuperResolution.NeedsUpdatedDriver"
+#define NVSDK_NGX_Parameter_ImageSignalProcessing_NeedsUpdatedDriver    "ImageSignalProcessing.NeedsUpdatedDriver"
+#define NVSDK_NGX_Parameter_DeepResolve_NeedsUpdatedDriver              "DeepResolve.NeedsUpdatedDriver"
+#define NVSDK_NGX_Parameter_FrameInterpolation_NeedsUpdatedDriver       "FrameInterpolation.NeedsUpdatedDriver"
+#define NVSDK_NGX_Parameter_SuperSampling_MinDriverVersionMajor         "SuperSampling.MinDriverVersionMajor"
+#define NVSDK_NGX_Parameter_InPainting_MinDriverVersionMajor            "InPainting.MinDriverVersionMajor"
+#define NVSDK_NGX_Parameter_ImageSuperResolution_MinDriverVersionMajor  "ImageSuperResolution.MinDriverVersionMajor"
+#define NVSDK_NGX_Parameter_SlowMotion_MinDriverVersionMajor            "SlowMotion.MinDriverVersionMajor"
+#define NVSDK_NGX_Parameter_VideoSuperResolution_MinDriverVersionMajor  "VideoSuperResolution.MinDriverVersionMajor"
+#define NVSDK_NGX_Parameter_ImageSignalProcessing_MinDriverVersionMajor "ImageSignalProcessing.MinDriverVersionMajor"
+#define NVSDK_NGX_Parameter_DeepResolve_MinDriverVersionMajor           "DeepResolve.MinDriverVersionMajor"
+#define NVSDK_NGX_Parameter_FrameInterpolation_MinDriverVersionMajor    "FrameInterpolation.MinDriverVersionMajor"
+#define NVSDK_NGX_Parameter_SuperSampling_MinDriverVersionMinor         "SuperSampling.MinDriverVersionMinor"
+#define NVSDK_NGX_Parameter_InPainting_MinDriverVersionMinor            "InPainting.MinDriverVersionMinor"
+#define NVSDK_NGX_Parameter_ImageSuperResolution_MinDriverVersionMinor  "ImageSuperResolution.MinDriverVersionMinor"
+#define NVSDK_NGX_Parameter_SlowMotion_MinDriverVersionMinor            "SlowMotion.MinDriverVersionMinor"
+#define NVSDK_NGX_Parameter_VideoSuperResolution_MinDriverVersionMinor  "VideoSuperResolution.MinDriverVersionMinor"
+#define NVSDK_NGX_Parameter_ImageSignalProcessing_MinDriverVersionMinor "ImageSignalProcessing.MinDriverVersionMinor"
+#define NVSDK_NGX_Parameter_DeepResolve_MinDriverVersionMinor           "DeepResolve.MinDriverVersionMinor"
+#define NVSDK_NGX_Parameter_SuperSampling_FeatureInitResult             "SuperSampling.FeatureInitResult"
+#define NVSDK_NGX_Parameter_InPainting_FeatureInitResult                "InPainting.FeatureInitResult"
+#define NVSDK_NGX_Parameter_ImageSuperResolution_FeatureInitResult      "ImageSuperResolution.FeatureInitResult"
+#define NVSDK_NGX_Parameter_SlowMotion_FeatureInitResult                "SlowMotion.FeatureInitResult"
+#define NVSDK_NGX_Parameter_VideoSuperResolution_FeatureInitResult      "VideoSuperResolution.FeatureInitResult"
+#define NVSDK_NGX_Parameter_ImageSignalProcessing_FeatureInitResult     "ImageSignalProcessing.FeatureInitResult"
+#define NVSDK_NGX_Parameter_DeepResolve_FeatureInitResult               "DeepResolve.FeatureInitResult"
+#define NVSDK_NGX_Parameter_FrameInterpolation_FeatureInitResult        "FrameInterpolation.FeatureInitResult"
+#define NVSDK_NGX_Parameter_ImageSuperResolution_ScaleFactor_2_1 "ImageSuperResolution.ScaleFactor.2.1"
+#define NVSDK_NGX_Parameter_ImageSuperResolution_ScaleFactor_3_1 "ImageSuperResolution.ScaleFactor.3.1"
+#define NVSDK_NGX_Parameter_ImageSuperResolution_ScaleFactor_3_2 "ImageSuperResolution.ScaleFactor.3.2"
+#define NVSDK_NGX_Parameter_ImageSuperResolution_ScaleFactor_4_3 "ImageSuperResolution.ScaleFactor.4.3"
+#define NVSDK_NGX_Parameter_NumFrames "NumFrames"
+#define NVSDK_NGX_Parameter_Scale "Scale"
+#define NVSDK_NGX_Parameter_Width "Width"
+#define NVSDK_NGX_Parameter_Height "Height"
+#define NVSDK_NGX_Parameter_OutWidth "OutWidth"
+#define NVSDK_NGX_Parameter_OutHeight "OutHeight"
+#define NVSDK_NGX_Parameter_Sharpness "Sharpness"
+#define NVSDK_NGX_Parameter_Scratch "Scratch"
+#define NVSDK_NGX_Parameter_Scratch_SizeInBytes "Scratch.SizeInBytes"
+#define NVSDK_NGX_Parameter_Input1 "Input1"
+#define NVSDK_NGX_Parameter_Input1_Format "Input1.Format"
+#define NVSDK_NGX_Parameter_Input1_SizeInBytes "Input1.SizeInBytes"
+#define NVSDK_NGX_Parameter_Input2 "Input2"
+#define NVSDK_NGX_Parameter_Input2_Format "Input2.Format"
+#define NVSDK_NGX_Parameter_Input2_SizeInBytes "Input2.SizeInBytes"
+#define NVSDK_NGX_Parameter_Color "Color"
+#define NVSDK_NGX_Parameter_Color_Format "Color.Format"
+#define NVSDK_NGX_Parameter_Color_SizeInBytes "Color.SizeInBytes"
+#define NVSDK_NGX_Parameter_FI_Color1 "Color1"
+#define NVSDK_NGX_Parameter_FI_Color2 "Color2"
+#define NVSDK_NGX_Parameter_Albedo "Albedo"
+#define NVSDK_NGX_Parameter_Output "Output"
+#define NVSDK_NGX_Parameter_Output_SizeInBytes "Output.SizeInBytes"
+#define NVSDK_NGX_Parameter_FI_Output1 "Output1"
+#define NVSDK_NGX_Parameter_FI_Output2 "Output2"
+#define NVSDK_NGX_Parameter_FI_Output3 "Output3"
+#define NVSDK_NGX_Parameter_Reset "Reset"
+#define NVSDK_NGX_Parameter_BlendFactor "BlendFactor"
+#define NVSDK_NGX_Parameter_MotionVectors "MotionVectors"
+#define NVSDK_NGX_Parameter_FI_MotionVectors1 "MotionVectors1"
+#define NVSDK_NGX_Parameter_FI_MotionVectors2 "MotionVectors2"
+#define NVSDK_NGX_Parameter_Rect_X "Rect.X"
+#define NVSDK_NGX_Parameter_Rect_Y "Rect.Y"
+#define NVSDK_NGX_Parameter_Rect_W "Rect.W"
+#define NVSDK_NGX_Parameter_Rect_H "Rect.H"
+#define NVSDK_NGX_Parameter_MV_Scale_X "MV.Scale.X"
+#define NVSDK_NGX_Parameter_MV_Scale_Y "MV.Scale.Y"
+#define NVSDK_NGX_Parameter_Model "Model"
+#define NVSDK_NGX_Parameter_Format "Format"
+#define NVSDK_NGX_Parameter_SizeInBytes "SizeInBytes"
+#define NVSDK_NGX_Parameter_ResourceAllocCallback      "ResourceAllocCallback"
+#define NVSDK_NGX_Parameter_BufferAllocCallback        "BufferAllocCallback"
+#define NVSDK_NGX_Parameter_Tex2DAllocCallback         "Tex2DAllocCallback"
+#define NVSDK_NGX_Parameter_ResourceReleaseCallback    "ResourceReleaseCallback"
+#define NVSDK_NGX_Parameter_CreationNodeMask           "CreationNodeMask"
+#define NVSDK_NGX_Parameter_VisibilityNodeMask         "VisibilityNodeMask"
+#define NVSDK_NGX_Parameter_MV_Offset_X "MV.Offset.X"
+#define NVSDK_NGX_Parameter_MV_Offset_Y "MV.Offset.Y"
+#define NVSDK_NGX_Parameter_Hint_UseFireflySwatter "Hint.UseFireflySwatter"
+#define NVSDK_NGX_Parameter_Resource_Width "ResourceWidth"
+#define NVSDK_NGX_Parameter_Resource_Height "ResourceHeight"
+#define NVSDK_NGX_Parameter_Resource_OutWidth "ResourceOutWidth"
+#define NVSDK_NGX_Parameter_Resource_OutHeight "ResourceOutHeight"
+#define NVSDK_NGX_Parameter_Depth "Depth"
+#define NVSDK_NGX_Parameter_FI_Depth1 "Depth1"
+#define NVSDK_NGX_Parameter_FI_Depth2 "Depth2"
+#define NVSDK_NGX_Parameter_DLSSOptimalSettingsCallback    "DLSSOptimalSettingsCallback"
+#define NVSDK_NGX_Parameter_DLSSGetStatsCallback    "DLSSGetStatsCallback"
+#define NVSDK_NGX_Parameter_PerfQualityValue    "PerfQualityValue"
+#define NVSDK_NGX_Parameter_RTXValue    "RTXValue"
+#define NVSDK_NGX_Parameter_DLSSMode    "DLSSMode"
+#define NVSDK_NGX_Parameter_FI_Mode     "FIMode"
+#define NVSDK_NGX_Parameter_FI_OF_Preset    "FIOFPreset"
+#define NVSDK_NGX_Parameter_FI_OF_GridSize  "FIOFGridSize"
+#define NVSDK_NGX_Parameter_Jitter_Offset_X     "Jitter.Offset.X"
+#define NVSDK_NGX_Parameter_Jitter_Offset_Y     "Jitter.Offset.Y"
+#define NVSDK_NGX_Parameter_Denoise "Denoise"
+#define NVSDK_NGX_Parameter_TransparencyMask "TransparencyMask"
+#define NVSDK_NGX_Parameter_ExposureTexture   "ExposureTexture" // a 1x1 texture containing the final exposure scale
+#define NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags "DLSS.Feature.Create.Flags"
+#define NVSDK_NGX_Parameter_DLSS_Checkerboard_Jitter_Hack "DLSS.Checkerboard.Jitter.Hack"
+#define NVSDK_NGX_Parameter_GBuffer_Normals "GBuffer.Normals"
+#define NVSDK_NGX_Parameter_GBuffer_Albedo "GBuffer.Albedo"
+#define NVSDK_NGX_Parameter_GBuffer_Roughness "GBuffer.Roughness"
+#define NVSDK_NGX_Parameter_GBuffer_DiffuseAlbedo "GBuffer.DiffuseAlbedo"
+#define NVSDK_NGX_Parameter_GBuffer_SpecularAlbedo "GBuffer.SpecularAlbedo"
+#define NVSDK_NGX_Parameter_GBuffer_IndirectAlbedo "GBuffer.IndirectAlbedo"
+#define NVSDK_NGX_Parameter_GBuffer_SpecularMvec "GBuffer.SpecularMvec"
+#define NVSDK_NGX_Parameter_GBuffer_DisocclusionMask "GBuffer.DisocclusionMask"
+#define NVSDK_NGX_Parameter_GBuffer_Metallic "GBuffer.Metallic"
+#define NVSDK_NGX_Parameter_GBuffer_Specular "GBuffer.Specular"
+#define NVSDK_NGX_Parameter_GBuffer_Subsurface "GBuffer.Subsurface"
+#define NVSDK_NGX_Parameter_GBuffer_Normals "GBuffer.Normals"
+#define NVSDK_NGX_Parameter_GBuffer_ShadingModelId "GBuffer.ShadingModelId"
+#define NVSDK_NGX_Parameter_GBuffer_MaterialId "GBuffer.MaterialId"
+#define NVSDK_NGX_Parameter_GBuffer_Atrrib_8 "GBuffer.Attrib.8"
+#define NVSDK_NGX_Parameter_GBuffer_Atrrib_9 "GBuffer.Attrib.9"
+#define NVSDK_NGX_Parameter_GBuffer_Atrrib_10 "GBuffer.Attrib.10"
+#define NVSDK_NGX_Parameter_GBuffer_Atrrib_11 "GBuffer.Attrib.11"
+#define NVSDK_NGX_Parameter_GBuffer_Atrrib_12 "GBuffer.Attrib.12"
+#define NVSDK_NGX_Parameter_GBuffer_Atrrib_13 "GBuffer.Attrib.13"
+#define NVSDK_NGX_Parameter_GBuffer_Atrrib_14 "GBuffer.Attrib.14"
+#define NVSDK_NGX_Parameter_GBuffer_Atrrib_15 "GBuffer.Attrib.15"
+#define NVSDK_NGX_Parameter_TonemapperType "TonemapperType"
+#define NVSDK_NGX_Parameter_FreeMemOnReleaseFeature "FreeMemOnReleaseFeature"
+#define NVSDK_NGX_Parameter_MotionVectors3D "MotionVectors3D"
+#define NVSDK_NGX_Parameter_IsParticleMask "IsParticleMask"
+#define NVSDK_NGX_Parameter_AnimatedTextureMask "AnimatedTextureMask"
+#define NVSDK_NGX_Parameter_DepthHighRes "DepthHighRes"
+#define NVSDK_NGX_Parameter_Position_ViewSpace "Position.ViewSpace"
+#define NVSDK_NGX_Parameter_FrameTimeDeltaInMsec "FrameTimeDeltaInMsec"
+#define NVSDK_NGX_Parameter_RayTracingHitDistance "RayTracingHitDistance"
+#define NVSDK_NGX_Parameter_MotionVectorsReflection "MotionVectorsReflection"
+#define NVSDK_NGX_Parameter_DLSS_Enable_Output_Subrects "DLSS.Enable.Output.Subrects"
+#define NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X "DLSS.Input.Color.Subrect.Base.X"
+#define NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y "DLSS.Input.Color.Subrect.Base.Y"
+#define NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X "DLSS.Input.Depth.Subrect.Base.X"
+#define NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_Y "DLSS.Input.Depth.Subrect.Base.Y"
+#define NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_X "DLSS.Input.MV.Subrect.Base.X"
+#define NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_Y "DLSS.Input.MV.Subrect.Base.Y"
+#define NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_X "DLSS.Input.Translucency.Subrect.Base.X"
+#define NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_Y "DLSS.Input.Translucency.Subrect.Base.Y"
+#define NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_X "DLSS.Output.Subrect.Base.X"
+#define NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_Y "DLSS.Output.Subrect.Base.Y"
+#define NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width  "DLSS.Render.Subrect.Dimensions.Width"
+#define NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height "DLSS.Render.Subrect.Dimensions.Height"
+#define NVSDK_NGX_Parameter_DLSS_Pre_Exposure "DLSS.Pre.Exposure"
+#define NVSDK_NGX_Parameter_DLSS_Exposure_Scale "DLSS.Exposure.Scale"
+#define NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask          "DLSS.Input.Bias.Current.Color.Mask"
+#define NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_X "DLSS.Input.Bias.Current.Color.Subrect.Base.X"
+#define NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_Y "DLSS.Input.Bias.Current.Color.Subrect.Base.Y"
+#define NVSDK_NGX_Parameter_DLSS_Indicator_Invert_Y_Axis          "DLSS.Indicator.Invert.Y.Axis"
+#define NVSDK_NGX_Parameter_DLSS_Indicator_Invert_X_Axis          "DLSS.Indicator.Invert.X.Axis"
+
+#define NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Max_Render_Width     "DLSS.Get.Dynamic.Max.Render.Width"
+#define NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Max_Render_Height    "DLSS.Get.Dynamic.Max.Render.Height"
+#define NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Min_Render_Width     "DLSS.Get.Dynamic.Min.Render.Width"
+#define NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Min_Render_Height    "DLSS.Get.Dynamic.Min.Render.Height"
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif

+ 630 - 0
ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_helpers.h

@@ -0,0 +1,630 @@
+/*
+* Copyright (c) 2018 NVIDIA CORPORATION.  All rights reserved.
+*
+* NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+* rights in and to this software, related documentation and any modifications thereto.
+* Any use, reproduction, disclosure or distribution of this software and related
+* documentation without an express license agreement from NVIDIA Corporation is strictly
+* prohibited.
+*
+* TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS*
+* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
+* INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
+* SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT
+* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF
+* BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
+* INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGES.
+*/
+
+#ifndef NVSDK_NGX_HELPERS_H
+#define NVSDK_NGX_HELPERS_H
+#pragma once
+
+#include "nvsdk_ngx.h"
+#include "nvsdk_ngx_defs.h"
+
+typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_DLSS_GetStatsCallback)(NVSDK_NGX_Parameter *InParams);
+
+static inline NVSDK_NGX_Result NGX_DLSS_GET_STATS_2(
+    NVSDK_NGX_Parameter *pInParams,
+    unsigned long long *pVRAMAllocatedBytes,
+    unsigned int *pOptLevel, unsigned int *IsDevSnippetBranch)
+{
+    void *Callback = NULL;
+    NVSDK_NGX_Parameter_GetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSGetStatsCallback, &Callback);
+    if (!Callback)
+    {
+        // Possible reasons for this:
+        // - Installed DLSS is out of date and does not support the feature we need
+        // - You used NVSDK_NGX_AllocateParameters() for creating InParams. Try using NVSDK_NGX_GetCapabilityParameters() instead
+        return NVSDK_NGX_Result_FAIL_OutOfDate;
+    }
+
+    NVSDK_NGX_Result Res = NVSDK_NGX_Result_Success;
+    PFN_NVSDK_NGX_DLSS_GetStatsCallback PFNCallback = (PFN_NVSDK_NGX_DLSS_GetStatsCallback)Callback;
+    Res = PFNCallback(pInParams);
+    if (NVSDK_NGX_FAILED(Res))
+    {
+        return Res;
+    }
+    NVSDK_NGX_Parameter_GetULL(pInParams, NVSDK_NGX_Parameter_SizeInBytes, pVRAMAllocatedBytes);
+    NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_EParameter_OptLevel, pOptLevel);
+    NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_EParameter_IsDevSnippetBranch, IsDevSnippetBranch);
+    return Res;
+}
+
+static inline NVSDK_NGX_Result NGX_DLSS_GET_STATS_1(
+    NVSDK_NGX_Parameter *pInParams,
+    unsigned long long *pVRAMAllocatedBytes,
+    unsigned int *pOptLevel)
+{
+    unsigned int dummy = 0;
+    return NGX_DLSS_GET_STATS_2(pInParams, pVRAMAllocatedBytes, pOptLevel, &dummy);
+}
+
+static inline NVSDK_NGX_Result NGX_DLSS_GET_STATS(
+    NVSDK_NGX_Parameter *pInParams,
+    unsigned long long *pVRAMAllocatedBytes)
+{
+    unsigned int dummy = 0;
+    return NGX_DLSS_GET_STATS_2(pInParams, pVRAMAllocatedBytes, &dummy, &dummy);
+}
+
+typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_DLSS_GetOptimalSettingsCallback)(NVSDK_NGX_Parameter *InParams);
+
+static inline NVSDK_NGX_Result NGX_DLSS_GET_OPTIMAL_SETTINGS(
+    NVSDK_NGX_Parameter *pInParams,
+    unsigned int InUserSelectedWidth,
+    unsigned int InUserSelectedHeight,
+    NVSDK_NGX_PerfQuality_Value InPerfQualityValue,
+    unsigned int *pOutRenderOptimalWidth,
+    unsigned int *pOutRenderOptimalHeight,
+    unsigned int *pOutRenderMaxWidth,
+    unsigned int *pOutRenderMaxHeight,
+    unsigned int *pOutRenderMinWidth,
+    unsigned int *pOutRenderMinHeight,
+    float *pOutSharpness)
+{
+    void *Callback = NULL;
+    NVSDK_NGX_Parameter_GetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSOptimalSettingsCallback, &Callback);
+    if (!Callback)
+    {
+        // Possible reasons for this:
+        // - Installed DLSS is out of date and does not support the feature we need
+        // - You used NVSDK_NGX_AllocateParameters() for creating InParams. Try using NVSDK_NGX_GetCapabilityParameters() instead
+        return NVSDK_NGX_Result_FAIL_OutOfDate;
+    }
+
+    // These are selections made by user in UI
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, InUserSelectedWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, InUserSelectedHeight);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, InPerfQualityValue);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_RTXValue, false); // Some older DLSS dlls still expect this value to be set
+
+    NVSDK_NGX_Result Res = NVSDK_NGX_Result_Success;
+    PFN_NVSDK_NGX_DLSS_GetOptimalSettingsCallback PFNCallback = (PFN_NVSDK_NGX_DLSS_GetOptimalSettingsCallback)Callback;
+    Res = PFNCallback(pInParams);
+    if (NVSDK_NGX_FAILED(Res))
+    {
+        return Res;
+    }
+    NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pOutRenderOptimalWidth);
+    NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pOutRenderOptimalHeight);
+    // If we have an older DLSS Dll those might need to be set to the optimal dimensions instead
+    *pOutRenderMaxWidth  = *pOutRenderOptimalWidth;
+    *pOutRenderMaxHeight = *pOutRenderOptimalHeight;
+    *pOutRenderMinWidth  = *pOutRenderOptimalWidth;
+    *pOutRenderMinHeight = *pOutRenderOptimalHeight;
+    NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Max_Render_Width,  pOutRenderMaxWidth);
+    NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Max_Render_Height, pOutRenderMaxHeight);
+    NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Min_Render_Width,  pOutRenderMinWidth);
+    NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Min_Render_Height, pOutRenderMinHeight);
+    NVSDK_NGX_Parameter_GetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pOutSharpness);
+    return Res;
+}
+
+/*** D3D11 ***/
+typedef struct NVSDK_NGX_D3D11_Feature_Eval_Params
+{
+    ID3D11Resource*  pInColor;
+    ID3D11Resource*  pInOutput;
+    /*** OPTIONAL for DLSS ***/
+    float       InSharpness;
+} NVSDK_NGX_D3D11_Feature_Eval_Params;
+
+typedef struct NVSDK_NGX_CUDA_Feature_Eval_Params
+{
+    CUtexObject* pInColor;
+    CUtexObject* pInOutput;
+    /*** OPTIONAL for DLSS ***/
+    float       InSharpness;
+} NVSDK_NGX_CUDA_Feature_Eval_Params;
+
+typedef struct NVSDK_NGX_D3D11_GBuffer
+{
+    ID3D11Resource* pInAttrib[NVSDK_NGX_GBUFFERTYPE_NUM];
+} NVSDK_NGX_D3D11_GBuffer;
+
+typedef struct NVSDK_NGX_D3D11_DLSS_Eval_Params
+{
+    NVSDK_NGX_D3D11_Feature_Eval_Params Feature;
+    ID3D11Resource*                     pInDepth;
+    ID3D11Resource*                     pInMotionVectors;
+    float                               InJitterOffsetX;     /* Jitter offset must be in input/render pixel space */
+    float                               InJitterOffsetY;
+    NVSDK_NGX_Dimensions                InRenderSubrectDimensions;
+    /*** OPTIONAL - leave to 0/0.0f if unused ***/
+    int                                 InReset;             /* Set to 1 when scene changes completely (new level etc) */
+    float                               InMVScaleX;          /* If MVs need custom scaling to convert to pixel space */
+    float                               InMVScaleY;
+    ID3D11Resource*                     pInTransparencyMask; /* Unused/Reserved for future use */
+    ID3D11Resource*                     pInExposureTexture;
+    ID3D11Resource*                     pInBiasCurrentColorMask;
+    NVSDK_NGX_Coordinates               InColorSubrectBase;
+    NVSDK_NGX_Coordinates               InDepthSubrectBase;
+    NVSDK_NGX_Coordinates               InMVSubrectBase;
+    NVSDK_NGX_Coordinates               InTranslucencySubrectBase;
+    NVSDK_NGX_Coordinates               InBiasCurrentColorSubrectBase;
+    NVSDK_NGX_Coordinates               InOutputSubrectBase;
+    float                               InPreExposure;
+    float                               InExposureScale;
+    int                                 InIndicatorInvertXAxis;
+    int                                 InIndicatorInvertYAxis;
+    /*** OPTIONAL - only for research purposes ***/
+    NVSDK_NGX_D3D11_GBuffer             GBufferSurface;
+    NVSDK_NGX_ToneMapperType            InToneMapperType;
+    ID3D11Resource*                     pInMotionVectors3D;
+    ID3D11Resource*                     pInIsParticleMask; /* to identify which pixels contains particles, essentially that are not drawn as part of base pass */
+    ID3D11Resource*                     pInAnimatedTextureMask; /* a binary mask covering pixels occupied by animated textures */
+    ID3D11Resource*                     pInDepthHighRes;
+    ID3D11Resource*                     pInPositionViewSpace;
+    float                               InFrameTimeDeltaInMsec; /* helps in determining the amount to denoise or anti-alias based on the speed of the object from motion vector magnitudes and fps as determined by this delta */
+    ID3D11Resource*                     pInRayTracingHitDistance; /* for each effect - approximation to the amount of noise in a ray-traced color */
+    ID3D11Resource*                     pInMotionVectorsReflections; /* motion vectors of reflected objects like for mirrored surfaces */
+} NVSDK_NGX_D3D11_DLSS_Eval_Params;
+
+typedef struct NVSDK_NGX_D3D11_DLISP_Eval_Params
+{
+    NVSDK_NGX_D3D11_Feature_Eval_Params Feature;
+    /*** OPTIONAL - leave to 0/0.0f if unused  ***/
+    unsigned int                    InRectX;
+    unsigned int                    InRectY;
+    unsigned int                    InRectW;
+    unsigned int                    InRectH;
+    float                           InDenoise;
+} NVSDK_NGX_D3D11_DLISP_Eval_Params;
+
+typedef struct NVSDK_NGX_CUDA_DLISP_Eval_Params
+{
+    NVSDK_NGX_CUDA_Feature_Eval_Params Feature;
+    /*** OPTIONAL - leave to 0/0.0f if unused  ***/
+    unsigned int                    InRectX;
+    unsigned int                    InRectY;
+    unsigned int                    InRectW;
+    unsigned int                    InRectH;
+    float                           InDenoise;
+} NVSDK_NGX_CUDA_DLISP_Eval_Params;
+
+static inline NVSDK_NGX_Result NGX_D3D11_CREATE_DLSS_EXT(
+    ID3D11DeviceContext *pInCtx,
+    NVSDK_NGX_Handle **ppOutHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_DLSS_Create_Params *pInDlssCreateParams)
+{
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlssCreateParams->Feature.InWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlssCreateParams->Feature.InHeight);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pInDlssCreateParams->Feature.InTargetWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pInDlssCreateParams->Feature.InTargetHeight);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pInDlssCreateParams->Feature.InPerfQualityValue);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags, pInDlssCreateParams->InFeatureCreateFlags);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Enable_Output_Subrects, pInDlssCreateParams->InEnableOutputSubrects ? 1 : 0);
+
+    return NVSDK_NGX_D3D11_CreateFeature(pInCtx, NVSDK_NGX_Feature_SuperSampling, pInParams, ppOutHandle);
+}
+
+static inline NVSDK_NGX_Result NGX_D3D11_EVALUATE_DLSS_EXT(
+    ID3D11DeviceContext *pInCtx,
+    NVSDK_NGX_Handle *pInHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_D3D11_DLSS_Eval_Params *pInDlssEvalParams)
+{
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Color, pInDlssEvalParams->Feature.pInColor);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Output, pInDlssEvalParams->Feature.pInOutput);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Depth, pInDlssEvalParams->pInDepth);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_MotionVectors, pInDlssEvalParams->pInMotionVectors);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_X, pInDlssEvalParams->InJitterOffsetX);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_Y, pInDlssEvalParams->InJitterOffsetY);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pInDlssEvalParams->Feature.InSharpness);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_Reset, pInDlssEvalParams->InReset);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_X, pInDlssEvalParams->InMVScaleX == 0.0f ? 1.0f : pInDlssEvalParams->InMVScaleX);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_Y, pInDlssEvalParams->InMVScaleY == 0.0f ? 1.0f : pInDlssEvalParams->InMVScaleY);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_TransparencyMask, pInDlssEvalParams->pInTransparencyMask);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_ExposureTexture, pInDlssEvalParams->pInExposureTexture);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, pInDlssEvalParams->pInBiasCurrentColorMask);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Albedo, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ALBEDO]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Roughness, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ROUGHNESS]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Metallic, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_METALLIC]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Specular, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SPECULAR]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Subsurface, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SUBSURFACE]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Normals, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_NORMALS]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_ShadingModelId, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SHADINGMODELID]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_MaterialId, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_MATERIALID]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_8, pInDlssEvalParams->GBufferSurface.pInAttrib[8]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_9, pInDlssEvalParams->GBufferSurface.pInAttrib[9]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_10, pInDlssEvalParams->GBufferSurface.pInAttrib[10]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_11, pInDlssEvalParams->GBufferSurface.pInAttrib[11]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_12, pInDlssEvalParams->GBufferSurface.pInAttrib[12]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_13, pInDlssEvalParams->GBufferSurface.pInAttrib[13]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_14, pInDlssEvalParams->GBufferSurface.pInAttrib[14]);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_15, pInDlssEvalParams->GBufferSurface.pInAttrib[15]);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_TonemapperType, pInDlssEvalParams->InToneMapperType);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_MotionVectors3D, pInDlssEvalParams->pInMotionVectors3D);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_IsParticleMask, pInDlssEvalParams->pInIsParticleMask);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_AnimatedTextureMask, pInDlssEvalParams->pInAnimatedTextureMask);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DepthHighRes, pInDlssEvalParams->pInDepthHighRes);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Position_ViewSpace, pInDlssEvalParams->pInPositionViewSpace);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_FrameTimeDeltaInMsec, pInDlssEvalParams->InFrameTimeDeltaInMsec);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_RayTracingHitDistance, pInDlssEvalParams->pInRayTracingHitDistance);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_MotionVectorsReflection, pInDlssEvalParams->pInMotionVectorsReflections);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X, pInDlssEvalParams->InColorSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y, pInDlssEvalParams->InColorSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, pInDlssEvalParams->InDepthSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_Y, pInDlssEvalParams->InDepthSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_X, pInDlssEvalParams->InMVSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_Y, pInDlssEvalParams->InMVSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_X, pInDlssEvalParams->InTranslucencySubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_Y, pInDlssEvalParams->InTranslucencySubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_X, pInDlssEvalParams->InBiasCurrentColorSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_Y, pInDlssEvalParams->InBiasCurrentColorSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_X, pInDlssEvalParams->InOutputSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_Y, pInDlssEvalParams->InOutputSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width , pInDlssEvalParams->InRenderSubrectDimensions.Width);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height, pInDlssEvalParams->InRenderSubrectDimensions.Height);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Pre_Exposure, pInDlssEvalParams->InPreExposure == 0.0f ? 1.0f : pInDlssEvalParams->InPreExposure);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Exposure_Scale, pInDlssEvalParams->InExposureScale == 0.0f ? 1.0f : pInDlssEvalParams->InExposureScale);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_X_Axis, pInDlssEvalParams->InIndicatorInvertXAxis);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_Y_Axis, pInDlssEvalParams->InIndicatorInvertYAxis);
+
+    return NVSDK_NGX_D3D11_EvaluateFeature_C(pInCtx, pInHandle, pInParams, NULL);
+}
+
+static inline NVSDK_NGX_Result NGX_D3D11_CREATE_DLISP_EXT(
+    ID3D11DeviceContext *pInCtx,
+    NVSDK_NGX_Handle **ppOutHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_Feature_Create_Params *pDlispCreateParams)
+{
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pDlispCreateParams->InWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pDlispCreateParams->InHeight);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pDlispCreateParams->InTargetWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pDlispCreateParams->InTargetHeight);
+
+    return NVSDK_NGX_D3D11_CreateFeature(pInCtx, NVSDK_NGX_Feature_ImageSignalProcessing, pInParams, ppOutHandle);
+}
+
+static inline NVSDK_NGX_Result NGX_CUDA_CREATE_DLISP_EXT(
+    NVSDK_NGX_Handle** ppOutHandle,
+    NVSDK_NGX_Parameter* pInParams,
+    NVSDK_NGX_Feature_Create_Params* pDlispCreateParams)
+{
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pDlispCreateParams->InWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pDlispCreateParams->InHeight);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pDlispCreateParams->InTargetWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pDlispCreateParams->InTargetHeight);
+
+    return NVSDK_NGX_CUDA_CreateFeature(NVSDK_NGX_Feature_ImageSignalProcessing, pInParams, ppOutHandle);
+}
+
+static inline NVSDK_NGX_Result NGX_D3D11_EVALUATE_DLISP_EXT(
+    ID3D11DeviceContext *pInCtx,
+    NVSDK_NGX_Handle *pInHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_D3D11_DLISP_Eval_Params *pDlispEvalParams)
+{
+    if (pDlispEvalParams->Feature.InSharpness < 0.0f || pDlispEvalParams->Feature.InSharpness > 1.0f || pDlispEvalParams->InDenoise < 0.0f || pDlispEvalParams->InDenoise > 1.0f)
+    {
+        return NVSDK_NGX_Result_FAIL_InvalidParameter;
+    }
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Color, pDlispEvalParams->Feature.pInColor);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Output, pDlispEvalParams->Feature.pInOutput);
+    // Both sharpness and denoise in range [0.0f,1.0f]
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pDlispEvalParams->Feature.InSharpness);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Denoise, pDlispEvalParams->InDenoise);
+    // If input is atlas - use RECT to upscale only the required area
+    if (pDlispEvalParams->InRectW)
+    {
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_X, pDlispEvalParams->InRectX);
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_Y, pDlispEvalParams->InRectY);
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_W, pDlispEvalParams->InRectW);
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_H, pDlispEvalParams->InRectH);
+    }
+
+    return NVSDK_NGX_D3D11_EvaluateFeature_C(pInCtx, pInHandle, pInParams, NULL);
+}
+
+static inline NVSDK_NGX_Result NGX_CUDA_EVALUATE_DLISP_EXT(
+    NVSDK_NGX_Handle *pInHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_CUDA_DLISP_Eval_Params *pDlispEvalParams)
+{
+    if (pDlispEvalParams->Feature.InSharpness < 0.0f || pDlispEvalParams->Feature.InSharpness > 1.0f || pDlispEvalParams->InDenoise < 0.0f || pDlispEvalParams->InDenoise > 1.0f)
+    {
+        return NVSDK_NGX_Result_FAIL_InvalidParameter;
+    }
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Color, pDlispEvalParams->Feature.pInColor);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Output, pDlispEvalParams->Feature.pInOutput);
+    // Both sharpness and denoise in range [0.0f,1.0f]
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pDlispEvalParams->Feature.InSharpness);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Denoise, pDlispEvalParams->InDenoise);
+    // If input is atlas - use RECT to upscale only the required area
+    if (pDlispEvalParams->InRectW)
+    {
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_X, pDlispEvalParams->InRectX);
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_Y, pDlispEvalParams->InRectY);
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_W, pDlispEvalParams->InRectW);
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_H, pDlispEvalParams->InRectH);
+    }
+
+    return NVSDK_NGX_CUDA_EvaluateFeature_C(pInHandle, pInParams, NULL);
+}
+
+static inline NVSDK_NGX_Result NGX_D3D11_CREATE_DLRESOLVE_EXT(
+    ID3D11DeviceContext *pInCtx,
+    NVSDK_NGX_Handle **ppOutHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_Feature_Create_Params *pDlresolveCreateParams)
+{
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pDlresolveCreateParams->InWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pDlresolveCreateParams->InHeight);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pDlresolveCreateParams->InTargetWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pDlresolveCreateParams->InTargetHeight);
+
+    return NVSDK_NGX_D3D11_CreateFeature(pInCtx, NVSDK_NGX_Feature_DeepResolve, pInParams, ppOutHandle);
+}
+
+static inline NVSDK_NGX_Result NGX_D3D11_EVALUATE_DLRESOLVE_EXT(
+    ID3D11DeviceContext *pInCtx,
+    NVSDK_NGX_Handle *InHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_D3D11_Feature_Eval_Params *pDlresolveEvalParams)
+{
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Color, pDlresolveEvalParams->pInColor);
+    NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Output, pDlresolveEvalParams->pInOutput);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pDlresolveEvalParams->InSharpness);
+
+    return NVSDK_NGX_D3D11_EvaluateFeature_C(pInCtx, InHandle, pInParams, NULL);
+}
+
+/*** D3D12 ***/
+typedef struct NVSDK_NGX_D3D12_Feature_Eval_Params
+{
+    ID3D12Resource*  pInColor;
+    ID3D12Resource*  pInOutput;
+    /*** OPTIONAL for DLSS ***/
+    float       InSharpness;
+} NVSDK_NGX_D3D12_Feature_Eval_Params;
+
+typedef struct NVSDK_NGX_D3D12_GBuffer
+{
+    ID3D12Resource* pInAttrib[NVSDK_NGX_GBUFFERTYPE_NUM];
+} NVSDK_NGX_D3D12_GBuffer;
+
+typedef struct NVSDK_NGX_D3D12_DLSS_Eval_Params
+{
+    NVSDK_NGX_D3D12_Feature_Eval_Params Feature;
+    ID3D12Resource*                     pInDepth;
+    ID3D12Resource*                     pInMotionVectors;
+    float                               InJitterOffsetX;     /* Jitter offset must be in input/render pixel space */
+    float                               InJitterOffsetY;
+    NVSDK_NGX_Dimensions                InRenderSubrectDimensions;
+    /*** OPTIONAL - leave to 0/0.0f if unused ***/
+    int                                 InReset;             /* Set to 1 when scene changes completely (new level etc) */
+    float                               InMVScaleX;          /* If MVs need custom scaling to convert to pixel space */
+    float                               InMVScaleY;
+    ID3D12Resource*                     pInTransparencyMask; /* Unused/Reserved for future use */
+    ID3D12Resource*                     pInExposureTexture;
+    ID3D12Resource*                     pInBiasCurrentColorMask;
+    NVSDK_NGX_Coordinates               InColorSubrectBase;
+    NVSDK_NGX_Coordinates               InDepthSubrectBase;
+    NVSDK_NGX_Coordinates               InMVSubrectBase;
+    NVSDK_NGX_Coordinates               InTranslucencySubrectBase;
+    NVSDK_NGX_Coordinates               InBiasCurrentColorSubrectBase;
+    NVSDK_NGX_Coordinates               InOutputSubrectBase;
+    float                               InPreExposure;
+    float                               InExposureScale;
+    int                                 InIndicatorInvertXAxis;
+    int                                 InIndicatorInvertYAxis;
+    /*** OPTIONAL - only for research purposes ***/
+    NVSDK_NGX_D3D12_GBuffer             GBufferSurface;
+    NVSDK_NGX_ToneMapperType            InToneMapperType;
+    ID3D12Resource*                     pInMotionVectors3D;
+    ID3D12Resource*                     pInIsParticleMask; /* to identify which pixels contains particles, essentially that are not drawn as part of base pass */
+    ID3D12Resource*                     pInAnimatedTextureMask; /* a binary mask covering pixels occupied by animated textures */
+    ID3D12Resource*                     pInDepthHighRes;
+    ID3D12Resource*                     pInPositionViewSpace;
+    float                               InFrameTimeDeltaInMsec; /* helps in determining the amount to denoise or anti-alias based on the speed of the object from motion vector magnitudes and fps as determined by this delta */
+    ID3D12Resource*                     pInRayTracingHitDistance; /* for each effect - approximation to the amount of noise in a ray-traced color */
+    ID3D12Resource*                     pInMotionVectorsReflections; /* motion vectors of reflected objects like for mirrored surfaces */
+} NVSDK_NGX_D3D12_DLSS_Eval_Params;
+
+typedef struct NVSDK_NGX_D3D12_DLISP_Eval_Params
+{
+    NVSDK_NGX_D3D12_Feature_Eval_Params Feature;
+    /*** OPTIONAL ***/
+    unsigned int                        InRectX;
+    unsigned int                        InRectY;
+    unsigned int                        InRectW;
+    unsigned int                        InRectH;
+    float                               InDenoise;
+} NVSDK_NGX_D3D12_DLISP_Eval_Params;
+
+static inline NVSDK_NGX_Result NGX_D3D12_CREATE_DLSS_EXT(
+    ID3D12GraphicsCommandList *pInCmdList,
+    unsigned int InCreationNodeMask,
+    unsigned int InVisibilityNodeMask,
+    NVSDK_NGX_Handle **ppOutHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_DLSS_Create_Params *pInDlssCreateParams)
+{
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_CreationNodeMask, InCreationNodeMask);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_VisibilityNodeMask, InVisibilityNodeMask);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlssCreateParams->Feature.InWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlssCreateParams->Feature.InHeight);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pInDlssCreateParams->Feature.InTargetWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pInDlssCreateParams->Feature.InTargetHeight);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pInDlssCreateParams->Feature.InPerfQualityValue);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags, pInDlssCreateParams->InFeatureCreateFlags);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Enable_Output_Subrects, pInDlssCreateParams->InEnableOutputSubrects ? 1 : 0);
+
+    return NVSDK_NGX_D3D12_CreateFeature(pInCmdList, NVSDK_NGX_Feature_SuperSampling, pInParams, ppOutHandle);
+}
+
+static inline NVSDK_NGX_Result NGX_D3D12_EVALUATE_DLSS_EXT(
+    ID3D12GraphicsCommandList *pInCmdList,
+    NVSDK_NGX_Handle *pInHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_D3D12_DLSS_Eval_Params *pInDlssEvalParams)
+{
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Color, pInDlssEvalParams->Feature.pInColor);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Output, pInDlssEvalParams->Feature.pInOutput);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Depth, pInDlssEvalParams->pInDepth);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_MotionVectors, pInDlssEvalParams->pInMotionVectors);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_X, pInDlssEvalParams->InJitterOffsetX);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_Y, pInDlssEvalParams->InJitterOffsetY);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pInDlssEvalParams->Feature.InSharpness);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_Reset, pInDlssEvalParams->InReset);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_X, pInDlssEvalParams->InMVScaleX == 0.0f ? 1.0f : pInDlssEvalParams->InMVScaleX);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_Y, pInDlssEvalParams->InMVScaleY == 0.0f ? 1.0f : pInDlssEvalParams->InMVScaleY);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_TransparencyMask, pInDlssEvalParams->pInTransparencyMask);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_ExposureTexture, pInDlssEvalParams->pInExposureTexture);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, pInDlssEvalParams->pInBiasCurrentColorMask);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Albedo, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ALBEDO]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Roughness, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ROUGHNESS]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Metallic, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_METALLIC]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Specular, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SPECULAR]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Subsurface, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SUBSURFACE]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Normals, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_NORMALS]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_ShadingModelId, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SHADINGMODELID]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_MaterialId, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_MATERIALID]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_8, pInDlssEvalParams->GBufferSurface.pInAttrib[8]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_9, pInDlssEvalParams->GBufferSurface.pInAttrib[9]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_10, pInDlssEvalParams->GBufferSurface.pInAttrib[10]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_11, pInDlssEvalParams->GBufferSurface.pInAttrib[11]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_12, pInDlssEvalParams->GBufferSurface.pInAttrib[12]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_13, pInDlssEvalParams->GBufferSurface.pInAttrib[13]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_14, pInDlssEvalParams->GBufferSurface.pInAttrib[14]);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_15, pInDlssEvalParams->GBufferSurface.pInAttrib[15]);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_TonemapperType, pInDlssEvalParams->InToneMapperType);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_MotionVectors3D, pInDlssEvalParams->pInMotionVectors3D);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_IsParticleMask, pInDlssEvalParams->pInIsParticleMask);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_AnimatedTextureMask, pInDlssEvalParams->pInAnimatedTextureMask);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DepthHighRes, pInDlssEvalParams->pInDepthHighRes);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Position_ViewSpace, pInDlssEvalParams->pInPositionViewSpace);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_FrameTimeDeltaInMsec, pInDlssEvalParams->InFrameTimeDeltaInMsec);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_RayTracingHitDistance, pInDlssEvalParams->pInRayTracingHitDistance);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_MotionVectorsReflection, pInDlssEvalParams->pInMotionVectorsReflections);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X, pInDlssEvalParams->InColorSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y, pInDlssEvalParams->InColorSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, pInDlssEvalParams->InDepthSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_Y, pInDlssEvalParams->InDepthSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_X, pInDlssEvalParams->InMVSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_Y, pInDlssEvalParams->InMVSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_X, pInDlssEvalParams->InTranslucencySubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_Y, pInDlssEvalParams->InTranslucencySubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_X, pInDlssEvalParams->InBiasCurrentColorSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_Y, pInDlssEvalParams->InBiasCurrentColorSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_X, pInDlssEvalParams->InOutputSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_Y, pInDlssEvalParams->InOutputSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width , pInDlssEvalParams->InRenderSubrectDimensions.Width);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height, pInDlssEvalParams->InRenderSubrectDimensions.Height);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Pre_Exposure, pInDlssEvalParams->InPreExposure == 0.0f ? 1.0f : pInDlssEvalParams->InPreExposure);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Exposure_Scale, pInDlssEvalParams->InExposureScale == 0.0f ? 1.0f : pInDlssEvalParams->InExposureScale);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_X_Axis, pInDlssEvalParams->InIndicatorInvertXAxis);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_Y_Axis, pInDlssEvalParams->InIndicatorInvertYAxis);
+
+    return NVSDK_NGX_D3D12_EvaluateFeature_C(pInCmdList, pInHandle, pInParams, NULL);
+}
+
+static inline NVSDK_NGX_Result NGX_D3D12_CREATE_DLISP_EXT(
+    ID3D12GraphicsCommandList *InCmdList,
+    unsigned int InCreationNodeMask,
+    unsigned int InVisibilityNodeMask,
+    NVSDK_NGX_Handle **ppOutHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_Feature_Create_Params *pDlispCreateParams)
+{
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_CreationNodeMask, InCreationNodeMask);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_VisibilityNodeMask, InVisibilityNodeMask);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pDlispCreateParams->InWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pDlispCreateParams->InHeight);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pDlispCreateParams->InTargetWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pDlispCreateParams->InTargetHeight);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pDlispCreateParams->InPerfQualityValue);
+
+    return NVSDK_NGX_D3D12_CreateFeature(InCmdList, NVSDK_NGX_Feature_ImageSignalProcessing, pInParams, ppOutHandle);
+}
+
+static inline NVSDK_NGX_Result NGX_D3D12_EVALUATE_DLISP_EXT(
+    ID3D12GraphicsCommandList *pInCmdList,
+    NVSDK_NGX_Handle *pInHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_D3D12_DLISP_Eval_Params *pDlispEvalParams)
+{
+    if (pDlispEvalParams->Feature.InSharpness < 0.0f || pDlispEvalParams->Feature.InSharpness > 1.0f || pDlispEvalParams->InDenoise < 0.0f || pDlispEvalParams->InDenoise > 1.0f)
+    {
+        return NVSDK_NGX_Result_FAIL_InvalidParameter;
+    }
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Color, pDlispEvalParams->Feature.pInColor);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Output, pDlispEvalParams->Feature.pInOutput);
+    // Both sharpness and denoise in range [0.0f,1.0f]
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pDlispEvalParams->Feature.InSharpness);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Denoise, pDlispEvalParams->InDenoise);
+    // If input is atlas - use RECT to upscale only the required area
+    if (pDlispEvalParams->InRectW)
+    {
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_X, pDlispEvalParams->InRectX);
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_Y, pDlispEvalParams->InRectY);
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_W, pDlispEvalParams->InRectW);
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_H, pDlispEvalParams->InRectH);
+    }
+    return NVSDK_NGX_D3D12_EvaluateFeature_C(pInCmdList, pInHandle, pInParams, NULL);
+}
+
+static inline NVSDK_NGX_Result NGX_D3D12_CREATE_DLRESOLVE_EXT(
+    ID3D12GraphicsCommandList *pInCmdList,
+    unsigned int InCreationNodeMask,
+    unsigned int InVisibilityNodeMask,
+    NVSDK_NGX_Handle **ppOutHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_Feature_Create_Params *pDlresolveCreateParams)
+{
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_CreationNodeMask, InCreationNodeMask);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_VisibilityNodeMask, InVisibilityNodeMask);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pDlresolveCreateParams->InWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pDlresolveCreateParams->InHeight);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pDlresolveCreateParams->InTargetWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pDlresolveCreateParams->InTargetHeight);
+
+    return NVSDK_NGX_D3D12_CreateFeature(pInCmdList, NVSDK_NGX_Feature_DeepResolve, pInParams, ppOutHandle);
+}
+
+static inline NVSDK_NGX_Result NGX_D3D12_EVALUATE_DLRESOLVE_EXT(
+    ID3D12GraphicsCommandList *pInCmdList,
+    NVSDK_NGX_Handle *pInHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_D3D12_Feature_Eval_Params *pDlresolveEvalParams)
+{
+    // This call to NVSDK_NGX_Parameter_SetXXX() is equivalent to the Params->Set below functionally
+    // but to work around the lack of virtual functions and polymorphism in a C only project
+    // we introduced this new way to set params.
+    // The test should enforce that both paths work.
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Color, pDlresolveEvalParams->pInColor);
+    NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Output, pDlresolveEvalParams->pInOutput);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pDlresolveEvalParams->InSharpness);
+
+    return NVSDK_NGX_D3D12_EvaluateFeature_C(pInCmdList, pInHandle, pInParams, NULL);
+}
+
+#endif

+ 319 - 0
ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_helpers_vk.h

@@ -0,0 +1,319 @@
+/*
+* Copyright (c) 2018 NVIDIA CORPORATION.  All rights reserved.
+*
+* NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+* rights in and to this software, related documentation and any modifications thereto.
+* Any use, reproduction, disclosure or distribution of this software and related
+* documentation without an express license agreement from NVIDIA Corporation is strictly
+* prohibited.
+*
+* TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS*
+* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
+* INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
+* SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT
+* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF
+* BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
+* INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGES.
+*/
+
+#ifndef NVSDK_NGX_HELPERS_VK_H
+#define NVSDK_NGX_HELPERS_VK_H
+#pragma once
+
+#include "nvsdk_ngx_vk.h"
+
+#define NVSDK_NGX_ENSURE_VK_IMAGEVIEW(InResource) if ((InResource) && (InResource)->Type != NVSDK_NGX_RESOURCE_VK_TYPE_VK_IMAGEVIEW) { return NVSDK_NGX_Result_FAIL_InvalidParameter; }
+
+static inline NVSDK_NGX_Resource_VK NVSDK_NGX_Create_ImageView_Resource_VK(VkImageView imageView, VkImage image, VkImageSubresourceRange subresourceRange, VkFormat format, unsigned int width, unsigned int height, bool readWrite)
+{
+    NVSDK_NGX_Resource_VK resourceVK = {};
+    resourceVK.Type = NVSDK_NGX_RESOURCE_VK_TYPE_VK_IMAGEVIEW;
+    resourceVK.Resource.ImageViewInfo.ImageView = imageView;
+    resourceVK.Resource.ImageViewInfo.Image = image;
+    resourceVK.Resource.ImageViewInfo.SubresourceRange = subresourceRange;
+    resourceVK.Resource.ImageViewInfo.Height = height;
+    resourceVK.Resource.ImageViewInfo.Width = width;
+    resourceVK.Resource.ImageViewInfo.Format = format;
+    resourceVK.ReadWrite = readWrite;
+    return resourceVK;
+}
+
+static inline NVSDK_NGX_Resource_VK NVSDK_NGX_Create_Buffer_Resource_VK(VkBuffer buffer, unsigned int sizeInBytes, bool readWrite)
+{
+    NVSDK_NGX_Resource_VK resourceVK = {};
+    resourceVK.Type = NVSDK_NGX_RESOURCE_VK_TYPE_VK_BUFFER;
+    resourceVK.Resource.BufferInfo.Buffer = buffer;
+    resourceVK.Resource.BufferInfo.SizeInBytes = sizeInBytes;
+    resourceVK.ReadWrite = readWrite;
+    return resourceVK;
+}
+
+typedef struct NVSDK_NGX_VK_Feature_Eval_Params
+{
+    NVSDK_NGX_Resource_VK *pInColor;
+    NVSDK_NGX_Resource_VK *pInOutput;
+    /*** OPTIONAL for DLSS ***/
+    float                  InSharpness;
+} NVSDK_NGX_VK_Feature_Eval_Params;
+
+typedef struct NVSDK_NGX_VK_GBuffer
+{
+    NVSDK_NGX_Resource_VK *pInAttrib[NVSDK_NGX_GBUFFERTYPE_NUM];
+} NVSDK_NGX_VK_GBuffer;
+
+typedef struct NVSDK_NGX_Coordinates_VK
+{
+    unsigned int X;
+    unsigned int Y;
+} NVSDK_NGX_Coordinates_VK;
+
+typedef struct NVSDK_NGX_VK_DLSS_Eval_Params
+{
+    NVSDK_NGX_VK_Feature_Eval_Params    Feature;
+    NVSDK_NGX_Resource_VK *             pInDepth;
+    NVSDK_NGX_Resource_VK *             pInMotionVectors;
+    float                               InJitterOffsetX;     /* Jitter offset must be in input/render pixel space */
+    float                               InJitterOffsetY;
+    NVSDK_NGX_Dimensions                InRenderSubrectDimensions;
+    /*** OPTIONAL - leave to 0/0.0f if unused ***/
+    int                                 InReset;             /* Set to 1 when scene changes completely (new level etc) */
+    float                               InMVScaleX;          /* If MVs need custom scaling to convert to pixel space */
+    float                               InMVScaleY;
+    NVSDK_NGX_Resource_VK *             pInTransparencyMask; /* Unused/Reserved for future use */
+    NVSDK_NGX_Resource_VK *             pInExposureTexture;
+    NVSDK_NGX_Resource_VK *             pInBiasCurrentColorMask;
+    NVSDK_NGX_Coordinates               InColorSubrectBase;
+    NVSDK_NGX_Coordinates               InDepthSubrectBase;
+    NVSDK_NGX_Coordinates               InMVSubrectBase;
+    NVSDK_NGX_Coordinates               InTranslucencySubrectBase;
+    NVSDK_NGX_Coordinates               InBiasCurrentColorSubrectBase;
+    NVSDK_NGX_Coordinates               InOutputSubrectBase;
+    float                               InPreExposure;
+    float                               InExposureScale;
+    int                                 InIndicatorInvertXAxis;
+    int                                 InIndicatorInvertYAxis;
+    /*** OPTIONAL - only for research purposes ***/
+    NVSDK_NGX_VK_GBuffer                GBufferSurface;
+    NVSDK_NGX_ToneMapperType            InToneMapperType;
+    NVSDK_NGX_Resource_VK *             pInMotionVectors3D;
+    NVSDK_NGX_Resource_VK *             pInIsParticleMask; /* to identify which pixels contains particles, essentially that are not drawn as part of base pass */
+    NVSDK_NGX_Resource_VK *             pInAnimatedTextureMask; /* a binary mask covering pixels occupied by animated textures */
+    NVSDK_NGX_Resource_VK *             pInDepthHighRes;
+    NVSDK_NGX_Resource_VK *             pInPositionViewSpace;
+    float                               InFrameTimeDeltaInMsec; /* helps in determining the amount to denoise or anti-alias based on the speed of the object from motion vector magnitudes and fps as determined by this delta */
+    NVSDK_NGX_Resource_VK *             pInRayTracingHitDistance; /* for each effect - approximation to the amount of noise in a ray-traced color */
+    NVSDK_NGX_Resource_VK *             pInMotionVectorsReflections; /* motion vectors of reflected objects like for mirrored surfaces */
+} NVSDK_NGX_VK_DLSS_Eval_Params;
+
+typedef struct NVSDK_NGX_VK_DLISP_Eval_Params
+{
+    NVSDK_NGX_VK_Feature_Eval_Params Feature;
+    /*** OPTIONAL - leave to 0/0.0f if unused ***/
+    unsigned int                        InRectX;
+    unsigned int                        InRectY;
+    unsigned int                        InRectW;
+    unsigned int                        InRectH;
+    float                               InDenoise;
+} NVSDK_NGX_VK_DLISP_Eval_Params;
+
+static inline NVSDK_NGX_Result NGX_VULKAN_CREATE_DLSS_EXT1(
+    VkDevice InDevice,
+    VkCommandBuffer InCmdList,
+    unsigned int InCreationNodeMask,
+    unsigned int InVisibilityNodeMask,
+    NVSDK_NGX_Handle **ppOutHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_DLSS_Create_Params *pInDlssCreateParams)
+{
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_CreationNodeMask, InCreationNodeMask);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_VisibilityNodeMask, InVisibilityNodeMask);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlssCreateParams->Feature.InWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlssCreateParams->Feature.InHeight);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pInDlssCreateParams->Feature.InTargetWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pInDlssCreateParams->Feature.InTargetHeight);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pInDlssCreateParams->Feature.InPerfQualityValue);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags, pInDlssCreateParams->InFeatureCreateFlags);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Enable_Output_Subrects, pInDlssCreateParams->InEnableOutputSubrects ? 1 : 0);
+
+    if (InDevice) return NVSDK_NGX_VULKAN_CreateFeature1(InDevice, InCmdList, NVSDK_NGX_Feature_SuperSampling, pInParams, ppOutHandle);
+    else return NVSDK_NGX_VULKAN_CreateFeature(InCmdList, NVSDK_NGX_Feature_SuperSampling, pInParams, ppOutHandle);
+}
+
+static inline NVSDK_NGX_Result NGX_VULKAN_CREATE_DLSS_EXT(
+    VkCommandBuffer InCmdList,
+    unsigned int InCreationNodeMask,
+    unsigned int InVisibilityNodeMask,
+    NVSDK_NGX_Handle **ppOutHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_DLSS_Create_Params *pInDlssCreateParams)
+{
+    return NGX_VULKAN_CREATE_DLSS_EXT1(NULL, InCmdList, InCreationNodeMask, InVisibilityNodeMask, ppOutHandle, pInParams, pInDlssCreateParams);
+}
+
+static inline NVSDK_NGX_Result NGX_VULKAN_EVALUATE_DLSS_EXT(
+    VkCommandBuffer InCmdList,
+    NVSDK_NGX_Handle *pInHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_VK_DLSS_Eval_Params *pInDlssEvalParams)
+{
+	NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->Feature.pInColor);
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInMotionVectors);
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->Feature.pInOutput);
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInDepth);
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInTransparencyMask);
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInExposureTexture);
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInBiasCurrentColorMask);
+	for (size_t i = 0; i <= 15; i++)
+	{
+        NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->GBufferSurface.pInAttrib[i]);
+	}
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInMotionVectors3D);
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInIsParticleMask);
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInAnimatedTextureMask);
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInDepthHighRes);
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInPositionViewSpace);
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInRayTracingHitDistance);
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInMotionVectorsReflections);
+
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Color, pInDlssEvalParams->Feature.pInColor);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Output, pInDlssEvalParams->Feature.pInOutput);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Depth, pInDlssEvalParams->pInDepth);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_MotionVectors, pInDlssEvalParams->pInMotionVectors);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_X, pInDlssEvalParams->InJitterOffsetX);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_Y, pInDlssEvalParams->InJitterOffsetY);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pInDlssEvalParams->Feature.InSharpness);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_Reset, pInDlssEvalParams->InReset);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_X, pInDlssEvalParams->InMVScaleX == 0.0f ? 1.0f : pInDlssEvalParams->InMVScaleX);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_Y, pInDlssEvalParams->InMVScaleY == 0.0f ? 1.0f : pInDlssEvalParams->InMVScaleY);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_TransparencyMask, pInDlssEvalParams->pInTransparencyMask);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_ExposureTexture, pInDlssEvalParams->pInExposureTexture);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, pInDlssEvalParams->pInBiasCurrentColorMask);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Albedo, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ALBEDO]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Roughness, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ROUGHNESS]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Metallic, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_METALLIC]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Specular, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SPECULAR]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Subsurface, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SUBSURFACE]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Normals, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_NORMALS]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_ShadingModelId, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SHADINGMODELID]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_MaterialId, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_MATERIALID]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_8, pInDlssEvalParams->GBufferSurface.pInAttrib[8]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_9, pInDlssEvalParams->GBufferSurface.pInAttrib[9]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_10, pInDlssEvalParams->GBufferSurface.pInAttrib[10]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_11, pInDlssEvalParams->GBufferSurface.pInAttrib[11]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_12, pInDlssEvalParams->GBufferSurface.pInAttrib[12]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_13, pInDlssEvalParams->GBufferSurface.pInAttrib[13]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_14, pInDlssEvalParams->GBufferSurface.pInAttrib[14]);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_15, pInDlssEvalParams->GBufferSurface.pInAttrib[15]);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_TonemapperType, pInDlssEvalParams->InToneMapperType);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_MotionVectors3D, pInDlssEvalParams->pInMotionVectors3D);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_IsParticleMask, pInDlssEvalParams->pInIsParticleMask);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_AnimatedTextureMask, pInDlssEvalParams->pInAnimatedTextureMask);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DepthHighRes, pInDlssEvalParams->pInDepthHighRes);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Position_ViewSpace, pInDlssEvalParams->pInPositionViewSpace);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_FrameTimeDeltaInMsec, pInDlssEvalParams->InFrameTimeDeltaInMsec);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_RayTracingHitDistance, pInDlssEvalParams->pInRayTracingHitDistance);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_MotionVectorsReflection, pInDlssEvalParams->pInMotionVectorsReflections);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X, pInDlssEvalParams->InColorSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y, pInDlssEvalParams->InColorSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, pInDlssEvalParams->InDepthSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_Y, pInDlssEvalParams->InDepthSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_X, pInDlssEvalParams->InMVSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_Y, pInDlssEvalParams->InMVSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_X, pInDlssEvalParams->InTranslucencySubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_Y, pInDlssEvalParams->InTranslucencySubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_X, pInDlssEvalParams->InBiasCurrentColorSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_Y, pInDlssEvalParams->InBiasCurrentColorSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_X, pInDlssEvalParams->InOutputSubrectBase.X);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_Y, pInDlssEvalParams->InOutputSubrectBase.Y);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width , pInDlssEvalParams->InRenderSubrectDimensions.Width);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height, pInDlssEvalParams->InRenderSubrectDimensions.Height);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Pre_Exposure, pInDlssEvalParams->InPreExposure == 0.0f ? 1.0f : pInDlssEvalParams->InPreExposure);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Exposure_Scale, pInDlssEvalParams->InExposureScale == 0.0f ? 1.0f : pInDlssEvalParams->InExposureScale);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_X_Axis, pInDlssEvalParams->InIndicatorInvertXAxis);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_Y_Axis, pInDlssEvalParams->InIndicatorInvertYAxis);
+
+    return NVSDK_NGX_VULKAN_EvaluateFeature_C(InCmdList, pInHandle, pInParams, NULL);
+}
+
+static inline NVSDK_NGX_Result NGX_VULKAN_CREATE_DLISP_EXT(
+    VkCommandBuffer InCmdList,
+    unsigned int InCreationNodeMask,
+    unsigned int InVisibilityNodeMask,
+    NVSDK_NGX_Handle **ppOutHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_Feature_Create_Params *pInDlispCreateParams)
+{
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_CreationNodeMask, InCreationNodeMask);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_VisibilityNodeMask, InVisibilityNodeMask);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlispCreateParams->InWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlispCreateParams->InHeight);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pInDlispCreateParams->InTargetWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pInDlispCreateParams->InTargetHeight);
+    NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pInDlispCreateParams->InPerfQualityValue);
+
+    return NVSDK_NGX_VULKAN_CreateFeature(InCmdList, NVSDK_NGX_Feature_ImageSignalProcessing, pInParams, ppOutHandle);
+}
+
+static inline NVSDK_NGX_Result NGX_VULKAN_EVALUATE_DLISP_EXT(
+    VkCommandBuffer InCmdList,
+    NVSDK_NGX_Handle *InHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_VK_DLISP_Eval_Params *pInDlispEvalParams)
+{
+	NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlispEvalParams->Feature.pInColor);
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlispEvalParams->Feature.pInOutput); 
+
+   	NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Color, pInDlispEvalParams->Feature.pInColor);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Output, pInDlispEvalParams->Feature.pInOutput);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pInDlispEvalParams->Feature.InSharpness);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Denoise, pInDlispEvalParams->InDenoise);
+    // If input is atlas - use RECT to upscale only the required area
+    if (pInDlispEvalParams->InRectW)
+    {
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_X, pInDlispEvalParams->InRectX);
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_Y, pInDlispEvalParams->InRectY);
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_W, pInDlispEvalParams->InRectW);
+        NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_H, pInDlispEvalParams->InRectH);
+    }
+
+    return NVSDK_NGX_VULKAN_EvaluateFeature_C(InCmdList, InHandle, pInParams, NULL);
+}
+
+
+static inline NVSDK_NGX_Result NGX_VULKAN_CREATE_DLRESOLVE_EXT(
+    VkCommandBuffer InCmdList,
+    unsigned int InCreationNodeMask,
+    unsigned int InVisibilityNodeMask,
+    NVSDK_NGX_Handle **ppOutHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_Feature_Create_Params *pInDlresolveCreateParams)
+{
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_CreationNodeMask, InCreationNodeMask);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_VisibilityNodeMask, InVisibilityNodeMask);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlresolveCreateParams->InWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlresolveCreateParams->InHeight);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pInDlresolveCreateParams->InTargetWidth);
+    NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pInDlresolveCreateParams->InTargetHeight);
+
+    return NVSDK_NGX_VULKAN_CreateFeature(InCmdList, NVSDK_NGX_Feature_DeepResolve, pInParams, ppOutHandle);
+}
+
+static inline NVSDK_NGX_Result NGX_VULKAN_EVALUATE_DLRESOLVE_EXT(
+    VkCommandBuffer InCmdList,
+    NVSDK_NGX_Handle *pInHandle,
+    NVSDK_NGX_Parameter *pInParams,
+    NVSDK_NGX_VK_Feature_Eval_Params *pInDlresolveEvalParams)
+{
+	NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlresolveEvalParams->pInColor);
+    NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlresolveEvalParams->pInOutput);
+    
+	NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Color, pInDlresolveEvalParams->pInColor);
+    NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Output, pInDlresolveEvalParams->pInOutput);
+    NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pInDlresolveEvalParams->InSharpness);
+
+    return NVSDK_NGX_VULKAN_EvaluateFeature_C(InCmdList, pInHandle, pInParams, NULL);
+}
+
+#endif // NVSDK_NGX_HELPERS_VK_H

+ 124 - 0
ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_params.h

@@ -0,0 +1,124 @@
+/*
+* Copyright (c) 2018 NVIDIA CORPORATION.  All rights reserved.
+*
+* NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+* rights in and to this software, related documentation and any modifications thereto.
+* Any use, reproduction, disclosure or distribution of this software and related
+* documentation without an express license agreement from NVIDIA Corporation is strictly
+* prohibited.
+*
+* TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS*
+* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
+* INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
+* SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT
+* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF
+* BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
+* INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGES.
+*/
+
+
+#ifndef NVSDK_NGX_PARAMS_H
+#define NVSDK_NGX_PARAMS_H
+
+#include "nvsdk_ngx_defs.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct ID3D11Resource ID3D11Resource;
+typedef struct ID3D12Resource ID3D12Resource;
+
+typedef struct NVSDK_NGX_Feature_Create_Params
+{
+    unsigned int InWidth;
+    unsigned int InHeight;
+    unsigned int InTargetWidth;
+    unsigned int InTargetHeight;
+    /*** OPTIONAL ***/
+    NVSDK_NGX_PerfQuality_Value InPerfQualityValue;
+} NVSDK_NGX_Feature_Create_Params;
+
+typedef struct NVSDK_NGX_DLSS_Create_Params
+{
+    NVSDK_NGX_Feature_Create_Params Feature;
+    /*** OPTIONAL ***/
+    int     InFeatureCreateFlags;
+    bool    InEnableOutputSubrects;
+} NVSDK_NGX_DLSS_Create_Params;
+
+typedef struct NVSDK_NGX_DLDenoise_Create_Params
+{
+    NVSDK_NGX_Feature_Create_Params Feature;
+    /*** OPTIONAL ***/
+    int InFeatureCreateFlags;
+} NVSDK_NGX_DLDenoise_Create_Params;
+
+#ifdef __cplusplus
+typedef struct NVSDK_NGX_Parameter
+{
+    virtual void Set(const char * InName, unsigned long long InValue) = 0;
+    virtual void Set(const char * InName, float InValue) = 0;
+    virtual void Set(const char * InName, double InValue) = 0;
+    virtual void Set(const char * InName, unsigned int InValue) = 0;
+    virtual void Set(const char * InName, int InValue) = 0;    
+    virtual void Set(const char * InName, ID3D11Resource *InValue) = 0;
+    virtual void Set(const char * InName, ID3D12Resource *InValue) = 0;
+    virtual void Set(const char * InName, void *InValue) = 0;
+
+    virtual NVSDK_NGX_Result Get(const char * InName, unsigned long long *OutValue) const = 0;
+    virtual NVSDK_NGX_Result Get(const char * InName, float *OutValue) const = 0;
+    virtual NVSDK_NGX_Result Get(const char * InName, double *OutValue) const = 0;
+    virtual NVSDK_NGX_Result Get(const char * InName, unsigned int *OutValue) const = 0;
+    virtual NVSDK_NGX_Result Get(const char * InName, int *OutValue) const = 0;
+    virtual NVSDK_NGX_Result Get(const char * InName, ID3D11Resource **OutValue) const = 0;
+    virtual NVSDK_NGX_Result Get(const char * InName, ID3D12Resource **OutValue) const = 0;
+    virtual NVSDK_NGX_Result Get(const char * InName, void **OutValue) const = 0;
+    
+    virtual void Reset() = 0;
+} NVSDK_NGX_Parameter;
+#else
+typedef struct NVSDK_NGX_Parameter NVSDK_NGX_Parameter;
+#endif // _cplusplus
+
+typedef void             (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetULL)(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned long long InValue);
+NVSDK_NGX_API void        NVSDK_CONV      NVSDK_NGX_Parameter_SetULL(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned long long InValue);
+typedef void             (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetF)(NVSDK_NGX_Parameter *InParameter, const char * InName, float InValue);
+NVSDK_NGX_API void        NVSDK_CONV      NVSDK_NGX_Parameter_SetF(NVSDK_NGX_Parameter *InParameter, const char * InName, float InValue);
+typedef void             (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetD)(NVSDK_NGX_Parameter *InParameter, const char * InName, double InValue);
+NVSDK_NGX_API void        NVSDK_CONV      NVSDK_NGX_Parameter_SetD(NVSDK_NGX_Parameter *InParameter, const char * InName, double InValue);
+typedef void             (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetUI)(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned int InValue);
+NVSDK_NGX_API void        NVSDK_CONV      NVSDK_NGX_Parameter_SetUI(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned int InValue);
+typedef void             (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetI)(NVSDK_NGX_Parameter *InParameter, const char * InName, int InValue);
+NVSDK_NGX_API void        NVSDK_CONV      NVSDK_NGX_Parameter_SetI(NVSDK_NGX_Parameter *InParameter, const char * InName, int InValue);
+typedef void             (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetD3d11Resource)(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D11Resource *InValue);
+NVSDK_NGX_API void        NVSDK_CONV      NVSDK_NGX_Parameter_SetD3d11Resource(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D11Resource *InValue);
+typedef void             (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetD3d12Resource)(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D12Resource *InValue);
+NVSDK_NGX_API void        NVSDK_CONV      NVSDK_NGX_Parameter_SetD3d12Resource(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D12Resource *InValue);
+typedef void             (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetVoidPointer)(NVSDK_NGX_Parameter *InParameter, const char * InName, void *InValue);
+NVSDK_NGX_API void        NVSDK_CONV      NVSDK_NGX_Parameter_SetVoidPointer(NVSDK_NGX_Parameter *InParameter, const char * InName, void *InValue);
+typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetULL)(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned long long *OutValue);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetULL(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned long long *OutValue);
+typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetF)(NVSDK_NGX_Parameter *InParameter, const char * InName, float *OutValue);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetF(NVSDK_NGX_Parameter *InParameter, const char * InName, float *OutValue);
+typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetD)(NVSDK_NGX_Parameter *InParameter, const char * InName, double *OutValue);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetD(NVSDK_NGX_Parameter *InParameter, const char * InName, double *OutValue);
+typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetUI)(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned int *OutValue);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetUI(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned int *OutValue);
+typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetI)(NVSDK_NGX_Parameter *InParameter, const char * InName, int *OutValue);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetI(NVSDK_NGX_Parameter *InParameter, const char * InName, int *OutValue);
+typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetD3d11Resource)(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D11Resource **OutValue);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetD3d11Resource(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D11Resource **OutValue);
+typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetD3d12Resource)(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D12Resource **OutValue);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetD3d12Resource(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D12Resource **OutValue);
+typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetVoidPointer)(NVSDK_NGX_Parameter *InParameter, const char * InName, void **OutValue);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetVoidPointer(NVSDK_NGX_Parameter *InParameter, const char * InName, void **OutValue);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // #define NVSDK_NGX_PARAMS_H

+ 464 - 0
ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_vk.h

@@ -0,0 +1,464 @@
+/*
+* Copyright (c) 2018 NVIDIA CORPORATION.  All rights reserved.
+*
+* NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+* rights in and to this software, related documentation and any modifications thereto.
+* Any use, reproduction, disclosure or distribution of this software and related
+* documentation without an express license agreement from NVIDIA Corporation is strictly
+* prohibited.
+*
+* TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS*
+* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
+* INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
+* SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT
+* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF
+* BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
+* INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGES.
+*/
+
+/*
+*  HOW TO USE:
+*
+*  IMPORTANT: Methods in this library are NOT thread safe. It is up to the
+*  client to ensure that thread safety is enforced as needed.
+*  
+*  1) Call NVSDK_CONV NVSDK_NGX_D3D11/D3D12/CUDA_Init and pass your app Id
+*     and other parameters. This will initialize SDK or return an error code
+*     if SDK cannot run on target machine. Depending on error user might
+*     need to update drivers. Please note that application Id is provided
+*     by NVIDIA so if you do not have one please contact us.
+* 
+*  2) Call NVSDK_NGX_D3D11/D3D12/CUDA_GetParameters to obtain pointer to 
+*     interface used to pass parameters to SDK. Interface instance is 
+*     allocated and released by SDK so there is no need to do any memory 
+*     management on client side.
+*    
+*  3) Set key parameters for the feature you want to use. For example, 
+*     width and height are required for all features and they can be
+*     set like this: 
+*         Params->Set(NVSDK_NGX_Parameter_Width,MY_WIDTH);
+*         Params->Set(NVSDK_NGX_Parameter_Height,MY_HEIGHT);
+*
+*     You can also provide hints like NVSDK_NGX_Parameter_Hint_HDR to tell
+*     SDK that it should expect HDR color space is needed. Please refer to 
+*     samples since different features need different parameters and hints.
+*
+*  4) Call NVSDK_NGX_D3D11/D3D12/CUDA_GetScratchBufferSize to obtain size of
+*     the scratch buffer needed by specific feature. This D3D or CUDA buffer
+*     should be allocated by client and passed as:
+*        Params->Set(NVSDK_NGX_Parameter_Scratch,MY_SCRATCH_POINTER)
+*        Params->Set(NVSDK_NGX_Parameter_Scratch_SizeInBytes,MY_SCRATCH_SIZE_IN_BYTES)
+*     NOTE: Returned size can be 0 if feature does not use any scratch buffer.
+*     It is OK to use bigger buffer or reuse buffers across features as long
+*     as minimum size requirement is met.
+*
+*  5) Call NVSDK_NGX_D3D11/D3D12/CUDA_CreateFeature to create feature you need.
+*     On success SDK will return a handle which must be used in any successive 
+*     calls to SDK which require feature handle. SDK will use all parameters
+*     and hints provided by client to generate feature. If feature with the same
+*     parameters already exists and error code will be returned.
+*
+*  6) Call NVSDK_NGX_D3D11/D3D12/CUDA_EvaluateFeature to invoke execution of
+*     specific feature. Before feature can be evaluated input parameters must
+*     be specified (like for example color/albedo buffer, motion vectors etc)
+* 
+*  6) Call NVSDK_NGX_D3D11/D3D12/CUDA_ReleaseFeature when feature is no longer
+*     needed. After this call feature handle becomes invalid and cannot be used.
+* 
+*  7) Call NVSDK_NGX_D3D11/D3D12/CUDA_Shutdown when SDK is no longer needed to
+*     release all resources.
+
+*  Contact: [email protected]
+*/
+
+
+#ifndef NVSDK_NGX_VK_H
+#define NVSDK_NGX_VK_H
+
+#include "nvsdk_ngx_defs.h"
+#include "nvsdk_ngx_params.h"
+#ifndef __cplusplus
+#include <stdbool.h> 
+#include <wchar.h> 
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+    
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_ImageViewInfo_VK [Vulkan only]
+// Contains ImageView-specific metadata.
+// ImageView:
+//    The VkImageView resource.
+//
+// Image:
+//    The VkImage associated to this VkImageView.
+//
+// SubresourceRange:
+//    The VkImageSubresourceRange associated to this VkImageView.
+//
+//  Format:
+//    The format of the resource.
+//
+//  Width:
+//     The width of the resource.
+// 
+//  Height:
+//     The height of the resource.
+//
+typedef struct NVSDK_NGX_ImageViewInfo_VK {
+    VkImageView ImageView;
+    VkImage Image;
+    VkImageSubresourceRange SubresourceRange;
+    VkFormat Format;
+    unsigned int Width;
+    unsigned int Height;
+} NVSDK_NGX_ImageViewInfo_VK;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_BufferInfo_VK [Vulkan only]
+// Contains Buffer-specific metadata.
+// Buffer
+//    The VkBuffer resource.
+//
+// SizeInBytes:
+//    The size of the resource (in bytes).
+//
+typedef struct NVSDK_NGX_BufferInfo_VK {
+    VkBuffer Buffer;
+    unsigned int SizeInBytes;
+} NVSDK_NGX_BufferInfo_VK;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_Resource_VK [Vulkan only]
+//
+// ImageViewInfo:
+//    The VkImageView resource, and VkImageView-specific metadata. A NVSDK_NGX_Resource_VK can only have one of ImageViewInfo or BufferInfo.
+//
+// BufferInfo:
+//    The VkBuffer Resource, and VkBuffer-specific metadata. A NVSDK_NGX_Resource_VK can only have one of ImageViewInfo or BufferInfo.
+// 
+//  Type:
+//    Whether or this resource is a VkImageView or a VkBuffer.
+// 
+//  ReadWrite:
+//     True if the resource is available for read and write access.
+//          For VkBuffer resources: VkBufferUsageFlags includes VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
+//          For VkImage resources: VkImageUsageFlags for associated VkImage includes VK_IMAGE_USAGE_STORAGE_BIT
+//
+typedef struct NVSDK_NGX_Resource_VK {
+    union {
+        NVSDK_NGX_ImageViewInfo_VK ImageViewInfo;
+        NVSDK_NGX_BufferInfo_VK BufferInfo;
+    } Resource;
+    NVSDK_NGX_Resource_VK_Type Type;
+    bool ReadWrite;
+} NVSDK_NGX_Resource_VK;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_RequiredExtensions [Vulkan only]
+//
+// OutInstanceExtCount:
+//   Returns the number of instance extensions NGX requires
+// 
+// OutInstanceExts:
+//   Returns a pointer to *OutInstanceExtCount strings of instance extensions
+// 
+// OutDeviceExtCount:
+//   Returns the number of device extensions NGX requires
+// 
+// OutDeviceExts:
+//   Returns a pointer to *OutDeviceExtCount strings of device extensions
+//
+NVSDK_NGX_API NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_VULKAN_RequiredExtensions(unsigned int *OutInstanceExtCount, const char *** OutInstanceExts, unsigned int *OutDeviceExtCount, const char *** OutDeviceExts);
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_Init
+// -------------------------------------
+// 
+// InApplicationId:
+//      Unique Id provided by NVIDIA
+//
+// InApplicationDataPath:
+//      Folder to store logs and other temporary files (write access required),
+//      Normally this would be a location in Documents or ProgramData.
+//
+// InDevice: [d3d11/12 only]
+//      DirectX device to use
+//
+// DESCRIPTION:
+//      Initializes new SDK instance.
+//
+#ifdef __cplusplus
+NVSDK_NGX_API NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_VULKAN_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
+#else
+NVSDK_NGX_API NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_VULKAN_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_Init_with_ProjectID
+// -------------------------------------
+// 
+// InParojectId:
+//      Unique Id provided by the rendering engine used
+//
+// InEngineType:
+//      Rendering engine used by the application / plugin.
+//      Use NVSDK_NGX_ENGINE_TYPE_CUSTOM if the specific engine type is not supported explicitly
+//
+// InEngineVersion:
+//      Version number of the rendering engine used by the application / plugin.
+//
+// InApplicationDataPath:
+//      Folder to store logs and other temporary files (write access required),
+//      Normally this would be a location in Documents or ProgramData.
+//
+// InDevice: [d3d11/12 only]
+//      DirectX device to use
+//
+// InFeatureInfo:
+//      Contains information common to all features, presently only a list of all paths 
+//      feature dlls can be located in, other than the default path - application directory.
+//
+// DESCRIPTION:
+//      Initializes new SDK instance.
+//
+#ifdef __cplusplus
+NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_VULKAN_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
+#else
+NVSDK_NGX_Result  NVSDK_CONV NVSDK_NGX_VULKAN_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_Shutdown
+// -------------------------------------
+// 
+// DESCRIPTION:
+//      Shuts down the current SDK instance and releases all resources.
+//      Shutdown1(Device) only affects specified device
+//      Shutdown1(nullptr) = Shutdown() and shuts down all devices
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Shutdown(void);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Shutdown1(VkDevice InDevice);
+
+#ifdef NGX_ENABLE_DEPRECATED_GET_PARAMETERS
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_GetParameters
+// ----------------------------------------------------------
+//
+// OutParameters:
+//      Parameters interface used to set any parameter needed by the SDK
+//
+// DESCRIPTION:
+//      This interface allows simple parameter setup using named fields.
+//      For example one can set width by calling Set(NVSDK_NGX_Parameter_Denoiser_Width,100) or
+//      provide CUDA buffer pointer by calling Set(NVSDK_NGX_Parameter_Denoiser_Color,cudaBuffer)
+//      For more details please see sample code. Please note that allocated memory
+//      will be freed by NGX so free/delete operator should NOT be called.
+//      Parameter maps output by NVSDK_NGX_GetParameters are also pre-populated
+//      with NGX capabilities and available features.
+//      Unlike with NVSDK_NGX_AllocateParameters, parameter maps output by NVSDK_NGX_GetParameters
+//      have their lifetimes managed by NGX, and must not
+//      be destroyed by the app using NVSDK_NGX_DestroyParameters.
+//      NVSDK_NGX_GetParameters is deprecated and apps should move to using
+//      NVSDK_NGX_AllocateParameters and NVSDK_NGX_GetCapabilityParameters when possible.
+//      Nevertheless, due to the possibility that the user will be using an older driver version,
+//      NVSDK_NGX_GetParameters may still be used as a fallback if NVSDK_NGX_AllocateParameters
+//      or NVSDK_NGX_GetCapabilityParameters return NVSDK_NGX_Result_FAIL_OutOfDate.
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetParameters(NVSDK_NGX_Parameter **OutParameters);
+#endif // NGX_ENABLE_DEPRECATED_GET_PARAMETERS
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_AllocateParameters
+// ----------------------------------------------------------
+//
+// OutParameters:
+//      Parameters interface used to set any parameter needed by the SDK
+//
+// DESCRIPTION:
+//      This interface allows allocating a simple parameter setup using named fields, whose
+//      lifetime the app must manage.
+//      For example one can set width by calling Set(NVSDK_NGX_Parameter_Denoiser_Width,100) or
+//      provide CUDA buffer pointer by calling Set(NVSDK_NGX_Parameter_Denoiser_Color,cudaBuffer)
+//      For more details please see sample code.
+//      Parameter maps output by NVSDK_NGX_AllocateParameters must NOT be freed using
+//      the free/delete operator; to free a parameter map 
+//      output by NVSDK_NGX_AllocateParameters, NVSDK_NGX_DestroyParameters should be used.
+//      Unlike with NVSDK_NGX_GetParameters, parameter maps allocated with NVSDK_NGX_AllocateParameters
+//      must be destroyed by the app using NVSDK_NGX_DestroyParameters.
+//      Also unlike with NVSDK_NGX_GetParameters, parameter maps output by NVSDK_NGX_AllocateParameters
+//      do not come pre-populated with NGX capabilities and available features.
+//      To create a new parameter map pre-populated with such information, NVSDK_NGX_GetCapabilityParameters
+//      should be used.
+//      This function may return NVSDK_NGX_Result_FAIL_OutOfDate if an older driver, which
+//      does not support this API call is being used. In such a case, NVSDK_NGX_GetParameters
+//      may be used as a fallback.
+//      This function may only be called after a successful call into NVSDK_NGX_Init.
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_AllocateParameters(NVSDK_NGX_Parameter** OutParameters);
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_GetCapabilityParameters
+// ----------------------------------------------------------
+//
+// OutParameters:
+//      The parameters interface populated with NGX and feature capabilities
+//
+// DESCRIPTION:
+//      This interface allows the app to create a new parameter map
+//      pre-populated with NGX capabilities and available features.
+//      The output parameter map can also be used for any purpose
+//      parameter maps output by NVSDK_NGX_AllocateParameters can be used for
+//      but it is not recommended to use NVSDK_NGX_GetCapabilityParameters
+//      unless querying NGX capabilities and available features
+//      due to the overhead associated with pre-populating the parameter map.
+//      Parameter maps output by NVSDK_NGX_GetCapabilityParameters must NOT be freed using
+//      the free/delete operator; to free a parameter map
+//      output by NVSDK_NGX_GetCapabilityParameters, NVSDK_NGX_DestroyParameters should be used.
+//      Unlike with NVSDK_NGX_GetParameters, parameter maps allocated with NVSDK_NGX_GetCapabilityParameters
+//      must be destroyed by the app using NVSDK_NGX_DestroyParameters.
+//      This function may return NVSDK_NGX_Result_FAIL_OutOfDate if an older driver, which
+//      does not support this API call is being used. This function may only be called
+//      after a successful call into NVSDK_NGX_Init.
+//      If NVSDK_NGX_GetCapabilityParameters fails with NVSDK_NGX_Result_FAIL_OutOfDate,
+//      NVSDK_NGX_GetParameters may be used as a fallback, to get a parameter map pre-populated
+//      with NGX capabilities and available features.
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters);
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_DestroyParameters
+// ----------------------------------------------------------
+//
+// InParameters:
+//      The parameters interface to be destroyed
+//
+// DESCRIPTION:
+//      This interface allows the app to destroy the parameter map passed in. Once
+//      NVSDK_NGX_DestroyParameters is called on a parameter map, it
+//      must not be used again.
+//      NVSDK_NGX_DestroyParameters must not be called on any parameter map returned
+//      by NVSDK_NGX_GetParameters; NGX will manage the lifetime of those
+//      parameter maps.
+//      This function may return NVSDK_NGX_Result_FAIL_OutOfDate if an older driver, which
+//      does not support this API call is being used. This function may only be called
+//      after a successful call into NVSDK_NGX_Init.
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_DestroyParameters(NVSDK_NGX_Parameter* InParameters);
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_GetScratchBufferSize
+// ----------------------------------------------------------
+//
+// InFeatureId:
+//      AI feature in question
+//
+// InParameters:
+//      Parameters used by the feature to help estimate scratch buffer size
+//
+// OutSizeInBytes:
+//      Number of bytes needed for the scratch buffer for the specified feature.
+//
+// DESCRIPTION:
+//      SDK needs a buffer of a certain size provided by the client in
+//      order to initialize AI feature. Once feature is no longer
+//      needed buffer can be released. It is safe to reuse the same
+//      scratch buffer for different features as long as minimum size
+//      requirement is met for all features. Please note that some
+//      features might not need a scratch buffer so return size of 0
+//      is completely valid.
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter *InParameters, size_t *OutSizeInBytes);
+
+/////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_CreateFeature
+// -------------------------------------
+//
+// InCmdBuffer:
+//      Command buffer to use to execute GPU commands. Must be:
+//      - Open and recording 
+
+// InFeatureID:
+//      AI feature to initialize
+//
+// InParameters:
+//      List of parameters 
+// 
+// OutHandle:
+//      Handle which uniquely identifies the feature. If feature with
+//      provided parameters already exists the "already exists" error code is returned.
+//
+// DESCRIPTION:
+//      Each feature needs to be created before it can be used. 
+//      Refer to the sample code to find out which input parameters
+//      are needed to create specific feature.
+//      CreateFeature() creates feature on single existing Device
+//      CreateFeature1() creates feature on the specified Device
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_CreateFeature(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_CreateFeature1(VkDevice InDevice, VkCommandBuffer InCmdList, NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
+
+/////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_Release
+// -------------------------------------
+// 
+// InHandle:
+//      Handle to feature to be released
+//
+// DESCRIPTION:
+//      Releases feature with a given handle.
+//      Handles are not reference counted so
+//      after this call it is invalid to use provided handle.
+//
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_ReleaseFeature(NVSDK_NGX_Handle *InHandle);
+
+/////////////////////////////////////////////////////////////////////////
+// NVSDK_NGX_EvaluateFeature
+// -------------------------------------
+//
+// InCmdList:[d3d12 only]
+//      Command list to use to execute GPU commands. Must be:
+//      - Open and recording 
+//      - With node mask including the device provided in NVSDK_NGX_D3D12_Init
+//      - Execute on non-copy command queue.
+// InDevCtx: [d3d11 only]
+//      Device context to use to execute GPU commands
+//
+// InFeatureHandle:
+//      Handle representing feature to be evaluated
+// 
+// InParameters:
+//      List of parameters required to evaluate feature
+//
+// InCallback:
+//      Optional callback for features which might take longer
+//      to execture. If specified SDK will call it with progress
+//      values in range 0.0f - 1.0f
+//
+// DESCRIPTION:
+//      Evaluates given feature using the provided parameters and
+//      pre-trained NN. Please note that for most features
+//      it can be benefitials to pass as many input buffers and parameters
+//      as possible (for example provide all render targets like color, albedo, normals, depth etc)
+//
+
+#ifdef __cplusplus
+typedef void (NVSDK_CONV *PFN_NVSDK_NGX_ProgressCallback)(float InCurrentProgress, bool &OutShouldCancel);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_EvaluateFeature(VkCommandBuffer InCmdList, const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback = NULL);
+#endif
+typedef void (NVSDK_CONV *PFN_NVSDK_NGX_ProgressCallback_C)(float InCurrentProgress, bool *OutShouldCancel);
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_EvaluateFeature_C(VkCommandBuffer InCmdList, const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback_C InCallback);
+
+// NGX return-code conversion-to-string utility only as a helper for debugging/logging - not for official use.
+const wchar_t* NVSDK_CONV GetNGXResultAsString(NVSDK_NGX_Result InNGXResult);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // #define NVSDK_NGX_VK_H

BIN
ThirdParty/DlssSdk/sdk/lib/Linux_x86_64/libnvsdk_ngx.a


BIN
ThirdParty/DlssSdk/sdk/lib/Linux_x86_64/rel/libnvidia-ngx-dlss.so.2.4.0


BIN
ThirdParty/DlssSdk/sdk/lib/Windows_x86_64/dev/nvngx_dlss.dll


BIN
ThirdParty/DlssSdk/sdk/lib/Windows_x86_64/rel/nvngx_dlss.dll


BIN
ThirdParty/DlssSdk/sdk/lib/Windows_x86_64/x86_64/nvsdk_ngx_d.lib


BIN
ThirdParty/DlssSdk/sdk/lib/Windows_x86_64/x86_64/nvsdk_ngx_d_dbg.lib


BIN
ThirdParty/DlssSdk/sdk/lib/Windows_x86_64/x86_64/nvsdk_ngx_d_dbg_iterator0.lib


BIN
ThirdParty/DlssSdk/sdk/lib/Windows_x86_64/x86_64/nvsdk_ngx_d_dbg_iterator1.lib


BIN
ThirdParty/DlssSdk/sdk/lib/Windows_x86_64/x86_64/nvsdk_ngx_d_iterator1.lib


Some files were not shown because too many files changed in this diff