9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-21 07:49:18 +00:00

backport 1.21.5 features (final update)

This commit is contained in:
NONPLAYT
2025-04-27 01:42:02 +03:00
parent 2083c6fbe1
commit 59a30a282a
14 changed files with 590 additions and 24 deletions

View File

@@ -0,0 +1,33 @@
package gg.pufferfish.pufferfish.simd;
import org.slf4j.Logger;
import jdk.incubator.vector.FloatVector;
import jdk.incubator.vector.IntVector;
import jdk.incubator.vector.VectorSpecies;
@Deprecated
public class SIMDChecker {
public static boolean canEnable(Logger logger) {
try {
if (SIMDDetection.getJavaVersion() < 17) {
return false;
} else {
SIMDDetection.testRun = true;
VectorSpecies<Integer> ISPEC = IntVector.SPECIES_PREFERRED;
VectorSpecies<Float> FSPEC = FloatVector.SPECIES_PREFERRED;
logger.info("Max SIMD vector size on this system is {} bits (int)", ISPEC.vectorBitSize());
logger.info("Max SIMD vector size on this system is {} bits (float)", FSPEC.vectorBitSize());
if (ISPEC.elementSize() < 2 || FSPEC.elementSize() < 2) {
logger.warn("SIMD is not properly supported on this system!");
return false;
}
return true;
}
} catch (NoClassDefFoundError | Exception ignored) {} // Basically, we don't do anything. This lets us detect if it's not functional and disable it.
return false;
}
}

View File

@@ -0,0 +1,33 @@
package gg.pufferfish.pufferfish.simd;
import org.slf4j.Logger;
@Deprecated
public class SIMDDetection {
public static boolean isEnabled = false;
public static boolean versionLimited = false;
public static boolean testRun = false;
@Deprecated
public static boolean canEnable(Logger logger) {
try {
return SIMDChecker.canEnable(logger);
} catch (NoClassDefFoundError | Exception ignored) {
return false;
}
}
@Deprecated
public static int getJavaVersion() {
// https://stackoverflow.com/a/2591122
String version = System.getProperty("java.version");
if(version.startsWith("1.")) {
version = version.substring(2, 3);
} else {
int dot = version.indexOf(".");
if(dot != -1) { version = version.substring(0, dot); }
}
version = version.split("-")[0];
return Integer.parseInt(version);
}
}

View File

@@ -0,0 +1,82 @@
package gg.pufferfish.pufferfish.simd;
import java.awt.Color;
import jdk.incubator.vector.FloatVector;
import jdk.incubator.vector.IntVector;
import jdk.incubator.vector.VectorMask;
import jdk.incubator.vector.VectorSpecies;
import org.bukkit.map.MapPalette;
@Deprecated
public class VectorMapPalette {
private static final VectorSpecies<Integer> I_SPEC = IntVector.SPECIES_PREFERRED;
private static final VectorSpecies<Float> F_SPEC = FloatVector.SPECIES_PREFERRED;
@Deprecated
public static void matchColorVectorized(int[] in, byte[] out) {
int speciesLength = I_SPEC.length();
int i;
for (i = 0; i < in.length - speciesLength; i += speciesLength) {
float[] redsArr = new float[speciesLength];
float[] bluesArr = new float[speciesLength];
float[] greensArr = new float[speciesLength];
int[] alphasArr = new int[speciesLength];
for (int j = 0; j < speciesLength; j++) {
alphasArr[j] = (in[i + j] >> 24) & 0xFF;
redsArr[j] = (in[i + j] >> 16) & 0xFF;
greensArr[j] = (in[i + j] >> 8) & 0xFF;
bluesArr[j] = (in[i + j] >> 0) & 0xFF;
}
IntVector alphas = IntVector.fromArray(I_SPEC, alphasArr, 0);
FloatVector reds = FloatVector.fromArray(F_SPEC, redsArr, 0);
FloatVector greens = FloatVector.fromArray(F_SPEC, greensArr, 0);
FloatVector blues = FloatVector.fromArray(F_SPEC, bluesArr, 0);
IntVector resultIndex = IntVector.zero(I_SPEC);
VectorMask<Integer> modificationMask = VectorMask.fromLong(I_SPEC, 0xffffffff);
modificationMask = modificationMask.and(alphas.lt(128).not());
FloatVector bestDistances = FloatVector.broadcast(F_SPEC, Float.MAX_VALUE);
for (int c = 4; c < MapPalette.colors.length; c++) {
// We're using 32-bit floats here because it's 2x faster and nobody will know the difference.
// For correctness, the original algorithm uses 64-bit floats instead. Completely unnecessary.
FloatVector compReds = FloatVector.broadcast(F_SPEC, MapPalette.colors[c].getRed());
FloatVector compGreens = FloatVector.broadcast(F_SPEC, MapPalette.colors[c].getGreen());
FloatVector compBlues = FloatVector.broadcast(F_SPEC, MapPalette.colors[c].getBlue());
FloatVector rMean = reds.add(compReds).div(2.0f);
FloatVector rDiff = reds.sub(compReds);
FloatVector gDiff = greens.sub(compGreens);
FloatVector bDiff = blues.sub(compBlues);
FloatVector weightR = rMean.div(256.0f).add(2);
FloatVector weightG = FloatVector.broadcast(F_SPEC, 4.0f);
FloatVector weightB = FloatVector.broadcast(F_SPEC, 255.0f).sub(rMean).div(256.0f).add(2.0f);
FloatVector distance = weightR.mul(rDiff).mul(rDiff).add(weightG.mul(gDiff).mul(gDiff)).add(weightB.mul(bDiff).mul(bDiff));
// Now we compare to the best distance we've found.
// This mask contains a "1" if better, and a "0" otherwise.
VectorMask<Float> bestDistanceMask = distance.lt(bestDistances);
bestDistances = bestDistances.blend(distance, bestDistanceMask); // Update the best distances
// Update the result array
// We also AND with the modification mask because we don't want to interfere if the alpha value isn't large enough.
resultIndex = resultIndex.blend(c, bestDistanceMask.cast(I_SPEC).and(modificationMask)); // Update the results
}
for (int j = 0; j < speciesLength; j++) {
int index = resultIndex.lane(j);
out[i + j] = (byte) (index < 128 ? index : -129 + (index - 127));
}
}
// For the final ones, fall back to the regular method
for (; i < in.length; i++) {
//noinspection removal
out[i] = MapPalette.matchColor(new Color(in[i], true));
}
}
}