Remove refCounting from CaveBiomeMapFragment

This commit is contained in:
IntegratedQuantum 2025-07-26 17:37:25 +02:00
parent b5f255c9a2
commit 949900f518
9 changed files with 46 additions and 58 deletions

View File

@ -659,8 +659,8 @@ pub fn main() void { // MARK: main()
gui.openWindow("main"); gui.openWindow("main");
} }
server.terrain.initGenerators(); server.terrain.globalInit();
defer server.terrain.deinitGenerators(); defer server.terrain.globalDeinit();
const c = Window.c; const c = Window.c;

View File

@ -676,7 +676,6 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh
sortingOutputBuffer: []FaceData = &.{}, sortingOutputBuffer: []FaceData = &.{},
culledSortingCount: u31 = 0, culledSortingCount: u31 = 0,
lastTransparentUpdatePos: Vec3i = Vec3i{0, 0, 0}, lastTransparentUpdatePos: Vec3i = Vec3i{0, 0, 0},
refCount: std.atomic.Value(u32) = .init(1),
needsLightRefresh: std.atomic.Value(bool) = .init(false), needsLightRefresh: std.atomic.Value(bool) = .init(false),
needsMeshUpdate: bool = false, needsMeshUpdate: bool = false,
finishedMeshing: bool = false, // Must be synced with node.finishedMeshing in mesh_storage.zig finishedMeshing: bool = false, // Must be synced with node.finishedMeshing in mesh_storage.zig

View File

