This commit is contained in:
cdozdil
2025-06-25 11:35:20 +03:00
37 changed files with 1495 additions and 1620 deletions
+5
View File
@@ -327,6 +327,11 @@ DlssReactiveMaskBias=auto
; true or false - Default (auto) is depends on GPU
Fsr4Update=auto
; Select FSR4 model to use
; 0 = model used for FSR AA/Quality, 5 = model used for FSR Ultra Performance
; From 0 to 5 - Default (auto) is game's default
Fsr4Model=auto
; Indicates input color resource contains perceptual sRGB colors
; Might improve IQ of FSR4
; true or false - Default (auto) is false
+5
View File
@@ -127,6 +127,10 @@ bool Config::Reload(std::filesystem::path iniPath)
FsrUseMaskForTransparency.set_from_config(readBool("FSR", "UseReactiveMaskForTransparency"));
DlssReactiveMaskBias.set_from_config(readFloat("FSR", "DlssReactiveMaskBias"));
Fsr4Update.set_from_config(readBool("FSR", "Fsr4Update"));
if (auto setting = readInt("FSR", "Fsr4Model"); setting.has_value() && setting >= 0 && setting <= 5)
Fsr4Model.set_from_config(setting);
FsrNonLinearPQ.set_from_config(readBool("FSR", "FsrNonLinearPQ"));
FsrNonLinearSRGB.set_from_config(readBool("FSR", "FsrNonLinearSRGB"));
FsrAgilitySDKUpgrade.set_from_config(readBool("FSR", "FsrAgilitySDKUpgrade"));
@@ -693,6 +697,7 @@ bool Config::SaveIni()
ini.SetValue("FSR", "DlssReactiveMaskBias",
GetFloatValue(Instance()->DlssReactiveMaskBias.value_for_config()).c_str());
ini.SetValue("FSR", "Fsr4Update", GetBoolValue(Instance()->Fsr4Update.value_for_config()).c_str());
ini.SetValue("FSR", "Fsr4Model", GetIntValue(Instance()->Fsr4Model.value_for_config()).c_str());
ini.SetValue("FSR", "FsrNonLinearPQ", GetBoolValue(Instance()->FsrNonLinearPQ.value_for_config()).c_str());
ini.SetValue("FSR", "FsrNonLinearSRGB", GetBoolValue(Instance()->FsrNonLinearSRGB.value_for_config()).c_str());
ini.SetValue("FSR", "FsrAgilitySDKUpgrade",
+1
View File
@@ -292,6 +292,7 @@ class Config
CustomOptional<int> Fsr3xIndex { 0 };
CustomOptional<bool> FsrUseMaskForTransparency { true };
CustomOptional<bool> Fsr4Update { false };
CustomOptional<uint32_t, NoDefault> Fsr4Model;
CustomOptional<bool> FsrNonLinearSRGB { false };
CustomOptional<bool> FsrNonLinearPQ { false };
CustomOptional<bool> FsrAgilitySDKUpgrade { false };
+51
View File
@@ -9,11 +9,14 @@
#include <Unknwn.h>
#include <Windows.h>
#include <scanner/scanner.h>
typedef HRESULT(__cdecl* PFN_AmdExtD3DCreateInterface)(IUnknown* pOuter, REFIID riid, void** ppvObject);
typedef uint64_t (*PFN_getModelBlob)(uint32_t preset, uint64_t unknown, uint64_t* source, uint64_t* size);
static HMODULE moduleAmdxc64 = nullptr;
static HMODULE fsr4Module = nullptr;
static PFN_getModelBlob o_getModelBlob = nullptr;
#pragma region GDI32
@@ -145,6 +148,22 @@ inline static std::vector<std::filesystem::path> GetDriverStore()
#pragma endregion
uint64_t hkgetModelBlob(uint32_t preset, uint64_t unknown, uint64_t* source, uint64_t* size)
{
LOG_FUNC();
if (Config::Instance()->Fsr4Model.has_value())
{
preset = Config::Instance()->Fsr4Model.value();
}
State::Instance().currentFsr4Model = preset;
auto result = o_getModelBlob(preset, unknown, source, size);
return result;
}
/* Potato_of_Doom's Implementation */
#pragma region IAmdExtFfxApi
@@ -200,6 +219,38 @@ struct AmdExtFfxApi : public IAmdExtFfxApi
return E_NOINTERFACE;
}
{
const char* pattern = "83 F9 05 0F 87 ? ? ? ?";
auto fsr4ModulePtr = (uintptr_t) fsr4Module;
const uintptr_t moduleEnd = [&]()
{
auto ntHeaders = reinterpret_cast<PIMAGE_NT_HEADERS64>(
fsr4ModulePtr + reinterpret_cast<PIMAGE_DOS_HEADER>(fsr4ModulePtr)->e_lfanew);
return static_cast<uintptr_t>(fsr4ModulePtr + ntHeaders->OptionalHeader.SizeOfImage);
}();
o_getModelBlob =
(PFN_getModelBlob) scanner::FindPattern(fsr4ModulePtr, moduleEnd - fsr4ModulePtr, pattern);
}
if (o_getModelBlob)
{
LOG_DEBUG("Hooking model selection");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&) o_getModelBlob, hkgetModelBlob);
DetourTransactionCommit();
}
else
{
LOG_ERROR("Couldn't hook model selection");
}
o_UpdateFfxApiProvider =
(PFN_UpdateFfxApiProvider) KernelBaseProxy::GetProcAddress_()(fsr4Module, "UpdateFfxApiProvider");
+1
View File
@@ -130,6 +130,7 @@ class State
// FSR3.x
std::vector<const char*> fsr3xVersionNames {};
std::vector<uint64_t> fsr3xVersionIds {};
uint32_t currentFsr4Model {};
// Linux check
bool isRunningOnLinux = false;
+44
View File
@@ -42,6 +42,46 @@ static std::vector<HMODULE> _asiHandles;
typedef const char*(CDECL* PFN_wine_get_version)(void);
typedef void (*PFN_InitializeASI)(void);
static inline void* ManualGetProcAddress(HMODULE hModule, const char* functionName)
{
if (!hModule)
return nullptr;
// Verify the alignment
auto dosHeader = (IMAGE_DOS_HEADER*) hModule;
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
return nullptr;
auto ntHeaders = (IMAGE_NT_HEADERS*) ((BYTE*) hModule + dosHeader->e_lfanew);
if (ntHeaders->Signature != IMAGE_NT_SIGNATURE)
return nullptr;
// Look at the export directory
IMAGE_DATA_DIRECTORY exportData = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
if (!exportData.VirtualAddress)
return nullptr;
auto exportDir = (IMAGE_EXPORT_DIRECTORY*) ((BYTE*) hModule + exportData.VirtualAddress);
DWORD* nameRvas = (DWORD*) ((BYTE*) hModule + exportDir->AddressOfNames);
WORD* ordinalTable = (WORD*) ((BYTE*) hModule + exportDir->AddressOfNameOrdinals);
DWORD* functionTable = (DWORD*) ((BYTE*) hModule + exportDir->AddressOfFunctions);
// Iterate over exported names
for (DWORD i = 0; i < exportDir->NumberOfNames; ++i)
{
const char* name = (const char*) hModule + nameRvas[i];
if (_stricmp(name, functionName) == 0)
{
WORD ordinal = ordinalTable[i];
DWORD funcRva = functionTable[ordinal];
return (BYTE*) hModule + funcRva;
}
}
return nullptr; // Not found
}
static bool IsRunningOnWine()
{
LOG_FUNC();
@@ -56,6 +96,10 @@ static bool IsRunningOnWine()
auto pWineGetVersion = (PFN_wine_get_version) KernelBaseProxy::GetProcAddress_()(ntdll, "wine_get_version");
// Workaround for the ntdll-Hide_Wine_Exports patch
if (!pWineGetVersion && KernelBaseProxy::GetProcAddress_()(ntdll, "wine_server_call") != nullptr)
pWineGetVersion = (PFN_wine_get_version) ManualGetProcAddress(ntdll, "wine_get_version");
if (pWineGetVersion)
{
LOG_INFO("Running on Wine {0}!", pWineGetVersion());
+1 -1
View File
@@ -23,7 +23,7 @@ void FSRFG_Dx12::ConfigureFramePaceTuning()
{
State::Instance().FSRFGFTPchanged = false;
if (_swapChainContext == nullptr || !isVersionOrBetter(Version(), { 3, 1, 3 }))
if (_swapChainContext == nullptr || Version() < feature_version { 3, 1, 3 })
return;
FfxSwapchainFramePacingTuning fpt {};
+1 -1
View File
@@ -1253,7 +1253,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
auto* feature = deviceContext->feature.get();
// FSR 3.1 supports upscaleSize that doesn't need reinit to change output resolution
if (!(feature->Name().starts_with("FSR") && isVersionOrBetter(feature->Version(), { 3, 1, 0 })) &&
if (!(feature->Name().starts_with("FSR") && feature->Version() >= feature_version { 3, 1, 0 }) &&
feature->UpdateOutputResolution(InParameters))
State::Instance().changeBackend[handleId] = true;
}
+2 -1
View File
@@ -2,6 +2,7 @@
std::map<xess_context_handle_t, NVSDK_NGX_Parameter*> _nvParams;
std::map<xess_context_handle_t, NVSDK_NGX_Handle*> _contexts;
std::map<xess_context_handle_t, MotionScale> _motionScales;
std::map<xess_context_handle_t, Scale> _motionScales;
std::map<xess_context_handle_t, Scale> _jitterScales;
std::map<xess_context_handle_t, xess_d3d12_init_params_t> _d3d12InitParams;
std::map<xess_context_handle_t, xess_vk_init_params_t> _vkInitParams;
+4 -3
View File
@@ -6,14 +6,15 @@
#include <xess_d3d12.h>
#include <xess_vk.h>
typedef struct MotionScale
typedef struct Scale
{
float x;
float y;
} motion_scale;
} scale;
extern std::map<xess_context_handle_t, NVSDK_NGX_Parameter*> _nvParams;
extern std::map<xess_context_handle_t, NVSDK_NGX_Handle*> _contexts;
extern std::map<xess_context_handle_t, MotionScale> _motionScales;
extern std::map<xess_context_handle_t, Scale> _motionScales;
extern std::map<xess_context_handle_t, Scale> _jitterScales;
extern std::map<xess_context_handle_t, xess_d3d12_init_params_t> _d3d12InitParams;
extern std::map<xess_context_handle_t, xess_vk_init_params_t> _vkInitParams;
+10 -2
View File
@@ -256,8 +256,13 @@ xess_result_t hk_xessGetJitterScale(xess_context_handle_t hContext, float* pX, f
{
LOG_DEBUG("");
*pX = 1.0f;
*pY = 1.0f;
if (!_jitterScales.contains(hContext))
return XESS_RESULT_ERROR_INVALID_CONTEXT;
auto scales = &_jitterScales[hContext];
*pX = scales->x;
*pY = scales->y;
return XESS_RESULT_SUCCESS;
}
@@ -369,6 +374,9 @@ xess_result_t hk_xessGetVelocityScale(xess_context_handle_t hContext, float* pX,
xess_result_t hk_xessSetJitterScale(xess_context_handle_t hContext, float x, float y)
{
LOG_DEBUG("x: {}, y: {}", x, y);
_jitterScales[hContext] = { x, y };
return XESS_RESULT_SUCCESS;
}
+14 -4
View File
@@ -224,8 +224,18 @@ xess_result_t hk_xessD3D12Execute(xess_context_handle_t hContext, ID3D12Graphics
}
}
params->Set(NVSDK_NGX_Parameter_Jitter_Offset_X, pExecParams->jitterOffsetX);
params->Set(NVSDK_NGX_Parameter_Jitter_Offset_Y, pExecParams->jitterOffsetY);
float jitterScaleX = 1.0f;
float jitterScaleY = 1.0f;
if (_jitterScales.contains(hContext))
{
auto scales = &_jitterScales[hContext];
jitterScaleX = scales->x;
jitterScaleY = scales->y;
}
params->Set(NVSDK_NGX_Parameter_Jitter_Offset_X, pExecParams->jitterOffsetX * jitterScaleX);
params->Set(NVSDK_NGX_Parameter_Jitter_Offset_Y, pExecParams->jitterOffsetY * jitterScaleY);
params->Set(NVSDK_NGX_Parameter_DLSS_Exposure_Scale, pExecParams->exposureScale);
params->Set(NVSDK_NGX_Parameter_Reset, pExecParams->resetHistory);
params->Set(NVSDK_NGX_Parameter_Width, pExecParams->inputWidth);
@@ -235,8 +245,8 @@ xess_result_t hk_xessD3D12Execute(xess_context_handle_t hContext, ID3D12Graphics
params->Set(NVSDK_NGX_Parameter_Depth, pExecParams->pDepthTexture);
params->Set(NVSDK_NGX_Parameter_ExposureTexture, pExecParams->pExposureScaleTexture);
if (!isVersionOrBetter({ XeSSProxy::Version().major, XeSSProxy::Version().minor, XeSSProxy::Version().patch },
{ 2, 0, 1 }))
if (feature_version { XeSSProxy::Version().major, XeSSProxy::Version().minor, XeSSProxy::Version().patch } <
feature_version { 2, 0, 1 })
params->Set(NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, pExecParams->pResponsivePixelMaskTexture);
else
params->Set("FSR.reactive", pExecParams->pResponsivePixelMaskTexture);
+14 -4
View File
@@ -254,8 +254,18 @@ xess_result_t hk_xessVKExecute(xess_context_handle_t hContext, VkCommandBuffer c
}
}
params->Set(NVSDK_NGX_Parameter_Jitter_Offset_X, pExecParams->jitterOffsetX);
params->Set(NVSDK_NGX_Parameter_Jitter_Offset_Y, pExecParams->jitterOffsetY);
float jitterScaleX = 1.0f;
float jitterScaleY = 1.0f;
if (_jitterScales.contains(hContext))
{
auto scales = &_jitterScales[hContext];
jitterScaleX = scales->x;
jitterScaleY = scales->y;
}
params->Set(NVSDK_NGX_Parameter_Jitter_Offset_X, pExecParams->jitterOffsetX * jitterScaleX);
params->Set(NVSDK_NGX_Parameter_Jitter_Offset_Y, pExecParams->jitterOffsetY * jitterScaleY);
params->Set(NVSDK_NGX_Parameter_DLSS_Exposure_Scale, pExecParams->exposureScale);
params->Set(NVSDK_NGX_Parameter_Reset, pExecParams->resetHistory);
params->Set(NVSDK_NGX_Parameter_Width, pExecParams->inputWidth);
@@ -288,8 +298,8 @@ xess_result_t hk_xessVKExecute(xess_context_handle_t hContext, VkCommandBuffer c
{
CreateNVRes(&pExecParams->responsivePixelMaskTexture, &biasNVRes[index]);
if (!isVersionOrBetter({ XeSSProxy::Version().major, XeSSProxy::Version().minor, XeSSProxy::Version().patch },
{ 2, 0, 1 }))
if (feature_version { XeSSProxy::Version().major, XeSSProxy::Version().minor, XeSSProxy::Version().patch } <
feature_version { 2, 0, 1 })
params->Set(NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, &biasNVRes[index]);
else
params->Set("FSR.reactive", &biasNVRes[index]);
-363
View File
@@ -1,363 +0,0 @@
#include "ImguiSpdLog.h"
class SinkLineContent
{
public:
spdlog::level::level_enum LogLevel; // If n_levels, the message pushed counts to the previous pushed line
int32_t BeginIndex; // Base offset into the text buffer
struct ColorDataRanges
{
uint32_t SubStringBegin : 12;
uint32_t SubStringEnd : 12;
uint32_t FormatTag : 8;
};
ImVector<ColorDataRanges> FormattedStringRanges;
};
// TODO: work on filters, they are really needed, did optimize the memory storage quite a bit tho
class ImGuiSpdLogAdaptor : public spdlog::sinks::base_sink<std::mutex>
{
using sink_t = spdlog::sinks::base_sink<std::mutex>;
public:
void DrawLogWindow()
{
if (ImGui::Begin("CyberXeSS Log", &ShowWindow))
{
// Options submenu menu
if (ImGui::BeginPopup("Options"))
{
ImGui::Checkbox("Auto-scroll", &EnableAutoScrolling);
ImGui::EndPopup();
}
if (ImGui::Button("Options"))
ImGui::OpenPopup("Options");
ImGui::SameLine();
ImGui::SameLine();
if (ImGui::Button("Clear"))
ClearLogBuffers();
ImGui::SameLine();
ImGui::Text("%d messages logged, using %dmb memory", NumberOfLogEntries,
(LoggedContent.size() + IndicesInBytes) / (1024 * 1024));
// Filter out physical messgaes through logger
static const char* LogLevels[] = SPDLOG_LEVEL_NAMES;
static const auto LogSelectionWidth = []() -> float
{
float LongestTextWidth = 0;
for (auto LogLevelText : LogLevels)
{
auto TextWidth = ImGui::CalcTextSize(LogLevelText).x;
if (TextWidth > LongestTextWidth)
LongestTextWidth = TextWidth;
}
return LongestTextWidth + ImGui::GetStyle().FramePadding.x * 2 + ImGui::GetFrameHeight();
}();
auto ComboBoxRightAlignment =
ImGui::GetWindowSize().x - (LogSelectionWidth + ImGui::GetStyle().WindowPadding.x);
auto ActiveLogLevel = spdlog::get_level();
ImGui::SetNextItemWidth(LogSelectionWidth);
ImGui::SameLine(ComboBoxRightAlignment);
ImGui::Combo("##ActiveLogLevel", reinterpret_cast<int32_t*>(&ActiveLogLevel), LogLevels,
sizeof(LogLevels) / sizeof(LogLevels[0]));
spdlog::set_level(ActiveLogLevel);
// Filter out messages on display
FilterTextMatch.Draw("##LogFilter",
ImGui::GetWindowSize().x - (LogSelectionWidth + ImGui::GetStyle().WindowPadding.x * 2 +
ImGui::GetStyle().FramePadding.x));
ImGui::SetNextItemWidth(LogSelectionWidth);
ImGui::SameLine(ComboBoxRightAlignment);
ImGui::Combo("##FilterLogLevel", &FilterLogLevel, LogLevels, sizeof(LogLevels) / sizeof(LogLevels[0]));
// Draw main log window
ImGui::Separator();
ImGui::BeginChild("LogTextView", ImVec2(0, 0), false,
ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
const std::lock_guard LogLock(sink_t::mutex_);
RebuildFilterWithPreviousStates();
ImGuiListClipper ViewClipper;
ViewClipper.Begin(FilteredView.size());
while (ViewClipper.Step())
{
int32_t StylesPushedToStack = 0;
for (auto ClipperLineNumber = ViewClipper.DisplayStart; ClipperLineNumber < ViewClipper.DisplayEnd;
++ClipperLineNumber)
{
auto& LogMetaDataEntry = LogMetaData[FilteredView[ClipperLineNumber]];
if (LogMetaDataEntry.LogLevel == spdlog::level::n_levels)
ImGui::Indent();
for (auto i = 0; i < LogMetaDataEntry.FormattedStringRanges.size(); ++i)
{
static const ImVec4 BrightColorsToVec[] {
{ 0, 0, 0, 1 }, // COLOR_BRIGHTBLACK
{ 1, 0, 0, 1 }, // COLOR_BRIGHTRED
{ 0, 1, 0, 1 }, // COLOR_BRIGHTGREEN
{ 1, 1, 0, 1 }, // COLOR_BRIGHTYELLOW
{ 0, 0, 1, 1 }, // COLOR_BRIGHTBLUE
{ 1, 0, 1, 1 }, // COLOR_BRIGHTMAGENTA
{ 0, 1, 1, 1 }, // COLOR_BRIGHTCYAN
{ 1, 1, 1, 1 } // COLOR_BRIGHTWHITE
};
ImGui::PushStyleColor(ImGuiCol_Text,
BrightColorsToVec[LogMetaDataEntry.FormattedStringRanges[i].FormatTag]);
++StylesPushedToStack;
auto FormatRangeBegin = LoggedContent.begin() + LogMetaDataEntry.BeginIndex +
LogMetaDataEntry.FormattedStringRanges[i].SubStringBegin;
auto FormatRangeEnd = LoggedContent.begin() + LogMetaDataEntry.BeginIndex +
LogMetaDataEntry.FormattedStringRanges[i].SubStringEnd;
ImGui::TextUnformatted(FormatRangeBegin, FormatRangeEnd);
if (LogMetaDataEntry.FormattedStringRanges.size() - (i + 1))
ImGui::SameLine();
}
if (LogMetaDataEntry.LogLevel == spdlog::level::n_levels)
ImGui::Unindent();
}
ImGui::PopStyleColor(StylesPushedToStack);
}
ViewClipper.End();
ImGui::PopStyleVar();
if (EnableAutoScrolling && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
ImGui::SetScrollHereY(1.0f);
ImGui::EndChild();
}
ImGui::End();
}
void ClearLogBuffers(IN bool DisableLock = false)
{
if (!DisableLock)
sink_t::mutex_.lock();
LoggedContent.clear();
LogMetaData.clear();
NumberOfLogEntries = 0;
IndicesInBytes = 0;
if (!DisableLock)
sink_t::mutex_.unlock();
}
protected:
// Writing version 2, this will accept ansi escape sequences for colors
void sink_it_(IN const spdlog::details::log_msg& LogMessage) final
{
// This is all protected by the base sink under a mutex
++NumberOfLogEntries;
// Format the logged message and push it into the text buffer
spdlog::memory_buf_t FormattedBuffer;
sink_t::formatter_->format(LogMessage, FormattedBuffer);
std::string FormattedText = FormattedBuffer;
// Process string by converting the color range passed to an escape sequence first,
// yes may not be the nicest way of doing this but its way easier to process later.
const char* ColorToEscapeSequence[] { ESC_BRIGHTMAGENTA, ESC_CYAN, ESC_BRIGHTGREEN,
ESC_BRIGHTYELLOW, ESC_BRIGHTRED, ESC_RED };
FormattedText.insert(LogMessage.color_range_start, ColorToEscapeSequence[LogMessage.level]);
FormattedText.insert(LogMessage.color_range_end + 5, "\x1b[0m");
bool FilterPassing = LogMessage.level >= FilterLogLevel;
FilterPassing &=
FilterTextMatch.PassFilter(FormattedText.c_str(), FormattedText.c_str() + FormattedText.size());
// Parse formatted logged string for ansi escape sequences
auto OldTextBufferSize = LoggedContent.size();
SinkLineContent MessageData2 { LogMessage.level, OldTextBufferSize };
AnsiEscapeSequenceTag LastSequenceTagSinceBegin = FORMAT_RESET_COLORS;
// Prematurely filter out immediately starting non default formats,
// and then enter the main processing loop
switch (FormattedText[0])
{
case '\x1b':
case '\n':
break;
default:
SinkLineContent::ColorDataRanges FormatPush { 0, 0, LastSequenceTagSinceBegin };
MessageData2.FormattedStringRanges.push_back(FormatPush);
break;
}
for (auto i = 0; i < FormattedText.size(); ++i)
{
switch (FormattedText[i])
{
case '\n':
{
// Handle new line bullshit, spdlog will terminate any logged message witha new line
// we can also assume this may not be the last line, so we continue the previous sequence into
// the next logically text line if necessary and reconfigure pushstate
if (MessageData2.FormattedStringRanges.size())
MessageData2.FormattedStringRanges.back().SubStringEnd = i;
if (FilterPassing)
FilteredView.push_back(LogMetaData.size());
LogMetaData.push_back(MessageData2);
IndicesInBytes += MessageData2.FormattedStringRanges.size() * sizeof(SinkLineContent::ColorDataRanges) +
sizeof(SinkLineContent);
MessageData2.LogLevel = spdlog::level::n_levels;
MessageData2.BeginIndex = OldTextBufferSize + i + 1;
MessageData2.FormattedStringRanges.clear();
// Continue previous escape sequences pushed in the previous line
SinkLineContent::ColorDataRanges FormatPush { i + 1, 0, LastSequenceTagSinceBegin };
MessageData2.FormattedStringRanges.push_back(FormatPush);
}
break;
case '\x1b':
{
// Handle ansi escape sequence, convert textual to operand
if (FormattedText[i + 1] != '[')
throw std::runtime_error("Invalid ansi escape sequence passed");
size_t PositionProcessed = 0;
auto EscapeSequenceCode = static_cast<AnsiEscapeSequenceTag>(
std::stoi(&FormattedText[i + 2],
&PositionProcessed)); // this may throw, in which case we let it pass down
if (FormattedText[i + 2 + PositionProcessed] != 'm')
throw std::runtime_error("Invalid ansi escape sequence operand was passed");
++PositionProcessed;
LastSequenceTagSinceBegin = EscapeSequenceCode;
SinkLineContent::ColorDataRanges FormatPush { i, 0, EscapeSequenceCode };
if (MessageData2.FormattedStringRanges.size())
MessageData2.FormattedStringRanges.back().SubStringEnd = FormatPush.SubStringBegin;
MessageData2.FormattedStringRanges.push_back(FormatPush);
// Now the escape code has to be removed from the string,
// the iterator has to be kept stable, otherwise the next round could skip a char
FormattedText.erase(FormattedText.begin() + i--, FormattedText.begin() + (i + 2 + PositionProcessed));
}
}
}
// Append processed string to log text buffer
LoggedContent.append(FormattedText.c_str(), FormattedText.c_str() + FormattedText.size());
}
void flush_() {}
private:
// TODO: Need to implement double buffering for the filter
void RebuildFilterWithPreviousStates()
{
int32_t RebuildType = PreviousFilterLevel != FilterLogLevel;
RebuildType |= memcmp(PreviousFilterText, FilterTextMatch.InputBuf, sizeof(PreviousFilterText));
if (RebuildType)
{
// Filter was completely changed, have to rebuild array (very expensive,
// this may result in short freezes or stuttering on really large logs,
// one way to solve this could be to defer the calculation of the filter view
// to a thread pool and use a double buffering mechanism)
auto NewLinePasses = false;
FilteredView.clear();
for (auto i = 0; i < LogMetaData.size(); ++i)
{
if (LogMetaData[i].LogLevel == spdlog::level::n_levels&&)
{
FilteredView.push_back(i);
continue;
}
if (LogMetaData[i].LogLevel < FilterLogLevel)
{
NewLinePasses = false;
continue;
}
auto LineBegin = LoggedContent.begin() + LogMetaData[i].BeginIndex +
LogMetaData[i].FormattedStringRanges.front().SubStringBegin;
auto LineEnd = LoggedContent.begin() + LogMetaData[i].BeginIndex +
LogMetaData[i].FormattedStringRanges.back().SubStringEnd;
if (!FilterTextMatch.PassFilter(LineBegin, LineEnd))
{
NewLinePasses = false;
continue;
}
NewLinePasses = true;
FilteredView.push_back(i);
}
}
PreviousFilterLevel = FilterLogLevel;
memcpy(PreviousFilterText, FilterTextMatch.InputBuf, sizeof(PreviousFilterText));
}
// Using faster more efficient replacements of stl types for rendering
ImGuiTextBuffer LoggedContent;
// Cannot use ImVetctor here as the type is not trivially copyable
std::vector<SinkLineContent> LogMetaData;
// the type has to be moved into, slightly more expensive
// but overall totally fine, at least no weird hacks
ImGuiTextFilter FilterTextMatch;
// A filtered array of indexes into the LogMetaData vector
ImVector<int32_t> FilteredView;
// this view is calculated once any filter changes
int32_t FilterLogLevel = spdlog::level::trace;
// Counts the number of entries logged
uint32_t NumberOfLogEntries = 0;
// Keeps track of the amount of memory allocated by indices
uint32_t IndicesInBytes = 0;
bool EnableAutoScrolling = true;
// Previous Frame's filterdata, if any of these change to the new values the filter has to be recalculated
int32_t PreviousFilterLevel = spdlog::level::trace;
decltype(ImGuiTextFilter::InputBuf) PreviousFilterText {};
};
-4
View File
@@ -1,4 +0,0 @@
#pragma once
#include "../pch.h"
#include "spdlog/sinks/base_sink.h"
#include "imgui/imgui.h"
File diff suppressed because it is too large Load Diff
+2 -4
View File
@@ -46,7 +46,7 @@ void fakenvapi::reportFGPresent(IDXGISwapChain* pSwapChain, bool fg_state, bool
// and it will call SetFrameGenFrameType for us
auto static ffxApiVersion = FfxApiProxy::VersionDx12();
constexpr feature_version requiredVersion = { 3, 1, 1 };
if (isVersionOrBetter(ffxApiVersion, requiredVersion) && updateModeAndContext())
if (ffxApiVersion >= requiredVersion && updateModeAndContext())
{
if (_lowLatencyContext != nullptr && _lowLatencyMode == Mode::AntiLag2)
{
@@ -91,12 +91,10 @@ bool fakenvapi::updateModeAndContext()
// fallback for older fakenvapi builds
if (Fake_GetAntiLagCtx)
{
_lowLatencyMode = Mode::LatencyFlex;
auto result = Fake_GetAntiLagCtx(&_lowLatencyContext);
if (result != NVAPI_OK)
LOG_ERROR("Can't get AntiLag 2 context from fakenvapi");
_lowLatencyMode = Mode::LatencyFlex;
else
_lowLatencyMode = Mode::AntiLag2;
+19 -20
View File
@@ -71,35 +71,34 @@ inline DWORD processId;
#define LOG_FUNC_RESULT(result) spdlog::trace(__FUNCTION__ " result: {0:X}", (UINT64) result)
typedef struct _feature_version
struct feature_version
{
unsigned int major;
unsigned int minor;
unsigned int patch;
} feature_version;
inline static bool isVersionOrBetter(const feature_version& current, const feature_version& required)
{
if (current.major > required.major)
bool operator==(const feature_version& other) const
{
return true;
return major == other.major && minor == other.minor && patch == other.patch;
}
if (current.major == required.major)
bool operator!=(const feature_version& other) const { return !(*this == other); }
bool operator<(const feature_version& other) const
{
if (current.minor > required.minor)
{
return true;
}
if (current.minor == required.minor)
{
if (current.patch >= required.patch)
{
return true;
}
}
if (major != other.major)
return major < other.major;
if (minor != other.minor)
return minor < other.minor;
return patch < other.patch;
}
return false;
}
bool operator>(const feature_version& other) const { return other < *this; }
bool operator<=(const feature_version& other) const { return !(other < *this); }
bool operator>=(const feature_version& other) const { return !(*this < other); }
};
inline static std::string wstring_to_string(const std::wstring& wide_str)
{
+3 -1
View File
@@ -16,7 +16,7 @@ std::pair<uintptr_t, uintptr_t> GetModule(const std::wstring_view moduleName)
return { moduleBase, moduleEnd };
}
uintptr_t FindPattern(uintptr_t startAddress, uintptr_t maxSize, const char* mask)
uintptr_t scanner::FindPattern(uintptr_t startAddress, uintptr_t maxSize, const char* mask)
{
std::vector<std::pair<uint8_t, bool>> pattern;
@@ -47,6 +47,7 @@ uintptr_t FindPattern(uintptr_t startAddress, uintptr_t maxSize, const char* mas
return std::distance(dataStart, sig) + startAddress;
}
// Has some issues with DLLs on Linux
uintptr_t scanner::GetAddress(const std::wstring_view moduleName, const std::string_view pattern, ptrdiff_t offset,
uintptr_t startAddress)
{
@@ -58,6 +59,7 @@ uintptr_t scanner::GetAddress(const std::wstring_view moduleName, const std::str
address = FindPattern(GetModule(moduleName.data()).first,
GetModule(moduleName.data()).second - GetModule(moduleName.data()).first, pattern.data());
// Use KernelBaseProxy::GetModuleHandleW_() ?
if ((GetModuleHandleW(moduleName.data()) != nullptr) && (address != NULL))
{
return (address + offset);
+1
View File
@@ -4,6 +4,7 @@
namespace scanner
{
uintptr_t FindPattern(uintptr_t startAddress, uintptr_t maxSize, const char* mask);
uintptr_t GetAddress(const std::wstring_view moduleName, const std::string_view pattern, ptrdiff_t offset = 0,
uintptr_t startAddress = 0);
uintptr_t GetOffsetFromInstruction(const std::wstring_view moduleName, const std::string_view pattern,
+6 -5
View File
@@ -98,12 +98,13 @@ bool IFeature::SetInitParameters(NVSDK_NGX_Parameter* InParameters)
LOG_INFO("Init Flag SharpenEnabled: {}", _initFlags.SharpenEnabled);
}
if (InParameters->Get(NVSDK_NGX_Parameter_Width, &width) == NVSDK_NGX_Result_Success &&
InParameters->Get(NVSDK_NGX_Parameter_Height, &height) == NVSDK_NGX_Result_Success &&
InParameters->Get(NVSDK_NGX_Parameter_OutWidth, &outWidth) == NVSDK_NGX_Result_Success &&
InParameters->Get(NVSDK_NGX_Parameter_OutHeight, &outHeight) == NVSDK_NGX_Result_Success &&
InParameters->Get(NVSDK_NGX_Parameter_PerfQualityValue, &pqValue) == NVSDK_NGX_Result_Success)
if (InParameters->Get(NVSDK_NGX_Parameter_OutWidth, &outWidth) == NVSDK_NGX_Result_Success &&
InParameters->Get(NVSDK_NGX_Parameter_OutHeight, &outHeight) == NVSDK_NGX_Result_Success)
{
InParameters->Get(NVSDK_NGX_Parameter_Width, &width);
InParameters->Get(NVSDK_NGX_Parameter_Height, &height);
InParameters->Get(NVSDK_NGX_Parameter_PerfQualityValue, &pqValue);
GetDynamicOutputResolution(InParameters, &outWidth, &outHeight);
// Thanks to Crytek added these checks
-6
View File
@@ -36,10 +36,4 @@ IFeature_Dx11::~IFeature_Dx11()
Bias.reset();
Bias = nullptr;
}
if (DT != nullptr && DT.get() != nullptr)
{
DT.reset();
DT = nullptr;
}
}
-2
View File
@@ -4,7 +4,6 @@
#include <shaders/rcas/RCAS_Dx11.h>
#include <shaders/output_scaling/OS_Dx11.h>
#include <shaders/bias/Bias_Dx11.h>
#include <shaders/depth_transfer/DT_Dx11.h>
class IFeature_Dx11 : public virtual IFeature
{
@@ -16,7 +15,6 @@ class IFeature_Dx11 : public virtual IFeature
std::unique_ptr<OS_Dx11> OutputScaler = nullptr;
std::unique_ptr<RCAS_Dx11> RCAS = nullptr;
std::unique_ptr<Bias_Dx11> Bias = nullptr;
std::unique_ptr<DepthTransfer_Dx11> DT = nullptr;
public:
virtual bool Init(ID3D11Device* InDevice, ID3D11DeviceContext* InContext, NVSDK_NGX_Parameter* InParameters) = 0;
+1 -1
View File
@@ -192,7 +192,7 @@ void DLSSFeature::ReadVersion()
_version = GetVersionUsingNGXSnippet(possibleDlls);
if (isVersionOrBetter(_version, { 0, 0, 0 }))
if (_version > feature_version { 0, 0, 0 })
LOG_INFO("DLSS v{0}.{1}.{2} loaded.", _version.major, _version.minor, _version.patch);
else
LOG_WARN("Failed to get version using NVSDK_NGX_GetSnippetVersion!");
@@ -93,7 +93,7 @@ bool DLSSFeatureDx11::Evaluate(ID3D11DeviceContext* InDeviceContext, NVSDK_NGX_P
NVSDK_NGX_Result nvResult;
bool rcasEnabled = isVersionOrBetter(Version(), { 2, 5, 1 });
bool rcasEnabled = Version() >= feature_version { 2, 5, 1 };
if (Config::Instance()->RcasEnabled.value_or(rcasEnabled) &&
(RCAS == nullptr || RCAS.get() == nullptr || !RCAS->IsInit()))
@@ -99,7 +99,7 @@ bool DLSSFeatureDx12::Evaluate(ID3D12GraphicsCommandList* InCommandList, NVSDK_N
return false;
}
bool rcasEnabled = isVersionOrBetter(Version(), { 2, 5, 1 });
bool rcasEnabled = Version() >= feature_version { 2, 5, 1 };
if (Config::Instance()->RcasEnabled.value_or(rcasEnabled) &&
(RCAS == nullptr || RCAS.get() == nullptr || !RCAS->IsInit()))
+1 -1
View File
@@ -186,7 +186,7 @@ void DLSSDFeature::ReadVersion()
_version = GetVersionUsingNGXSnippet(possibleDlls);
if (isVersionOrBetter(_version, { 0, 0, 0 }))
if (_version > feature_version { 0, 0, 0 })
LOG_INFO("DLSSD v{0}.{1}.{2} loaded.", _version.major, _version.minor, _version.patch);
else
LOG_WARN("Failed to get version using NVSDK_NGX_GetSnippetVersion!");
+17 -184
View File
@@ -4,8 +4,6 @@
#include "FSR2Feature_Dx11.h"
#include <magic_enum.hpp>
#define ASSIGN_DESC(dest, src) \
dest.Width = src.Width; \
dest.Height = src.Height; \
@@ -22,48 +20,6 @@
} \
} while ((void) 0, 0);
static inline DXGI_FORMAT resolveTypelessFormat(DXGI_FORMAT format)
{
switch (format)
{
case DXGI_FORMAT_R16G16B16A16_TYPELESS:
return DXGI_FORMAT_R16G16B16A16_FLOAT;
case DXGI_FORMAT_R32G32B32A32_TYPELESS:
return DXGI_FORMAT_R32G32B32A32_FLOAT;
case DXGI_FORMAT_R16G16_TYPELESS:
return DXGI_FORMAT_R16G16_FLOAT;
case DXGI_FORMAT_R32G32_TYPELESS:
return DXGI_FORMAT_R32G32_FLOAT;
case DXGI_FORMAT_R8G8B8A8_TYPELESS:
return DXGI_FORMAT_R8G8B8A8_UNORM;
case DXGI_FORMAT_R32G8X24_TYPELESS:
return DXGI_FORMAT_R32G32_FLOAT;
case DXGI_FORMAT_R32_TYPELESS:
return DXGI_FORMAT_R32_FLOAT;
case DXGI_FORMAT_R8G8_TYPELESS:
return DXGI_FORMAT_R8G8_UNORM;
case DXGI_FORMAT_R16_TYPELESS:
return DXGI_FORMAT_R16_FLOAT;
case DXGI_FORMAT_R8_TYPELESS:
return DXGI_FORMAT_R8_UNORM;
case DXGI_FORMAT_R24G8_TYPELESS:
return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
default:
return format; // Already typed or unknown
}
}
bool FSR2FeatureDx11::Init(ID3D11Device* InDevice, ID3D11DeviceContext* InContext, NVSDK_NGX_Parameter* InParameters)
{
LOG_FUNC();
@@ -101,9 +57,8 @@ bool FSR2FeatureDx11::CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_RE
return false;
originalTexture->GetDesc(&desc);
auto format = resolveTypelessFormat(desc.Format);
if ((bindFlags == 9999 || desc.BindFlags == bindFlags) && desc.Format == format)
if (desc.BindFlags == bindFlags)
{
ASSIGN_DESC(OutTextureRes->Desc, desc);
OutTextureRes->Texture = originalTexture;
@@ -112,7 +67,7 @@ bool FSR2FeatureDx11::CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_RE
}
if (OutTextureRes->usingOriginal || OutTextureRes->Texture == nullptr || desc.Width != OutTextureRes->Desc.Width ||
desc.Height != OutTextureRes->Desc.Height || format != OutTextureRes->Desc.Format ||
desc.Height != OutTextureRes->Desc.Height || desc.Format != OutTextureRes->Desc.Format ||
desc.BindFlags != OutTextureRes->Desc.BindFlags)
{
if (OutTextureRes->Texture != nullptr)
@@ -123,7 +78,6 @@ bool FSR2FeatureDx11::CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_RE
OutTextureRes->Texture = nullptr;
}
desc.Format = format;
OutTextureRes->usingOriginal = false;
ASSIGN_DESC(OutTextureRes->Desc, desc);
@@ -151,31 +105,6 @@ void FSR2FeatureDx11::ReleaseResources()
{
SAFE_RELEASE(bufferColor.Texture);
}
if (!bufferDepth.usingOriginal)
{
SAFE_RELEASE(bufferDepth.Texture);
}
if (!bufferExposure.usingOriginal)
{
SAFE_RELEASE(bufferExposure.Texture);
}
if (!bufferReactive.usingOriginal)
{
SAFE_RELEASE(bufferReactive.Texture);
}
if (!bufferVelocity.usingOriginal)
{
SAFE_RELEASE(bufferVelocity.Texture);
}
if (!bufferTransparency.usingOriginal)
{
SAFE_RELEASE(bufferTransparency.Texture);
}
}
bool FSR2FeatureDx11::InitFSR2(const NVSDK_NGX_Parameter* InParameters)
@@ -308,37 +237,6 @@ FSR2FeatureDx11::FSR2FeatureDx11(unsigned int InHandleId, NVSDK_NGX_Parameter* I
{
}
void FSR2FeatureDx11::LogResource(std::string name, ID3D11Texture2D* resource)
{
if (_frameCount > 1)
return;
D3D11_TEXTURE2D_DESC desc {};
resource->GetDesc(&desc);
LOG_DEBUG("{}: {}x{}, Format: {}, Usage: {}, Bind: {:X}, Misc: {:X}, CPU: {:X}, ArraySize: {}, MipLevels: {}, "
"SD.Count: {}, SD.Quality: {}",
name, desc.Width, desc.Height, magic_enum::enum_name(desc.Format), magic_enum::enum_name(desc.Usage),
desc.BindFlags, desc.MiscFlags, desc.CPUAccessFlags, desc.ArraySize, desc.MipLevels,
desc.SampleDesc.Count, desc.SampleDesc.Quality);
}
void FSR2FeatureDx11::LogParams(FfxFsr2DispatchDescription* params)
{
if (_frameCount > 1)
return;
LOG_DEBUG("Color: {}x{}, Format: {}", params->color.description.width, params->color.description.height,
magic_enum::enum_name(params->color.description.format));
LOG_DEBUG("Depth: {}x{}, Format: {}", params->depth.description.width, params->depth.description.height,
magic_enum::enum_name(params->depth.description.format));
LOG_DEBUG("Velocity: {}x{}, Format: {}", params->motionVectors.description.width,
params->motionVectors.description.height,
magic_enum::enum_name(params->motionVectors.description.format));
LOG_DEBUG("Output: {}x{}, Format: {}", params->output.description.width, params->output.description.height,
magic_enum::enum_name(params->output.description.format));
}
bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Parameter* InParameters)
{
LOG_FUNC();
@@ -353,6 +251,8 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet
ID3D11SamplerState* restoreSamplerStates[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {};
ID3D11Buffer* restoreCBVs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {};
ID3D11UnorderedAccessView* restoreUAVs[D3D11_1_UAV_SLOT_COUNT] = {};
ID3D11RenderTargetView* restoreRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {};
ID3D11DepthStencilView* restoreDSV = nullptr;
// backup compute shader resources
for (UINT i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++)
@@ -379,6 +279,12 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet
InContext->CSGetUnorderedAccessViews(i, 1, &restoreUAVs[i]);
}
DeviceContext->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, restoreRTVs, &restoreDSV);
// Unbind RenderTargets
ID3D11RenderTargetView* nullRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {};
DeviceContext->OMSetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, nullRTVs, nullptr);
FfxFsr2DispatchDescription params {};
params.commandList = InContext;
@@ -422,8 +328,6 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet
{
LOG_DEBUG("Color exist..");
LogResource("Color", (ID3D11Texture2D*) paramColor);
if (!CopyTexture(paramColor, &bufferColor, 40, true))
{
LOG_DEBUG("Can't copy Color!");
@@ -447,20 +351,8 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet
if (paramVelocity)
{
LogResource("Velocity", (ID3D11Texture2D*) paramVelocity);
if (!CopyTexture(paramVelocity, &bufferVelocity, 9999, true))
{
LOG_DEBUG("Can't copy Velocity!");
return false;
}
LOG_DEBUG("MotionVectors exist..");
if (bufferVelocity.Texture != nullptr)
params.motionVectors =
ffxGetResourceDX11(&_context, bufferVelocity.Texture, (wchar_t*) L"FSR2_MotionVectors");
else
params.motionVectors = ffxGetResourceDX11(&_context, paramVelocity, (wchar_t*) L"FSR2_MotionVectors");
params.motionVectors = ffxGetResourceDX11(&_context, paramVelocity, (wchar_t*) L"FSR2_MotionVectors");
}
else
{
@@ -476,8 +368,6 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet
if (paramOutput)
{
LogResource("Output", (ID3D11Texture2D*) paramOutput);
LOG_DEBUG("Output exist..");
if (useSS)
@@ -518,38 +408,7 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet
if (paramDepth)
{
LOG_DEBUG("Depth exist..");
auto depthTexture = (ID3D11Texture2D*) paramDepth;
LogResource("Depth", depthTexture);
D3D11_TEXTURE2D_DESC desc {};
depthTexture->GetDesc(&desc);
if (desc.Format == DXGI_FORMAT_R24G8_TYPELESS || desc.Format == DXGI_FORMAT_R32G8X24_TYPELESS)
{
if (DT == nullptr || DT.get() == nullptr)
DT = std::make_unique<DepthTransfer_Dx11>("DT", Device);
if (DT->Buffer() == nullptr)
DT->CreateBufferResource(Device, paramDepth);
if (DT->CanRender() && DT->Dispatch(Device, DeviceContext, depthTexture, DT->Buffer()))
params.depth = ffxGetResourceDX11(&_context, DT->Buffer(), (wchar_t*) L"FSR2_Depth");
else
params.depth = ffxGetResourceDX11(&_context, paramDepth, (wchar_t*) L"FSR2_Depth");
}
else
{
if (!CopyTexture(paramDepth, &bufferDepth, 9999, true))
{
LOG_DEBUG("Can't copy Depth!");
return false;
}
if (bufferDepth.Texture != nullptr)
params.depth = ffxGetResourceDX11(&_context, bufferDepth.Texture, (wchar_t*) L"FSR2_Depth");
else
params.depth = ffxGetResourceDX11(&_context, paramDepth, (wchar_t*) L"FSR2_Depth");
}
params.depth = ffxGetResourceDX11(&_context, paramDepth, (wchar_t*) L"FSR2_Depth");
}
else
{
@@ -569,19 +428,8 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet
if (paramExp)
{
LogResource("Exposure", (ID3D11Texture2D*) paramExp);
if (!CopyTexture(paramExp, &bufferExposure, 9999, true))
{
LOG_DEBUG("Can't copy Exposure!");
return false;
}
params.exposure = ffxGetResourceDX11(&_context, paramExp, (wchar_t*) L"FSR2_Exposure");
LOG_DEBUG("ExposureTexture exist..");
if (bufferExposure.Texture != nullptr)
params.exposure = ffxGetResourceDX11(&_context, bufferExposure.Texture, (wchar_t*) L"FSR2_Exposure");
else
params.exposure = ffxGetResourceDX11(&_context, paramExp, (wchar_t*) L"FSR2_Exposure");
}
else
{
@@ -601,27 +449,12 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet
{
if (paramReactiveMask)
{
LogResource("Input Bias", (ID3D11Texture2D*) paramReactiveMask);
LOG_DEBUG("Input Bias mask exist..");
Config::Instance()->DisableReactiveMask.set_volatile_value(false);
if (Config::Instance()->FsrUseMaskForTransparency.value_or_default())
{
if (!CopyTexture(paramReactiveMask, &bufferTransparency, 9999, true))
{
LOG_DEBUG("Can't copy Exposure!");
return false;
}
if (bufferTransparency.Texture != nullptr)
params.transparencyAndComposition =
ffxGetResourceDX11(&_context, bufferTransparency.Texture, (wchar_t*) L"FSR2_Transparency",
FFX_RESOURCE_STATE_COMPUTE_READ);
else
params.transparencyAndComposition = ffxGetResourceDX11(
&_context, paramReactiveMask, (wchar_t*) L"FSR2_Transparency", FFX_RESOURCE_STATE_COMPUTE_READ);
}
params.transparencyAndComposition = ffxGetResourceDX11(
&_context, paramReactiveMask, (wchar_t*) L"FSR2_Transparency", FFX_RESOURCE_STATE_COMPUTE_READ);
if (Config::Instance()->DlssReactiveMaskBias.value_or_default() > 0.0f && Bias->IsInit() &&
Bias->CreateBufferResource(Device, paramReactiveMask) && Bias->CanRender())
@@ -695,8 +528,6 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet
if (InParameters->Get(NVSDK_NGX_Parameter_DLSS_Pre_Exposure, &params.preExposure) != NVSDK_NGX_Result_Success)
params.preExposure = 1.0f;
LogParams(&params);
LOG_DEBUG("Dispatch!!");
auto result = ffxFsr2ContextDispatch(&_context, &params);
@@ -800,6 +631,8 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet
InContext->CSSetUnorderedAccessViews(i, 1, &restoreUAVs[i], 0);
}
DeviceContext->OMSetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, restoreRTVs, restoreDSV);
_frameCount++;
return true;
@@ -27,16 +27,11 @@ class FSR2FeatureDx11 : public FSR2Feature, public IFeature_Dx11
D3D11_TEXTURE2D_RESOURCE_C bufferColor = {};
D3D11_TEXTURE2D_RESOURCE_C bufferDepth = {};
D3D11_TEXTURE2D_RESOURCE_C bufferExposure = {};
D3D11_TEXTURE2D_RESOURCE_C bufferTransparency = {};
D3D11_TEXTURE2D_RESOURCE_C bufferReactive = {};
D3D11_TEXTURE2D_RESOURCE_C bufferVelocity = {};
bool CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_RESOURCE_C* OutTextureDesc, UINT bindFlags,
bool InCopy);
void ReleaseResources();
void LogResource(std::string name, ID3D11Texture2D* resource);
void LogParams(FfxFsr2DispatchDescription* params);
protected:
bool InitFSR2(const NVSDK_NGX_Parameter* InParameters) override;
+23 -149
View File
@@ -52,48 +52,6 @@ bool FSR31FeatureDx11::Init(ID3D11Device* InDevice, ID3D11DeviceContext* InConte
return false;
}
static inline DXGI_FORMAT resolveTypelessFormat(DXGI_FORMAT format)
{
switch (format)
{
case DXGI_FORMAT_R16G16B16A16_TYPELESS:
return DXGI_FORMAT_R16G16B16A16_FLOAT;
case DXGI_FORMAT_R32G32B32A32_TYPELESS:
return DXGI_FORMAT_R32G32B32A32_FLOAT;
case DXGI_FORMAT_R16G16_TYPELESS:
return DXGI_FORMAT_R16G16_FLOAT;
case DXGI_FORMAT_R32G32_TYPELESS:
return DXGI_FORMAT_R32G32_FLOAT;
case DXGI_FORMAT_R8G8B8A8_TYPELESS:
return DXGI_FORMAT_R8G8B8A8_UNORM;
case DXGI_FORMAT_R32G8X24_TYPELESS:
return DXGI_FORMAT_R32G32_FLOAT;
case DXGI_FORMAT_R32_TYPELESS:
return DXGI_FORMAT_R32_FLOAT;
case DXGI_FORMAT_R8G8_TYPELESS:
return DXGI_FORMAT_R8G8_UNORM;
case DXGI_FORMAT_R16_TYPELESS:
return DXGI_FORMAT_R16_FLOAT;
case DXGI_FORMAT_R8_TYPELESS:
return DXGI_FORMAT_R8_UNORM;
case DXGI_FORMAT_R24G8_TYPELESS:
return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
default:
return format; // Already typed or unknown
}
}
// register a DX11 resource to the backend
Fsr31::FfxResource ffxGetResource(ID3D11Resource* dx11Resource, wchar_t const* ffxResName,
Fsr31::FfxResourceStates state = Fsr31::FFX_RESOURCE_STATE_COMPUTE_READ)
@@ -125,9 +83,8 @@ bool FSR31FeatureDx11::CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_R
return false;
originalTexture->GetDesc(&desc);
auto format = resolveTypelessFormat(desc.Format);
if ((bindFlags == 9999 || desc.BindFlags == bindFlags) && desc.Format == format)
if (desc.BindFlags == bindFlags)
{
ASSIGN_DESC(OutTextureRes->Desc, desc);
OutTextureRes->Texture = originalTexture;
@@ -136,7 +93,7 @@ bool FSR31FeatureDx11::CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_R
}
if (OutTextureRes->usingOriginal || OutTextureRes->Texture == nullptr || desc.Width != OutTextureRes->Desc.Width ||
desc.Height != OutTextureRes->Desc.Height || format != OutTextureRes->Desc.Format ||
desc.Height != OutTextureRes->Desc.Height || desc.Format != OutTextureRes->Desc.Format ||
desc.BindFlags != OutTextureRes->Desc.BindFlags)
{
if (OutTextureRes->Texture != nullptr)
@@ -147,7 +104,6 @@ bool FSR31FeatureDx11::CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_R
OutTextureRes->Texture = nullptr;
}
desc.Format = format;
OutTextureRes->usingOriginal = false;
ASSIGN_DESC(OutTextureRes->Desc, desc);
@@ -171,35 +127,12 @@ bool FSR31FeatureDx11::CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_R
void FSR31FeatureDx11::ReleaseResources()
{
LOG_FUNC();
if (!bufferColor.usingOriginal)
{
SAFE_RELEASE(bufferColor.Texture);
}
if (!bufferDepth.usingOriginal)
{
SAFE_RELEASE(bufferDepth.Texture);
}
if (!bufferExposure.usingOriginal)
{
SAFE_RELEASE(bufferExposure.Texture);
}
if (!bufferReactive.usingOriginal)
{
SAFE_RELEASE(bufferReactive.Texture);
}
if (!bufferVelocity.usingOriginal)
{
SAFE_RELEASE(bufferVelocity.Texture);
}
if (!bufferTransparency.usingOriginal)
{
SAFE_RELEASE(bufferTransparency.Texture);
}
}
bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Parameter* InParameters)
@@ -219,6 +152,8 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa
ID3D11SamplerState* restoreSamplerStates[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {};
ID3D11Buffer* restoreCBVs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {};
ID3D11UnorderedAccessView* restoreUAVs[D3D11_1_UAV_SLOT_COUNT] = {};
ID3D11RenderTargetView* restoreRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {};
ID3D11DepthStencilView* restoreDSV = nullptr;
// backup compute shader resources
for (UINT i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++)
@@ -245,6 +180,12 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa
DeviceContext->CSGetUnorderedAccessViews(i, 1, &restoreUAVs[i]);
}
DeviceContext->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, restoreRTVs, &restoreDSV);
// Unbind RenderTargets
ID3D11RenderTargetView* nullRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {};
DeviceContext->OMSetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, nullRTVs, nullptr);
Fsr31::FfxFsr3DispatchUpscaleDescription params {};
if (Config::Instance()->FsrDebugView.value_or_default())
@@ -325,19 +266,8 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa
if (paramVelocity)
{
LOG_DEBUG("MotionVectors exist..");
if (!CopyTexture(paramVelocity, &bufferVelocity, 9999, true))
{
LOG_DEBUG("Can't copy Velocity!");
return false;
}
if (bufferVelocity.Texture != nullptr)
params.motionVectors = ffxGetResource(bufferVelocity.Texture, L"FSR3_InputMotionVectors",
Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
else
params.motionVectors =
ffxGetResource(paramVelocity, L"FSR3_InputMotionVectors", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
params.motionVectors =
ffxGetResource(paramVelocity, L"FSR3_InputMotionVectors", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
}
else
{
@@ -390,39 +320,7 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa
if (paramDepth)
{
LOG_DEBUG("Depth exist..");
auto depthTexture = (ID3D11Texture2D*) paramDepth;
D3D11_TEXTURE2D_DESC desc {};
depthTexture->GetDesc(&desc);
if (desc.Format == DXGI_FORMAT_R24G8_TYPELESS || desc.Format == DXGI_FORMAT_R32G8X24_TYPELESS)
{
if (DT == nullptr || DT.get() == nullptr)
DT = std::make_unique<DepthTransfer_Dx11>("DT", Device);
if (DT->Buffer() == nullptr)
DT->CreateBufferResource(Device, paramDepth);
if (DT->CanRender() && DT->Dispatch(Device, DeviceContext, depthTexture, DT->Buffer()))
params.depth =
ffxGetResource(DT->Buffer(), L"FSR3_InputDepth", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
else
ffxGetResource(paramDepth, L"FSR3_InputDepth", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
}
else
{
if (!CopyTexture(paramDepth, &bufferDepth, 9999, true))
{
LOG_DEBUG("Can't copy Depth!");
return false;
}
if (bufferDepth.Texture != nullptr)
ffxGetResource(bufferDepth.Texture, L"FSR3_InputDepth", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
else
ffxGetResource(paramDepth, L"FSR3_InputDepth", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
}
params.depth = ffxGetResource(paramDepth, L"FSR3_InputDepth", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
}
else
{
@@ -444,20 +342,9 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa
if (paramExp)
{
params.exposure =
ffxGetResource(paramExp, L"FSR3_InputExposure", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
LOG_DEBUG("ExposureTexture exist..");
if (!CopyTexture(paramExp, &bufferExposure, 9999, true))
{
LOG_DEBUG("Can't copy Exposure!");
return false;
}
if (bufferVelocity.Texture != nullptr)
params.exposure = ffxGetResource(bufferVelocity.Texture, L"FSR3_InputExposure",
Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
else
params.exposure =
ffxGetResource(paramExp, L"FSR3_InputExposure", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
}
else
{
@@ -481,22 +368,9 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa
Config::Instance()->DisableReactiveMask.set_volatile_value(false);
if (Config::Instance()->FsrUseMaskForTransparency.value_or_default())
{
if (!CopyTexture(paramReactiveMask, &bufferTransparency, 9999, true))
{
LOG_DEBUG("Can't copy Transparency!");
return false;
}
if (bufferVelocity.Texture != nullptr)
params.transparencyAndComposition =
ffxGetResource(bufferVelocity.Texture, L"FSR3_TransparencyAndCompositionMap",
Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
else
params.transparencyAndComposition =
ffxGetResource(paramReactiveMask, L"FSR3_TransparencyAndCompositionMap",
Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
}
params.transparencyAndComposition =
ffxGetResource(paramReactiveMask, L"FSR3_TransparencyAndCompositionMap",
Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
if (Config::Instance()->DlssReactiveMaskBias.value_or_default() > 0.0f && Bias->IsInit() &&
Bias->CreateBufferResource(Device, paramReactiveMask) && Bias->CanRender())
@@ -579,7 +453,7 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa
params.upscaleSize.width = TargetWidth();
params.upscaleSize.height = TargetHeight();
if (isVersionOrBetter(Version(), { 3, 1, 1 }) && _velocity != Config::Instance()->FsrVelocity.value_or_default())
if (Version() >= feature_version { 3, 1, 1 } && _velocity != Config::Instance()->FsrVelocity.value_or_default())
{
_velocity = Config::Instance()->FsrVelocity.value_or_default();
auto result = ffxFsr3SetUpscalerConstant(
@@ -701,6 +575,8 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa
DeviceContext->CSSetUnorderedAccessViews(i, 1, &restoreUAVs[i], 0);
}
DeviceContext->OMSetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, restoreRTVs, restoreDSV);
_frameCount++;
return true;
@@ -711,8 +587,6 @@ FSR31FeatureDx11::~FSR31FeatureDx11()
if (!IsInited())
return;
ReleaseResources();
if (!State::Instance().isShuttingDown)
{
auto errorCode = Fsr31::ffxFsr3ContextDestroy(&_upscalerContext);
@@ -81,14 +81,10 @@ class FSR31FeatureDx11 : public FSR31Feature, public IFeature_Dx11
D3D11_TEXTURE2D_RESOURCE_C bufferColor = {};
D3D11_TEXTURE2D_RESOURCE_C bufferDepth = {};
D3D11_TEXTURE2D_RESOURCE_C bufferExposure = {};
D3D11_TEXTURE2D_RESOURCE_C bufferTransparency = {};
D3D11_TEXTURE2D_RESOURCE_C bufferReactive = {};
D3D11_TEXTURE2D_RESOURCE_C bufferVelocity = {};
bool CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_RESOURCE_C* OutTextureDesc, UINT bindFlags,
bool InCopy);
void ReleaseResources();
protected:
@@ -331,8 +331,7 @@ bool FSR31FeatureDx11on12::Evaluate(ID3D11DeviceContext* InDeviceContext, NVSDK_
params.viewSpaceToMetersFactor = 1.0f;
// Version 3.1.1 check
if (isVersionOrBetter(Version(), { 3, 1, 1 }) &&
_velocity != Config::Instance()->FsrVelocity.value_or_default())
if (Version() >= feature_version { 3, 1, 1 } && _velocity != Config::Instance()->FsrVelocity.value_or_default())
{
_velocity = Config::Instance()->FsrVelocity.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
@@ -345,60 +344,59 @@ bool FSR31FeatureDx11on12::Evaluate(ID3D11DeviceContext* InDeviceContext, NVSDK_
LOG_WARN("Velocity configure result: {}", (UINT) result);
}
if (isVersionOrBetter(Version(), { 3, 1, 4 }) &&
_reactiveScale != Config::Instance()->FsrReactiveScale.value_or_default())
if (Version() >= feature_version { 3, 1, 4 })
{
_reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FREACTIVENESSSCALE;
m_upscalerKeyValueConfig.ptr = &_reactiveScale;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (_reactiveScale != Config::Instance()->FsrReactiveScale.value_or_default())
{
_reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FREACTIVENESSSCALE;
m_upscalerKeyValueConfig.ptr = &_reactiveScale;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Reactive Scale configure result: {}", (UINT) result);
}
if (result != FFX_API_RETURN_OK)
LOG_WARN("Reactive Scale configure result: {}", (UINT) result);
}
if (isVersionOrBetter(Version(), { 3, 1, 4 }) &&
_shadingScale != Config::Instance()->FsrShadingScale.value_or_default())
{
_shadingScale = Config::Instance()->FsrShadingScale.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FSHADINGCHANGESCALE;
m_upscalerKeyValueConfig.ptr = &_shadingScale;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (_shadingScale != Config::Instance()->FsrShadingScale.value_or_default())
{
_shadingScale = Config::Instance()->FsrShadingScale.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FSHADINGCHANGESCALE;
m_upscalerKeyValueConfig.ptr = &_shadingScale;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Shading Scale configure result: {}", (UINT) result);
}
if (result != FFX_API_RETURN_OK)
LOG_WARN("Shading Scale configure result: {}", (UINT) result);
}
if (isVersionOrBetter(Version(), { 3, 1, 4 }) &&
_accAddPerFrame != Config::Instance()->FsrAccAddPerFrame.value_or_default())
{
_accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FACCUMULATIONADDEDPERFRAME;
m_upscalerKeyValueConfig.ptr = &_accAddPerFrame;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (_accAddPerFrame != Config::Instance()->FsrAccAddPerFrame.value_or_default())
{
_accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FACCUMULATIONADDEDPERFRAME;
m_upscalerKeyValueConfig.ptr = &_accAddPerFrame;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Acc. Add Per Frame configure result: {}", (UINT) result);
}
if (result != FFX_API_RETURN_OK)
LOG_WARN("Acc. Add Per Frame configure result: {}", (UINT) result);
}
if (isVersionOrBetter(Version(), { 3, 1, 4 }) &&
_minDisOccAcc != Config::Instance()->FsrMinDisOccAcc.value_or_default())
{
_minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FMINDISOCCLUSIONACCUMULATION;
m_upscalerKeyValueConfig.ptr = &_minDisOccAcc;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (_minDisOccAcc != Config::Instance()->FsrMinDisOccAcc.value_or_default())
{
_minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FMINDISOCCLUSIONACCUMULATION;
m_upscalerKeyValueConfig.ptr = &_minDisOccAcc;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Minimum Disocclusion Acc. configure result: {}", (UINT) result);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Minimum Disocclusion Acc. configure result: {}", (UINT) result);
}
}
if (InParameters->Get("FSR.upscaleSize.width", &params.upscaleSize.width) == NVSDK_NGX_Result_Success &&
@@ -421,7 +421,7 @@ bool FSR31FeatureDx12::Evaluate(ID3D12GraphicsCommandList* InCommandList, NVSDK_
if (InParameters->Get(NVSDK_NGX_Parameter_DLSS_Pre_Exposure, &params.preExposure) != NVSDK_NGX_Result_Success)
params.preExposure = 1.0f;
if (isVersionOrBetter(Version(), { 3, 1, 1 }) && _velocity != Config::Instance()->FsrVelocity.value_or_default())
if (Version() >= feature_version { 3, 1, 1 } && _velocity != Config::Instance()->FsrVelocity.value_or_default())
{
_velocity = Config::Instance()->FsrVelocity.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
@@ -434,60 +434,59 @@ bool FSR31FeatureDx12::Evaluate(ID3D12GraphicsCommandList* InCommandList, NVSDK_
LOG_WARN("Velocity configure result: {}", (UINT) result);
}
if (isVersionOrBetter(Version(), { 3, 1, 4 }) &&
_reactiveScale != Config::Instance()->FsrReactiveScale.value_or_default())
if (Version() >= feature_version { 3, 1, 4 })
{
_reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FREACTIVENESSSCALE;
m_upscalerKeyValueConfig.ptr = &_reactiveScale;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (_reactiveScale != Config::Instance()->FsrReactiveScale.value_or_default())
{
_reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FREACTIVENESSSCALE;
m_upscalerKeyValueConfig.ptr = &_reactiveScale;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Reactive Scale configure result: {}", (UINT) result);
}
if (result != FFX_API_RETURN_OK)
LOG_WARN("Reactive Scale configure result: {}", (UINT) result);
}
if (isVersionOrBetter(Version(), { 3, 1, 4 }) &&
_shadingScale != Config::Instance()->FsrShadingScale.value_or_default())
{
_shadingScale = Config::Instance()->FsrShadingScale.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FSHADINGCHANGESCALE;
m_upscalerKeyValueConfig.ptr = &_shadingScale;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (_shadingScale != Config::Instance()->FsrShadingScale.value_or_default())
{
_shadingScale = Config::Instance()->FsrShadingScale.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FSHADINGCHANGESCALE;
m_upscalerKeyValueConfig.ptr = &_shadingScale;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Shading Scale configure result: {}", (UINT) result);
}
if (result != FFX_API_RETURN_OK)
LOG_WARN("Shading Scale configure result: {}", (UINT) result);
}
if (isVersionOrBetter(Version(), { 3, 1, 4 }) &&
_accAddPerFrame != Config::Instance()->FsrAccAddPerFrame.value_or_default())
{
_accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FACCUMULATIONADDEDPERFRAME;
m_upscalerKeyValueConfig.ptr = &_accAddPerFrame;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (_accAddPerFrame != Config::Instance()->FsrAccAddPerFrame.value_or_default())
{
_accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FACCUMULATIONADDEDPERFRAME;
m_upscalerKeyValueConfig.ptr = &_accAddPerFrame;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Acc. Add Per Frame configure result: {}", (UINT) result);
}
if (result != FFX_API_RETURN_OK)
LOG_WARN("Acc. Add Per Frame configure result: {}", (UINT) result);
}
if (isVersionOrBetter(Version(), { 3, 1, 4 }) &&
_minDisOccAcc != Config::Instance()->FsrMinDisOccAcc.value_or_default())
{
_minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FMINDISOCCLUSIONACCUMULATION;
m_upscalerKeyValueConfig.ptr = &_minDisOccAcc;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (_minDisOccAcc != Config::Instance()->FsrMinDisOccAcc.value_or_default())
{
_minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FMINDISOCCLUSIONACCUMULATION;
m_upscalerKeyValueConfig.ptr = &_minDisOccAcc;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Minimum Disocclusion Acc. configure result: {}", (UINT) result);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Minimum Disocclusion Acc. configure result: {}", (UINT) result);
}
}
if (InParameters->Get("FSR.upscaleSize.width", &params.upscaleSize.width) == NVSDK_NGX_Result_Success &&
+46 -47
View File
@@ -512,7 +512,7 @@ bool FSR31FeatureVk::Evaluate(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Parameter*
if (InParameters->Get(NVSDK_NGX_Parameter_DLSS_Pre_Exposure, &params.preExposure) != NVSDK_NGX_Result_Success)
params.preExposure = 1.0f;
if (isVersionOrBetter(Version(), { 3, 1, 1 }) && _velocity != Config::Instance()->FsrVelocity.value_or_default())
if (Version() >= feature_version { 3, 1, 1 } && _velocity != Config::Instance()->FsrVelocity.value_or_default())
{
_velocity = Config::Instance()->FsrVelocity.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
@@ -525,60 +525,59 @@ bool FSR31FeatureVk::Evaluate(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Parameter*
LOG_WARN("Velocity configure result: {}", (UINT) result);
}
if (isVersionOrBetter(Version(), { 3, 1, 4 }) &&
_reactiveScale != Config::Instance()->FsrReactiveScale.value_or_default())
if (Version() >= feature_version { 3, 1, 4 })
{
_reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FREACTIVENESSSCALE;
m_upscalerKeyValueConfig.ptr = &_reactiveScale;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (_reactiveScale != Config::Instance()->FsrReactiveScale.value_or_default())
{
_reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FREACTIVENESSSCALE;
m_upscalerKeyValueConfig.ptr = &_reactiveScale;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Reactive Scale configure result: {}", (UINT) result);
}
if (result != FFX_API_RETURN_OK)
LOG_WARN("Reactive Scale configure result: {}", (UINT) result);
}
if (isVersionOrBetter(Version(), { 3, 1, 4 }) &&
_shadingScale != Config::Instance()->FsrShadingScale.value_or_default())
{
_shadingScale = Config::Instance()->FsrShadingScale.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FSHADINGCHANGESCALE;
m_upscalerKeyValueConfig.ptr = &_shadingScale;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (_shadingScale != Config::Instance()->FsrShadingScale.value_or_default())
{
_shadingScale = Config::Instance()->FsrShadingScale.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FSHADINGCHANGESCALE;
m_upscalerKeyValueConfig.ptr = &_shadingScale;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Shading Scale configure result: {}", (UINT) result);
}
if (result != FFX_API_RETURN_OK)
LOG_WARN("Shading Scale configure result: {}", (UINT) result);
}
if (isVersionOrBetter(Version(), { 3, 1, 4 }) &&
_accAddPerFrame != Config::Instance()->FsrAccAddPerFrame.value_or_default())
{
_accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FACCUMULATIONADDEDPERFRAME;
m_upscalerKeyValueConfig.ptr = &_accAddPerFrame;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (_accAddPerFrame != Config::Instance()->FsrAccAddPerFrame.value_or_default())
{
_accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FACCUMULATIONADDEDPERFRAME;
m_upscalerKeyValueConfig.ptr = &_accAddPerFrame;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Acc. Add Per Frame configure result: {}", (UINT) result);
}
if (result != FFX_API_RETURN_OK)
LOG_WARN("Acc. Add Per Frame configure result: {}", (UINT) result);
}
if (isVersionOrBetter(Version(), { 3, 1, 4 }) &&
_minDisOccAcc != Config::Instance()->FsrMinDisOccAcc.value_or_default())
{
_minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FMINDISOCCLUSIONACCUMULATION;
m_upscalerKeyValueConfig.ptr = &_minDisOccAcc;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (_minDisOccAcc != Config::Instance()->FsrMinDisOccAcc.value_or_default())
{
_minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default();
ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {};
m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FMINDISOCCLUSIONACCUMULATION;
m_upscalerKeyValueConfig.ptr = &_minDisOccAcc;
auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Minimum Disocclusion Acc. configure result: {}", (UINT) result);
if (result != FFX_API_RETURN_OK)
LOG_WARN("Minimum Disocclusion Acc. configure result: {}", (UINT) result);
}
}
if (InParameters->Get("FSR.upscaleSize.width", &params.upscaleSize.width) == NVSDK_NGX_Result_Success &&
@@ -241,12 +241,13 @@ bool XeSSFeatureDx12::Evaluate(ID3D12GraphicsCommandList* InCommandList, NVSDK_N
else
LOG_DEBUG("AutoExposure enabled!");
bool supportsFloatResponsivePixelMask = Version() >= feature_version { 2, 0, 1 };
ID3D12Resource* paramReactiveMask = nullptr;
if (isVersionOrBetter(Version(), { 2, 0, 1 }) &&
if (supportsFloatResponsivePixelMask &&
InParameters->Get("FSR.reactive", &paramReactiveMask) == NVSDK_NGX_Result_Success)
{
if (!Config::Instance()->DisableReactiveMask.value_or(!isVersionOrBetter(Version(), { 2, 0, 1 })))
if (!Config::Instance()->DisableReactiveMask.value_or(!supportsFloatResponsivePixelMask))
params.pResponsivePixelMaskTexture = paramReactiveMask;
}
else
@@ -255,8 +256,7 @@ bool XeSSFeatureDx12::Evaluate(ID3D12GraphicsCommandList* InCommandList, NVSDK_N
NVSDK_NGX_Result_Success)
InParameters->Get(NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, (void**) &paramReactiveMask);
if (!Config::Instance()->DisableReactiveMask.value_or(!isVersionOrBetter(Version(), { 2, 0, 1 })) &&
paramReactiveMask)
if (!Config::Instance()->DisableReactiveMask.value_or(!supportsFloatResponsivePixelMask) && paramReactiveMask)
{
LOG_DEBUG("Input Bias mask exist..");
Config::Instance()->DisableReactiveMask = false;
+4 -2
View File
@@ -505,8 +505,10 @@ bool XeSSFeature_Vk::Evaluate(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Parameter*
else
LOG_DEBUG("AutoExposure enabled!");
bool supportsFloatResponsivePixelMask = Version() >= feature_version { 2, 0, 1 };
NVSDK_NGX_Resource_VK* paramReactiveMask = nullptr;
if (isVersionOrBetter(Version(), { 2, 0, 1 }) &&
if (supportsFloatResponsivePixelMask &&
InParameters->Get("FSR.reactive", (void**) &paramReactiveMask) == NVSDK_NGX_Result_Success)
{
if (!Config::Instance()->DisableReactiveMask.value_or(true))
@@ -521,7 +523,7 @@ bool XeSSFeature_Vk::Evaluate(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Parameter*
LOG_DEBUG("Input Bias mask exist..");
Config::Instance()->DisableReactiveMask = false;
if (!Config::Instance()->DisableReactiveMask.value_or(!isVersionOrBetter(Version(), { 2, 0, 1 })))
if (!Config::Instance()->DisableReactiveMask.value_or(!supportsFloatResponsivePixelMask))
params.responsivePixelMaskTexture = NV_to_XeSS(paramReactiveMask);
}
else
+325
View File
@@ -0,0 +1,325 @@
#!/bin/bash
# Setup OptiScaler for your game (Linux version)
clear
echo " :::::::: ::::::::: ::::::::::: ::::::::::: :::::::: :::::::: ::: ::: :::::::::: ::::::::: "
echo ":+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: "
echo "#+: +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ "
echo "+#+ +:+ +#++:++#+ +#+ +#+ +#++:++#++ +#+ +#++:++#++: +#+ +#++:++# +#++:++#: "
echo "+#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ "
echo "#+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# "
echo " ######## ### ### ########### ######## ######## ### ### ########## ########## ### ### "
echo ""
echo "Coping is strong with this one..."
echo ""
# Remove extraction marker file if it exists
rm -f "$SCRIPT_DIR/!! EXTRACT ALL FILES TO GAME FOLDER !!" 2>/dev/null
# Get the script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
GAME_PATH="$SCRIPT_DIR"
OPTISCALER_FILE="$GAME_PATH/OptiScaler.dll"
SETUP_SUCCESS=false
# Check if OptiScaler.dll exists
if [ ! -f "OptiScaler.dll" ]; then
echo "OptiScaler \"OptiScaler.dll\" file is not found!"
echo "Please make sure you extracted all OptiScaler files to the game folder."
echo ""
echo "For Unreal Engine games, look for the game executable in:"
echo "- <path-to-game>/Game-or-Project-name/Binaries/Win64/"
echo "- Ignore the Engine folder"
echo ""
read -p "Press Enter to exit..."
exit 1
fi
# Check if the Engine folder exists (Unreal Engine detection)
if [ -d "$GAME_PATH/Engine" ]; then
echo "Found Engine folder, if this is an Unreal Engine game then please extract OptiScaler to #CODENAME#/Binaries/Win64"
echo ""
while true; do
read -p "Continue installation to current folder? [y/n]: " continue_choice
continue_choice=$(echo "$continue_choice" | tr -d ' ')
if [ "$continue_choice" = "y" ] || [ "$continue_choice" = "Y" ]; then
break
elif [ "$continue_choice" = "n" ] || [ "$continue_choice" = "N" ]; then
echo "Installation cancelled."
read -p "Press Enter to exit..."
exit 0
fi
done
fi
# Function to select filename
select_filename() {
while true; do
echo ""
echo "Choose a filename for OptiScaler (default is dxgi.dll):"
echo " [1] dxgi.dll"
echo " [2] winmm.dll"
echo " [3] version.dll"
echo " [4] dbghelp.dll"
echo " [5] d3d12.dll"
echo " [6] wininet.dll"
echo " [7] winhttp.dll"
echo " [8] OptiScaler.asi"
read -p "Enter 1-8 (or press Enter for default): " filename_choice
case "$filename_choice" in
""|"1")
selected_filename="dxgi.dll"
;;
"2")
selected_filename="winmm.dll"
;;
"3")
selected_filename="version.dll"
;;
"4")
selected_filename="dbghelp.dll"
;;
"5")
selected_filename="d3d12.dll"
;;
"6")
selected_filename="wininet.dll"
;;
"7")
selected_filename="winhttp.dll"
;;
"8")
selected_filename="OptiScaler.asi"
;;
*)
echo "Invalid choice. Please select a valid option."
echo ""
continue
;;
esac
# Check if file already exists
if [ -f "$selected_filename" ]; then
echo ""
echo "WARNING: $selected_filename already exists in the current folder."
echo ""
while true; do
read -p "Do you want to overwrite $selected_filename? [y/n]: " overwrite_choice
overwrite_choice=$(echo "$overwrite_choice" | tr -d ' ')
if [ "$overwrite_choice" = "y" ] || [ "$overwrite_choice" = "Y" ]; then
break 2 # Break out of both loops
elif [ "$overwrite_choice" = "n" ] || [ "$overwrite_choice" = "N" ]; then
break # Break inner loop, continue filename selection
fi
done
else
break # File doesn't exist, proceed
fi
done
}
# Call filename selection function
select_filename
echo ""
# Try to detect GPU type
NVIDIA_DETECTED=false
if command -v nvidia-smi >/dev/null 2>&1; then
if nvidia-smi >/dev/null 2>&1; then
NVIDIA_DETECTED=true
echo "Nvidia GPU detected."
fi
elif [ -d "/proc/driver/nvidia" ] || lspci 2>/dev/null | grep -i nvidia >/dev/null 2>&1; then
NVIDIA_DETECTED=true
echo "Nvidia GPU detected."
fi
# GPU type detection and configuration
echo ""
echo "Are you using an Nvidia GPU or AMD/Intel GPU?"
echo "[1] AMD/Intel"
echo "[2] Nvidia"
while true; do
if [ "$NVIDIA_DETECTED" = true ]; then
read -p "Enter 1 or 2 (or press Enter for Nvidia): " gpu_choice
else
read -p "Enter 1 or 2 (or press Enter for AMD/Intel): " gpu_choice
fi
case "$gpu_choice" in
""|"1")
# Default logic: if Nvidia detected, skip AMD/Intel unless explicitly chosen
if [ "$gpu_choice" = "1" ] || [ "$NVIDIA_DETECTED" = false ]; then
# AMD/Intel GPU - ask about DLSS usage
echo ""
echo "Will you try to use DLSS inputs? (enables spoofing, required for DLSS FG, Reflex->AL2)"
echo "[1] Yes"
echo "[2] No"
while true; do
read -p "Enter 1 or 2 (or press Enter for Yes): " enabling_spoofing
case "$enabling_spoofing" in
""|"1")
# Keep spoofing enabled (default)
break
;;
"2")
# Disable spoofing
config_file="OptiScaler.ini"
if [ ! -f "$config_file" ]; then
echo "Config file not found: $config_file"
read -p "Press Enter to continue..."
else
# Use sed to replace Dxgi=auto with Dxgi=false
sed -i 's/Dxgi=auto/Dxgi=false/g' "$config_file"
echo "Spoofing disabled in configuration."
fi
break
;;
*)
echo "Invalid choice. Please enter 1 or 2."
continue
;;
esac
done
fi
break
;;
"2")
# Nvidia GPU - skip spoofing configuration
break
;;
*)
echo "Invalid choice. Please enter 1 or 2."
continue
;;
esac
done
# Complete setup - rename OptiScaler file
echo ""
if [ "$overwrite_choice" = "y" ] || [ "$overwrite_choice" = "Y" ]; then
echo "Removing previous $selected_filename..."
rm -f "$selected_filename"
fi
echo "Renaming OptiScaler file to $selected_filename..."
if ! mv "$OPTISCALER_FILE" "$selected_filename"; then
echo ""
echo "ERROR: Failed to rename OptiScaler file to $selected_filename."
echo "Please check file permissions and try again."
read -p "Press Enter to exit..."
exit 1
fi
# Create uninstaller
create_uninstaller() {
cat > "remove_optiscaler.sh" << 'EOF'
#!/bin/bash
clear
echo " :::::::: ::::::::: ::::::::::: ::::::::::: :::::::: :::::::: ::: ::: :::::::::: ::::::::: "
echo ":+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: "
echo "#+: +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ "
echo "+#+ +:+ +#++:++#+ +#+ +#+ +#++:++#++ +#+ +#++:++#++: +#+ +#++:++# +#++:++#: "
echo "+#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ "
echo "#+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# "
echo " ######## ### ### ########### ######## ######## ### ### ########## ########## ### ### "
echo ""
echo "Coping is strong with this one..."
echo ""
read -p "Do you want to remove OptiScaler? [y/n]: " remove_choice
if [ "$remove_choice" = "y" ] || [ "$remove_choice" = "Y" ]; then
echo ""
echo "Removing OptiScaler files..."
# Remove OptiScaler files
rm -f OptiScaler.log
rm -f OptiScaler.ini
rm -f "OptiScaler Setup.bat"
rm -f SELECTED_FILENAME_PLACEHOLDER
# Remove directories
rm -rf D3D12_Optiscaler
rm -rf DlssOverrides
rm -rf Licenses
echo ""
echo "OptiScaler removed!"
echo ""
# Remove this uninstaller
rm -f "$0"
else
echo ""
echo "Operation cancelled."
echo ""
fi
read -p "Press Enter to exit..."
EOF
# Replace the placeholder with the actual selected filename
sed -i "s/SELECTED_FILENAME_PLACEHOLDER/$selected_filename/g" "remove_optiscaler.sh"
# Make the uninstaller executable
chmod +x "remove_optiscaler.sh"
echo ""
echo "Uninstaller created: remove_optiscaler.sh"
echo ""
}
# Create the uninstaller
create_uninstaller
# Success message
clear
echo " OptiScaler setup completed successfully..."
echo ""
echo " ___ "
echo " (_ ' "
echo " /__ /) / () (/ "
echo " _/ / "
echo ""
# Display Wine DLL override information
echo "IMPORTANT FOR LINUX/WINE USERS:"
echo "You need to add the renamed DLL to Wine overrides:"
echo ""
echo "WINEDLLOVERRIDES=$selected_filename=n,b %COMMAND%"
echo ""
echo "For example, if using Steam, add this to launch options:"
echo "WINEDLLOVERRIDES=$selected_filename=n,b %command%"
echo ""
echo "Remember: Insert key opens OptiScaler overlay, Page Up/Down for performance stats"
echo ""
echo "Note: If you need to send log files for support, set LogLevel=0 and"
echo "LogToFile=true in OptiScaler.ini (forced debugging is disabled since 0.7.7-Pre8)"
echo ""
echo "IMPORTANT: Do not rename OptiScaler.ini - it must stay as OptiScaler.ini"
echo ""
SETUP_SUCCESS=true
# Cleanup - remove setup script
read -p "Press Enter to exit..."
if [ "$SETUP_SUCCESS" = true ]; then
# Remove this setup script
rm -f "$0"
fi
exit 0