mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-08-24 15:16:45 +00:00
Add version selection to Nvngx FFX output
This commit is contained in:
@@ -10,7 +10,12 @@ constexpr unsigned int NVNGX_PROVIDER_ID_OFFSET = 2000000;
|
||||
|
||||
class IFGNvngx
|
||||
{
|
||||
protected:
|
||||
feature_version _version { 0, 0, 0 };
|
||||
|
||||
public:
|
||||
feature_version version() const { return _version; };
|
||||
|
||||
virtual ~IFGNvngx() = default;
|
||||
|
||||
virtual int getMaxFakeFramesCount(API api) = 0;
|
||||
|
||||
@@ -331,8 +331,36 @@ NVSDK_NGX_Result Nvngx_FFX::D3D12_EvaluateFeature(ID3D12GraphicsCommandList* InC
|
||||
backendDesc.header.type = FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_DX12;
|
||||
backendDesc.device = InOurHandle->device;
|
||||
|
||||
if (State::Instance().fgChanged && InOurHandle->fgContext)
|
||||
{
|
||||
auto retCode = FfxApiProxy::D3D12_DestroyContext(&InOurHandle->fgContext, nullptr);
|
||||
|
||||
if (retCode == FFX_API_RETURN_OK)
|
||||
InOurHandle->fgContext = nullptr;
|
||||
else
|
||||
LOG_WARN("Could destroy FFX context");
|
||||
}
|
||||
|
||||
State::Instance().fgChanged = false;
|
||||
|
||||
if (InOurHandle->fgContext == nullptr)
|
||||
{
|
||||
ffxQueryDescGetVersions versionQuery {};
|
||||
versionQuery.header.type = FFX_API_QUERY_DESC_TYPE_GET_VERSIONS;
|
||||
versionQuery.createDescType = FFX_API_CREATE_CONTEXT_DESC_TYPE_FRAMEGENERATION;
|
||||
versionQuery.device = InOurHandle->device;
|
||||
uint64_t versionCount = 0;
|
||||
versionQuery.outputCount = &versionCount;
|
||||
// get number of versions for allocation
|
||||
FfxApiProxy::D3D12_Query(nullptr, &versionQuery.header);
|
||||
|
||||
State::Instance().ffxFGVersionIds.resize(versionCount);
|
||||
State::Instance().ffxFGVersionNames.resize(versionCount);
|
||||
versionQuery.versionIds = State::Instance().ffxFGVersionIds.data();
|
||||
versionQuery.versionNames = State::Instance().ffxFGVersionNames.data();
|
||||
// fill version ids and names arrays.
|
||||
FfxApiProxy::D3D12_Query(nullptr, &versionQuery.header);
|
||||
|
||||
ffxCreateContextDescFrameGeneration createFg {};
|
||||
createFg.header.type = FFX_API_CREATE_CONTEXT_DESC_TYPE_FRAMEGENERATION;
|
||||
|
||||
@@ -369,8 +397,8 @@ NVSDK_NGX_Result Nvngx_FFX::D3D12_EvaluateFeature(ID3D12GraphicsCommandList* InC
|
||||
createFg.flags |= FFX_FRAMEGENERATION_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS;
|
||||
}
|
||||
|
||||
// if (fgConstants.flags & FG_Flags::Async)
|
||||
createFg.flags |= FFX_FRAMEGENERATION_ENABLE_ASYNC_WORKLOAD_SUPPORT;
|
||||
if (Config::Instance()->FGAsync.value_or_default())
|
||||
createFg.flags |= FFX_FRAMEGENERATION_ENABLE_ASYNC_WORKLOAD_SUPPORT;
|
||||
|
||||
if (depthPlaneInfinite)
|
||||
createFg.flags |= FFX_FRAMEGENERATION_ENABLE_DEPTH_INFINITE;
|
||||
@@ -383,12 +411,32 @@ NVSDK_NGX_Result Nvngx_FFX::D3D12_EvaluateFeature(ID3D12GraphicsCommandList* InC
|
||||
|
||||
// TODO: add code for hudless with different formats
|
||||
|
||||
ffxReturnCode_t retCode = FfxApiProxy::D3D12_CreateContext(&InOurHandle->fgContext, &createFg.header, nullptr);
|
||||
|
||||
if (retCode != FFX_API_RETURN_OK)
|
||||
{
|
||||
LOG_ERROR("Failed to create FFX context");
|
||||
return NVSDK_NGX_Result_Fail;
|
||||
ScopedSkipSpoofing skipSpoofing {};
|
||||
ScopedSkipHeapCapture skipHeapCapture {};
|
||||
|
||||
// Currently 0 is non-ML FG and 1 is ML FG
|
||||
if (Config::Instance()->FfxFGIndex.value_or_default() < 0 ||
|
||||
Config::Instance()->FfxFGIndex.value_or_default() >= State::Instance().ffxFGVersionIds.size())
|
||||
Config::Instance()->FfxFGIndex.set_volatile_value(0);
|
||||
|
||||
ffxOverrideVersion override = { 0 };
|
||||
override.header.type = FFX_API_DESC_TYPE_OVERRIDE_VERSION;
|
||||
override.versionId = State::Instance().ffxFGVersionIds[Config::Instance()->FfxFGIndex.value_or_default()];
|
||||
|
||||
backendDesc.header.pNext = &override.header;
|
||||
|
||||
_version.parse_version(
|
||||
State::Instance().ffxFGVersionNames[Config::Instance()->FfxFGIndex.value_or_default()]);
|
||||
|
||||
ffxReturnCode_t retCode =
|
||||
FfxApiProxy::D3D12_CreateContext(&InOurHandle->fgContext, &createFg.header, nullptr);
|
||||
|
||||
if (retCode != FFX_API_RETURN_OK)
|
||||
{
|
||||
LOG_ERROR("Failed to create FFX context");
|
||||
return NVSDK_NGX_Result_Fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,8 +453,12 @@ NVSDK_NGX_Result Nvngx_FFX::D3D12_EvaluateFeature(ID3D12GraphicsCommandList* InC
|
||||
ffxConfigureDescFrameGeneration configureDesc {};
|
||||
configureDesc.header.type = FFX_API_CONFIGURE_DESC_TYPE_FRAMEGENERATION;
|
||||
configureDesc.frameGenerationEnabled = true;
|
||||
// configureDesc.allowAsyncWorkloads = true; // TODO: can crash
|
||||
configureDesc.allowAsyncWorkloads = Config::Instance()->FGAsync.value_or_default();
|
||||
configureDesc.flags = FFX_FRAMEGENERATION_FLAG_NO_SWAPCHAIN_CONTEXT_NOTIFY;
|
||||
|
||||
if (Config::Instance()->FGDebugView.value_or_default())
|
||||
configureDesc.flags |= FFX_FRAMEGENERATION_FLAG_DRAW_DEBUG_VIEW;
|
||||
|
||||
configureDesc.frameID = InOurHandle->lastFrameId;
|
||||
configureDesc.generationRect = { 0, 0, (int) InOurHandle->swapchainWidth, (int) InOurHandle->swapchainHeight };
|
||||
|
||||
|
||||
@@ -130,6 +130,16 @@ bool Nvngx_FG::isVulkanAvailable()
|
||||
return provider->isVulkanAvailable();
|
||||
}
|
||||
|
||||
feature_version Nvngx_FG::version()
|
||||
{
|
||||
auto* provider = getProvider();
|
||||
|
||||
if (!provider)
|
||||
return {};
|
||||
|
||||
return provider->version();
|
||||
}
|
||||
|
||||
void Nvngx_FG::setDebugView(bool enabled)
|
||||
{
|
||||
auto* provider = getProvider();
|
||||
|
||||
@@ -19,6 +19,7 @@ class Nvngx_FG
|
||||
static int getMaxFakeFramesCount(API api);
|
||||
static bool isDx12Available();
|
||||
static bool isVulkanAvailable();
|
||||
static feature_version version();
|
||||
|
||||
// TODO: nukem-specific, unify
|
||||
static void setDebugView(bool enabled);
|
||||
|
||||
@@ -3571,7 +3571,7 @@ void MenuCommon::RenderFrameGenerationRuntimeSettings(RenderMenuContext& ctx)
|
||||
|
||||
ImGui::SameLine(0.0f, 16.0f);
|
||||
|
||||
if (state.currentFG->Version().major > 3)
|
||||
if (state.currentFG && state.currentFG->Version().major > 3)
|
||||
{
|
||||
if (bool fgwm = config->FSRFGEnableWatermark.value_or_default();
|
||||
ImGui::Checkbox("Enable Watermark", &fgwm))
|
||||
@@ -4438,13 +4438,6 @@ void MenuCommon::RenderFrameGenerationRuntimeSettings(RenderMenuContext& ctx)
|
||||
|
||||
if (isLoaded)
|
||||
{
|
||||
if (bool disableHudless = config->NvngxFGDisableHudless.value_or_default();
|
||||
ImGui::Checkbox("Disable HUDless", &disableHudless))
|
||||
{
|
||||
config->NvngxFGDisableHudless = disableHudless;
|
||||
}
|
||||
ShowHelpMarker("Might be required for some sets of DispatchFlags");
|
||||
|
||||
if (activeNvngxFg == FGNvngxReplacement::Arturs)
|
||||
{
|
||||
if (bool showDebug = config->NvngxFGShowDebug.value_or_default();
|
||||
@@ -4513,8 +4506,93 @@ void MenuCommon::RenderFrameGenerationRuntimeSettings(RenderMenuContext& ctx)
|
||||
}
|
||||
else if (activeNvngxFg == FGNvngxReplacement::FFX)
|
||||
{
|
||||
// TODO: FSR version selection
|
||||
if (_ffxFGIndex < 0)
|
||||
_ffxFGIndex = config->FfxFGIndex.value_or_default();
|
||||
|
||||
if (state.ffxFGVersionNames.size() > 0)
|
||||
{
|
||||
ImGui::PushItemWidth(135.0f * menuResScale);
|
||||
|
||||
auto currentName = StrFmt("FSR %s", state.ffxFGVersionNames[_ffxFGIndex]);
|
||||
if (ImGui::BeginCombo("FFX FG", currentName.c_str()))
|
||||
{
|
||||
for (int n = 0; n < state.ffxFGVersionIds.size(); n++)
|
||||
{
|
||||
auto name = StrFmt("FSR %s", state.ffxFGVersionNames[n]);
|
||||
if (ImGui::Selectable(name.c_str(), config->FfxFGIndex.value_or_default() == n))
|
||||
_ffxFGIndex = n;
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
ShowHelpMarker("List of FGs reported by FFX SDK");
|
||||
|
||||
ImGui::SameLine(0.0f, 6.0f);
|
||||
|
||||
if (ImGui::Button("Change FG") && _ffxFGIndex != config->FfxFGIndex.value_or_default())
|
||||
{
|
||||
config->FfxFGIndex = _ffxFGIndex;
|
||||
state.fgChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool fgAsync = config->FGAsync.value_or_default();
|
||||
if (ImGui::Checkbox("Allow Async##2", &fgAsync))
|
||||
{
|
||||
config->FGAsync = fgAsync;
|
||||
|
||||
if (config->FGEnabled.value_or_default())
|
||||
{
|
||||
state.fgChanged = true;
|
||||
LOG_DEBUG("Async set FGChanged");
|
||||
}
|
||||
}
|
||||
ShowHelpMarker("Enable Async for better FG performance\nMight cause crashes, especially with HUD Fix!");
|
||||
|
||||
ImGui::SameLine(0.0f, 20.0f * menuResScale);
|
||||
bool fgDV = config->FGDebugView.value_or_default();
|
||||
if (ImGui::Checkbox("Debug View##3", &fgDV))
|
||||
{
|
||||
config->FGDebugView = fgDV;
|
||||
|
||||
if (config->FGEnabled.value_or_default())
|
||||
{
|
||||
state.fgChanged = true;
|
||||
LOG_DEBUG("DebugView set FGChanged");
|
||||
}
|
||||
}
|
||||
ShowHelpMarker("Enable FSR3.1-FG Debug view\n\n"
|
||||
"Top left: Game Motion Vectors\n"
|
||||
"Top middle: GMV Depth\n"
|
||||
"Top right: Optical Flow MV\n"
|
||||
"Middle: Interpolated frame only\n"
|
||||
"Bottom left: Disocclusion mask\n"
|
||||
"Bottom middle: Interpolation source (w/o UI)\n"
|
||||
"Bottom right: HUDless resource");
|
||||
|
||||
if (Nvngx_FG::version().major > 3)
|
||||
{
|
||||
ImGui::SameLine(0.0f, 20.0f * menuResScale);
|
||||
if (bool fgwm = config->FSRFGEnableWatermark.value_or_default();
|
||||
ImGui::Checkbox("Enable Watermark", &fgwm))
|
||||
{
|
||||
LOG_DEBUG("FSRFGEnableWatermark set FGWatermark: {}", fgwm);
|
||||
config->FSRFGEnableWatermark = fgwm;
|
||||
}
|
||||
|
||||
ShowHelpMarker("After changing this option, please Save Settings\n"
|
||||
"It will be applied on next launch.");
|
||||
}
|
||||
}
|
||||
|
||||
if (bool disableHudless = config->NvngxFGDisableHudless.value_or_default();
|
||||
ImGui::Checkbox("Disable HUDless", &disableHudless))
|
||||
{
|
||||
config->NvngxFGDisableHudless = disableHudless;
|
||||
}
|
||||
ShowHelpMarker("Might be required for some sets of DispatchFlags");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user