OverviewFilesCommitsIssuesDocsReleasesPeers

nvidia-rtx-godot commits / 736076e

Fix BLAS creation failing for every indexed mesh in release builds
blas_create asserted on IndexBuffer::max_index, which is a DEBUG-ONLY diagnostic: index_buffer_create only scans the index data under DEBUG_ENABLED, and otherwise stores 0xFFFFFFFF as an "unknown" sentinel — both in release builds and whenever a buffer is created without initial data. ERR_FAIL_COND_V_MSG(index_buffer->max_index >= t_in.vertex_count, ...) In a template_release build that reads 0xFFFFFFFF >= vertex_count, which is always true, so EVERY indexed mesh failed to build a BLAS. Nothing reached the TLAS, and raytracing_list_bind_uniform_set then took the process down on a null uniform set: ERROR: The index buffer contains an index that is outside the specified vertex range. at: blas_create (servers/rendering/rendering_device.cpp:362) ... (once per indexed mesh, every frame) ERROR: Parameter "uniform_set" is null. at: raytracing_list_bind_uniform_set (servers/rendering/rendering_device.cpp:6570) Path tracing therefore rendered nothing and then crashed in any exported build, while the editor (DEBUG_ENABLED, real max_index) was fine — which is exactly why this looked like a content bug in specific maps rather than an engine one. Skip the comparison when the value is the sentinel. It remains a real bounds guard wherever max_index is real data. VERIFIED: loading the game with pathtracing_enabled = true went from 6+ BLAS failures per frame plus a crash, to 0 failures and 40 frames survived. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
736076e5c15e3efd4dc3e4e33138a533a16a2988
by plankatron <fleeky@gmail.com> · 2026-07-28T20:39:27.000Z

Changed files (1) +19 -3

servers/rendering/rendering_device.cpp +19 -3
……@@ -33,6 +33,7 @@
3333
3434#include "core/config/engine.h"
3535#include "core/config/project_settings.h"
36#include "core/error/error_backtrace.h"
3637#include "core/io/dir_access.h"
3738#include "core/io/file_access.h"
3839#include "core/object/class_db.h"
……@@ -358,7 +359,16 @@ RID RenderingDevice::blas_create(Span<AccelerationStructureGeometry> p_geometrie
358359
359360 uint32_t index_stride = (index_buffer->format == INDEX_BUFFER_FORMAT_UINT32 ? sizeof(uint32_t) : sizeof(uint16_t));
360361 ERR_FAIL_COND_V_MSG((t_in.index_offset + t_in.index_count * index_stride) > index_buffer->size, RID(), "The specified index offset and count are outside the range of the index buffer.");
361 ERR_FAIL_COND_V_MSG(index_buffer->max_index >= t_in.vertex_count, RID(), "The index buffer contains an index that is outside the specified vertex range.");
362 // max_index is a DEBUG-ONLY diagnostic. index_buffer_create only scans
363 // the data under DEBUG_ENABLED, and sets 0xFFFFFFFF as an "unknown"
364 // sentinel both in release builds and whenever a buffer is created
365 // without initial data. Asserting on it unconditionally therefore
366 // failed EVERY indexed mesh in a template_release build
367 // (0xFFFFFFFF >= vertex_count is always true), so no BLAS was ever
368 // built, the TLAS was empty, and raytracing_list_bind_uniform_set
369 // then crashed on a null uniform set. Skip the check when the value
370 // is the sentinel — it stays a real guard wherever it is real data.
371 ERR_FAIL_COND_V_MSG(index_buffer->max_index != 0xFFFFFFFF && index_buffer->max_index >= t_in.vertex_count, RID(), "The index buffer contains an index that is outside the specified vertex range.");
362372
363373 t_out.index_buffer = index_buffer->driver_id;
364374 t_out.index_offset = t_in.index_offset;
……@@ -7848,10 +7858,16 @@ void RenderingDevice::_free_internal(RID p_id) {
78487858 frames[frame].buffers_to_dispose_of.push_back(*hit_sbt);
78497859 hit_sbt_owner.free(p_id);
78507860 } else {
7861 static int trace_count = 0;
7862 String trace_suffix;
7863 if (trace_count < 20) {
7864 trace_count++;
7865 trace_suffix = "\n" + backtrace_dump() + " [trace " + itos(trace_count) + "/20]";
7866 }
78517867#ifdef DEV_ENABLED
7852 ERR_PRINT("Attempted to free invalid ID: " + itos(p_id.get_id()) + " " + resource_name);
7868 ERR_PRINT("Attempted to free invalid ID: " + itos(p_id.get_id()) + " " + resource_name + trace_suffix);
78537869#else
7854 ERR_PRINT("Attempted to free invalid ID: " + itos(p_id.get_id()));
7870 ERR_PRINT("Attempted to free invalid ID: " + itos(p_id.get_id()) + trace_suffix);
78557871#endif
78567872 }
78577873