🔍 Module Scanned
modules/engine-ui/src/ (automated audit scan)
📝 Summary
The setTextureUniforms function is never called after shadow system initialization, causing shadow_map_handles in the render context to remain zero-initialized. When DebugShadowOverlay calls ui.drawDepthTexture(handle, tex_rect) using handles from getShadowMapHandle(), the handles are invalid (0), causing "Texture handle X not found in textures map" errors during debug shadow overlay rendering.
📍 Location
- File:
modules/engine-graphics/src/vulkan/rhi_state_control.zig:13
- Function/Scope:
setTextureUniforms and shadow_runtime.shadow_map_handles
🔴 Severity: High
- High: Memory leaks, race conditions, incorrect rendering, broken features
💥 Impact
When the debug shadow overlay is enabled (via debug_shadow debug feature), calling drawDepthTexture will pass invalid texture handle 0 to the Vulkan debug shadow pipeline. This results in:
- Error logging: "drawDepthTexture: Texture handle 0 not found in textures map!"
- The debug shadow overlay renders nothing for cascade textures
- Potential descriptor binding issues with VkImageView being null
The root cause is that setTextureUniforms (which should propagate shadow_map_handles from shadow system to render state) is never invoked after the shadow system initializes these handles at startup. The handles are registered correctly during rhi_resource_setup.zig:116 but the copy into shadow_runtime.shadow_map_handles only happens through setTextureUniforms (see rhi_state_control.zig:15).
🔎 Evidence
Issue in rhi_state_control.zig:13-15:
pub fn setTextureUniforms(ctx: anytype, texture_enabled: bool, shadow_map_handles: [rhi.SHADOW_CASCADE_COUNT]rhi.TextureHandle) void {
ctx.options.textures_enabled = texture_enabled;
ctx.shadow_runtime.shadow_map_handles = shadow_map_handles; // <-- This is the only place that updates shadow_map_handles
Shadow map handles initialized to zero in rhi_context_types.zig:99:
shadow_map_handles: [rhi.SHADOW_CASCADE_COUNT]rhi.TextureHandle = .{0} ** rhi.SHADOW_CASCADE_COUNT,
Handles are registered in rhi_resource_setup.zig:116 but never copied to render context:
ctx.shadow_runtime.shadow_map_handles[si] = try ctx.resources.registerExternalTexture(shadow_res, shadow_res, .depth, layer_view, ctx.shadow_system.shadow_sampler_regular);
getShadowMapHandle in rhi_shadow_bridge.zig:22-24 returns the zero-initialized handles:
pub fn getShadowMapHandle(ctx: anytype, cascade_index: u32) rhi.TextureHandle {
if (cascade_index >= rhi.SHADOW_CASCADE_COUNT) return 0;
return ctx.shadow_runtime.shadow_map_handles[cascade_index]; // <-- Returns 0!
}
Debug shadow overlay uses these handles without validation in debug_shadow_overlay.zig:31:
const handle = shadow.getShadowMapHandle(@intCast(i));
if (handle == 0) continue; // This check is present, so nothing renders
🛠️ Proposed Fix
Add a call to setTextureUniforms during RHI initialization or after shadow system setup to propagate the initialized shadow map handles from ctx.shadow_runtime.shadow_map_handles (set during registerExternalTexture) to the render state copy.
In rhi_resource_setup.zig, after line 116 where handles are set:
ctx.shadow_runtime.shadow_map_handles[si] = try ctx.resources.registerExternalTexture(...);
Add after the loop (around line 128):
// Propagate shadow map handles to render state
state_control.setTextureUniforms(ctx, true, ctx.shadow_runtime.shadow_map_handles);
Alternatively, modify getShadowMapHandle to directly query ctx.shadow_system.shadow_image_views instead of going through the stale shadow_runtime.shadow_map_handles.
✅ Acceptance Criteria
📚 References
rhi_state_control.zig:13-19 - setTextureUniforms function that updates shadow_map_handles
rhi_shadow_bridge.zig:22-24 - getShadowMapHandle implementation
rhi_context_types.zig:99 - shadow_map_handles field initialization
rhi_resource_setup.zig:105-116 - where shadow map handles are initially registered
🔍 Module Scanned
modules/engine-ui/src/(automated audit scan)📝 Summary
The
setTextureUniformsfunction is never called after shadow system initialization, causingshadow_map_handlesin the render context to remain zero-initialized. WhenDebugShadowOverlaycallsui.drawDepthTexture(handle, tex_rect)using handles fromgetShadowMapHandle(), the handles are invalid (0), causing "Texture handle X not found in textures map" errors during debug shadow overlay rendering.📍 Location
modules/engine-graphics/src/vulkan/rhi_state_control.zig:13setTextureUniformsandshadow_runtime.shadow_map_handles🔴 Severity: High
💥 Impact
When the debug shadow overlay is enabled (via
debug_shadowdebug feature), callingdrawDepthTexturewill pass invalid texture handle 0 to the Vulkan debug shadow pipeline. This results in:The root cause is that
setTextureUniforms(which should propagateshadow_map_handlesfrom shadow system to render state) is never invoked after the shadow system initializes these handles at startup. The handles are registered correctly duringrhi_resource_setup.zig:116but the copy intoshadow_runtime.shadow_map_handlesonly happens throughsetTextureUniforms(seerhi_state_control.zig:15).🔎 Evidence
Issue in
rhi_state_control.zig:13-15:Shadow map handles initialized to zero in
rhi_context_types.zig:99:Handles are registered in
rhi_resource_setup.zig:116but never copied to render context:getShadowMapHandleinrhi_shadow_bridge.zig:22-24returns the zero-initialized handles:Debug shadow overlay uses these handles without validation in
debug_shadow_overlay.zig:31:🛠️ Proposed Fix
Add a call to
setTextureUniformsduring RHI initialization or after shadow system setup to propagate the initialized shadow map handles fromctx.shadow_runtime.shadow_map_handles(set duringregisterExternalTexture) to the render state copy.In
rhi_resource_setup.zig, after line 116 where handles are set:Add after the loop (around line 128):
Alternatively, modify
getShadowMapHandleto directly queryctx.shadow_system.shadow_image_viewsinstead of going through the staleshadow_runtime.shadow_map_handles.✅ Acceptance Criteria
drawDepthTexturesuccessfully renders shadow cascade textures in debug overlay whendebug_shadowsbuild option is enabledzig build testcontinue to pass📚 References
rhi_state_control.zig:13-19- setTextureUniforms function that updates shadow_map_handlesrhi_shadow_bridge.zig:22-24- getShadowMapHandle implementationrhi_context_types.zig:99- shadow_map_handles field initializationrhi_resource_setup.zig:105-116- where shadow map handles are initially registered