mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-03 19:06:27 +01:00
Housekeeping
- Update dependencies, forge version - Bump LICENCE year - Use fma in MatrixUtil and VertexTransformations - Remove some dead variables from TransformCall - Use onSpinWait in WaitGroup#await - Do not allow adding negative numbers to a WaitGroup - Thin abstraction for TaskNotifier - Clean up WorkerThread task polling
This commit is contained in:
parent
37ecedb97a
commit
3da51885d1
10 changed files with 60 additions and 58 deletions
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2021 Jozufozu
|
Copyright (c) 2021-2023 Jozufozu
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -146,8 +146,8 @@ dependencies {
|
||||||
|
|
||||||
// switch to implementation for debugging
|
// switch to implementation for debugging
|
||||||
compileOnly fg.deobf("maven.modrinth:starlight-forge:1.0.2+1.18.2")
|
compileOnly fg.deobf("maven.modrinth:starlight-forge:1.0.2+1.18.2")
|
||||||
compileOnly fg.deobf("maven.modrinth:rubidium:0.5.3a")
|
compileOnly fg.deobf("maven.modrinth:rubidium:0.5.6")
|
||||||
compileOnly fg.deobf("maven.modrinth:oculus:1.18.2-1.2.5a")
|
compileOnly fg.deobf("maven.modrinth:oculus:1.18.2-1.5.2")
|
||||||
|
|
||||||
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
|
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
|
||||||
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
|
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
|
||||||
|
|
|
@ -5,12 +5,12 @@ org.gradle.daemon = false
|
||||||
mod_version = 1.0.0-alpha
|
mod_version = 1.0.0-alpha
|
||||||
artifact_minecraft_version = 1.18.2
|
artifact_minecraft_version = 1.18.2
|
||||||
|
|
||||||
minecraft_version = 1.18.2
|
minecraft_version=1.18.2
|
||||||
forge_version = 40.1.68
|
forge_version=40.2.4
|
||||||
|
|
||||||
# build dependency versions
|
# build dependency versions
|
||||||
forgegradle_version = 5.1.53
|
forgegradle_version=5.1.+
|
||||||
mixingradle_version = 0.7-SNAPSHOT
|
mixingradle_version=0.7-SNAPSHOT
|
||||||
mixin_version = 0.8.5
|
mixin_version = 0.8.5
|
||||||
librarian_version = 1.+
|
librarian_version = 1.+
|
||||||
cursegradle_version = 1.4.0
|
cursegradle_version = 1.4.0
|
||||||
|
|
|
@ -20,11 +20,7 @@ import com.mojang.math.Matrix4f;
|
||||||
|
|
||||||
public class TransformCall<I extends Instance> {
|
public class TransformCall<I extends Instance> {
|
||||||
private final CPUInstancer<I> instancer;
|
private final CPUInstancer<I> instancer;
|
||||||
private final Material material;
|
|
||||||
private final BatchedMeshPool.BufferedMesh mesh;
|
|
||||||
|
|
||||||
private final int meshVertexCount;
|
private final int meshVertexCount;
|
||||||
private final int meshByteSize;
|
|
||||||
private final InstanceVertexTransformer<I> instanceVertexTransformer;
|
private final InstanceVertexTransformer<I> instanceVertexTransformer;
|
||||||
private final MaterialVertexTransformer materialVertexTransformer;
|
private final MaterialVertexTransformer materialVertexTransformer;
|
||||||
private final InstanceBoundingSphereTransformer<I> boundingSphereTransformer;
|
private final InstanceBoundingSphereTransformer<I> boundingSphereTransformer;
|
||||||
|
@ -34,15 +30,12 @@ public class TransformCall<I extends Instance> {
|
||||||
|
|
||||||
public TransformCall(CPUInstancer<I> instancer, Material material, BatchedMeshPool.BufferedMesh mesh) {
|
public TransformCall(CPUInstancer<I> instancer, Material material, BatchedMeshPool.BufferedMesh mesh) {
|
||||||
this.instancer = instancer;
|
this.instancer = instancer;
|
||||||
this.material = material;
|
|
||||||
this.mesh = mesh;
|
|
||||||
|
|
||||||
instanceVertexTransformer = instancer.type.getVertexTransformer();
|
instanceVertexTransformer = instancer.type.getVertexTransformer();
|
||||||
boundingSphereTransformer = instancer.type.getBoundingSphereTransformer();
|
boundingSphereTransformer = instancer.type.getBoundingSphereTransformer();
|
||||||
materialVertexTransformer = material.getVertexTransformer();
|
materialVertexTransformer = material.getVertexTransformer();
|
||||||
|
|
||||||
meshVertexCount = mesh.getVertexCount();
|
meshVertexCount = mesh.getVertexCount();
|
||||||
meshByteSize = mesh.size();
|
|
||||||
boundingSphere = mesh.mesh.getBoundingSphere();
|
boundingSphere = mesh.mesh.getBoundingSphere();
|
||||||
|
|
||||||
drawPlan = RunOnAllWithContextPlan.of(instancer::getAll, (instance, ctx) -> {
|
drawPlan = RunOnAllWithContextPlan.of(instancer::getAll, (instance, ctx) -> {
|
||||||
|
|
|
@ -9,11 +9,11 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||||
|
import com.jozufozu.flywheel.lib.task.ThreadGroupNotifier;
|
||||||
import com.jozufozu.flywheel.lib.task.WaitGroup;
|
import com.jozufozu.flywheel.lib.task.WaitGroup;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.logging.LogUtils;
|
import com.mojang.logging.LogUtils;
|
||||||
|
@ -37,7 +37,7 @@ public class ParallelTaskExecutor implements TaskExecutor {
|
||||||
private final Deque<Runnable> taskQueue = new ConcurrentLinkedDeque<>();
|
private final Deque<Runnable> taskQueue = new ConcurrentLinkedDeque<>();
|
||||||
private final Queue<Runnable> mainThreadQueue = new ConcurrentLinkedQueue<>();
|
private final Queue<Runnable> mainThreadQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
private final Object taskNotifier = new Object();
|
private final ThreadGroupNotifier taskNotifier = new ThreadGroupNotifier();
|
||||||
private final WaitGroup waitGroup = new WaitGroup();
|
private final WaitGroup waitGroup = new WaitGroup();
|
||||||
|
|
||||||
public ParallelTaskExecutor(String name) {
|
public ParallelTaskExecutor(String name) {
|
||||||
|
@ -114,9 +114,7 @@ public class ParallelTaskExecutor implements TaskExecutor {
|
||||||
waitGroup.add();
|
waitGroup.add();
|
||||||
taskQueue.add(task);
|
taskQueue.add(task);
|
||||||
|
|
||||||
synchronized (taskNotifier) {
|
taskNotifier.postNotification();
|
||||||
taskNotifier.notifyAll();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -148,8 +146,8 @@ public class ParallelTaskExecutor implements TaskExecutor {
|
||||||
} else {
|
} else {
|
||||||
// then wait for the other threads to finish.
|
// then wait for the other threads to finish.
|
||||||
waitGroup.await();
|
waitGroup.await();
|
||||||
// at this point there will be no more tasks in the queue, but
|
// at this point we know taskQueue is empty,
|
||||||
// one of the worker threads may have submitted a main thread task.
|
// but one of the worker threads may have submitted a main thread task.
|
||||||
if (mainThreadQueue.isEmpty()) {
|
if (mainThreadQueue.isEmpty()) {
|
||||||
// if they didn't, we're done.
|
// if they didn't, we're done.
|
||||||
break;
|
break;
|
||||||
|
@ -170,23 +168,6 @@ public class ParallelTaskExecutor implements TaskExecutor {
|
||||||
mainThreadQueue.clear();
|
mainThreadQueue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private Runnable getNextTask() {
|
|
||||||
Runnable task = taskQueue.pollFirst();
|
|
||||||
|
|
||||||
if (task == null) {
|
|
||||||
synchronized (taskNotifier) {
|
|
||||||
try {
|
|
||||||
taskNotifier.wait();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processTask(Runnable task) {
|
private void processTask(Runnable task) {
|
||||||
try {
|
try {
|
||||||
task.run();
|
task.run();
|
||||||
|
@ -226,9 +207,11 @@ public class ParallelTaskExecutor implements TaskExecutor {
|
||||||
public void run() {
|
public void run() {
|
||||||
// Run until the executor shuts down
|
// Run until the executor shuts down
|
||||||
while (ParallelTaskExecutor.this.running.get()) {
|
while (ParallelTaskExecutor.this.running.get()) {
|
||||||
Runnable task = getNextTask();
|
Runnable task = taskQueue.pollFirst();
|
||||||
|
|
||||||
if (task == null) {
|
if (task == null) {
|
||||||
|
// Nothing to do, time to sleep.
|
||||||
|
taskNotifier.awaitNotification();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package com.jozufozu.flywheel.lib.math;
|
package com.jozufozu.flywheel.lib.math;
|
||||||
|
|
||||||
|
import static org.joml.Math.fma;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import org.joml.Math;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.mixin.matrix.Matrix3fAccessor;
|
import com.jozufozu.flywheel.mixin.matrix.Matrix3fAccessor;
|
||||||
|
@ -12,32 +15,32 @@ import com.mojang.math.Matrix4f;
|
||||||
public final class MatrixUtil {
|
public final class MatrixUtil {
|
||||||
public static float transformPositionX(Matrix4f matrix, float x, float y, float z) {
|
public static float transformPositionX(Matrix4f matrix, float x, float y, float z) {
|
||||||
Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
|
Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
|
||||||
return (m.flywheel$m00() * x) + (m.flywheel$m01() * y) + (m.flywheel$m02() * z) + m.flywheel$m03();
|
return fma(m.flywheel$m00(), x, fma(m.flywheel$m01(), y, fma(m.flywheel$m02(), z, m.flywheel$m03())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float transformPositionY(Matrix4f matrix, float x, float y, float z) {
|
public static float transformPositionY(Matrix4f matrix, float x, float y, float z) {
|
||||||
Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
|
Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
|
||||||
return (m.flywheel$m10() * x) + (m.flywheel$m11() * y) + (m.flywheel$m12() * z) + m.flywheel$m13();
|
return fma(m.flywheel$m10(), x, fma(m.flywheel$m11(), y, fma(m.flywheel$m12(), z, m.flywheel$m13())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float transformPositionZ(Matrix4f matrix, float x, float y, float z) {
|
public static float transformPositionZ(Matrix4f matrix, float x, float y, float z) {
|
||||||
Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
|
Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
|
||||||
return (m.flywheel$m20() * x) + (m.flywheel$m21() * y) + (m.flywheel$m22() * z) + m.flywheel$m23();
|
return fma(m.flywheel$m20(), x, fma(m.flywheel$m21(), y, fma(m.flywheel$m22(), z, m.flywheel$m23())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float transformNormalX(Matrix3f matrix, float x, float y, float z) {
|
public static float transformNormalX(Matrix3f matrix, float x, float y, float z) {
|
||||||
Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
|
Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
|
||||||
return (m.flywheel$m00() * x) + (m.flywheel$m01() * y) + (m.flywheel$m02() * z);
|
return fma(m.flywheel$m00(), x, fma(m.flywheel$m01(), y, m.flywheel$m02() * z));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float transformNormalY(Matrix3f matrix, float x, float y, float z) {
|
public static float transformNormalY(Matrix3f matrix, float x, float y, float z) {
|
||||||
Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
|
Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
|
||||||
return (m.flywheel$m10() * x) + (m.flywheel$m11() * y) + (m.flywheel$m12() * z);
|
return fma(m.flywheel$m10(), x, fma(m.flywheel$m11(), y, m.flywheel$m12() * z));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float transformNormalZ(Matrix3f matrix, float x, float y, float z) {
|
public static float transformNormalZ(Matrix3f matrix, float x, float y, float z) {
|
||||||
Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
|
Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
|
||||||
return (m.flywheel$m20() * x) + (m.flywheel$m21() * y) + (m.flywheel$m22() * z);
|
return fma(m.flywheel$m20(), x, fma(m.flywheel$m21(), y, m.flywheel$m22() * z));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void write(Matrix4f matrix, ByteBuffer buf) {
|
public static void write(Matrix4f matrix, ByteBuffer buf) {
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.jozufozu.flywheel.lib.task;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thin wrapper around Java's built-in object synchronization primitives.
|
||||||
|
*/
|
||||||
|
public class ThreadGroupNotifier {
|
||||||
|
|
||||||
|
public synchronized void awaitNotification() {
|
||||||
|
try {
|
||||||
|
this.wait();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// we don't care if we're interrupted, just continue.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void postNotification() {
|
||||||
|
this.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import com.mojang.logging.LogUtils;
|
import com.mojang.logging.LogUtils;
|
||||||
|
|
||||||
public class WaitGroup {
|
public class WaitGroup {
|
||||||
|
@ -16,6 +17,7 @@ public class WaitGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(int i) {
|
public void add(int i) {
|
||||||
|
Preconditions.checkArgument(i >= 0, "Cannot add a negative number of tasks to a WaitGroup!");
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -31,17 +33,9 @@ public class WaitGroup {
|
||||||
|
|
||||||
public void await() {
|
public void await() {
|
||||||
// TODO: comprehensive performance tracking for tasks
|
// TODO: comprehensive performance tracking for tasks
|
||||||
long start = System.nanoTime();
|
|
||||||
int count = 0;
|
|
||||||
while (counter.get() > 0) {
|
while (counter.get() > 0) {
|
||||||
// spin in place to avoid sleeping the main thread
|
// spin in place to avoid sleeping the main thread
|
||||||
count++;
|
Thread.onSpinWait();
|
||||||
}
|
|
||||||
long end = System.nanoTime();
|
|
||||||
long elapsed = end - start;
|
|
||||||
|
|
||||||
if (elapsed > 1000000) { // > 1ms
|
|
||||||
// LOGGER.debug("Waited " + StringUtil.formatTime(elapsed) + ", looped " + count + " times");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package com.jozufozu.flywheel.lib.vertex;
|
package com.jozufozu.flywheel.lib.vertex;
|
||||||
|
|
||||||
|
import static org.joml.Math.fma;
|
||||||
|
import static org.joml.Math.invsqrt;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||||
import com.jozufozu.flywheel.lib.math.MatrixUtil;
|
import com.jozufozu.flywheel.lib.math.MatrixUtil;
|
||||||
import com.mojang.math.Matrix3f;
|
import com.mojang.math.Matrix3f;
|
||||||
|
@ -22,9 +25,9 @@ public final class VertexTransformations {
|
||||||
float tnx = MatrixUtil.transformNormalX(matrix, nx, ny, nz);
|
float tnx = MatrixUtil.transformNormalX(matrix, nx, ny, nz);
|
||||||
float tny = MatrixUtil.transformNormalY(matrix, nx, ny, nz);
|
float tny = MatrixUtil.transformNormalY(matrix, nx, ny, nz);
|
||||||
float tnz = MatrixUtil.transformNormalZ(matrix, nx, ny, nz);
|
float tnz = MatrixUtil.transformNormalZ(matrix, nx, ny, nz);
|
||||||
float sqrLength = tnx * tnx + tny * tny + tnz * tnz;
|
float sqrLength = fma(tnx, tnx, fma(tny, tny, tnz * tnz));
|
||||||
if (sqrLength != 0) {
|
if (sqrLength != 0) {
|
||||||
float f = 1 / (float) Math.sqrt(sqrLength);
|
float f = invsqrt(sqrLength);
|
||||||
tnx *= f;
|
tnx *= f;
|
||||||
tny *= f;
|
tny *= f;
|
||||||
tnz *= f;
|
tnz *= f;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.jozufozu.flywheel.lib.task;
|
package com.jozufozu.flywheel.lib.task;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class WaitGroupTest {
|
public class WaitGroupTest {
|
||||||
|
@ -9,6 +10,12 @@ public class WaitGroupTest {
|
||||||
WaitGroup wg = new WaitGroup();
|
WaitGroup wg = new WaitGroup();
|
||||||
wg.add();
|
wg.add();
|
||||||
wg.done();
|
wg.done();
|
||||||
Assertions.assertThrows(IllegalStateException.class, wg::done);
|
assertThrows(IllegalStateException.class, wg::done);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddNegative() {
|
||||||
|
WaitGroup wg = new WaitGroup();
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> wg.add(-1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue