mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 11:17:05 -04:00
Merge branch 'master' into toadstool-mushroom-caves
This commit is contained in:
commit
d572521204
@ -1215,7 +1215,6 @@ pub const Protocols = struct {
|
||||
var ligthMapReader = utils.BinaryReader.init(_inflatedData);
|
||||
const map = main.globalAllocator.create(main.server.terrain.LightMap.LightMapFragment);
|
||||
map.init(pos.wx, pos.wy, pos.voxelSize);
|
||||
_ = map.refCount.fetchAdd(1, .monotonic);
|
||||
for(&map.startHeight) |*val| {
|
||||
val.* = try ligthMapReader.readInt(i16);
|
||||
}
|
||||
|
@ -807,8 +807,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh
|
||||
var allSun: bool = self.chunk.data.paletteLength == 1 and self.chunk.data.palette[0].typ == 0;
|
||||
var sunStarters: [chunk.chunkSize*chunk.chunkSize][3]u8 = undefined;
|
||||
var index: usize = 0;
|
||||
const lightStartMap = mesh_storage.getLightMapPieceAndIncreaseRefCount(self.pos.wx, self.pos.wy, self.pos.voxelSize) orelse break :sunLight;
|
||||
defer lightStartMap.decreaseRefCount();
|
||||
const lightStartMap = mesh_storage.getLightMapPiece(self.pos.wx, self.pos.wy, self.pos.voxelSize) orelse break :sunLight;
|
||||
x = 0;
|
||||
while(x < chunk.chunkSize) : (x += 1) {
|
||||
var y: u8 = 0;
|
||||
|
@ -33,7 +33,7 @@ const ChunkMeshNode = struct {
|
||||
const storageSize = 64;
|
||||
const storageMask = storageSize - 1;
|
||||
var storageLists: [settings.highestSupportedLod + 1]*[storageSize*storageSize*storageSize]ChunkMeshNode = undefined;
|
||||
var mapStorageLists: [settings.highestSupportedLod + 1]*[storageSize*storageSize]?*LightMap.LightMapFragment = undefined;
|
||||
var mapStorageLists: [settings.highestSupportedLod + 1]*[storageSize*storageSize]Atomic(?*LightMap.LightMapFragment) = undefined;
|
||||
var meshList = main.List(*chunk_meshing.ChunkMesh).init(main.globalAllocator);
|
||||
var priorityMeshUpdateList: main.utils.ConcurrentQueue(chunk.ChunkPosition) = undefined;
|
||||
pub var updatableList = main.List(chunk.ChunkPosition).init(main.globalAllocator);
|
||||
@ -85,8 +85,8 @@ pub fn init() void { // MARK: init()
|
||||
}
|
||||
}
|
||||
for(&mapStorageLists) |*mapStorageList| {
|
||||
mapStorageList.* = main.globalAllocator.create([storageSize*storageSize]?*LightMap.LightMapFragment);
|
||||
@memset(mapStorageList.*, null);
|
||||
mapStorageList.* = main.globalAllocator.create([storageSize*storageSize]Atomic(?*LightMap.LightMapFragment));
|
||||
@memset(mapStorageList.*, .init(null));
|
||||
}
|
||||
priorityMeshUpdateList = .init(main.globalAllocator, 16);
|
||||
mapUpdatableList = .init(main.globalAllocator, 16);
|
||||
@ -102,7 +102,6 @@ pub fn deinit() void {
|
||||
lastPz = 0;
|
||||
lastRD = 0;
|
||||
freeOldMeshes(olderPx, olderPy, olderPz, olderRD);
|
||||
main.heap.GarbageCollection.waitForFreeCompletion();
|
||||
for(storageLists) |storageList| {
|
||||
main.globalAllocator.destroy(storageList);
|
||||
}
|
||||
@ -112,7 +111,7 @@ pub fn deinit() void {
|
||||
|
||||
updatableList.clearAndFree();
|
||||
while(mapUpdatableList.dequeue()) |map| {
|
||||
map.decreaseRefCount();
|
||||
map.deferredDeinit();
|
||||
}
|
||||
mapUpdatableList.deinit();
|
||||
priorityMeshUpdateList.deinit();
|
||||
@ -121,6 +120,7 @@ pub fn deinit() void {
|
||||
}
|
||||
blockUpdateList.deinit();
|
||||
meshList.clearAndFree();
|
||||
main.heap.GarbageCollection.waitForFreeCompletion();
|
||||
meshMemoryPool.deinit();
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ fn updateHigherLodNodeFinishedMeshing(pos_: chunk.ChunkPosition, finishedMeshing
|
||||
}
|
||||
}
|
||||
|
||||
fn getMapPiecePointer(x: i32, y: i32, voxelSize: u31) *?*LightMap.LightMapFragment {
|
||||
fn getMapPiecePointer(x: i32, y: i32, voxelSize: u31) *Atomic(?*LightMap.LightMapFragment) {
|
||||
const lod = std.math.log2_int(u31, voxelSize);
|
||||
var xIndex = x >> lod + LightMap.LightMapFragment.mapShift;
|
||||
var yIndex = y >> lod + LightMap.LightMapFragment.mapShift;
|
||||
@ -169,14 +169,8 @@ fn getMapPiecePointer(x: i32, y: i32, voxelSize: u31) *?*LightMap.LightMapFragme
|
||||
return &(&mapStorageLists)[lod][@intCast(index)];
|
||||
}
|
||||
|
||||
pub fn getLightMapPieceAndIncreaseRefCount(x: i32, y: i32, voxelSize: u31) ?*LightMap.LightMapFragment {
|
||||
mutex.lock();
|
||||
defer mutex.unlock();
|
||||
const result: *LightMap.LightMapFragment = getMapPiecePointer(x, y, voxelSize).* orelse {
|
||||
return null;
|
||||
};
|
||||
result.increaseRefCount();
|
||||
return result;
|
||||
pub fn getLightMapPiece(x: i32, y: i32, voxelSize: u31) ?*LightMap.LightMapFragment {
|
||||
return getMapPiecePointer(x, y, voxelSize).load(.acquire);
|
||||
}
|
||||
|
||||
pub fn getBlockFromRenderThread(x: i32, y: i32, z: i32) ?blocks.Block {
|
||||
@ -437,13 +431,9 @@ fn freeOldMeshes(olderPx: i32, olderPy: i32, olderPz: i32, olderRD: u16) void {
|
||||
const yIndex = @divExact(y, size) & storageMask;
|
||||
const index = xIndex*storageSize + yIndex;
|
||||
|
||||
const mapPointer = &mapStorageLists[_lod][@intCast(index)];
|
||||
mutex.lock();
|
||||
const oldMap = mapPointer.*;
|
||||
mapPointer.* = null;
|
||||
mutex.unlock();
|
||||
const oldMap = mapStorageLists[_lod][@intCast(index)].swap(null, .monotonic);
|
||||
if(oldMap) |map| {
|
||||
map.decreaseRefCount();
|
||||
map.deferredDeinit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -576,14 +566,12 @@ fn createNewMeshes(olderPx: i32, olderPy: i32, olderPz: i32, olderRD: u16, meshR
|
||||
const index = xIndex*storageSize + yIndex;
|
||||
const pos = LightMap.MapFragmentPosition{.wx = x, .wy = y, .voxelSize = @as(u31, 1) << lod, .voxelSizeShift = lod};
|
||||
|
||||
const node = &mapStorageLists[_lod][@intCast(index)];
|
||||
mutex.lock();
|
||||
if(node.*) |map| {
|
||||
std.debug.assert(std.meta.eql(pos, map.pos));
|
||||
const map = mapStorageLists[_lod][@intCast(index)].load(.unordered);
|
||||
if(map) |_map| {
|
||||
std.debug.assert(std.meta.eql(pos, _map.pos));
|
||||
} else {
|
||||
mapRequests.append(pos);
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -770,13 +758,12 @@ pub fn updateMeshes(targetTime: i64) void { // MARK: updateMeshes()=
|
||||
}
|
||||
while(mapUpdatableList.dequeue()) |map| {
|
||||
if(!isMapInRenderDistance(map.pos)) {
|
||||
map.decreaseRefCount();
|
||||
map.deferredDeinit();
|
||||
} else {
|
||||
const mapPointer = getMapPiecePointer(map.pos.wx, map.pos.wy, map.pos.voxelSize);
|
||||
if(mapPointer.*) |old| {
|
||||
old.decreaseRefCount();
|
||||
const mapPointer = getMapPiecePointer(map.pos.wx, map.pos.wy, map.pos.voxelSize).swap(map, .release);
|
||||
if(mapPointer) |old| {
|
||||
old.deferredDeinit();
|
||||
}
|
||||
mapPointer.* = map;
|
||||
}
|
||||
}
|
||||
while(updatableList.items.len != 0) {
|
||||
|
@ -20,25 +20,18 @@ pub const LightMapFragment = struct {
|
||||
startHeight: [mapSize*mapSize]i16 = undefined,
|
||||
pos: MapFragmentPosition,
|
||||
|
||||
refCount: Atomic(u16) = .init(0),
|
||||
|
||||
pub fn init(self: *LightMapFragment, wx: i32, wy: i32, voxelSize: u31) void {
|
||||
self.* = .{
|
||||
.pos = MapFragmentPosition.init(wx, wy, voxelSize),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn increaseRefCount(self: *LightMapFragment) void {
|
||||
const prevVal = self.refCount.fetchAdd(1, .monotonic);
|
||||
std.debug.assert(prevVal != 0);
|
||||
fn deinit(self: *const LightMapFragment, _: usize) void {
|
||||
main.globalAllocator.destroy(self);
|
||||
}
|
||||
|
||||
pub fn decreaseRefCount(self: *LightMapFragment) void {
|
||||
const prevVal = self.refCount.fetchSub(1, .monotonic);
|
||||
std.debug.assert(prevVal != 0);
|
||||
if(prevVal == 1) {
|
||||
main.globalAllocator.destroy(self);
|
||||
}
|
||||
pub fn deferredDeinit(self: *LightMapFragment) void {
|
||||
main.heap.GarbageCollection.deferredFree(.{.ptr = self, .freeFunction = main.utils.castFunctionSelfToAnyopaque(LightMapFragment.deinit)});
|
||||
}
|
||||
|
||||
pub fn getHeight(self: *LightMapFragment, wx: i32, wy: i32) i32 {
|
||||
@ -51,7 +44,7 @@ pub const LightMapFragment = struct {
|
||||
const cacheSize = 1 << 6; // Must be a power of 2!
|
||||
const cacheMask = cacheSize - 1;
|
||||
const associativity = 8; // 64MiB MiB Cache size
|
||||
var cache: Cache(LightMapFragment, cacheSize, associativity, LightMapFragment.decreaseRefCount) = .{};
|
||||
var cache: Cache(LightMapFragment, cacheSize, associativity, LightMapFragment.deferredDeinit) = .{};
|
||||
|
||||
fn cacheInit(pos: MapFragmentPosition) *LightMapFragment {
|
||||
const mapFragment = main.globalAllocator.create(LightMapFragment);
|
||||
@ -65,7 +58,6 @@ fn cacheInit(pos: MapFragmentPosition) *LightMapFragment {
|
||||
mapFragment.startHeight[x << LightMapFragment.mapShift | y] = @max(0, baseHeight +| 16); // Simple heuristic. TODO: Update this value once chunks get generated in the region.
|
||||
}
|
||||
}
|
||||
_ = @atomicRmw(u16, &mapFragment.refCount.raw, .Add, 1, .monotonic);
|
||||
return mapFragment;
|
||||
}
|
||||
|
||||
@ -73,12 +65,12 @@ pub fn deinit() void {
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
pub fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32, voxelSize: u31) *LightMapFragment {
|
||||
pub fn getOrGenerateFragment(wx: i32, wy: i32, voxelSize: u31) *LightMapFragment {
|
||||
const compare = MapFragmentPosition.init(
|
||||
wx & ~@as(i32, LightMapFragment.mapMask*voxelSize | voxelSize - 1),
|
||||
wy & ~@as(i32, LightMapFragment.mapMask*voxelSize | voxelSize - 1),
|
||||
voxelSize,
|
||||
);
|
||||
const result = cache.findOrCreate(compare, cacheInit, LightMapFragment.increaseRefCount);
|
||||
const result = cache.findOrCreate(compare, cacheInit, null);
|
||||
return result;
|
||||
}
|
||||
|
@ -226,8 +226,7 @@ const ChunkManager = struct { // MARK: ChunkManager
|
||||
|
||||
pub fn run(self: *LightMapLoadTask) void {
|
||||
defer self.clean();
|
||||
const map = terrain.LightMap.getOrGenerateFragmentAndIncreaseRefCount(self.pos.wx, self.pos.wy, self.pos.voxelSize);
|
||||
defer map.decreaseRefCount();
|
||||
const map = terrain.LightMap.getOrGenerateFragment(self.pos.wx, self.pos.wy, self.pos.voxelSize);
|
||||
if(self.source) |source| {
|
||||
if(source.connected.load(.unordered)) main.network.Protocols.lightMapTransmission.sendLightMap(source.conn, map);
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user