From ab184d5a33aef28378a81b8dcc26804c41f20946 Mon Sep 17 00:00:00 2001 From: peterino2 Date: Fri, 26 Sep 2025 21:20:24 -0700 Subject: [PATCH] lots of memory tracking in the game now --- engine/core/src/MemoryTracker.zig | 18 +++++++++++-- engine/papyrus/src/Event.zig | 25 +++++++++++++++---- engine/papyrus/src/papyrus.zig | 8 +++--- engine/papyrus/src/primitives/button.zig | 10 +++----- engine/physics/src/physicsSystem.zig | 1 + engine/rend/src/sgpu/ParticleRenderer.zig | 4 +-- engine/ui/src/sgpu/papyrusSgpu.zig | 9 +++++++ engine/ui/src/sgpu/textRenderer.zig | 4 +++ lib/p2/src/structures/bump-arena.zig | 8 ++++++ projects/sampleGame/externGame/externGame.zig | 12 ++++++--- 10 files changed, 75 insertions(+), 24 deletions(-) diff --git a/engine/core/src/MemoryTracker.zig b/engine/core/src/MemoryTracker.zig index 5443d12..1c8d9b9 100644 --- a/engine/core/src/MemoryTracker.zig +++ b/engine/core/src/MemoryTracker.zig @@ -264,18 +264,32 @@ pub fn addUntrackedAllocation(self: *@This(), allocatedSize: usize) void { self.lock.lock(); self.untrackedAllocationsCount += 1; self.untrackedAllocationsSize += allocatedSize; - self.totalAllocSize += allocatedSize; + + if (self.timeline) |*timeline| { + timeline.pushAlloc(self.stackCompactor.?, 0, allocatedSize); + } + self.lock.unlock(); } pub fn removeUntrackedAllocation(self: *@This(), allocatedSize: usize) void { self.lock.lock(); - self.totalAllocSize -= allocatedSize; self.untrackedAllocationsCount -= 1; self.untrackedAllocationsSize -= allocatedSize; self.lock.unlock(); } +pub fn getTotalMemoryUsed(self: *@This()) usize { + return self.totalAllocSize + self.untrackedAllocationsSize + self.getTrackerUsage(); +} + +pub fn getTrackerUsage(self: *@This()) usize { + if (self.timeline) |timeline| { + return timeline.events.capacity() + self.stackCompactor.?.stackArena.usage(); + } + return 0; +} + var gMemTracker: ?*@This() = null; pub const SetupSettings = struct { diff --git a/engine/papyrus/src/Event.zig b/engine/papyrus/src/Event.zig index 5c515aa..d17a643 100644 --- a/engine/papyrus/src/Event.zig +++ b/engine/papyrus/src/Event.zig @@ -87,10 +87,11 @@ pub const HandlerError = error{ EventIgnored, }; -pub const SingleFn = *const fn (NodeHandle, ?*anyopaque) HandlerError!void; -pub const PressedFn = *const fn (NodeHandle, PressedType, ?*anyopaque) HandlerError!void; +pub const SingleFn = *const fn (*papyrus.Context, NodeHandle, ?*anyopaque) HandlerError!void; +pub const PressedFn = *const fn (*papyrus.Context, NodeHandle, PressedType, ?*anyopaque) HandlerError!void; const Listener = struct { + ctx: *papyrus.Context, node: NodeHandle, event: Type, context: ?*anyopaque, @@ -99,6 +100,7 @@ const Listener = struct { }; const PressedListener = struct { + ctx: *papyrus.Context, node: NodeHandle, keycode: Key, event: PressedType, @@ -109,6 +111,7 @@ const PressedListener = struct { pub fn installMouseOverEventAdvanced( self: *@This(), + ctx: *papyrus.Context, node: NodeHandle, event: Type, context: ?*anyopaque, @@ -118,6 +121,7 @@ pub fn installMouseOverEventAdvanced( const allocator = self.arena.allocator(); const listener: Listener = .{ + .ctx = ctx, .node = node, .event = event, .context = context, @@ -136,19 +140,20 @@ pub fn installMouseOverEventAdvanced( pub fn installMouseOverEvent( self: *@This(), + ctx: *papyrus.Context, node: NodeHandle, event: Type, context: ?*anyopaque, eventFn: SingleFn, ) !void { - try installMouseOverEventAdvanced(self, node, event, context, eventFn, false); + try installMouseOverEventAdvanced(self, ctx, node, event, context, eventFn, false); } pub fn pushMouseOverEvent(self: *@This(), node: NodeHandle, event: Type) HandlerError!void { if (self.inputEvents.get(node)) |listeners| { for (listeners.items) |listener| { if (listener.event == event) { - try listener.eventFn(node, listener.context); + try listener.eventFn(listener.ctx, node, listener.context); } } } @@ -164,8 +169,18 @@ pub fn pushPressedEvent(self: *@This(), node: NodeHandle, event: PressedType, ke } } -pub fn installOnPressedEventAdvanced(self: *@This(), node: NodeHandle, event: PressedType, keycode: Key, context: ?*anyopaque, eventFn: PressedFn, innate: bool) !void { +pub fn installOnPressedEventAdvanced( + self: *@This(), + ctx: *papyrus.Context, + node: NodeHandle, + event: PressedType, + keycode: Key, + context: ?*anyopaque, + eventFn: PressedFn, + innate: bool, +) !void { const listener: PressedListener = .{ + .ctx = ctx, .node = node, .event = event, .keycode = keycode, diff --git a/engine/papyrus/src/papyrus.zig b/engine/papyrus/src/papyrus.zig index 23faf25..323a530 100644 --- a/engine/papyrus/src/papyrus.zig +++ b/engine/papyrus/src/papyrus.zig @@ -733,11 +733,11 @@ pub const Context = struct { self.get(button).text = LocText.fromUtf8(t); } - try self.events.installMouseOverEventAdvanced(button, .mouseOver, null, NodeProperty_Button.buttonMouseOverListener, true); - try self.events.installMouseOverEventAdvanced(button, .mouseOff, null, NodeProperty_Button.buttonMouseOffListener, true); + try self.events.installMouseOverEventAdvanced(self, button, .mouseOver, null, NodeProperty_Button.buttonMouseOverListener, true); + try self.events.installMouseOverEventAdvanced(self, button, .mouseOff, null, NodeProperty_Button.buttonMouseOffListener, true); - try self.events.installOnPressedEventAdvanced(button, .onPressed, .Mouse1, null, NodeProperty_Button.buttonOnPressedEvent, true); - try self.events.installOnPressedEventAdvanced(button, .onReleased, .Mouse1, null, NodeProperty_Button.buttonOnPressedEvent, true); + try self.events.installOnPressedEventAdvanced(self, button, .onPressed, .Mouse1, null, NodeProperty_Button.buttonOnPressedEvent, true); + try self.events.installOnPressedEventAdvanced(self, button, .onReleased, .Mouse1, null, NodeProperty_Button.buttonOnPressedEvent, true); return button; } diff --git a/engine/papyrus/src/primitives/button.zig b/engine/papyrus/src/primitives/button.zig index a5d9f20..b100a76 100644 --- a/engine/papyrus/src/primitives/button.zig +++ b/engine/papyrus/src/primitives/button.zig @@ -3,7 +3,6 @@ font: papyrus.Font, buttonStyle: ButtonStyle = .{}, disabled: bool = false, buttonState: ButtonState = .Normal, - // documentation: // Each PapyrusNode has a common set of fields, these are defined in PapyrusNode // @@ -118,24 +117,21 @@ pub fn addToDrawList(dlb: DrawListBuilder) !void { }; } -pub fn buttonMouseOverListener(node: papyrus.NodeHandle, _: ?*anyopaque) papyrus.HandlerError!void { - var ctx = papyrus.getContext(); +pub fn buttonMouseOverListener(ctx: *papyrus.Context, node: papyrus.NodeHandle, _: ?*anyopaque) papyrus.HandlerError!void { var btn = ctx.getButton(node); if (btn.disabled == false) { btn.buttonState = .Hovered; } } -pub fn buttonMouseOffListener(node: papyrus.NodeHandle, _: ?*anyopaque) papyrus.HandlerError!void { - var ctx = papyrus.getContext(); +pub fn buttonMouseOffListener(ctx: *papyrus.Context, node: papyrus.NodeHandle, _: ?*anyopaque) papyrus.HandlerError!void { var btn = ctx.getButton(node); if (btn.disabled == false) { btn.buttonState = .Normal; } } -pub fn buttonOnPressedEvent(node: papyrus.NodeHandle, eventType: papyrus.PressedType, _: ?*anyopaque) papyrus.HandlerError!void { - var ctx = papyrus.getContext(); +pub fn buttonOnPressedEvent(ctx: *papyrus.Context, node: papyrus.NodeHandle, eventType: papyrus.PressedType, _: ?*anyopaque) papyrus.HandlerError!void { var btn = ctx.getButton(node); if (eventType == .onPressed) { diff --git a/engine/physics/src/physicsSystem.zig b/engine/physics/src/physicsSystem.zig index 47c73fb..86a0d5c 100644 --- a/engine/physics/src/physicsSystem.zig +++ b/engine/physics/src/physicsSystem.zig @@ -155,6 +155,7 @@ pub const PhysicsRuntime = struct { pub fn init(allocator: std.mem.Allocator) !*@This() { const self = try allocator.create(@This()); try zphysics.init(std.heap.c_allocator, .{}); + //try zphysics.init(allocator, .{}); self.* = .{ .allocator = allocator, diff --git a/engine/rend/src/sgpu/ParticleRenderer.zig b/engine/rend/src/sgpu/ParticleRenderer.zig index ff1e9f9..acd8416 100644 --- a/engine/rend/src/sgpu/ParticleRenderer.zig +++ b/engine/rend/src/sgpu/ParticleRenderer.zig @@ -23,6 +23,8 @@ pub fn create(allocator: std.mem.Allocator) !*@This() { const device = rend.context().device; + const MaxParticleCount = core.configVar(u32, "rend.particles.maxCount", 200_000); + self.ssboScene = device.createGPUBuffer(&.{ .usage = .{ .bufferusageGraphicsStorageRead = true, @@ -125,8 +127,6 @@ pub fn destroy(self: *@This()) void { self.allocator.destroy(self); } -const MaxParticleCount = 10_000_000; - const assets = @import("assets"); const core = @import("core"); const std = @import("std"); diff --git a/engine/ui/src/sgpu/papyrusSgpu.zig b/engine/ui/src/sgpu/papyrusSgpu.zig index d652651..28a7971 100644 --- a/engine/ui/src/sgpu/papyrusSgpu.zig +++ b/engine/ui/src/sgpu/papyrusSgpu.zig @@ -150,6 +150,15 @@ pub fn tick(self: *@This(), dt: f64) void { tracker.eventsCount - self.lastEventsCount, }) catch {}; + self.screenContext.pushDebugText("untracked allocations: {d:.4} MiB in {d} allocations", .{ + @as(f64, @floatFromInt(tracker.untrackedAllocationsSize)) / 1024 / 1024, + tracker.untrackedAllocationsCount, + }) catch {}; + + self.screenContext.pushDebugText("total {d:.4} MiB", .{ + @as(f64, @floatFromInt(tracker.getTotalMemoryUsed())) / 1024 / 1024, + }) catch {}; + self.lastEventsCount = tracker.eventsCount; } } diff --git a/engine/ui/src/sgpu/textRenderer.zig b/engine/ui/src/sgpu/textRenderer.zig index 59b2e67..a7a64bf 100644 --- a/engine/ui/src/sgpu/textRenderer.zig +++ b/engine/ui/src/sgpu/textRenderer.zig @@ -371,6 +371,10 @@ pub const TextRenderer = struct { item.destroy(self.allocator); } + for (self.deadList.items) |item| { + item.destroy(self.allocator); + } + self.geo.destroy(); self.linearBuffers.deinit(self.allocator); self.assignedBuffers.deinit(self.allocator); diff --git a/lib/p2/src/structures/bump-arena.zig b/lib/p2/src/structures/bump-arena.zig index 077a01b..6b59464 100644 --- a/lib/p2/src/structures/bump-arena.zig +++ b/lib/p2/src/structures/bump-arena.zig @@ -10,6 +10,8 @@ pub const BumpArena = struct { smallBumpOffset: usize = 0, pageIndex: usize = 0, + allocatedBytes: usize = 0, + backing: std.mem.Allocator, small: SmallAllocPages, large: std.heap.ArenaAllocator, @@ -22,6 +24,10 @@ pub const BumpArena = struct { .remap = std.mem.Allocator.noRemap, }; + pub fn usage(self: *@This()) usize { + return self.allocatedBytes; + } + pub fn init(backing: std.mem.Allocator) !@This() { return .{ .backing = backing, @@ -52,6 +58,8 @@ pub const BumpArena = struct { self.mutex.lock(); defer self.mutex.unlock(); + self.allocatedBytes += len; + if (len > 4096) { return self.largeAllocator().vtable.alloc(self.largeAllocator().ptr, len, ptr_align, ret_addr); } else { diff --git a/projects/sampleGame/externGame/externGame.zig b/projects/sampleGame/externGame/externGame.zig index 6cf87f3..07edb65 100644 --- a/projects/sampleGame/externGame/externGame.zig +++ b/projects/sampleGame/externGame/externGame.zig @@ -129,7 +129,7 @@ pub const ExternGameObject = struct { defer settings.release(); try physics.addShape("ph_small_box", settings); - if (false) { + if (true) { const ctx = ui.getScreen(); const panel2 = try ctx.addPanel(.{}); ctx.drawDebug = true; @@ -138,14 +138,18 @@ pub const ExternGameObject = struct { //ctx.get(panel2).anchor = .TopRight; // ctx.get(panel2).fill = .FillY; todo, this is a bug. why. ctx.get(panel2).pos = .{ .x = 900, .y = 200 }; - ctx.get(panel2).size = .{ .x = 300, .y = 400 }; + ctx.get(panel2).size = .{ .x = 300, .y = 500 }; ctx.get(panel2).style.backgroundColor = ui.ModernStyle.GreyDark; ctx.getPanel(panel2).titleColor = ui.ModernStyle.GreyDark; + ctx.getPanel(panel2).layoutMode = .Vertical; // add some text to this panel - const text = try ctx.addText(panel2, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."); + const text = try ctx.addText(panel2, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); ctx.get(text).pos = .{ .x = 2, .y = 2 }; - ctx.get(text).size = ctx.get(panel2).size.sub(.{ .x = 4, .y = 36 }); + ctx.get(text).size = .{ .x = 296, .y = 300 }; + + const btn = try ctx.addButton(panel2, "select file..."); + _ = btn; } }