From 949900f51896143328eaecc1c34d2a09f5f85ba1 Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Sat, 26 Jul 2025 17:37:25 +0200 Subject: [PATCH] Remove refCounting from CaveBiomeMapFragment --- src/main.zig | 4 +-- src/renderer/chunk_meshing.zig | 1 - src/renderer/mesh_storage.zig | 1 - src/server/terrain/CaveBiomeMap.zig | 42 +++++++++++------------------ src/server/terrain/CaveMap.zig | 8 +++--- src/server/terrain/ClimateMap.zig | 8 +++--- src/server/terrain/StructureMap.zig | 8 +++--- src/server/terrain/SurfaceMap.zig | 8 +++--- src/server/terrain/terrain.zig | 24 ++++++++--------- 9 files changed, 46 insertions(+), 58 deletions(-) diff --git a/src/main.zig b/src/main.zig index 0fe846c8..8700d778 100644 --- a/src/main.zig +++ b/src/main.zig @@ -659,8 +659,8 @@ pub fn main() void { // MARK: main() gui.openWindow("main"); } - server.terrain.initGenerators(); - defer server.terrain.deinitGenerators(); + server.terrain.globalInit(); + defer server.terrain.globalDeinit(); const c = Window.c; diff --git a/src/renderer/chunk_meshing.zig b/src/renderer/chunk_meshing.zig index 643016d9..c2bfdfd3 100644 --- a/src/renderer/chunk_meshing.zig +++ b/src/renderer/chunk_meshing.zig @@ -676,7 +676,6 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh sortingOutputBuffer: []FaceData = &.{}, culledSortingCount: u31 = 0, lastTransparentUpdatePos: Vec3i = Vec3i{0, 0, 0}, - refCount: std.atomic.Value(u32) = .init(1), needsLightRefresh: std.atomic.Value(bool) = .init(false), needsMeshUpdate: bool = false, finishedMeshing: bool = false, // Must be synced with node.finishedMeshing in mesh_storage.zig diff --git a/src/renderer/mesh_storage.zig b/src/renderer/mesh_storage.zig index 92d46a35..6dafd9d8 100644 --- a/src/renderer/mesh_storage.zig +++ b/src/renderer/mesh_storage.zig @@ -835,7 +835,6 @@ fn batchUpdateBlocks() void { // MARK: adders pub fn addToUpdateList(mesh: *chunk_meshing.ChunkMesh) void { - std.debug.assert(mesh.refCount.load(.monotonic) != 0); mutex.lock(); defer mutex.unlock(); if(mesh.finishedMeshing) { diff --git a/src/server/terrain/CaveBiomeMap.zig b/src/server/terrain/CaveBiomeMap.zig index 39021c28..733c6cf1 100644 --- a/src/server/terrain/CaveBiomeMap.zig +++ b/src/server/terrain/CaveBiomeMap.zig @@ -27,7 +27,6 @@ pub const CaveBiomeMapFragment = struct { // MARK: caveBiomeMapFragment pos: main.chunk.ChunkPosition, biomeMap: [1 << 3*(caveBiomeMapShift - caveBiomeShift)][2]*const Biome = undefined, - refCount: std.atomic.Value(u16) = .init(0), pub fn init(self: *CaveBiomeMapFragment, wx: i32, wy: i32, wz: i32) void { self.* = .{ @@ -40,6 +39,14 @@ pub const CaveBiomeMapFragment = struct { // MARK: caveBiomeMapFragment }; } + fn deinit(self: *CaveBiomeMapFragment, _: usize) void { + memoryPool.destroy(self); + } + + pub fn deferredDeinit(self: *CaveBiomeMapFragment) void { + main.heap.GarbageCollection.deferredFree(.{.ptr = self, .freeFunction = main.utils.castFunctionSelfToAnyopaque(CaveBiomeMapFragment.deinit)}); + } + const rotationMatrixShift = 30; const fac: comptime_int = @intFromFloat(@as(comptime_float, 1 << rotationMatrixShift)/25.0); const rotationMatrix = .{ @@ -82,19 +89,6 @@ pub const CaveBiomeMapFragment = struct { // MARK: caveBiomeMapFragment relZ >>= caveBiomeShift; return relX << 2*(caveBiomeMapShift - caveBiomeShift) | relY << caveBiomeMapShift - caveBiomeShift | relZ; } - - pub fn increaseRefCount(self: *CaveBiomeMapFragment) void { - const prevVal = self.refCount.fetchAdd(1, .monotonic); - std.debug.assert(prevVal != 0); - } - - pub fn decreaseRefCount(self: *CaveBiomeMapFragment) void { - const prevVal = self.refCount.fetchSub(1, .monotonic); - std.debug.assert(prevVal != 0); - if(prevVal == 1) { - memoryPool.destroy(self); - } - } }; /// A generator for the cave biome map. @@ -175,7 +169,7 @@ pub const InterpolatableCaveBiomeMapView = struct { // MARK: InterpolatableCaveB for(0..caveBiomeFragmentWidth) |x| { for(0..caveBiomeFragmentWidth) |y| { for(0..caveBiomeFragmentWidth) |z| { - result.fragments.set(x, y, z, getOrGenerateFragmentAndIncreaseRefCount( + result.fragments.set(x, y, z, getOrGenerateFragment( startX +% CaveBiomeMapFragment.caveBiomeMapSize*@as(i32, @intCast(x)), startY +% CaveBiomeMapFragment.caveBiomeMapSize*@as(i32, @intCast(y)), startZ +% CaveBiomeMapFragment.caveBiomeMapSize*@as(i32, @intCast(z)), @@ -187,9 +181,6 @@ pub const InterpolatableCaveBiomeMapView = struct { // MARK: InterpolatableCaveB } pub fn deinit(self: InterpolatableCaveBiomeMapView) void { - for(self.fragments.mem) |mapFragment| { - mapFragment.decreaseRefCount(); - } self.fragments.deinit(self.allocator); for(self.surfaceFragments) |mapFragment| { mapFragment.decreaseRefCount(); @@ -523,31 +514,31 @@ pub const CaveBiomeMapView = struct { // MARK: CaveBiomeMapView const cacheSize = 1 << 8; // Must be a power of 2! const cacheMask = cacheSize - 1; const associativity = 8; // 128 MiB -var cache: Cache(CaveBiomeMapFragment, cacheSize, associativity, CaveBiomeMapFragment.decreaseRefCount) = .{}; +var cache: Cache(CaveBiomeMapFragment, cacheSize, associativity, CaveBiomeMapFragment.deferredDeinit) = .{}; var profile: TerrainGenerationProfile = undefined; var memoryPool: main.heap.MemoryPool(CaveBiomeMapFragment) = undefined; -pub fn initGenerators() void { +pub fn globalInit() void { const list = @import("cavebiomegen/_list.zig"); inline for(@typeInfo(list).@"struct".decls) |decl| { CaveBiomeGenerator.registerGenerator(@field(list, decl.name)); } + memoryPool = .init(main.globalAllocator); } -pub fn deinitGenerators() void { +pub fn globalDeinit() void { CaveBiomeGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator); + memoryPool.deinit(); } pub fn init(_profile: TerrainGenerationProfile) void { profile = _profile; - memoryPool = .init(main.globalAllocator); } pub fn deinit() void { cache.clear(); - memoryPool.deinit(); } fn cacheInit(pos: ChunkPosition) *CaveBiomeMapFragment { @@ -556,11 +547,10 @@ fn cacheInit(pos: ChunkPosition) *CaveBiomeMapFragment { for(profile.caveBiomeGenerators) |generator| { generator.generate(mapFragment, profile.seed ^ generator.generatorSeed); } - _ = @atomicRmw(u16, &mapFragment.refCount.raw, .Add, 1, .monotonic); return mapFragment; } -fn getOrGenerateFragmentAndIncreaseRefCount(_wx: i32, _wy: i32, _wz: i32) *CaveBiomeMapFragment { +fn getOrGenerateFragment(_wx: i32, _wy: i32, _wz: i32) *CaveBiomeMapFragment { const wx = _wx & ~@as(i32, CaveBiomeMapFragment.caveBiomeMapMask); const wy = _wy & ~@as(i32, CaveBiomeMapFragment.caveBiomeMapMask); const wz = _wz & ~@as(i32, CaveBiomeMapFragment.caveBiomeMapMask); @@ -570,6 +560,6 @@ fn getOrGenerateFragmentAndIncreaseRefCount(_wx: i32, _wy: i32, _wz: i32) *CaveB .wz = wz, .voxelSize = CaveBiomeMapFragment.caveBiomeSize, }; - const result = cache.findOrCreate(compare, cacheInit, CaveBiomeMapFragment.increaseRefCount); + const result = cache.findOrCreate(compare, cacheInit, null); return result; } diff --git a/src/server/terrain/CaveMap.zig b/src/server/terrain/CaveMap.zig index 1322fc40..24c86f8d 100644 --- a/src/server/terrain/CaveMap.zig +++ b/src/server/terrain/CaveMap.zig @@ -304,25 +304,25 @@ fn cacheInit(pos: ChunkPosition) *CaveMapFragment { return mapFragment; } -pub fn initGenerators() void { +pub fn globalInit() void { const list = @import("cavegen/_list.zig"); inline for(@typeInfo(list).@"struct".decls) |decl| { CaveGenerator.registerGenerator(@field(list, decl.name)); } + memoryPool = .init(main.globalAllocator); } -pub fn deinitGenerators() void { +pub fn globalDeinit() void { CaveGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator); + memoryPool.deinit(); } pub fn init(_profile: TerrainGenerationProfile) void { profile = _profile; - memoryPool = .init(main.globalAllocator); } pub fn deinit() void { cache.clear(); - memoryPool.deinit(); } fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32, wz: i32, voxelSize: u31) *CaveMapFragment { diff --git a/src/server/terrain/ClimateMap.zig b/src/server/terrain/ClimateMap.zig index b4365bb4..6b9bcf86 100644 --- a/src/server/terrain/ClimateMap.zig +++ b/src/server/terrain/ClimateMap.zig @@ -107,15 +107,17 @@ var profile: TerrainGenerationProfile = undefined; var memoryPool: main.heap.MemoryPool(ClimateMapFragment) = undefined; -pub fn initGenerators() void { +pub fn globalInit() void { const list = @import("climategen/_list.zig"); inline for(@typeInfo(list).@"struct".decls) |decl| { ClimateMapGenerator.registerGenerator(@field(list, decl.name)); } + memoryPool = .init(main.globalAllocator); } -pub fn deinitGenerators() void { +pub fn globalDeinit() void { ClimateMapGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator); + memoryPool.deinit(); } fn cacheInit(pos: ClimateMapFragmentPosition) *ClimateMapFragment { @@ -128,12 +130,10 @@ fn cacheInit(pos: ClimateMapFragmentPosition) *ClimateMapFragment { pub fn init(_profile: TerrainGenerationProfile) void { profile = _profile; - memoryPool = .init(main.globalAllocator); } pub fn deinit() void { cache.clear(); - memoryPool.deinit(); } pub fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32) *ClimateMapFragment { diff --git a/src/server/terrain/StructureMap.zig b/src/server/terrain/StructureMap.zig index ce11e7f7..e26a139b 100644 --- a/src/server/terrain/StructureMap.zig +++ b/src/server/terrain/StructureMap.zig @@ -191,25 +191,25 @@ fn cacheInit(pos: ChunkPosition) *StructureMapFragment { return mapFragment; } -pub fn initGenerators() void { +pub fn globalInit() void { const list = @import("structuremapgen/_list.zig"); inline for(@typeInfo(list).@"struct".decls) |decl| { StructureMapGenerator.registerGenerator(@field(list, decl.name)); } + memoryPool = .init(main.globalAllocator); } -pub fn deinitGenerators() void { +pub fn globalDeinit() void { StructureMapGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator); + memoryPool.deinit(); } pub fn init(_profile: TerrainGenerationProfile) void { profile = _profile; - memoryPool = .init(main.globalAllocator); } pub fn deinit() void { cache.clear(); - memoryPool.deinit(); } pub fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32, wz: i32, voxelSize: u31) *StructureMapFragment { diff --git a/src/server/terrain/SurfaceMap.zig b/src/server/terrain/SurfaceMap.zig index 551bf04f..f7480c5b 100644 --- a/src/server/terrain/SurfaceMap.zig +++ b/src/server/terrain/SurfaceMap.zig @@ -259,15 +259,17 @@ var profile: TerrainGenerationProfile = undefined; var memoryPool: main.heap.MemoryPool(MapFragment) = undefined; -pub fn initGenerators() void { +pub fn globalInit() void { const list = @import("mapgen/_list.zig"); inline for(@typeInfo(list).@"struct".decls) |decl| { MapGenerator.registerGenerator(@field(list, decl.name)); } + memoryPool = .init(main.globalAllocator); } -pub fn deinitGenerators() void { +pub fn globalDeinit() void { MapGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator); + memoryPool.deinit(); } fn cacheInit(pos: MapFragmentPosition) *MapFragment { @@ -634,12 +636,10 @@ pub fn regenerateLOD(worldName: []const u8) !void { // MARK: regenerateLOD() pub fn init(_profile: TerrainGenerationProfile) void { profile = _profile; - memoryPool = .init(main.globalAllocator); } pub fn deinit() void { cache.clear(); - memoryPool.deinit(); } /// Call deinit on the result. diff --git a/src/server/terrain/terrain.zig b/src/server/terrain/terrain.zig index 0e277cf2..31ec8527 100644 --- a/src/server/terrain/terrain.zig +++ b/src/server/terrain/terrain.zig @@ -133,12 +133,12 @@ pub const TerrainGenerationProfile = struct { } }; -pub fn initGenerators() void { - SurfaceMap.initGenerators(); - ClimateMap.initGenerators(); - CaveBiomeMap.initGenerators(); - CaveMap.initGenerators(); - StructureMap.initGenerators(); +pub fn globalInit() void { + SurfaceMap.globalInit(); + ClimateMap.globalInit(); + CaveBiomeMap.globalInit(); + CaveMap.globalInit(); + StructureMap.globalInit(); const list = @import("chunkgen/_list.zig"); inline for(@typeInfo(list).@"struct".decls) |decl| { BlockGenerator.registerGenerator(@field(list, decl.name)); @@ -148,12 +148,12 @@ pub fn initGenerators() void { std.log.info("Blue noise took {} ms to load", .{std.time.milliTimestamp() -% t1}); } -pub fn deinitGenerators() void { - SurfaceMap.deinitGenerators(); - ClimateMap.deinitGenerators(); - CaveBiomeMap.deinitGenerators(); - CaveMap.deinitGenerators(); - StructureMap.deinitGenerators(); +pub fn globalDeinit() void { + CaveBiomeMap.globalDeinit(); + CaveMap.globalDeinit(); + StructureMap.globalDeinit(); + ClimateMap.globalDeinit(); + SurfaceMap.globalDeinit(); BlockGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator); }