| … | … | @@ -33,6 +33,7 @@ |
| 33 | 33 | |
| 34 | 34 | #include "core/config/engine.h" |
| 35 | 35 | #include "core/config/project_settings.h" |
| 36 | #include "core/error/error_backtrace.h" |
| 36 | 37 | #include "core/io/dir_access.h" |
| 37 | 38 | #include "core/io/file_access.h" |
| 38 | 39 | #include "core/object/class_db.h" |
| … | … | @@ -358,7 +359,16 @@ RID RenderingDevice::blas_create(Span<AccelerationStructureGeometry> p_geometrie |
| 358 | 359 | |
| 359 | 360 | uint32_t index_stride = (index_buffer->format == INDEX_BUFFER_FORMAT_UINT32 ? sizeof(uint32_t) : sizeof(uint16_t)); |
| 360 | 361 | 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."); |
| 362 | 372 | |
| 363 | 373 | t_out.index_buffer = index_buffer->driver_id; |
| 364 | 374 | t_out.index_offset = t_in.index_offset; |
| … | … | @@ -7848,10 +7858,16 @@ void RenderingDevice::_free_internal(RID p_id) { |
| 7848 | 7858 | frames[frame].buffers_to_dispose_of.push_back(*hit_sbt); |
| 7849 | 7859 | hit_sbt_owner.free(p_id); |
| 7850 | 7860 | } 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 | } |
| 7851 | 7867 | #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); |
| 7853 | 7869 | #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); |
| 7855 | 7871 | #endif |
| 7856 | 7872 | } |
| 7857 | 7873 | |