Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions OptiScaler/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,9 @@ class Config
CustomOptional<bool> DontCreateD3D12DeviceForLuma { false };

// Upscalers
CustomOptional<std::string, SoftDefault> Dx11Upscaler { "fsr22" };
CustomOptional<std::string, SoftDefault> Dx12Upscaler { "xess" };
CustomOptional<std::string, SoftDefault> VulkanUpscaler { "fsr22" };
CustomOptional<std::string, SoftDefault> Dx11Upscaler { std::string(OptiKeys::FSR22) };
CustomOptional<std::string, SoftDefault> Dx12Upscaler { std::string(OptiKeys::XeSS) };
CustomOptional<std::string, SoftDefault> VulkanUpscaler { std::string(OptiKeys::FSR22) };

// Output Scaling
CustomOptional<bool> OutputScalingEnabled { false };
Expand Down
47 changes: 47 additions & 0 deletions OptiScaler/MathUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#pragma once
#include <numbers>
#include <cmath>

namespace OptiMath
{
// Radians per degree. Used to convert from degrees to radians
inline constexpr float DegToRad = std::numbers::pi_v<float> / 180.0f;
// Degrees per radian. Used to convert from radians to degrees
inline constexpr float RadToDeg = 180.0f / std::numbers::pi_v<float>;

// Converts from an angle in degrees to radians
[[nodiscard]] inline constexpr float GetRadiansFromDeg(const float deg) { return deg * DegToRad; }

// Converts from an angle in radians to degrees
[[nodiscard]] inline constexpr float GetDegreesFromRad(const float rad) { return rad * RadToDeg; }

/**
* @brief Calculates the vertical field of view for a camera from its horizontal FOV and its
* viewport dimensions according to the formula: vFov = 2 * arctan( tan( hFov / 2 ) * ( h / w ) ).
* @param hFovRad: Horizontal field of view
* @param width: Width of the camera viewport
* @param height: Height of the camera viewport
* @return Vertical FOV in radians
*/
[[nodiscard]] inline float GetVerticalFovFromHorizontal(const float hFovRad, const float width, const float height)
{
if (width <= 0.0f)
return 0.0f;
return 2.0f * std::atan(std::tan(hFovRad * 0.5f) * (height / width));
}

/**
* @brief Calculates the horizontal field of view for a camera from its vertical FOV and its
* viewport dimensions according to the formula: hFov = 2 * arctan( tan( vFov / 2 ) * ( w / h ) ).
* @param vFovRad: Vertical field of view in radians
* @param width: Width of the camera viewport
* @param height: Height of the camera viewport
* @return Horizontal FOV in radians
*/
[[nodiscard]] inline float GetHorizontalFovFromVertical(const float vFovRad, const float width, const float height)
{
if (height <= 0.0f)
return 0.0f;
return 2.0f * std::atan(std::tan(vFovRad * 0.5f) * (width / height));
}
} // namespace OptiMath
92 changes: 84 additions & 8 deletions OptiScaler/NVNGX_Parameter.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#pragma once
#include "SysUtils.h"

#include "Config.h"

#include <ankerl/unordered_dense.h>

// Use real NVNGX params encapsulated in custom one
Expand All @@ -18,6 +16,24 @@
#define LOG_PARAM(msg, ...)
#endif

/** @brief Indicates the lifetime management required by an NGX parameter table. */
namespace NGX_AllocTypes
{
// Key used to get/set enum from table
constexpr std::string_view AllocKey = "OptiScaler.ParamAllocType";

constexpr uint32_t Unknown = 0;
// Standard behavior in modern DLSS. Created with NGX Allocate(). Freed with Destroy().
constexpr uint32_t NVDynamic = 1;
// Legacy DLSS. Lifetime managed internally by the SDK.
constexpr uint32_t NVPersistent = 2;
// OptiScaler implementation used internally with new/delete.
constexpr uint32_t InternDynamic = 3;
// OptiScaler implementation for legacy applications. Must maintain a persistent instance
// for the lifetime of the application.
constexpr uint32_t InternPersistent = 4;
} // namespace NGX_AllocTypes

