|
|
@@ -10,193 +10,121 @@
|
|
|
|
|
|
// Ngx specific
|
|
|
#if ANKI_DLSS
|
|
|
-#include <ThirdParty/nvngx_dlss_sdk/sdk/include/nvsdk_ngx.h>
|
|
|
-#include <ThirdParty/nvngx_dlss_sdk/sdk/include/nvsdk_ngx_helpers.h>
|
|
|
-#include <ThirdParty/nvngx_dlss_sdk/sdk/include/nvsdk_ngx_vk.h>
|
|
|
-#include <ThirdParty/nvngx_dlss_sdk/sdk/include/nvsdk_ngx_helpers_vk.h>
|
|
|
+# include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx.h>
|
|
|
+# include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_helpers.h>
|
|
|
+# include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_vk.h>
|
|
|
+# include <ThirdParty/DlssSdk/sdk/include/nvsdk_ngx_helpers_vk.h>
|
|
|
#endif
|
|
|
|
|
|
namespace anki {
|
|
|
|
|
|
GrUpscalerImpl::~GrUpscalerImpl()
|
|
|
-{
|
|
|
- shutdown();
|
|
|
-}
|
|
|
-
|
|
|
-Error GrUpscalerImpl::initInternal(const GrUpscalerInitInfo& initInfo)
|
|
|
{
|
|
|
#if ANKI_DLSS
|
|
|
- if(initInfo.m_upscalerType != GrUpscalerType::DLSS_2)
|
|
|
+ if(m_upscalerType == GrUpscalerType::DLSS_2)
|
|
|
{
|
|
|
- ANKI_VK_LOGE("Currently only DLSS supported");
|
|
|
- return Error::FUNCTION_FAILED;
|
|
|
+ destroyDlss();
|
|
|
}
|
|
|
- return initAsDLSS(initInfo);
|
|
|
-#else
|
|
|
- return Error::FUNCTION_FAILED;
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-void GrUpscalerImpl::shutdown()
|
|
|
+Error GrUpscalerImpl::initInternal(const GrUpscalerInitInfo& initInfo)
|
|
|
{
|
|
|
+ m_upscalerType = initInfo.m_upscalerType;
|
|
|
+
|
|
|
#if ANKI_DLSS
|
|
|
- shutdownDLSS();
|
|
|
+ ANKI_ASSERT(initInfo.m_upscalerType == GrUpscalerType::DLSS_2);
|
|
|
+ ANKI_CHECK(initDlss(initInfo));
|
|
|
+#else
|
|
|
+ ANKI_ASSERT(!"Not supported");
|
|
|
#endif
|
|
|
+
|
|
|
+ return Error::NONE;
|
|
|
}
|
|
|
|
|
|
-// NGX related logic
|
|
|
+// ==== DLSS ====
|
|
|
#if ANKI_DLSS
|
|
|
|
|
|
-// Use random ID
|
|
|
-# define ANKI_NGX_APP_ID 231313132
|
|
|
-# define ANKI_RW_LOGS_DIR L"./"
|
|
|
-
|
|
|
-// See enum DLSSQualityMode
|
|
|
-static NVSDK_NGX_PerfQuality_Value g_NVQUALITYMODES[] = {
|
|
|
- NVSDK_NGX_PerfQuality_Value_MaxPerf, // DISABLED
|
|
|
- NVSDK_NGX_PerfQuality_Value_MaxPerf, NVSDK_NGX_PerfQuality_Value_Balanced, NVSDK_NGX_PerfQuality_Value_MaxQuality};
|
|
|
-
|
|
|
-static inline NVSDK_NGX_PerfQuality_Value getDlssQualityModeToNVQualityMode(GrUpscalerQualityMode mode)
|
|
|
+# define ANKI_NGX_CHECK(x_) \
|
|
|
+ do \
|
|
|
+ { \
|
|
|
+ const NVSDK_NGX_Result result = x_; \
|
|
|
+ if(NVSDK_NGX_FAILED(result)) \
|
|
|
+ { \
|
|
|
+ ANKI_VK_LOGE("DLSS failed to initialize %ls", GetNGXResultAsString(result)); \
|
|
|
+ return Error::FUNCTION_FAILED; \
|
|
|
+ } \
|
|
|
+ } while(0)
|
|
|
+
|
|
|
+static NVSDK_NGX_PerfQuality_Value getDlssQualityModeToNVQualityMode(GrUpscalerQualityMode mode)
|
|
|
{
|
|
|
- return g_NVQUALITYMODES[static_cast<U32>(mode)];
|
|
|
+ static Array<NVSDK_NGX_PerfQuality_Value, U32(GrUpscalerQualityMode::COUNT)> nvQualityModes = {
|
|
|
+ NVSDK_NGX_PerfQuality_Value_MaxPerf, NVSDK_NGX_PerfQuality_Value_Balanced,
|
|
|
+ NVSDK_NGX_PerfQuality_Value_MaxQuality};
|
|
|
+
|
|
|
+ return nvQualityModes[mode];
|
|
|
}
|
|
|
|
|
|
-Error GrUpscalerImpl::initAsDLSS(const GrUpscalerInitInfo& initInfo)
|
|
|
+Error GrUpscalerImpl::initDlss(const GrUpscalerInitInfo& initInfo)
|
|
|
{
|
|
|
NVSDK_NGX_Result result = NVSDK_NGX_Result_Fail;
|
|
|
|
|
|
const VkDevice vkdevice = getGrManagerImpl().getDevice();
|
|
|
const VkPhysicalDevice vkphysicaldevice = getGrManagerImpl().getPhysicalDevice();
|
|
|
const VkInstance vkinstance = getGrManagerImpl().getInstance();
|
|
|
- result = NVSDK_NGX_VULKAN_Init(ANKI_NGX_APP_ID, ANKI_RW_LOGS_DIR, vkinstance, vkphysicaldevice, vkdevice);
|
|
|
+ const U32 ngxAppId = 231313132; // Something random
|
|
|
+ const WChar* appLogs = L"./";
|
|
|
+ ANKI_NGX_CHECK(NVSDK_NGX_VULKAN_Init(ngxAppId, appLogs, vkinstance, vkphysicaldevice, vkdevice));
|
|
|
+ m_ngxInitialized = true;
|
|
|
|
|
|
- m_ngxInitialized = !NVSDK_NGX_FAILED(result);
|
|
|
- if(!isNgxInitialized())
|
|
|
- {
|
|
|
- if(result == NVSDK_NGX_Result_FAIL_FeatureNotSupported || result == NVSDK_NGX_Result_FAIL_PlatformError)
|
|
|
- {
|
|
|
- ANKI_VK_LOGE("NVIDIA NGX not available on this hardware/platform., code = 0x%08x, info: %ls", result,
|
|
|
- GetNGXResultAsString(result));
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- ANKI_VK_LOGE("Failed to initialize NGX, error code = 0x%08x, info: %ls", result,
|
|
|
- GetNGXResultAsString(result));
|
|
|
- }
|
|
|
-
|
|
|
- return Error::FUNCTION_FAILED;
|
|
|
- }
|
|
|
-
|
|
|
- result = NVSDK_NGX_VULKAN_GetCapabilityParameters(&m_ngxParameters);
|
|
|
-
|
|
|
- if(NVSDK_NGX_FAILED(result))
|
|
|
- {
|
|
|
- ANKI_VK_LOGE("NVSDK_NGX_GetCapabilityParameters failed, code = 0x%08x, info: %ls", result,
|
|
|
- GetNGXResultAsString(result));
|
|
|
- return Error::FUNCTION_FAILED;
|
|
|
- }
|
|
|
+ ANKI_NGX_CHECK(NVSDK_NGX_VULKAN_GetCapabilityParameters(&m_ngxParameters));
|
|
|
+ ANKI_ASSERT(m_ngxParameters);
|
|
|
|
|
|
// Currently, the SDK and this sample are not in sync. The sample is a bit forward looking,
|
|
|
// in this case. This will likely be resolved very shortly, and therefore, the code below
|
|
|
// should be thought of as needed for a smooth user experience.
|
|
|
-#if defined(NVSDK_NGX_Parameter_SuperSampling_NeedsUpdatedDriver) \
|
|
|
- && defined(NVSDK_NGX_Parameter_SuperSampling_MinDriverVersionMajor) \
|
|
|
- && defined(NVSDK_NGX_Parameter_SuperSampling_MinDriverVersionMinor)
|
|
|
+# if defined(NVSDK_NGX_Parameter_SuperSampling_NeedsUpdatedDriver) \
|
|
|
+ && defined(NVSDK_NGX_Parameter_SuperSampling_MinDriverVersionMajor) \
|
|
|
+ && defined(NVSDK_NGX_Parameter_SuperSampling_MinDriverVersionMinor)
|
|
|
|
|
|
// If NGX Successfully initialized then it should set those flags in return
|
|
|
I32 needsUpdatedDriver = 0;
|
|
|
- U32 minDriverVersionMajor = 0;
|
|
|
- U32 minDriverVersionMinor = 0;
|
|
|
- const NVSDK_NGX_Result resultUpdatedDriver =
|
|
|
- m_ngxParameters->Get(NVSDK_NGX_Parameter_SuperSampling_NeedsUpdatedDriver, &needsUpdatedDriver);
|
|
|
- const NVSDK_NGX_Result resultMinDriverVersionMajor =
|
|
|
- m_ngxParameters->Get(NVSDK_NGX_Parameter_SuperSampling_MinDriverVersionMajor, &minDriverVersionMajor);
|
|
|
- const NVSDK_NGX_Result resultMinDriverVersionMinor =
|
|
|
- m_ngxParameters->Get(NVSDK_NGX_Parameter_SuperSampling_MinDriverVersionMinor, &minDriverVersionMinor);
|
|
|
- if(resultUpdatedDriver == NVSDK_NGX_Result_Success && resultMinDriverVersionMajor == NVSDK_NGX_Result_Success
|
|
|
- && resultMinDriverVersionMinor == NVSDK_NGX_Result_Success)
|
|
|
- {
|
|
|
- if(needsUpdatedDriver)
|
|
|
- {
|
|
|
- ANKI_VK_LOGE("NVIDIA DLSS cannot be loaded due to outdated driver. Minimum Driver Version required : %u.%u",
|
|
|
- minDriverVersionMajor, minDriverVersionMinor);
|
|
|
+ ANKI_NGX_CHECK(m_ngxParameters->Get(NVSDK_NGX_Parameter_SuperSampling_NeedsUpdatedDriver, &needsUpdatedDriver));
|
|
|
|
|
|
- return Error::FUNCTION_FAILED;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- ANKI_VK_LOGI("NVIDIA DLSS Minimum driver version was reported as : %u.%u", minDriverVersionMajor,
|
|
|
- minDriverVersionMinor);
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
+ if(needsUpdatedDriver)
|
|
|
{
|
|
|
- ANKI_VK_LOGI("NVIDIA DLSS Minimum driver version was not reported.");
|
|
|
+ ANKI_VK_LOGE("DLSS cannot be loaded due to outdated driver");
|
|
|
+ return Error::FUNCTION_FAILED;
|
|
|
}
|
|
|
-
|
|
|
-#endif
|
|
|
+# endif
|
|
|
|
|
|
I32 dlssAvailable = 0;
|
|
|
- const NVSDK_NGX_Result resultDLSS =
|
|
|
- m_ngxParameters->Get(NVSDK_NGX_Parameter_SuperSampling_Available, &dlssAvailable);
|
|
|
- if(resultDLSS != NVSDK_NGX_Result_Success || !dlssAvailable)
|
|
|
+ ANKI_NGX_CHECK(m_ngxParameters->Get(NVSDK_NGX_Parameter_SuperSampling_Available, &dlssAvailable));
|
|
|
+ if(!dlssAvailable)
|
|
|
{
|
|
|
- // More details about what failed (per feature init result)
|
|
|
- I32 featureInitResult = NVSDK_NGX_Result_Fail;
|
|
|
- NVSDK_NGX_Parameter_GetI(m_ngxParameters, NVSDK_NGX_Parameter_SuperSampling_FeatureInitResult,
|
|
|
- &featureInitResult);
|
|
|
- ANKI_VK_LOGE("NVIDIA DLSS not available on this hardware/platform., FeatureInitResult = 0x%08x, info: %ls",
|
|
|
- featureInitResult, GetNGXResultAsString(static_cast<NVSDK_NGX_Result>(featureInitResult)));
|
|
|
+ ANKI_VK_LOGE("NVIDIA DLSS not available on this hardware/platform");
|
|
|
return Error::FUNCTION_FAILED;
|
|
|
}
|
|
|
|
|
|
// Create the feature
|
|
|
- if(createDLSSFeature(initInfo.m_sourceImageResolution, initInfo.m_targetImageResolution,
|
|
|
- initInfo.m_qualityMode)
|
|
|
- != Error::NONE)
|
|
|
- {
|
|
|
- ANKI_VK_LOGE("Failed to create DLSS feature");
|
|
|
- return Error::FUNCTION_FAILED;
|
|
|
- }
|
|
|
+ ANKI_CHECK(createDlssFeature(initInfo.m_sourceTextureResolution, initInfo.m_targetTextureResolution,
|
|
|
+ initInfo.m_qualityMode));
|
|
|
|
|
|
return Error::NONE;
|
|
|
}
|
|
|
|
|
|
-void GrUpscalerImpl::shutdownDLSS()
|
|
|
-{
|
|
|
- if(isNgxInitialized())
|
|
|
- {
|
|
|
- // WaitForIdle
|
|
|
- getManager().finish();
|
|
|
-
|
|
|
- if(m_dlssFeature != nullptr)
|
|
|
- {
|
|
|
- releaseDLSSFeature();
|
|
|
- }
|
|
|
- NVSDK_NGX_VULKAN_DestroyParameters(m_ngxParameters);
|
|
|
- NVSDK_NGX_VULKAN_Shutdown();
|
|
|
- m_ngxInitialized = false;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-Error GrUpscalerImpl::createDLSSFeature(const UVec2& srcRes, const UVec2& dstRes, const GrUpscalerQualityMode mode)
|
|
|
+Error GrUpscalerImpl::createDlssFeature(const UVec2& srcRes, const UVec2& dstRes, const GrUpscalerQualityMode quality)
|
|
|
{
|
|
|
- ANKI_ASSERT(isNgxInitialized());
|
|
|
+ NVSDK_NGX_PerfQuality_Value nvQuality = getDlssQualityModeToNVQualityMode(quality);
|
|
|
+ ANKI_NGX_CHECK(NGX_DLSS_GET_OPTIMAL_SETTINGS(
|
|
|
+ m_ngxParameters, dstRes.x(), dstRes.y(), nvQuality, &m_recommendedSettings.m_optimalRenderSize.x(),
|
|
|
+ &m_recommendedSettings.m_optimalRenderSize.y(), &m_recommendedSettings.m_dynamicMaximumRenderSize.x(),
|
|
|
+ &m_recommendedSettings.m_dynamicMaximumRenderSize.y(), &m_recommendedSettings.m_dynamicMinimumRenderSize.x(),
|
|
|
+ &m_recommendedSettings.m_dynamicMinimumRenderSize.y(), &m_recommendedSettings.m_sharpness));
|
|
|
|
|
|
- const U32 creationNodeMask = 1;
|
|
|
- const U32 visibilityNodeMask = 1;
|
|
|
// Next create features (See NVSDK_NGX_DLSS_Feature_Flags in nvsdk_ngx_defs.h)
|
|
|
const I32 dlssCreateFeatureFlags =
|
|
|
- NVSDK_NGX_DLSS_Feature_Flags_None | NVSDK_NGX_DLSS_Feature_Flags_MVLowRes | NVSDK_NGX_DLSS_Feature_Flags_IsHDR;
|
|
|
-
|
|
|
- const Error querySettingsResult = queryOptimalSettings(dstRes, mode, m_recommendedSettings);
|
|
|
- if(querySettingsResult != Error::NONE
|
|
|
- || (srcRes < m_recommendedSettings.m_dynamicMinimumRenderSize
|
|
|
- || srcRes > m_recommendedSettings.m_dynamicMaximumRenderSize))
|
|
|
- {
|
|
|
- ANKI_VK_LOGE("Selected DLSS mode or render resolution is not supported");
|
|
|
- return Error::FUNCTION_FAILED;
|
|
|
- }
|
|
|
+ NVSDK_NGX_DLSS_Feature_Flags_MVLowRes | NVSDK_NGX_DLSS_Feature_Flags_IsHDR; // TODO
|
|
|
|
|
|
NVSDK_NGX_DLSS_Create_Params dlssCreateParams;
|
|
|
memset(&dlssCreateParams, 0, sizeof(dlssCreateParams));
|
|
|
@@ -204,95 +132,44 @@ Error GrUpscalerImpl::createDLSSFeature(const UVec2& srcRes, const UVec2& dstRes
|
|
|
dlssCreateParams.Feature.InHeight = srcRes.y();
|
|
|
dlssCreateParams.Feature.InTargetWidth = dstRes.x();
|
|
|
dlssCreateParams.Feature.InTargetHeight = dstRes.y();
|
|
|
- dlssCreateParams.Feature.InPerfQualityValue =
|
|
|
- getDlssQualityModeToNVQualityMode(m_recommendedSettings.m_qualityMode);
|
|
|
+ dlssCreateParams.Feature.InPerfQualityValue = nvQuality;
|
|
|
dlssCreateParams.InFeatureCreateFlags = dlssCreateFeatureFlags;
|
|
|
|
|
|
// Create the feature with a tmp CmdBuffer
|
|
|
CommandBufferInitInfo cmdbinit;
|
|
|
cmdbinit.m_flags = CommandBufferFlag::GENERAL_WORK | CommandBufferFlag::SMALL_BATCH;
|
|
|
- const CommandBufferPtr cmdb = getManager().newCommandBuffer(cmdbinit);
|
|
|
+ CommandBufferPtr cmdb = getManager().newCommandBuffer(cmdbinit);
|
|
|
CommandBufferImpl& cmdbImpl = static_cast<CommandBufferImpl&>(*cmdb);
|
|
|
|
|
|
cmdbImpl.beginRecordingExt();
|
|
|
- const NVSDK_NGX_Result resultDLSS = NGX_VULKAN_CREATE_DLSS_EXT(cmdbImpl.getHandle(), creationNodeMask, visibilityNodeMask,
|
|
|
- &m_dlssFeature,
|
|
|
- m_ngxParameters, &dlssCreateParams);
|
|
|
- if(NVSDK_NGX_FAILED(resultDLSS))
|
|
|
- {
|
|
|
- ANKI_VK_LOGE("Failed to create DLSS Features = 0x%08x, info: %ls", resultDLSS,
|
|
|
- GetNGXResultAsString(resultDLSS));
|
|
|
- return Error::FUNCTION_FAILED;
|
|
|
- }
|
|
|
+ const U32 creationNodeMask = 1;
|
|
|
+ const U32 visibilityNodeMask = 1;
|
|
|
+ ANKI_NGX_CHECK(NGX_VULKAN_CREATE_DLSS_EXT(cmdbImpl.getHandle(), creationNodeMask, visibilityNodeMask,
|
|
|
+ &m_dlssFeature, m_ngxParameters, &dlssCreateParams));
|
|
|
cmdb->flush();
|
|
|
|
|
|
return Error::NONE;
|
|
|
}
|
|
|
|
|
|
-void GrUpscalerImpl::releaseDLSSFeature()
|
|
|
+void GrUpscalerImpl::destroyDlss()
|
|
|
{
|
|
|
- ANKI_ASSERT(isNgxInitialized());
|
|
|
-
|
|
|
- getManager().finish();
|
|
|
-
|
|
|
- const NVSDK_NGX_Result resultDLSS =
|
|
|
- (m_dlssFeature != nullptr) ? NVSDK_NGX_VULKAN_ReleaseFeature(m_dlssFeature) : NVSDK_NGX_Result_Success;
|
|
|
- if(NVSDK_NGX_FAILED(resultDLSS))
|
|
|
+ if(m_dlssFeature)
|
|
|
{
|
|
|
- ANKI_VK_LOGE("Failed to NVSDK_NGX_D3D12_ReleaseFeature, code = 0x%08x, info: %ls", resultDLSS,
|
|
|
- GetNGXResultAsString(resultDLSS));
|
|
|
+ NVSDK_NGX_VULKAN_ReleaseFeature(m_dlssFeature);
|
|
|
+ m_dlssFeature = nullptr;
|
|
|
}
|
|
|
|
|
|
- m_dlssFeature = nullptr;
|
|
|
-}
|
|
|
-
|
|
|
-static Error queryNgxQualitySettings(const UVec2& displayRes, const NVSDK_NGX_PerfQuality_Value quality,
|
|
|
- NVSDK_NGX_Parameter& parameters, DLSSRecommendedSettings& outSettings)
|
|
|
-{
|
|
|
- const NVSDK_NGX_Result result = NGX_DLSS_GET_OPTIMAL_SETTINGS(
|
|
|
- ¶meters, displayRes.x(), displayRes.y(), quality, &outSettings.m_recommendedOptimalRenderSize[0],
|
|
|
- &outSettings.m_recommendedOptimalRenderSize[1], &outSettings.m_dynamicMaximumRenderSize[0],
|
|
|
- &outSettings.m_dynamicMaximumRenderSize[1], &outSettings.m_dynamicMinimumRenderSize[0],
|
|
|
- &outSettings.m_dynamicMinimumRenderSize[1], &outSettings.m_recommendedSharpness);
|
|
|
-
|
|
|
- if(NVSDK_NGX_FAILED(result))
|
|
|
+ if(m_ngxParameters)
|
|
|
{
|
|
|
- outSettings.m_recommendedOptimalRenderSize = displayRes;
|
|
|
- outSettings.m_dynamicMaximumRenderSize = displayRes;
|
|
|
- outSettings.m_dynamicMinimumRenderSize = displayRes;
|
|
|
- outSettings.m_recommendedSharpness = 0.0f;
|
|
|
-
|
|
|
- ANKI_VK_LOGW("Querying Settings failed! code = 0x%08x, info: %ls", result, GetNGXResultAsString(result));
|
|
|
- return Error::FUNCTION_FAILED;
|
|
|
+ NVSDK_NGX_VULKAN_DestroyParameters(m_ngxParameters);
|
|
|
+ m_ngxParameters = nullptr;
|
|
|
}
|
|
|
- return Error::NONE;
|
|
|
-}
|
|
|
|
|
|
-Error GrUpscalerImpl::queryOptimalSettings(const UVec2& displayRes, const GrUpscalerQualityMode mode,
|
|
|
- DLSSRecommendedSettings& outRecommendedSettings)
|
|
|
-{
|
|
|
- ANKI_ASSERT(mode < GrUpscalerQualityMode::COUNT);
|
|
|
-
|
|
|
- outRecommendedSettings.m_qualityMode = mode;
|
|
|
- Error err(Error::FUNCTION_FAILED);
|
|
|
- switch(mode)
|
|
|
+ if(m_ngxInitialized)
|
|
|
{
|
|
|
- case GrUpscalerQualityMode::PERFORMANCE:
|
|
|
- err = queryNgxQualitySettings(displayRes, NVSDK_NGX_PerfQuality_Value_MaxPerf, *m_ngxParameters,
|
|
|
- outRecommendedSettings);
|
|
|
- break;
|
|
|
- case GrUpscalerQualityMode::BALANCED:
|
|
|
- err = queryNgxQualitySettings(displayRes, NVSDK_NGX_PerfQuality_Value_Balanced, *m_ngxParameters,
|
|
|
- outRecommendedSettings);
|
|
|
- break;
|
|
|
- case GrUpscalerQualityMode::QUALITY:
|
|
|
- err = queryNgxQualitySettings(displayRes, NVSDK_NGX_PerfQuality_Value_MaxQuality, *m_ngxParameters,
|
|
|
- outRecommendedSettings);
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
+ NVSDK_NGX_VULKAN_Shutdown();
|
|
|
+ m_ngxInitialized = false;
|
|
|
}
|
|
|
- return err;
|
|
|
}
|
|
|
#endif // ANKI_DLSS
|
|
|
|