OverviewFilesCommitsIssuesDocsReleasesPeers

nvidia-rtx-godot commits / 650dcc4

Fix dangling stack pointers passed to NGX as the DLSS-RR camera matrices
The DLSS-RR eval path built its world-to-view and view-to-clip matrices in stack-local float[16] arrays and assigned their addresses to pInWorldToViewMatrix / pInViewToClipMatrix. NGX's helper forwards those through NVSDK_NGX_Parameter_SetVoidPointer, which stores the POINTER -- it does not copy -- and NGX dereferences it during feature evaluation. The arrays died as soon as evaluate() returned, so from the first frame onward NGX was reading whatever later occupied that stack memory. The parameters also persist in the shared parameter block, so the SR path -- which never sets these matrices, they are DLSS-D-only (nvsdk_ngx_defs_dlssd.h) -- inherited the same dangling pointers. Result, every frame: [EvaluateFeature:920] Warning: WorldToScreenMatrix not invertible! Store them on NGXDLSSContext so they outlive the call and stay valid for as long as NGX may read them. Reading garbage camera matrices means reprojection has no valid transform, so this is also a candidate for the motion-vector ghosting/smearing artifacts and for RR appearing not to denoise. Whether it also relates to the VK_ERROR_DEVICE_ LOST seen on exit is unproven. Also renames the local Projection from view_proj to world_to_view: it is the view transform, not a view-projection product, and the old name read like a bug. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
650dcc4f603375bfa83971a033d15659a7d3c8d2
by plankatron <fleeky@gmail.com> · 2026-07-29T17:56:08.000Z

Changed files (1) +21 -14

servers/rendering/renderer_rd/effects/dlss.cpp +21 -14
……@@ -606,6 +606,14 @@ public:
606606 NVSDK_NGX_Handle *dlss_rr_handle = nullptr;
607607 NVSDK_NGX_Handle *dlss_sr_handle = nullptr;
608608 bool feature_created = false;
609 // DLSS-RR camera matrices. These MUST outlive the evaluate() call: the NGX
610 // helper hands them to NVSDK_NGX_Parameter_SetVoidPointer, which stores the
611 // POINTER rather than copying, and NGX dereferences it during evaluation --
612 // including on later frames and on the SR path, which never sets them. Held
613 // as stack locals they dangled the moment evaluate() returned, which is what
614 // produced "WorldToScreenMatrix not invertible!" every frame.
615 float world_to_view_matrix[16] = {};
616 float view_to_clip_matrix[16] = {};
609617 NVSDK_NGX_PerfQuality_Value perf_quality = NVSDK_NGX_PerfQuality_Value_Balanced;
610618 uint32_t render_width = 0;
611619 uint32_t render_height = 0;
……@@ -1034,25 +1042,24 @@ void DLSSEffect::_upscale_internal(RDD::CommandBufferID cmdid, const DLSSContext
10341042 eval.pInSpecularHitDistance = &hit_dist_res;
10351043 }
10361044
1037 // View/projection matrices for DLSS-RR
1045 // View/projection matrices for DLSS-RR. Stored on the context, NOT on the
1046 // stack -- see the declaration: NGX keeps the pointer and reads it later.
10381047 Transform3D view_matrix = p_params.cam_transform.affine_inverse();
1039 Projection view_proj(view_matrix);
1040 float world_to_view[16];
1041 float view_to_clip[16];
1048 Projection world_to_view(view_matrix);
10421049 for (int i = 0; i < 4; i++) {
1043 world_to_view[i * 4 + 0] = view_proj.columns[0][i];
1044 world_to_view[i * 4 + 1] = view_proj.columns[1][i];
1045 world_to_view[i * 4 + 2] = view_proj.columns[2][i];
1046 world_to_view[i * 4 + 3] = view_proj.columns[3][i];
1050 ctx->world_to_view_matrix[i * 4 + 0] = world_to_view.columns[0][i];
1051 ctx->world_to_view_matrix[i * 4 + 1] = world_to_view.columns[1][i];
1052 ctx->world_to_view_matrix[i * 4 + 2] = world_to_view.columns[2][i];
1053 ctx->world_to_view_matrix[i * 4 + 3] = world_to_view.columns[3][i];
10471054 }
10481055 for (int i = 0; i < 4; i++) {
1049 view_to_clip[i * 4 + 0] = p_params.cam_projection.columns[0][i];
1050 view_to_clip[i * 4 + 1] = p_params.cam_projection.columns[1][i];
1051 view_to_clip[i * 4 + 2] = p_params.cam_projection.columns[2][i];
1052 view_to_clip[i * 4 + 3] = p_params.cam_projection.columns[3][i];
1056 ctx->view_to_clip_matrix[i * 4 + 0] = p_params.cam_projection.columns[0][i];
1057 ctx->view_to_clip_matrix[i * 4 + 1] = p_params.cam_projection.columns[1][i];
1058 ctx->view_to_clip_matrix[i * 4 + 2] = p_params.cam_projection.columns[2][i];
1059 ctx->view_to_clip_matrix[i * 4 + 3] = p_params.cam_projection.columns[3][i];
10531060 }
1054 eval.pInWorldToViewMatrix = world_to_view;
1055 eval.pInViewToClipMatrix = view_to_clip;
1061 eval.pInWorldToViewMatrix = ctx->world_to_view_matrix;
1062 eval.pInViewToClipMatrix = ctx->view_to_clip_matrix;
10561063
10571064 NVSDK_NGX_Result result = NGX_VULKAN_EVALUATE_DLSSD_EXT(vk_cmd, ctx->dlss_rr_handle, g_ngx_params, &eval);
10581065