/// @brief Calculates the resolution scaling ratio override based on the provided quality level and current
/// configuration.
/// @param input The performance quality value (e.g. Quality, Balanced, Performance).
Expand Down Expand Up @@ -670,6 +686,15 @@ struct NVNGX_Parameters : public NVSDK_NGX_Parameter
{
std::string Name;

NVNGX_Parameters(std::string_view name, bool isPersistent) : Name(name)
{
// Old flag used to indicate custom table. Obsolete?
Set("OptiScaler", 1);
// New tracking flag
Set(NGX_AllocTypes::AllocKey.data(),
isPersistent ? NGX_AllocTypes::InternPersistent : NGX_AllocTypes::InternDynamic);
}

#ifdef ENABLE_ENCAPSULATED_PARAMS
NVSDK_NGX_Parameter* OriginalParam = nullptr;
#endif // ENABLE_ENCAPSULATED_PARAMS
Expand Down Expand Up @@ -981,13 +1006,64 @@ struct NVNGX_Parameters : public NVSDK_NGX_Parameter
}
};

/// @brief Allocates and populates a new NGX param map.
inline static NVNGX_Parameters* GetNGXParameters(std::string InName)
/**
* @brief Allocates and populates a new custom NGX param map. The persistence flag indicates
* whether the table should be destroyed when NGX DestroyParameters() is used.
*/
inline static NVNGX_Parameters* GetNGXParameters(std::string_view name, bool isPersistent)
{
auto params = new NVNGX_Parameters();
params->Name = InName;
auto params = new NVNGX_Parameters(name, isPersistent);
InitNGXParameters(params);
params->Set("OptiScaler", 1);

return params;
}

/**
* @brief Sets a custom tracking tag to indicate the memory management strategy required by
* the table, indicated by NGX_AllocTypes.
*/
inline static void SetNGXParamAllocType(NVSDK_NGX_Parameter& params, uint32_t allocType)
{
params.Set(NGX_AllocTypes::AllocKey.data(), allocType);
}

/**
* @brief Attempts to safely delete an NGX parameter table. Dynamically allocated NGX tables use the NGX API.
* OptiScaler tables use delete. Persistent tables are not freed.
*/
template <typename PFN_DestroyNGXParameters>
static inline bool TryDestroyNGXParameters(NVSDK_NGX_Parameter* InParameters, PFN_DestroyNGXParameters NVFree = nullptr)
{
if (InParameters == nullptr)
return false;

uint32_t allocType = NGX_AllocTypes::Unknown;
NVSDK_NGX_Result result = InParameters->Get(NGX_AllocTypes::AllocKey.data(), &allocType);

// Key not set. Either a bug, or the client application called Reset() on the table before destroying.
// Derived type unknown if this happens. Not safe to delete. Leaking is the best option.
if (result == NVSDK_NGX_Result_Fail)
{
LOG_WARN("Destroy called on NGX table with unset alloc type. Leaking.");
return false;
}

if (allocType == NGX_AllocTypes::NVDynamic)
{
if (NVFree != nullptr)
{
LOG_INFO("Calling NVFree");
result = NVFree(InParameters);
LOG_INFO("Calling NVFree result: {0:X}", (UINT) result);
return true;
}
else
return false;
}
else if (allocType == NGX_AllocTypes::InternDynamic)
{
delete static_cast<NVNGX_Parameters*>(InParameters);
return true;
}

return false;
}
4 changes: 3 additions & 1 deletion OptiScaler/OptiScaler.vcxproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
Expand Down Expand Up @@ -322,6 +322,8 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
<ClInclude Include="inputs\FSR2_Dx11.h" />
<ClInclude Include="inputs\FSR2_Vk.h" />
<ClInclude Include="inputs\XeSS_Dx11.h" />
<ClInclude Include="MathUtils.h" />
<ClInclude Include="OptiTexts.h" />
<ClInclude Include="shaders\depth_invert\DI_Common.h" />
<ClInclude Include="shaders\depth_invert\DI_Dx12.h" />
<ClInclude Include="shaders\depth_invert\precompiled\DI_Shader.h" />
Expand Down
5 changes: 4 additions & 1 deletion OptiScaler/OptiScaler.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@
<ClInclude Include="shaders\hud_copy\HudCopy_Dx12.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="shaders\hud_copy\precompile\HudCopy_Shader.h">
<ClInclude Include="MathUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="shaders\output_scaling\precompile\bcds_bicubic_Shader_Vk.h">
Expand Down Expand Up @@ -737,6 +737,9 @@
<ClInclude Include="shaders\render_ui\RUI_Dx12.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="OptiTexts.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Config.cpp">
Expand Down
52 changes: 52 additions & 0 deletions OptiScaler/OptiTexts.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

