From eeff9bd507c484dffb4db8af7bc7dc15b6c22629 Mon Sep 17 00:00:00 2001 From: MichaelFisher1997 Date: Sat, 28 Mar 2026 02:18:33 +0000 Subject: [PATCH] fix: improve error context with unified logging and error return traces (#276) Add errWithTrace() to log.zig for automatic stack trace dumps at error sites. Migrate all 139 std.log.* calls to the custom logger across 27 files for consistent formatting. Add errWithTrace to 30+ critical catch sites (mesh build, GPU recovery, resource recreation, shader loading). Add contextual init logging to App, World, and RenderSystem startup. Fix missing errdefer in World.initGen() that leaked the streamer on renderer init failure. --- src/engine/core/log.zig | 18 ++++++++- src/engine/graphics/lpv_system.zig | 11 +++--- src/engine/graphics/render_graph.zig | 4 +- src/engine/graphics/render_system.zig | 6 +++ src/engine/graphics/rhi_vulkan.zig | 7 ++-- .../graphics/vulkan/descriptor_manager.zig | 5 ++- .../graphics/vulkan/render_pass_manager.zig | 3 +- .../graphics/vulkan/resource_manager.zig | 11 +++--- .../graphics/vulkan/resource_texture_ops.zig | 3 +- .../graphics/vulkan/rhi_context_factory.zig | 3 +- .../graphics/vulkan/rhi_draw_submission.zig | 9 +++-- .../vulkan/rhi_frame_orchestration.zig | 39 ++++++++++--------- .../graphics/vulkan/rhi_init_deinit.zig | 15 +++---- .../vulkan/rhi_pass_orchestration.zig | 23 +++++------ .../graphics/vulkan/rhi_resource_setup.zig | 3 +- .../graphics/vulkan/rhi_state_control.zig | 13 ++++--- .../graphics/vulkan/rhi_ui_submission.zig | 7 ++-- .../graphics/vulkan/swapchain_presenter.zig | 11 +++--- src/engine/graphics/vulkan_device.zig | 37 +++++++++--------- src/engine/graphics/vulkan_swapchain.zig | 3 +- src/game/app.zig | 8 +++- src/game/session.zig | 2 +- src/game/settings/json_presets.zig | 29 +++++++------- src/game/settings/persistence.zig | 27 ++++++------- src/robust_demo.zig | 5 ++- src/world/chunk_allocator.zig | 11 +++--- src/world/chunk_mesh.zig | 7 ++-- src/world/lod_manager.zig | 2 +- src/world/lod_renderer.zig | 2 +- src/world/lod_upload_queue.zig | 5 ++- src/world/world.zig | 12 ++++-- src/world/world_renderer.zig | 3 +- src/world/world_streamer.zig | 2 +- src/world/worldgen/overworld_generator.zig | 2 +- src/world/worldgen/registry.zig | 3 +- 35 files changed, 203 insertions(+), 148 deletions(-) diff --git a/src/engine/core/log.zig b/src/engine/core/log.zig index 7e351374..c4bbddd5 100644 --- a/src/engine/core/log.zig +++ b/src/engine/core/log.zig @@ -1,4 +1,12 @@ -//! Engine-wide logging system with severity levels. +//! Engine-wide logging system with severity levels and error return trace +//! support. All logging should go through this module rather than std.log +//! directly to ensure consistent formatting. +//! +//! Usage: +//! const log = @import("../engine/core/log.zig"); +//! log.log.info("initialized subsystem", .{}); +//! log.log.err("failed: {}", .{err}); +//! log.log.errWithTrace("init failed: {}", .{err}); // includes stack trace const std = @import("std"); const builtin = @import("builtin"); @@ -43,6 +51,13 @@ pub const Logger = struct { self.log(.fatal, fmt, args); } + pub fn errWithTrace(self: *const Logger, comptime fmt: []const u8, args: anytype) void { + self.log(.err, fmt, args); + if (@errorReturnTrace()) |ret_trace| { + std.debug.dumpStackTrace(ret_trace); + } + } + fn log(self: *const Logger, level: LogLevel, comptime fmt: []const u8, args: anytype) void { if (@intFromEnum(level) < @intFromEnum(self.min_level)) return; @@ -59,5 +74,4 @@ pub const Logger = struct { } }; -/// Global logger instance pub var log = Logger.init(if (builtin.is_test) .err else .debug); diff --git a/src/engine/graphics/lpv_system.zig b/src/engine/graphics/lpv_system.zig index 83538c76..5c4994c0 100644 --- a/src/engine/graphics/lpv_system.zig +++ b/src/engine/graphics/lpv_system.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("../../c.zig").c; const rhi_pkg = @import("rhi.zig"); +const log = @import("../core/log.zig"); const Vec3 = @import("../math/vec3.zig").Vec3; const World = @import("../../world/world.zig").World; const CHUNK_SIZE_X = @import("../../world/chunk.zig").CHUNK_SIZE_X; @@ -418,7 +419,7 @@ pub const LPVSystem = struct { // Ensure CPU buffer is allocated if (self.occlusion_grid.len != total_cells) { const new_grid = self.allocator.alloc(u32, total_cells) catch |err| { - std.log.err("LPV occlusion grid allocation failed ({} cells): {}", .{ total_cells, err }); + log.log.err("LPV occlusion grid allocation failed ({} cells): {}", .{ total_cells, err }); return false; }; if (self.occlusion_grid.len > 0) self.allocator.free(self.occlusion_grid); @@ -494,7 +495,7 @@ pub const LPVSystem = struct { return true; } - std.log.err("LPV occlusion upload skipped: buffer is not mapped", .{}); + log.log.err("LPV occlusion upload skipped: buffer is not mapped", .{}); return false; } @@ -797,7 +798,7 @@ pub const LPVSystem = struct { fn destroyLightBuffer(self: *LPVSystem) void { if (self.light_buffer.buffer != null) { if (self.light_buffer.memory == null) { - std.log.warn("LPV light buffer has VkBuffer but null VkDeviceMemory during teardown", .{}); + log.log.warn("LPV light buffer has VkBuffer but null VkDeviceMemory during teardown", .{}); } if (self.light_buffer.mapped_ptr != null) { c.vkUnmapMemory(self.vk_ctx.vulkan_device.vk_device, self.light_buffer.memory); @@ -1119,8 +1120,8 @@ fn createShaderModule(vk: c.VkDevice, path: []const u8, allocator: std.mem.Alloc fn ensureShaderFileExists(path: []const u8) !void { std.fs.cwd().access(path, .{}) catch |err| { - std.log.err("LPV shader artifact missing: {s} ({})", .{ path, err }); - std.log.err("Run `nix develop --command zig build` to regenerate Vulkan SPIR-V shaders.", .{}); + log.log.errWithTrace("LPV shader artifact missing: {s} ({})", .{ path, err }); + log.log.err("Run `nix develop --command zig build` to regenerate Vulkan SPIR-V shaders.", .{}); return err; }; } diff --git a/src/engine/graphics/render_graph.zig b/src/engine/graphics/render_graph.zig index dd8bb7aa..066502fd 100644 --- a/src/engine/graphics/render_graph.zig +++ b/src/engine/graphics/render_graph.zig @@ -305,7 +305,7 @@ pub const SkyPass = struct { err != error.SkyPipelineLayoutNotReady and err != error.CommandBufferNotReady) { - log.log.err("SkyPass: rendering failed: {}", .{err}); + log.log.errWithTrace("SkyPass: rendering failed: {}", .{err}); } }; } @@ -359,7 +359,7 @@ pub const CloudPass = struct { err != error.CloudPipelineLayoutNotReady and err != error.CommandBufferNotReady) { - log.log.err("CloudPass: rendering failed: {}", .{err}); + log.log.errWithTrace("CloudPass: rendering failed: {}", .{err}); } }; } diff --git a/src/engine/graphics/render_system.zig b/src/engine/graphics/render_system.zig index 3676ed9c..b0822984 100644 --- a/src/engine/graphics/render_system.zig +++ b/src/engine/graphics/render_system.zig @@ -101,8 +101,10 @@ pub const RenderSystem = struct { const rhi = try rhi_vulkan.createRHI(allocator, window, null, settings.getShadowResolution(), settings.msaa_samples, settings.anisotropic_filtering); errdefer rhi.deinit(); + log.log.info("RenderSystem.init: initializing RHI device", .{}); try rhi.init(allocator, null); + log.log.info("RenderSystem.init: scanning resource packs", .{}); var resource_pack_manager = ResourcePackManager.init(allocator); errdefer resource_pack_manager.deinit(); try resource_pack_manager.scanPacks(); @@ -112,6 +114,7 @@ pub const RenderSystem = struct { try resource_pack_manager.setActivePack("default"); } + log.log.info("RenderSystem.init: creating texture atlas (max_resolution={})", .{settings.max_texture_resolution}); const atlas = try TextureAtlas.init(allocator, rhi.resourceManager(), &resource_pack_manager, settings.max_texture_resolution); var atlas_mut = atlas; errdefer atlas_mut.deinit(); @@ -134,6 +137,7 @@ pub const RenderSystem = struct { } errdefer if (env_map) |*t| t.deinit(); + log.log.info("RenderSystem.init: initializing AtmosphereSystem", .{}); const atmosphere_system = try AtmosphereSystem.init(allocator, rhi.resourceManager()); errdefer atmosphere_system.deinit(); @@ -177,8 +181,10 @@ pub const RenderSystem = struct { .disable_clouds = disable_clouds, }; + log.log.info("RenderSystem.init: initializing MaterialSystem", .{}); self.material_system = try MaterialSystem.init(allocator, &self.atlas); errdefer self.material_system.deinit(); + log.log.info("RenderSystem.init: initializing LPVSystem (grid_size={}, cell_size={})", .{ settings.lpv_grid_size, settings.lpv_cell_size }); self.lpv_system = try LPVSystem.init( allocator, rhi, diff --git a/src/engine/graphics/rhi_vulkan.zig b/src/engine/graphics/rhi_vulkan.zig index c1ff7390..a64c9fad 100644 --- a/src/engine/graphics/rhi_vulkan.zig +++ b/src/engine/graphics/rhi_vulkan.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("../../c.zig").c; const rhi = @import("rhi.zig"); +const log = @import("../core/log.zig"); const RenderDevice = @import("render_device.zig").RenderDevice; const Mat4 = @import("../math/mat4.zig").Mat4; const Vec3 = @import("../math/vec3.zig").Vec3; @@ -67,13 +68,13 @@ fn beginFrame(ctx_ptr: *anyopaque) void { if (ctx.frames.frame_in_progress) return; if (ctx.runtime.framebuffer_resized) { - std.log.info("beginFrame: triggering recreateSwapchainInternal (resize)", .{}); + log.log.info("beginFrame: triggering recreateSwapchainInternal (resize)", .{}); frame_orchestration.recreateSwapchainInternal(ctx); } if (ctx.resources.transfer_ready) { ctx.resources.flushTransfer() catch |err| { - std.log.err("Failed to flush inter-frame transfers: {}", .{err}); + log.log.errWithTrace("Failed to flush inter-frame transfers: {}", .{err}); }; } @@ -82,7 +83,7 @@ fn beginFrame(ctx_ptr: *anyopaque) void { if (err == error.GpuLost) { ctx.runtime.gpu_fault_detected = true; } else { - std.log.err("beginFrame failed: {}", .{err}); + log.log.errWithTrace("beginFrame failed: {}", .{err}); } return; }; diff --git a/src/engine/graphics/vulkan/descriptor_manager.zig b/src/engine/graphics/vulkan/descriptor_manager.zig index 06c04bc2..756578cc 100644 --- a/src/engine/graphics/vulkan/descriptor_manager.zig +++ b/src/engine/graphics/vulkan/descriptor_manager.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("../../../c.zig").c; const rhi = @import("../rhi.zig"); +const log = @import("../../core/log.zig"); const rhi_types = @import("../rhi_types.zig"); const VulkanDevice = @import("../vulkan_device.zig").VulkanDevice; const ResourceManager = @import("resource_manager.zig").ResourceManager; @@ -278,7 +279,7 @@ pub const DescriptorManager = struct { pub fn updateGlobalUniforms(self: *DescriptorManager, frame_index: usize, data: *const anyopaque) !void { const dest = self.global_ubos_mapped[frame_index] orelse { - std.log.err("Failed to update global uniforms: memory not mapped", .{}); + log.log.err("Failed to update global uniforms: memory not mapped", .{}); return error.UnmappedBuffer; }; const src = @as([*]const u8, @ptrCast(data)); @@ -287,7 +288,7 @@ pub const DescriptorManager = struct { pub fn updateShadowUniforms(self: *DescriptorManager, frame_index: usize, data: *const anyopaque) !void { const dest = self.shadow_ubos_mapped[frame_index] orelse { - std.log.err("Failed to update shadow uniforms: memory not mapped", .{}); + log.log.err("Failed to update shadow uniforms: memory not mapped", .{}); return error.UnmappedBuffer; }; const src = @as([*]const u8, @ptrCast(data)); diff --git a/src/engine/graphics/vulkan/render_pass_manager.zig b/src/engine/graphics/vulkan/render_pass_manager.zig index def0911f..e712639e 100644 --- a/src/engine/graphics/vulkan/render_pass_manager.zig +++ b/src/engine/graphics/vulkan/render_pass_manager.zig @@ -9,6 +9,7 @@ const std = @import("std"); const c = @import("../../../c.zig").c; const rhi = @import("../rhi.zig"); +const log = @import("../../core/log.zig"); const VulkanDevice = @import("../vulkan_device.zig").VulkanDevice; const Utils = @import("utils.zig"); @@ -196,7 +197,7 @@ pub const RenderPassManager = struct { render_pass_info.pDependencies = &dependencies[0]; try Utils.checkVk(c.vkCreateRenderPass(vk_device, &render_pass_info, null, &self.hdr_render_pass)); - std.log.info("Created HDR MSAA {}x render pass", .{msaa_samples}); + log.log.info("Created HDR MSAA {}x render pass", .{msaa_samples}); } else { // Non-MSAA render pass: 2 attachments (color, depth) var color_attachment = std.mem.zeroes(c.VkAttachmentDescription); diff --git a/src/engine/graphics/vulkan/resource_manager.zig b/src/engine/graphics/vulkan/resource_manager.zig index 242ba8df..018bd441 100644 --- a/src/engine/graphics/vulkan/resource_manager.zig +++ b/src/engine/graphics/vulkan/resource_manager.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("../../../c.zig").c; const rhi = @import("../rhi.zig"); +const log = @import("../../core/log.zig"); const VulkanDevice = @import("../vulkan_device.zig").VulkanDevice; const Utils = @import("utils.zig"); const resource_texture_ops = @import("resource_texture_ops.zig"); @@ -150,7 +151,7 @@ pub const ResourceManager = struct { fence_info.sType = c.VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fence_info.flags = 0; // Not signaled initially Utils.checkVk(c.vkCreateFence(vulkan_device.vk_device, &fence_info, null, &self.transfer_fence)) catch |err| { - std.log.err("Failed to create transfer fence: {}", .{err}); + log.log.err("Failed to create transfer fence: {}", .{err}); // Cleanup command pool and buffers before returning to avoid leaks if (self.transfer_command_pool != null) { c.vkDestroyCommandPool(vulkan_device.vk_device, self.transfer_command_pool, null); @@ -317,7 +318,7 @@ pub const ResourceManager = struct { }; _ = self.buffers.remove(handle); self.buffer_deletion_queue[self.current_frame_index].append(self.allocator, .{ .buffer = buf.buffer, .memory = buf.memory }) catch |err| { - std.log.err("Failed to queue buffer deletion: {}", .{err}); + log.log.err("Failed to queue buffer deletion: {}", .{err}); }; } @@ -330,7 +331,7 @@ pub const ResourceManager = struct { const staging = &self.staging_buffers[self.current_frame_index]; const staging_offset = staging.allocate(data.len) orelse { - std.log.err("Staging buffer overflow in updateBuffer! Data dropped.", .{}); + log.log.err("Staging buffer overflow in updateBuffer! Data dropped.", .{}); return error.OutOfMemory; }; @@ -389,7 +390,7 @@ pub const ResourceManager = struct { .sampler = tex.sampler, .is_owned = tex.is_owned, }) catch |err| { - std.log.err("Failed to queue texture deletion: {}", .{err}); + log.log.err("Failed to queue texture deletion: {}", .{err}); }; } @@ -481,7 +482,7 @@ pub const ResourceManager = struct { c.vkCmdPipelineBarrier(transfer_cb, c.VK_PIPELINE_STAGE_TRANSFER_BIT, c.VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, null, 0, null, 1, &barrier); } else { // Buffer full, drop update for now (or implement fallback) - std.log.err("Staging buffer full during updateTexture! Update dropped.", .{}); + log.log.err("Staging buffer full during updateTexture! Update dropped.", .{}); return error.OutOfMemory; } } diff --git a/src/engine/graphics/vulkan/resource_texture_ops.zig b/src/engine/graphics/vulkan/resource_texture_ops.zig index 04d3cf8a..7574174d 100644 --- a/src/engine/graphics/vulkan/resource_texture_ops.zig +++ b/src/engine/graphics/vulkan/resource_texture_ops.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("../../../c.zig").c; const rhi = @import("../rhi.zig"); +const log = @import("../../core/log.zig"); const Utils = @import("utils.zig"); pub fn createTexture(self: anytype, width: u32, height: u32, format: rhi.TextureFormat, config: rhi.TextureConfig, data_opt: ?[]const u8) rhi.RhiError!rhi.TextureHandle { @@ -229,7 +230,7 @@ pub fn createTexture(self: anytype, width: u32, height: u32, format: rhi.Texture pub fn createTexture3D(self: anytype, width: u32, height: u32, depth: u32, format: rhi.TextureFormat, config: rhi.TextureConfig, data_opt: ?[]const u8) rhi.RhiError!rhi.TextureHandle { var texture_config = config; if (texture_config.generate_mipmaps) { - std.log.warn("3D texture mipmaps are not supported yet; disabling generate_mipmaps", .{}); + log.log.warn("3D texture mipmaps are not supported yet; disabling generate_mipmaps", .{}); texture_config.generate_mipmaps = false; } diff --git a/src/engine/graphics/vulkan/rhi_context_factory.zig b/src/engine/graphics/vulkan/rhi_context_factory.zig index ca338514..f1638b11 100644 --- a/src/engine/graphics/vulkan/rhi_context_factory.zig +++ b/src/engine/graphics/vulkan/rhi_context_factory.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("../../../c.zig").c; const rhi = @import("../rhi.zig"); +const log = @import("../../core/log.zig"); const RenderDevice = @import("../render_device.zig").RenderDevice; const Mat4 = @import("../../math/mat4.zig").Mat4; const build_options = @import("build_options"); @@ -100,7 +101,7 @@ pub fn createRHI( else false; if (ctx.options.safe_mode) { - std.log.warn("ZIGCRAFT_SAFE_MODE enabled: throttling uploads and forcing GPU idle each frame", .{}); + log.log.warn("ZIGCRAFT_SAFE_MODE enabled: throttling uploads and forcing GPU idle each frame", .{}); } ctx.frames.command_pool = null; diff --git a/src/engine/graphics/vulkan/rhi_draw_submission.zig b/src/engine/graphics/vulkan/rhi_draw_submission.zig index f7f4165d..922a0969 100644 --- a/src/engine/graphics/vulkan/rhi_draw_submission.zig +++ b/src/engine/graphics/vulkan/rhi_draw_submission.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("../../../c.zig").c; const rhi = @import("../rhi.zig"); +const log = @import("../../core/log.zig"); const Mat4 = @import("../../math/mat4.zig").Mat4; const pass_orchestration = @import("rhi_pass_orchestration.zig"); @@ -88,7 +89,7 @@ pub fn drawIndirect(ctx: anytype, handle: rhi.BufferHandle, command_buffer: rhi. else ctx.pipeline_manager.terrain_pipeline; if (selected_pipeline == null) { - std.log.warn("drawIndirect: main pipeline (selected_pipeline) is null - cannot draw terrain", .{}); + log.log.warn("drawIndirect: main pipeline (selected_pipeline) is null - cannot draw terrain", .{}); return; } c.vkCmdBindPipeline(cb, c.VK_PIPELINE_BIND_POINT_GRAPHICS, selected_pipeline); @@ -139,7 +140,7 @@ pub fn drawIndirect(ctx: anytype, handle: rhi.BufferHandle, command_buffer: rhi. return; } } else { - std.log.warn("drawIndirect: command buffer range out of bounds (offset={}, size={}, buffer={})", .{ offset, map_size, cmd_size }); + log.log.warn("drawIndirect: command buffer range out of bounds (offset={}, size={}, buffer={})", .{ offset, map_size, cmd_size }); } } @@ -152,7 +153,7 @@ pub fn drawIndirect(ctx: anytype, handle: rhi.BufferHandle, command_buffer: rhi. const draw_offset = offset + @as(usize, draw_index) * stride_bytes; c.vkCmdDrawIndirect(cb, cmd.buffer, @intCast(draw_offset), 1, stride); } - std.log.info("drawIndirect: MDI unsupported - drew {} draws via single-draw fallback", .{draw_count}); + log.log.info("drawIndirect: MDI unsupported - drew {} draws via single-draw fallback", .{draw_count}); } } } @@ -245,7 +246,7 @@ pub fn drawOffset(ctx: anytype, handle: rhi.BufferHandle, count: u32, mode: rhi. const vertex_stride: u64 = @sizeOf(rhi.Vertex); const required_bytes: u64 = @as(u64, offset) + @as(u64, count) * vertex_stride; if (required_bytes > vbo.size) { - std.log.err("drawOffset: vertex buffer overrun (handle={}, offset={}, count={}, size={})", .{ handle, offset, count, vbo.size }); + log.log.err("drawOffset: vertex buffer overrun (handle={}, offset={}, count={}, size={})", .{ handle, offset, count, vbo.size }); return; } diff --git a/src/engine/graphics/vulkan/rhi_frame_orchestration.zig b/src/engine/graphics/vulkan/rhi_frame_orchestration.zig index 75399db3..7a5c356a 100644 --- a/src/engine/graphics/vulkan/rhi_frame_orchestration.zig +++ b/src/engine/graphics/vulkan/rhi_frame_orchestration.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("../../../c.zig").c; const rhi = @import("../rhi.zig"); +const log = @import("../../core/log.zig"); const build_options = @import("build_options"); const bindings = @import("descriptor_bindings.zig"); const lifecycle = @import("rhi_resource_lifecycle.zig"); @@ -28,52 +29,52 @@ pub fn recreateSwapchainInternal(ctx: anytype) void { ctx.runtime.ssao_pass_active = false; ctx.swapchain.recreate() catch |err| { - std.log.err("Failed to recreate swapchain: {}", .{err}); + log.log.errWithTrace("Failed to recreate swapchain: {}", .{err}); return; }; lifecycle.createHDRResources(ctx) catch |err| { - std.log.err("Failed to recreate HDR resources: {}", .{err}); + log.log.errWithTrace("Failed to recreate HDR resources: {}", .{err}); return; }; setup.createGPassResources(ctx) catch |err| { - std.log.err("Failed to recreate G-Pass resources: {}", .{err}); + log.log.errWithTrace("Failed to recreate G-Pass resources: {}", .{err}); return; }; setup.createSSAOResources(ctx) catch |err| { - std.log.err("Failed to recreate SSAO resources: {}", .{err}); + log.log.errWithTrace("Failed to recreate SSAO resources: {}", .{err}); return; }; setup.createTAAResources(ctx) catch |err| { - std.log.err("Failed to recreate TAA resources: {}", .{err}); + log.log.errWithTrace("Failed to recreate TAA resources: {}", .{err}); return; }; ctx.render_pass_manager.createMainRenderPass(ctx.vulkan_device.vk_device, ctx.swapchain.getExtent(), ctx.options.msaa_samples) catch |err| { - std.log.err("Failed to recreate render pass: {}", .{err}); + log.log.errWithTrace("Failed to recreate render pass: {}", .{err}); return; }; ctx.pipeline_manager.createMainPipelines(ctx.allocator, ctx.vulkan_device.vk_device, ctx.render_pass_manager.hdr_render_pass, ctx.render_pass_manager.g_render_pass, ctx.options.msaa_samples) catch |err| { - std.log.err("Failed to recreate pipelines: {}", .{err}); + log.log.errWithTrace("Failed to recreate pipelines: {}", .{err}); return; }; setup.createPostProcessResources(ctx) catch |err| { - std.log.err("Failed to recreate post-process resources: {}", .{err}); + log.log.errWithTrace("Failed to recreate post-process resources: {}", .{err}); return; }; setup.createSwapchainUIResources(ctx) catch |err| { - std.log.err("Failed to recreate swapchain UI resources: {}", .{err}); + log.log.errWithTrace("Failed to recreate swapchain UI resources: {}", .{err}); return; }; ctx.fxaa.init(&ctx.vulkan_device, ctx.allocator, ctx.descriptors.descriptor_pool, ctx.swapchain.getExtent(), ctx.swapchain.getImageFormat(), ctx.post_process.sampler, ctx.swapchain.getImageViews()) catch |err| { - std.log.err("Failed to recreate FXAA resources: {}", .{err}); + log.log.errWithTrace("Failed to recreate FXAA resources: {}", .{err}); return; }; ctx.pipeline_manager.createSwapchainUIPipelines(ctx.allocator, ctx.vulkan_device.vk_device, ctx.render_pass_manager.ui_swapchain_render_pass) catch |err| { - std.log.err("Failed to recreate swapchain UI pipelines: {}", .{err}); + log.log.errWithTrace("Failed to recreate swapchain UI pipelines: {}", .{err}); return; }; ctx.bloom.init(&ctx.vulkan_device, ctx.allocator, ctx.descriptors.descriptor_pool, ctx.hdr.hdr_view, ctx.swapchain.getExtent().width, ctx.swapchain.getExtent().height, c.VK_FORMAT_R16G16B16A16_SFLOAT) catch |err| { - std.log.err("Failed to recreate Bloom resources: {}", .{err}); + log.log.errWithTrace("Failed to recreate Bloom resources: {}", .{err}); return; }; setup.updatePostProcessDescriptorsWithBloom(ctx); @@ -96,14 +97,14 @@ pub fn recreateSwapchainInternal(ctx: anytype) void { } if (count > 0) { - lifecycle.transitionImagesToShaderRead(ctx, list[0..count], false) catch |err| std.log.warn("Failed to transition images: {}", .{err}); + lifecycle.transitionImagesToShaderRead(ctx, list[0..count], false) catch |err| log.log.warn("Failed to transition images: {}", .{err}); } if (ctx.gpass.g_depth_image != null) { - lifecycle.transitionImagesToShaderRead(ctx, &[_]c.VkImage{ctx.gpass.g_depth_image}, true) catch |err| std.log.warn("Failed to transition G-depth image: {}", .{err}); + lifecycle.transitionImagesToShaderRead(ctx, &[_]c.VkImage{ctx.gpass.g_depth_image}, true) catch |err| log.log.warn("Failed to transition G-depth image: {}", .{err}); } if (ctx.shadow_system.shadow_image != null) { - lifecycle.transitionImagesToShaderRead(ctx, &[_]c.VkImage{ctx.shadow_system.shadow_image}, true) catch |err| std.log.warn("Failed to transition Shadow image: {}", .{err}); + lifecycle.transitionImagesToShaderRead(ctx, &[_]c.VkImage{ctx.shadow_system.shadow_image}, true) catch |err| log.log.warn("Failed to transition Shadow image: {}", .{err}); for (0..rhi.SHADOW_CASCADE_COUNT) |i| { ctx.shadow_system.shadow_image_layouts[i] = c.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } @@ -192,7 +193,7 @@ pub fn prepareFrameState(ctx: anytype) void { if (ctx.draw.descriptors_dirty[ctx.frames.current_frame]) { if (ctx.descriptors.descriptor_sets[ctx.frames.current_frame] == null) { - std.log.err("CRITICAL: Descriptor set for frame {} is NULL!", .{ctx.frames.current_frame}); + log.log.err("CRITICAL: Descriptor set for frame {} is NULL!", .{ctx.frames.current_frame}); return; } var writes: [14]c.VkWriteDescriptorSet = undefined; @@ -236,13 +237,13 @@ pub fn prepareFrameState(ctx: anytype) void { } if (ctx.shadow_system.shadow_sampler == null) { - std.log.err("CRITICAL: Shadow sampler is NULL!", .{}); + log.log.err("CRITICAL: Shadow sampler is NULL!", .{}); } if (ctx.shadow_system.shadow_sampler_regular == null) { - std.log.err("CRITICAL: Shadow regular sampler is NULL!", .{}); + log.log.err("CRITICAL: Shadow regular sampler is NULL!", .{}); } if (ctx.shadow_system.shadow_image_view == null) { - std.log.err("CRITICAL: Shadow image view is NULL!", .{}); + log.log.err("CRITICAL: Shadow image view is NULL!", .{}); } image_infos[info_count] = .{ .sampler = ctx.shadow_system.shadow_sampler, diff --git a/src/engine/graphics/vulkan/rhi_init_deinit.zig b/src/engine/graphics/vulkan/rhi_init_deinit.zig index fa38fe4e..d4e97443 100644 --- a/src/engine/graphics/vulkan/rhi_init_deinit.zig +++ b/src/engine/graphics/vulkan/rhi_init_deinit.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("../../../c.zig").c; const rhi = @import("../rhi.zig"); +const log = @import("../../core/log.zig"); const RenderDevice = @import("../render_device.zig").RenderDevice; const VulkanDevice = @import("device.zig").VulkanDevice; const ResourceManager = @import("resource_manager.zig").ResourceManager; @@ -70,7 +71,7 @@ pub fn initContext(ctx: anytype, allocator: std.mem.Allocator, render_device: ?* else false; if (ctx.options.safe_mode) { - std.log.warn("ZIGCRAFT_SAFE_MODE enabled: throttling uploads and forcing GPU idle each frame", .{}); + log.log.warn("ZIGCRAFT_SAFE_MODE enabled: throttling uploads and forcing GPU idle each frame", .{}); } try setup.createShadowResources(ctx); @@ -116,14 +117,14 @@ pub fn initContext(ctx: anytype, allocator: std.mem.Allocator, render_device: ?* ctx.draw.current_lpv_texture_b = ctx.draw.dummy_texture_3d; const cloud_vbo_handle = try ctx.resources.createBuffer(8 * @sizeOf(f32), .vertex); - std.log.info("Cloud VBO handle: {}, map count: {}", .{ cloud_vbo_handle, ctx.resources.buffers.count() }); + log.log.info("Cloud VBO handle: {}, map count: {}", .{ cloud_vbo_handle, ctx.resources.buffers.count() }); if (cloud_vbo_handle == 0) { - std.log.err("Failed to create cloud VBO", .{}); + log.log.err("Failed to create cloud VBO", .{}); return error.InitializationFailed; } const cloud_buf = ctx.resources.buffers.get(cloud_vbo_handle); if (cloud_buf == null) { - std.log.err("Cloud VBO created but not found in map!", .{}); + log.log.err("Cloud VBO created but not found in map!", .{}); return error.InitializationFailed; } ctx.cloud.cloud_vbo = cloud_buf.?; @@ -142,7 +143,7 @@ pub fn initContext(ctx: anytype, allocator: std.mem.Allocator, render_device: ?* alloc_info.pSetLayouts = &ctx.pipeline_manager.ui_tex_descriptor_set_layout; const result = c.vkAllocateDescriptorSets(ctx.vulkan_device.vk_device, &alloc_info, &ctx.ui.ui_tex_descriptor_pool[i][j]); if (result != c.VK_SUCCESS) { - std.log.err("Failed to allocate UI texture descriptor set [{}][{}]: error {}. Pool state: maxSets={}, available may be exhausted by FXAA+Bloom+UI", .{ i, j, result, @as(u32, 1000) }); + log.log.err("Failed to allocate UI texture descriptor set [{}][{}]: error {}. Pool state: maxSets={}, available may be exhausted by FXAA+Bloom+UI", .{ i, j, result, @as(u32, 1000) }); } } ctx.ui.ui_tex_descriptor_next[i] = 0; @@ -176,11 +177,11 @@ pub fn initContext(ctx: anytype, allocator: std.mem.Allocator, render_device: ?* } if (count > 0) { - lifecycle.transitionImagesToShaderRead(ctx, list[0..count], false) catch |err| std.log.err("Failed to transition images during init: {}", .{err}); + lifecycle.transitionImagesToShaderRead(ctx, list[0..count], false) catch |err| log.log.err("Failed to transition images during init: {}", .{err}); } if (ctx.gpass.g_depth_image != null) { - lifecycle.transitionImagesToShaderRead(ctx, &[_]c.VkImage{ctx.gpass.g_depth_image}, true) catch |err| std.log.err("Failed to transition G-depth image during init: {}", .{err}); + lifecycle.transitionImagesToShaderRead(ctx, &[_]c.VkImage{ctx.gpass.g_depth_image}, true) catch |err| log.log.err("Failed to transition G-depth image during init: {}", .{err}); } } diff --git a/src/engine/graphics/vulkan/rhi_pass_orchestration.zig b/src/engine/graphics/vulkan/rhi_pass_orchestration.zig index 14e37dc0..8f78e3f4 100644 --- a/src/engine/graphics/vulkan/rhi_pass_orchestration.zig +++ b/src/engine/graphics/vulkan/rhi_pass_orchestration.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("../../../c.zig").c; const post_process_system_pkg = @import("post_process_system.zig"); +const log = @import("../../core/log.zig"); const PostProcessPushConstants = post_process_system_pkg.PostProcessPushConstants; const fxaa_system_pkg = @import("fxaa_system.zig"); const FXAAPushConstants = fxaa_system_pkg.FXAAPushConstants; @@ -10,19 +11,19 @@ pub fn beginGPassInternal(ctx: anytype) void { if (!ctx.frames.frame_in_progress or ctx.runtime.g_pass_active) return; if (ctx.render_pass_manager.g_render_pass == null or ctx.render_pass_manager.g_framebuffer == null or ctx.pipeline_manager.g_pipeline == null) { - std.log.warn("beginGPass: skipping - resources null (rp={}, fb={}, pipeline={})", .{ ctx.render_pass_manager.g_render_pass != null, ctx.render_pass_manager.g_framebuffer != null, ctx.pipeline_manager.g_pipeline != null }); + log.log.warn("beginGPass: skipping - resources null (rp={}, fb={}, pipeline={})", .{ ctx.render_pass_manager.g_render_pass != null, ctx.render_pass_manager.g_framebuffer != null, ctx.pipeline_manager.g_pipeline != null }); return; } if (ctx.gpass.g_pass_extent.width != ctx.swapchain.getExtent().width or ctx.gpass.g_pass_extent.height != ctx.swapchain.getExtent().height) { - std.log.warn("beginGPass: size mismatch! G-pass={}x{}, swapchain={}x{} - recreating", .{ ctx.gpass.g_pass_extent.width, ctx.gpass.g_pass_extent.height, ctx.swapchain.getExtent().width, ctx.swapchain.getExtent().height }); + log.log.warn("beginGPass: size mismatch! G-pass={}x{}, swapchain={}x{} - recreating", .{ ctx.gpass.g_pass_extent.width, ctx.gpass.g_pass_extent.height, ctx.swapchain.getExtent().width, ctx.swapchain.getExtent().height }); _ = c.vkDeviceWaitIdle(ctx.vulkan_device.vk_device); setup.createGPassResources(ctx) catch |err| { - std.log.err("Failed to recreate G-pass resources: {}", .{err}); + log.log.errWithTrace("Failed to recreate G-Pass resources: {}", .{err}); return; }; setup.createSSAOResources(ctx) catch |err| { - std.log.err("Failed to recreate SSAO resources: {}", .{err}); + log.log.errWithTrace("Failed to recreate SSAO resources: {}", .{err}); return; }; } @@ -34,7 +35,7 @@ pub fn beginGPassInternal(ctx: anytype) void { const command_buffer = ctx.frames.command_buffers[current_frame]; if (command_buffer == null or ctx.pipeline_manager.pipeline_layout == null) { - std.log.err("beginGPass: invalid command state (cb={}, layout={})", .{ command_buffer != null, ctx.pipeline_manager.pipeline_layout != null }); + log.log.err("beginGPass: invalid command state (cb={}, layout={})", .{ command_buffer != null, ctx.pipeline_manager.pipeline_layout != null }); return; } @@ -64,7 +65,7 @@ pub fn beginGPassInternal(ctx: anytype) void { c.vkCmdSetScissor(command_buffer, 0, 1, &scissor); const ds = ctx.descriptors.descriptor_sets[ctx.frames.current_frame]; - if (ds == null) std.log.err("CRITICAL: descriptor_set is NULL for frame {}", .{ctx.frames.current_frame}); + if (ds == null) log.log.err("CRITICAL: descriptor_set is NULL for frame {}", .{ctx.frames.current_frame}); c.vkCmdBindDescriptorSets(command_buffer, c.VK_PIPELINE_BIND_POINT_GRAPHICS, ctx.pipeline_manager.pipeline_layout, 0, 1, &ds, 0, null); } @@ -191,13 +192,13 @@ pub fn beginMainPassInternal(ctx: anytype) void { if (ctx.render_pass_manager.hdr_render_pass == null) { ctx.render_pass_manager.createMainRenderPass(ctx.vulkan_device.vk_device, ctx.swapchain.getExtent(), ctx.options.msaa_samples) catch |err| { - std.log.err("beginMainPass: failed to recreate render pass: {}", .{err}); + log.log.errWithTrace("beginMainPass: failed to recreate render pass: {}", .{err}); return; }; } if (ctx.render_pass_manager.main_framebuffer == null) { setup.createMainFramebuffers(ctx) catch |err| { - std.log.err("beginMainPass: failed to recreate framebuffer: {}", .{err}); + log.log.errWithTrace("beginMainPass: failed to recreate framebuffer: {}", .{err}); return; }; } @@ -301,7 +302,7 @@ pub fn beginPostProcessPassInternal(ctx: anytype) void { ctx.runtime.post_process_ran_this_frame = true; if (ctx.post_process.pipeline == null) { - std.log.err("Post-process pipeline is null, skipping draw", .{}); + log.log.err("Post-process pipeline is null, skipping draw", .{}); return; } @@ -319,7 +320,7 @@ pub fn beginPostProcessPassInternal(ctx: anytype) void { const pp_ds = ctx.post_process.descriptor_sets[ctx.frames.current_frame]; if (pp_ds == null) { - std.log.err("Post-process descriptor set is null for frame {}", .{ctx.frames.current_frame}); + log.log.err("Post-process descriptor set is null for frame {}", .{ctx.frames.current_frame}); return; } c.vkCmdBindDescriptorSets(command_buffer, c.VK_PIPELINE_BIND_POINT_GRAPHICS, ctx.post_process.pipeline_layout, 0, 1, &pp_ds, 0, null); @@ -392,7 +393,7 @@ pub fn endFrame(ctx: anytype) void { const transfer_cb = ctx.resources.getTransferCommandBuffer(); ctx.frames.endFrame(&ctx.swapchain, transfer_cb) catch |err| { - std.log.err("endFrame failed: {}", .{err}); + log.log.errWithTrace("endFrame failed: {}", .{err}); }; if (transfer_cb != null) { diff --git a/src/engine/graphics/vulkan/rhi_resource_setup.zig b/src/engine/graphics/vulkan/rhi_resource_setup.zig index b27472fa..a4b87904 100644 --- a/src/engine/graphics/vulkan/rhi_resource_setup.zig +++ b/src/engine/graphics/vulkan/rhi_resource_setup.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("../../../c.zig").c; const rhi = @import("../rhi.zig"); +const log = @import("../../core/log.zig"); const Utils = @import("utils.zig"); const shader_registry = @import("shader_registry.zig"); const build_options = @import("build_options"); @@ -325,7 +326,7 @@ pub fn createGPassResources(ctx: anytype) !void { try lifecycle.transitionImagesToShaderRead(ctx, &d_images, true); ctx.gpass.g_pass_extent = extent; - std.log.debug("G-Pass resources created ({}x{}) with velocity buffer", .{ extent.width, extent.height }); + log.log.debug("G-Pass resources created ({}x{}) with velocity buffer", .{ extent.width, extent.height }); } pub fn createSSAOResources(ctx: anytype) !void { diff --git a/src/engine/graphics/vulkan/rhi_state_control.zig b/src/engine/graphics/vulkan/rhi_state_control.zig index 28fc868a..9a804fcc 100644 --- a/src/engine/graphics/vulkan/rhi_state_control.zig +++ b/src/engine/graphics/vulkan/rhi_state_control.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("../../../c.zig").c; const frame_orchestration = @import("rhi_frame_orchestration.zig"); +const log = @import("../../core/log.zig"); pub fn waitIdle(ctx: anytype) void { if (!ctx.frames.dry_run and ctx.vulkan_device.vk_device != null) { @@ -62,12 +63,12 @@ pub fn recover(ctx: anytype) !void { if (!ctx.runtime.gpu_fault_detected) return; if (ctx.vulkan_device.recovery_count >= ctx.vulkan_device.max_recovery_attempts) { - std.log.err("RHI: Max recovery attempts ({d}) exceeded. GPU is unstable.", .{ctx.vulkan_device.max_recovery_attempts}); + log.log.err("RHI: Max recovery attempts ({d}) exceeded. GPU is unstable.", .{ctx.vulkan_device.max_recovery_attempts}); return error.GpuLost; } ctx.vulkan_device.recovery_count += 1; - std.log.info("RHI: Attempting GPU recovery (Attempt {d}/{d})...", .{ ctx.vulkan_device.recovery_count, ctx.vulkan_device.max_recovery_attempts }); + log.log.info("RHI: Attempting GPU recovery (Attempt {d}/{d})...", .{ ctx.vulkan_device.recovery_count, ctx.vulkan_device.max_recovery_attempts }); _ = c.vkDeviceWaitIdle(ctx.vulkan_device.vk_device); @@ -77,14 +78,14 @@ pub fn recover(ctx: anytype) !void { frame_orchestration.recreateSwapchainInternal(ctx); if (c.vkDeviceWaitIdle(ctx.vulkan_device.vk_device) != c.VK_SUCCESS) { - std.log.err("RHI: Device unresponsive after recovery. Recovery failed.", .{}); + log.log.err("RHI: Device unresponsive after recovery. Recovery failed.", .{}); ctx.vulkan_device.recovery_fail_count += 1; ctx.runtime.gpu_fault_detected = true; return error.GpuLost; } ctx.vulkan_device.recovery_success_count += 1; - std.log.info("RHI: Recovery step complete. If issues persist, please restart.", .{}); + log.log.info("RHI: Recovery step complete. If issues persist, please restart.", .{}); } pub fn setWireframe(ctx: anytype, enabled: bool) void { @@ -139,7 +140,7 @@ pub fn setVSync(ctx: anytype, enabled: bool) void { c.VK_PRESENT_MODE_FIFO_RELAXED_KHR => "FIFO_RELAXED", else => "UNKNOWN", }; - std.log.info("Vulkan present mode: {s}", .{mode_name}); + log.log.info("Vulkan present mode: {s}", .{mode_name}); } pub fn setAnisotropicFiltering(ctx: anytype, level: u8) void { @@ -160,7 +161,7 @@ pub fn setMSAA(ctx: anytype, samples: u8) void { ctx.swapchain.msaa_samples = clamped; ctx.runtime.framebuffer_resized = true; ctx.runtime.pipeline_rebuild_needed = true; - std.log.info("Vulkan MSAA set to {}x (pending swapchain recreation)", .{clamped}); + log.log.info("Vulkan MSAA set to {}x (pending swapchain recreation)", .{clamped}); } pub fn getMaxAnisotropy(ctx: anytype) u8 { diff --git a/src/engine/graphics/vulkan/rhi_ui_submission.zig b/src/engine/graphics/vulkan/rhi_ui_submission.zig index b04baf44..2df029ff 100644 --- a/src/engine/graphics/vulkan/rhi_ui_submission.zig +++ b/src/engine/graphics/vulkan/rhi_ui_submission.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("../../../c.zig").c; const rhi = @import("../rhi.zig"); +const log = @import("../../core/log.zig"); const Mat4 = @import("../../math/mat4.zig").Mat4; const build_options = @import("build_options"); const pass_orchestration = @import("rhi_pass_orchestration.zig"); @@ -56,7 +57,7 @@ pub fn begin2DPass(ctx: anytype, screen_width: f32, screen_height: f32) void { if (ui_vbo.mapped_ptr) |ptr| { ctx.ui.ui_mapped_ptr = ptr; } else { - std.log.err("UI VBO memory not mapped!", .{}); + log.log.err("UI VBO memory not mapped!", .{}); } const command_buffer = ctx.frames.command_buffers[ctx.frames.current_frame]; @@ -136,7 +137,7 @@ pub fn drawTexture2D(ctx: anytype, texture: rhi.TextureHandle, rect: rhi.Rect) v const tex_opt = ctx.resources.textures.get(texture); if (tex_opt == null) { - std.log.err("drawTexture2D: Texture handle {} not found in textures map!", .{texture}); + log.log.err("drawTexture2D: Texture handle {} not found in textures map!", .{texture}); return; } const tex = tex_opt.?; @@ -219,7 +220,7 @@ pub fn drawDepthTexture(ctx: anytype, texture: rhi.TextureHandle, rect: rhi.Rect const tex_opt = ctx.resources.textures.get(texture); if (tex_opt == null) { - std.log.err("drawDepthTexture: Texture handle {} not found in textures map!", .{texture}); + log.log.err("drawDepthTexture: Texture handle {} not found in textures map!", .{texture}); return; } const tex = tex_opt.?; diff --git a/src/engine/graphics/vulkan/swapchain_presenter.zig b/src/engine/graphics/vulkan/swapchain_presenter.zig index 184d5a40..20cd7b9d 100644 --- a/src/engine/graphics/vulkan/swapchain_presenter.zig +++ b/src/engine/graphics/vulkan/swapchain_presenter.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("../../../c.zig").c; const rhi_types = @import("../rhi_types.zig"); +const log = @import("../../core/log.zig"); const VulkanDevice = @import("../vulkan_device.zig").VulkanDevice; const VulkanSwapchain = @import("../vulkan_swapchain.zig").VulkanSwapchain; const Utils = @import("utils.zig"); @@ -29,14 +30,14 @@ pub const SwapchainPresenter = struct { // Load vkQueuePresentKHR dynamically to avoid linking issues or NULL symbols const fp_present = c.vkGetDeviceProcAddr(vulkan_device.vk_device, "vkQueuePresentKHR"); if (fp_present == null) { - std.log.err("Failed to load vkQueuePresentKHR function pointer", .{}); + log.log.err("Failed to load vkQueuePresentKHR function pointer", .{}); return error.ExtensionNotPresent; } const build_options = @import("build_options"); const skip = if (@hasDecl(build_options, "skip_present")) build_options.skip_present else false; - if (skip) std.log.warn("Headless/DryRun mode: Skipping vkQueuePresentKHR", .{}); + if (skip) log.log.warn("Headless/DryRun mode: Skipping vkQueuePresentKHR", .{}); return SwapchainPresenter{ .allocator = allocator, @@ -78,10 +79,10 @@ pub const SwapchainPresenter = struct { if (result == c.VK_ERROR_OUT_OF_DATE_KHR) { return error.OutOfDate; } else if (result == c.VK_TIMEOUT) { - std.log.err("vkAcquireNextImageKHR timed out (2s). Swapchain exhaustion?", .{}); + log.log.err("vkAcquireNextImageKHR timed out (2s). Swapchain exhaustion?", .{}); return error.Timeout; } else if (result != c.VK_SUCCESS and result != c.VK_SUBOPTIMAL_KHR) { - std.log.err("vkAcquireNextImageKHR failed with result: {d}", .{result}); + log.log.err("vkAcquireNextImageKHR failed with result: {d}", .{result}); return error.VulkanError; } @@ -90,7 +91,7 @@ pub const SwapchainPresenter = struct { pub fn present(self: *SwapchainPresenter, wait_semaphore: c.VkSemaphore, image_index: u32) !void { if (self.skip_present) { - std.log.debug("Skipping vkQueuePresentKHR (headless mode)", .{}); + log.log.debug("Skipping vkQueuePresentKHR (headless mode)", .{}); return; } diff --git a/src/engine/graphics/vulkan_device.zig b/src/engine/graphics/vulkan_device.zig index 60b2fe82..90165946 100644 --- a/src/engine/graphics/vulkan_device.zig +++ b/src/engine/graphics/vulkan_device.zig @@ -19,6 +19,7 @@ const std = @import("std"); const c = @import("../../c.zig").c; const rhi = @import("rhi.zig"); +const log = @import("../core/log.zig"); fn debugCallback( severity: c.VkDebugUtilsMessageSeverityFlagBitsEXT, @@ -33,7 +34,7 @@ fn debugCallback( if (callback_data) |data| { if (data.pMessage != null) { const message = std.mem.span(data.pMessage); - std.log.err("Vulkan validation error: {s}", .{message}); + log.log.err("Vulkan validation error: {s}", .{message}); } } } @@ -140,12 +141,12 @@ pub const VulkanDevice = struct { const debug_utils_enabled = enable_validation and debug_utils_supported and (debug_utils_in_sdl or enable_debug_utils); self.debug_utils_enabled = debug_utils_enabled; if (props2_supported and enable_props2) { - std.log.info("Enabling VK_KHR_get_physical_device_properties2", .{}); + log.log.info("Enabling VK_KHR_get_physical_device_properties2", .{}); } else if (!props2_supported) { - std.log.warn("VK_KHR_get_physical_device_properties2 not supported by instance", .{}); + log.log.warn("VK_KHR_get_physical_device_properties2 not supported by instance", .{}); } if (enable_validation and !debug_utils_enabled) { - std.log.warn("VK_EXT_debug_utils not available; validation errors will not be counted", .{}); + log.log.warn("VK_EXT_debug_utils not available; validation errors will not be counted", .{}); } var app_info = std.mem.zeroes(c.VkApplicationInfo); @@ -180,7 +181,7 @@ pub const VulkanDevice = struct { if (found) { create_info.enabledLayerCount = 1; create_info.ppEnabledLayerNames = &validation_layers; - std.log.info("Vulkan validation layers enabled", .{}); + log.log.info("Vulkan validation layers enabled", .{}); } } } @@ -273,14 +274,14 @@ pub const VulkanDevice = struct { if (std.mem.eql(u8, name_slice, device_fault_name_slice)) supports_device_fault = true; } - if (supports_robustness2) std.log.info("VK_EXT_robustness2 supported", .{}); - if (supports_device_fault) std.log.info("VK_EXT_device_fault supported", .{}); + if (supports_robustness2) log.log.info("VK_EXT_robustness2 supported", .{}); + if (supports_device_fault) log.log.info("VK_EXT_device_fault supported", .{}); self.supports_device_fault = supports_device_fault; const allow_robustness2 = supports_robustness2 and props2_enabled; const allow_device_fault = supports_device_fault and props2_enabled; if (!props2_enabled and (supports_robustness2 or supports_device_fault)) { - std.log.warn("VK_KHR_get_physical_device_properties2 not enabled; skipping robustness/device fault", .{}); + log.log.warn("VK_KHR_get_physical_device_properties2 not enabled; skipping robustness/device fault", .{}); } var robustness2_features = std.mem.zeroes(c.VkPhysicalDeviceRobustness2FeaturesEXT); @@ -332,7 +333,7 @@ pub const VulkanDevice = struct { if ((allow_robustness2 or allow_device_fault) and (create_result == c.VK_ERROR_FEATURE_NOT_PRESENT or create_result == c.VK_ERROR_EXTENSION_NOT_PRESENT)) { - std.log.warn("Robustness/device fault features not available, falling back to basic device", .{}); + log.log.warn("Robustness/device fault features not available, falling back to basic device", .{}); device_create_info.pNext = null; enabled_extensions[0] = c.VK_KHR_SWAPCHAIN_EXTENSION_NAME; enabled_extension_count = 1; @@ -372,13 +373,13 @@ pub const VulkanDevice = struct { debug_info.pfnUserCallback = debugCallback; debug_info.pUserData = self; if (func(self.instance, &debug_info, null, &self.debug_messenger) != c.VK_SUCCESS) { - std.log.warn("Failed to create debug utils messenger", .{}); + log.log.warn("Failed to create debug utils messenger", .{}); } } else { - std.log.warn("vkCreateDebugUtilsMessengerEXT not available", .{}); + log.log.warn("vkCreateDebugUtilsMessengerEXT not available", .{}); } } else { - std.log.warn("vkCreateDebugUtilsMessengerEXT not found; validation errors will not be counted", .{}); + log.log.warn("vkCreateDebugUtilsMessengerEXT not found; validation errors will not be counted", .{}); } } @@ -423,7 +424,7 @@ pub const VulkanDevice = struct { if (result == c.VK_ERROR_DEVICE_LOST) { self.fault_count += 1; - std.log.err("GPU reset triggered voluntarily (VK_ERROR_DEVICE_LOST). Total faults: {d}", .{self.fault_count}); + log.log.err("GPU reset triggered voluntarily (VK_ERROR_DEVICE_LOST). Total faults: {d}", .{self.fault_count}); self.logDeviceFaults(); return error.GpuLost; } @@ -434,11 +435,11 @@ pub const VulkanDevice = struct { /// Logs detailed fault information if VK_EXT_device_fault is enabled and supported. pub fn logDeviceFaults(self: VulkanDevice) void { const func = self.vkGetDeviceFaultInfoEXT orelse { - std.log.warn("VK_EXT_device_fault not available; review system logs (dmesg) for GPU errors.", .{}); + log.log.warn("VK_EXT_device_fault not available; review system logs (dmesg) for GPU errors.", .{}); return; }; - std.log.info("Querying VK_EXT_device_fault for detailed hang info...", .{}); + log.log.info("Querying VK_EXT_device_fault for detailed hang info...", .{}); var fault_info = std.mem.zeroes(c.VkDeviceFaultInfoEXT); fault_info.sType = c.VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT; @@ -446,11 +447,11 @@ pub const VulkanDevice = struct { const result = func(self.vk_device, &fault_info); if (result == c.VK_SUCCESS) { const desc: [*:0]const u8 = @ptrCast(&fault_info.description); - std.log.err("GPU Fault Detected: {s}", .{desc}); + log.log.err("GPU Fault Detected: {s}", .{desc}); } else { - std.log.warn("Failed to retrieve device fault info: {d}", .{result}); + log.log.warn("Failed to retrieve device fault info: {d}", .{result}); } - std.log.warn("Review system logs (dmesg/journalctl) for kernel-level GPU driver errors.", .{}); + log.log.warn("Review system logs (dmesg/journalctl) for kernel-level GPU driver errors.", .{}); } }; diff --git a/src/engine/graphics/vulkan_swapchain.zig b/src/engine/graphics/vulkan_swapchain.zig index efb08833..31cd3999 100644 --- a/src/engine/graphics/vulkan_swapchain.zig +++ b/src/engine/graphics/vulkan_swapchain.zig @@ -2,6 +2,7 @@ const std = @import("std"); const c = @import("../../c.zig").c; const rhi = @import("rhi.zig"); const VulkanDevice = @import("vulkan_device.zig").VulkanDevice; +const log = @import("../core/log.zig"); pub const VulkanSwapchain = struct { device: *const VulkanDevice, @@ -112,7 +113,7 @@ pub const VulkanSwapchain = struct { fn createSwapchain(self: *VulkanSwapchain) !void { if (self.headless_mode) { - std.log.info("VulkanSwapchain: Initializing in HEADLESS mode (offscreen)", .{}); + log.log.info("VulkanSwapchain: Initializing in HEADLESS mode (offscreen)", .{}); self.image_format = c.VK_FORMAT_B8G8R8A8_UNORM; self.extent = .{ .width = 1920, .height = 1080 }; self.pixel_width = 1920; diff --git a/src/game/app.zig b/src/game/app.zig index 2ed6d00a..39f74b6f 100644 --- a/src/game/app.zig +++ b/src/game/app.zig @@ -43,9 +43,12 @@ pub const App = struct { pub fn init(allocator: std.mem.Allocator) !*App { log.log.info("Initializing engine systems...", .{}); + + log.log.info("App.init: initializing SettingsManager", .{}); var settings_manager = try SettingsManager.init(allocator); errdefer settings_manager.deinit(); + log.log.info("App.init: initializing WindowManager ({}x{})", .{ settings_manager.settings.window_width, settings_manager.settings.window_height }); var wm = try WindowManager.init(allocator, true, settings_manager.settings.window_width, settings_manager.settings.window_height); errdefer wm.deinit(); @@ -54,6 +57,7 @@ pub const App = struct { input.initWindowSize(wm.window); const time = Time.init(); + log.log.info("App.init: initializing RenderSystem", .{}); const render_system = try RenderSystem.init(allocator, wm.window, &settings_manager.settings); errdefer render_system.deinit(); @@ -73,9 +77,11 @@ pub const App = struct { log.log.warn("ZIGCRAFT_SKIP_WORLD_UPDATE enabled", .{}); } + log.log.info("App.init: initializing AudioSystemManager", .{}); const audio_manager = try AudioSystemManager.init(allocator); errdefer audio_manager.deinit(); + log.log.info("App.init: initializing UISystemManager", .{}); var ui_manager = try UISystemManager.init(render_system.getRHI().uiRenderer(), input.window_width, input.window_height, build_options.smoke_test); errdefer ui_manager.deinit(); @@ -150,7 +156,7 @@ pub const App = struct { pub fn saveAllSettings(self: *const App) void { self.settings_manager.save(); InputSettings.saveFromMapper(self.allocator, self.input_mapper.interface()) catch |err| { - log.log.err("Failed to save input settings: {}", .{err}); + log.log.errWithTrace("Failed to save input settings: {}", .{err}); }; } diff --git a/src/game/session.zig b/src/game/session.zig index cae36770..f31513ea 100644 --- a/src/game/session.zig +++ b/src/game/session.zig @@ -115,7 +115,7 @@ pub const GameSession = struct { const effective_lod_enabled = if (safe_mode) false else lod_enabled; if (safe_mode) { - std.log.warn("ZIGCRAFT_SAFE_MODE enabled: render distance capped to {} and LOD disabled", .{effective_render_distance}); + log.log.warn("ZIGCRAFT_SAFE_MODE enabled: render distance capped to {} and LOD disabled", .{effective_render_distance}); } const lod_config = if (safe_mode) diff --git a/src/game/settings/json_presets.zig b/src/game/settings/json_presets.zig index ee22ae06..12f3a9f2 100644 --- a/src/game/settings/json_presets.zig +++ b/src/game/settings/json_presets.zig @@ -1,6 +1,7 @@ const std = @import("std"); const data = @import("data.zig"); const Settings = data.Settings; +const log = @import("../../engine/core/log.zig"); // Preset config compatible with static presets but with dynamic string name pub const PresetConfig = struct { @@ -48,7 +49,7 @@ pub fn initPresets(allocator: std.mem.Allocator) !void { // Load from assets/config/presets.json const content = std.fs.cwd().readFileAlloc("assets/config/presets.json", allocator, @enumFromInt(1024 * 1024)) catch |err| { - std.log.warn("Failed to open presets.json: {}", .{err}); + log.log.warn("Failed to open presets.json: {}", .{err}); return err; }; defer allocator.free(content); @@ -64,51 +65,51 @@ pub fn initPresets(allocator: std.mem.Allocator) !void { // Validate preset values against metadata constraints // Skip invalid presets instead of failing entire load if (p.shadow_distance < 100.0 or p.shadow_distance > 1000.0) { - std.log.warn("Skipping preset '{s}': invalid shadow_distance {}", .{ p.name, p.shadow_distance }); + log.log.warn("Skipping preset '{s}': invalid shadow_distance {}", .{ p.name, p.shadow_distance }); continue; } if (p.shadow_caster_distance < 50.0 or p.shadow_caster_distance > 500.0) { - std.log.warn("Skipping preset '{s}': invalid shadow_caster_distance {}", .{ p.name, p.shadow_caster_distance }); + log.log.warn("Skipping preset '{s}': invalid shadow_caster_distance {}", .{ p.name, p.shadow_caster_distance }); continue; } if (p.shadow_lod_bias < 0.0 or p.shadow_lod_bias > 3.0) { - std.log.warn("Skipping preset '{s}': invalid shadow_lod_bias {}", .{ p.name, p.shadow_lod_bias }); + log.log.warn("Skipping preset '{s}': invalid shadow_lod_bias {}", .{ p.name, p.shadow_lod_bias }); continue; } if (p.volumetric_density < 0.0 or p.volumetric_density > 0.5) { - std.log.warn("Skipping preset '{s}': invalid volumetric_density {}", .{ p.name, p.volumetric_density }); + log.log.warn("Skipping preset '{s}': invalid volumetric_density {}", .{ p.name, p.volumetric_density }); continue; } if (p.volumetric_steps < 4 or p.volumetric_steps > 32) { - std.log.warn("Skipping preset '{s}': invalid volumetric_steps {}", .{ p.name, p.volumetric_steps }); + log.log.warn("Skipping preset '{s}': invalid volumetric_steps {}", .{ p.name, p.volumetric_steps }); continue; } if (p.volumetric_scattering < 0.0 or p.volumetric_scattering > 1.0) { - std.log.warn("Skipping preset '{s}': invalid volumetric_scattering {}", .{ p.name, p.volumetric_scattering }); + log.log.warn("Skipping preset '{s}': invalid volumetric_scattering {}", .{ p.name, p.volumetric_scattering }); continue; } if (p.bloom_intensity < 0.0 or p.bloom_intensity > 2.0) { - std.log.warn("Skipping preset '{s}': invalid bloom_intensity {}", .{ p.name, p.bloom_intensity }); + log.log.warn("Skipping preset '{s}': invalid bloom_intensity {}", .{ p.name, p.bloom_intensity }); continue; } if (p.lpv_intensity < 0.0 or p.lpv_intensity > 2.0) { - std.log.warn("Skipping preset '{s}': invalid lpv_intensity {}", .{ p.name, p.lpv_intensity }); + log.log.warn("Skipping preset '{s}': invalid lpv_intensity {}", .{ p.name, p.lpv_intensity }); continue; } if (p.lpv_quality_preset > 2) { - std.log.warn("Skipping preset '{s}': invalid lpv_quality_preset {}", .{ p.name, p.lpv_quality_preset }); + log.log.warn("Skipping preset '{s}': invalid lpv_quality_preset {}", .{ p.name, p.lpv_quality_preset }); continue; } if (p.lpv_cell_size < 1.0 or p.lpv_cell_size > 4.0) { - std.log.warn("Skipping preset '{s}': invalid lpv_cell_size {}", .{ p.name, p.lpv_cell_size }); + log.log.warn("Skipping preset '{s}': invalid lpv_cell_size {}", .{ p.name, p.lpv_cell_size }); continue; } if (p.lpv_grid_size != 16 and p.lpv_grid_size != 32 and p.lpv_grid_size != 64) { - std.log.warn("Skipping preset '{s}': invalid lpv_grid_size {}", .{ p.name, p.lpv_grid_size }); + log.log.warn("Skipping preset '{s}': invalid lpv_grid_size {}", .{ p.name, p.lpv_grid_size }); continue; } if (p.lpv_propagation_iterations < 1 or p.lpv_propagation_iterations > 8) { - std.log.warn("Skipping preset '{s}': invalid lpv_propagation_iterations {}", .{ p.name, p.lpv_propagation_iterations }); + log.log.warn("Skipping preset '{s}': invalid lpv_propagation_iterations {}", .{ p.name, p.lpv_propagation_iterations }); continue; } // Duplicate name because parsed.deinit() will free strings @@ -116,7 +117,7 @@ pub fn initPresets(allocator: std.mem.Allocator) !void { errdefer allocator.free(p.name); try graphics_presets.append(allocator, p); } - std.log.info("Loaded {} graphics presets", .{graphics_presets.items.len}); + log.log.info("Loaded {} graphics presets", .{graphics_presets.items.len}); } pub fn deinitPresets(allocator: std.mem.Allocator) void { diff --git a/src/game/settings/persistence.zig b/src/game/settings/persistence.zig index c88ca1f4..c67fea19 100644 --- a/src/game/settings/persistence.zig +++ b/src/game/settings/persistence.zig @@ -1,6 +1,7 @@ const std = @import("std"); const data = @import("data.zig"); const Settings = data.Settings; +const log = @import("../../engine/core/log.zig"); const CONFIG_DIR = ".config/zigcraft"; const CONFIG_FILE = "settings.json"; @@ -28,7 +29,7 @@ pub fn load(allocator: std.mem.Allocator) Settings { // Open home directory var home_dir = std.fs.openDirAbsolute(home, .{}) catch |err| { - std.log.warn("Failed to open home directory '{s}': {}", .{ home, err }); + log.log.warn("Failed to open home directory '{s}': {}", .{ home, err }); return .{}; }; defer home_dir.close(); @@ -37,7 +38,7 @@ pub fn load(allocator: std.mem.Allocator) Settings { const config_path = CONFIG_DIR ++ "/" ++ CONFIG_FILE; const content = home_dir.readFileAlloc(config_path, allocator, @enumFromInt(16 * 1024)) catch |err| { if (err != error.FileNotFound) { - std.log.warn("Failed to read settings file '{s}': {}", .{ config_path, err }); + log.log.warn("Failed to read settings file '{s}': {}", .{ config_path, err }); } return .{}; }; @@ -46,7 +47,7 @@ pub fn load(allocator: std.mem.Allocator) Settings { const parsed = std.json.parseFromSlice(Settings, allocator, content, .{ .ignore_unknown_fields = true, }) catch |err| { - std.log.warn("Failed to parse settings JSON: {}. Using defaults.", .{err}); + log.log.warn("Failed to parse settings JSON: {}. Using defaults.", .{err}); return .{}; }; defer parsed.deinit(); @@ -55,14 +56,14 @@ pub fn load(allocator: std.mem.Allocator) Settings { // Deep copy string fields so they survive parsed.deinit() const texture_pack = dupStringField(allocator, settings.texture_pack) catch { - std.log.warn("Failed to allocate texture_pack string, using default", .{}); + log.log.warn("Failed to allocate texture_pack string, using default", .{}); settings.texture_pack = "default"; settings.environment_map = "default"; return settings; }; const environment_map = dupStringField(allocator, settings.environment_map) catch { - std.log.warn("Failed to allocate environment_map string, using default", .{}); + log.log.warn("Failed to allocate environment_map string, using default", .{}); freeStringField(allocator, texture_pack); // Clean up successful first allocation settings.texture_pack = "default"; settings.environment_map = "default"; @@ -72,7 +73,7 @@ pub fn load(allocator: std.mem.Allocator) Settings { settings.texture_pack = texture_pack; settings.environment_map = environment_map; - std.log.info("Settings loaded from ~/{s}", .{config_path}); + log.log.info("Settings loaded from ~/{s}", .{config_path}); return settings; } @@ -98,43 +99,43 @@ pub fn setEnvironmentMap(settings: *Settings, allocator: std.mem.Allocator, name /// Save settings to ~/.config/zigcraft/settings.json pub fn save(settings: *const Settings, allocator: std.mem.Allocator) void { const home = std.posix.getenv("HOME") orelse { - std.log.warn("Cannot save settings: HOME not set", .{}); + log.log.warn("Cannot save settings: HOME not set", .{}); return; }; // Open home directory var home_dir = std.fs.openDirAbsolute(home, .{}) catch |err| { - std.log.warn("Cannot open home directory: {}", .{err}); + log.log.warn("Cannot open home directory: {}", .{err}); return; }; defer home_dir.close(); // Create config directory if it doesn't exist home_dir.makePath(CONFIG_DIR) catch |err| { - std.log.warn("Failed to create config directory: {}", .{err}); + log.log.warn("Failed to create config directory: {}", .{err}); return; }; // Open/create the settings file const config_path = CONFIG_DIR ++ "/" ++ CONFIG_FILE; const file = home_dir.createFile(config_path, .{}) catch |err| { - std.log.warn("Failed to create settings file: {}", .{err}); + log.log.warn("Failed to create settings file: {}", .{err}); return; }; defer file.close(); // Serialize settings to JSON and write to file const json_str = std.json.Stringify.valueAlloc(allocator, settings.*, .{ .whitespace = .indent_2 }) catch |err| { - std.log.warn("Failed to serialize settings: {}", .{err}); + log.log.warn("Failed to serialize settings: {}", .{err}); return; }; defer allocator.free(json_str); // Write to file _ = file.writeAll(json_str) catch |err| { - std.log.warn("Failed to write settings: {}", .{err}); + log.log.warn("Failed to write settings: {}", .{err}); return; }; - std.log.info("Settings saved to ~/{s}", .{config_path}); + log.log.info("Settings saved to ~/{s}", .{config_path}); } diff --git a/src/robust_demo.zig b/src/robust_demo.zig index a1d3d755..404c2b22 100644 --- a/src/robust_demo.zig +++ b/src/robust_demo.zig @@ -6,6 +6,7 @@ const std = @import("std"); const c = @import("c.zig").c; const VulkanDevice = @import("engine/graphics/vulkan_device.zig").VulkanDevice; +const log = @import("engine/core/log.zig"); pub fn main() !void { std.debug.print("\n=== GPU Robustness Demo ===\n\n", .{}); @@ -23,7 +24,7 @@ pub fn main() !void { defer c.SDL_DestroyWindow(window); // 2. Create Robust Vulkan Device - std.log.info("Initializing robust Vulkan device...", .{}); + log.log.info("Initializing robust Vulkan device...", .{}); var device = try VulkanDevice.init(allocator, window.?); device.initDebugMessenger(); defer device.deinit(); @@ -87,7 +88,7 @@ pub fn main() !void { submit_info.commandBufferCount = 1; submit_info.pCommandBuffers = &cmd; - std.log.info("Submitting via device.submitGuarded()...", .{}); + log.log.info("Submitting via device.submitGuarded()...", .{}); device.submitGuarded(submit_info, null) catch |err| { if (err == error.GpuLost) { std.debug.print("\n[EXPECTED] GPU was lost but system is stable.\n", .{}); diff --git a/src/world/chunk_allocator.zig b/src/world/chunk_allocator.zig index b9a9d1e0..528ff98a 100644 --- a/src/world/chunk_allocator.zig +++ b/src/world/chunk_allocator.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const log = @import("../engine/core/log.zig"); const rhi_mod = @import("../engine/graphics/rhi.zig"); const ResourceManager = rhi_mod.ResourceManager; const IDeviceQuery = rhi_mod.IDeviceQuery; @@ -35,7 +36,7 @@ pub const GlobalVertexAllocator = struct { var free_blocks = std.ArrayListUnmanaged(FreeBlock){}; try free_blocks.append(allocator, .{ .offset = 0, .size = capacity }); - std.log.info("Initialized GlobalVertexAllocator with {}MB, buffer handle={}", .{ capacity_mb, buffer }); + log.log.info("Initialized GlobalVertexAllocator with {}MB, buffer handle={}", .{ capacity_mb, buffer }); var deferred_frees: [rhi_mod.MAX_FRAMES_IN_FLIGHT]std.ArrayListUnmanaged(VertexAllocation) = undefined; for (0..rhi_mod.MAX_FRAMES_IN_FLIGHT) |i| { @@ -126,7 +127,7 @@ pub const GlobalVertexAllocator = struct { total_free += block.size; } - std.log.err("GlobalVertexAllocator OOM: needed {} ({} vertices), capacity {}GB, total free: {} KB, free blocks: {}. Largest block: {} KB", .{ + log.log.err("GlobalVertexAllocator OOM: needed {} ({} vertices), capacity {}GB, total free: {} KB, free blocks: {}. Largest block: {} KB", .{ size_needed, vertices.len, self.capacity / (1024 * 1024 * 1024), @@ -154,7 +155,7 @@ pub const GlobalVertexAllocator = struct { const frame_idx = self.device_query.getFrameIndex(); self.deferred_frees[frame_idx].append(self.allocator, allocation) catch { // Fallback to immediate free if queue is full (better than leak, though slightly risky) - std.log.warn("Deferred free queue full, falling back to immediate free", .{}); + log.log.warn("Deferred free queue full, falling back to immediate free", .{}); self.freeImmediateUnlocked(allocation); }; } @@ -165,7 +166,7 @@ pub const GlobalVertexAllocator = struct { // Safety check: ensure we're not double-freeing or freeing an overlapping region for (self.free_blocks.items) |block| { if (allocation.offset < block.offset + block.size and allocation.offset + size > block.offset) { - std.log.err("Double-free or overlapping free detected in GlobalVertexAllocator! offset={}, size={}", .{ allocation.offset, size }); + log.log.err("Double-free or overlapping free detected in GlobalVertexAllocator! offset={}, size={}", .{ allocation.offset, size }); return; } } @@ -185,7 +186,7 @@ pub const GlobalVertexAllocator = struct { } self.free_blocks.insert(self.allocator, insert_idx, new_block) catch { - std.log.err("Failed to track free block in GlobalVertexAllocator", .{}); + log.log.err("Failed to track free block in GlobalVertexAllocator", .{}); return; }; diff --git a/src/world/chunk_mesh.zig b/src/world/chunk_mesh.zig index d2a6bf6f..7e332e2b 100644 --- a/src/world/chunk_mesh.zig +++ b/src/world/chunk_mesh.zig @@ -5,6 +5,7 @@ //! delegated to modules in `meshing/`. const std = @import("std"); +const log = @import("../engine/core/log.zig"); const Chunk = @import("chunk.zig").Chunk; const CHUNK_SIZE_X = @import("chunk.zig").CHUNK_SIZE_X; @@ -249,7 +250,7 @@ pub const ChunkMesh = struct { if (v.len > 0) { self.solid_allocation = allocator.allocate(v) catch |err| { - std.log.err("Failed to allocate chunk mesh vertices (will retry): {}", .{err}); + log.log.errWithTrace("Failed to allocate chunk mesh vertices (will retry): {}", .{err}); return; }; } @@ -272,7 +273,7 @@ pub const ChunkMesh = struct { if (v.len > 0) { self.cutout_allocation = allocator.allocate(v) catch |err| { - std.log.err("Failed to allocate chunk cutout vertices (will retry): {}", .{err}); + log.log.errWithTrace("Failed to allocate chunk cutout vertices (will retry): {}", .{err}); return; }; } @@ -294,7 +295,7 @@ pub const ChunkMesh = struct { if (v.len > 0) { self.fluid_allocation = allocator.allocate(v) catch |err| { - std.log.err("Failed to allocate chunk fluid vertices (will retry): {}", .{err}); + log.log.errWithTrace("Failed to allocate chunk fluid vertices (will retry): {}", .{err}); return; }; } diff --git a/src/world/lod_manager.zig b/src/world/lod_manager.zig index b3d461a7..916cb20d 100644 --- a/src/world/lod_manager.zig +++ b/src/world/lod_manager.zig @@ -962,7 +962,7 @@ pub const LODManager = struct { // Build mesh (expensive, done without lock) // Note: buildMeshForChunk -> getOrCreateMesh acquires its own lock self.buildMeshForChunk(chunk) catch |err| { - log.log.err("Failed to build LOD{} async mesh: {}", .{ @intFromEnum(lod_level), err }); + log.log.errWithTrace("Failed to build LOD{} async mesh: {}", .{ @intFromEnum(lod_level), err }); new_state = .generated; // Retry later chunk.unpin(); // Acquire lock briefly to update state diff --git a/src/world/lod_renderer.zig b/src/world/lod_renderer.zig index 2c96a8df..bb6785b6 100644 --- a/src/world/lod_renderer.zig +++ b/src/world/lod_renderer.zig @@ -135,7 +135,7 @@ pub fn LODRenderer(comptime RHI: type) type { var i: usize = LODLevel.count - 1; while (i > 0) : (i -= 1) { self.collectVisibleMeshes(&meshes[i], ®ions[i], config, view_proj, camera_pos, frustum, lod_y_offset, chunk_checker, checker_ctx, use_frustum) catch |err| { - log.log.err("Failed to collect visible meshes for LOD{}: {}", .{ i, err }); + log.log.errWithTrace("Failed to collect visible meshes for LOD{}: {}", .{ i, err }); }; } diff --git a/src/world/lod_upload_queue.zig b/src/world/lod_upload_queue.zig index d292ff03..3972a19e 100644 --- a/src/world/lod_upload_queue.zig +++ b/src/world/lod_upload_queue.zig @@ -4,6 +4,7 @@ //! LODManager uses these interfaces instead of holding a direct RHI reference. const std = @import("std"); +const log = @import("../engine/core/log.zig"); const lod_chunk = @import("lod_chunk.zig"); const LODLevel = lod_chunk.LODLevel; const LODChunk = lod_chunk.LODChunk; @@ -46,7 +47,7 @@ pub const LODGPUBridge = struct { pub fn destroy(self: LODGPUBridge, mesh: *LODMesh) void { if (self.hasInvalidCtx()) { - std.log.err("LODGPUBridge.destroy called with invalid context pointer", .{}); + log.log.err("LODGPUBridge.destroy called with invalid context pointer", .{}); return; } self.assertValidCtx(); @@ -55,7 +56,7 @@ pub const LODGPUBridge = struct { pub fn waitIdle(self: LODGPUBridge) void { if (self.hasInvalidCtx()) { - std.log.err("LODGPUBridge.waitIdle called with invalid context pointer", .{}); + log.log.err("LODGPUBridge.waitIdle called with invalid context pointer", .{}); return; } self.assertValidCtx(); diff --git a/src/world/world.zig b/src/world/world.zig index f60139ab..46c8eed7 100644 --- a/src/world/world.zig +++ b/src/world/world.zig @@ -77,9 +77,9 @@ pub const World = struct { const safe_render_distance: i32 = if (safe_mode) @min(render_distance, 8) else render_distance; const max_uploads: usize = if (safe_mode) @as(usize, 4) else @as(usize, 32); if (safe_mode) { - std.log.warn("ZIGCRAFT_SAFE_MODE enabled: limiting uploads to {} per frame", .{max_uploads}); + log.log.warn("ZIGCRAFT_SAFE_MODE enabled: limiting uploads to {} per frame", .{max_uploads}); if (safe_render_distance != render_distance) { - std.log.warn("ZIGCRAFT_SAFE_MODE clamped render distance to {}", .{safe_render_distance}); + log.log.warn("ZIGCRAFT_SAFE_MODE clamped render distance to {}", .{safe_render_distance}); } } @@ -99,7 +99,11 @@ pub const World = struct { .lod_enabled = false, }; + log.log.info("World.initGen: initializing WorldStreamer (render_distance={})", .{safe_render_distance}); world.streamer = try WorldStreamer.init(allocator, &world.storage, world.generator, atlas, render_distance); + errdefer world.streamer.deinit(); + + log.log.info("World.initGen: initializing WorldRenderer", .{}); world.renderer = try WorldRenderer.init(allocator, rhi.resourceManager(), rhi.renderContext(), rhi.query(), &world.storage); return world; @@ -162,9 +166,9 @@ pub const World = struct { if (self.render_distance != target) { if (self.safe_mode and target != distance) { - std.log.warn("ZIGCRAFT_SAFE_MODE clamped render distance {} -> {}", .{ distance, target }); + log.log.warn("ZIGCRAFT_SAFE_MODE clamped render distance {} -> {}", .{ distance, target }); } - std.log.info("Render distance changed: {} -> {}", .{ self.render_distance, target }); + log.log.info("Render distance changed: {} -> {}", .{ self.render_distance, target }); self.render_distance = target; self.streamer.setRenderDistance(target); diff --git a/src/world/world_renderer.zig b/src/world/world_renderer.zig index a0634a21..fb61bba5 100644 --- a/src/world/world_renderer.zig +++ b/src/world/world_renderer.zig @@ -1,6 +1,7 @@ //! World renderer - handles chunk rendering, culling, and MDI. const std = @import("std"); +const log = @import("../engine/core/log.zig"); const ChunkData = @import("chunk_storage.zig").ChunkData; const ChunkStorage = @import("chunk_storage.zig").ChunkStorage; const worldToChunk = @import("chunk.zig").worldToChunk; @@ -55,7 +56,7 @@ pub const WorldRenderer = struct { const vertex_capacity_mb: usize = if (safe_mode) 1024 else 2048; if (safe_mode) { - std.log.warn("ZIGCRAFT_SAFE_MODE enabled: GlobalVertexAllocator reduced to {}MB", .{vertex_capacity_mb}); + log.log.warn("ZIGCRAFT_SAFE_MODE enabled: GlobalVertexAllocator reduced to {}MB", .{vertex_capacity_mb}); } const vertex_allocator = try allocator.create(GlobalVertexAllocator); diff --git a/src/world/world_streamer.zig b/src/world/world_streamer.zig index ff349317..27c0330c 100644 --- a/src/world/world_streamer.zig +++ b/src/world/world_streamer.zig @@ -467,7 +467,7 @@ pub const WorldStreamer = struct { if (chunk_data.chunk.state == .meshing and chunk_data.chunk.job_token == job.data.chunk.job_token) { chunk_data.mesh.buildWithNeighbors(&chunk_data.chunk, neighbors, self.atlas) catch |err| { - log.log.err("Mesh build failed for chunk ({}, {}): {}", .{ cx, cz, err }); + log.log.errWithTrace("Mesh build failed for chunk ({}, {}): {}", .{ cx, cz, err }); }; if (self.mesh_queue.abort_worker) { chunk_data.chunk.state = .generated; diff --git a/src/world/worldgen/overworld_generator.zig b/src/world/worldgen/overworld_generator.zig index affe5b1b..1f7ece68 100644 --- a/src/world/worldgen/overworld_generator.zig +++ b/src/world/worldgen/overworld_generator.zig @@ -190,7 +190,7 @@ pub const OverworldGenerator = struct { LightingComputer.computeSkylight(chunk); if (stop_flag) |sf| if (sf.*) return; LightingComputer.computeBlockLight(chunk, self.allocator) catch |err| { - log.log.err("Failed to compute block light for chunk ({}, {}): {}", .{ chunk.chunk_x, chunk.chunk_z, err }); + log.log.errWithTrace("Failed to compute block light for chunk ({}, {}): {}", .{ chunk.chunk_x, chunk.chunk_z, err }); return; }; diff --git a/src/world/worldgen/registry.zig b/src/world/worldgen/registry.zig index 38cfcb9d..0786d30e 100644 --- a/src/world/worldgen/registry.zig +++ b/src/world/worldgen/registry.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const log = @import("../../engine/core/log.zig"); const gen_interface = @import("generator_interface.zig"); const Generator = gen_interface.Generator; const overworld = @import("overworld_generator.zig"); @@ -51,7 +52,7 @@ pub fn getGeneratorInfo(index: usize) gen_interface.GeneratorInfo { pub fn createGenerator(index: usize, seed: u64, allocator: std.mem.Allocator) RegistryError!Generator { if (index >= GENERATORS.len) return error.InvalidGeneratorIndex; return GENERATORS[index].initFn(seed, allocator) catch |err| { - std.log.err("Generator initialization failed for index {}: {}", .{ index, err }); + log.log.err("Generator initialization failed for index {}: {}", .{ index, err }); return err; }; }