From 4981cf0630ef109f73e7b99be7b3c71f798be4aa Mon Sep 17 00:00:00 2001 From: dhaern Date: Mon, 5 Oct 2026 23:35:38 +0000 Subject: [PATCH] Clean up NGX state when feature setup fails Reuse feature teardown on setup errors and publish output metadata only after all slots are ready. Keep render-size recovery retryable after failed restoration, and retry partially failed library loads. --- tools/d4r_nvngx_shim.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/tools/d4r_nvngx_shim.cpp b/tools/d4r_nvngx_shim.cpp index 960cd80..e4e15cc 100644 --- a/tools/d4r_nvngx_shim.cpp +++ b/tools/d4r_nvngx_shim.cpp @@ -1455,7 +1455,10 @@ static NgxResult initialize(unsigned long long applicationId, const wchar_t* dat logf("d4r: %s", note.c_str()); } if (g.core == nullptr && !load_libraries()) + { + g.core = nullptr; return NGX_FAIL_PLATFORM_ERROR; + } if (device != nullptr) { device->AddRef(); @@ -3921,18 +3924,19 @@ static bool recreate_for_render_size(Feature& feature, FrameParams& params, uint { logf("frame %u: recreating the NGX feature at %ux%u failed (0x%08x); restoring %ux%u", frame, width, height, created, feature.cudaWidth, feature.cudaHeight); - feature.refusedWidth = width; - feature.refusedHeight = height; width = feature.cudaWidth; height = feature.cudaHeight; d4r_ngx_set_uint(p, "Width", width); d4r_ngx_set_uint(p, "Height", height); - feature.cudaHandle = nullptr; - created = g.ngx.createFeature(NGX_FEATURE_SUPER_SAMPLING, p, &feature.cudaHandle); + if (width != 0 && height != 0) + created = g.ngx.createFeature(NGX_FEATURE_SUPER_SAMPLING, p, &feature.cudaHandle); + feature.refusedWidth = created == NGX_SUCCESS ? params.renderWidth : 0; + feature.refusedHeight = created == NGX_SUCCESS ? params.renderHeight : 0; if (created != NGX_SUCCESS) { logf("frame %u: restoring the NGX feature failed (0x%08x)", frame, created); feature.cudaHandle = nullptr; + width = height = 0; } } // a new feature has no history @@ -4303,6 +4307,7 @@ static void drain_pipeline() g.finish.call([] { return 0; }); } +static void release_feature(Feature* feature); static void destroy_recorded_resources(Feature* feature); static void finish_shutdown(); @@ -4645,13 +4650,13 @@ D4R_EXPORT NgxResult NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsCommandList*, u logf("NVSDK_NGX_CUDA_CreateFeature -> 0x%08x", result); if (result != NGX_SUCCESS) { - delete feature; + release_feature(feature); return result; } if (!create_buffer(D3D12_HEAP_TYPE_READBACK, 256, &feature->marker, reinterpret_cast(const_cast(&feature->markerValue)))) { - delete feature; + release_feature(feature); return NGX_FAIL_PLATFORM_ERROR; } for (int index = 0; index <= kSlots; ++index) @@ -4893,9 +4898,6 @@ static NgxResult evaluate(ID3D12GraphicsCommandList* list, const NgxHandle* hand // before the output buffers go away. drain_pipeline(); feature->latestOutput = -1; - feature->outputFormat = outputDesc.Format; - feature->outputWidth = static_cast(outputDesc.Width); - feature->outputHeight = outputDesc.Height; for (OutputSlot& outputSlot : feature->outputs) { outputSlot.staging.retire(); @@ -4904,6 +4906,9 @@ static NgxResult evaluate(ID3D12GraphicsCommandList* list, const NgxHandle* hand : !ensure_staging(outputSlot.staging, output, D3D12_HEAP_TYPE_UPLOAD)) return NGX_FAIL_PLATFORM_ERROR; } + feature->outputFormat = outputDesc.Format; + feature->outputWidth = static_cast(outputDesc.Width); + feature->outputHeight = outputDesc.Height; } const auto inputState = static_cast(env_uint("D4R_SHIM_INPUT_STATE", 0x40)); @@ -5094,7 +5099,10 @@ static void release_feature(Feature* feature) } // Recorded lists retain this owner through their allocator. Reset/discard // or GPU completion followed by allocator destruction releases those refs. - feature->resources->Release(); + if (feature->resources != nullptr) + feature->resources->Release(); + else + delete feature; } static void destroy_recorded_resources(Feature* feature)