Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/engine/core/log.zig
Original file line number Diff line number Diff line change
@@ -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");
Expand Down Expand Up @@ -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;

Expand All @@ -59,5 +74,4 @@ pub const Logger = struct {
}
};

/// Global logger instance
pub var log = Logger.init(if (builtin.is_test) .err else .debug);
11 changes: 6 additions & 5 deletions src/engine/graphics/lpv_system.zig
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
};
}
4 changes: 2 additions & 2 deletions src/engine/graphics/render_graph.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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});
}
};
}
Expand Down Expand Up @@ -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});
}
};
}
Expand Down
6 changes: 6 additions & 0 deletions src/engine/graphics/render_system.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
Expand All @@ -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();

Expand Down Expand Up @@ -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,
Expand Down
7 changes: 4 additions & 3 deletions src/engine/graphics/rhi_vulkan.zig
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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});
};
}

Expand All @@ -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;
};
Expand Down
5 changes: 3 additions & 2 deletions src/engine/graphics/vulkan/descriptor_manager.zig
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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));
Expand All @@ -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));
Expand Down
3 changes: 2 additions & 1 deletion src/engine/graphics/vulkan/render_pass_manager.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down Expand Up @@ -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);
Expand Down
11 changes: 6 additions & 5 deletions src/engine/graphics/vulkan/resource_manager.zig
Original file line number Diff line number Diff line change
@@ -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");
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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});
};
}

Expand All @@ -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;
};

Expand Down Expand Up @@ -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});
};
}

Expand Down Expand Up @@ -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;
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/engine/graphics/vulkan/resource_texture_ops.zig
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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;
}

Expand Down
3 changes: 2 additions & 1 deletion src/engine/graphics/vulkan/rhi_context_factory.zig
Original file line number Diff line number Diff line change
@@ -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");
Expand Down Expand Up @@ -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;
Expand Down
9 changes: 5 additions & 4 deletions src/engine/graphics/vulkan/rhi_draw_submission.zig
Original file line number Diff line number Diff line change
@@ -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");

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 });
}
}

Expand All @@ -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});
}
}
}
Expand Down Expand Up @@ -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;
}

Expand Down
Loading
Loading