Skip to content

Refactor XeSS #482

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions OptiScaler/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define _CRT_SECURE_NO_DEPRECATE
#include <Windows.h>
#include <string>
#include <variant>
#include <stdint.h>
#include <libloaderapi.h>

Expand Down
316 changes: 99 additions & 217 deletions OptiScaler/upscalers/xess/XeSSFeature.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include "XeSSFeature.h"

#include <pch.h>
Expand All @@ -15,27 +15,37 @@ inline void XeSSLogCallback(const char* Message, xess_logging_level_t Level)
}

bool XeSSFeature::InitXeSS(ID3D12Device* device, const NVSDK_NGX_Parameter* InParameters)
{

return true;
}

XeSSFeature::XeSSFeature(unsigned int handleId, NVSDK_NGX_Parameter* InParameters) : IFeature(handleId, InParameters)
{
_initParameters = SetInitParameters(InParameters);
}

bool XeSSFeature::Init(ApiContext* context, const NVSDK_NGX_Parameter* InParameters)
{
LOG_FUNC();
if (IsInited())
return true;

if (!_moduleLoaded)
{
LOG_ERROR("libxess.dll not loaded!");
return false;
}

if (IsInited())
return true;

if (device == nullptr)
if (!CheckInitializationContext(context))
{
LOG_ERROR("D3D12Device is null!");
LOG_ERROR("XeSSFeature::Init context is not valid!");
return false;
}

State::Instance().skipSpoofing = true;

auto ret = XeSSProxy::D3D12CreateContext()(device, &_xessContext);
auto ret = CreateXessContext(context, &_xessContext);

if (ret != XESS_RESULT_SUCCESS)
{
Expand All @@ -49,88 +59,9 @@ bool XeSSFeature::InitXeSS(ID3D12Device* device, const NVSDK_NGX_Parameter* InPa
ret = XeSSProxy::SetLoggingCallback()(_xessContext, XESS_LOGGING_LEVEL_DEBUG, XeSSLogCallback);
LOG_DEBUG("xessSetLoggingCallback : {0}", ResultToString(ret));

xess_d3d12_init_params_t xessParams {};

xessParams.initFlags = XESS_INIT_FLAG_NONE;

if (DepthInverted())
xessParams.initFlags |= XESS_INIT_FLAG_INVERTED_DEPTH;

if (AutoExposure())
xessParams.initFlags |= XESS_INIT_FLAG_ENABLE_AUTOEXPOSURE;
else
xessParams.initFlags |= XESS_INIT_FLAG_EXPOSURE_SCALE_TEXTURE;

if (!IsHdr())
xessParams.initFlags |= XESS_INIT_FLAG_LDR_INPUT_COLOR;

if (JitteredMV())
xessParams.initFlags |= XESS_INIT_FLAG_JITTERED_MV;

if (!LowResMV())
xessParams.initFlags |= XESS_INIT_FLAG_HIGH_RES_MV;

if (!Config::Instance()->DisableReactiveMask.value_or(true))
{
xessParams.initFlags |= XESS_INIT_FLAG_RESPONSIVE_PIXEL_MASK;
LOG_DEBUG("xessParams.initFlags (ReactiveMaskActive) {0:b}", xessParams.initFlags);
}

switch (PerfQualityValue())
{
case NVSDK_NGX_PerfQuality_Value_UltraPerformance:
if (Version().major >= 1 && Version().minor >= 3)
xessParams.qualitySetting = XESS_QUALITY_SETTING_ULTRA_PERFORMANCE;
else
xessParams.qualitySetting = XESS_QUALITY_SETTING_PERFORMANCE;

break;

case NVSDK_NGX_PerfQuality_Value_MaxPerf:
if (Version().major >= 1 && Version().minor >= 3)
xessParams.qualitySetting = XESS_QUALITY_SETTING_BALANCED;
else
xessParams.qualitySetting = XESS_QUALITY_SETTING_PERFORMANCE;

break;

case NVSDK_NGX_PerfQuality_Value_Balanced:
if (Version().major >= 1 && Version().minor >= 3)
xessParams.qualitySetting = XESS_QUALITY_SETTING_QUALITY;
else
xessParams.qualitySetting = XESS_QUALITY_SETTING_BALANCED;

break;

case NVSDK_NGX_PerfQuality_Value_MaxQuality:
if (Version().major >= 1 && Version().minor >= 3)
xessParams.qualitySetting = XESS_QUALITY_SETTING_ULTRA_QUALITY;
else
xessParams.qualitySetting = XESS_QUALITY_SETTING_QUALITY;

break;
uint32_t initFlags = GetInitFlags();

case NVSDK_NGX_PerfQuality_Value_UltraQuality:
if (Version().major >= 1 && Version().minor >= 3)
xessParams.qualitySetting = XESS_QUALITY_SETTING_ULTRA_QUALITY_PLUS;
else
xessParams.qualitySetting = XESS_QUALITY_SETTING_ULTRA_QUALITY;

break;

case NVSDK_NGX_PerfQuality_Value_DLAA:
if (Version().major >= 1 && Version().minor >= 3)
xessParams.qualitySetting = XESS_QUALITY_SETTING_AA;
else
xessParams.qualitySetting = XESS_QUALITY_SETTING_ULTRA_QUALITY;

break;

default:
xessParams.qualitySetting =
XESS_QUALITY_SETTING_BALANCED; // Set out-of-range value for non-existing XESS_QUALITY_SETTING_BALANCED mode
break;
}
xess_quality_settings_t qualitySetting = GetQualitySetting();

if (Config::Instance()->OutputScalingEnabled.value_or(false) && LowResMV())
{
Expand Down Expand Up @@ -169,114 +100,9 @@ bool XeSSFeature::InitXeSS(ID3D12Device* device, const NVSDK_NGX_Parameter* InPa
}
}

xessParams.outputResolution.x = TargetWidth();
xessParams.outputResolution.y = TargetHeight();

// create heaps to prevent create heap errors of xess
if (Config::Instance()->CreateHeaps.value_or(true))
{
HRESULT hr;
xess_properties_t xessProps {};
ret = XeSSProxy::GetProperties()(_xessContext, &xessParams.outputResolution, &xessProps);

if (ret == XESS_RESULT_SUCCESS)
{
CD3DX12_HEAP_DESC bufferHeapDesc(xessProps.tempBufferHeapSize, D3D12_HEAP_TYPE_DEFAULT);
State::Instance().skipHeapCapture = true;
hr = device->CreateHeap(&bufferHeapDesc, IID_PPV_ARGS(&_localBufferHeap));
State::Instance().skipHeapCapture = false;

if (SUCCEEDED(hr))
{
D3D12_HEAP_DESC textureHeapDesc { xessProps.tempTextureHeapSize,
{ D3D12_HEAP_TYPE_DEFAULT, D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
D3D12_MEMORY_POOL_UNKNOWN, 0, 0 },
0,
D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES };

State::Instance().skipHeapCapture = true;
hr = device->CreateHeap(&textureHeapDesc, IID_PPV_ARGS(&_localTextureHeap));
State::Instance().skipHeapCapture = false;

if (SUCCEEDED(hr))
{
Config::Instance()->CreateHeaps = true;

LOG_DEBUG("using _localBufferHeap & _localTextureHeap!");

xessParams.bufferHeapOffset = 0;
xessParams.textureHeapOffset = 0;
xessParams.pTempBufferHeap = _localBufferHeap;
xessParams.pTempTextureHeap = _localTextureHeap;
}
else
{
_localBufferHeap->Release();
LOG_ERROR("CreateHeap textureHeapDesc failed {0:x}!", (UINT) hr);
}
}
else
{
LOG_ERROR("CreateHeap bufferHeapDesc failed {0:x}!", (UINT) hr);
}
}
else
{
LOG_ERROR("xessGetProperties failed {0}!", ResultToString(ret));
}
}

// try to build pipelines with local pipeline object
if (Config::Instance()->BuildPipelines.value_or(true))
{
LOG_DEBUG("xessD3D12BuildPipelines!");
State::Instance().skipHeapCapture = true;
xess_2d_t outputResolution = {TargetWidth(), TargetHeight()};

ID3D12Device1* device1;
if (FAILED(device->QueryInterface(IID_PPV_ARGS(&device1))))
{
LOG_ERROR("QueryInterface device1 failed!");
ret = XeSSProxy::D3D12BuildPipelines()(_xessContext, NULL, false, xessParams.initFlags);
}
else
{
HRESULT hr = device1->CreatePipelineLibrary(nullptr, 0, IID_PPV_ARGS(&_localPipeline));

if (FAILED(hr) || !_localPipeline)
{
LOG_ERROR("CreatePipelineLibrary failed {0:x}!", (UINT) hr);
ret = XeSSProxy::D3D12BuildPipelines()(_xessContext, NULL, false, xessParams.initFlags);
}
else
{
ret = XeSSProxy::D3D12BuildPipelines()(_xessContext, _localPipeline, false, xessParams.initFlags);

if (ret != XESS_RESULT_SUCCESS)
{
LOG_ERROR("xessD3D12BuildPipelines error with _localPipeline: {0}", ResultToString(ret));
ret = XeSSProxy::D3D12BuildPipelines()(_xessContext, NULL, false, xessParams.initFlags);
}
else
{
LOG_DEBUG("using _localPipelines!");
xessParams.pPipelineLibrary = _localPipeline;
}
}
}

if (device1 != nullptr)
device1->Release();

State::Instance().skipHeapCapture = false;

if (ret != XESS_RESULT_SUCCESS)
{
LOG_ERROR("xessD3D12BuildPipelines error: {0}", ResultToString(ret));
return false;
}
}

LOG_DEBUG("xessD3D12Init!");
XessInitParams xessParams = CreateInitParams(outputResolution, qualitySetting, initFlags);

if (Config::Instance()->NetworkModel.has_value() && Config::Instance()->NetworkModel.value() >= 0 &&
Config::Instance()->NetworkModel.value() <= 5)
Expand All @@ -286,9 +112,7 @@ bool XeSSFeature::InitXeSS(ID3D12Device* device, const NVSDK_NGX_Parameter* InPa
LOG_ERROR("xessSelectNetworkModel result: {0}", ResultToString(ret));
}

State::Instance().skipHeapCapture = true;
ret = XeSSProxy::D3D12Init()(_xessContext, &xessParams);
State::Instance().skipHeapCapture = false;
ret = ApiInit(context, &xessParams);

State::Instance().skipSpoofing = false;

Expand All @@ -300,40 +124,98 @@ bool XeSSFeature::InitXeSS(ID3D12Device* device, const NVSDK_NGX_Parameter* InPa

SetInit(true);

InitMenuAndOutput(context);

return true;
}

XeSSFeature::XeSSFeature(unsigned int handleId, NVSDK_NGX_Parameter* InParameters) : IFeature(handleId, InParameters)
bool XeSSFeature::Evaluate(EvalContext* context, const NVSDK_NGX_Parameter* InParameters,
const NVSDK_NGX_Parameter* OutParameters)
{
_initParameters = SetInitParameters(InParameters);
return false;
}

XeSSFeature::~XeSSFeature()
uint32_t XeSSFeature::GetInitFlags()
{
if (State::Instance().isShuttingDown || _xessContext == nullptr)
return;
uint32_t initFlags = XESS_INIT_FLAG_NONE;
if (DepthInverted())
initFlags |= XESS_INIT_FLAG_INVERTED_DEPTH;

if (_xessContext)
{
XeSSProxy::DestroyContext()(_xessContext);
_xessContext = nullptr;
}
if (AutoExposure())
initFlags |= XESS_INIT_FLAG_ENABLE_AUTOEXPOSURE;
else
initFlags |= XESS_INIT_FLAG_EXPOSURE_SCALE_TEXTURE;

if (!IsHdr())
initFlags |= XESS_INIT_FLAG_LDR_INPUT_COLOR;

if (JitteredMV())
initFlags |= XESS_INIT_FLAG_JITTERED_MV;

if (!LowResMV())
initFlags |= XESS_INIT_FLAG_HIGH_RES_MV;

if (_localPipeline != nullptr)
if (!Config::Instance()->DisableReactiveMask.value_or(true))
{
_localPipeline->Release();
_localPipeline = nullptr;
initFlags |= XESS_INIT_FLAG_RESPONSIVE_PIXEL_MASK;
LOG_DEBUG("xessParams.initFlags (ReactiveMaskActive) {0:b}", initFlags);
}
return initFlags;
}

if (_localBufferHeap != nullptr)
xess_quality_settings_t XeSSFeature::GetQualitySetting()
{
switch (PerfQualityValue())
{
_localBufferHeap->Release();
_localBufferHeap = nullptr;
case NVSDK_NGX_PerfQuality_Value_UltraPerformance:
if (Version().major >= 1 && Version().minor >= 3)
return XESS_QUALITY_SETTING_ULTRA_PERFORMANCE;
else
return XESS_QUALITY_SETTING_PERFORMANCE;
break;
case NVSDK_NGX_PerfQuality_Value_MaxPerf:
if (Version().major >= 1 && Version().minor >= 3)
return XESS_QUALITY_SETTING_BALANCED;
else
return XESS_QUALITY_SETTING_PERFORMANCE;
break;
case NVSDK_NGX_PerfQuality_Value_Balanced:
if (Version().major >= 1 && Version().minor >= 3)
return XESS_QUALITY_SETTING_QUALITY;
else
return XESS_QUALITY_SETTING_BALANCED;
break;
case NVSDK_NGX_PerfQuality_Value_MaxQuality:
if (Version().major >= 1 && Version().minor >= 3)
return XESS_QUALITY_SETTING_ULTRA_QUALITY;
else
return XESS_QUALITY_SETTING_QUALITY;
break;
case NVSDK_NGX_PerfQuality_Value_UltraQuality:
if (Version().major >= 1 && Version().minor >= 3)
return XESS_QUALITY_SETTING_ULTRA_QUALITY_PLUS;
else
return XESS_QUALITY_SETTING_ULTRA_QUALITY;
break;

case NVSDK_NGX_PerfQuality_Value_DLAA:
if (Version().major >= 1 && Version().minor >= 3)
return XESS_QUALITY_SETTING_AA;
else
return XESS_QUALITY_SETTING_ULTRA_QUALITY;
break;
}
return XESS_QUALITY_SETTING_BALANCED;
}

if (_localTextureHeap != nullptr)
XeSSFeature::~XeSSFeature()
{
if (State::Instance().isShuttingDown || _xessContext == nullptr)
return;

if (_xessContext)
{
_localTextureHeap->Release();
_localTextureHeap = nullptr;
XeSSProxy::DestroyContext()(_xessContext);
_xessContext = nullptr;
}
}
Loading
Loading