Skip to content

Commit 3d2963b

Browse files
committed
fix(ngx): retain owned search paths through native initialization
1 parent 1854488 commit 3d2963b

11 files changed

Lines changed: 309 additions & 107 deletions

‎.github/workflows/just_build_no_signature.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ jobs:
133133
& $env:ComSpec /d /c $command
134134
if ($LASTEXITCODE) { throw "Compatibility guard test failed: $name" }
135135
}
136-
foreach ($script in @('test_shutdown_routing.py','test_provider_publication_routes.py','test_provider_dll_boundary.py','test_combo_release.py','test_native_operation_routes.py','test_native_module_publication.py','test_native_init_scopes.py')) {
136+
foreach ($script in @('test_shutdown_routing.py','test_provider_publication_routes.py','test_provider_dll_boundary.py','test_combo_release.py','test_native_operation_routes.py','test_native_module_publication.py','test_native_init_scopes.py','test_ngx_init_paths.py')) {
137137
$command = 'call "' + $vcvars + '" && python tests\' + $script + ' --compiler cl'
138138
& $env:ComSpec /d /c $command
139139
if ($LASTEXITCODE) { throw "Compatibility routing test failed: $script" }

‎OptiScaler/State.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <inputs/FG/Streamline_Inputs_Sl1_Dx12.h>
99

1010
#include <atomic>
11+
#include <proxies/NgxPathSnapshot.h>
1112
#include <set>
1213
#include <deque>
1314
#include <mutex>
@@ -180,7 +181,7 @@ class State
180181
std::wstring NVNGX_ApplicationDataPath;
181182
std::string NVNGX_ProjectId;
182183
NVSDK_NGX_Version NVNGX_Version {};
183-
std::vector<std::wstring> NVNGX_FeatureInfo_Paths;
184+
NgxPathCache NVNGX_FeatureInfo_Paths;
184185
NVSDK_NGX_LoggingInfo NVNGX_Logger { nullptr, NVSDK_NGX_LOGGING_LEVEL_OFF, false };
185186
NVSDK_NGX_EngineType NVNGX_Engine = NVSDK_NGX_ENGINE_TYPE_CUSTOM;
186187
std::string NVNGX_EngineVersion;

‎OptiScaler/dlssnr/DlssNr_Proxy.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ unsigned int Run(ID3D12GraphicsCommandList* cmdList, ID3D12Device* device, ID3D1
204204
reinitialised = true;
205205

206206
NVSDK_NGX_FeatureCommonInfo fcInfo {};
207-
NVNGXProxy::GetFeatureCommonInfo(&fcInfo);
207+
const auto initPaths = NVNGXProxy::GetFeatureCommonInfo(&fcInfo);
208208

209209
const auto initResult = NVNGXProxy::D3D12_Init_Ext()(
210210
app_id_override, State::Instance().NVNGX_ApplicationDataPath.c_str(), device,

‎OptiScaler/inputs/NVNGX_DLSS_Dx11.cpp‎

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ static ankerl::unordered_dense::map<unsigned int, ContextData<IFeature_Dx11>> Dx
2222
static int evalCounter = 0;
2323
static bool shutdown = false;
2424
static thread_local bool _skipInit = false;
25-
static wchar_t const** paths;
2625

2726
class ScopedInitDx11
2827
{
@@ -39,9 +38,9 @@ class ScopedInitDx11
3938
~ScopedInitDx11() { _skipInit = previousState; }
4039
};
4140

42-
static void UpdateInitPaths(NVSDK_NGX_FeatureCommonInfo* InFeatureInfo)
41+
[[nodiscard]] static NgxPathSnapshot::Owner UpdateInitPaths(NVSDK_NGX_FeatureCommonInfo* InFeatureInfo)
4342
{
44-
State::Instance().NVNGX_FeatureInfo_Paths.clear();
43+
std::vector<std::wstring> initPaths;
4544

4645
if (InFeatureInfo != nullptr)
4746
{
@@ -92,47 +91,41 @@ static void UpdateInitPaths(NVSDK_NGX_FeatureCommonInfo* InFeatureInfo)
9291

9392
// Override locations
9493
if (Config::Instance()->DLSSFeaturePath.has_value())
95-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(Config::Instance()->DLSSFeaturePath.value());
94+
initPaths.push_back(Config::Instance()->DLSSFeaturePath.value());
9695

9796
// If DLSS path is overriden
9897
if (Config::Instance()->NVNGX_DLSS_Library.has_value() && nvngxDlssPath.has_value())
99-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(nvngxDlssPath.value().parent_path().wstring());
98+
initPaths.push_back(nvngxDlssPath.value().parent_path().wstring());
10099

101100
// OptiDll Path
102-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(Config::Instance()->MainDllPath.value());
101+
initPaths.push_back(Config::Instance()->MainDllPath.value());
103102

104103
// Original paths from NVNGX
105104
for (size_t i = 0; i < InFeatureInfo->PathListInfo.Length; i++)
106105
{
107106
const wchar_t* path = InFeatureInfo->PathListInfo.Path[i];
108-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(std::wstring(path));
107+
initPaths.push_back(std::wstring(path));
109108
}
110109

111110
// Exe path
112-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(exePath.wstring());
111+
initPaths.push_back(exePath.wstring());
113112

114113
// If DLSS path is not overriden
115114
if (!Config::Instance()->NVNGX_DLSS_Library.has_value() && nvngxDlssPath.has_value())
116-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(nvngxDlssPath.value().parent_path().wstring());
115+
initPaths.push_back(nvngxDlssPath.value().parent_path().wstring());
117116

118117
// Add found locations
119118
if (nvngxDlssDPath.has_value())
120-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(nvngxDlssDPath.value().parent_path().wstring());
119+
initPaths.push_back(nvngxDlssDPath.value().parent_path().wstring());
121120

122121
if (nvngxDlssGPath.has_value())
123-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(nvngxDlssGPath.value().parent_path().wstring());
122+
initPaths.push_back(nvngxDlssGPath.value().parent_path().wstring());
124123

125-
// Build pointer array
126-
paths = new const wchar_t*[State::Instance().NVNGX_FeatureInfo_Paths.size()];
127-
for (size_t i = 0; i < State::Instance().NVNGX_FeatureInfo_Paths.size(); ++i)
128-
{
129-
paths[i] = State::Instance().NVNGX_FeatureInfo_Paths[i].c_str();
130-
LOG_DEBUG("Feature Path [{}]: {}", i, wstring_to_string(State::Instance().NVNGX_FeatureInfo_Paths[i]));
131-
}
132-
133-
InFeatureInfo->PathListInfo.Path = paths;
134-
InFeatureInfo->PathListInfo.Length = (int) State::Instance().NVNGX_FeatureInfo_Paths.size();
124+
auto owner = State::Instance().NVNGX_FeatureInfo_Paths.Publish(std::move(initPaths));
125+
owner->Bind(InFeatureInfo->PathListInfo);
126+
return owner;
135127
}
128+
return {};
136129
}
137130

138131
#pragma region NVSDK_NGX_D3D11_Init
@@ -147,8 +140,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_Init_Ext(unsigned long long InApp
147140
if (InFeatureInfo != nullptr)
148141
std::memcpy(&localFeatureInfo, InFeatureInfo, sizeof(NVSDK_NGX_FeatureCommonInfo));
149142

150-
if (!_skipInit)
151-
UpdateInitPaths(&localFeatureInfo);
143+
// A delegated call borrows its outer call's still-live snapshot.
144+
const auto initPaths = _skipInit ? NgxPathSnapshot::Owner {} : UpdateInitPaths(&localFeatureInfo);
152145

153146
State::Instance().NVNGX_ApplicationId = InApplicationId;
154147
State::Instance().NVNGX_ApplicationDataPath = std::wstring(InApplicationDataPath);
@@ -213,8 +206,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_Init(unsigned long long InApplica
213206
if (InFeatureInfo != nullptr)
214207
std::memcpy(&localFeatureInfo, InFeatureInfo, sizeof(NVSDK_NGX_FeatureCommonInfo));
215208

216-
if (!_skipInit)
217-
UpdateInitPaths(&localFeatureInfo);
209+
// A delegated call borrows its outer call's still-live snapshot.
210+
const auto initPaths = _skipInit ? NgxPathSnapshot::Owner {} : UpdateInitPaths(&localFeatureInfo);
218211

219212
if (Config::Instance()->DLSSEnabled.value_or_default() && !_skipInit)
220213
{
@@ -256,8 +249,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_Init_ProjectID(const char* InProj
256249
if (InFeatureInfo != nullptr)
257250
std::memcpy(&localFeatureInfo, InFeatureInfo, sizeof(NVSDK_NGX_FeatureCommonInfo));
258251

259-
if (!_skipInit)
260-
UpdateInitPaths(&localFeatureInfo);
252+
// A delegated call borrows its outer call's still-live snapshot.
253+
const auto initPaths = _skipInit ? NgxPathSnapshot::Owner {} : UpdateInitPaths(&localFeatureInfo);
261254

262255
if (Config::Instance()->DLSSEnabled.value_or_default() && !_skipInit)
263256
{

‎OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp‎

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ static ID3D12Device* D3D12Device = nullptr;
3434
static int evalCounter = 0;
3535
static bool shutdown = false;
3636
static thread_local bool _skipInit = false;
37-
static wchar_t const** paths;
3837

3938
class ScopedInitDx12
4039
{
@@ -51,9 +50,9 @@ class ScopedInitDx12
5150
~ScopedInitDx12() { _skipInit = previousState; }
5251
};
5352

54-
static void UpdateInitPaths(NVSDK_NGX_FeatureCommonInfo* InFeatureInfo)
53+
[[nodiscard]] static NgxPathSnapshot::Owner UpdateInitPaths(NVSDK_NGX_FeatureCommonInfo* InFeatureInfo)
5554
{
56-
State::Instance().NVNGX_FeatureInfo_Paths.clear();
55+
std::vector<std::wstring> initPaths;
5756

5857
if (InFeatureInfo != nullptr)
5958
{
@@ -104,47 +103,41 @@ static void UpdateInitPaths(NVSDK_NGX_FeatureCommonInfo* InFeatureInfo)
104103

105104
// Override locations
106105
if (Config::Instance()->DLSSFeaturePath.has_value())
107-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(Config::Instance()->DLSSFeaturePath.value());
106+
initPaths.push_back(Config::Instance()->DLSSFeaturePath.value());
108107

109108
// If DLSS path is overriden
110109
if (Config::Instance()->NVNGX_DLSS_Library.has_value() && nvngxDlssPath.has_value())
111-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(nvngxDlssPath.value().parent_path().wstring());
110+
initPaths.push_back(nvngxDlssPath.value().parent_path().wstring());
112111

113112
// OptiDll Path
114-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(Config::Instance()->MainDllPath.value());
113+
initPaths.push_back(Config::Instance()->MainDllPath.value());
115114

116115
// Original paths from NVNGX
117116
for (size_t i = 0; i < InFeatureInfo->PathListInfo.Length; i++)
118117
{
119118
const wchar_t* path = InFeatureInfo->PathListInfo.Path[i];
120-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(std::wstring(path));
119+
initPaths.push_back(std::wstring(path));
121120
}
122121

123122
// Exe path
124-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(exePath.wstring());
123+
initPaths.push_back(exePath.wstring());
125124

126125
// If DLSS path is not overriden
127126
if (!Config::Instance()->NVNGX_DLSS_Library.has_value() && nvngxDlssPath.has_value())
128-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(nvngxDlssPath.value().parent_path().wstring());
127+
initPaths.push_back(nvngxDlssPath.value().parent_path().wstring());
129128

130129
// Add found locations
131130
if (nvngxDlssDPath.has_value())
132-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(nvngxDlssDPath.value().parent_path().wstring());
131+
initPaths.push_back(nvngxDlssDPath.value().parent_path().wstring());
133132

134133
if (nvngxDlssGPath.has_value())
135-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(nvngxDlssGPath.value().parent_path().wstring());
134+
initPaths.push_back(nvngxDlssGPath.value().parent_path().wstring());
136135

137-
// Build pointer array
138-
paths = new const wchar_t*[State::Instance().NVNGX_FeatureInfo_Paths.size()];
139-
for (size_t i = 0; i < State::Instance().NVNGX_FeatureInfo_Paths.size(); ++i)
140-
{
141-
paths[i] = State::Instance().NVNGX_FeatureInfo_Paths[i].c_str();
142-
LOG_DEBUG("Feature Path [{}]: {}", i, wstring_to_string(State::Instance().NVNGX_FeatureInfo_Paths[i]));
143-
}
144-
145-
InFeatureInfo->PathListInfo.Path = paths;
146-
InFeatureInfo->PathListInfo.Length = (int) State::Instance().NVNGX_FeatureInfo_Paths.size();
136+
auto owner = State::Instance().NVNGX_FeatureInfo_Paths.Publish(std::move(initPaths));
137+
owner->Bind(InFeatureInfo->PathListInfo);
138+
return owner;
147139
}
140+
return {};
148141
}
149142

150143
#pragma region DLSS Init Calls
@@ -161,8 +154,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_Ext(unsigned long long InApp
161154
if (InFeatureInfo != nullptr)
162155
std::memcpy(&localFeatureInfo, InFeatureInfo, sizeof(NVSDK_NGX_FeatureCommonInfo));
163156

164-
if (!_skipInit)
165-
UpdateInitPaths(&localFeatureInfo);
157+
// A delegated call borrows its outer call's still-live snapshot.
158+
const auto initPaths = _skipInit ? NgxPathSnapshot::Owner {} : UpdateInitPaths(&localFeatureInfo);
166159

167160
State::Instance().NVNGX_ApplicationId = InApplicationId;
168161
State::Instance().NVNGX_ApplicationDataPath = std::wstring(InApplicationDataPath);
@@ -243,8 +236,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init(unsigned long long InApplica
243236
if (InFeatureInfo != nullptr)
244237
std::memcpy(&localFeatureInfo, InFeatureInfo, sizeof(NVSDK_NGX_FeatureCommonInfo));
245238

246-
if (!_skipInit)
247-
UpdateInitPaths(&localFeatureInfo);
239+
// A delegated call borrows its outer call's still-live snapshot.
240+
const auto initPaths = _skipInit ? NgxPathSnapshot::Owner {} : UpdateInitPaths(&localFeatureInfo);
248241

249242
if (Config::Instance()->DLSSEnabled.value_or_default() && !_skipInit)
250243
{
@@ -306,8 +299,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_ProjectID(const char* InProj
306299
if (InFeatureInfo != nullptr)
307300
std::memcpy(&localFeatureInfo, InFeatureInfo, sizeof(NVSDK_NGX_FeatureCommonInfo));
308301

309-
if (!_skipInit)
310-
UpdateInitPaths(&localFeatureInfo);
302+
// A delegated call borrows its outer call's still-live snapshot.
303+
const auto initPaths = _skipInit ? NgxPathSnapshot::Owner {} : UpdateInitPaths(&localFeatureInfo);
311304

312305
if (Config::Instance()->DLSSEnabled.value_or_default() && !_skipInit)
313306
{

‎OptiScaler/inputs/NVNGX_DLSS_Vk.cpp‎

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ static ankerl::unordered_dense::map<unsigned int, ContextData<IFeature_Vk>> VkCo
2828
static int evalCounter = 0;
2929
static bool shutdown = false;
3030
static thread_local bool _skipInit = false;
31-
static wchar_t const** paths;
3231

3332
class ScopedInitVk
3433
{
@@ -45,9 +44,9 @@ class ScopedInitVk
4544
~ScopedInitVk() { _skipInit = previousState; }
4645
};
4746

48-
static void UpdateInitPaths(NVSDK_NGX_FeatureCommonInfo* InFeatureInfo)
47+
[[nodiscard]] static NgxPathSnapshot::Owner UpdateInitPaths(NVSDK_NGX_FeatureCommonInfo* InFeatureInfo)
4948
{
50-
State::Instance().NVNGX_FeatureInfo_Paths.clear();
49+
std::vector<std::wstring> initPaths;
5150

5251
if (InFeatureInfo != nullptr)
5352
{
@@ -98,14 +97,14 @@ static void UpdateInitPaths(NVSDK_NGX_FeatureCommonInfo* InFeatureInfo)
9897

9998
// Override locations
10099
if (Config::Instance()->DLSSFeaturePath.has_value())
101-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(Config::Instance()->DLSSFeaturePath.value());
100+
initPaths.push_back(Config::Instance()->DLSSFeaturePath.value());
102101

103102
// If DLSS path is overriden
104103
if (Config::Instance()->NVNGX_DLSS_Library.has_value() && nvngxDlssPath.has_value())
105-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(nvngxDlssPath.value().parent_path().wstring());
104+
initPaths.push_back(nvngxDlssPath.value().parent_path().wstring());
106105

107106
// OptiDll Path
108-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(Config::Instance()->MainDllPath.value());
107+
initPaths.push_back(Config::Instance()->MainDllPath.value());
109108

110109
// WAR: Doom Ethernal is sending junk data
111110
if (InFeatureInfo->PathListInfo.Length < 10)
@@ -114,35 +113,29 @@ static void UpdateInitPaths(NVSDK_NGX_FeatureCommonInfo* InFeatureInfo)
114113
for (size_t i = 0; i < InFeatureInfo->PathListInfo.Length; i++)
115114
{
116115
const wchar_t* path = InFeatureInfo->PathListInfo.Path[i];
117-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(std::wstring(path));
116+
initPaths.push_back(std::wstring(path));
118117
}
119118
}
120119

121120
// Exe path
122-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(exePath.wstring());
121+
initPaths.push_back(exePath.wstring());
123122

124123
// If DLSS path is not overriden
125124
if (!Config::Instance()->NVNGX_DLSS_Library.has_value() && nvngxDlssPath.has_value())
126-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(nvngxDlssPath.value().parent_path().wstring());
125+
initPaths.push_back(nvngxDlssPath.value().parent_path().wstring());
127126

128127
// Add found locations
129128
if (nvngxDlssDPath.has_value())
130-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(nvngxDlssDPath.value().parent_path().wstring());
129+
initPaths.push_back(nvngxDlssDPath.value().parent_path().wstring());
131130

132131
if (nvngxDlssGPath.has_value())
133-
State::Instance().NVNGX_FeatureInfo_Paths.push_back(nvngxDlssGPath.value().parent_path().wstring());
132+
initPaths.push_back(nvngxDlssGPath.value().parent_path().wstring());
134133

135-
// Build pointer array
136-
paths = new const wchar_t*[State::Instance().NVNGX_FeatureInfo_Paths.size()];
137-
for (size_t i = 0; i < State::Instance().NVNGX_FeatureInfo_Paths.size(); ++i)
138-
{
139-
paths[i] = State::Instance().NVNGX_FeatureInfo_Paths[i].c_str();
140-
LOG_DEBUG("Feature Path [{}]: {}", i, wstring_to_string(State::Instance().NVNGX_FeatureInfo_Paths[i]));
141-
}
142-
143-
InFeatureInfo->PathListInfo.Path = paths;
144-
InFeatureInfo->PathListInfo.Length = (int) State::Instance().NVNGX_FeatureInfo_Paths.size();
134+
auto owner = State::Instance().NVNGX_FeatureInfo_Paths.Publish(std::move(initPaths));
135+
owner->Bind(InFeatureInfo->PathListInfo);
136+
return owner;
145137
}
138+
return {};
146139
}
147140

148141
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_Ext2(
@@ -157,8 +150,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_Ext2(
157150
if (InFeatureInfo != nullptr)
158151
std::memcpy(&localFeatureInfo, InFeatureInfo, sizeof(NVSDK_NGX_FeatureCommonInfo));
159152

160-
if (!_skipInit)
161-
UpdateInitPaths(&localFeatureInfo);
153+
// A delegated call borrows its outer call's still-live snapshot.
154+
const auto initPaths = _skipInit ? NgxPathSnapshot::Owner {} : UpdateInitPaths(&localFeatureInfo);
162155

163156
State::Instance().NVNGX_ApplicationId = InApplicationId;
164157
State::Instance().NVNGX_ApplicationDataPath = std::wstring(InApplicationDataPath);
@@ -273,8 +266,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_Ext(unsigned long long InAp
273266
if (InFeatureInfo != nullptr)
274267
std::memcpy(&localFeatureInfo, InFeatureInfo, sizeof(NVSDK_NGX_FeatureCommonInfo));
275268

276-
if (!_skipInit)
277-
UpdateInitPaths(&localFeatureInfo);
269+
// A delegated call borrows its outer call's still-live snapshot.
270+
const auto initPaths = _skipInit ? NgxPathSnapshot::Owner {} : UpdateInitPaths(&localFeatureInfo);
278271

279272
if (Config::Instance()->DLSSEnabled.value_or_default() && !_skipInit)
280273
{
@@ -324,8 +317,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_ProjectID_Ext(
324317
if (InFeatureInfo != nullptr)
325318
std::memcpy(&localFeatureInfo, InFeatureInfo, sizeof(NVSDK_NGX_FeatureCommonInfo));
326319

327-
if (!_skipInit)
328-
UpdateInitPaths(&localFeatureInfo);
320+
// A delegated call borrows its outer call's still-live snapshot.
321+
const auto initPaths = _skipInit ? NgxPathSnapshot::Owner {} : UpdateInitPaths(&localFeatureInfo);
329322

330323
if (Config::Instance()->DLSSEnabled.value_or_default() && !_skipInit)
331324
{
@@ -379,8 +372,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init(unsigned long long InApplic
379372
if (InFeatureInfo != nullptr)
380373
std::memcpy(&localFeatureInfo, InFeatureInfo, sizeof(NVSDK_NGX_FeatureCommonInfo));
381374

382-
if (!_skipInit)
383-
UpdateInitPaths(&localFeatureInfo);
375+
// A delegated call borrows its outer call's still-live snapshot.
376+
const auto initPaths = _skipInit ? NgxPathSnapshot::Owner {} : UpdateInitPaths(&localFeatureInfo);
384377

385378
if (Config::Instance()->DLSSEnabled.value_or_default() && !_skipInit)
386379
{
@@ -430,8 +423,8 @@ NVSDK_NGX_VULKAN_Init_ProjectID(const char* InProjectId, NVSDK_NGX_EngineType In
430423
if (InFeatureInfo != nullptr)
431424
std::memcpy(&localFeatureInfo, InFeatureInfo, sizeof(NVSDK_NGX_FeatureCommonInfo));
432425

433-
if (!_skipInit)
434-
UpdateInitPaths(&localFeatureInfo);
426+
// A delegated call borrows its outer call's still-live snapshot.
427+
const auto initPaths = _skipInit ? NgxPathSnapshot::Owner {} : UpdateInitPaths(&localFeatureInfo);
435428

436429
if (Config::Instance()->DLSSEnabled.value_or_default() && !_skipInit)
437430
{

0 commit comments

Comments
 (0)