@ -835,7 +835,6 @@ fn batchUpdateBlocks() void {
// MARK: adders // MARK: adders
pub fn addToUpdateList(mesh: *chunk_meshing.ChunkMesh) void { pub fn addToUpdateList(mesh: *chunk_meshing.ChunkMesh) void {
std.debug.assert(mesh.refCount.load(.monotonic) != 0);
mutex.lock(); mutex.lock();
defer mutex.unlock(); defer mutex.unlock();
if(mesh.finishedMeshing) { if(mesh.finishedMeshing) {

View File

@ -27,7 +27,6 @@ pub const CaveBiomeMapFragment = struct { // MARK: caveBiomeMapFragment
pos: main.chunk.ChunkPosition, pos: main.chunk.ChunkPosition,
biomeMap: [1 << 3*(caveBiomeMapShift - caveBiomeShift)][2]*const Biome = undefined, 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 { pub fn init(self: *CaveBiomeMapFragment, wx: i32, wy: i32, wz: i32) void {
self.* = .{ 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 rotationMatrixShift = 30;
const fac: comptime_int = @intFromFloat(@as(comptime_float, 1 << rotationMatrixShift)/25.0); const fac: comptime_int = @intFromFloat(@as(comptime_float, 1 << rotationMatrixShift)/25.0);
const rotationMatrix = .{ const rotationMatrix = .{
@ -82,19 +89,6 @@ pub const CaveBiomeMapFragment = struct { // MARK: caveBiomeMapFragment
relZ >>= caveBiomeShift; relZ >>= caveBiomeShift;
return relX << 2*(caveBiomeMapShift - caveBiomeShift) | relY << caveBiomeMapShift - caveBiomeShift | relZ; 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. /// A generator for the cave biome map.
@ -175,7 +169,7 @@ pub const InterpolatableCaveBiomeMapView = struct { // MARK: InterpolatableCaveB
for(0..caveBiomeFragmentWidth) |x| { for(0..caveBiomeFragmentWidth) |x| {
for(0..caveBiomeFragmentWidth) |y| { for(0..caveBiomeFragmentWidth) |y| {
for(0..caveBiomeFragmentWidth) |z| { 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)), startX +% CaveBiomeMapFragment.caveBiomeMapSize*@as(i32, @intCast(x)),
startY +% CaveBiomeMapFragment.caveBiomeMapSize*@as(i32, @intCast(y)), startY +% CaveBiomeMapFragment.caveBiomeMapSize*@as(i32, @intCast(y)),
startZ +% CaveBiomeMapFragment.caveBiomeMapSize*@as(i32, @intCast(z)), startZ +% CaveBiomeMapFragment.caveBiomeMapSize*@as(i32, @intCast(z)),
@ -187,9 +181,6 @@ pub const InterpolatableCaveBiomeMapView = struct { // MARK: InterpolatableCaveB
} }
pub fn deinit(self: InterpolatableCaveBiomeMapView) void { pub fn deinit(self: InterpolatableCaveBiomeMapView) void {
for(self.fragments.mem) |mapFragment| {
mapFragment.decreaseRefCount();
}
self.fragments.deinit(self.allocator); self.fragments.deinit(self.allocator);
for(self.surfaceFragments) |mapFragment| { for(self.surfaceFragments) |mapFragment| {
mapFragment.decreaseRefCount(); mapFragment.decreaseRefCount();
@ -523,31 +514,31 @@ pub const CaveBiomeMapView = struct { // MARK: CaveBiomeMapView
const cacheSize = 1 << 8; // Must be a power of 2! const cacheSize = 1 << 8; // Must be a power of 2!
const cacheMask = cacheSize - 1; const cacheMask = cacheSize - 1;
const associativity = 8; // 128 MiB 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 profile: TerrainGenerationProfile = undefined;
var memoryPool: main.heap.MemoryPool(CaveBiomeMapFragment) = undefined; var memoryPool: main.heap.MemoryPool(CaveBiomeMapFragment) = undefined;
pub fn initGenerators() void { pub fn globalInit() void {
const list = @import("cavebiomegen/_list.zig"); const list = @import("cavebiomegen/_list.zig");
inline for(@typeInfo(list).@"struct".decls) |decl| { inline for(@typeInfo(list).@"struct".decls) |decl| {
CaveBiomeGenerator.registerGenerator(@field(list, decl.name)); CaveBiomeGenerator.registerGenerator(@field(list, decl.name));
} }
memoryPool = .init(main.globalAllocator);
} }
pub fn deinitGenerators() void { pub fn globalDeinit() void {
CaveBiomeGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator); CaveBiomeGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator);
memoryPool.deinit();
} }
pub fn init(_profile: TerrainGenerationProfile) void { pub fn init(_profile: TerrainGenerationProfile) void {
profile = _profile; profile = _profile;
memoryPool = .init(main.globalAllocator);
} }
pub fn deinit() void { pub fn deinit() void {
cache.clear(); cache.clear();
memoryPool.deinit();
} }
fn cacheInit(pos: ChunkPosition) *CaveBiomeMapFragment { fn cacheInit(pos: ChunkPosition) *CaveBiomeMapFragment {
@ -556,11 +547,10 @@ fn cacheInit(pos: ChunkPosition) *CaveBiomeMapFragment {
for(profile.caveBiomeGenerators) |generator| { for(profile.caveBiomeGenerators) |generator| {
generator.generate(mapFragment, profile.seed ^ generator.generatorSeed); generator.generate(mapFragment, profile.seed ^ generator.generatorSeed);
} }
_ = @atomicRmw(u16, &mapFragment.refCount.raw, .Add, 1, .monotonic);
return mapFragment; 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 wx = _wx & ~@as(i32, CaveBiomeMapFragment.caveBiomeMapMask);
const wy = _wy & ~@as(i32, CaveBiomeMapFragment.caveBiomeMapMask); const wy = _wy & ~@as(i32, CaveBiomeMapFragment.caveBiomeMapMask);
const wz = _wz & ~@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, .wz = wz,
.voxelSize = CaveBiomeMapFragment.caveBiomeSize, .voxelSize = CaveBiomeMapFragment.caveBiomeSize,
}; };
const result = cache.findOrCreate(compare, cacheInit, CaveBiomeMapFragment.increaseRefCount); const result = cache.findOrCreate(compare, cacheInit, null);
return result; return result;
} }

View File

@ -304,25 +304,25 @@ fn cacheInit(pos: ChunkPosition) *CaveMapFragment {
return mapFragment; return mapFragment;
} }
pub fn initGenerators() void { pub fn globalInit() void {
const list = @import("cavegen/_list.zig"); const list = @import("cavegen/_list.zig");
inline for(@typeInfo(list).@"struct".decls) |decl| { inline for(@typeInfo(list).@"struct".decls) |decl| {
CaveGenerator.registerGenerator(@field(list, decl.name)); CaveGenerator.registerGenerator(@field(list, decl.name));
} }
memoryPool = .init(main.globalAllocator);
} }
pub fn deinitGenerators() void { pub fn globalDeinit() void {
CaveGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator); CaveGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator);
memoryPool.deinit();
} }
pub fn init(_profile: TerrainGenerationProfile) void { pub fn init(_profile: TerrainGenerationProfile) void {
profile = _profile; profile = _profile;
memoryPool = .init(main.globalAllocator);
} }
pub fn deinit() void { pub fn deinit() void {
cache.clear(); cache.clear();
memoryPool.deinit();
} }
fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32, wz: i32, voxelSize: u31) *CaveMapFragment { fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32, wz: i32, voxelSize: u31) *CaveMapFragment {

View File

@ -107,15 +107,17 @@ var profile: TerrainGenerationProfile = undefined;
var memoryPool: main.heap.MemoryPool(ClimateMapFragment) = undefined; var memoryPool: main.heap.MemoryPool(ClimateMapFragment) = undefined;
pub fn initGenerators() void { pub fn globalInit() void {
const list = @import("climategen/_list.zig"); const list = @import("climategen/_list.zig");
inline for(@typeInfo(list).@"struct".decls) |decl| { inline for(@typeInfo(list).@"struct".decls) |decl| {
ClimateMapGenerator.registerGenerator(@field(list, decl.name)); ClimateMapGenerator.registerGenerator(@field(list, decl.name));
} }
memoryPool = .init(main.globalAllocator);
} }
pub fn deinitGenerators() void { pub fn globalDeinit() void {
ClimateMapGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator); ClimateMapGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator);
memoryPool.deinit();
} }
fn cacheInit(pos: ClimateMapFragmentPosition) *ClimateMapFragment { fn cacheInit(pos: ClimateMapFragmentPosition) *ClimateMapFragment {
@ -128,12 +130,10 @@ fn cacheInit(pos: ClimateMapFragmentPosition) *ClimateMapFragment {
pub fn init(_profile: TerrainGenerationProfile) void { pub fn init(_profile: TerrainGenerationProfile) void {
profile = _profile; profile = _profile;
memoryPool = .init(main.globalAllocator);
} }
pub fn deinit() void { pub fn deinit() void {
cache.clear(); cache.clear();
memoryPool.deinit();
} }
pub fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32) *ClimateMapFragment { pub fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32) *ClimateMapFragment {

View File

@ -191,25 +191,25 @@ fn cacheInit(pos: ChunkPosition) *StructureMapFragment {
return mapFragment; return mapFragment;
} }
pub fn initGenerators() void { pub fn globalInit() void {
const list = @import("structuremapgen/_list.zig"); const list = @import("structuremapgen/_list.zig");
inline for(@typeInfo(list).@"struct".decls) |decl| { inline for(@typeInfo(list).@"struct".decls) |decl| {
StructureMapGenerator.registerGenerator(@field(list, decl.name)); StructureMapGenerator.registerGenerator(@field(list, decl.name));
} }
memoryPool = .init(main.globalAllocator);
} }
pub fn deinitGenerators() void { pub fn globalDeinit() void {
StructureMapGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator); StructureMapGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator);
memoryPool.deinit();
} }
pub fn init(_profile: TerrainGenerationProfile) void { pub fn init(_profile: TerrainGenerationProfile) void {
profile = _profile; profile = _profile;
memoryPool = .init(main.globalAllocator);
} }
pub fn deinit() void { pub fn deinit() void {
cache.clear(); cache.clear();
memoryPool.deinit();
} }
pub fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32, wz: i32, voxelSize: u31) *StructureMapFragment { pub fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32, wz: i32, voxelSize: u31) *StructureMapFragment {

View File

@ -259,15 +259,17 @@ var profile: TerrainGenerationProfile = undefined;
var memoryPool: main.heap.MemoryPool(MapFragment) = undefined; var memoryPool: main.heap.MemoryPool(MapFragment) = undefined;
pub fn initGenerators() void { pub fn globalInit() void {
const list = @import("mapgen/_list.zig"); const list = @import("mapgen/_list.zig");
inline for(@typeInfo(list).@"struct".decls) |decl| { inline for(@typeInfo(list).@"struct".decls) |decl| {
MapGenerator.registerGenerator(@field(list, decl.name)); MapGenerator.registerGenerator(@field(list, decl.name));
} }
memoryPool = .init(main.globalAllocator);
} }
pub fn deinitGenerators() void { pub fn globalDeinit() void {
MapGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator); MapGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator);
memoryPool.deinit();
} }
fn cacheInit(pos: MapFragmentPosition) *MapFragment { fn cacheInit(pos: MapFragmentPosition) *MapFragment {
@ -634,12 +636,10 @@ pub fn regenerateLOD(worldName: []const u8) !void { // MARK: regenerateLOD()
pub fn init(_profile: TerrainGenerationProfile) void { pub fn init(_profile: TerrainGenerationProfile) void {
profile = _profile; profile = _profile;
memoryPool = .init(main.globalAllocator);
} }
pub fn deinit() void { pub fn deinit() void {
cache.clear(); cache.clear();
memoryPool.deinit();
} }
/// Call deinit on the result. /// Call deinit on the result.

View File

@ -133,12 +133,12 @@ pub const TerrainGenerationProfile = struct {
} }
}; };
pub fn initGenerators() void { pub fn globalInit() void {
SurfaceMap.initGenerators(); SurfaceMap.globalInit();
ClimateMap.initGenerators(); ClimateMap.globalInit();
CaveBiomeMap.initGenerators(); CaveBiomeMap.globalInit();
CaveMap.initGenerators(); CaveMap.globalInit();
StructureMap.initGenerators(); StructureMap.globalInit();
const list = @import("chunkgen/_list.zig"); const list = @import("chunkgen/_list.zig");
inline for(@typeInfo(list).@"struct".decls) |decl| { inline for(@typeInfo(list).@"struct".decls) |decl| {
BlockGenerator.registerGenerator(@field(list, decl.name)); 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}); std.log.info("Blue noise took {} ms to load", .{std.time.milliTimestamp() -% t1});
} }
pub fn deinitGenerators() void { pub fn globalDeinit() void {
SurfaceMap.deinitGenerators(); CaveBiomeMap.globalDeinit();
ClimateMap.deinitGenerators(); CaveMap.globalDeinit();
CaveBiomeMap.deinitGenerators(); StructureMap.globalDeinit();
CaveMap.deinitGenerators(); ClimateMap.globalDeinit();
StructureMap.deinitGenerators(); SurfaceMap.globalDeinit();
BlockGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator); BlockGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator);
} }