Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import me.cortex.voxy.commonImpl.VoxyCommon;
import org.lwjgl.system.MemoryUtil;

import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.util.Arrays;


Expand Down Expand Up @@ -213,7 +215,7 @@ private static long packPartialQuadData(int modelId, long state, long metadata)
return quadData;
}

private int prepareSectionData(final long[] rawSectionData) {
private int prepareSectionData(final MemorySegment rawSectionData) {
final var sectionData = this.sectionData;
final var rawModelIds = this.modelMan._unsafeRawAccess();
long opaque = 0;
Expand All @@ -225,7 +227,7 @@ private int prepareSectionData(final long[] rawSectionData) {
int i = 0;
for (int q = 0; q < 512; q++) {
for (int j = 0; j < 64; i++, j++) {
long block = rawSectionData[i];//Get the block mapping
long block = rawSectionData.getAtIndex(ValueLayout.JAVA_LONG, i);//Get the block mapping
if (Mapper.isAir(block)) {//If it is air, just emit lighting
sectionData[i * 2] = (block & (0xFFL << 56)) >>> 1;
sectionData[i * 2 + 1] = 0;
Expand Down Expand Up @@ -297,7 +299,8 @@ private void acquireNeighborData(WorldSection section, int msk) {
//Note this is not thread safe! (but eh, fk it)
var raw = sec._unsafeGetRawDataArray();
for (int i = 0; i < 32*32; i++) {
this.neighboringFaces[i] = raw[(i<<5)+31];//pull the +x faces from the section
//pull the +x faces from the section
this.neighboringFaces[i] = raw.getAtIndex(ValueLayout.JAVA_LONG, (i<<5)+31);
}
sec.release(WorldSection.RELEASE_HINT_POSSIBLE_REUSE);
}
Expand All @@ -306,7 +309,8 @@ private void acquireNeighborData(WorldSection section, int msk) {
//Note this is not thread safe! (but eh, fk it)
var raw = sec._unsafeGetRawDataArray();
for (int i = 0; i < 32*32; i++) {
this.neighboringFaces[i+32*32] = raw[(i<<5)];//pull the -x faces from the section
//pull the -x faces from the section
this.neighboringFaces[i+32*32] = raw.getAtIndex(ValueLayout.JAVA_LONG, (i<<5));
}
sec.release(WorldSection.RELEASE_HINT_POSSIBLE_REUSE);
}
Expand All @@ -316,7 +320,8 @@ private void acquireNeighborData(WorldSection section, int msk) {
//Note this is not thread safe! (but eh, fk it)
var raw = sec._unsafeGetRawDataArray();
for (int i = 0; i < 32*32; i++) {
this.neighboringFaces[i+32*32*2] = raw[i|(0x1F<<10)];//pull the +y faces from the section
//pull the +y faces from the section
this.neighboringFaces[i+32*32*2] = raw.getAtIndex(ValueLayout.JAVA_LONG, i|(0x1F<<10));
}
sec.release(WorldSection.RELEASE_HINT_POSSIBLE_REUSE);
}
Expand All @@ -325,7 +330,8 @@ private void acquireNeighborData(WorldSection section, int msk) {
//Note this is not thread safe! (but eh, fk it)
var raw = sec._unsafeGetRawDataArray();
for (int i = 0; i < 32*32; i++) {
this.neighboringFaces[i+32*32*3] = raw[i];//pull the -y faces from the section
//pull the -y faces from the section
this.neighboringFaces[i+32*32*3] = raw.getAtIndex(ValueLayout.JAVA_LONG, i);
}
sec.release(WorldSection.RELEASE_HINT_POSSIBLE_REUSE);
}
Expand All @@ -335,7 +341,8 @@ private void acquireNeighborData(WorldSection section, int msk) {
//Note this is not thread safe! (but eh, fk it)
var raw = sec._unsafeGetRawDataArray();
for (int i = 0; i < 32*32; i++) {
this.neighboringFaces[i+32*32*4] = raw[Integer.expand(i,0b11111_00000_11111)|(0x1F<<5)];//pull the +z faces from the section
//pull the +z faces from the section
this.neighboringFaces[i+32*32*4] = raw.getAtIndex(ValueLayout.JAVA_LONG, Integer.expand(i,0b11111_00000_11111)|(0x1F<<5));
}
sec.release(WorldSection.RELEASE_HINT_POSSIBLE_REUSE);
}
Expand All @@ -344,7 +351,8 @@ private void acquireNeighborData(WorldSection section, int msk) {
//Note this is not thread safe! (but eh, fk it)
var raw = sec._unsafeGetRawDataArray();
for (int i = 0; i < 32*32; i++) {
this.neighboringFaces[i+32*32*5] = raw[Integer.expand(i,0b11111_00000_11111)];//pull the -z faces from the section
//pull the -z faces from the section
this.neighboringFaces[i+32*32*5] = raw.getAtIndex(ValueLayout.JAVA_LONG, Integer.expand(i,0b11111_00000_11111));
}
sec.release(WorldSection.RELEASE_HINT_POSSIBLE_REUSE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import me.cortex.voxy.common.world.WorldSection;
import me.cortex.voxy.common.world.other.Mapper;

import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.util.List;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
Expand Down Expand Up @@ -107,7 +109,12 @@ private void computeAndRequestRequiredModels(IntOpenHashSet seenMissedIds, int b
private void computeAndRequestRequiredModels(IntOpenHashSet seenMissedIds, WorldSection section) {
//Know this is... very much not safe, however it reduces allocation rates and other garbage, am sure its "fine"
final var factory = this.modelBakery.factory;
for (long state : section._unsafeGetRawDataArray()) {

MemorySegment data = section._unsafeGetRawDataArray();
int dataLength = section._unsafeGetRawDataArrayLength();

for (int i = 0; i < dataLength; i++) {
long state = data.getAtIndex(ValueLayout.JAVA_LONG, i);
int block = Mapper.getBlockId(state);
if (block != 0 && !factory.hasModelForBlockId(block)) {
if (seenMissedIds.add(block)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
import me.cortex.voxy.common.world.WorldSection;
import me.cortex.voxy.common.world.other.Mapper;

import java.lang.foreign.ValueLayout;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.function.LongConsumer;

public class SectionSerializationStorage extends SectionStorage {
Expand All @@ -30,7 +30,9 @@ public int loadSection(WorldSection into) {
if (!SaveLoadSystem3.deserialize(into, data)) {
this.backend.deleteSectionData(into.key);
//TODO: regenerate the section from children
Arrays.fill(into._unsafeGetRawDataArray(), Mapper.AIR);
for (int i = 0; i < into._unsafeGetRawDataArrayLength(); i++) {
into._unsafeGetRawDataArray().setAtIndex(ValueLayout.JAVA_LONG, i, Mapper.AIR);
}
Logger.error("Section " + into.lvl + ", " + into.x + ", " + into.y + ", " + into.z + " was unable to load, removing");
return -1;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import me.cortex.voxy.common.world.other.Mapper;
import org.jetbrains.annotations.Nullable;

import java.lang.foreign.ValueLayout;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.StampedLock;

Expand Down Expand Up @@ -66,10 +66,18 @@ public ActiveSectionTracker(int numSlicesBits, SectionLoader loader, int cacheSi
}

public WorldSection acquire(int lvl, int x, int y, int z, boolean nullOnEmpty) {
return this.acquire(WorldEngine.getWorldSectionId(lvl, x, y, z), nullOnEmpty);
return this.acquire(lvl, x, y, z, nullOnEmpty, WorldSection.DEFAULT_ALLOCATOR);
}

public WorldSection acquire(int lvl, int x, int y, int z, boolean nullOnEmpty, WorldSection.Allocator allocator) {
return this.acquire(WorldEngine.getWorldSectionId(lvl, x, y, z), nullOnEmpty, allocator);
}

public WorldSection acquire(long key, boolean nullOnEmpty) {
return this.acquire(key, nullOnEmpty, WorldSection.DEFAULT_ALLOCATOR);
}

public WorldSection acquire(long key, boolean nullOnEmpty, WorldSection.Allocator allocator) {
//TODO: add optional verification check to ensure this (or other critical systems) arnt being called on the render or server thread
if (this.engine != null) this.engine.lastActiveTime = System.currentTimeMillis();
int index = this.getCacheArrayIndex(key);
Expand Down Expand Up @@ -142,7 +150,7 @@ public WorldSection acquire(long key, boolean nullOnEmpty) {
WorldEngine.getX(key),
WorldEngine.getY(key),
WorldEngine.getZ(key),
this);
this, allocator);

status = this.loader.load(section);

Expand All @@ -158,7 +166,12 @@ public WorldSection acquire(long key, boolean nullOnEmpty) {
//We need to set the data to air as it is undefined state
int sky = 15;
int block = 0;
Arrays.fill(section.data, Mapper.composeMappingId((byte) (sky|(block<<4)),0,0));

long id = Mapper.composeMappingId((byte) (sky|(block<<4)),0,0);

for (int i = 0; i < section.dataLength; i++) {
section.data.setAtIndex(ValueLayout.JAVA_LONG, i, id);
}
}
section.acquire(1);
}
Expand Down
15 changes: 11 additions & 4 deletions src/main/java/me/cortex/voxy/common/world/SaveLoadSystem3.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import me.cortex.voxy.common.world.other.Mapper;
import org.lwjgl.system.MemoryUtil;

import java.lang.foreign.ValueLayout;

public class SaveLoadSystem3 {
public static final int STORAGE_VERSION = 0;

Expand Down Expand Up @@ -38,6 +40,7 @@ public static int z2lin(int i) {
public static MemoryBuffer serialize(WorldSection section) {
var cache = CACHE.get();
var data = section.data;
var dataLength = section.dataLength;

Long2ShortOpenHashMap LUT = cache.lutMapCache; LUT.clear();

Expand All @@ -48,9 +51,10 @@ public static MemoryBuffer serialize(WorldSection section) {
long metadataPtr = ptr; ptr += 8;

long blockPtr = ptr; ptr += WorldSection.SECTION_VOLUME*2;
long prev = data[0]; MemoryUtil.memPutLong(ptr, prev); ptr+=8; LUT.put(prev, (short) 0);
long prev = data.getAtIndex(ValueLayout.JAVA_LONG, 0); MemoryUtil.memPutLong(ptr, prev); ptr+=8; LUT.put(prev, (short) 0);
short mapping = 0;
for (long block : data) {
for (int i = 0; i < dataLength; i++) {
long block = data.getAtIndex(ValueLayout.JAVA_LONG, i);
if (prev != block) {
prev = block;
mapping = LUT.putIfAbsent(block, (short) LUT.size());
Expand Down Expand Up @@ -92,13 +96,16 @@ public static boolean deserialize(WorldSection section, MemoryBuffer data) {
final long lutBasePtr = ptr + WorldSection.SECTION_VOLUME * 2;

final var blockData = section.data;
final var blockDataLength = section.dataLength;
for (int i = 0; i < WorldSection.SECTION_VOLUME; i++) {
blockData[i] = MemoryUtil.memGetLong(lutBasePtr + Short.toUnsignedLong(MemoryUtil.memGetShort(ptr)) * 8L);ptr += 2;
blockData.setAtIndex(ValueLayout.JAVA_LONG, i, MemoryUtil.memGetLong(lutBasePtr + Short.toUnsignedLong(MemoryUtil.memGetShort(ptr)) * 8L));
ptr += 2;
}

if (section.lvl == 0) {
int emptyBlockCount = 0;
for (long block : blockData) {
for (int i = 0; i < blockDataLength; i++) {
long block = blockData.getAtIndex(ValueLayout.JAVA_LONG, i);
emptyBlockCount += Mapper.isAir(block) ? 1 : 0;
}
section.nonEmptyBlockCount = WorldSection.SECTION_VOLUME-emptyBlockCount;
Expand Down
Loading
Loading