9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-19 14:59:25 +00:00

rollback to java 21, move native math to other branch

This commit is contained in:
NONPLAYT
2025-03-23 02:40:37 +03:00
parent 35f1a407cb
commit f4e79b8427
28 changed files with 330 additions and 3125 deletions

View File

@@ -23,11 +23,11 @@ jobs:
generate-job-summary: false
cache-read-only: false
- name: Setup JDK 22
- name: Setup JDK 21
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 22
java-version: 21
- name: Configure Git and Gradle
run: |

View File

@@ -17,11 +17,11 @@ jobs:
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Setup JDK 22
- name: Setup JDK 21
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 22
java-version: 21
cache: 'gradle'
- name: Configure Git and Gradle

View File

@@ -15,13 +15,15 @@ DivineMC is a high-performance [Purpur](https://github.com/PurpurMC/Purpur) fork
> DivineMC is a performance-oriented fork. Make sure to take backups **before** switching to it. We also welcome a new contributor to help us improve the fork.
## ⚙️ Features
- **Based on [Purpur](https://github.com/PurpurMC/Purpur)** that adds a high customization level to the server.
- All worlds **are ticked in parallel**, so the server can take full advantage of multicore processors.
- **Implemented Secure Seed mod** that changes default 64-bit seed to a 1024-bit seed, making it almost impossible to crack the seed.
- **Native math functions** using a new Java 22 feature, calling C functions directly from Java.
- **Optimized chunk generation** that can generate chunks up to 70% faster than vanilla.
- **Async pathfinding and entity tracker**
- **Async** pathfinding, mob spawning and entity tracker
- Implemented **Linear region file format**
- **Fully compatible** with Bukkit, Spigot and Paper plugins
- **Fixes** some Minecraft bugs
- Integrated with [Sentry](https://sentry.io/welcome/) to easy track all errors coming from your server in excruciating detail (original by [Pufferfish](https://github.com/pufferfish-gg/Pufferfish))
- and more...
## 📥 Downloading & Installing

View File

@@ -43,7 +43,7 @@ allprojects {
java {
toolchain {
languageVersion = JavaLanguageVersion.of(22)
languageVersion = JavaLanguageVersion.of(21)
}
}
@@ -64,13 +64,13 @@ subprojects {
extensions.configure<JavaPluginExtension> {
toolchain {
languageVersion = JavaLanguageVersion.of(22)
languageVersion = JavaLanguageVersion.of(21)
}
}
tasks.withType<JavaCompile> {
options.encoding = Charsets.UTF_8.name()
options.release = 22
options.release = 21
options.isFork = true
}
tasks.withType<Javadoc> {

View File

@@ -18,7 +18,7 @@ index 394443d00e661715439be1e56dddc129947699a4..480ad57a6b7b74e6b83e9c6ceb69ea1f
public CrashReport(String title, Throwable exception) {
io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateThrowable(exception); // Paper
diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java
index 1485186d4989874ef89c4e83830f26358a43759c..680369af59fd2aa36bf1cf4e28b598854383abe3 100644
index 1485186d4989874ef89c4e83830f26358a43759c..b48fc9e0b95fe6c8f72c5501b8de374e6ac2e5d6 100644
--- a/net/minecraft/server/Main.java
+++ b/net/minecraft/server/Main.java
@@ -62,6 +62,14 @@ import org.slf4j.Logger;
@@ -36,25 +36,6 @@ index 1485186d4989874ef89c4e83830f26358a43759c..680369af59fd2aa36bf1cf4e28b59885
@SuppressForbidden(
reason = "System.out needed before bootstrap"
@@ -114,6 +122,18 @@ public class Main {
org.purpurmc.purpur.PurpurConfig.registerMinecraftDebugCommands = purpurConfiguration.getBoolean("settings.register-minecraft-debug-commands"); // Purpur - register minecraft debug commands
// Purpur end - Add toggle for enchant level clamping - load config files early
+ // DivineMC start - Server startup settings
+ org.bukkit.configuration.file.YamlConfiguration divinemcConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionSet.valueOf("divinemc-settings"));
+ boolean divinemcNativeMathEnabled = divinemcConfiguration.getBoolean("settings.chunk-generation.native-acceleration-enabled", true);
+ if (divinemcNativeMathEnabled) {
+ try {
+ Class.forName("org.bxteam.divinemc.math.NativeLoader").getField("lookup").get(null);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ // DivineMC end - Server startup settings
+
io.papermc.paper.plugin.PluginInitializerManager.load(optionSet); // Paper
Bootstrap.bootStrap();
Bootstrap.validate();
diff --git a/net/minecraft/server/gui/MinecraftServerGui.java b/net/minecraft/server/gui/MinecraftServerGui.java
index 614c7d9f673c926562acc8fa3b3788623900db41..33456c7c106abbddf743e1203a6e8122cf10b797 100644
--- a/net/minecraft/server/gui/MinecraftServerGui.java

View File

@@ -0,0 +1,315 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Fri, 31 Jan 2025 21:50:46 +0300
Subject: [PATCH] Math Optimizations
diff --git a/com/mojang/math/OctahedralGroup.java b/com/mojang/math/OctahedralGroup.java
index 11902e7427761746ee098fea3276a34fef0096ba..3ba23fa243f7af712a41316066ca554f1c23b495 100644
--- a/com/mojang/math/OctahedralGroup.java
+++ b/com/mojang/math/OctahedralGroup.java
@@ -112,6 +112,7 @@ public enum OctahedralGroup implements StringRepresentable {
this.transformation = new Matrix3f().scaling(invertX ? -1.0F : 1.0F, invertY ? -1.0F : 1.0F, invertZ ? -1.0F : 1.0F);
this.transformation.mul(permutation.transformation());
this.initializeRotationDirections(); // Paper - Avoid Lazy Initialization for Enum Fields
+ this.rotate(Direction.UP); // DivineMC - Math Optimizations
}
private BooleanList packInversions() {
diff --git a/com/mojang/math/Transformation.java b/com/mojang/math/Transformation.java
index aa755b8b7f8bc5910322e0c5b520f603da06a85a..e781dea43279aa77cc40a7afd2281c32cc8347a9 100644
--- a/com/mojang/math/Transformation.java
+++ b/com/mojang/math/Transformation.java
@@ -51,6 +51,7 @@ public final class Transformation {
} else {
this.matrix = matrix;
}
+ ensureDecomposed(); // DivineMC - Math Optimizations
}
public Transformation(@Nullable Vector3f translation, @Nullable Quaternionf leftRotation, @Nullable Vector3f scale, @Nullable Quaternionf rightRotation) {
@@ -60,6 +61,7 @@ public final class Transformation {
this.scale = scale != null ? scale : new Vector3f(1.0F, 1.0F, 1.0F);
this.rightRotation = rightRotation != null ? rightRotation : new Quaternionf();
this.decomposed = true;
+ ensureDecomposed(); // DivineMC - Math Optimizations
}
public static Transformation identity() {
diff --git a/net/minecraft/util/Mth.java b/net/minecraft/util/Mth.java
index ae1ab070a93b46a0790eed3feda1d09f5fbe9b25..3befc00c10ce8f29d3ee1ea493c2b220df5eaaea 100644
--- a/net/minecraft/util/Mth.java
+++ b/net/minecraft/util/Mth.java
@@ -58,18 +58,15 @@ public class Mth {
}
public static int floor(float value) {
- int i = (int)value;
- return value < i ? i - 1 : i;
+ return (int) Math.floor(value); // DivineMC - Math Optimizations
}
public static int floor(double value) {
- int i = (int)value;
- return value < i ? i - 1 : i;
+ return (int) Math.floor(value); // DivineMC - Math Optimizations
}
public static long lfloor(double value) {
- long l = (long)value;
- return value < l ? l - 1L : l;
+ return (long) Math.floor(value); // DivineMC - Math Optimizations
}
public static float abs(float value) {
@@ -81,13 +78,11 @@ public class Mth {
}
public static int ceil(float value) {
- int i = (int)value;
- return value > i ? i + 1 : i;
+ return (int) Math.ceil(value); // DivineMC - Math Optimizations
}
public static int ceil(double value) {
- int i = (int)value;
- return value > i ? i + 1 : i;
+ return (int) Math.ceil(value); // DivineMC - Math Optimizations
}
public static int clamp(int value, int min, int max) {
@@ -123,15 +118,7 @@ public class Mth {
}
public static double absMax(double x, double y) {
- if (x < 0.0) {
- x = -x;
- }
-
- if (y < 0.0) {
- y = -y;
- }
-
- return Math.max(x, y);
+ return Math.max(Math.abs(x), Math.abs(y)); // DivineMC - Math Optimizations
}
public static int floorDiv(int dividend, int divisor) {
@@ -162,14 +149,26 @@ public class Mth {
return Math.floorMod(x, y);
}
- public static float positiveModulo(float numerator, float denominator) {
+ public static float positiveModuloForAnyDenominator(float numerator, float denominator) { // DivineMC - Math Optimizations
return (numerator % denominator + denominator) % denominator;
}
- public static double positiveModulo(double numerator, double denominator) {
+ public static double positiveModuloForAnyDenominator(double numerator, double denominator) { // DivineMC - Math Optimizations
return (numerator % denominator + denominator) % denominator;
}
+ // DivineMC start - Math Optimizations
+ public static float positiveModuloForPositiveIntegerDenominator(float numerator, float denominator) {
+ var modulo = numerator % denominator;
+ return modulo < 0 ? modulo + denominator : modulo;
+ }
+
+ public static double positiveModuloForPositiveIntegerDenominator(double numerator, double denominator) {
+ var modulo = numerator % denominator;
+ return modulo < 0 ? modulo + denominator : modulo;
+ }
+ // DivineMC end - Math Optimizations
+
public static boolean isMultipleOf(int number, int multiple) {
return number % multiple == 0;
}
diff --git a/net/minecraft/world/level/biome/BiomeManager.java b/net/minecraft/world/level/biome/BiomeManager.java
index 73962e79a0f3d892e3155443a1b84508b0f4042e..db400d7b25e454b4a1ac8d09a590c3c7d2504052 100644
--- a/net/minecraft/world/level/biome/BiomeManager.java
+++ b/net/minecraft/world/level/biome/BiomeManager.java
@@ -14,6 +14,7 @@ public class BiomeManager {
private static final int ZOOM_MASK = 3;
private final BiomeManager.NoiseBiomeSource noiseBiomeSource;
private final long biomeZoomSeed;
+ private static final double maxOffset = 0.4500000001D; // DivineMC - Math Optimizations
public BiomeManager(BiomeManager.NoiseBiomeSource noiseBiomeSource, long biomeZoomSeed) {
this.noiseBiomeSource = noiseBiomeSource;
@@ -29,39 +30,65 @@ public class BiomeManager {
}
public Holder<Biome> getBiome(BlockPos pos) {
- int i = pos.getX() - 2;
- int i1 = pos.getY() - 2;
- int i2 = pos.getZ() - 2;
- int i3 = i >> 2;
- int i4 = i1 >> 2;
- int i5 = i2 >> 2;
- double d = (i & 3) / 4.0;
- double d1 = (i1 & 3) / 4.0;
- double d2 = (i2 & 3) / 4.0;
- int i6 = 0;
- double d3 = Double.POSITIVE_INFINITY;
+ // DivineMC start - Math Optimizations
+ int xMinus2 = pos.getX() - 2;
+ int yMinus2 = pos.getY() - 2;
+ int zMinus2 = pos.getZ() - 2;
+ int x = xMinus2 >> 2;
+ int y = yMinus2 >> 2;
+ int z = zMinus2 >> 2;
+ double quartX = (double) (xMinus2 & 3) / 4.0;
+ double quartY = (double) (yMinus2 & 3) / 4.0;
+ double quartZ = (double) (zMinus2 & 3) / 4.0;
+ int smallestX = 0;
+ double smallestDist = Double.POSITIVE_INFINITY;
+ for (int biomeX = 0; biomeX < 8; ++biomeX) {
+ boolean everyOtherQuad = (biomeX & 4) == 0;
+ boolean everyOtherPair = (biomeX & 2) == 0;
+ boolean everyOther = (biomeX & 1) == 0;
+ double quartXX = everyOtherQuad ? quartX : quartX - 1.0;
+ double quartYY = everyOtherPair ? quartY : quartY - 1.0;
+ double quartZZ = everyOther ? quartZ : quartZ - 1.0;
- for (int i7 = 0; i7 < 8; i7++) {
- boolean flag = (i7 & 4) == 0;
- boolean flag1 = (i7 & 2) == 0;
- boolean flag2 = (i7 & 1) == 0;
- int i8 = flag ? i3 : i3 + 1;
- int i9 = flag1 ? i4 : i4 + 1;
- int i10 = flag2 ? i5 : i5 + 1;
- double d4 = flag ? d : d - 1.0;
- double d5 = flag1 ? d1 : d1 - 1.0;
- double d6 = flag2 ? d2 : d2 - 1.0;
- double fiddledDistance = getFiddledDistance(this.biomeZoomSeed, i8, i9, i10, d4, d5, d6);
- if (d3 > fiddledDistance) {
- i6 = i7;
- d3 = fiddledDistance;
+ double maxQuartYY = 0.0, maxQuartZZ = 0.0;
+ if (biomeX != 0) {
+ maxQuartYY = Mth.square(Math.max(quartYY + maxOffset, Math.abs(quartYY - maxOffset)));
+ maxQuartZZ = Mth.square(Math.max(quartZZ + maxOffset, Math.abs(quartZZ - maxOffset)));
+ double maxQuartXX = Mth.square(Math.max(quartXX + maxOffset, Math.abs(quartXX - maxOffset)));
+ if (smallestDist < maxQuartXX + maxQuartYY + maxQuartZZ) continue;
}
- }
+ int xx = everyOtherQuad ? x : x + 1;
+ int yy = everyOtherPair ? y : y + 1;
+ int zz = everyOther ? z : z + 1;
+
+ long seed = LinearCongruentialGenerator.next(this.biomeZoomSeed, xx);
+ seed = LinearCongruentialGenerator.next(seed, yy);
+ seed = LinearCongruentialGenerator.next(seed, zz);
+ seed = LinearCongruentialGenerator.next(seed, xx);
+ seed = LinearCongruentialGenerator.next(seed, yy);
+ seed = LinearCongruentialGenerator.next(seed, zz);
+ double offsetX = getFiddle(seed);
+ double sqrX = Mth.square(quartXX + offsetX);
+ if (biomeX != 0 && smallestDist < sqrX + maxQuartYY + maxQuartZZ) continue;
+ seed = LinearCongruentialGenerator.next(seed, this.biomeZoomSeed);
+ double offsetY = getFiddle(seed);
+ double sqrY = Mth.square(quartYY + offsetY);
+ if (biomeX != 0 && smallestDist < sqrX + sqrY + maxQuartZZ) continue;
+ seed = LinearCongruentialGenerator.next(seed, this.biomeZoomSeed);
+ double offsetZ = getFiddle(seed);
+ double biomeDist = sqrX + sqrY + Mth.square(quartZZ + offsetZ);
- int i7x = (i6 & 4) == 0 ? i3 : i3 + 1;
- int i11 = (i6 & 2) == 0 ? i4 : i4 + 1;
- int i12 = (i6 & 1) == 0 ? i5 : i5 + 1;
- return this.noiseBiomeSource.getNoiseBiome(i7x, i11, i12);
+ if (smallestDist > biomeDist) {
+ smallestX = biomeX;
+ smallestDist = biomeDist;
+ }
+ }
+ return this.noiseBiomeSource.getNoiseBiome(
+ (smallestX & 4) == 0 ? x : x + 1,
+ (smallestX & 2) == 0 ? y : y + 1,
+ (smallestX & 1) == 0 ? z : z + 1
+ );
+ // DivineMC end - Math Optimizations
}
public Holder<Biome> getNoiseBiomeAtPosition(double x, double y, double z) {
diff --git a/net/minecraft/world/level/levelgen/blending/Blender.java b/net/minecraft/world/level/levelgen/blending/Blender.java
index 01e5b29d6e9a5c53c0e23b61ed0c1d7be1a0fe08..d80df05e40f3941ade5ed320e12f8dcf47e6b247 100644
--- a/net/minecraft/world/level/levelgen/blending/Blender.java
+++ b/net/minecraft/world/level/levelgen/blending/Blender.java
@@ -144,7 +144,7 @@ public class Blender {
private static double heightToOffset(double height) {
double d = 1.0;
double d1 = height + 0.5;
- double d2 = Mth.positiveModulo(d1, 8.0);
+ double d2 = Mth.positiveModuloForPositiveIntegerDenominator(d1, 8.0); // DivineMC - Math optimizations
return 1.0 * (32.0 * (d1 - 128.0) - 3.0 * (d1 - 120.0) * d2 + 3.0 * d2 * d2) / (128.0 * (32.0 - 3.0 * d2));
}
diff --git a/net/minecraft/world/phys/AABB.java b/net/minecraft/world/phys/AABB.java
index c9c6e4e460ad8435f12761704bb9b0284d6aa708..54807bb4b4189ceaded1f78a1a9ab85ce40ab2b1 100644
--- a/net/minecraft/world/phys/AABB.java
+++ b/net/minecraft/world/phys/AABB.java
@@ -189,13 +189,15 @@ public class AABB {
}
public AABB intersect(AABB other) {
- double max = Math.max(this.minX, other.minX);
- double max1 = Math.max(this.minY, other.minY);
- double max2 = Math.max(this.minZ, other.minZ);
- double min = Math.min(this.maxX, other.maxX);
- double min1 = Math.min(this.maxY, other.maxY);
- double min2 = Math.min(this.maxZ, other.maxZ);
- return new AABB(max, max1, max2, min, min1, min2);
+ // DivineMC start - Math Optimizations
+ return new AABB(
+ this.minX > other.minX ? this.minX : other.minX,
+ this.minY > other.minY ? this.minY : other.minY,
+ this.minZ > other.minZ ? this.minZ : other.minZ,
+ this.maxX < other.maxX ? this.maxX : other.maxX,
+ this.maxY < other.maxY ? this.maxY : other.maxY,
+ this.maxZ < other.maxZ ? this.maxZ : other.maxZ
+ );
}
public AABB minmax(AABB other) {
@@ -227,16 +229,37 @@ public class AABB {
}
public boolean intersects(AABB other) {
- return this.intersects(other.minX, other.minY, other.minZ, other.maxX, other.maxY, other.maxZ);
+ // DivineMC start - Math Optimizations
+ return this.minX < other.maxX &&
+ this.maxX > other.minX &&
+ this.minY < other.maxY &&
+ this.maxY > other.minY &&
+ this.minZ < other.maxZ &&
+ this.maxZ > other.minZ;
+ // DivineMC end - Math Optimizations
}
public boolean intersects(double x1, double y1, double z1, double x2, double y2, double z2) {
- return this.minX < x2 && this.maxX > x1 && this.minY < y2 && this.maxY > y1 && this.minZ < z2 && this.maxZ > z1;
+ // DivineMC start - Math Optimizations
+ return this.minX < x2 &&
+ this.maxX > x1 &&
+ this.minY < y2 &&
+ this.maxY > y1 &&
+ this.minZ < z2 &&
+ this.maxZ > z1;
+ // DivineMC end - Math Optimizations
}
public boolean intersects(Vec3 min, Vec3 max) {
return this.intersects(
- Math.min(min.x, max.x), Math.min(min.y, max.y), Math.min(min.z, max.z), Math.max(min.x, max.x), Math.max(min.y, max.y), Math.max(min.z, max.z)
+ // DivineMC start - Math Optimizations
+ min.x < max.x ? min.x : max.x,
+ min.y < max.y ? min.y : max.y,
+ min.z < max.z ? min.z : max.z,
+ min.x > max.x ? min.x : max.x,
+ min.y > max.y ? min.y : max.y,
+ min.z > max.z ? min.z : max.z
+ // DivineMC end - Math Optimizations
);
}

View File

@@ -1,602 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Fri, 31 Jan 2025 21:50:46 +0300
Subject: [PATCH] Native Math Optimizations
diff --git a/com/mojang/math/OctahedralGroup.java b/com/mojang/math/OctahedralGroup.java
index 11902e7427761746ee098fea3276a34fef0096ba..3ba23fa243f7af712a41316066ca554f1c23b495 100644
--- a/com/mojang/math/OctahedralGroup.java
+++ b/com/mojang/math/OctahedralGroup.java
@@ -112,6 +112,7 @@ public enum OctahedralGroup implements StringRepresentable {
this.transformation = new Matrix3f().scaling(invertX ? -1.0F : 1.0F, invertY ? -1.0F : 1.0F, invertZ ? -1.0F : 1.0F);
this.transformation.mul(permutation.transformation());
this.initializeRotationDirections(); // Paper - Avoid Lazy Initialization for Enum Fields
+ this.rotate(Direction.UP); // DivineMC - Math Optimizations
}
private BooleanList packInversions() {
diff --git a/com/mojang/math/Transformation.java b/com/mojang/math/Transformation.java
index aa755b8b7f8bc5910322e0c5b520f603da06a85a..e781dea43279aa77cc40a7afd2281c32cc8347a9 100644
--- a/com/mojang/math/Transformation.java
+++ b/com/mojang/math/Transformation.java
@@ -51,6 +51,7 @@ public final class Transformation {
} else {
this.matrix = matrix;
}
+ ensureDecomposed(); // DivineMC - Math Optimizations
}
public Transformation(@Nullable Vector3f translation, @Nullable Quaternionf leftRotation, @Nullable Vector3f scale, @Nullable Quaternionf rightRotation) {
@@ -60,6 +61,7 @@ public final class Transformation {
this.scale = scale != null ? scale : new Vector3f(1.0F, 1.0F, 1.0F);
this.rightRotation = rightRotation != null ? rightRotation : new Quaternionf();
this.decomposed = true;
+ ensureDecomposed(); // DivineMC - Math Optimizations
}
public static Transformation identity() {
diff --git a/net/minecraft/util/Mth.java b/net/minecraft/util/Mth.java
index ae1ab070a93b46a0790eed3feda1d09f5fbe9b25..3befc00c10ce8f29d3ee1ea493c2b220df5eaaea 100644
--- a/net/minecraft/util/Mth.java
+++ b/net/minecraft/util/Mth.java
@@ -58,18 +58,15 @@ public class Mth {
}
public static int floor(float value) {
- int i = (int)value;
- return value < i ? i - 1 : i;
+ return (int) Math.floor(value); // DivineMC - Math Optimizations
}
public static int floor(double value) {
- int i = (int)value;
- return value < i ? i - 1 : i;
+ return (int) Math.floor(value); // DivineMC - Math Optimizations
}
public static long lfloor(double value) {
- long l = (long)value;
- return value < l ? l - 1L : l;
+ return (long) Math.floor(value); // DivineMC - Math Optimizations
}
public static float abs(float value) {
@@ -81,13 +78,11 @@ public class Mth {
}
public static int ceil(float value) {
- int i = (int)value;
- return value > i ? i + 1 : i;
+ return (int) Math.ceil(value); // DivineMC - Math Optimizations
}
public static int ceil(double value) {
- int i = (int)value;
- return value > i ? i + 1 : i;
+ return (int) Math.ceil(value); // DivineMC - Math Optimizations
}
public static int clamp(int value, int min, int max) {
@@ -123,15 +118,7 @@ public class Mth {
}
public static double absMax(double x, double y) {
- if (x < 0.0) {
- x = -x;
- }
-
- if (y < 0.0) {
- y = -y;
- }
-
- return Math.max(x, y);
+ return Math.max(Math.abs(x), Math.abs(y)); // DivineMC - Math Optimizations
}
public static int floorDiv(int dividend, int divisor) {
@@ -162,14 +149,26 @@ public class Mth {
return Math.floorMod(x, y);
}
- public static float positiveModulo(float numerator, float denominator) {
+ public static float positiveModuloForAnyDenominator(float numerator, float denominator) { // DivineMC - Math Optimizations
return (numerator % denominator + denominator) % denominator;
}
- public static double positiveModulo(double numerator, double denominator) {
+ public static double positiveModuloForAnyDenominator(double numerator, double denominator) { // DivineMC - Math Optimizations
return (numerator % denominator + denominator) % denominator;
}
+ // DivineMC start - Math Optimizations
+ public static float positiveModuloForPositiveIntegerDenominator(float numerator, float denominator) {
+ var modulo = numerator % denominator;
+ return modulo < 0 ? modulo + denominator : modulo;
+ }
+
+ public static double positiveModuloForPositiveIntegerDenominator(double numerator, double denominator) {
+ var modulo = numerator % denominator;
+ return modulo < 0 ? modulo + denominator : modulo;
+ }
+ // DivineMC end - Math Optimizations
+
public static boolean isMultipleOf(int number, int multiple) {
return number % multiple == 0;
}
diff --git a/net/minecraft/world/level/biome/BiomeManager.java b/net/minecraft/world/level/biome/BiomeManager.java
index 73962e79a0f3d892e3155443a1b84508b0f4042e..10b930f7e0314bf6658ea9ae79ae88b37aee3e05 100644
--- a/net/minecraft/world/level/biome/BiomeManager.java
+++ b/net/minecraft/world/level/biome/BiomeManager.java
@@ -29,39 +29,64 @@ public class BiomeManager {
}
public Holder<Biome> getBiome(BlockPos pos) {
- int i = pos.getX() - 2;
- int i1 = pos.getY() - 2;
- int i2 = pos.getZ() - 2;
- int i3 = i >> 2;
- int i4 = i1 >> 2;
- int i5 = i2 >> 2;
- double d = (i & 3) / 4.0;
- double d1 = (i1 & 3) / 4.0;
- double d2 = (i2 & 3) / 4.0;
- int i6 = 0;
- double d3 = Double.POSITIVE_INFINITY;
+ // DivineMC start - Native Math Optimizations
+ if (org.bxteam.divinemc.DivineConfig.nativeAccelerationEnabled) {
+ int mask = org.bxteam.divinemc.math.Bindings.c2me_natives_biome_access_sample(this.biomeZoomSeed, pos.getX(), pos.getY(), pos.getZ());
- for (int i7 = 0; i7 < 8; i7++) {
- boolean flag = (i7 & 4) == 0;
- boolean flag1 = (i7 & 2) == 0;
- boolean flag2 = (i7 & 1) == 0;
- int i8 = flag ? i3 : i3 + 1;
- int i9 = flag1 ? i4 : i4 + 1;
- int i10 = flag2 ? i5 : i5 + 1;
- double d4 = flag ? d : d - 1.0;
- double d5 = flag1 ? d1 : d1 - 1.0;
- double d6 = flag2 ? d2 : d2 - 1.0;
- double fiddledDistance = getFiddledDistance(this.biomeZoomSeed, i8, i9, i10, d4, d5, d6);
- if (d3 > fiddledDistance) {
- i6 = i7;
- d3 = fiddledDistance;
+ return this.noiseBiomeSource.getNoiseBiome(
+ ((pos.getX() - 2) >> 2) + ((mask & 4) != 0 ? 1 : 0),
+ ((pos.getY() - 2) >> 2) + ((mask & 2) != 0 ? 1 : 0),
+ ((pos.getZ() - 2) >> 2) + ((mask & 1) != 0 ? 1 : 0)
+ );
+ } else {
+ final int var0 = pos.getX() - 2;
+ final int var1 = pos.getY() - 2;
+ final int var2 = pos.getZ() - 2;
+ final int var3 = var0 >> 2;
+ final int var4 = var1 >> 2;
+ final int var5 = var2 >> 2;
+ final double var6 = (double) (var0 & 3) / 4.0;
+ final double var7 = (double) (var1 & 3) / 4.0;
+ final double var8 = (double) (var2 & 3) / 4.0;
+ int var9 = 0;
+ double var10 = Double.POSITIVE_INFINITY;
+ for (int var11 = 0; var11 < 8; ++var11) {
+ boolean var12 = (var11 & 4) == 0;
+ boolean var13 = (var11 & 2) == 0;
+ boolean var14 = (var11 & 1) == 0;
+ long var15 = var12 ? var3 : var3 + 1;
+ long var16 = var13 ? var4 : var4 + 1;
+ long var17 = var14 ? var5 : var5 + 1;
+ double var18 = var12 ? var6 : var6 - 1.0;
+ double var19 = var13 ? var7 : var7 - 1.0;
+ double var20 = var14 ? var8 : var8 - 1.0;
+ long var21 = this.biomeZoomSeed * (this.biomeZoomSeed * 6364136223846793005L + 1442695040888963407L) + var15;
+ var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var16;
+ var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var17;
+ var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var15;
+ var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var16;
+ var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var17;
+ double var22 = (double) ((var21 >> 24) & 1023) / 1024.0;
+ double var23 = (var22 - 0.5) * 0.9;
+ var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + this.biomeZoomSeed;
+ double var24 = (double) ((var21 >> 24) & 1023) / 1024.0;
+ double var25 = (var24 - 0.5) * 0.9;
+ var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + this.biomeZoomSeed;
+ double var26 = (double) ((var21 >> 24) & 1023) / 1024.0;
+ double var27 = (var26 - 0.5) * 0.9;
+ double var28 = Mth.square(var20 + var27) + Mth.square(var19 + var25) + Mth.square(var18 + var23);
+ if (var10 > var28) {
+ var9 = var11;
+ var10 = var28;
+ }
}
- }
- int i7x = (i6 & 4) == 0 ? i3 : i3 + 1;
- int i11 = (i6 & 2) == 0 ? i4 : i4 + 1;
- int i12 = (i6 & 1) == 0 ? i5 : i5 + 1;
- return this.noiseBiomeSource.getNoiseBiome(i7x, i11, i12);
+ int resX = (var9 & 4) == 0 ? var3 : var3 + 1;
+ int resY = (var9 & 2) == 0 ? var4 : var4 + 1;
+ int resZ = (var9 & 1) == 0 ? var5 : var5 + 1;
+ return this.noiseBiomeSource.getNoiseBiome(resX, resY, resZ);
+ }
+ // DivineMC end - Native Math Optimizations
}
public Holder<Biome> getNoiseBiomeAtPosition(double x, double y, double z) {
diff --git a/net/minecraft/world/level/levelgen/DensityFunctions.java b/net/minecraft/world/level/levelgen/DensityFunctions.java
index fa08f06be03b2e6120ddc105563f68d551da741c..6ff9175641234b0fe55dc4613c6d7c56e00211fd 100644
--- a/net/minecraft/world/level/levelgen/DensityFunctions.java
+++ b/net/minecraft/world/level/levelgen/DensityFunctions.java
@@ -501,6 +501,11 @@ public final class DensityFunctions {
}
protected static final class EndIslandDensityFunction implements DensityFunction.SimpleFunction {
+ // DivineMC start - Native Math Optimizations
+ private final java.lang.foreign.Arena c2me$arena = java.lang.foreign.Arena.ofAuto();
+ private java.lang.foreign.MemorySegment c2me$samplerData = null;
+ private long c2me$samplerDataPtr;
+ // DivineMC end - Native Math Optimizations
public static final KeyDispatchDataCodec<DensityFunctions.EndIslandDensityFunction> CODEC = KeyDispatchDataCodec.of(
MapCodec.unit(new DensityFunctions.EndIslandDensityFunction(0L))
);
@@ -521,6 +526,16 @@ public final class DensityFunctions {
RandomSource randomSource = new LegacyRandomSource(seed);
randomSource.consumeCount(17292);
this.islandNoise = new SimplexNoise(randomSource);
+ // DivineMC start - Native Math Optimizations
+ if (org.bxteam.divinemc.DivineConfig.nativeAccelerationEnabled) {
+ int[] permutation = (this.islandNoise).p;
+ java.lang.foreign.MemorySegment segment = this.c2me$arena.allocate(permutation.length * 4L, 64);
+ java.lang.foreign.MemorySegment.copy(java.lang.foreign.MemorySegment.ofArray(permutation), 0L, segment, 0L, permutation.length * 4L);
+ java.lang.invoke.VarHandle.fullFence();
+ this.c2me$samplerData = segment;
+ this.c2me$samplerDataPtr = segment.address();
+ }
+ // DivineMC end - Native Math Optimizations
}
private static float getHeightValue(SimplexNoise noise, int x, int z) {
@@ -567,7 +582,13 @@ public final class DensityFunctions {
@Override
public double compute(DensityFunction.FunctionContext context) {
- return (getHeightValue(this.islandNoise, context.blockX() / 8, context.blockZ() / 8) - 8.0) / 128.0;
+ // DivineMC start - Native Math Optimizations
+ if (org.bxteam.divinemc.DivineConfig.nativeAccelerationEnabled && this.c2me$samplerDataPtr != 0L) {
+ return ((double) org.bxteam.divinemc.math.Bindings.c2me_natives_end_islands_sample(this.c2me$samplerDataPtr, context.blockX() / 8, context.blockZ() / 8) - 8.0) / 128.0;
+ } else {
+ return (getHeightValue(this.islandNoise, context.blockX() / 8, context.blockZ() / 8) - 8.0) / 128.0;
+ }
+ // DivineMC end - Native Math Optimizations
}
@Override
@@ -814,10 +835,42 @@ public final class DensityFunctions {
return this.noise.getValue(context.blockX() * this.xzScale, context.blockY() * this.yScale, context.blockZ() * this.xzScale);
}
+ // DivineMC start - Native Math Optimizations
@Override
- public void fillArray(double[] array, DensityFunction.ContextProvider contextProvider) {
- contextProvider.fillAllDirectly(array, this);
+ public void fillArray(double[] densities, DensityFunction.ContextProvider applier) {
+ if (!org.bxteam.divinemc.DivineConfig.nativeAccelerationEnabled) {
+ applier.fillAllDirectly(densities, this);
+ return;
+ }
+ NormalNoise noise = this.noise.noise();
+ if (noise == null) {
+ Arrays.fill(densities, 0.0);
+ return;
+ }
+ long ptr = noise.c2me$getPointer();
+ if (ptr == 0L) {
+ applier.fillAllDirectly(densities, this);
+ return;
+ }
+ double[] x = new double[densities.length];
+ double[] y = new double[densities.length];
+ double[] z = new double[densities.length];
+ for (int i = 0; i < densities.length; i++) {
+ FunctionContext pos = applier.forIndex(i);
+ x[i] = pos.blockX() * this.xzScale();
+ y[i] = pos.blockY() * this.yScale();
+ z[i] = pos.blockZ() * this.xzScale();
+ }
+ org.bxteam.divinemc.math.Bindings.c2me_natives_noise_perlin_double_batch(
+ ptr,
+ java.lang.foreign.MemorySegment.ofArray(densities),
+ java.lang.foreign.MemorySegment.ofArray(x),
+ java.lang.foreign.MemorySegment.ofArray(y),
+ java.lang.foreign.MemorySegment.ofArray(z),
+ densities.length
+ );
}
+ // DivineMC end - Native Math Optimizations
@Override
public DensityFunction mapAll(DensityFunction.Visitor visitor) {
@@ -938,6 +991,46 @@ public final class DensityFunctions {
public KeyDispatchDataCodec<? extends DensityFunction> codec() {
return CODEC;
}
+
+ // DivineMC start - Native Math Optimizations
+ @Override
+ public void fillArray(final double[] densities, final ContextProvider applier) {
+ if (!org.bxteam.divinemc.DivineConfig.nativeAccelerationEnabled) {
+ applier.fillAllDirectly(densities, this);
+ return;
+ }
+ NormalNoise noise = this.offsetNoise.noise();
+ if (noise == null) {
+ Arrays.fill(densities, 0.0);
+ return;
+ }
+ long ptr = noise.c2me$getPointer();
+ if (ptr == 0L) {
+ applier.fillAllDirectly(densities, this);
+ return;
+ }
+ double[] x = new double[densities.length];
+ double[] y = new double[densities.length];
+ double[] z = new double[densities.length];
+ for (int i = 0; i < densities.length; i++) {
+ FunctionContext pos = applier.forIndex(i);
+ x[i] = pos.blockX() * 0.25;
+ y[i] = pos.blockY() * 0.25;
+ z[i] = pos.blockZ() * 0.25;
+ }
+ org.bxteam.divinemc.math.Bindings.c2me_natives_noise_perlin_double_batch(
+ ptr,
+ java.lang.foreign.MemorySegment.ofArray(densities),
+ java.lang.foreign.MemorySegment.ofArray(x),
+ java.lang.foreign.MemorySegment.ofArray(y),
+ java.lang.foreign.MemorySegment.ofArray(z),
+ densities.length
+ );
+ for (int i = 0; i < densities.length; i++) {
+ densities[i] *= 4.0;
+ }
+ }
+ // DivineMC end - Native Math Optimizations
}
public record ShiftA(@Override DensityFunction.NoiseHolder offsetNoise) implements DensityFunctions.ShiftNoise {
@@ -959,6 +1052,46 @@ public final class DensityFunctions {
public KeyDispatchDataCodec<? extends DensityFunction> codec() {
return CODEC;
}
+
+ // DivineMC start - Native Math Optimizations
+ @Override
+ public void fillArray(final double[] densities, final ContextProvider applier) {
+ if (!org.bxteam.divinemc.DivineConfig.nativeAccelerationEnabled) {
+ applier.fillAllDirectly(densities, this);
+ return;
+ }
+ NormalNoise noise = this.offsetNoise.noise();
+ if (noise == null) {
+ Arrays.fill(densities, 0.0);
+ return;
+ }
+ long ptr = noise.c2me$getPointer();
+ if (ptr == 0L) {
+ applier.fillAllDirectly(densities, this);
+ return;
+ }
+ double[] x = new double[densities.length];
+ double[] y = new double[densities.length];
+ double[] z = new double[densities.length];
+ for (int i = 0; i < densities.length; i++) {
+ FunctionContext pos = applier.forIndex(i);
+ x[i] = pos.blockX() * 0.25;
+ y[i] = 0;
+ z[i] = pos.blockZ() * 0.25;
+ }
+ org.bxteam.divinemc.math.Bindings.c2me_natives_noise_perlin_double_batch(
+ ptr,
+ java.lang.foreign.MemorySegment.ofArray(densities),
+ java.lang.foreign.MemorySegment.ofArray(x),
+ java.lang.foreign.MemorySegment.ofArray(y),
+ java.lang.foreign.MemorySegment.ofArray(z),
+ densities.length
+ );
+ for (int i = 0; i < densities.length; i++) {
+ densities[i] *= 4.0;
+ }
+ }
+ // DivineMC end - Native Math Optimizations
}
public record ShiftB(@Override DensityFunction.NoiseHolder offsetNoise) implements DensityFunctions.ShiftNoise {
@@ -980,6 +1113,46 @@ public final class DensityFunctions {
public KeyDispatchDataCodec<? extends DensityFunction> codec() {
return CODEC;
}
+
+ // DivineMC start - Native Math Optimizations
+ @Override
+ public void fillArray(final double[] densities, final ContextProvider applier) {
+ if (!org.bxteam.divinemc.DivineConfig.nativeAccelerationEnabled) {
+ applier.fillAllDirectly(densities, this);
+ return;
+ }
+ NormalNoise noise = this.offsetNoise.noise();
+ if (noise == null) {
+ Arrays.fill(densities, 0.0);
+ return;
+ }
+ long ptr = noise.c2me$getPointer();
+ if (ptr == 0L) {
+ applier.fillAllDirectly(densities, this);
+ return;
+ }
+ double[] x = new double[densities.length];
+ double[] y = new double[densities.length];
+ double[] z = new double[densities.length];
+ for (int i = 0; i < densities.length; i++) {
+ FunctionContext pos = applier.forIndex(i);
+ x[i] = pos.blockZ() * 0.25;
+ y[i] = pos.blockX() * 0.25;
+ z[i] = 0.0;
+ }
+ org.bxteam.divinemc.math.Bindings.c2me_natives_noise_perlin_double_batch(
+ ptr,
+ java.lang.foreign.MemorySegment.ofArray(densities),
+ java.lang.foreign.MemorySegment.ofArray(x),
+ java.lang.foreign.MemorySegment.ofArray(y),
+ java.lang.foreign.MemorySegment.ofArray(z),
+ densities.length
+ );
+ for (int i = 0; i < densities.length; i++) {
+ densities[i] *= 4.0;
+ }
+ }
+ // DivineMC end - Native Math Optimizations
}
interface ShiftNoise extends DensityFunction {
diff --git a/net/minecraft/world/level/levelgen/blending/Blender.java b/net/minecraft/world/level/levelgen/blending/Blender.java
index 01e5b29d6e9a5c53c0e23b61ed0c1d7be1a0fe08..d80df05e40f3941ade5ed320e12f8dcf47e6b247 100644
--- a/net/minecraft/world/level/levelgen/blending/Blender.java
+++ b/net/minecraft/world/level/levelgen/blending/Blender.java
@@ -144,7 +144,7 @@ public class Blender {
private static double heightToOffset(double height) {
double d = 1.0;
double d1 = height + 0.5;
- double d2 = Mth.positiveModulo(d1, 8.0);
+ double d2 = Mth.positiveModuloForPositiveIntegerDenominator(d1, 8.0); // DivineMC - Math optimizations
return 1.0 * (32.0 * (d1 - 128.0) - 3.0 * (d1 - 120.0) * d2 + 3.0 * d2 * d2) / (128.0 * (32.0 - 3.0 * d2));
}
diff --git a/net/minecraft/world/level/levelgen/synth/BlendedNoise.java b/net/minecraft/world/level/levelgen/synth/BlendedNoise.java
index af5f714c285aad5ef844b17a266e06b5092d33aa..6c022157a898e96daabc5c82c7f8b34bee64aca4 100644
--- a/net/minecraft/world/level/levelgen/synth/BlendedNoise.java
+++ b/net/minecraft/world/level/levelgen/synth/BlendedNoise.java
@@ -36,6 +36,11 @@ public class BlendedNoise implements DensityFunction.SimpleFunction {
private final double maxValue;
public final double xzScale;
public final double yScale;
+ // DivineMC start - Native Math Optimizations
+ private final java.lang.foreign.Arena c2me$arena = java.lang.foreign.Arena.ofAuto();
+ private java.lang.foreign.MemorySegment c2me$samplerData = null;
+ private long c2me$samplerDataPtr;
+ // DivineMC end - Native Math Optimizations
public static BlendedNoise createUnseeded(double xzScale, double yScale, double xzFactor, double yFactor, double smearScaleMultiplier) {
return new BlendedNoise(new XoroshiroRandomSource(0L), xzScale, yScale, xzFactor, yFactor, smearScaleMultiplier);
@@ -62,6 +67,12 @@ public class BlendedNoise implements DensityFunction.SimpleFunction {
this.xzMultiplier = 684.412 * this.xzScale;
this.yMultiplier = 684.412 * this.yScale;
this.maxValue = minLimitNoise.maxBrokenValue(this.yMultiplier);
+ // DivineMC start - Native Math Optimizations
+ if (org.bxteam.divinemc.DivineConfig.nativeAccelerationEnabled) {
+ this.c2me$samplerData = org.bxteam.divinemc.math.BindingsTemplate.interpolated_noise_sampler$create(this.c2me$arena, this);
+ this.c2me$samplerDataPtr = this.c2me$samplerData.address();
+ }
+ // DivineMC end - Native Math Optimizations
}
@VisibleForTesting
diff --git a/net/minecraft/world/level/levelgen/synth/NormalNoise.java b/net/minecraft/world/level/levelgen/synth/NormalNoise.java
index 45060882654217eeb9a07357c5149b12fbff02c1..c17f43164009f47050a390eb50688460e1d4cf3b 100644
--- a/net/minecraft/world/level/levelgen/synth/NormalNoise.java
+++ b/net/minecraft/world/level/levelgen/synth/NormalNoise.java
@@ -21,6 +21,15 @@ public class NormalNoise {
private final PerlinNoise second;
private final double maxValue;
private final NormalNoise.NoiseParameters parameters;
+ // DivineMC start - Native Math Optimizations
+ private final java.lang.foreign.Arena c2me$arena = java.lang.foreign.Arena.ofAuto();
+ private java.lang.foreign.MemorySegment c2me$samplerData = null;
+ private long c2me$samplerDataPtr;
+
+ public long c2me$getPointer() {
+ return this.c2me$samplerDataPtr;
+ }
+ // DivineMC end - Native Math Optimizations
@Deprecated
public static NormalNoise createLegacyNetherBiome(RandomSource random, NormalNoise.NoiseParameters parameters) {
@@ -62,6 +71,12 @@ public class NormalNoise {
this.valueFactor = 0.16666666666666666 / expectedDeviation(i2 - i1);
this.maxValue = (this.first.maxValue() + this.second.maxValue()) * this.valueFactor;
+ // DivineMC start - Native Math Optimizations
+ if (org.bxteam.divinemc.DivineConfig.nativeAccelerationEnabled) {
+ this.c2me$samplerData = org.bxteam.divinemc.math.BindingsTemplate.double_octave_sampler_data$create(this.c2me$arena, this.first, this.second, this.valueFactor);
+ this.c2me$samplerDataPtr = this.c2me$samplerData.address();
+ }
+ // DivineMC end - Native Math Optimizations
}
public double maxValue() {
diff --git a/net/minecraft/world/phys/AABB.java b/net/minecraft/world/phys/AABB.java
index c9c6e4e460ad8435f12761704bb9b0284d6aa708..54807bb4b4189ceaded1f78a1a9ab85ce40ab2b1 100644
--- a/net/minecraft/world/phys/AABB.java
+++ b/net/minecraft/world/phys/AABB.java
@@ -189,13 +189,15 @@ public class AABB {
}
public AABB intersect(AABB other) {
- double max = Math.max(this.minX, other.minX);
- double max1 = Math.max(this.minY, other.minY);
- double max2 = Math.max(this.minZ, other.minZ);
- double min = Math.min(this.maxX, other.maxX);
- double min1 = Math.min(this.maxY, other.maxY);
- double min2 = Math.min(this.maxZ, other.maxZ);
- return new AABB(max, max1, max2, min, min1, min2);
+ // DivineMC start - Math Optimizations
+ return new AABB(
+ this.minX > other.minX ? this.minX : other.minX,
+ this.minY > other.minY ? this.minY : other.minY,
+ this.minZ > other.minZ ? this.minZ : other.minZ,
+ this.maxX < other.maxX ? this.maxX : other.maxX,
+ this.maxY < other.maxY ? this.maxY : other.maxY,
+ this.maxZ < other.maxZ ? this.maxZ : other.maxZ
+ );
}
public AABB minmax(AABB other) {
@@ -227,16 +229,37 @@ public class AABB {
}
public boolean intersects(AABB other) {
- return this.intersects(other.minX, other.minY, other.minZ, other.maxX, other.maxY, other.maxZ);
+ // DivineMC start - Math Optimizations
+ return this.minX < other.maxX &&
+ this.maxX > other.minX &&
+ this.minY < other.maxY &&
+ this.maxY > other.minY &&
+ this.minZ < other.maxZ &&
+ this.maxZ > other.minZ;
+ // DivineMC end - Math Optimizations
}
public boolean intersects(double x1, double y1, double z1, double x2, double y2, double z2) {
- return this.minX < x2 && this.maxX > x1 && this.minY < y2 && this.maxY > y1 && this.minZ < z2 && this.maxZ > z1;
+ // DivineMC start - Math Optimizations
+ return this.minX < x2 &&
+ this.maxX > x1 &&
+ this.minY < y2 &&
+ this.maxY > y1 &&
+ this.minZ < z2 &&
+ this.maxZ > z1;
+ // DivineMC end - Math Optimizations
}
public boolean intersects(Vec3 min, Vec3 max) {
return this.intersects(
- Math.min(min.x, max.x), Math.min(min.y, max.y), Math.min(min.z, max.z), Math.max(min.x, max.x), Math.max(min.y, max.y), Math.max(min.z, max.z)
+ // DivineMC start - Math Optimizations
+ min.x < max.x ? min.x : max.x,
+ min.y < max.y ? min.y : max.y,
+ min.z < max.z ? min.z : max.z,
+ min.x > max.x ? min.x : max.x,
+ min.y > max.y ? min.y : max.y,
+ min.z > max.z ? min.z : max.z
+ // DivineMC end - Math Optimizations
);
}

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Verify Minecraft EULA earlier
diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java
index 680369af59fd2aa36bf1cf4e28b598854383abe3..d415a175ea1e7b5a5bf1149187247dd7b2619c29 100644
index b48fc9e0b95fe6c8f72c5501b8de374e6ac2e5d6..44e98037c986dec845613fa24f9664ef1803b96c 100644
--- a/net/minecraft/server/Main.java
+++ b/net/minecraft/server/Main.java
@@ -143,7 +143,6 @@ public class Main {
@@ -131,7 +131,6 @@ public class Main {
dedicatedServerSettings.forceSave();
RegionFileVersion.configure(dedicatedServerSettings.getProperties().regionFileComression);
Path path2 = Paths.get("eula.txt");
@@ -16,7 +16,7 @@ index 680369af59fd2aa36bf1cf4e28b598854383abe3..d415a175ea1e7b5a5bf1149187247dd7
// Paper start - load config files early for access below if needed
org.bukkit.configuration.file.YamlConfiguration bukkitConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionSet.valueOf("bukkit-settings"));
org.bukkit.configuration.file.YamlConfiguration spigotConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionSet.valueOf("spigot-settings"));
@@ -166,19 +165,6 @@ public class Main {
@@ -154,19 +153,6 @@ public class Main {
return;
}

View File

@@ -1,32 +0,0 @@
cmake_minimum_required(VERSION 3.25)
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
project(c2me-opts-natives-math C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_COMPILER clang)
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -g")
set(CMAKE_C_STANDARD_LIBRARIES "")
set(CMAKE_CXX_STANDARD_LIBRARIES "")
add_library(c2me-opts-natives-math SHARED
exports.c
system_isa_x86_64.c
exports_x86_64_nogather.c
system_isa_aarch64.c
flibc.c
)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
set_source_files_properties(exports_x86_64_nogather.c PROPERTIES COMPILE_FLAGS "-mno-gather -mno-scatter")
endif()
execute_process(COMMAND llvm-config --prefix OUTPUT_VARIABLE LLVM_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
target_include_directories(c2me-opts-natives-math PRIVATE includes/)
target_compile_options(c2me-opts-natives-math PRIVATE $<$<COMPILE_LANGUAGE:C>:-Wall -Wextra -Wpedantic -ffreestanding -ffile-prefix-map=${CMAKE_SOURCE_DIR}=. -fdebug-compilation-dir=. -fdebug-prefix-map=${CMAKE_SOURCE_DIR}=. -fdebug-prefix-map=${LLVM_PREFIX}=.../llvm-prefix -fno-math-errno -mprefer-vector-width=512 -ffp-contract=off -Rpass-analysis=loop-vectorize -mno-stack-arg-probe -fsave-optimization-record "SHELL:-mllvm -extra-vectorizer-passes" "SHELL:-mllvm -slp-vectorize-hor-store" "SHELL:-mllvm -slp-min-tree-size=1" "SHELL:-mllvm -slp-min-reg-size=64" "SHELL:-mllvm -slp-threshold=-1" "SHELL:-mllvm -enable-epilogue-vectorization">)
target_link_options(c2me-opts-natives-math PRIVATE -v -nostdlib -fuse-ld=lld -ffile-prefix-map=${CMAKE_SOURCE_DIR}=. -fdebug-compilation-dir=. -fdebug-prefix-map=${CMAKE_SOURCE_DIR}=. -fdebug-prefix-map=${LLVM_PREFIX}=.../llvm-prefix)

View File

@@ -1,34 +0,0 @@
#include <ext_math.h>
#include <target_macros.h>
TARGET_IMPL(c2me_natives_noise_perlin_sample, double, (const aligned_uint32_ptr permutations, const double originX,
const double originY, const double originZ, const double x,
const double y, const double z, const double yScale,
const double yMax) {
return math_noise_perlin_sample(permutations, originX, originY, originZ, x, y, z, yScale, yMax);
})
TARGET_IMPL(c2me_natives_noise_perlin_double, double, (const double_octave_sampler_data_t *const data,
const double x, const double y, const double z) {
return math_noise_perlin_double_octave_sample(data, x, y, z);
})
TARGET_IMPL(c2me_natives_noise_perlin_double_batch, void, (const double_octave_sampler_data_t *const data,
double *const res, const double *const x,
const double *const y, const double *const z,
const uint32_t length) {
math_noise_perlin_double_octave_sample_batch(data, res, x, y, z, length);
})
TARGET_IMPL(c2me_natives_noise_interpolated, double, (const interpolated_noise_sampler_t *const data,
const double x, const double y, const double z) {
return math_noise_perlin_interpolated_sample(data, x, y, z);
})
TARGET_IMPL(c2me_natives_end_islands_sample, float, (const aligned_uint32_ptr simplex_permutations, const int32_t x, const int32_t z) {
return math_end_islands_sample(simplex_permutations, x, z);
})
TARGET_IMPL(c2me_natives_biome_access_sample, uint32_t, (const int64_t theSeed, const int32_t x, const int32_t y, const int32_t z) {
return math_biome_access_sample(theSeed, x, y, z);
})

View File

@@ -1,9 +0,0 @@
#ifdef __x86_64__
#define GATHER_DISABLED 1
#include "exports.c"
#endif
typedef int make_iso_compiler_happy;

View File

@@ -1,672 +0,0 @@
#include <stddef.h>
#include <stdint.h>
#include <float.h>
typedef int make_iso_compilers_happy;
#ifdef WIN32
// ld.lld: error: <root>: undefined symbol: DllMainCRTStartup
int __stdcall DllMainCRTStartup(void* instance, unsigned reason, void* reserved)
{
(void) instance;
(void) reason;
(void) reserved;
return 1;
}
// ld.lld: error: undefined symbol: _fltused
int _fltused = 0;
// ld.lld: error: undefined symbol: abort
void abort(void)
{
__builtin_trap();
}
#endif // WIN32
/*
The following code is from musl, original license below:
musl as a whole is licensed under the following standard MIT license:
----------------------------------------------------------------------
Copyright © 2005-2020 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------
*/
// src/internal/libm.h
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
union ldshape {
long double f;
struct {
uint64_t m;
uint16_t se;
} i;
};
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
/* This is the m68k variant of 80-bit long double, and this definition only works
* on archs where the alignment requirement of uint64_t is <= 4. */
union ldshape {
long double f;
struct {
uint16_t se;
uint16_t pad;
uint64_t m;
} i;
};
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
union ldshape {
long double f;
struct {
uint64_t lo;
uint32_t mid;
uint16_t top;
uint16_t se;
} i;
struct {
uint64_t lo;
uint64_t hi;
} i2;
};
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
union ldshape {
long double f;
struct {
uint16_t se;
uint16_t top;
uint32_t mid;
uint64_t lo;
} i;
struct {
uint64_t hi;
uint64_t lo;
} i2;
};
#else
#error Unsupported long double representation
#endif
/* Support non-nearest rounding mode. */
#define WANT_ROUNDING 1
/* Support signaling NaNs. */
#define WANT_SNAN 0
#if WANT_SNAN
#error SNaN is unsupported
#else
#define issignalingf_inline(x) 0
#define issignaling_inline(x) 0
#endif
#ifndef TOINT_INTRINSICS
#define TOINT_INTRINSICS 0
#endif
#if TOINT_INTRINSICS
/* Round x to nearest int in all rounding modes, ties have to be rounded
consistently with converttoint so the results match. If the result
would be outside of [-2^31, 2^31-1] then the semantics is unspecified. */
static double_t roundtoint(double_t);
/* Convert x to nearest int in all rounding modes, ties have to be rounded
consistently with roundtoint. If the result is not representible in an
int32_t then the semantics is unspecified. */
static int32_t converttoint(double_t);
#endif
/* Helps static branch prediction so hot path can be better optimized. */
#ifdef __GNUC__
#define predict_true(x) __builtin_expect(!!(x), 1)
#define predict_false(x) __builtin_expect(x, 0)
#else
#define predict_true(x) (x)
#define predict_false(x) (x)
#endif
/* Evaluate an expression as the specified type. With standard excess
precision handling a type cast or assignment is enough (with
-ffloat-store an assignment is required, in old compilers argument
passing and return statement may not drop excess precision). */
static inline float eval_as_float(float x) {
float y = x;
return y;
}
static inline double eval_as_double(double x) {
double y = x;
return y;
}
/* fp_barrier returns its input, but limits code transformations
as if it had a side-effect (e.g. observable io) and returned
an arbitrary value. */
#ifndef fp_barrierf
#define fp_barrierf fp_barrierf
static inline float fp_barrierf(float x) {
volatile float y = x;
return y;
}
#endif
#ifndef fp_barrier
#define fp_barrier fp_barrier
static inline double fp_barrier(double x) {
volatile double y = x;
return y;
}
#endif
#ifndef fp_barrierl
#define fp_barrierl fp_barrierl
static inline long double fp_barrierl(long double x) {
volatile long double y = x;
return y;
}
#endif
/* fp_force_eval ensures that the input value is computed when that's
otherwise unused. To prevent the constant folding of the input
expression, an additional fp_barrier may be needed or a compilation
mode that does so (e.g. -frounding-math in gcc). Then it can be
used to evaluate an expression for its fenv side-effects only. */
#ifndef fp_force_evalf
#define fp_force_evalf fp_force_evalf
static inline void fp_force_evalf(float x) {
volatile float y;
y = x;
}
#endif
#ifndef fp_force_eval
#define fp_force_eval fp_force_eval
static inline void fp_force_eval(double x) {
volatile double y;
y = x;
}
#endif
#ifndef fp_force_evall
#define fp_force_evall fp_force_evall
static inline void fp_force_evall(long double x) {
volatile long double y;
y = x;
}
#endif
#define FORCE_EVAL(x) do { \
if (sizeof(x) == sizeof(float)) { \
fp_force_evalf(x); \
} else if (sizeof(x) == sizeof(double)) { \
fp_force_eval(x); \
} else { \
fp_force_evall(x); \
} \
} while(0)
#define asuint(f) ((union{float _f; uint32_t _i;}){f})._i
#define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f
#define asuint64(f) ((union{double _f; uint64_t _i;}){f})._i
#define asdouble(i) ((union{uint64_t _i; double _f;}){i})._f
#define EXTRACT_WORDS(hi, lo, d) \
do { \
uint64_t __u = asuint64(d); \
(hi) = __u >> 32; \
(lo) = (uint32_t)__u; \
} while (0)
#define GET_HIGH_WORD(hi, d) \
do { \
(hi) = asuint64(d) >> 32; \
} while (0)
#define GET_LOW_WORD(lo, d) \
do { \
(lo) = (uint32_t)asuint64(d); \
} while (0)
#define INSERT_WORDS(d, hi, lo) \
do { \
(d) = asdouble(((uint64_t)(hi)<<32) | (uint32_t)(lo)); \
} while (0)
#define SET_HIGH_WORD(d, hi) \
INSERT_WORDS(d, hi, (uint32_t)asuint64(d))
#define SET_LOW_WORD(d, lo) \
INSERT_WORDS(d, asuint64(d)>>32, lo)
#define GET_FLOAT_WORD(w, d) \
do { \
(w) = asuint(d); \
} while (0)
#define SET_FLOAT_WORD(d, w) \
do { \
(d) = asfloat(w); \
} while (0)
static int __rem_pio2_large(double *, double *, int, int, int);
static int __rem_pio2(double, double *);
static double __sin(double, double, int);
static double __cos(double, double);
static double __tan(double, double, int);
static double __expo2(double, double);
static int __rem_pio2f(float, double *);
static float __sindf(double);
static float __cosdf(double);
static float __tandf(double, int);
static float __expo2f(float, float);
static int __rem_pio2l(long double, long double *);
static long double __sinl(long double, long double, int);
static long double __cosl(long double, long double);
static long double __tanl(long double, long double, int);
static long double __polevll(long double, const long double *, int);
static long double __p1evll(long double, const long double *, int);
//extern int __signgam;
static double __lgamma_r(double, int *);
static float __lgammaf_r(float, int *);
/* error handling functions */
static float __math_xflowf(uint32_t, float);
static float __math_uflowf(uint32_t);
static float __math_oflowf(uint32_t);
static float __math_divzerof(uint32_t);
static float __math_invalidf(float);
static double __math_xflow(uint32_t, double);
static double __math_uflow(uint32_t);
static double __math_oflow(uint32_t);
static double __math_divzero(uint32_t);
static double __math_invalid(double);
#if LDBL_MANT_DIG != DBL_MANT_DIG
static long double __math_invalidl(long double);
#endif
// src/math/__math_invalidf.c
static float __math_invalidf(float x)
{
return (x - x) / (x - x);
}
// src/math/truncf.c
float truncf(float x) {
union {
float f;
uint32_t i;
} u = {x};
int e = (int) (u.i >> 23 & 0xff) - 0x7f + 9;
uint32_t m;
if (e >= 23 + 9)
return x;
if (e < 9)
e = 1;
m = -1U >> e;
if ((u.i & m) == 0)
return x;
FORCE_EVAL(x + 0x1p120f);
u.i &= ~m;
return u.f;
}
// src/math/floor.c
#if FLT_EVAL_METHOD == 0 || FLT_EVAL_METHOD == 1
#define EPS DBL_EPSILON
#elif FLT_EVAL_METHOD == 2
#define EPS LDBL_EPSILON
#endif
static const double toint = 1 / EPS;
double floor(double x) {
union {
double f;
uint64_t i;
} u = {x};
int e = u.i >> 52 & 0x7ff;
double y;
if (e >= 0x3ff + 52 || x == 0)
return x;
/* y = int(x) - x, where int(x) is an integer neighbor of x */
if (u.i >> 63)
y = x - toint + toint - x;
else
y = x + toint - toint - x;
/* special case because of non-nearest rounding modes */
if (e <= 0x3ff - 1) {
FORCE_EVAL(y);
return u.i >> 63 ? -1 : 0;
}
if (y > 0)
return x + y - 1;
return x + y;
}
// src/math/fmodf.c
float fmodf(float x, float y) {
union {
float f;
uint32_t i;
} ux = {x}, uy = {y};
int ex = ux.i >> 23 & 0xff;
int ey = uy.i >> 23 & 0xff;
uint32_t sx = ux.i & 0x80000000;
uint32_t i;
uint32_t uxi = ux.i;
if (uy.i << 1 == 0 || __builtin_isnan(y) || ex == 0xff)
return (x * y) / (x * y);
if (uxi << 1 <= uy.i << 1) {
if (uxi << 1 == uy.i << 1)
return 0 * x;
return x;
}
/* normalize x and y */
if (!ex) {
for (i = uxi << 9; i >> 31 == 0; ex--, i <<= 1);
uxi <<= -ex + 1;
} else {
uxi &= -1U >> 9;
uxi |= 1U << 23;
}
if (!ey) {
for (i = uy.i << 9; i >> 31 == 0; ey--, i <<= 1);
uy.i <<= -ey + 1;
} else {
uy.i &= -1U >> 9;
uy.i |= 1U << 23;
}
/* x mod y */
for (; ex > ey; ex--) {
i = uxi - uy.i;
if (i >> 31 == 0) {
if (i == 0)
return 0 * x;
uxi = i;
}
uxi <<= 1;
}
i = uxi - uy.i;
if (i >> 31 == 0) {
if (i == 0)
return 0 * x;
uxi = i;
}
for (; uxi >> 23 == 0; uxi <<= 1, ex--);
/* scale result up */
if (ex > 0) {
uxi -= 1U << 23;
uxi |= (uint32_t) ex << 23;
} else {
uxi >>= -ex + 1;
}
uxi |= sx;
ux.i = uxi;
return ux.f;
}
// src/string/memset.c
void *memset(void *dest, int c, size_t n) {
unsigned char *s = dest;
size_t k;
/* Fill head and tail with minimal branching. Each
* conditional ensures that all the subsequently used
* offsets are well-defined and in the dest region. */
if (!n) return dest;
s[0] = c;
s[n - 1] = c;
if (n <= 2) return dest;
s[1] = c;
s[2] = c;
s[n - 2] = c;
s[n - 3] = c;
if (n <= 6) return dest;
s[3] = c;
s[n - 4] = c;
if (n <= 8) return dest;
/* Advance pointer to align it at a 4-byte boundary,
* and truncate n to a multiple of 4. The previous code
* already took care of any head/tail that get cut off
* by the alignment. */
k = -(uintptr_t) s & 3;
s += k;
n -= k;
n &= -4;
#ifdef __GNUC__
typedef uint32_t __attribute__((__may_alias__)) u32;
typedef uint64_t __attribute__((__may_alias__)) u64;
u32 c32 = ((u32) -1) / 255 * (unsigned char) c;
/* In preparation to copy 32 bytes at a time, aligned on
* an 8-byte bounary, fill head/tail up to 28 bytes each.
* As in the initial byte-based head/tail fill, each
* conditional below ensures that the subsequent offsets
* are valid (e.g. !(n<=24) implies n>=28). */
*(u32 *) (s + 0) = c32;
*(u32 *) (s + n - 4) = c32;
if (n <= 8) return dest;
*(u32 *) (s + 4) = c32;
*(u32 *) (s + 8) = c32;
*(u32 *) (s + n - 12) = c32;
*(u32 *) (s + n - 8) = c32;
if (n <= 24) return dest;
*(u32 *) (s + 12) = c32;
*(u32 *) (s + 16) = c32;
*(u32 *) (s + 20) = c32;
*(u32 *) (s + 24) = c32;
*(u32 *) (s + n - 28) = c32;
*(u32 *) (s + n - 24) = c32;
*(u32 *) (s + n - 20) = c32;
*(u32 *) (s + n - 16) = c32;
/* Align to a multiple of 8 so we can fill 64 bits at a time,
* and avoid writing the same bytes twice as much as is
* practical without introducing additional branching. */
k = 24 + ((uintptr_t) s & 4);
s += k;
n -= k;
/* If this loop is reached, 28 tail bytes have already been
* filled, so any remainder when n drops below 32 can be
* safely ignored. */
u64 c64 = c32 | ((u64) c32 << 32);
for (; n >= 32; n -= 32, s += 32) {
*(u64 *) (s + 0) = c64;
*(u64 *) (s + 8) = c64;
*(u64 *) (s + 16) = c64;
*(u64 *) (s + 24) = c64;
}
#else
/* Pure C fallback with no aliasing violations. */
for (; n; n--, s++) *s = c;
#endif
return dest;
}
// src/math/sqrt_data.[c|h]
/* if x in [1,2): i = (int)(64*x);
if x in [2,4): i = (int)(32*x-64);
__rsqrt_tab[i]*2^-16 is estimating 1/sqrt(x) with small relative error:
|__rsqrt_tab[i]*0x1p-16*sqrt(x) - 1| < -0x1.fdp-9 < 2^-8 */
extern const uint16_t __rsqrt_tab[128] = {
0xb451, 0xb2f0, 0xb196, 0xb044, 0xaef9, 0xadb6, 0xac79, 0xab43,
0xaa14, 0xa8eb, 0xa7c8, 0xa6aa, 0xa592, 0xa480, 0xa373, 0xa26b,
0xa168, 0xa06a, 0x9f70, 0x9e7b, 0x9d8a, 0x9c9d, 0x9bb5, 0x9ad1,
0x99f0, 0x9913, 0x983a, 0x9765, 0x9693, 0x95c4, 0x94f8, 0x9430,
0x936b, 0x92a9, 0x91ea, 0x912e, 0x9075, 0x8fbe, 0x8f0a, 0x8e59,
0x8daa, 0x8cfe, 0x8c54, 0x8bac, 0x8b07, 0x8a64, 0x89c4, 0x8925,
0x8889, 0x87ee, 0x8756, 0x86c0, 0x862b, 0x8599, 0x8508, 0x8479,
0x83ec, 0x8361, 0x82d8, 0x8250, 0x81c9, 0x8145, 0x80c2, 0x8040,
0xff02, 0xfd0e, 0xfb25, 0xf947, 0xf773, 0xf5aa, 0xf3ea, 0xf234,
0xf087, 0xeee3, 0xed47, 0xebb3, 0xea27, 0xe8a3, 0xe727, 0xe5b2,
0xe443, 0xe2dc, 0xe17a, 0xe020, 0xdecb, 0xdd7d, 0xdc34, 0xdaf1,
0xd9b3, 0xd87b, 0xd748, 0xd61a, 0xd4f1, 0xd3cd, 0xd2ad, 0xd192,
0xd07b, 0xcf69, 0xce5b, 0xcd51, 0xcc4a, 0xcb48, 0xca4a, 0xc94f,
0xc858, 0xc764, 0xc674, 0xc587, 0xc49d, 0xc3b7, 0xc2d4, 0xc1f4,
0xc116, 0xc03c, 0xbf65, 0xbe90, 0xbdbe, 0xbcef, 0xbc23, 0xbb59,
0xba91, 0xb9cc, 0xb90a, 0xb84a, 0xb78c, 0xb6d0, 0xb617, 0xb560,
};
// src/math/sqrtf.c
#define FENV_SUPPORT 1
static inline uint32_t mul32(uint32_t a, uint32_t b) {
return (uint64_t) a * b >> 32;
}
/* see sqrt.c for more detailed comments. */
float sqrtf(float x) {
uint32_t ix, m, m1, m0, even, ey;
ix = asuint(x);
if (predict_false(ix - 0x00800000 >= 0x7f800000 - 0x00800000)) {
/* x < 0x1p-126 or inf or nan. */
if (ix * 2 == 0)
return x;
if (ix == 0x7f800000)
return x;
if (ix > 0x7f800000)
return __math_invalidf(x);
/* x is subnormal, normalize it. */
ix = asuint(x * 0x1p23f);
ix -= 23 << 23;
}
/* x = 4^e m; with int e and m in [1, 4). */
even = ix & 0x00800000;
m1 = (ix << 8) | 0x80000000;
m0 = (ix << 7) & 0x7fffffff;
m = even ? m0 : m1;
/* 2^e is the exponent part of the return value. */
ey = ix >> 1;
ey += 0x3f800000 >> 1;
ey &= 0x7f800000;
/* compute r ~ 1/sqrt(m), s ~ sqrt(m) with 2 goldschmidt iterations. */
static const uint32_t three = 0xc0000000;
uint32_t r, s, d, u, i;
i = (ix >> 17) % 128;
r = (uint32_t) __rsqrt_tab[i] << 16;
/* |r*sqrt(m) - 1| < 0x1p-8 */
s = mul32(m, r);
/* |s/sqrt(m) - 1| < 0x1p-8 */
d = mul32(s, r);
u = three - d;
r = mul32(r, u) << 1;
/* |r*sqrt(m) - 1| < 0x1.7bp-16 */
s = mul32(s, u) << 1;
/* |s/sqrt(m) - 1| < 0x1.7bp-16 */
d = mul32(s, r);
u = three - d;
s = mul32(s, u);
/* -0x1.03p-28 < s/sqrt(m) - 1 < 0x1.fp-31 */
s = (s - 1) >> 6;
/* s < sqrt(m) < s + 0x1.08p-23 */
/* compute nearest rounded result. */
uint32_t d0, d1, d2;
float y, t;
d0 = (m << 16) - s * s;
d1 = s - d0;
d2 = d1 + s + 1;
s += d1 >> 31;
s &= 0x007fffff;
s |= ey;
y = asfloat(s);
if (FENV_SUPPORT) {
/* handle rounding and inexact exception. */
uint32_t tiny = predict_false(d2 == 0) ? 0 : 0x01000000;
tiny |= (d1 ^ d2) & 0x80000000;
t = asfloat(tiny);
y = eval_as_float(y + t);
}
return y;
}

View File

@@ -1,744 +0,0 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <float.h>
__attribute__((aligned(64))) static const double FLAT_SIMPLEX_GRAD[] = {
1, 1, 0, 0,
-1, 1, 0, 0,
1, -1, 0, 0,
-1, -1, 0, 0,
1, 0, 1, 0,
-1, 0, 1, 0,
1, 0, -1, 0,
-1, 0, -1, 0,
0, 1, 1, 0,
0, -1, 1, 0,
0, 1, -1, 0,
0, -1, -1, 0,
1, 1, 0, 0,
0, -1, 1, 0,
-1, 1, 0, 0,
0, -1, -1, 0,
};
static const double SQRT_3 = 1.7320508075688772;
// 0.5 * (SQRT_3 - 1.0)
static const double SKEW_FACTOR_2D = 0.3660254037844386;
// (3.0 - SQRT_3) / 6.0
static const double UNSKEW_FACTOR_2D = 0.21132486540518713;
typedef const double *aligned_double_ptr __attribute__((align_value(64)));
typedef const uint8_t *aligned_uint8_ptr __attribute__((align_value(64)));
typedef const uint32_t *aligned_uint32_ptr __attribute__((align_value(64)));
#pragma clang attribute push (__attribute__((always_inline)), apply_to = function)
static inline __attribute__((const)) float fminf(const float x, const float y) {
return __builtin_fminf(x, y);
}
static inline __attribute__((const)) float fmaxf(const float x, const float y) {
return __builtin_fmaxf(x, y);
}
static inline __attribute__((const)) float fabsf(const float x) {
union {
float f;
uint32_t i;
} u = {x};
u.i &= 0x7fffffff;
return u.f;
}
static inline __attribute__((const)) int64_t labs(const int64_t x) {
return __builtin_labs(x);
}
static inline __attribute__((const)) double floor(double x) {
return __builtin_floor(x);
}
static inline __attribute__((const)) float sqrtf(float x) {
return __builtin_sqrtf(x);
}
static inline __attribute__((const)) float fmodf(float x, float y) {
return __builtin_fmodf(x, y);
}
static inline __attribute__((const)) int32_t math_floorDiv(const int32_t x, const int32_t y) {
int r = x / y;
// if the signs are different and modulo not zero, round down
if ((x ^ y) < 0 && (r * y != x)) {
r--;
}
return r;
}
static inline __attribute__((const)) float clampf(const float value, const float min, const float max) {
return fminf(fmaxf(value, min), max);
}
static inline __attribute__((const)) double math_octave_maintainPrecision(const double value) {
return value - floor(value / 3.3554432E7 + 0.5) * 3.3554432E7;
}
static inline __attribute__((const)) double math_simplex_grad(const int32_t hash, const double x, const double y,
const double z, const double distance) {
double d = distance - x * x - y * y - z * z;
if (d < 0.0) {
return 0.0;
} else {
int32_t i = hash << 2;
double var0 = FLAT_SIMPLEX_GRAD[i | 0] * x;
double var1 = FLAT_SIMPLEX_GRAD[i | 1] * y;
double var2 = FLAT_SIMPLEX_GRAD[i | 2] * z;
return d * d * d * d * (var0 + var1 + var2);
}
}
static inline __attribute__((const)) double math_lerp(const double delta, const double start, const double end) {
return start + delta * (end - start);
}
static inline __attribute__((const)) float math_lerpf(const float delta, const float start, const float end) {
return start + delta * (end - start);
}
static inline __attribute__((const)) double math_clampedLerp(const double start, const double end, const double delta) {
if (delta < 0.0) {
return start;
} else {
return delta > 1.0 ? end : math_lerp(delta, start, end);
}
}
static inline __attribute__((const)) double math_square(const double operand) {
return operand * operand;
}
static inline __attribute__((const)) double math_lerp2(const double deltaX, const double deltaY, const double x0y0,
const double x1y0, const double x0y1, const double x1y1) {
return math_lerp(deltaY, math_lerp(deltaX, x0y0, x1y0), math_lerp(deltaX, x0y1, x1y1));
}
static inline __attribute__((const)) double math_lerp3(
const double deltaX,
const double deltaY,
const double deltaZ,
const double x0y0z0,
const double x1y0z0,
const double x0y1z0,
const double x1y1z0,
const double x0y0z1,
const double x1y0z1,
const double x0y1z1,
const double x1y1z1
) {
return math_lerp(deltaZ, math_lerp2(deltaX, deltaY, x0y0z0, x1y0z0, x0y1z0, x1y1z0),
math_lerp2(deltaX, deltaY, x0y0z1, x1y0z1, x0y1z1, x1y1z1));
}
static inline __attribute__((const)) double math_getLerpProgress(const double value, const double start,
const double end) {
return (value - start) / (end - start);
}
static inline __attribute__((const)) double
math_clampedLerpFromProgress(const double lerpValue, const double lerpStart, const double lerpEnd, const double start,
const double end) {
return math_clampedLerp(start, end, math_getLerpProgress(lerpValue, lerpStart, lerpEnd));
}
static inline __attribute__((const)) int32_t math_floorMod(const int32_t x, const int32_t y) {
int32_t mod = x % y;
// if the signs are different and modulo not zero, adjust result
if ((mod ^ y) < 0 && mod != 0) {
mod += y;
}
return mod;
}
static inline __attribute__((const)) int32_t math_biome2block(const int32_t biomeCoord) {
return biomeCoord << 2;
}
static inline __attribute__((const)) int32_t math_block2biome(const int32_t blockCoord) {
return blockCoord >> 2;
}
static inline __attribute__((const)) uint32_t
__math_simplex_map(const aligned_uint32_ptr permutations, const int32_t input) {
return permutations[input & 0xFF];
}
static inline __attribute__((const)) double math_simplex_dot(const int32_t hash, const double x, const double y,
const double z) {
const int32_t loc = hash << 2;
return FLAT_SIMPLEX_GRAD[loc + 0] * x + FLAT_SIMPLEX_GRAD[loc + 1] * y + FLAT_SIMPLEX_GRAD[loc + 2] * z;
}
static inline __attribute__((const)) double __math_simplex_grad(const int32_t hash, const double x, const double y,
const double z, const double distance) {
double d = distance - x * x - y * y - z * z;
double e;
if (d < 0.0) {
e = 0.0;
} else {
d *= d;
e = d * d * math_simplex_dot(hash, x, y, z);
}
return e;
// double tmp = d * d; // speculative execution
// return d < 0.0 ? 0.0 : tmp * tmp * math_simplex_dot(hash, x, y, z);
}
static inline double __attribute__((const))
math_noise_simplex_sample2d(const aligned_uint32_ptr permutations, const double x, const double y) {
const double d = (x + y) * SKEW_FACTOR_2D;
const double i = floor(x + d);
const double j = floor(y + d);
const double e = (i + j) * UNSKEW_FACTOR_2D;
const double f = i - e;
const double g = j - e;
const double h = x - f;
const double k = y - g;
double l;
int32_t li;
double m;
int32_t mi;
if (h > k) {
l = 1;
li = 1;
m = 0;
mi = 0;
} else {
l = 0;
li = 1;
m = 1;
mi = 1;
}
const double n = h - (double) l + UNSKEW_FACTOR_2D;
const double o = k - (double) m + UNSKEW_FACTOR_2D;
const double p = h - 1.0 + 2.0 * UNSKEW_FACTOR_2D;
const double q = k - 1.0 + 2.0 * UNSKEW_FACTOR_2D;
const int32_t r = (int32_t) i & 0xFF;
const int32_t s = (int32_t) j & 0xFF;
const int32_t t = __math_simplex_map(permutations, r + __math_simplex_map(permutations, s)) % 12;
const int32_t u = __math_simplex_map(permutations, r + li + __math_simplex_map(permutations, s + mi)) % 12;
const int32_t v = __math_simplex_map(permutations, r + 1 + __math_simplex_map(permutations, s + 1)) % 12;
const double w = __math_simplex_grad(t, h, k, 0.0, 0.5);
const double z = __math_simplex_grad(u, n, o, 0.0, 0.5);
const double aa = __math_simplex_grad(v, p, q, 0.0, 0.5);
return 70.0 * (w + z + aa);
}
static inline __attribute__((const)) double math_perlinFade(const double value) {
return value * value * value * (value * (value * 6.0 - 15.0) + 10.0);
}
static inline __attribute__((const)) double __math_perlin_grad(const aligned_uint32_ptr permutations, const int32_t px,
const int32_t py, const int32_t pz, const double fx,
const double fy, const double fz) {
const double f[3] = {fx, fy, fz};
const int32_t p[3] = {px, py, pz};
const uint32_t q[3] = {p[0] & 0xFF, p[1] & 0xFF, p[2] & 0xFF};
const uint32_t hash = permutations[(permutations[(permutations[q[0]] + q[1]) & 0xFF] + q[2]) & 0xFF] & 0xF;
const double *const grad = FLAT_SIMPLEX_GRAD + (hash << 2);
return grad[0] * f[0] + grad[1] * f[1] + grad[2] * f[2];
}
static inline __attribute__((const)) double
math_noise_perlin_sampleScalar(const aligned_uint32_ptr permutations,
const int32_t px0, const int32_t py0, const int32_t pz0,
const double fx0, const double fy0, const double fz0, const double fadeLocalY) {
const int32_t px1 = px0 + 1;
const int32_t py1 = py0 + 1;
const int32_t pz1 = pz0 + 1;
const double fx1 = fx0 - 1;
const double fy1 = fy0 - 1;
const double fz1 = fz0 - 1;
const double f000 = __math_perlin_grad(permutations, px0, py0, pz0, fx0, fy0, fz0);
const double f100 = __math_perlin_grad(permutations, px1, py0, pz0, fx1, fy0, fz0);
const double f010 = __math_perlin_grad(permutations, px0, py1, pz0, fx0, fy1, fz0);
const double f110 = __math_perlin_grad(permutations, px1, py1, pz0, fx1, fy1, fz0);
const double f001 = __math_perlin_grad(permutations, px0, py0, pz1, fx0, fy0, fz1);
const double f101 = __math_perlin_grad(permutations, px1, py0, pz1, fx1, fy0, fz1);
const double f011 = __math_perlin_grad(permutations, px0, py1, pz1, fx0, fy1, fz1);
const double f111 = __math_perlin_grad(permutations, px1, py1, pz1, fx1, fy1, fz1);
const double dx = math_perlinFade(fx0);
const double dy = math_perlinFade(fadeLocalY);
const double dz = math_perlinFade(fz0);
return math_lerp3(dx, dy, dz, f000, f100, f010, f110, f001, f101, f011, f111);
}
static inline __attribute__((const)) double
math_noise_perlin_sample(const aligned_uint32_ptr permutations,
const double originX, const double originY, const double originZ,
const double x, const double y, const double z,
const double yScale, const double yMax) {
const double d = x + originX;
const double e = y + originY;
const double f = z + originZ;
const double i = floor(d);
const double j = floor(e);
const double k = floor(f);
const double g = d - i;
const double h = e - j;
const double l = f - k;
const double o = yScale != 0 ? floor(((yMax >= 0.0 && yMax < h) ? yMax : h) / yScale + 1.0E-7) * yScale : 0;
return math_noise_perlin_sampleScalar(permutations, (int32_t) i, (int32_t) j, (int32_t) k, g, h - o, l, h);
}
typedef const struct double_octave_sampler_data {
const uint64_t length;
const double amplitude;
const bool *const need_shift;
const aligned_double_ptr lacunarity_powd;
const aligned_double_ptr persistence_powd;
const aligned_uint32_ptr sampler_permutations;
const aligned_double_ptr sampler_originX;
const aligned_double_ptr sampler_originY;
const aligned_double_ptr sampler_originZ;
const aligned_double_ptr amplitudes;
} double_octave_sampler_data_t;
static inline __attribute__((const)) double
math_noise_perlin_double_octave_sample_impl(const double_octave_sampler_data_t *const data,
const double x, const double y, const double z,
const double yScale, const double yMax, const uint8_t useOrigin) {
double ds[data->length];
#pragma clang loop vectorize(enable) interleave(enable) interleave_count(2)
for (uint32_t i = 0; i < data->length; i++) {
const double e = data->lacunarity_powd[i];
const double f = data->persistence_powd[i];
const aligned_uint32_ptr permutations = data->sampler_permutations + 256 * i;
const double sampleX = data->need_shift[i] ? x * 1.0181268882175227 : x;
const double sampleY = data->need_shift[i] ? y * 1.0181268882175227 : y;
const double sampleZ = data->need_shift[i] ? z * 1.0181268882175227 : z;
const double g = math_noise_perlin_sample(
permutations,
data->sampler_originX[i],
data->sampler_originY[i],
data->sampler_originZ[i],
math_octave_maintainPrecision(sampleX * e),
useOrigin ? -(data->sampler_originY[i]) : math_octave_maintainPrecision(sampleY * e),
math_octave_maintainPrecision(sampleZ * e),
yScale * e,
yMax * e);
ds[i] = data->amplitudes[i] * g * f;
}
double d1 = 0.0;
double d2 = 0.0;
for (uint32_t i = 0; i < data->length; i++) {
if (!data->need_shift[i]) {
d1 += ds[i];
} else {
d2 += ds[i];
}
}
return (d1 + d2) * data->amplitude;
}
//static inline void
//math_noise_perlin_double_octave_sample_impl_batch(const double_octave_sampler_data_t *const data, double *const res,
// const double *const x, const double *const y, const double *const z,
// const uint32_t length) {
// double ds[data->length][length];
//
// for (uint32_t si = 0; si < data->length; si ++) {
//#pragma clang loop vectorize(enable) interleave(enable) interleave_count(2)
// for (uint32_t bi = 0; bi < length; bi++) {
// const double e = data->lacunarity_powd[si];
// const double f = data->persistence_powd[si];
// const aligned_uint32_ptr permutations = data->sampler_permutations + 256 * si;
// const double sampleX = data->need_shift[si] ? x[bi] * 1.0181268882175227 : x[bi];
// const double sampleY = data->need_shift[si] ? y[bi] * 1.0181268882175227 : y[bi];
// const double sampleZ = data->need_shift[si] ? z[bi] * 1.0181268882175227 : z[bi];
// const double g = math_noise_perlin_sample(
// permutations,
// data->sampler_originX[si],
// data->sampler_originY[si],
// data->sampler_originZ[si],
// math_octave_maintainPrecision(sampleX * e),
// math_octave_maintainPrecision(sampleY * e),
// math_octave_maintainPrecision(sampleZ * e),
// 0.0,
// 0.0);
// ds[si][bi] = data->amplitudes[si] * g * f;
// }
// }
//
// double d1[length];
// double d2[length];
// for (uint32_t i = 0; i < length; i ++) {
// d1[i] = 0.0;
// d2[i] = 0.0;
// }
// for (uint32_t bi = 0; bi < length; bi++) {
// for (uint32_t si = 0; si < data->length; si ++) {
// if (!data->need_shift[si]) {
// d1[bi] += ds[si][bi];
// } else {
// d2[bi] += ds[si][bi];
// }
// }
// }
// for (uint32_t bi = 0; bi < length; bi++) {
// res[bi] = (d1[bi] + d2[bi]) * data->amplitude;
// }
//}
//static inline void
//math_noise_perlin_double_octave_sample_impl_batch(const double_octave_sampler_data_t *restrict const data,
// double *restrict const res, const double *restrict const x,
// const double *restrict const y, const double *restrict const z,
// const uint32_t length) {
// const uint32_t total_len = data->length * length;
//
// double ds[total_len];
// uint32_t sia[total_len]; // sampler index array
// uint32_t bia[total_len]; // batch index array
// double xa[total_len]; // x array
// double ya[total_len]; // y array
// double za[total_len]; // z array
//
// double lacunarity_powd[total_len];
// double persistence_powd[total_len];
// bool need_shift[total_len];
// double sampler_originX[total_len];
// double sampler_originY[total_len];
// double sampler_originZ[total_len];
// double amplitudes[total_len];
//
// {
// uint32_t idx = 0;
// for (uint32_t si = 0; si < data->length; si++) {
// for (uint32_t bi = 0; bi < length; bi++) {
// sia[idx] = si;
// bia[idx] = bi;
// xa[idx] = x[bi];
// ya[idx] = y[bi];
// za[idx] = z[bi];
// lacunarity_powd[idx] = data->lacunarity_powd[si];
// persistence_powd[idx] = data->persistence_powd[si];
// need_shift[idx] = data->need_shift[si];
// sampler_originX[idx] = data->sampler_originX[si];
// sampler_originY[idx] = data->sampler_originY[si];
// sampler_originZ[idx] = data->sampler_originZ[si];
// amplitudes[idx] = data->amplitudes[si];
// idx++;
// }
// }
// }
//
//#pragma clang loop vectorize(enable) interleave(enable) interleave_count(2)
// for (uint32_t idx = 0; idx < total_len; idx++) {
// const uint32_t si = sia[idx];
// const double xi = xa[idx];
// const double yi = ya[idx];
// const double zi = za[idx];
// const double e = lacunarity_powd[idx];
// const double f = persistence_powd[idx];
// const aligned_uint32_ptr permutations = data->sampler_permutations + 256 * si;
// const double sampleX = need_shift[idx] ? xi * 1.0181268882175227 : xi;
// const double sampleY = need_shift[idx] ? yi * 1.0181268882175227 : yi;
// const double sampleZ = need_shift[idx] ? zi * 1.0181268882175227 : zi;
// const double g = math_noise_perlin_sample(
// permutations,
// sampler_originX[idx],
// sampler_originY[idx],
// sampler_originZ[idx],
// math_octave_maintainPrecision(sampleX * e),
// math_octave_maintainPrecision(sampleY * e),
// math_octave_maintainPrecision(sampleZ * e),
// 0.0,
// 0.0);
// ds[idx] = amplitudes[idx] * g * f;
// }
//
// double d1[length];
// double d2[length];
// for (uint32_t i = 0; i < length; i++) {
// d1[i] = 0.0;
// d2[i] = 0.0;
// }
// for (uint32_t idx = 0; idx < total_len; idx++) {
// const uint32_t si = sia[idx];
// const uint32_t bi = bia[idx];
// if (!data->need_shift[si]) {
// d1[bi] += ds[idx];
// } else {
// d2[bi] += ds[idx];
// }
// }
// for (uint32_t bi = 0; bi < length; bi++) {
// res[bi] = (d1[bi] + d2[bi]) * data->amplitude;
// }
//}
static inline __attribute__((const)) double
math_noise_perlin_double_octave_sample(const double_octave_sampler_data_t *const data,
const double x, const double y, const double z) {
return math_noise_perlin_double_octave_sample_impl(data, x, y, z, 0.0, 0.0, 0);
}
static inline void
math_noise_perlin_double_octave_sample_batch(const double_octave_sampler_data_t *const data, double *const res,
const double *const x, const double *const y, const double *const z,
const uint32_t length) {
// math_noise_perlin_double_octave_sample_impl_batch(data, res, x, y, z, length);
for (uint32_t i = 0; i < length; i ++) {
res[i] = math_noise_perlin_double_octave_sample_impl(data, x[i], y[i], z[i], 0.0, 0.0, 0);
}
}
typedef const struct interpolated_noise_sub_sampler {
const aligned_uint32_ptr sampler_permutations;
const aligned_double_ptr sampler_originX;
const aligned_double_ptr sampler_originY;
const aligned_double_ptr sampler_originZ;
const aligned_double_ptr sampler_mulFactor;
const uint32_t length;
} interpolated_noise_sub_sampler_t;
typedef const struct interpolated_noise_sampler {
const double scaledXzScale;
const double scaledYScale;
const double xzFactor;
const double yFactor;
const double smearScaleMultiplier;
const double xzScale;
const double yScale;
const interpolated_noise_sub_sampler_t lower;
const interpolated_noise_sub_sampler_t upper;
const interpolated_noise_sub_sampler_t normal;
} interpolated_noise_sampler_t;
static inline __attribute__((const)) double
math_noise_perlin_interpolated_sample(const interpolated_noise_sampler_t *const data,
const double x, const double y, const double z) {
const double d = x * data->scaledXzScale;
const double e = y * data->scaledYScale;
const double f = z * data->scaledXzScale;
const double g = d / data->xzFactor;
const double h = e / data->yFactor;
const double i = f / data->xzFactor;
const double j = data->scaledYScale * data->smearScaleMultiplier;
const double k = j / data->yFactor;
double l = 0.0;
double m = 0.0;
double n = 0.0;
double ns[data->normal.length];
#pragma clang loop vectorize(enable)
for (uint32_t offset = 0; offset < data->normal.length; offset++) {
ns[offset] = math_noise_perlin_sample(
data->normal.sampler_permutations + 256 * offset,
data->normal.sampler_originX[offset],
data->normal.sampler_originY[offset],
data->normal.sampler_originZ[offset],
math_octave_maintainPrecision(g * data->normal.sampler_mulFactor[offset]),
math_octave_maintainPrecision(h * data->normal.sampler_mulFactor[offset]),
math_octave_maintainPrecision(i * data->normal.sampler_mulFactor[offset]),
k * data->normal.sampler_mulFactor[offset],
h * data->normal.sampler_mulFactor[offset]
) / data->normal.sampler_mulFactor[offset];
}
for (uint32_t offset = 0; offset < data->normal.length; offset++) {
n += ns[offset];
}
const double q = (n / 10.0 + 1.0) / 2.0;
const uint8_t bl2 = q >= 1.0;
const uint8_t bl3 = q <= 0.0;
if (!bl2) {
double ls[data->lower.length];
#pragma clang loop vectorize(enable) interleave_count(2)
for (uint32_t offset = 0; offset < data->lower.length; offset++) {
ls[offset] = math_noise_perlin_sample(
data->lower.sampler_permutations + 256 * offset,
data->lower.sampler_originX[offset],
data->lower.sampler_originY[offset],
data->lower.sampler_originZ[offset],
math_octave_maintainPrecision(d * data->lower.sampler_mulFactor[offset]),
math_octave_maintainPrecision(e * data->lower.sampler_mulFactor[offset]),
math_octave_maintainPrecision(f * data->lower.sampler_mulFactor[offset]),
j * data->lower.sampler_mulFactor[offset],
e * data->lower.sampler_mulFactor[offset]
) / data->lower.sampler_mulFactor[offset];
}
for (uint32_t offset = 0; offset < data->lower.length; offset++) {
l += ls[offset];
}
}
if (!bl3) {
double ms[data->upper.length];
#pragma clang loop vectorize(enable) interleave_count(2)
for (uint32_t offset = 0; offset < data->upper.length; offset++) {
ms[offset] = math_noise_perlin_sample(
data->upper.sampler_permutations + 256 * offset,
data->upper.sampler_originX[offset],
data->upper.sampler_originY[offset],
data->upper.sampler_originZ[offset],
math_octave_maintainPrecision(d * data->upper.sampler_mulFactor[offset]),
math_octave_maintainPrecision(e * data->upper.sampler_mulFactor[offset]),
math_octave_maintainPrecision(f * data->upper.sampler_mulFactor[offset]),
j * data->upper.sampler_mulFactor[offset],
e * data->upper.sampler_mulFactor[offset]
) / data->upper.sampler_mulFactor[offset];
}
for (uint32_t offset = 0; offset < data->upper.length; offset++) {
m += ms[offset];
}
}
return math_clampedLerp(l / 512.0, m / 512.0, q) / 128.0;
}
static inline __attribute__((const)) float
math_end_islands_sample(const aligned_uint32_ptr simplex_permutations, const int32_t x, const int32_t z) {
const int32_t i = x / 2;
const int32_t j = z / 2;
const int32_t k = x % 2;
const int32_t l = z % 2;
const int32_t muld = x * x + z * z; // int32_t intentionally
if (muld < 0) {
return __builtin_nanf("");
}
float f = 100.0F - sqrtf((float) muld) * 8.0F;
f = clampf(f, -100.0F, 80.0F);
int8_t ms[25 * 25], ns[25 * 25], hit[25 * 25];
const int64_t omin = labs(i) - 12LL;
const int64_t pmin = labs(j) - 12LL;
const int64_t omax = labs(i) + 12LL;
const int64_t pmax = labs(j) + 12LL;
{
uint32_t idx = 0;
#pragma clang loop vectorize(enable)
for (int8_t m = -12; m < 13; m++) {
for (int8_t n = -12; n < 13; n++) {
ms[idx] = m;
ns[idx] = n;
idx++;
}
}
if (idx != 25 * 25) {
__builtin_trap();
}
}
if (omin * omin + pmin * pmin > 4096LL) {
for (uint32_t idx = 0; idx < 25 * 25; idx++) {
const int64_t o = (int64_t) i + (int64_t) ms[idx];
const int64_t p = (int64_t) j + (int64_t) ns[idx];
hit[idx] = math_noise_simplex_sample2d(simplex_permutations, (double) o, (double) p) < -0.9F;
}
} else {
for (uint32_t idx = 0; idx < 25 * 25; idx++) {
const int64_t o = (int64_t) i + (int64_t) ms[idx];
const int64_t p = (int64_t) j + (int64_t) ns[idx];
hit[idx] = (o * o + p * p > 4096LL) && math_noise_simplex_sample2d(
simplex_permutations, (double) o, (double) p) < -0.9F;
}
}
#pragma clang loop vectorize(enable) interleave(enable)
for (uint32_t idx = 0; idx < 25 * 25; idx++) {
if (hit[idx]) {
const int32_t m = ms[idx];
const int32_t n = ns[idx];
const int64_t o = (int64_t) i + (int64_t) m;
const int64_t p = (int64_t) j + (int64_t) n;
const float g1 = fabsf((float) o) * 3439.0F;
const float g2 = fabsf((float) p) * 147.0F;
const float g = fmodf((g1 + g2), 13.0F) + 9.0F;
const float h = (float) (k - m * 2);
const float q = (float) (l - n * 2);
float r = 100.0F - sqrtf(h * h + q * q) * g;
r = clampf(r, -100.0F, 80.0F);
f = fmaxf(f, r);
}
}
return f;
}
static inline __attribute__((const)) uint32_t
math_biome_access_sample(const int64_t theSeed, const int32_t x, const int32_t y, const int32_t z) {
const int32_t var0 = x - 2;
const int32_t var1 = y - 2;
const int32_t var2 = z - 2;
const int32_t var3 = var0 >> 2;
const int32_t var4 = var1 >> 2;
const int32_t var5 = var2 >> 2;
const double var6 = (double) (var0 & 3) / 4.0;
const double var7 = (double) (var1 & 3) / 4.0;
const double var8 = (double) (var2 & 3) / 4.0;
uint32_t var9 = 0;
double var10 = DBL_MAX;
double var28s[8];
#pragma clang loop interleave_count(2)
for (uint32_t var11 = 0; var11 < 8; ++var11) {
uint32_t var12 = var11 & 4;
uint32_t var13 = var11 & 2;
uint32_t var14 = var11 & 1;
int64_t var15 = var12 ? var3 + 1 : var3;
int64_t var16 = var13 ? var4 + 1 : var4;
int64_t var17 = var14 ? var5 + 1 : var5;
double var18 = var12 ? var6 - 1.0 : var6;
double var19 = var13 ? var7 - 1.0 : var7;
double var20 = var14 ? var8 - 1.0 : var8;
int64_t var21 = theSeed * (theSeed * 6364136223846793005L + 1442695040888963407L) + var15;
var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var16;
var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var17;
var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var15;
var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var16;
var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var17;
double var22 = (double) ((var21 >> 24) & 1023) / 1024.0;
double var23 = (var22 - 0.5) * 0.9;
var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + theSeed;
double var24 = (double) ((var21 >> 24) & 1023) / 1024.0;
double var25 = (var24 - 0.5) * 0.9;
var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + theSeed;
double var26 = (double) ((var21 >> 24) & 1023) / 1024.0;
double var27 = (var26 - 0.5) * 0.9;
double var28 = math_square(var20 + var27) + math_square(var19 + var25) + math_square(var18 + var23);
var28s[var11] = var28;
}
for (int i = 0; i < 8; ++i) {
if (var10 > var28s[i]) {
var9 = i;
var10 = var28s[i];
}
}
return var9;
}
#pragma clang attribute pop

View File

@@ -1,28 +0,0 @@
#pragma once
#define TARGET_IMPL_ARCH(suffix, func_prefix, func_ret, func_call) \
func_ret func_prefix##_##suffix func_call
#ifdef __x86_64__
#ifdef GATHER_DISABLED
#define TARGET_IMPL(func_prefix, func_ret, func_call) \
__attribute__((pure, target("arch=haswell"))) TARGET_IMPL_ARCH(avx2, func_prefix, func_ret, func_call) \
__attribute__((pure, target("arch=skylake-avx512"))) TARGET_IMPL_ARCH(avx512skx, func_prefix, func_ret, func_call) \
__attribute__((pure, target("arch=icelake-server"))) TARGET_IMPL_ARCH(avx512icl, func_prefix, func_ret, func_call)
#else
#define TARGET_IMPL(func_prefix, func_ret, func_call) \
__attribute__((pure, target("arch=x86-64"))) TARGET_IMPL_ARCH(sse2, func_prefix, func_ret, func_call) \
__attribute__((pure, target("arch=x86-64-v2"))) TARGET_IMPL_ARCH(sse4_2, func_prefix, func_ret, func_call) \
__attribute__((pure, target("arch=sandybridge"))) TARGET_IMPL_ARCH(avx, func_prefix, func_ret, func_call) \
__attribute__((pure, target("arch=alderlake"))) TARGET_IMPL_ARCH(avx2adl, func_prefix, func_ret, func_call) \
__attribute__((pure, target("arch=sapphirerapids"))) TARGET_IMPL_ARCH(avx512spr, func_prefix, func_ret, func_call)
#endif
#else
#define TARGET_IMPL(func_prefix, func_ret, func_call) \
__attribute__((pure)) TARGET_IMPL_ARCH(generic, func_prefix, func_ret, func_call)
#endif

View File

@@ -1,11 +0,0 @@
#ifdef __aarch64__
#include <stdint.h>
int32_t c2me_natives_get_system_isa(_Bool allowAVX512) {
return 0;
}
#endif
typedef int make_iso_compiler_happy;

View File

@@ -1,154 +0,0 @@
#ifdef __x86_64__
#include <stdint.h>
static void __cpuid(int info[4], int infoType) {
__asm__ __volatile__("cpuid" : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3]) : "0"(infoType));
}
static void __cpuidex(int info[4], int level, int count) {
__asm__ __volatile__("cpuid" : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3]) : "0"(level), "2"(count));
}
static int __os_has_avx_support(void) {
// Check xgetbv; this uses a .byte sequence instead of the instruction
// directly because older assemblers do not include support for xgetbv and
// there is no easy way to conditionally compile based on the assembler used.
int rEAX, rEDX;
__asm__ __volatile__(".byte 0x0f, 0x01, 0xd0" : "=a"(rEAX), "=d"(rEDX) : "c"(0));
return (rEAX & 6) == 6;
}
#if !defined(__APPLE__)
static int __os_has_avx512_support(void) {
// Check if the OS saves the XMM, YMM and ZMM registers, i.e. it supports AVX2 and AVX512.
// See section 2.1 of software.intel.com/sites/default/files/managed/0d/53/319433-022.pdf
// Check xgetbv; this uses a .byte sequence instead of the instruction
// directly because older assemblers do not include support for xgetbv and
// there is no easy way to conditionally compile based on the assembler used.
int rEAX, rEDX;
__asm__ __volatile__(".byte 0x0f, 0x01, 0xd0" : "=a"(rEAX), "=d"(rEDX) : "c"(0));
return (rEAX & 0xE6) == 0xE6;
}
#endif // !__APPLE__
// __get_system_isa should return a value corresponding to one of the
// Target::ISA enumerant values that gives the most capable ISA that the
// current system can run.
int32_t c2me_natives_get_system_isa(_Bool allowAVX512) {
int info[4];
__cpuid(info, 1);
// Call cpuid with eax=7, ecx=0
int info2[4];
__cpuidex(info2, 7, 0);
int info3[4] = {0, 0, 0, 0};
int max_subleaf = info2[0];
// Call cpuid with eax=7, ecx=1
if (max_subleaf >= 1)
__cpuidex(info3, 7, 1);
// clang-format off
_Bool sse2 = (info[3] & (1 << 26)) != 0;
_Bool sse41 = (info[2] & (1 << 19)) != 0;
_Bool sse42 = (info[2] & (1 << 20)) != 0;
_Bool avx = (info[2] & (1 << 28)) != 0;
_Bool avx2 = (info2[1] & (1 << 5)) != 0;
_Bool avx_vnni = (info3[0] & (1 << 4)) != 0;
_Bool avx_f16c = (info[2] & (1 << 29)) != 0;
_Bool avx_rdrand = (info[2] & (1 << 30)) != 0;
_Bool osxsave = (info[2] & (1 << 27)) != 0;
_Bool avx512_f = (info2[1] & (1 << 16)) != 0;
// clang-format on
// NOTE: the values returned below must be the same as the
// corresponding enumerant values in Target::ISA.
if (allowAVX512 && osxsave && avx2 && avx512_f
#if !defined(__APPLE__)
&& __os_has_avx512_support()
#endif // !__APPLE__
) {
// We need to verify that AVX2 is also available,
// as well as AVX512, because our targets are supposed
// to use both.
// clang-format off
_Bool avx512_dq = (info2[1] & (1 << 17)) != 0;
_Bool avx512_pf = (info2[1] & (1 << 26)) != 0;
_Bool avx512_er = (info2[1] & (1 << 27)) != 0;
_Bool avx512_cd = (info2[1] & (1 << 28)) != 0;
_Bool avx512_bw = (info2[1] & (1 << 30)) != 0;
_Bool avx512_vl = (info2[1] & (1 << 31)) != 0;
#if !defined(__APPLE__)
_Bool avx512_vbmi2 = (info2[2] & (1 << 6)) != 0;
_Bool avx512_gfni = (info2[2] & (1 << 8)) != 0;
_Bool avx512_vaes = (info2[2] & (1 << 9)) != 0;
_Bool avx512_vpclmulqdq = (info2[2] & (1 << 10)) != 0;
_Bool avx512_vnni = (info2[2] & (1 << 11)) != 0;
_Bool avx512_bitalg = (info2[2] & (1 << 12)) != 0;
_Bool avx512_vpopcntdq = (info2[2] & (1 << 14)) != 0;
_Bool avx512_bf16 = (info3[0] & (1 << 5)) != 0;
_Bool avx512_vp2intersect = (info2[3] & (1 << 8)) != 0;
_Bool avx512_amx_bf16 = (info2[3] & (1 << 22)) != 0;
_Bool avx512_amx_tile = (info2[3] & (1 << 24)) != 0;
_Bool avx512_amx_int8 = (info2[3] & (1 << 25)) != 0;
_Bool avx512_fp16 = (info2[3] & (1 << 23)) != 0;
#endif // !__APPLE__
// clang-format on
// Knights Landing: KNL = F + PF + ER + CD
// Skylake server: SKX = F + DQ + CD + BW + VL
// Cascade Lake server: CLX = SKX + VNNI
// Cooper Lake server: CPX = CLX + BF16
// Ice Lake client & server: ICL = CLX + VBMI2 + GFNI + VAES + VPCLMULQDQ + BITALG + VPOPCNTDQ
// Tiger Lake: TGL = ICL + VP2INTERSECT
// Sapphire Rapids: SPR = ICL + BF16 + AMX_BF16 + AMX_TILE + AMX_INT8 + AVX_VNNI + FP16
_Bool knl = avx512_pf && avx512_er && avx512_cd;
_Bool skx = avx512_dq && avx512_cd && avx512_bw && avx512_vl;
#if !defined(__APPLE__)
_Bool clx = skx && avx512_vnni;
_Bool cpx = clx && avx512_bf16;
_Bool icl =
clx && avx512_vbmi2 && avx512_gfni && avx512_vaes && avx512_vpclmulqdq && avx512_bitalg && avx512_vpopcntdq;
_Bool tgl = icl && avx512_vp2intersect;
_Bool spr =
icl && avx512_bf16 && avx512_amx_bf16 && avx512_amx_tile && avx512_amx_int8 && avx_vnni && avx512_fp16;
if (spr) {
return 9; // SPR
} else if (icl) {
return 8; // ICL
}
#endif // !__APPLE__
if (skx) {
return 7; // SKX
} else if (knl) {
return 6; // KNL
}
// If it's unknown AVX512 target, fall through and use AVX2
// or whatever is available in the machine.
}
if (osxsave && avx && __os_has_avx_support()) {
// if (avx_vnni) {
// return 5; // ADL
// }
if (avx_f16c && avx_rdrand && avx2) {
return 4;
}
// Regular AVX
return 3;
} else if (sse42) {
return 2; // SSE4.2
} else if (sse41) {
return 1; // SSE4.1
} else if (sse2) {
return 0; // SSE2
} else {
__builtin_trap();
}
}
#endif
typedef int make_iso_compiler_happy;

View File

@@ -1,11 +0,0 @@
set(CMAKE_SYSTEM_NAME Darwin)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
set(triple x86_64-apple-darwin)
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_COMPILER_TARGET ${triple})
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_COMPILER_TARGET ${triple})
set(CMAKE_C_FLAGS "-march=x86-64 -Wl,-no_uuid")

View File

@@ -1,10 +0,0 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm64)
set(triple aarch64-unknown-linux-musl)
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_COMPILER_TARGET ${triple})
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_COMPILER_TARGET ${triple})

View File

@@ -1,11 +0,0 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
set(triple x86_64-unknown-linux-musl)
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_COMPILER_TARGET ${triple})
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_COMPILER_TARGET ${triple})
set(CMAKE_C_FLAGS -march=x86-64)

View File

@@ -1,11 +0,0 @@
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR AMD64)
set(triple x86_64-pc-windows-gnu)
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_COMPILER_TARGET ${triple})
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_COMPILER_TARGET ${triple})
set(CMAKE_C_FLAGS "-march=x86-64 -Wl,--no-insert-timestamp")

View File

@@ -1,105 +0,0 @@
package org.bxteam.divinemc.math;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.foreign.MemorySegment;
import java.lang.invoke.MethodHandle;
public class Bindings {
private static final Logger LOGGER = LoggerFactory.getLogger(Bindings.class);
private static final MethodHandle MH_c2me_natives_noise_perlin_double = bind(BindingsTemplate.c2me_natives_noise_perlin_double, "c2me_natives_noise_perlin_double");
private static final MethodHandle MH_c2me_natives_noise_perlin_double_ptr = bind(BindingsTemplate.c2me_natives_noise_perlin_double_ptr, "c2me_natives_noise_perlin_double");
private static final MethodHandle MH_c2me_natives_noise_perlin_double_batch = bind(BindingsTemplate.c2me_natives_noise_perlin_double_batch, "c2me_natives_noise_perlin_double_batch");
private static final MethodHandle MH_c2me_natives_noise_perlin_double_batch_partial_ptr = bind(BindingsTemplate.c2me_natives_noise_perlin_double_batch_ptr, "c2me_natives_noise_perlin_double_batch");
private static final MethodHandle MH_c2me_natives_noise_interpolated = bind(BindingsTemplate.c2me_natives_noise_interpolated, "c2me_natives_noise_interpolated");
private static final MethodHandle MH_c2me_natives_noise_interpolated_ptr = bind(BindingsTemplate.c2me_natives_noise_interpolated_ptr, "c2me_natives_noise_interpolated");
private static final MethodHandle MH_c2me_natives_end_islands_sample = bind(BindingsTemplate.c2me_natives_end_islands_sample, "c2me_natives_end_islands_sample");
private static final MethodHandle MH_c2me_natives_end_islands_sample_ptr = bind(BindingsTemplate.c2me_natives_end_islands_sample_ptr, "c2me_natives_end_islands_sample");
private static final MethodHandle MH_c2me_natives_biome_access_sample = bind(BindingsTemplate.c2me_natives_biome_access_sample, "c2me_natives_biome_access_sample");
private static @Nullable MethodHandle bind(@NotNull MethodHandle template, String prefix) {
if (NativeLoader.currentMachineTarget == null) {
LOGGER.warn("Call to bindings was found! Please disable native acceleration in config, as your system may be incompatible");
return null;
}
return template.bindTo(NativeLoader.lookup.find(prefix + NativeLoader.currentMachineTarget.getSuffix()).get());
}
public static double c2me_natives_noise_perlin_double(MemorySegment data, double x, double y, double z) {
try {
return (double) MH_c2me_natives_noise_perlin_double.invokeExact(data, x, y, z);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public static double c2me_natives_noise_perlin_double(long data_ptr, double x, double y, double z) {
try {
return (double) MH_c2me_natives_noise_perlin_double_ptr.invokeExact(data_ptr, x, y, z);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public static void c2me_natives_noise_perlin_double_batch(MemorySegment data, MemorySegment res, MemorySegment x, MemorySegment y, MemorySegment z, int length) {
try {
MH_c2me_natives_noise_perlin_double_batch.invokeExact(data, res, x, y, z, length);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public static void c2me_natives_noise_perlin_double_batch(long data_ptr, MemorySegment res, MemorySegment x, MemorySegment y, MemorySegment z, int length) {
try {
MH_c2me_natives_noise_perlin_double_batch_partial_ptr.invokeExact(data_ptr, res, x, y, z, length);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public static double c2me_natives_noise_interpolated(MemorySegment data, double x, double y, double z) {
try {
return (double) MH_c2me_natives_noise_interpolated.invokeExact(data, x, y, z);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public static double c2me_natives_noise_interpolated(long data_ptr, double x, double y, double z) {
try {
return (double) MH_c2me_natives_noise_interpolated_ptr.invokeExact(data_ptr, x, y, z);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public static float c2me_natives_end_islands_sample(MemorySegment data, int x, int z) {
try {
return (float) MH_c2me_natives_end_islands_sample.invokeExact(data, x, z);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public static float c2me_natives_end_islands_sample(long data_ptr, int x, int z) {
if ((x * x + z * z) < 0) { // workaround some compiler bugs
return Float.NaN;
}
try {
return (float) MH_c2me_natives_end_islands_sample_ptr.invokeExact(data_ptr, x, z);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public static int c2me_natives_biome_access_sample(long seed, int x, int y, int z) {
try {
return (int) MH_c2me_natives_biome_access_sample.invokeExact(seed, x, y, z);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -1,401 +0,0 @@
package org.bxteam.divinemc.math;
import net.minecraft.world.level.levelgen.synth.BlendedNoise;
import net.minecraft.world.level.levelgen.synth.ImprovedNoise;
import net.minecraft.world.level.levelgen.synth.PerlinNoise;
import org.jetbrains.annotations.NotNull;
import org.bxteam.divinemc.util.MemoryUtil;
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.VarHandle;
import java.util.Objects;
import java.util.stream.IntStream;
public class BindingsTemplate {
// double c2me_natives_noise_perlin_sample (const uint8_t *permutations, double originX, double originY, double originZ, double x, double y, double z, double yScale, double yMax)
public static final MethodHandle c2me_natives_noise_perlin_sample = NativeLoader.linker.downcallHandle(
FunctionDescriptor.of(
ValueLayout.JAVA_DOUBLE,
ValueLayout.ADDRESS,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE
),
Linker.Option.critical(true)
);
// c2me_natives_noise_perlin_double, double, (const double_octave_sampler_data_t *data, double x, double y, double z)
public static final MethodHandle c2me_natives_noise_perlin_double = NativeLoader.linker.downcallHandle(
FunctionDescriptor.of(
ValueLayout.JAVA_DOUBLE,
ValueLayout.ADDRESS,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE
),
Linker.Option.critical(false)
);
public static final MethodHandle c2me_natives_noise_perlin_double_ptr = NativeLoader.linker.downcallHandle(
FunctionDescriptor.of(
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_LONG,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE
),
Linker.Option.critical(false)
);
// c2me_natives_noise_perlin_double_batch, void, (const double_octave_sampler_data_t *const data,
// double *const res, const double *const x,
// const double *const y, const double *const z,
// const uint32_t length)
public static final MethodHandle c2me_natives_noise_perlin_double_batch = NativeLoader.linker.downcallHandle(
FunctionDescriptor.ofVoid(
ValueLayout.ADDRESS,
ValueLayout.ADDRESS,
ValueLayout.ADDRESS,
ValueLayout.ADDRESS,
ValueLayout.ADDRESS,
ValueLayout.JAVA_INT
),
Linker.Option.critical(true)
);
public static final MethodHandle c2me_natives_noise_perlin_double_batch_ptr = NativeLoader.linker.downcallHandle(
FunctionDescriptor.ofVoid(
ValueLayout.JAVA_LONG,
ValueLayout.ADDRESS,
ValueLayout.ADDRESS,
ValueLayout.ADDRESS,
ValueLayout.ADDRESS,
ValueLayout.JAVA_INT
),
Linker.Option.critical(true)
);
public static final StructLayout double_octave_sampler_data = MemoryLayout.structLayout(
ValueLayout.JAVA_LONG.withName("length"),
ValueLayout.JAVA_DOUBLE.withName("amplitude"),
ValueLayout.ADDRESS.withName("need_shift"),
ValueLayout.ADDRESS.withName("lacunarity_powd"),
ValueLayout.ADDRESS.withName("persistence_powd"),
ValueLayout.ADDRESS.withName("sampler_permutations"),
ValueLayout.ADDRESS.withName("sampler_originX"),
ValueLayout.ADDRESS.withName("sampler_originY"),
ValueLayout.ADDRESS.withName("sampler_originZ"),
ValueLayout.ADDRESS.withName("amplitudes")
).withByteAlignment(32).withName("double_double_octave_sampler_data");
public static final VarHandle double_octave_sampler_data$length = double_octave_sampler_data.varHandle(MemoryLayout.PathElement.groupElement("length"));
public static final VarHandle double_octave_sampler_data$amplitude = double_octave_sampler_data.varHandle(MemoryLayout.PathElement.groupElement("amplitude"));
public static final VarHandle double_octave_sampler_data$need_shift = double_octave_sampler_data.varHandle(MemoryLayout.PathElement.groupElement("need_shift"));
public static final VarHandle double_octave_sampler_data$lacunarity_powd = double_octave_sampler_data.varHandle(MemoryLayout.PathElement.groupElement("lacunarity_powd"));
public static final VarHandle double_octave_sampler_data$persistence_powd = double_octave_sampler_data.varHandle(MemoryLayout.PathElement.groupElement("persistence_powd"));
public static final VarHandle double_octave_sampler_data$sampler_permutations = double_octave_sampler_data.varHandle(MemoryLayout.PathElement.groupElement("sampler_permutations"));
public static final VarHandle double_octave_sampler_data$sampler_originX = double_octave_sampler_data.varHandle(MemoryLayout.PathElement.groupElement("sampler_originX"));
public static final VarHandle double_octave_sampler_data$sampler_originY = double_octave_sampler_data.varHandle(MemoryLayout.PathElement.groupElement("sampler_originY"));
public static final VarHandle double_octave_sampler_data$sampler_originZ = double_octave_sampler_data.varHandle(MemoryLayout.PathElement.groupElement("sampler_originZ"));
public static final VarHandle double_octave_sampler_data$amplitudes = double_octave_sampler_data.varHandle(MemoryLayout.PathElement.groupElement("amplitudes"));
// c2me_natives_noise_interpolated, double, (const interpolated_noise_sampler_t *const data, const double x, const double y, const double z)
public static final MethodHandle c2me_natives_noise_interpolated = NativeLoader.linker.downcallHandle(
FunctionDescriptor.of(
ValueLayout.JAVA_DOUBLE,
ValueLayout.ADDRESS,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE
),
Linker.Option.critical(false)
);
public static final MethodHandle c2me_natives_noise_interpolated_ptr = NativeLoader.linker.downcallHandle(
FunctionDescriptor.of(
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_LONG,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE,
ValueLayout.JAVA_DOUBLE
),
Linker.Option.critical(false)
);
// typedef const struct interpolated_noise_sub_sampler {
// const aligned_uint8_ptr sampler_permutations;
// const aligned_double_ptr sampler_originX;
// const aligned_double_ptr sampler_originY;
// const aligned_double_ptr sampler_originZ;
// const aligned_double_ptr sampler_mulFactor;
// const uint32_t length;
// } interpolated_noise_sub_sampler_t;
public static final StructLayout interpolated_noise_sub_sampler = MemoryLayout.structLayout(
ValueLayout.ADDRESS.withName("sampler_permutations"),
ValueLayout.ADDRESS.withName("sampler_originX"),
ValueLayout.ADDRESS.withName("sampler_originY"),
ValueLayout.ADDRESS.withName("sampler_originZ"),
ValueLayout.ADDRESS.withName("sampler_mulFactor"),
ValueLayout.JAVA_INT.withName("length"),
MemoryLayout.paddingLayout(4)
).withName("interpolated_noise_sub_sampler_t");
// typedef const struct interpolated_noise_sampler {
// const double scaledXzScale;
// const double scaledYScale;
// const double xzFactor;
// const double yFactor;
// const double smearScaleMultiplier;
// const double xzScale;
// const double yScale;
//
// const interpolated_noise_sub_sampler_t lower;
// const interpolated_noise_sub_sampler_t upper;
// const interpolated_noise_sub_sampler_t normal;
// } interpolated_noise_sampler_t;
public static final StructLayout interpolated_noise_sampler = MemoryLayout.structLayout(
ValueLayout.JAVA_DOUBLE.withName("scaledXzScale"),
ValueLayout.JAVA_DOUBLE.withName("scaledYScale"),
ValueLayout.JAVA_DOUBLE.withName("xzFactor"),
ValueLayout.JAVA_DOUBLE.withName("yFactor"),
ValueLayout.JAVA_DOUBLE.withName("smearScaleMultiplier"),
ValueLayout.JAVA_DOUBLE.withName("xzScale"),
ValueLayout.JAVA_DOUBLE.withName("yScale"),
interpolated_noise_sub_sampler.withName("lower"),
interpolated_noise_sub_sampler.withName("upper"),
interpolated_noise_sub_sampler.withName("normal")
).withByteAlignment(32).withName("interpolated_noise_sampler_t");
public static final VarHandle interpolated_noise_sampler$scaledXzScale = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("scaledXzScale"));
public static final VarHandle interpolated_noise_sampler$scaledYScale = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("scaledYScale"));
public static final VarHandle interpolated_noise_sampler$xzFactor = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("xzFactor"));
public static final VarHandle interpolated_noise_sampler$yFactor = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("yFactor"));
public static final VarHandle interpolated_noise_sampler$smearScaleMultiplier = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("smearScaleMultiplier"));
public static final VarHandle interpolated_noise_sampler$xzScale = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("xzScale"));
public static final VarHandle interpolated_noise_sampler$yScale = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("yScale"));
public static final VarHandle interpolated_noise_sampler$lower$sampler_permutations = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("lower"), MemoryLayout.PathElement.groupElement("sampler_permutations"));
public static final VarHandle interpolated_noise_sampler$lower$sampler_originX = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("lower"), MemoryLayout.PathElement.groupElement("sampler_originX"));
public static final VarHandle interpolated_noise_sampler$lower$sampler_originY = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("lower"), MemoryLayout.PathElement.groupElement("sampler_originY"));
public static final VarHandle interpolated_noise_sampler$lower$sampler_originZ = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("lower"), MemoryLayout.PathElement.groupElement("sampler_originZ"));
public static final VarHandle interpolated_noise_sampler$lower$sampler_mulFactor = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("lower"), MemoryLayout.PathElement.groupElement("sampler_mulFactor"));
public static final VarHandle interpolated_noise_sampler$lower$length = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("lower"), MemoryLayout.PathElement.groupElement("length"));
public static final VarHandle interpolated_noise_sampler$upper$sampler_permutations = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("upper"), MemoryLayout.PathElement.groupElement("sampler_permutations"));
public static final VarHandle interpolated_noise_sampler$upper$sampler_originX = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("upper"), MemoryLayout.PathElement.groupElement("sampler_originX"));
public static final VarHandle interpolated_noise_sampler$upper$sampler_originY = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("upper"), MemoryLayout.PathElement.groupElement("sampler_originY"));
public static final VarHandle interpolated_noise_sampler$upper$sampler_originZ = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("upper"), MemoryLayout.PathElement.groupElement("sampler_originZ"));
public static final VarHandle interpolated_noise_sampler$upper$sampler_mulFactor = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("upper"), MemoryLayout.PathElement.groupElement("sampler_mulFactor"));
public static final VarHandle interpolated_noise_sampler$upper$length = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("upper"), MemoryLayout.PathElement.groupElement("length"));
public static final VarHandle interpolated_noise_sampler$normal$sampler_permutations = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("normal"), MemoryLayout.PathElement.groupElement("sampler_permutations"));
public static final VarHandle interpolated_noise_sampler$normal$sampler_originX = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("normal"), MemoryLayout.PathElement.groupElement("sampler_originX"));
public static final VarHandle interpolated_noise_sampler$normal$sampler_originY = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("normal"), MemoryLayout.PathElement.groupElement("sampler_originY"));
public static final VarHandle interpolated_noise_sampler$normal$sampler_originZ = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("normal"), MemoryLayout.PathElement.groupElement("sampler_originZ"));
public static final VarHandle interpolated_noise_sampler$normal$sampler_mulFactor = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("normal"), MemoryLayout.PathElement.groupElement("sampler_mulFactor"));
public static final VarHandle interpolated_noise_sampler$normal$length = interpolated_noise_sampler.varHandle(MemoryLayout.PathElement.groupElement("normal"), MemoryLayout.PathElement.groupElement("length"));
// c2me_natives_end_islands_sample, float, (const int32_t *const simplex_permutations, const int32_t x, const int32_t z)
public static final MethodHandle c2me_natives_end_islands_sample = NativeLoader.linker.downcallHandle(
FunctionDescriptor.of(
ValueLayout.JAVA_FLOAT,
ValueLayout.ADDRESS,
ValueLayout.JAVA_INT,
ValueLayout.JAVA_INT
),
Linker.Option.critical(true)
);
public static final MethodHandle c2me_natives_end_islands_sample_ptr = NativeLoader.linker.downcallHandle(
FunctionDescriptor.of(
ValueLayout.JAVA_FLOAT,
ValueLayout.JAVA_LONG,
ValueLayout.JAVA_INT,
ValueLayout.JAVA_INT
),
Linker.Option.critical(false)
);
// c2me_natives_biome_access_sample, uint32_t, (const int64_t theSeed, const int32_t x, const int32_t y, const int32_t z)
public static final MethodHandle c2me_natives_biome_access_sample = NativeLoader.linker.downcallHandle(
FunctionDescriptor.of(
ValueLayout.JAVA_INT,
ValueLayout.JAVA_LONG,
ValueLayout.JAVA_INT,
ValueLayout.JAVA_INT,
ValueLayout.JAVA_INT
),
Linker.Option.critical(false)
);
public static MemorySegment double_octave_sampler_data$create(Arena arena, @NotNull PerlinNoise firstSampler, PerlinNoise secondSampler, double amplitude) {
long nonNullSamplerCount = 0;
for (ImprovedNoise sampler : (firstSampler.noiseLevels)) {
if (sampler != null) {
nonNullSamplerCount++;
}
}
for (ImprovedNoise sampler : (secondSampler.noiseLevels)) {
if (sampler != null) {
nonNullSamplerCount++;
}
}
final MemorySegment data = arena.allocate(double_octave_sampler_data.byteSize(), 64);
final MemorySegment need_shift = arena.allocate(nonNullSamplerCount, 64);
final MemorySegment lacunarity_powd = arena.allocate(nonNullSamplerCount * 8, 64);
final MemorySegment persistence_powd = arena.allocate(nonNullSamplerCount * 8, 64);
final MemorySegment sampler_permutations = arena.allocate(nonNullSamplerCount * 256 * 4, 64);
final MemorySegment sampler_originX = arena.allocate(nonNullSamplerCount * 8, 64);
final MemorySegment sampler_originY = arena.allocate(nonNullSamplerCount * 8, 64);
final MemorySegment sampler_originZ = arena.allocate(nonNullSamplerCount * 8, 64);
final MemorySegment amplitudes = arena.allocate(nonNullSamplerCount * 8, 64);
double_octave_sampler_data$length.set(data, 0L, nonNullSamplerCount);
double_octave_sampler_data$amplitude.set(data, 0L, amplitude);
double_octave_sampler_data$need_shift.set(data, 0L, need_shift);
double_octave_sampler_data$lacunarity_powd.set(data, 0L, lacunarity_powd);
double_octave_sampler_data$persistence_powd.set(data, 0L, persistence_powd);
double_octave_sampler_data$sampler_permutations.set(data, 0L, sampler_permutations);
double_octave_sampler_data$sampler_originX.set(data, 0L, sampler_originX);
double_octave_sampler_data$sampler_originY.set(data, 0L, sampler_originY);
double_octave_sampler_data$sampler_originZ.set(data, 0L, sampler_originZ);
double_octave_sampler_data$amplitudes.set(data, 0L, amplitudes);
long index = 0;
{
ImprovedNoise[] octaveSamplers = (firstSampler.noiseLevels);
for (int i = 0, octaveSamplersLength = octaveSamplers.length; i < octaveSamplersLength; i++) {
ImprovedNoise sampler = octaveSamplers[i];
if (sampler != null) {
need_shift.set(ValueLayout.JAVA_BOOLEAN, index, false);
lacunarity_powd.set(ValueLayout.JAVA_DOUBLE, index * 8, (firstSampler.lowestFreqInputFactor) * Math.pow(2.0, i));
persistence_powd.set(ValueLayout.JAVA_DOUBLE, index * 8, (firstSampler.lowestFreqValueFactor) * Math.pow(2.0, -i));
MemorySegment.copy(MemorySegment.ofArray(MemoryUtil.byte2int(sampler.p)), 0, sampler_permutations, index * 256L * 4L, 256 * 4);
sampler_originX.set(ValueLayout.JAVA_DOUBLE, index * 8, sampler.xo);
sampler_originY.set(ValueLayout.JAVA_DOUBLE, index * 8, sampler.yo);
sampler_originZ.set(ValueLayout.JAVA_DOUBLE, index * 8, sampler.zo);
amplitudes.set(ValueLayout.JAVA_DOUBLE, index * 8, (firstSampler.amplitudes).getDouble(i));
index++;
}
}
}
{
ImprovedNoise[] octaveSamplers = (secondSampler.noiseLevels);
for (int i = 0, octaveSamplersLength = octaveSamplers.length; i < octaveSamplersLength; i++) {
ImprovedNoise sampler = octaveSamplers[i];
if (sampler != null) {
need_shift.set(ValueLayout.JAVA_BOOLEAN, index, true);
lacunarity_powd.set(ValueLayout.JAVA_DOUBLE, index * 8, (secondSampler.lowestFreqInputFactor) * Math.pow(2.0, i));
persistence_powd.set(ValueLayout.JAVA_DOUBLE, index * 8, (secondSampler.lowestFreqValueFactor) * Math.pow(2.0, -i));
MemorySegment.copy(MemorySegment.ofArray(MemoryUtil.byte2int(sampler.p)), 0, sampler_permutations, index * 256L * 4L, 256 * 4);
sampler_originX.set(ValueLayout.JAVA_DOUBLE, index * 8, sampler.xo);
sampler_originY.set(ValueLayout.JAVA_DOUBLE, index * 8, sampler.yo);
sampler_originZ.set(ValueLayout.JAVA_DOUBLE, index * 8, sampler.zo);
amplitudes.set(ValueLayout.JAVA_DOUBLE, index * 8, (secondSampler.amplitudes).getDouble(i));
index++;
}
}
}
VarHandle.fullFence();
return data;
}
public static boolean interpolated_noise_sampler$isSpecializedBase3dNoiseFunction(BlendedNoise interpolated) {
return IntStream.range(0, 16).mapToObj((interpolated).minLimitNoise::getOctaveNoise).filter(Objects::nonNull).count() == 16 &&
IntStream.range(0, 16).mapToObj((interpolated).maxLimitNoise::getOctaveNoise).filter(Objects::nonNull).count() == 16 &&
IntStream.range(0, 8).mapToObj((interpolated).mainNoise::getOctaveNoise).filter(Objects::nonNull).count() == 8;
}
public static MemorySegment interpolated_noise_sampler$create(@NotNull Arena arena, BlendedNoise interpolated) {
final MemorySegment data = arena.allocate(interpolated_noise_sampler.byteSize(), 64);
interpolated_noise_sampler$scaledXzScale.set(data, 0L, (interpolated).xzMultiplier);
interpolated_noise_sampler$scaledYScale.set(data, 0L, (interpolated).yMultiplier);
interpolated_noise_sampler$xzFactor.set(data, 0L, (interpolated).xzFactor);
interpolated_noise_sampler$yFactor.set(data, 0L, (interpolated).yFactor);
interpolated_noise_sampler$smearScaleMultiplier.set(data, 0L, (interpolated).smearScaleMultiplier);
interpolated_noise_sampler$xzScale.set(data, 0L, (interpolated).xzScale);
interpolated_noise_sampler$yScale.set(data, 0L, (interpolated).yScale);
// if (true) {
// System.out.println(String.format("Interpolated total: %d", countNonNull));
// System.out.println(String.format("lower: %d", IntStream.range(0, 16).mapToObj(((IInterpolatedNoiseSampler) interpolated).getLowerInterpolatedNoise()::getOctave).filter(Objects::nonNull).count()));
// System.out.println(String.format("upper: %d", IntStream.range(0, 16).mapToObj(((IInterpolatedNoiseSampler) interpolated).getUpperInterpolatedNoise()::getOctave).filter(Objects::nonNull).count()));
// System.out.println(String.format("normal: %d", IntStream.range(0, 8).mapToObj(((IInterpolatedNoiseSampler) interpolated).getInterpolationNoise()::getOctave).filter(Objects::nonNull).count()));
// }
final MemorySegment sampler_permutations = arena.allocate(40 * 256L * 4L, 64);
final MemorySegment sampler_originX = arena.allocate(40 * 8L, 64);
final MemorySegment sampler_originY = arena.allocate(40 * 8L, 64);
final MemorySegment sampler_originZ = arena.allocate(40 * 8L, 64);
final MemorySegment sampler_mulFactor = arena.allocate(40 * 8L, 64);
int index = 0;
{
int startIndex = index;
for (int i = 0; i < 8; i++) {
ImprovedNoise sampler = (interpolated.mainNoise).getOctaveNoise(i);
if (sampler != null) {
MemorySegment.copy(MemorySegment.ofArray(MemoryUtil.byte2int(sampler.p)), 0, sampler_permutations, index * 256L * 4L, 256 * 4);
sampler_originX.set(ValueLayout.JAVA_DOUBLE, index * 8L, sampler.xo);
sampler_originY.set(ValueLayout.JAVA_DOUBLE, index * 8L, sampler.yo);
sampler_originZ.set(ValueLayout.JAVA_DOUBLE, index * 8L, sampler.zo);
sampler_mulFactor.set(ValueLayout.JAVA_DOUBLE, index * 8L, Math.pow(2, -i));
index++;
}
}
BindingsTemplate.interpolated_noise_sampler$normal$sampler_permutations.set(data, 0L, sampler_permutations.asSlice(startIndex * 256L * 4L));
BindingsTemplate.interpolated_noise_sampler$normal$sampler_originX.set(data, 0L, sampler_originX.asSlice(startIndex * 8L));
BindingsTemplate.interpolated_noise_sampler$normal$sampler_originY.set(data, 0L, sampler_originY.asSlice(startIndex * 8L));
BindingsTemplate.interpolated_noise_sampler$normal$sampler_originZ.set(data, 0L, sampler_originZ.asSlice(startIndex * 8L));
BindingsTemplate.interpolated_noise_sampler$normal$sampler_mulFactor.set(data, 0L, sampler_mulFactor.asSlice(startIndex * 8L));
BindingsTemplate.interpolated_noise_sampler$normal$length.set(data, 0L, index - startIndex);
}
{
int startIndex = index = 8;
for (int i = 0; i < 16; i++) {
ImprovedNoise sampler = (interpolated.minLimitNoise).getOctaveNoise(i);
if (sampler != null) {
MemorySegment.copy(MemorySegment.ofArray(MemoryUtil.byte2int(sampler.p)), 0, sampler_permutations, index * 256L * 4L, 256 * 4);
sampler_originX.set(ValueLayout.JAVA_DOUBLE, index * 8L, sampler.xo);
sampler_originY.set(ValueLayout.JAVA_DOUBLE, index * 8L, sampler.yo);
sampler_originZ.set(ValueLayout.JAVA_DOUBLE, index * 8L, sampler.zo);
sampler_mulFactor.set(ValueLayout.JAVA_DOUBLE, index * 8L, Math.pow(2, -i));
index++;
}
}
BindingsTemplate.interpolated_noise_sampler$lower$sampler_permutations.set(data, 0L, sampler_permutations.asSlice(startIndex * 256L * 4L));
BindingsTemplate.interpolated_noise_sampler$lower$sampler_originX.set(data, 0L, sampler_originX.asSlice(startIndex * 8L));
BindingsTemplate.interpolated_noise_sampler$lower$sampler_originY.set(data, 0L, sampler_originY.asSlice(startIndex * 8L));
BindingsTemplate.interpolated_noise_sampler$lower$sampler_originZ.set(data, 0L, sampler_originZ.asSlice(startIndex * 8L));
BindingsTemplate.interpolated_noise_sampler$lower$sampler_mulFactor.set(data, 0L, sampler_mulFactor.asSlice(startIndex * 8L));
BindingsTemplate.interpolated_noise_sampler$lower$length.set(data, 0L, index - startIndex);
}
{
int startIndex = index = 8 + 16;
for (int i = 0; i < 16; i++) {
ImprovedNoise sampler = (interpolated.maxLimitNoise).getOctaveNoise(i);
if (sampler != null) {
MemorySegment.copy(MemorySegment.ofArray(MemoryUtil.byte2int(sampler.p)), 0, sampler_permutations, index * 256L * 4L, 256 * 4);
sampler_originX.set(ValueLayout.JAVA_DOUBLE, index * 8L, sampler.xo);
sampler_originY.set(ValueLayout.JAVA_DOUBLE, index * 8L, sampler.yo);
sampler_originZ.set(ValueLayout.JAVA_DOUBLE, index * 8L, sampler.zo);
sampler_mulFactor.set(ValueLayout.JAVA_DOUBLE, index * 8L, Math.pow(2, -i));
index++;
}
}
BindingsTemplate.interpolated_noise_sampler$upper$sampler_permutations.set(data, 0L, sampler_permutations.asSlice(startIndex * 256L * 4L));
BindingsTemplate.interpolated_noise_sampler$upper$sampler_originX.set(data, 0L, sampler_originX.asSlice(startIndex * 8L));
BindingsTemplate.interpolated_noise_sampler$upper$sampler_originY.set(data, 0L, sampler_originY.asSlice(startIndex * 8L));
BindingsTemplate.interpolated_noise_sampler$upper$sampler_originZ.set(data, 0L, sampler_originZ.asSlice(startIndex * 8L));
BindingsTemplate.interpolated_noise_sampler$upper$sampler_mulFactor.set(data, 0L, sampler_mulFactor.asSlice(startIndex * 8L));
BindingsTemplate.interpolated_noise_sampler$upper$length.set(data, 0L, index - startIndex);
}
VarHandle.fullFence();
return data;
}
}

View File

@@ -1,20 +0,0 @@
package org.bxteam.divinemc.math;
import org.bxteam.divinemc.math.isa.ISA_aarch64;
import org.bxteam.divinemc.math.isa.ISA_x86_64;
public interface ISATarget {
int ordinal();
String getSuffix();
boolean isNativelySupported();
static Class<? extends Enum<? extends ISATarget>> getInstance() {
return switch (NativeLoader.NORMALIZED_ARCH) {
case "x86_64" -> ISA_x86_64.class;
case "aarch_64" -> ISA_aarch64.class;
default -> null;
};
}
}

View File

@@ -1,179 +0,0 @@
package org.bxteam.divinemc.math;
import io.netty.util.internal.SystemPropertyUtil;
import org.bxteam.divinemc.DivineConfig;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.InputStream;
import java.lang.foreign.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.Locale;
public class NativeLoader {
private static final Logger LOGGER = LoggerFactory.getLogger(NativeLoader.class);
public static final String NORMALIZED_ARCH = normalizeArch(SystemPropertyUtil.get("os.arch", ""));
public static final String NORMALIZED_OS = normalizeOs(SystemPropertyUtil.get("os.name", ""));
private static final Arena arena = Arena.ofAuto();
public static final SymbolLookup lookup;
public static final Linker linker = Linker.nativeLinker();
public static final ISATarget currentMachineTarget;
static {
String libName = String.format("%s-%s-%s", NORMALIZED_OS, NORMALIZED_ARCH, System.mapLibraryName("c2me-opts-natives-math"));
lookup = load0(libName);
if (lookup == null) {
currentMachineTarget = null;
DivineConfig.nativeAccelerationEnabled = false;
LOGGER.warn("Disabling native math optimization due to unsupported platform.");
} else {
try {
LOGGER.info("Attempting to call native library. If your game crashes right after this point, native acceleration may not be available for your system.");
int level = (int) linker.downcallHandle(
lookup.find("c2me_natives_get_system_isa").get(),
FunctionDescriptor.of(
ValueLayout.JAVA_INT,
ValueLayout.JAVA_BOOLEAN
)
).invokeExact(DivineConfig.allowAVX512);
ISATarget target;
if (DivineConfig.isaTargetLevelOverride != -1) {
target = (ISATarget) ISATarget.getInstance().getEnumConstants()[DivineConfig.isaTargetLevelOverride];
} else {
target = (ISATarget) ISATarget.getInstance().getEnumConstants()[level];
while (!target.isNativelySupported()) target = (ISATarget) ISATarget.getInstance().getEnumConstants()[target.ordinal() - 1];
}
currentMachineTarget = target;
LOGGER.info("Detected maximum supported ISA target: {}", currentMachineTarget);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
@Contract(pure = true)
public static @NotNull String getAvailabilityString() {
if (lookup != null) {
return String.format("Available, with ISA target %s", currentMachineTarget);
} else {
return "Unavailable";
}
}
private static @Nullable SymbolLookup load0(String libName) {
// load from resources
try (final InputStream in = NativeLoader.class.getClassLoader().getResourceAsStream(libName)) {
if (in == null) {
LOGGER.warn("Cannot find native library {}, possibly unsupported platform for native acceleration", libName);
return null;
}
final Path tempFile;
if (Boolean.getBoolean("vectorizedgen.preserveNative")) {
tempFile = Path.of(".", libName);
} else {
tempFile = Files.createTempFile(null, libName);
tempFile.toFile().deleteOnExit();
}
Files.copy(in, tempFile, StandardCopyOption.REPLACE_EXISTING);
return SymbolLookup.libraryLookup(tempFile, arena);
} catch (Throwable e) {
LOGGER.warn("Failed to load native library", e);
return null;
}
}
private static @NotNull String normalize(@NotNull String value) {
return value.toLowerCase(Locale.US).replaceAll("[^a-z0-9]+", "");
}
private static @NotNull String normalizeArch(String value) {
value = normalize(value);
if (value.matches("^(x8664|amd64|ia32e|em64t|x64)$")) {
return "x86_64";
}
if (value.matches("^(x8632|x86|i[3-6]86|ia32|x32)$")) {
return "x86_32";
}
if (value.matches("^(ia64|itanium64)$")) {
return "itanium_64";
}
if (value.matches("^(sparc|sparc32)$")) {
return "sparc_32";
}
if (value.matches("^(sparcv9|sparc64)$")) {
return "sparc_64";
}
if (value.matches("^(arm|arm32)$")) {
return "arm_32";
}
if ("aarch64".equals(value)) {
return "aarch_64";
}
if (value.matches("^(ppc|ppc32)$")) {
return "ppc_32";
}
if ("ppc64".equals(value)) {
return "ppc_64";
}
if ("ppc64le".equals(value)) {
return "ppcle_64";
}
if ("s390".equals(value)) {
return "s390_32";
}
if ("s390x".equals(value)) {
return "s390_64";
}
if ("loongarch64".equals(value)) {
return "loongarch_64";
}
return "unknown";
}
private static @NotNull String normalizeOs(String value) {
value = normalize(value);
if (value.startsWith("aix")) {
return "aix";
}
if (value.startsWith("hpux")) {
return "hpux";
}
if (value.startsWith("os400")) {
// Avoid the names such as os4000
if (value.length() <= 5 || !Character.isDigit(value.charAt(5))) {
return "os400";
}
}
if (value.startsWith("linux")) {
return "linux";
}
if (value.startsWith("macosx") || value.startsWith("osx") || value.startsWith("darwin")) {
return "osx";
}
if (value.startsWith("freebsd")) {
return "freebsd";
}
if (value.startsWith("openbsd")) {
return "openbsd";
}
if (value.startsWith("netbsd")) {
return "netbsd";
}
if (value.startsWith("solaris") || value.startsWith("sunos")) {
return "sunos";
}
if (value.startsWith("windows")) {
return "windows";
}
return "unknown";
}
}

View File

@@ -1,25 +0,0 @@
package org.bxteam.divinemc.math.isa;
import org.bxteam.divinemc.math.ISATarget;
public enum ISA_aarch64 implements ISATarget {
GENERIC("_generic", true);
private final String suffix;
private final boolean nativelySupported;
ISA_aarch64(String suffix, boolean nativelySupported) {
this.suffix = suffix;
this.nativelySupported = nativelySupported;
}
@Override
public String getSuffix() {
return this.suffix;
}
@Override
public boolean isNativelySupported() {
return this.nativelySupported;
}
}

View File

@@ -1,34 +0,0 @@
package org.bxteam.divinemc.math.isa;
import org.bxteam.divinemc.math.ISATarget;
public enum ISA_x86_64 implements ISATarget {
SSE2("_sse2", true), // 0
SSE4_1("_sse2", false), // 1, not implemented
SSE4_2("_sse4_2", true), // 2
AVX("_avx", true), // 3
AVX2("_avx2", true), // 4
AVX2ADL("_avx2adl", true), // 5
AVX512KNL("_avx2", false), // 6, not implemented
AVX512SKX("_avx512skx", true), // 7
AVX512ICL("_avx512icl", true), // 8
AVX512SPR("_avx512spr", true); // 9
private final String suffix;
private final boolean nativelySupported;
ISA_x86_64(String suffix, boolean nativelySupported) {
this.suffix = suffix;
this.nativelySupported = nativelySupported;
}
@Override
public String getSuffix() {
return this.suffix;
}
@Override
public boolean isNativelySupported() {
return this.nativelySupported;
}
}