/**
* @brief Common strings and identifiers used internally by OptiScaler
*/
namespace OptiKeys
{
using CString = const char[];

// Application name provided to upscalers
inline constexpr CString ProjectID = "OptiScaler";

// ID code used for the Vulkan input provider
inline constexpr CString VkProvider = "OptiVk";
// ID code used for the DX11 input provider
inline constexpr CString Dx11Provider = "OptiDx11";
// ID code used for the DX12 input provider
inline constexpr CString Dx12Provider = "OptiDx12";

// ID code used for the XeSS upscaler backend
inline constexpr CString XeSS = "xess";
// ID code used for the XeSS upscaler backend used with the DirectX 11 on 12 compatibility layer
inline constexpr CString XeSS_11on12 = "xess_12";
// ID code used for the FSR 2.1.x upscaler backend
inline constexpr CString FSR21 = "fsr21";
// ID code used for the FSR 2.1.x upscaler backend used with the DirectX 11 on 12 compatibility layer
inline constexpr CString FSR21_11on12 = "fsr21_12";
// ID code used for the FSR 2.2.x upscaler backend
inline constexpr CString FSR22 = "fsr22";
// ID code used for the FSR 2.2.x upscaler backend used with the DirectX 11 on 12 compatibility layer
inline constexpr CString FSR22_11on12 = "fsr22_12";
// ID code used for the FSR 3.1+ upscaler backend
inline constexpr CString FSR31 = "fsr31";
// ID code used for the FSR 3.1+ upscaler backend used with the DirectX 11 on 12 compatibility layer
inline constexpr CString FSR31_11on12 = "fsr31_12";
// ID code used for the DLSS upscaler backend
inline constexpr CString DLSS = "dlss";
// ID code used for the DLSS-D/Ray Reconstruction upscaler+denoiser backend
inline constexpr CString DLSSD = "dlssd";

inline constexpr CString FSR_UpscaleWidth = "FSR.upscaleSize.width";
inline constexpr CString FSR_UpscaleHeight = "FSR.upscaleSize.height";

inline constexpr CString FSR_NearPlane = "FSR.cameraNear";
inline constexpr CString FSR_FarPlane = "FSR.cameraFar";
inline constexpr CString FSR_CameraFovVertical = "FSR.cameraFovAngleVertical";
inline constexpr CString FSR_FrameTimeDelta = "FSR.frameTimeDelta";
inline constexpr CString FSR_ViewSpaceToMetersFactor = "FSR.viewSpaceToMetersFactor";
inline constexpr CString FSR_TransparencyAndComp = "FSR.transparencyAndComposition";
inline constexpr CString FSR_Reactive = "FSR.reactive";

} // namespace OptiKeys
2 changes: 2 additions & 0 deletions OptiScaler/SysUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,5 @@ inline static void to_lower_in_place(std::string& string)
{
std::transform(string.begin(), string.end(), string.begin(), ::tolower);
}

#include "OptiTexts.h"
45 changes: 27 additions & 18 deletions OptiScaler/inputs/FG/FSR3_Dx12_FG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "Config.h"
#include "Util.h"
#include "MathUtils.h"

#include "resource.h"
#include "NVNGX_Parameter.h"
Expand All @@ -23,6 +24,7 @@
#include "fsr3/ffx_frameinterpolation.h"

