diff --git a/OptiScaler/FSR2_Dx12.cpp b/OptiScaler/FSR2_Dx12.cpp new file mode 100644 index 00000000..2e84770f --- /dev/null +++ b/OptiScaler/FSR2_Dx12.cpp @@ -0,0 +1,196 @@ +//#include "FSR2_Dx12.h" +// +//#include "Config.h" +//#include "Util.h" +// +//#include "resource.h" +//#include "NVNGX_Parameter.h" +// +//#include "fsr2_212/include/ffx_fsr2.h" +//#include "fsr2_212/include/dx12/ffx_fsr2_dx12.h" +// +//static UINT64 _handleCounter = 0x73310000; +// +//static Fsr212::FfxFsr2Context* _currentContext = nullptr; +//static std::map _initParams; +//static std::map _nvParams; +//static std::map _contexts; +//static ID3D12Device* _d3d12Device = nullptr; +//static bool _nvnxgInited = false; +// +//static bool CreateDLSSContext(Fsr212::FfxFsr2Context* handle, const Fsr212::FfxFsr2DispatchDescription* pExecParams) +//{ +// LOG_DEBUG(""); +// +// if (!_nvParams.contains(handle)) +// return false; +// +// NVSDK_NGX_Handle* nvHandle = nullptr; +// auto params = _nvParams[handle]; +// auto initParams = &_initParams[handle]; +// auto commandList = (ID3D12GraphicsCommandList*)pExecParams->commandList; +// +// UINT initFlags = 0; +// +// if (initParams->flags & FFX_UPSCALE_ENABLE_HIGH_DYNAMIC_RANGE) +// initFlags |= NVSDK_NGX_DLSS_Feature_Flags_IsHDR; +// +// if (initParams->flags & FFX_UPSCALE_ENABLE_DEPTH_INVERTED) +// initFlags |= NVSDK_NGX_DLSS_Feature_Flags_DepthInverted; +// +// if (initParams->flags & FFX_UPSCALE_ENABLE_AUTO_EXPOSURE) +// initFlags |= NVSDK_NGX_DLSS_Feature_Flags_AutoExposure; +// +// if (initParams->flags & FFX_UPSCALE_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION) +// initFlags |= NVSDK_NGX_DLSS_Feature_Flags_MVJittered; +// +// if ((initParams->flags & FFX_UPSCALE_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS) == 0) +// initFlags |= NVSDK_NGX_DLSS_Feature_Flags_MVLowRes; +// +// params->Set(NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags, initFlags); +// +// params->Set(NVSDK_NGX_Parameter_Width, pExecParams->renderSize.width); +// params->Set(NVSDK_NGX_Parameter_Height, pExecParams->renderSize.height); +// params->Set(NVSDK_NGX_Parameter_OutWidth, initParams->maxUpscaleSize.width); +// params->Set(NVSDK_NGX_Parameter_OutHeight, initParams->maxUpscaleSize.height); +// +// auto ratio = (float)initParams->maxUpscaleSize.width / (float)pExecParams->renderSize.width; +// +// if (ratio <= 3.0) +// params->Set(NVSDK_NGX_Parameter_PerfQualityValue, NVSDK_NGX_PerfQuality_Value_UltraPerformance); +// else if (ratio <= 2.0) +// params->Set(NVSDK_NGX_Parameter_PerfQualityValue, NVSDK_NGX_PerfQuality_Value_MaxPerf); +// else if (ratio <= 1.7) +// params->Set(NVSDK_NGX_Parameter_PerfQualityValue, NVSDK_NGX_PerfQuality_Value_Balanced); +// else if (ratio <= 1.5) +// params->Set(NVSDK_NGX_Parameter_PerfQualityValue, NVSDK_NGX_PerfQuality_Value_MaxQuality); +// else if (ratio <= 1.3) +// params->Set(NVSDK_NGX_Parameter_PerfQualityValue, NVSDK_NGX_PerfQuality_Value_UltraQuality); +// else +// params->Set(NVSDK_NGX_Parameter_PerfQualityValue, NVSDK_NGX_PerfQuality_Value_DLAA); +// +// if (NVSDK_NGX_D3D12_CreateFeature(commandList, NVSDK_NGX_Feature_SuperSampling, params, &nvHandle) != NVSDK_NGX_Result_Success) +// return false; +// +// _contexts[handle] = nvHandle; +// +// return true; +//} +// +//static std::optional GetQualityOverrideRatioFfx(const Fsr212::FfxFsr2QualityMode input) +//{ +// std::optional output; +// +// auto sliderLimit = Config::Instance()->ExtendedLimits.value_or(false) ? 0.1f : 1.0f; +// +// if (Config::Instance()->UpscaleRatioOverrideEnabled.value_or(false) && +// Config::Instance()->UpscaleRatioOverrideValue.value_or(1.3f) >= sliderLimit) +// { +// output = Config::Instance()->UpscaleRatioOverrideValue.value_or(1.3f); +// +// return output; +// } +// +// if (!Config::Instance()->QualityRatioOverrideEnabled.value_or(false)) +// return output; // override not enabled +// +// switch (input) +// { +// case FFX_UPSCALE_QUALITY_MODE_ULTRA_PERFORMANCE: +// if (Config::Instance()->QualityRatio_UltraPerformance.value_or(3.0) >= sliderLimit) +// output = Config::Instance()->QualityRatio_UltraPerformance.value_or(3.0); +// +// break; +// +// case FFX_UPSCALE_QUALITY_MODE_PERFORMANCE: +// if (Config::Instance()->QualityRatio_Performance.value_or(2.0) >= sliderLimit) +// output = Config::Instance()->QualityRatio_Performance.value_or(2.0); +// +// break; +// +// case FFX_UPSCALE_QUALITY_MODE_BALANCED: +// if (Config::Instance()->QualityRatio_Balanced.value_or(1.7) >= sliderLimit) +// output = Config::Instance()->QualityRatio_Balanced.value_or(1.7); +// +// break; +// +// case FFX_UPSCALE_QUALITY_MODE_QUALITY: +// if (Config::Instance()->QualityRatio_Quality.value_or(1.5) >= sliderLimit) +// output = Config::Instance()->QualityRatio_Quality.value_or(1.5); +// +// break; +// +// case FFX_UPSCALE_QUALITY_MODE_NATIVEAA: +// if (Config::Instance()->QualityRatio_DLAA.value_or(1.0) >= sliderLimit) +// output = Config::Instance()->QualityRatio_DLAA.value_or(1.0); +// +// break; +// +// default: +// LOG_WARN("Unknown quality: {0}", (int)input); +// break; +// } +// +// return output; +//} +// +//// FS2 Upscaler +//static Fsr212::FfxErrorCode ffxFsr2ContextCreate_Dx12(Fsr212::FfxFsr2Context* context, const Fsr212::FfxFsr2ContextDescription* contextDescription) +//{ +// +//} +// +//static Fsr212::FfxErrorCode ffxFsr2ContextDispatch_Dx12(Fsr212::FfxFsr2Context* context, const Fsr212::FfxFsr2DispatchDescription* dispatchDescription) +//{ +// +//} +// +//static Fsr212::FfxErrorCode ffxFsr2ContextGenerateReactiveMask_Dx12(Fsr212::FfxFsr2Context* context, const Fsr212::FfxFsr2GenerateReactiveDescription* params) +//{ +// +//} +// +//static Fsr212::FfxErrorCode ffxFsr2ContextDestroy_Dx12(Fsr212::FfxFsr2Context* context) +//{ +// +//} +// +//static float ffxFsr2GetUpscaleRatioFromQualityMode_Dx12(Fsr212::FfxFsr2QualityMode qualityMode) +//{ +// +//} +// +//static Fsr212::FfxErrorCode ffxFsr2GetRenderResolutionFromQualityMode_Dx12(uint32_t* renderWidth, uint32_t* renderHeight, +// uint32_t displayWidth, uint32_t displayHeight, Fsr212::FfxFsr2QualityMode qualityMode) +//{ +// +//} +// +//// Dx12 Backend +//static size_t hk_ffxFsr2GetScratchMemorySizeDX12() +//{ +// +//} +// +//static Fsr212::FfxErrorCode hk_ffxFsr2GetInterfaceDX12(Fsr212::FfxFsr2Interface212* fsr2Interface, ID3D12Device* device, +// void* scratchBuffer, size_t scratchBufferSize) +//{ +// +//} +// +//static Fsr212::FfxResource hk_ffxGetResourceDX12(Fsr212::FfxFsr2Context* context, ID3D12Resource* resDx12, const wchar_t* name = nullptr, +// Fsr212::FfxResourceStates state = Fsr212::FFX_RESOURCE_STATE_COMPUTE_READ, +// UINT shaderComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING) +//{ +// +//} +// +//static ID3D12Resource* hk_ffxGetDX12ResourcePtr(Fsr212::FfxFsr2Context* context, uint32_t resId) +//{ +// +//} +// +//void HookFSR2Inputs() +//{ +// +//} diff --git a/OptiScaler/FSR2_Dx12.h b/OptiScaler/FSR2_Dx12.h new file mode 100644 index 00000000..2640473a --- /dev/null +++ b/OptiScaler/FSR2_Dx12.h @@ -0,0 +1,4 @@ +#pragma once + +void HookFSR2Inputs(); + diff --git a/OptiScaler/FfxApi_Dx12.cpp b/OptiScaler/FfxApi_Dx12.cpp index f17a0786..0e9faf43 100644 --- a/OptiScaler/FfxApi_Dx12.cpp +++ b/OptiScaler/FfxApi_Dx12.cpp @@ -14,6 +14,7 @@ static std::map _nvParams; static std::map _contexts; static ID3D12Device* _d3d12Device = nullptr; static bool _nvnxgInited = false; +static float qualityRatios[] = { 1.0, 1.5, 1.7, 2.0, 3.0 }; static bool CreateDLSSContext(ffxContext handle, const ffxDispatchDescUpscale* pExecParams) { @@ -53,6 +54,8 @@ static bool CreateDLSSContext(ffxContext handle, const ffxDispatchDescUpscale* p auto ratio = (float)initParams->maxUpscaleSize.width / (float)pExecParams->renderSize.width; + LOG_INFO("renderWidth: {}, maxWidth: {}, ratio: {}", pExecParams->renderSize.width, initParams->maxUpscaleSize.width, ratio); + if (ratio <= 3.0) params->Set(NVSDK_NGX_Parameter_PerfQualityValue, NVSDK_NGX_PerfQuality_Value_UltraPerformance); else if (ratio <= 2.0) @@ -79,7 +82,7 @@ static bool CreateDLSSContext(ffxContext handle, const ffxDispatchDescUpscale* p return true; } -static std::optional GetQualityOverrideRatioFfx(const FfxApiUpscaleQualityMode input) +static std::optional GetQualityOverrideRatioFfx(const uint32_t input) { std::optional output; @@ -133,6 +136,11 @@ static std::optional GetQualityOverrideRatioFfx(const FfxApiUpscaleQualit break; } + if (output.has_value()) + LOG_DEBUG("ratio: {}", output.value()); + else + LOG_DEBUG("ratio: no value"); + return output; } @@ -216,20 +224,18 @@ ffxReturnCode_t ffxDestroyContext_Dx12(ffxContext* context, const ffxAllocationC auto contextId = (size_t)*context; - if (!_contexts.contains(*context) && *context != _currentContext && contextId < 0x13370000 && contextId > 0x13379999) + if (!_initParams.contains(*context)) { LOG_INFO("Not upscaler context: {:X}", (size_t)*context); return FfxApiProxy::D3D12_DestroyContext()(context, memCb); } if (_contexts.contains(*context)) - { NVSDK_NGX_D3D12_ReleaseFeature(_contexts[*context]); - _contexts.erase(*context); - _nvParams.erase(*context); - _initParams.erase(*context); - } + _contexts.erase(*context); + _nvParams.erase(*context); + _initParams.erase(*context); return FFX_API_RETURN_OK; } @@ -257,15 +263,28 @@ ffxReturnCode_t ffxQuery_Dx12(ffxContext* context, ffxQueryDescHeader* desc) if (desc->type == FFX_API_QUERY_DESC_TYPE_UPSCALE_GETRENDERRESOLUTIONFROMQUALITYMODE) { auto ratioDesc = (ffxQueryDescUpscaleGetRenderResolutionFromQualityMode*)desc; - auto ratio = GetQualityOverrideRatioFfx((FfxApiUpscaleQualityMode)ratioDesc->qualityMode); - *ratioDesc->pOutRenderHeight = (uint32_t)(ratioDesc->displayHeight / ratio.value_or(1.7)); - *ratioDesc->pOutRenderHeight = (uint32_t)(ratioDesc->displayWidth / ratio.value_or(1.7)); + auto ratio = GetQualityOverrideRatioFfx(ratioDesc->qualityMode); + + if (ratioDesc->pOutRenderHeight != nullptr) + *ratioDesc->pOutRenderHeight = (uint32_t)(ratioDesc->displayHeight / ratio.value_or(qualityRatios[ratioDesc->qualityMode])); + + if (ratioDesc->pOutRenderWidth != nullptr) + *ratioDesc->pOutRenderWidth = (uint32_t)(ratioDesc->displayWidth / ratio.value_or(qualityRatios[ratioDesc->qualityMode])); + + if (ratioDesc->pOutRenderWidth != nullptr && ratioDesc->pOutRenderHeight != nullptr) + LOG_DEBUG("Quality mode: {}, Render resolution: {}x{}", ratioDesc->qualityMode, *ratioDesc->pOutRenderWidth, *ratioDesc->pOutRenderHeight); + else + LOG_WARN("Quality mode: {}, pOutRenderWidth or pOutRenderHeight is null!", ratioDesc->qualityMode); + return FFX_API_RETURN_OK; } else if (desc->type == FFX_API_QUERY_DESC_TYPE_UPSCALE_GETUPSCALERATIOFROMQUALITYMODE) { auto scaleDesc = (ffxQueryDescUpscaleGetUpscaleRatioFromQualityMode*)desc; - *scaleDesc->pOutUpscaleRatio = GetQualityOverrideRatioFfx((FfxApiUpscaleQualityMode)scaleDesc->qualityMode).value_or(1.7); + *scaleDesc->pOutUpscaleRatio = GetQualityOverrideRatioFfx((FfxApiUpscaleQualityMode)scaleDesc->qualityMode).value_or(qualityRatios[scaleDesc->qualityMode]); + + LOG_DEBUG("Quality mode: {}, Upscale ratio: {}", scaleDesc->qualityMode, *scaleDesc->pOutUpscaleRatio); + return FFX_API_RETURN_OK; } else if (desc->type == FFX_API_QUERY_DESC_TYPE_UPSCALE_GPU_MEMORY_USAGE) @@ -279,11 +298,13 @@ ffxReturnCode_t ffxQuery_Dx12(ffxContext* context, ffxQueryDescHeader* desc) memoryDesc->gpuMemoryUsageUpscaler->totalUsageInBytes = memValue; memoryDesc->gpuMemoryUsageUpscaler->aliasableUsageInBytes = memValue / 20; + return FFX_API_RETURN_OK; } if (desc->type == FFX_API_QUERY_DESC_TYPE_UPSCALE_GETJITTEROFFSET || desc->type == FFX_API_QUERY_DESC_TYPE_UPSCALE_GETJITTERPHASECOUNT) { + LOG_TRACE("Jitter queries"); return FfxApiProxy::D3D12_Query()(nullptr, desc); } @@ -292,12 +313,12 @@ ffxReturnCode_t ffxQuery_Dx12(ffxContext* context, ffxQueryDescHeader* desc) ffxReturnCode_t ffxDispatch_Dx12(ffxContext* context, ffxDispatchDescHeader* desc) { - if (desc == nullptr) + if (desc == nullptr || context == nullptr) return FFX_API_RETURN_ERROR_PARAMETER; - LOG_DEBUG("type: {:X}", desc->type); + LOG_DEBUG("context: {:X}, type: {:X}", (size_t)*context, desc->type); - if (context == nullptr || (!_contexts.contains(*context) && *context != _currentContext)) + if (context == nullptr || !_initParams.contains(*context)) { LOG_INFO("Not in _contexts, desc type: {:X}", desc->type); return FfxApiProxy::D3D12_Dispatch()(context, desc); @@ -338,7 +359,8 @@ ffxReturnCode_t ffxDispatch_Dx12(ffxContext* context, ffxDispatchDescHeader* des return FFX_API_RETURN_ERROR_PARAMETER; // If not in contexts list create and add context - if ((!_contexts.contains(*context) && *context == _currentContext) && !CreateDLSSContext(*context, dispatchDesc)) + auto contextId = (size_t)*context; + if (!_contexts.contains(*context) && _initParams.contains(*context) && !CreateDLSSContext(*context, dispatchDesc)) return FFX_API_RETURN_ERROR_RUNTIME_ERROR; NVSDK_NGX_Parameter* params = _nvParams[*context]; @@ -361,11 +383,23 @@ ffxReturnCode_t ffxDispatch_Dx12(ffxContext* context, ffxDispatchDescHeader* des params->Set(NVSDK_NGX_Parameter_Color, dispatchDesc->color.resource); params->Set(NVSDK_NGX_Parameter_MotionVectors, dispatchDesc->motionVectors.resource); params->Set(NVSDK_NGX_Parameter_Output, dispatchDesc->output.resource); + params->Set("FSR.cameraNear", dispatchDesc->cameraNear); + params->Set("FSR.cameraFar", dispatchDesc->cameraFar); + params->Set("FSR.cameraFovAngleVertical", dispatchDesc->cameraFovAngleVertical); + params->Set("FSR.frameTimeDelta", dispatchDesc->frameTimeDelta); + params->Set("FSR.viewSpaceToMetersFactor", dispatchDesc->viewSpaceToMetersFactor); + params->Set("FSR.transparencyAndComposition", dispatchDesc->transparencyAndComposition.resource); + params->Set("FSR.reactive", dispatchDesc->reactive.resource); + + LOG_DEBUG("handle: {:X}, internalResolution: {}x{}", handle->Id, dispatchDesc->renderSize.width, dispatchDesc->renderSize.height); Config::Instance()->setInputApiName = "FFX-DX12"; - if (NVSDK_NGX_D3D12_EvaluateFeature((ID3D12GraphicsCommandList*)dispatchDesc->commandList, handle, params, nullptr) == NVSDK_NGX_Result_Success) + auto evalResult = NVSDK_NGX_D3D12_EvaluateFeature((ID3D12GraphicsCommandList*)dispatchDesc->commandList, handle, params, nullptr); + + if (evalResult == NVSDK_NGX_Result_Success) return FFX_API_RETURN_OK; + LOG_ERROR("evalResult: {:X}", (UINT)evalResult); return FFX_API_RETURN_ERROR_RUNTIME_ERROR; } \ No newline at end of file diff --git a/OptiScaler/NVNGX_DLSS_Dx12.cpp b/OptiScaler/NVNGX_DLSS_Dx12.cpp index c2a88cf2..21c032aa 100644 --- a/OptiScaler/NVNGX_DLSS_Dx12.cpp +++ b/OptiScaler/NVNGX_DLSS_Dx12.cpp @@ -46,7 +46,8 @@ static NVSDK_NGX_Parameter* createParams = nullptr; static int changeBackendCounter = 0; static int evalCounter = 0; static std::wstring appDataPath = L"."; -static inline bool shutdown = false; +static bool shutdown = false; +static bool inited = false; static void ResourceBarrier(ID3D12GraphicsCommandList* InCommandList, ID3D12Resource* InResource, D3D12_RESOURCE_STATES InBeforeState, D3D12_RESOURCE_STATES InAfterState) { @@ -203,6 +204,12 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_Ext(unsigned long long InApp { LOG_FUNC(); + if (inited) + { + LOG_WARN("NVNGX already inited"); + return NVSDK_NGX_Result_Success; + } + if (Config::Instance()->UseGenericAppIdWithDlss.value_or(false)) InApplicationId = app_id_override; @@ -307,6 +314,12 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init(unsigned long long InApplica { LOG_FUNC(); + if (inited) + { + LOG_WARN("NVNGX already inited"); + return NVSDK_NGX_Result_Success; + } + if (Config::Instance()->DLSSEnabled.value_or(true) && !NVNGXProxy::IsDx12Inited()) { if (Config::Instance()->UseGenericAppIdWithDlss.value_or(false)) @@ -338,6 +351,12 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_ProjectID(const char* InProj { LOG_FUNC(); + if (inited) + { + LOG_WARN("NVNGX already inited"); + return NVSDK_NGX_Result_Success; + } + if (Config::Instance()->DLSSEnabled.value_or(true) && !NVNGXProxy::IsDx12Inited()) { if (Config::Instance()->UseGenericAppIdWithDlss.value_or(false)) @@ -378,6 +397,12 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_with_ProjectID(const char* I { LOG_FUNC(); + if (inited) + { + LOG_WARN("NVNGX already inited"); + return NVSDK_NGX_Result_Success; + } + auto result = NVSDK_NGX_D3D12_Init_Ext(0x1337, InApplicationDataPath, InDevice, InSDKVersion, InFeatureInfo); LOG_INFO("InProjectId: {0}", InProjectId); @@ -398,6 +423,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_with_ProjectID(const char* I NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Shutdown(void) { shutdown = true; + inited = false; for (auto const& [key, val] : Dx12Contexts) NVSDK_NGX_D3D12_ReleaseFeature(val->Handle()); @@ -433,6 +459,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Shutdown(void) NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Shutdown1(ID3D12Device* InDevice) { shutdown = true; + inited = false; if (Config::Instance()->DLSSEnabled.value_or(true) && NVNGXProxy::IsDx12Inited() && NVNGXProxy::D3D12_Shutdown1() != nullptr) { diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj index 3eed2317..9ee71f83 100644 --- a/OptiScaler/OptiScaler.vcxproj +++ b/OptiScaler/OptiScaler.vcxproj @@ -82,7 +82,7 @@ $(SolutionDir)external\vulkan\include;$(SolutionDir)external\nvngx_dlss_sdk;$(SolutionDir)external\xess\inc\xess;$(SolutionDir)external\FidelityFX-SDK\ffx-api\include\ffx_api;$(SolutionDir)external\simpleini;$(SolutionDir)external\unordered_dense\include;$(SolutionDir)external\spdlog\include;$(SolutionDir)external\freetype;$(IncludePath) $(ProjectDir)fsr2\lib;$(ProjectDir)fsr2_212\lib;$(ProjectDir)fsr31\lib;$(ProjectDir)vulkan;$(ProjectDir)d3dx;$(ProjectDir)detours;$(SolutionDir)external\xess\lib;$(SolutionDir)external\freetype;$(LibraryPath) dxgi - F:\source\optiscaler\external\FidelityFX-SDK\bin\ + E:\Games\Deep Rock Galactic\FSD\Binaries\Win64\ .\x64\Debug .dll @@ -214,6 +214,7 @@ copy $(SolutionDir)nvngx.ini $(SolutionDir)x64\Release\a\ + @@ -315,6 +316,7 @@ copy $(SolutionDir)nvngx.ini $(SolutionDir)x64\Release\a\ + diff --git a/OptiScaler/OptiScaler.vcxproj.filters b/OptiScaler/OptiScaler.vcxproj.filters index 27103f5e..a002768b 100644 --- a/OptiScaler/OptiScaler.vcxproj.filters +++ b/OptiScaler/OptiScaler.vcxproj.filters @@ -284,6 +284,12 @@ Header Files + + Header Files + + + Header Files + @@ -491,6 +497,12 @@ Source Files + + Source Files + + + Source Files + diff --git a/OptiScaler/XeSS_Dx12.cpp b/OptiScaler/XeSS_Dx12.cpp index a02e2755..011d9cc8 100644 --- a/OptiScaler/XeSS_Dx12.cpp +++ b/OptiScaler/XeSS_Dx12.cpp @@ -401,8 +401,8 @@ XESS_API xess_result_t xessGetInputResolution(xess_context_handle_t hContext, co if (QualityRatio.has_value()) { - OutHeight = (unsigned int)((float)pOutputResolution->x / QualityRatio.value()); - OutWidth = (unsigned int)((float)pOutputResolution->y / QualityRatio.value()); + OutHeight = (unsigned int)((float)pOutputResolution->y / QualityRatio.value()); + OutWidth = (unsigned int)((float)pOutputResolution->x / QualityRatio.value()); scalingRatio = 1.0f / QualityRatio.value(); } else diff --git a/OptiScaler/backends/IFeature.cpp b/OptiScaler/backends/IFeature.cpp index 6ef5650e..d201304e 100644 --- a/OptiScaler/backends/IFeature.cpp +++ b/OptiScaler/backends/IFeature.cpp @@ -80,6 +80,8 @@ void IFeature::GetRenderResolution(NVSDK_NGX_Parameter* InParameters, unsigned i if (InParameters->Get(NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width, OutWidth) != NVSDK_NGX_Result_Success || InParameters->Get(NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height, OutHeight) != NVSDK_NGX_Result_Success) { + LOG_WARN("No subrect dimension info!"); + unsigned int width; unsigned int height; unsigned int outWidth; diff --git a/OptiScaler/hooks/HooksDx.cpp b/OptiScaler/hooks/HooksDx.cpp index deecdb1c..7647b1f6 100644 --- a/OptiScaler/hooks/HooksDx.cpp +++ b/OptiScaler/hooks/HooksDx.cpp @@ -33,11 +33,11 @@ typedef struct FfxSwapchainFramePacingTuning { - float safetyMarginInMs = 1.0; // in Millisecond - float varianceFactor = 0.2; // valid range [0.0,1.0] + float safetyMarginInMs = 3.0; // in Millisecond + float varianceFactor = 0.3; // valid range [0.0,1.0] bool allowHybridSpin = true; //Allows pacing spinlock to sleep. - uint32_t hybridSpinTime = 2; //How long to spin when hybridSpin is enabled. Measured in timer resolution units. Not recommended to go below 2. Will result in frequent overshoots. - bool allowWaitForSingleObjectOnFence = true; //Allows to call WaitForSingleObject() instead of spinning for fence value. + uint32_t hybridSpinTime = 4; //How long to spin when hybridSpin is enabled. Measured in timer resolution units. Not recommended to go below 2. Will result in frequent overshoots. + bool allowWaitForSingleObjectOnFence = false; //Allows to call WaitForSingleObject() instead of spinning for fence value. } FfxSwapchainFramePacingTuning; enum ResourceType @@ -68,6 +68,62 @@ typedef struct ResourceInfo double lastUsedFrame = 0; } resource_info; +typedef struct HeapInfo +{ + SIZE_T cpuStart = NULL; + SIZE_T cpuEnd = NULL; + SIZE_T gpuStart = NULL; + SIZE_T gpuEnd = NULL; + UINT numDescriptors = 0; + UINT increment = 0; + UINT type = 0; + std::shared_ptr info; + + HeapInfo(SIZE_T cpuStart, SIZE_T cpuEnd, SIZE_T gpuStart, SIZE_T gpuEnd, UINT numResources, UINT increment, UINT type) + : cpuStart(cpuStart), cpuEnd(cpuEnd), gpuStart(gpuStart), gpuEnd(gpuEnd), numDescriptors(numResources), increment(increment), info(new ResourceInfo[numResources]), type(type) {} + + ResourceInfo* GetByCpuHandle(SIZE_T cpuHandle) const + { + if (cpuStart > cpuHandle || cpuEnd < cpuHandle) + return nullptr; + + auto index = (cpuHandle - cpuStart) / increment; + + return &info[index]; + } + + ResourceInfo* GetByGpuHandle(SIZE_T gpuHandle) const + { + if (gpuStart > gpuHandle || gpuEnd < gpuHandle) + return nullptr; + + auto index = (gpuHandle - gpuStart) / increment; + + return &info[index]; + } + + void SetByCpuHandle(SIZE_T cpuHandle, ResourceInfo setInfo) const + { + if (cpuStart > cpuHandle || cpuEnd < cpuHandle) + return; + + auto index = (cpuHandle - cpuStart) / increment; + + info[index] = setInfo; + } + + void SetByGpuHandle(SIZE_T gpuHandle, ResourceInfo setInfo) const + { + if (gpuStart > gpuHandle || gpuEnd < gpuHandle) + return; + + auto index = (gpuHandle - gpuStart) / increment; + + info[index] = setInfo; + } +} heap_info; + +/* typedef struct HeapInfo { SIZE_T cpuStart = NULL; @@ -130,6 +186,7 @@ typedef struct HeapInfo } } } heap_info; +*/ typedef struct ResourceHeapInfo { @@ -1207,7 +1264,7 @@ static void hkCopyDescriptors(ID3D12Device* This, if (DescriptorHeapsType != D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV && DescriptorHeapsType != D3D12_DESCRIPTOR_HEAP_TYPE_RTV) return; - if (Config::Instance()->FGAlwaysTrackHeaps.value_or(false) && !IsHudFixActive()) + if (!Config::Instance()->FGAlwaysTrackHeaps.value_or(false) && !IsHudFixActive()) return; // make copies, just in case @@ -1339,7 +1396,7 @@ static void hkCopyDescriptorsSimple(ID3D12Device* This, UINT NumDescriptors, D3D if (DescriptorHeapsType != D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV && DescriptorHeapsType != D3D12_DESCRIPTOR_HEAP_TYPE_RTV) return; - if (Config::Instance()->FGAlwaysTrackHeaps.value_or(false) && !IsHudFixActive()) + if (!Config::Instance()->FGAlwaysTrackHeaps.value_or(false) && !IsHudFixActive()) return; if (Config::Instance()->UseThreadingForHeaps) @@ -1649,6 +1706,9 @@ static void hkDrawInstanced(ID3D12GraphicsCommandList* This, UINT VertexCountPer { o_DrawInstanced(This, VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation); + if (!IsHudFixActive()) + return; + auto fIndex = fgFrameIndex; if (This == ImGuiOverlayDx::MenuCommandList() || IsFGCommandList(This)) @@ -1656,9 +1716,6 @@ static void hkDrawInstanced(ID3D12GraphicsCommandList* This, UINT VertexCountPer LOG_DEBUG_ONLY("CommandList: {:X}", (size_t)This); - if (!IsHudFixActive()) - return; - { ankerl::unordered_dense::map val0; @@ -1705,6 +1762,9 @@ static void hkDrawIndexedInstanced(ID3D12GraphicsCommandList* This, UINT IndexCo { o_DrawIndexedInstanced(This, IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); + if (!IsHudFixActive()) + return; + auto fIndex = fgFrameIndex; if (This == ImGuiOverlayDx::MenuCommandList() || IsFGCommandList(This)) @@ -1712,9 +1772,6 @@ static void hkDrawIndexedInstanced(ID3D12GraphicsCommandList* This, UINT IndexCo LOG_DEBUG_ONLY("CommandList: {:X}", (size_t)This); - if (!IsHudFixActive()) - return; - { ankerl::unordered_dense::map val0; @@ -1763,6 +1820,9 @@ static void hkDispatch(ID3D12GraphicsCommandList* This, UINT ThreadGroupCountX, { o_Dispatch(This, ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); + if (!IsHudFixActive()) + return; + auto fIndex = fgFrameIndex; if (This == ImGuiOverlayDx::MenuCommandList() || IsFGCommandList(This)) @@ -1770,9 +1830,6 @@ static void hkDispatch(ID3D12GraphicsCommandList* This, UINT ThreadGroupCountX, LOG_DEBUG_ONLY("CommandList: {:X}", (size_t)This); - if (!IsHudFixActive()) - return; - { ankerl::unordered_dense::map val0; @@ -2275,6 +2332,7 @@ static HRESULT hkCreateSwapChain(IDXGIFactory* pFactory, IUnknown* pDevice, DXGI } ID3D12CommandQueue* cq = nullptr; + // PerfReg?? if (Config::Instance()->FGUseFGSwapChain.value_or(true) && !fgSkipSCWrapping && FfxApiProxy::InitFfxDx12() && pDevice->QueryInterface(IID_PPV_ARGS(&cq)) == S_OK) { cq->SetName(L"GameQueue"); @@ -2567,7 +2625,8 @@ static HRESULT hkCreateSwapChainForHwnd(IDXGIFactory* This, IUnknown* pDevice, H } ID3D12CommandQueue* cq = nullptr; - if (Config::Instance()->FGUseFGSwapChain.value_or(true) /*&& fgSCCount > 0*/ && !fgSkipSCWrapping && FfxApiProxy::InitFfxDx12() && pDevice->QueryInterface(IID_PPV_ARGS(&cq)) == S_OK) + // PerfReg?? + if (Config::Instance()->FGUseFGSwapChain.value_or(true) && !fgSkipSCWrapping && FfxApiProxy::InitFfxDx12() && pDevice->QueryInterface(IID_PPV_ARGS(&cq)) == S_OK) { cq->SetName(L"GameQueueHwnd"); cq->Release(); @@ -3096,8 +3155,8 @@ static void HookToDevice(ID3D12Device* InDevice) DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); - if (o_CreateDescriptorHeap != nullptr) - DetourAttach(&(PVOID&)o_CreateDescriptorHeap, hkCreateDescriptorHeap); + //if (o_CreateDescriptorHeap != nullptr) + // DetourAttach(&(PVOID&)o_CreateDescriptorHeap, hkCreateDescriptorHeap); if (o_CreateSampler != nullptr) DetourAttach(&(PVOID&)o_CreateSampler, hkCreateSampler); @@ -4013,8 +4072,10 @@ void FrameGen_Dx12::StopAndDestroyFGContext(bool destroy, bool shutDown, bool us { FrameGen_Dx12::fgSkipHudlessChecks = false; +#ifdef USE_MUTEX_FOR_FFX if (useMutex) - FrameGen_Dx12::ffxMutex.lock(); + FrameGen_Dx12::fiffxMutex.lock(); +#endif if (!(shutDown || Config::Instance()->IsShuttingDown) && FrameGen_Dx12::fgContext != nullptr) { @@ -4047,8 +4108,10 @@ void FrameGen_Dx12::StopAndDestroyFGContext(bool destroy, bool shutDown, bool us if ((shutDown || Config::Instance()->IsShuttingDown) || destroy) ReleaseFGObjects(); +#ifdef USE_MUTEX_FOR_FFX if (useMutex) FrameGen_Dx12::ffxMutex.unlock(); +#endif } void FrameGen_Dx12::CheckUpscaledFrame(ID3D12GraphicsCommandList* InCmdList, ID3D12Resource* InUpscaled) diff --git a/OptiScaler/hooks/HooksDx.h b/OptiScaler/hooks/HooksDx.h index 335ff72e..453571d3 100644 --- a/OptiScaler/hooks/HooksDx.h +++ b/OptiScaler/hooks/HooksDx.h @@ -11,7 +11,7 @@ // According to https://gpuopen.com/manuals/fidelityfx_sdk/fidelityfx_sdk-page_techniques_super-resolution-interpolation/#id11 // Will use mutex to prevent race condutions -#define USE_MUTEX_FOR_FFX +// #define USE_MUTEX_FOR_FFX #ifdef USE_MUTEX_FOR_FFX #define USE_PRESENT_FOR_FT diff --git a/OptiScaler/hooks/wrapped_swapchain.cpp b/OptiScaler/hooks/wrapped_swapchain.cpp index d170a5ea..79a6919a 100644 --- a/OptiScaler/hooks/wrapped_swapchain.cpp +++ b/OptiScaler/hooks/wrapped_swapchain.cpp @@ -117,8 +117,11 @@ HRESULT WrappedIDXGISwapChain4::ResizeBuffers(UINT BufferCount, UINT Width, UINT LOG_DEBUG(""); std::lock_guard lock(_localMutex); + +#ifdef USE_MUTEX_FOR_FFX LOG_TRACE("Waiting mutex"); std::unique_lock lock2(FrameGen_Dx12::ffxMutex); +#endif HRESULT result; DXGI_SWAP_CHAIN_DESC desc{}; @@ -222,18 +225,21 @@ HRESULT WrappedIDXGISwapChain4::ResizeBuffers(UINT BufferCount, UINT Width, UINT HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::GetContainingOutput(IDXGIOutput** ppOutput) { - std::lock_guard lock(_localMutex); + //std::lock_guard lock(_localMutex); return m_pReal->GetContainingOutput(ppOutput); } HRESULT WrappedIDXGISwapChain4::ResizeBuffers1(UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT Format, UINT SwapChainFlags, const UINT* pCreationNodeMask, IUnknown* const* ppPresentQueue) { + LOG_DEBUG(""); + std::lock_guard lock(_localMutex); + +#ifdef USE_MUTEX_FOR_FFX LOG_TRACE("Waiting mutex"); std::unique_lock lock2(FrameGen_Dx12::ffxMutex); - - LOG_DEBUG(""); +#endif HRESULT result; DXGI_SWAP_CHAIN_DESC desc{}; @@ -363,8 +369,11 @@ HRESULT WrappedIDXGISwapChain4::SetFullscreenState(BOOL Fullscreen, IDXGIOutput* { std::lock_guard lock(_localMutex); + +#ifdef USE_MUTEX_FOR_FFX LOG_TRACE("Waiting mutex"); std::unique_lock lock2(FrameGen_Dx12::ffxMutex); +#endif result = m_pReal->SetFullscreenState(Fullscreen, pTarget); @@ -414,13 +423,13 @@ HRESULT WrappedIDXGISwapChain4::SetFullscreenState(BOOL Fullscreen, IDXGIOutput* HRESULT WrappedIDXGISwapChain4::GetFullscreenState(BOOL* pFullscreen, IDXGIOutput** ppTarget) { - std::lock_guard lock(_localMutex); + //std::lock_guard lock(_localMutex); return m_pReal->GetFullscreenState(pFullscreen, ppTarget); } HRESULT WrappedIDXGISwapChain4::GetBuffer(UINT Buffer, REFIID riid, void** ppSurface) { - std::lock_guard lock(_localMutex); + //std::lock_guard lock(_localMutex); return m_pReal->GetBuffer(Buffer, riid, ppSurface); } diff --git a/OptiScaler/resource.h b/OptiScaler/resource.h index f4cac579..315054f7 100644 --- a/OptiScaler/resource.h +++ b/OptiScaler/resource.h @@ -21,7 +21,7 @@ #define VER_MAJOR_VERSION 0 #define VER_MINOR_VERSION 7 #define VER_HOTFIX_VERSION 0 -#define VER_BUILD_NUMBER 79 +#define VER_BUILD_NUMBER 81 #define VER_PRE_RELEASE