Port biome palette and chunk section optimizations from Hydrogen
This commit is contained in:
parent
ad5fcf44e5
commit
6b28cb5ebc
|
|
@ -33,6 +33,8 @@ public class ModernFixEarlyConfig {
|
|||
this.addMixinRule("perf.sync_executor_sleep", true);
|
||||
this.addMixinRule("perf.scan_cache", true);
|
||||
this.addMixinRule("perf.parallel_blockstate_cache_rebuild", true);
|
||||
this.addMixinRule("perf.compress_biome_container", true);
|
||||
this.addMixinRule("perf.nuke_empty_chunk_sections", true);
|
||||
this.addMixinRule("perf.deduplicate_location", true);
|
||||
this.addMixinRule("safety", true);
|
||||
this.addMixinRule("launch.transformer_cache", false);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,148 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.compress_biome_container;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ShortMap;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ShortOpenHashMap;
|
||||
import net.minecraft.util.BitArray;
|
||||
import net.minecraft.util.IObjectIntIterable;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.BiomeContainer;
|
||||
import net.minecraft.world.biome.provider.BiomeProvider;
|
||||
import org.spongepowered.asm.mixin.*;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(BiomeContainer.class)
|
||||
public class MixinBiomeContainer {
|
||||
@Mutable
|
||||
@Shadow
|
||||
@Final
|
||||
private Biome[] biomes;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private IObjectIntIterable<Biome> biomeRegistry;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private static int WIDTH_BITS;
|
||||
|
||||
private Biome[] palette;
|
||||
private BitArray intArray;
|
||||
|
||||
@Inject(method = "<init>(Lnet/minecraft/util/IObjectIntIterable;[I)V", at = @At("RETURN"))
|
||||
private void reinit1(IObjectIntIterable p_i241970_1_, int[] p_i241970_2_, CallbackInfo ci) {
|
||||
this.createCompact();
|
||||
}
|
||||
|
||||
@Inject(method = "<init>(Lnet/minecraft/util/IObjectIntIterable;[Lnet/minecraft/world/biome/Biome;)V", at = @At("RETURN"))
|
||||
private void reinit2(IObjectIntIterable p_i241971_1_, Biome[] p_i241971_2_, CallbackInfo ci) {
|
||||
this.createCompact();
|
||||
}
|
||||
|
||||
@Inject(method = "<init>(Lnet/minecraft/util/IObjectIntIterable;Lnet/minecraft/util/math/ChunkPos;Lnet/minecraft/world/biome/provider/BiomeProvider;)V", at = @At("RETURN"))
|
||||
private void reinit3(IObjectIntIterable p_i241968_1_, ChunkPos p_i241968_2_, BiomeProvider p_i241968_3_, CallbackInfo ci) {
|
||||
this.createCompact();
|
||||
}
|
||||
|
||||
@Inject(method = "<init>(Lnet/minecraft/util/IObjectIntIterable;Lnet/minecraft/util/math/ChunkPos;Lnet/minecraft/world/biome/provider/BiomeProvider;[I)V", at = @At("RETURN"))
|
||||
private void reinit4(IObjectIntIterable p_i241969_1_, ChunkPos p_i241969_2_, BiomeProvider p_i241969_3_, int[] p_i241969_4_, CallbackInfo ci) {
|
||||
this.createCompact();
|
||||
}
|
||||
|
||||
private void createCompact() {
|
||||
if (this.intArray != null || this.biomes[0] == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference2ShortOpenHashMap<Biome> paletteTable = this.createPalette();
|
||||
Biome[] paletteIndexed = new Biome[paletteTable.size()];
|
||||
|
||||
for (Reference2ShortMap.Entry<Biome> entry : paletteTable.reference2ShortEntrySet()) {
|
||||
paletteIndexed[entry.getShortValue()] = entry.getKey();
|
||||
}
|
||||
|
||||
int packedIntSize = Math.max(2, MathHelper.ceillog2(paletteTable.size()));
|
||||
BitArray integerArray = new BitArray(packedIntSize, BiomeContainer.BIOMES_SIZE);
|
||||
|
||||
Biome prevBiome = null;
|
||||
short prevId = -1;
|
||||
|
||||
for (int i = 0; i < this.biomes.length; i++) {
|
||||
Biome biome = this.biomes[i];
|
||||
short id;
|
||||
|
||||
if (prevBiome == biome) {
|
||||
id = prevId;
|
||||
} else {
|
||||
id = paletteTable.getShort(biome);
|
||||
|
||||
if (id < 0) {
|
||||
throw new IllegalStateException("Palette is missing entry: " + biome);
|
||||
}
|
||||
|
||||
prevId = id;
|
||||
prevBiome = biome;
|
||||
}
|
||||
|
||||
integerArray.set(i, id);
|
||||
}
|
||||
|
||||
this.palette = paletteIndexed;
|
||||
this.intArray = integerArray;
|
||||
this.biomes = null;
|
||||
}
|
||||
|
||||
private Reference2ShortOpenHashMap<Biome> createPalette() {
|
||||
Reference2ShortOpenHashMap<Biome> map = new Reference2ShortOpenHashMap<>();
|
||||
map.defaultReturnValue(Short.MIN_VALUE);
|
||||
|
||||
Biome prevObj = null;
|
||||
short id = 0;
|
||||
|
||||
for (Biome obj : this.biomes) {
|
||||
if (obj == prevObj) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (map.getShort(obj) < 0) {
|
||||
map.put(obj, id++);
|
||||
}
|
||||
|
||||
prevObj = obj;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Use paletted lookup
|
||||
*/
|
||||
@Overwrite
|
||||
public int[] writeBiomes() {
|
||||
int size = this.intArray.getSize();
|
||||
int[] array = new int[size];
|
||||
|
||||
for(int i = 0; i < size; ++i) {
|
||||
array[i] = this.biomeRegistry.getId(this.palette[this.intArray.get(i)]);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author JellySquid
|
||||
* @reason Use paletted lookup
|
||||
*/
|
||||
@Overwrite
|
||||
public Biome getNoiseBiome(int biomeX, int biomeY, int biomeZ) {
|
||||
int x = biomeX & BiomeContainer.HORIZONTAL_MASK;
|
||||
int y = MathHelper.clamp(biomeY, 0, BiomeContainer.VERTICAL_MASK);
|
||||
int z = biomeZ & BiomeContainer.HORIZONTAL_MASK;
|
||||
|
||||
return this.palette[this.intArray.get(y << WIDTH_BITS + WIDTH_BITS | z << WIDTH_BITS | x)];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.nuke_empty_chunk_sections;
|
||||
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.palette.UpgradeData;
|
||||
import net.minecraft.world.ITickList;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.BiomeContainer;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.ChunkSection;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Mixin(Chunk.class)
|
||||
public class MixinChunk {
|
||||
@Shadow @Final private ChunkSection[] sections;
|
||||
|
||||
@Inject(method = "<init>(Lnet/minecraft/world/World;" +
|
||||
"Lnet/minecraft/util/math/ChunkPos;Lnet/minecraft/world/biome/BiomeContainer;" +
|
||||
"Lnet/minecraft/util/palette/UpgradeData;Lnet/minecraft/world/ITickList;" +
|
||||
"Lnet/minecraft/world/ITickList;J[Lnet/minecraft/world/chunk/ChunkSection;Ljava/util/function/Consumer;)V",
|
||||
at = @At("RETURN"))
|
||||
private void reinit(World world, ChunkPos pos, BiomeContainer container, UpgradeData data,
|
||||
ITickList list1, ITickList list2, long inhabited,
|
||||
ChunkSection[] oldSections, Consumer consumer, CallbackInfo ci) {
|
||||
/* taken from Hydrogen */
|
||||
for(int i = 0; i < this.sections.length; i++) {
|
||||
if(ChunkSection.isEmpty(this.sections[i])) {
|
||||
this.sections[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,9 @@
|
|||
"perf.parallel_blockstate_cache_rebuild.BlockCallbacksMixin",
|
||||
"perf.parallel_blockstate_cache_rebuild.ShapeCacheMixin",
|
||||
"perf.deduplicate_location.MixinResourceLocation",
|
||||
"perf.sync_executor_sleep.SyncExecutorMixin"
|
||||
"perf.sync_executor_sleep.SyncExecutorMixin",
|
||||
"perf.compress_biome_container.MixinBiomeContainer",
|
||||
"perf.nuke_empty_chunk_sections.MixinChunk"
|
||||
],
|
||||
"client": [
|
||||
"perf.skip_first_datapack_reload.MinecraftMixin",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user