const UINT fgContext = 0x1337;
using namespace OptiMath;

// Swapchain create
typedef FFX_API
Expand Down Expand Up @@ -1252,21 +1254,25 @@ void FSR3FG::SetUpscalerInputs(ID3D12GraphicsCommandList* InCmdList, NVSDK_NGX_P

float tempCameraNear = 0.0f;
float tempCameraFar = 0.0f;
InParameters->Get("FSR.cameraNear", &tempCameraNear);
InParameters->Get("FSR.cameraFar", &tempCameraFar);

if (!Config::Instance()->FsrUseFsrInputValues.value_or_default() ||
(tempCameraNear == 0.0f && tempCameraFar == 0.0f))
auto& state = State::Instance();
auto& cfg = *Config::Instance();
const auto& ngxParams = *InParameters;

ngxParams.Get(OptiKeys::FSR_NearPlane, &tempCameraNear);
ngxParams.Get(OptiKeys::FSR_FarPlane, &tempCameraFar);

if (!cfg.FsrUseFsrInputValues.value_or_default() || (tempCameraNear == 0.0f && tempCameraFar == 0.0f))
{
if (feature->DepthInverted())
{
cameraFar = Config::Instance()->FsrCameraNear.value_or_default();
cameraNear = Config::Instance()->FsrCameraFar.value_or_default();
cameraFar = cfg.FsrCameraNear.value_or_default();
cameraNear = cfg.FsrCameraFar.value_or_default();
}
else
{
cameraFar = Config::Instance()->FsrCameraFar.value_or_default();
cameraNear = Config::Instance()->FsrCameraNear.value_or_default();
cameraFar = cfg.FsrCameraFar.value_or_default();
cameraNear = cfg.FsrCameraNear.value_or_default();
}
}
else
Expand All @@ -1275,20 +1281,23 @@ void FSR3FG::SetUpscalerInputs(ID3D12GraphicsCommandList* InCmdList, NVSDK_NGX_P
cameraFar = tempCameraFar;
}

if (!Config::Instance()->FsrUseFsrInputValues.value_or_default() ||
InParameters->Get("FSR.cameraFovAngleVertical", &cameraVFov) != NVSDK_NGX_Result_Success)
if (!cfg.FsrUseFsrInputValues.value_or_default() ||
ngxParams.Get(OptiKeys::FSR_CameraFovVertical, &cameraVFov) != NVSDK_NGX_Result_Success)
{
if (Config::Instance()->FsrVerticalFov.has_value())
cameraVFov = Config::Instance()->FsrVerticalFov.value() * 0.0174532925199433f;
else if (Config::Instance()->FsrHorizontalFov.value_or_default() > 0.0f)
cameraVFov = 2.0f * atan((tan(Config::Instance()->FsrHorizontalFov.value() * 0.0174532925199433f) * 0.5f) /
(float) feature->TargetHeight() * (float) feature->TargetWidth());
if (cfg.FsrVerticalFov.has_value())
cameraVFov = GetRadiansFromDeg(cfg.FsrVerticalFov.value());
else if (cfg.FsrHorizontalFov.value_or_default() > 0.0f)
{
const float hFovRad = GetRadiansFromDeg(cfg.FsrHorizontalFov.value());
cameraVFov =
GetVerticalFovFromHorizontal(hFovRad, (float) feature->TargetWidth(), (float) feature->TargetHeight());
}
else
cameraVFov = 1.0471975511966f;
cameraVFov = GetRadiansFromDeg(60);
}

if (!Config::Instance()->FsrUseFsrInputValues.value_or_default())
InParameters->Get("FSR.viewSpaceToMetersFactor", &meterFactor);
if (!cfg.FsrUseFsrInputValues.value_or_default())
ngxParams.Get(OptiKeys::FSR_ViewSpaceToMetersFactor, &meterFactor);

State::Instance().lastFsrCameraFar = cameraFar;
State::Instance().lastFsrCameraNear = cameraNear;
Expand Down
Loading