| … | … | @@ -620,7 +620,13 @@ public: |
| 620 | 620 | uint32_t output_width = 0; |
| 621 | 621 | uint32_t output_height = 0; |
| 622 | 622 | |
| 623 | | virtual ~NGXDLSSContext() { |
| 623 | // Which kind of feature feature_created refers to. RR and SR are distinct NGX |
| 624 | // features with separate handles, so switching between them at runtime has to |
| 625 | // tear the old one down -- otherwise the evaluate path picks the branch for |
| 626 | // the newly requested mode and finds a null handle. |
| 627 | bool feature_is_rr = false; |
| 628 | |
| 629 | void release_feature() { |
| 624 | 630 | if (dlss_rr_handle) { |
| 625 | 631 | NVSDK_NGX_VULKAN_ReleaseFeature(dlss_rr_handle); |
| 626 | 632 | dlss_rr_handle = nullptr; |
| … | … | @@ -629,6 +635,11 @@ public: |
| 629 | 635 | NVSDK_NGX_VULKAN_ReleaseFeature(dlss_sr_handle); |
| 630 | 636 | dlss_sr_handle = nullptr; |
| 631 | 637 | } |
| 638 | feature_created = false; |
| 639 | } |
| 640 | |
| 641 | virtual ~NGXDLSSContext() { |
| 642 | release_feature(); |
| 632 | 643 | } |
| 633 | 644 | }; |
| 634 | 645 | } // namespace RendererRD |
| … | … | @@ -934,6 +945,14 @@ void DLSSEffect::_upscale_internal(RDD::CommandBufferID cmdid, const DLSSContext |
| 934 | 945 | |
| 935 | 946 | bool use_dlss_rr = p_params.dlss_rr && g_ngx_dlss_rr_available; |
| 936 | 947 | |
| 948 | // Ray Reconstruction and Super Resolution are separate NGX features with |
| 949 | // separate handles. Toggling between them at runtime (a settings change) must |
| 950 | // destroy the existing one, or creation is skipped as already-done and the |
| 951 | // evaluate branch for the newly requested mode dereferences a null handle. |
| 952 | if (ctx->feature_created && ctx->feature_is_rr != use_dlss_rr) { |
| 953 | ctx->release_feature(); |
| 954 | } |
| 955 | |
| 937 | 956 | // Create NGX feature on first use |
| 938 | 957 | if (!ctx->feature_created) { |
| 939 | 958 | NVSDK_NGX_Result result; |
| … | … | @@ -959,6 +978,7 @@ void DLSSEffect::_upscale_internal(RDD::CommandBufferID cmdid, const DLSSContext |
| 959 | 978 | |
| 960 | 979 | if (NVSDK_NGX_SUCCEED(result)) { |
| 961 | 980 | ctx->feature_created = true; |
| 981 | ctx->feature_is_rr = true; |
| 962 | 982 | print_line("[NGX DLSS] DLSS-RR feature created successfully"); |
| 963 | 983 | } else { |
| 964 | 984 | WARN_PRINT(vformat("[NGX DLSS] DLSS-RR creation failed (0x%x), falling back to DLSS-SR", (uint32_t)result)); |
| … | … | @@ -989,6 +1009,7 @@ void DLSSEffect::_upscale_internal(RDD::CommandBufferID cmdid, const DLSSContext |
| 989 | 1009 | return; |
| 990 | 1010 | } |
| 991 | 1011 | ctx->feature_created = true; |
| 1012 | ctx->feature_is_rr = false; |
| 992 | 1013 | use_dlss_rr = false; |
| 993 | 1014 | print_line("[NGX DLSS] DLSS-SR feature created successfully"); |
| 994 | 1015 | } |
| … | … | @@ -1089,6 +1110,9 @@ void DLSSEffect::_upscale_internal(RDD::CommandBufferID cmdid, const DLSSContext |
| 1089 | 1110 | eval.InMVScaleX = (float)ctx->render_width; |
| 1090 | 1111 | eval.InMVScaleY = (float)ctx->render_height; |
| 1091 | 1112 | |
| 1113 | // Defensive: the mode-change path above should always have recreated the |
| 1114 | // feature, but never hand NGX a null handle. |
| 1115 | ERR_FAIL_NULL_MSG(ctx->dlss_sr_handle, "[NGX DLSS] SR evaluate with no SR feature."); |
| 1092 | 1116 | NVSDK_NGX_Result result = NGX_VULKAN_EVALUATE_DLSS_EXT(vk_cmd, ctx->dlss_sr_handle, g_ngx_params, &eval); |
| 1093 | 1117 | if (NVSDK_NGX_FAILED(result)) { |
| 1094 | 1118 | ERR_PRINT(vformat("[NGX DLSS] DLSS-SR evaluate failed: 0x%x", (uint32_t)result)); |