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 6448ee2c..0032e925 100644 --- a/src/world/world.zig +++ b/src/world/world.zig @@ -75,9 +75,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}); } } @@ -96,8 +96,13 @@ pub const World = struct { .lod_enabled = false, }; + log.log.info("World.initGen: initializing WorldRenderer", .{}); world.renderer = try WorldRenderer.init(allocator, rhi.resourceManager(), rhi.renderContext(), rhi.query(), &world.storage); + errdefer _ = world.renderer; + + log.log.info("World.initGen: initializing WorldStreamer (render_distance={})", .{safe_render_distance}); world.streamer = try WorldStreamer.init(allocator, &world.storage, world.generator, atlas, world.render_distance, world.renderer.vertex_allocator, max_uploads); + errdefer world.streamer.deinit(); return world; } @@ -160,9 +165,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 a99ac440..2d5e381c 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 5c4a124e..3555fe19 100644 --- a/src/world/world_streamer.zig +++ b/src/world/world_streamer.zig @@ -481,7 +481,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; }; }