mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-06 04:16:36 +01:00
Batched simplification
- Perform various cleanup in batching code - Remove ClientLevel argument from InstanceVertexTransformer#transform - Rename Plan#maybeSimplify to simplify - Rename some classes - Move TickContext from impl to impl.visualization - Move VertexListProviderRegistryImpl from impl to impl.vertex
This commit is contained in:
parent
afb14bc1f6
commit
961fafce0d
33 changed files with 172 additions and 169 deletions
|
@ -12,6 +12,7 @@ import net.minecraft.client.Camera;
|
|||
import net.minecraft.core.Vec3i;
|
||||
|
||||
public interface Engine extends InstancerProvider {
|
||||
Plan<RenderContext> createFramePlan();
|
||||
|
||||
void renderStage(TaskExecutor executor, RenderContext context, RenderStage stage);
|
||||
|
||||
|
@ -28,6 +29,4 @@ public interface Engine extends InstancerProvider {
|
|||
void addDebugInfo(List<String> info);
|
||||
|
||||
void delete();
|
||||
|
||||
Plan<RenderContext> createFramePlan();
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@ package com.jozufozu.flywheel.api.instance;
|
|||
|
||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
|
||||
public interface InstanceVertexTransformer<I extends Instance> {
|
||||
void transform(MutableVertexList vertexList, I instance, ClientLevel level);
|
||||
void transform(MutableVertexList vertexList, I instance);
|
||||
}
|
||||
|
|
|
@ -67,5 +67,5 @@ public interface Plan<C> {
|
|||
*
|
||||
* @return A simplified plan, or this.
|
||||
*/
|
||||
Plan<C> maybeSimplify();
|
||||
Plan<C> simplify();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.jozufozu.flywheel.api.vertex;
|
||||
|
||||
import com.jozufozu.flywheel.impl.VertexListProviderRegistryImpl;
|
||||
import com.jozufozu.flywheel.impl.vertex.VertexListProviderRegistryImpl;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
||||
public final class VertexListProviderRegistry {
|
||||
|
|
|
@ -20,5 +20,5 @@ public interface DynamicVisual extends Visual {
|
|||
* <p>
|
||||
* {@link Instancer}/{@link Instance} creation/acquisition is safe here.
|
||||
*/
|
||||
void beginFrame(VisualFrameContext context);
|
||||
void beginFrame(VisualFrameContext ctx);
|
||||
}
|
||||
|
|
|
@ -27,5 +27,5 @@ public interface TickableVisual extends Visual {
|
|||
* <p>
|
||||
* {@link Instancer}/{@link Instance} creation/acquisition is safe here.
|
||||
*/
|
||||
void tick(VisualTickContext c);
|
||||
void tick(VisualTickContext ctx);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import net.minecraft.client.multiplayer.ClientLevel;
|
|||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public record BatchContext(ClientLevel level, PoseStack.Pose matrices, FrustumIntersection frustum) {
|
||||
public record BatchContext(FrustumIntersection frustum, ClientLevel level, PoseStack.Pose matrices) {
|
||||
@NotNull
|
||||
static BatchContext create(RenderContext context, BlockPos origin) {
|
||||
Vec3 cameraPos = context.camera()
|
||||
|
@ -23,6 +23,6 @@ public record BatchContext(ClientLevel level, PoseStack.Pose matrices, FrustumIn
|
|||
org.joml.Matrix4f proj = MatrixUtil.toJoml(context.viewProjection());
|
||||
proj.translate((float) (origin.getX() - cameraPos.x), (float) (origin.getY() - cameraPos.y), (float) (origin.getZ() - cameraPos.z));
|
||||
|
||||
return new BatchContext(context.level(), stack.last(), new FrustumIntersection(proj));
|
||||
return new BatchContext(new FrustumIntersection(proj), context.level(), stack.last());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,12 +7,9 @@ import java.util.Set;
|
|||
|
||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||
import com.jozufozu.flywheel.extension.BufferBuilderExtension;
|
||||
import com.jozufozu.flywheel.extension.RenderTypeExtension;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
||||
public class BatchingDrawTracker {
|
||||
public class BatchedDrawTracker {
|
||||
private final Map<RenderStage, Set<DrawBuffer>> activeBuffers = new EnumMap<>(RenderStage.class);
|
||||
{
|
||||
for (RenderStage stage : RenderStage.values()) {
|
||||
|
@ -22,31 +19,33 @@ public class BatchingDrawTracker {
|
|||
|
||||
private final BufferBuilder scratch;
|
||||
|
||||
public BatchingDrawTracker() {
|
||||
public BatchedDrawTracker() {
|
||||
scratch = new BufferBuilder(8);
|
||||
|
||||
((BufferBuilderExtension) scratch).flywheel$freeBuffer();
|
||||
}
|
||||
|
||||
public static DrawBuffer getBuffer(RenderType renderType, RenderStage stage) {
|
||||
return RenderTypeExtension.getDrawBufferSet(renderType)
|
||||
.getBuffer(stage);
|
||||
}
|
||||
|
||||
public void markActive(RenderStage stage, DrawBuffer buffer) {
|
||||
public void markActive(DrawBuffer buffer) {
|
||||
synchronized (activeBuffers) {
|
||||
activeBuffers.get(stage)
|
||||
activeBuffers.get(buffer.getRenderStage())
|
||||
.add(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void markInactive(RenderStage stage, DrawBuffer buffer) {
|
||||
public void markInactive(DrawBuffer buffer) {
|
||||
synchronized (activeBuffers) {
|
||||
activeBuffers.get(stage)
|
||||
activeBuffers.get(buffer.getRenderStage())
|
||||
.remove(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasStage(RenderStage stage) {
|
||||
synchronized (activeBuffers) {
|
||||
return !activeBuffers.get(stage)
|
||||
.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw and reset all DrawBuffers for the given RenderStage.
|
||||
*
|
||||
|
@ -80,11 +79,4 @@ public class BatchingDrawTracker {
|
|||
buffers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasStage(RenderStage stage) {
|
||||
synchronized (activeBuffers) {
|
||||
return !activeBuffers.get(stage)
|
||||
.isEmpty();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,8 +6,8 @@ import com.jozufozu.flywheel.api.instance.Instance;
|
|||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
||||
|
||||
public class CPUInstancer<I extends Instance> extends AbstractInstancer<I> {
|
||||
public CPUInstancer(InstanceType<I> type) {
|
||||
public class BatchedInstancer<I extends Instance> extends AbstractInstancer<I> {
|
||||
public BatchedInstancer(InstanceType<I> type) {
|
||||
super(type);
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Vector4fc;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
|
@ -149,9 +150,10 @@ public class BatchedMeshPool {
|
|||
}
|
||||
|
||||
public class BufferedMesh {
|
||||
public final Mesh mesh;
|
||||
private final Mesh mesh;
|
||||
private final int byteSize;
|
||||
private final int vertexCount;
|
||||
private final Vector4fc boundingSphere;
|
||||
|
||||
private long byteIndex;
|
||||
private boolean deleted;
|
||||
|
@ -159,6 +161,7 @@ public class BatchedMeshPool {
|
|||
private BufferedMesh(Mesh mesh, long byteIndex) {
|
||||
this.mesh = mesh;
|
||||
vertexCount = mesh.getVertexCount();
|
||||
boundingSphere = mesh.getBoundingSphere();
|
||||
byteSize = vertexCount * vertexFormat.getVertexSize();
|
||||
this.byteIndex = byteIndex;
|
||||
}
|
||||
|
@ -171,6 +174,10 @@ public class BatchedMeshPool {
|
|||
return vertexCount;
|
||||
}
|
||||
|
||||
public Vector4fc getBoundingSphere() {
|
||||
return boundingSphere;
|
||||
}
|
||||
|
||||
public VertexFormat getVertexFormat() {
|
||||
return vertexFormat;
|
||||
}
|
||||
|
|
|
@ -16,39 +16,39 @@ import net.minecraft.client.renderer.RenderType;
|
|||
/**
|
||||
* All the rendering that happens within a render stage.
|
||||
*/
|
||||
public class BatchingStage implements SimplyComposedPlan<BatchContext> {
|
||||
public class BatchedStagePlan implements SimplyComposedPlan<BatchContext> {
|
||||
private final RenderStage stage;
|
||||
private final BatchingDrawTracker tracker;
|
||||
private final Map<RenderType, BufferPlan> buffers = new HashMap<>();
|
||||
private final BatchedDrawTracker tracker;
|
||||
private final Map<RenderType, BufferPlan> bufferPlans = new HashMap<>();
|
||||
|
||||
public BatchingStage(RenderStage renderStage, BatchingDrawTracker tracker) {
|
||||
public BatchedStagePlan(RenderStage renderStage, BatchedDrawTracker tracker) {
|
||||
stage = renderStage;
|
||||
this.tracker = tracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(TaskExecutor taskExecutor, BatchContext context, Runnable onCompletion) {
|
||||
if (buffers.isEmpty()) {
|
||||
if (isEmpty()) {
|
||||
onCompletion.run();
|
||||
return;
|
||||
}
|
||||
|
||||
taskExecutor.execute(() -> {
|
||||
var sync = new Synchronizer(buffers.size(), onCompletion);
|
||||
var sync = new Synchronizer(bufferPlans.size(), onCompletion);
|
||||
|
||||
for (var buffer : buffers.values()) {
|
||||
buffer.execute(taskExecutor, context, sync);
|
||||
for (var plan : bufferPlans.values()) {
|
||||
plan.execute(taskExecutor, context, sync);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void put(RenderType renderType, TransformCall<?> transformCall) {
|
||||
buffers.computeIfAbsent(renderType, type -> new BufferPlan(BatchingDrawTracker.getBuffer(type, stage)))
|
||||
bufferPlans.computeIfAbsent(renderType, type -> new BufferPlan(DrawBuffer.get(type, stage)))
|
||||
.add(transformCall);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return buffers.isEmpty();
|
||||
return bufferPlans.isEmpty();
|
||||
}
|
||||
|
||||
private class BufferPlan implements SimplyComposedPlan<BatchContext> {
|
||||
|
@ -72,19 +72,17 @@ public class BatchingStage implements SimplyComposedPlan<BatchContext> {
|
|||
return;
|
||||
}
|
||||
|
||||
tracker.markActive(stage, buffer);
|
||||
|
||||
var vertexCounter = new AtomicInteger(0);
|
||||
|
||||
tracker.markActive(buffer);
|
||||
buffer.prepare(vertexCount);
|
||||
|
||||
var vertexCounter = new AtomicInteger(0);
|
||||
var planContext = new TransformCall.PlanContext(ctx.frustum(), vertexCounter, buffer, ctx.level(), ctx.matrices());
|
||||
|
||||
var synchronizer = new Synchronizer(transformCalls.size(), () -> {
|
||||
buffer.vertexCount(vertexCounter.get());
|
||||
buffer.verticesToDraw(vertexCounter.get());
|
||||
onCompletion.run();
|
||||
});
|
||||
|
||||
var planContext = new TransformCall.PlanContext(ctx, buffer, vertexCounter);
|
||||
|
||||
for (var transformCall : transformCalls) {
|
||||
transformCall.plan()
|
||||
.execute(taskExecutor, planContext, synchronizer);
|
|
@ -24,11 +24,11 @@ import com.mojang.blaze3d.vertex.VertexFormat;
|
|||
import net.minecraft.client.renderer.RenderType;
|
||||
|
||||
public class BatchingEngine extends AbstractEngine implements SimplyComposedPlan<RenderContext> {
|
||||
private final BatchingDrawTracker drawTracker = new BatchingDrawTracker();
|
||||
private final Map<InstancerKey<?>, CPUInstancer<?>> instancers = new HashMap<>();
|
||||
private final BatchedDrawTracker drawTracker = new BatchedDrawTracker();
|
||||
private final Map<InstancerKey<?>, BatchedInstancer<?>> instancers = new HashMap<>();
|
||||
private final List<UninitializedInstancer> uninitializedInstancers = new ArrayList<>();
|
||||
private final List<CPUInstancer<?>> initializedInstancers = new ArrayList<>();
|
||||
private final Map<RenderStage, BatchingStage> stages = new EnumMap<>(RenderStage.class);
|
||||
private final List<BatchedInstancer<?>> initializedInstancers = new ArrayList<>();
|
||||
private final Map<RenderStage, BatchedStagePlan> stagePlans = new EnumMap<>(RenderStage.class);
|
||||
private final Map<VertexFormat, BatchedMeshPool> meshPools = new HashMap<>();
|
||||
|
||||
public BatchingEngine(int maxOriginDistance) {
|
||||
|
@ -36,8 +36,16 @@ public class BatchingEngine extends AbstractEngine implements SimplyComposedPlan
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <I extends Instance> Instancer<I> instancer(InstanceType<I> type, Model model, RenderStage stage) {
|
||||
return this.getInstancer(type, model, stage);
|
||||
InstancerKey<I> key = new InstancerKey<>(type, model, stage);
|
||||
BatchedInstancer<I> instancer = (BatchedInstancer<I>) instancers.get(key);
|
||||
if (instancer == null) {
|
||||
instancer = new BatchedInstancer<>(type);
|
||||
instancers.put(key, instancer);
|
||||
uninitializedInstancers.add(new UninitializedInstancer(instancer, model, stage));
|
||||
}
|
||||
return instancer;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -46,11 +54,11 @@ public class BatchingEngine extends AbstractEngine implements SimplyComposedPlan
|
|||
|
||||
BatchContext ctx = BatchContext.create(context, renderOrigin);
|
||||
|
||||
var sync = new Synchronizer(stages.values()
|
||||
var sync = new Synchronizer(stagePlans.values()
|
||||
.size(), onCompletion);
|
||||
|
||||
for (var transformSet : stages.values()) {
|
||||
transformSet.execute(taskExecutor, ctx, sync);
|
||||
for (var stagePlan : stagePlans.values()) {
|
||||
stagePlan.execute(taskExecutor, ctx, sync);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +75,7 @@ public class BatchingEngine extends AbstractEngine implements SimplyComposedPlan
|
|||
|
||||
@Override
|
||||
protected void onRenderOriginChanged() {
|
||||
initializedInstancers.forEach(CPUInstancer::clear);
|
||||
initializedInstancers.forEach(BatchedInstancer::clear);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -87,18 +95,6 @@ public class BatchingEngine extends AbstractEngine implements SimplyComposedPlan
|
|||
info.add("Origin: " + renderOrigin.getX() + ", " + renderOrigin.getY() + ", " + renderOrigin.getZ());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <I extends Instance> Instancer<I> getInstancer(InstanceType<I> type, Model model, RenderStage stage) {
|
||||
InstancerKey<I> key = new InstancerKey<>(type, model, stage);
|
||||
CPUInstancer<I> instancer = (CPUInstancer<I>) instancers.get(key);
|
||||
if (instancer == null) {
|
||||
instancer = new CPUInstancer<>(type);
|
||||
instancers.put(key, instancer);
|
||||
uninitializedInstancers.add(new UninitializedInstancer(instancer, model, stage));
|
||||
}
|
||||
return instancer;
|
||||
}
|
||||
|
||||
private void flush() {
|
||||
for (var instancer : uninitializedInstancers) {
|
||||
add(instancer.instancer(), instancer.model(), instancer.stage());
|
||||
|
@ -110,14 +106,14 @@ public class BatchingEngine extends AbstractEngine implements SimplyComposedPlan
|
|||
}
|
||||
}
|
||||
|
||||
private void add(CPUInstancer<?> instancer, Model model, RenderStage stage) {
|
||||
var batchingStage = stages.computeIfAbsent(stage, renderStage -> new BatchingStage(renderStage, drawTracker));
|
||||
private void add(BatchedInstancer<?> instancer, Model model, RenderStage stage) {
|
||||
var stagePlan = stagePlans.computeIfAbsent(stage, renderStage -> new BatchedStagePlan(renderStage, drawTracker));
|
||||
var meshes = model.getMeshes();
|
||||
for (var entry : meshes.entrySet()) {
|
||||
var material = entry.getKey();
|
||||
RenderType renderType = material.getBatchingRenderType();
|
||||
var transformCall = new TransformCall<>(instancer, material, alloc(entry.getValue(), renderType.format()));
|
||||
batchingStage.put(renderType, transformCall);
|
||||
stagePlan.put(renderType, transformCall);
|
||||
}
|
||||
initializedInstancers.add(instancer);
|
||||
}
|
||||
|
@ -127,6 +123,6 @@ public class BatchingEngine extends AbstractEngine implements SimplyComposedPlan
|
|||
.alloc(mesh);
|
||||
}
|
||||
|
||||
private record UninitializedInstancer(CPUInstancer<?> instancer, Model model, RenderStage stage) {
|
||||
private record UninitializedInstancer(BatchedInstancer<?> instancer, Model model, RenderStage stage) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,11 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.ReloadRenderersEvent;
|
||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
|
||||
import com.jozufozu.flywheel.extension.BufferBuilderExtension;
|
||||
import com.jozufozu.flywheel.extension.RenderTypeExtension;
|
||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
||||
|
@ -22,6 +24,7 @@ public class DrawBuffer {
|
|||
private static final List<DrawBuffer> ALL = new ArrayList<>();
|
||||
|
||||
private final RenderType renderType;
|
||||
private final RenderStage renderStage;
|
||||
private final VertexFormat format;
|
||||
private final int stride;
|
||||
private final VertexListProvider provider;
|
||||
|
@ -31,9 +34,11 @@ public class DrawBuffer {
|
|||
|
||||
private boolean prepared;
|
||||
private int vertexCount;
|
||||
private int verticesToDraw;
|
||||
|
||||
public DrawBuffer(RenderType renderType, VertexFormat format, int stride, VertexListProvider provider) {
|
||||
public DrawBuffer(RenderType renderType, RenderStage renderStage, VertexFormat format, int stride, VertexListProvider provider) {
|
||||
this.renderType = renderType;
|
||||
this.renderStage = renderStage;
|
||||
this.format = format;
|
||||
this.stride = stride;
|
||||
this.provider = provider;
|
||||
|
@ -52,6 +57,7 @@ public class DrawBuffer {
|
|||
}
|
||||
|
||||
this.vertexCount = vertexCount;
|
||||
verticesToDraw = this.vertexCount;
|
||||
|
||||
// Add one extra vertex to uphold the vanilla assumption that BufferBuilders have at least
|
||||
// enough buffer space for one more vertex. Rubidium checks for this extra space when popNextBuffer
|
||||
|
@ -69,15 +75,15 @@ public class DrawBuffer {
|
|||
prepared = true;
|
||||
}
|
||||
|
||||
public void vertexCount(int vertexCount) {
|
||||
this.vertexCount = vertexCount;
|
||||
}
|
||||
|
||||
public ReusableVertexList slice(int startVertex, int vertexCount) {
|
||||
if (!prepared) {
|
||||
throw new IllegalStateException("Cannot slice DrawBuffer that is not prepared!");
|
||||
}
|
||||
|
||||
if (startVertex + vertexCount > this.vertexCount) {
|
||||
throw new IndexOutOfBoundsException("Vertex count greater than allocated: " + startVertex + " + " + vertexCount + " > " + this.vertexCount);
|
||||
}
|
||||
|
||||
ReusableVertexList vertexList = provider.createVertexList();
|
||||
vertexList.ptr(ptrForVertex(startVertex));
|
||||
vertexList.vertexCount(vertexCount);
|
||||
|
@ -88,6 +94,10 @@ public class DrawBuffer {
|
|||
return memory.ptr() + startVertex * stride;
|
||||
}
|
||||
|
||||
public void verticesToDraw(int verticesToDraw) {
|
||||
this.verticesToDraw = verticesToDraw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the backing buffer into the given builder and prepares it for rendering.
|
||||
*
|
||||
|
@ -99,13 +109,17 @@ public class DrawBuffer {
|
|||
}
|
||||
|
||||
buffer.clear();
|
||||
bufferBuilder.flywheel$injectForRender(buffer, format, vertexCount);
|
||||
bufferBuilder.flywheel$injectForRender(buffer, format, verticesToDraw);
|
||||
}
|
||||
|
||||
public RenderType getRenderType() {
|
||||
return renderType;
|
||||
}
|
||||
|
||||
public RenderStage getRenderStage() {
|
||||
return renderStage;
|
||||
}
|
||||
|
||||
public VertexFormat getVertexFormat() {
|
||||
return format;
|
||||
}
|
||||
|
@ -118,11 +132,15 @@ public class DrawBuffer {
|
|||
return vertexCount;
|
||||
}
|
||||
|
||||
public int getVerticesToDraw() {
|
||||
return verticesToDraw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the buffer has any vertices.
|
||||
* @return {@code true} if the buffer has any vertices to draw.
|
||||
*/
|
||||
public boolean hasVertices() {
|
||||
return vertexCount > 0;
|
||||
return verticesToDraw > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,6 +151,7 @@ public class DrawBuffer {
|
|||
public void reset() {
|
||||
prepared = false;
|
||||
vertexCount = 0;
|
||||
verticesToDraw = 0;
|
||||
}
|
||||
|
||||
public void free() {
|
||||
|
@ -150,4 +169,9 @@ public class DrawBuffer {
|
|||
public static void onReloadRenderers(ReloadRenderersEvent event) {
|
||||
ALL.forEach(DrawBuffer::free);
|
||||
}
|
||||
|
||||
public static DrawBuffer get(RenderType renderType, RenderStage stage) {
|
||||
return RenderTypeExtension.getDrawBufferSet(renderType)
|
||||
.getBuffer(stage);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,6 @@ public class DrawBufferSet {
|
|||
}
|
||||
|
||||
public DrawBuffer getBuffer(RenderStage stage) {
|
||||
return buffers.computeIfAbsent(stage, $ -> new DrawBuffer(renderType, format, stride, provider));
|
||||
return buffers.computeIfAbsent(stage, renderStage -> new DrawBuffer(renderType, renderStage, format, stride, provider));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.jozufozu.flywheel.backend.engine.batching;
|
|||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.joml.FrustumIntersection;
|
||||
import org.joml.Vector4f;
|
||||
import org.joml.Vector4fc;
|
||||
|
||||
|
@ -18,61 +19,51 @@ import com.mojang.blaze3d.vertex.PoseStack;
|
|||
import com.mojang.math.Matrix3f;
|
||||
import com.mojang.math.Matrix4f;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
|
||||
public class TransformCall<I extends Instance> {
|
||||
private final CPUInstancer<I> instancer;
|
||||
private final BatchedInstancer<I> instancer;
|
||||
private final int meshVertexCount;
|
||||
private final InstanceVertexTransformer<I> instanceVertexTransformer;
|
||||
private final MaterialVertexTransformer materialVertexTransformer;
|
||||
private final InstanceBoundingSphereTransformer<I> boundingSphereTransformer;
|
||||
private final Vector4fc boundingSphere;
|
||||
|
||||
private final Plan<PlanContext> drawPlan;
|
||||
|
||||
public TransformCall(CPUInstancer<I> instancer, Material material, BatchedMeshPool.BufferedMesh mesh) {
|
||||
public TransformCall(BatchedInstancer<I> instancer, Material material, BatchedMeshPool.BufferedMesh mesh) {
|
||||
this.instancer = instancer;
|
||||
|
||||
instanceVertexTransformer = instancer.type.getVertexTransformer();
|
||||
boundingSphereTransformer = instancer.type.getBoundingSphereTransformer();
|
||||
materialVertexTransformer = material.getVertexTransformer();
|
||||
InstanceVertexTransformer<I> instanceVertexTransformer = instancer.type.getVertexTransformer();
|
||||
InstanceBoundingSphereTransformer<I> boundingSphereTransformer = instancer.type.getBoundingSphereTransformer();
|
||||
MaterialVertexTransformer materialVertexTransformer = material.getVertexTransformer();
|
||||
|
||||
meshVertexCount = mesh.getVertexCount();
|
||||
boundingSphere = mesh.mesh.getBoundingSphere();
|
||||
Vector4fc meshBoundingSphere = mesh.getBoundingSphere();
|
||||
|
||||
drawPlan = ForEachPlan.of(instancer::getAll, (instance, ctx) -> {
|
||||
var boundingSphere = new Vector4f(this.boundingSphere);
|
||||
|
||||
var boundingSphere = new Vector4f(meshBoundingSphere);
|
||||
boundingSphereTransformer.transform(boundingSphere, instance);
|
||||
|
||||
if (!ctx.ctx.frustum()
|
||||
if (!ctx.frustum
|
||||
.testSphere(boundingSphere.x, boundingSphere.y, boundingSphere.z, boundingSphere.w)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int baseVertex = ctx.vertexCount.getAndAdd(meshVertexCount);
|
||||
|
||||
if (baseVertex + meshVertexCount > ctx.buffer.getVertexCount()) {
|
||||
throw new IndexOutOfBoundsException("Vertex count greater than allocated: " + baseVertex + " + " + meshVertexCount + " > " + ctx.buffer.getVertexCount());
|
||||
}
|
||||
|
||||
final int baseVertex = ctx.vertexCounter.getAndAdd(meshVertexCount);
|
||||
var sub = ctx.buffer.slice(baseVertex, meshVertexCount);
|
||||
|
||||
mesh.copyTo(sub.ptr());
|
||||
|
||||
instanceVertexTransformer.transform(sub, instance, ctx.ctx.level());
|
||||
|
||||
materialVertexTransformer.transform(sub, ctx.ctx.level());
|
||||
applyMatrices(sub, ctx.ctx.matrices());
|
||||
instanceVertexTransformer.transform(sub, instance);
|
||||
materialVertexTransformer.transform(sub, ctx.level);
|
||||
applyMatrices(sub, ctx.matrices);
|
||||
});
|
||||
}
|
||||
|
||||
public int getTotalVertexCount() {
|
||||
return meshVertexCount * instancer.getInstanceCount();
|
||||
}
|
||||
|
||||
public void setup() {
|
||||
instancer.update();
|
||||
}
|
||||
|
||||
public int getTotalVertexCount() {
|
||||
return meshVertexCount * instancer.getInstanceCount();
|
||||
}
|
||||
|
||||
public Plan<PlanContext> plan() {
|
||||
return drawPlan;
|
||||
}
|
||||
|
@ -87,6 +78,6 @@ public class TransformCall<I extends Instance> {
|
|||
}
|
||||
}
|
||||
|
||||
public record PlanContext(BatchContext ctx, DrawBuffer buffer, AtomicInteger vertexCount) {
|
||||
public record PlanContext(FrustumIntersection frustum, AtomicInteger vertexCounter, DrawBuffer buffer, ClientLevel level, PoseStack.Pose matrices) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@ package com.jozufozu.flywheel.backend.engine.instancing;
|
|||
import com.jozufozu.flywheel.gl.array.GlVertexArray;
|
||||
|
||||
public class DrawCall {
|
||||
private final GPUInstancer<?> instancer;
|
||||
private final InstancedInstancer<?> instancer;
|
||||
private final InstancedMeshPool.BufferedMesh mesh;
|
||||
|
||||
private final int meshAttributes;
|
||||
private GlVertexArray vao;
|
||||
|
||||
public DrawCall(GPUInstancer<?> instancer, InstancedMeshPool.BufferedMesh mesh) {
|
||||
public DrawCall(InstancedInstancer<?> instancer, InstancedMeshPool.BufferedMesh mesh) {
|
||||
this.instancer = instancer;
|
||||
this.mesh = mesh;
|
||||
|
||||
|
|
|
@ -22,10 +22,10 @@ import com.jozufozu.flywheel.api.model.Model;
|
|||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
||||
|
||||
public class InstancingDrawManager {
|
||||
private final Map<InstancerKey<?>, GPUInstancer<?>> instancers = new HashMap<>();
|
||||
public class InstancedDrawManager {
|
||||
private final Map<InstancerKey<?>, InstancedInstancer<?>> instancers = new HashMap<>();
|
||||
private final List<UninitializedInstancer> uninitializedInstancers = new ArrayList<>();
|
||||
private final List<GPUInstancer<?>> initializedInstancers = new ArrayList<>();
|
||||
private final List<InstancedInstancer<?>> initializedInstancers = new ArrayList<>();
|
||||
private final Map<RenderStage, DrawSet> drawSets = new EnumMap<>(RenderStage.class);
|
||||
private final Map<VertexType, InstancedMeshPool> meshPools = new HashMap<>();
|
||||
|
||||
|
@ -36,9 +36,9 @@ public class InstancingDrawManager {
|
|||
@SuppressWarnings("unchecked")
|
||||
public <I extends Instance> Instancer<I> getInstancer(InstanceType<I> type, Model model, RenderStage stage) {
|
||||
InstancerKey<I> key = new InstancerKey<>(type, model, stage);
|
||||
GPUInstancer<I> instancer = (GPUInstancer<I>) instancers.get(key);
|
||||
InstancedInstancer<I> instancer = (InstancedInstancer<I>) instancers.get(key);
|
||||
if (instancer == null) {
|
||||
instancer = new GPUInstancer<>(type);
|
||||
instancer = new InstancedInstancer<>(type);
|
||||
instancers.put(key, instancer);
|
||||
uninitializedInstancers.add(new UninitializedInstancer(instancer, model, stage));
|
||||
}
|
||||
|
@ -67,15 +67,15 @@ public class InstancingDrawManager {
|
|||
.forEach(DrawSet::delete);
|
||||
drawSets.clear();
|
||||
|
||||
initializedInstancers.forEach(GPUInstancer::delete);
|
||||
initializedInstancers.forEach(InstancedInstancer::delete);
|
||||
initializedInstancers.clear();
|
||||
}
|
||||
|
||||
public void clearInstancers() {
|
||||
initializedInstancers.forEach(GPUInstancer::clear);
|
||||
initializedInstancers.forEach(InstancedInstancer::clear);
|
||||
}
|
||||
|
||||
private void add(GPUInstancer<?> instancer, Model model, RenderStage stage) {
|
||||
private void add(InstancedInstancer<?> instancer, Model model, RenderStage stage) {
|
||||
instancer.init();
|
||||
DrawSet drawSet = drawSets.computeIfAbsent(stage, DrawSet::new);
|
||||
var meshes = model.getMeshes();
|
||||
|
@ -129,6 +129,6 @@ public class InstancingDrawManager {
|
|||
}
|
||||
}
|
||||
|
||||
private record UninitializedInstancer(GPUInstancer<?> instancer, Model model, RenderStage stage) {
|
||||
private record UninitializedInstancer(InstancedInstancer<?> instancer, Model model, RenderStage stage) {
|
||||
}
|
||||
}
|
|
@ -14,14 +14,14 @@ import com.jozufozu.flywheel.gl.buffer.GlBuffer;
|
|||
import com.jozufozu.flywheel.gl.buffer.GlBufferUsage;
|
||||
import com.jozufozu.flywheel.gl.buffer.MappedBuffer;
|
||||
|
||||
public class GPUInstancer<I extends Instance> extends AbstractInstancer<I> {
|
||||
public class InstancedInstancer<I extends Instance> extends AbstractInstancer<I> {
|
||||
private final BufferLayout instanceFormat;
|
||||
private final int instanceStride;
|
||||
|
||||
private final Set<GlVertexArray> boundTo = new HashSet<>();
|
||||
private GlBuffer vbo;
|
||||
|
||||
public GPUInstancer(InstanceType<I> type) {
|
||||
public InstancedInstancer(InstanceType<I> type) {
|
||||
super(type);
|
||||
instanceFormat = type.getLayout();
|
||||
instanceStride = instanceFormat.getStride();
|
|
@ -26,7 +26,7 @@ import net.minecraft.client.Minecraft;
|
|||
|
||||
public class InstancingEngine extends AbstractEngine {
|
||||
private final Context context;
|
||||
private final InstancingDrawManager drawManager = new InstancingDrawManager();
|
||||
private final InstancedDrawManager drawManager = new InstancedDrawManager();
|
||||
|
||||
public InstancingEngine(int maxOriginDistance, Context context) {
|
||||
super(maxOriginDistance);
|
||||
|
@ -77,7 +77,7 @@ public class InstancingEngine extends AbstractEngine {
|
|||
RenderSystem.enableCull();
|
||||
}
|
||||
|
||||
private void render(InstancingDrawManager.DrawSet drawSet) {
|
||||
private void render(InstancedDrawManager.DrawSet drawSet) {
|
||||
for (var entry : drawSet) {
|
||||
var shader = entry.getKey();
|
||||
var drawCalls = entry.getValue();
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package com.jozufozu.flywheel.impl;
|
||||
package com.jozufozu.flywheel.impl.vertex;
|
||||
|
||||
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
|
||||
import com.jozufozu.flywheel.extension.VertexFormatExtension;
|
||||
import com.jozufozu.flywheel.impl.vertex.InferredVertexListProviderImpl;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
||||
// TODO: Add freezing
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.impl;
|
||||
package com.jozufozu.flywheel.impl.visualization;
|
||||
|
||||
public record TickContext(double cameraX, double cameraY, double cameraZ) {
|
||||
}
|
|
@ -17,7 +17,6 @@ import com.jozufozu.flywheel.backend.task.FlwTaskExecutor;
|
|||
import com.jozufozu.flywheel.backend.task.ParallelTaskExecutor;
|
||||
import com.jozufozu.flywheel.config.FlwCommands;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.impl.TickContext;
|
||||
import com.jozufozu.flywheel.impl.visualization.manager.BlockEntityVisualManager;
|
||||
import com.jozufozu.flywheel.impl.visualization.manager.EffectVisualManager;
|
||||
import com.jozufozu.flywheel.impl.visualization.manager.EntityVisualManager;
|
||||
|
@ -59,7 +58,7 @@ public class VisualWorld implements AutoCloseable {
|
|||
tickPlan = blockEntities.createTickPlan()
|
||||
.and(entities.createTickPlan())
|
||||
.and(effects.createTickPlan())
|
||||
.maybeSimplify();
|
||||
.simplify();
|
||||
framePlan = new FramePlan();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ import com.jozufozu.flywheel.api.task.Plan;
|
|||
import com.jozufozu.flywheel.api.visual.VisualFrameContext;
|
||||
import com.jozufozu.flywheel.api.visual.VisualTickContext;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.impl.TickContext;
|
||||
import com.jozufozu.flywheel.impl.visualization.FrameContext;
|
||||
import com.jozufozu.flywheel.impl.visualization.TickContext;
|
||||
import com.jozufozu.flywheel.impl.visualization.ratelimit.BandedPrimeLimiter;
|
||||
import com.jozufozu.flywheel.impl.visualization.ratelimit.DistanceUpdateLimiterImpl;
|
||||
import com.jozufozu.flywheel.impl.visualization.ratelimit.NonLimiter;
|
||||
|
|
|
@ -38,9 +38,9 @@ public class VisualUpdatePlan<C> implements SimplyComposedPlan<C> {
|
|||
@NotNull
|
||||
private Plan<C> updatePlans() {
|
||||
if (plan == null) {
|
||||
plan = new NestedPlan<>(initializer.get()).maybeSimplify();
|
||||
plan = new NestedPlan<>(initializer.get()).simplify();
|
||||
} else if (needsSimplify) {
|
||||
plan = plan.maybeSimplify();
|
||||
plan = plan.simplify();
|
||||
}
|
||||
|
||||
needsSimplify = false;
|
||||
|
|
|
@ -48,7 +48,7 @@ public class OrientedType implements InstanceType<OrientedInstance> {
|
|||
|
||||
@Override
|
||||
public InstanceVertexTransformer<OrientedInstance> getVertexTransformer() {
|
||||
return (vertexList, instance, level) -> {
|
||||
return (vertexList, instance) -> {
|
||||
Quaternion q = new Quaternion(instance.qX, instance.qY, instance.qZ, instance.qW);
|
||||
|
||||
Matrix4f modelMatrix = new Matrix4f();
|
||||
|
|
|
@ -43,7 +43,7 @@ public class TransformedType implements InstanceType<TransformedInstance> {
|
|||
|
||||
@Override
|
||||
public InstanceVertexTransformer<TransformedInstance> getVertexTransformer() {
|
||||
return (vertexList, instance, level) -> {
|
||||
return (vertexList, instance) -> {
|
||||
float r = RenderMath.uf(instance.r);
|
||||
float g = RenderMath.uf(instance.g);
|
||||
float b = RenderMath.uf(instance.b);
|
||||
|
|
|
@ -14,9 +14,9 @@ public record BarrierPlan<C>(Plan<C> first, Plan<C> second) implements SimplyCom
|
|||
}
|
||||
|
||||
@Override
|
||||
public Plan<C> maybeSimplify() {
|
||||
var first = this.first.maybeSimplify();
|
||||
var second = this.second.maybeSimplify();
|
||||
public Plan<C> simplify() {
|
||||
var first = this.first.simplify();
|
||||
var second = this.second.simplify();
|
||||
|
||||
if (first == UnitPlan.of()) {
|
||||
return second;
|
||||
|
|
|
@ -13,8 +13,8 @@ public record MapContextPlan<C, D>(Function<C, D> map, Plan<D> plan) implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public Plan<C> maybeSimplify() {
|
||||
var maybeSimplified = plan.maybeSimplify();
|
||||
public Plan<C> simplify() {
|
||||
var maybeSimplified = plan.simplify();
|
||||
|
||||
if (maybeSimplified instanceof UnitPlan) {
|
||||
return UnitPlan.of();
|
||||
|
|
|
@ -44,14 +44,14 @@ public record NestedPlan<C>(List<Plan<C>> parallelPlans) implements SimplyCompos
|
|||
}
|
||||
|
||||
@Override
|
||||
public Plan<C> maybeSimplify() {
|
||||
public Plan<C> simplify() {
|
||||
if (parallelPlans.isEmpty()) {
|
||||
return UnitPlan.of();
|
||||
}
|
||||
|
||||
if (parallelPlans.size() == 1) {
|
||||
return parallelPlans.get(0)
|
||||
.maybeSimplify();
|
||||
.simplify();
|
||||
}
|
||||
|
||||
var simplifiedTasks = new ArrayList<ContextConsumer<C>>();
|
||||
|
@ -59,7 +59,7 @@ public record NestedPlan<C>(List<Plan<C>> parallelPlans) implements SimplyCompos
|
|||
var toVisit = new ArrayDeque<>(parallelPlans);
|
||||
while (!toVisit.isEmpty()) {
|
||||
var plan = toVisit.pop()
|
||||
.maybeSimplify();
|
||||
.simplify();
|
||||
|
||||
if (plan == UnitPlan.of()) {
|
||||
continue;
|
||||
|
|
|
@ -45,7 +45,7 @@ public record SimplePlan<C>(List<ContextConsumer<C>> parallelTasks) implements S
|
|||
}
|
||||
|
||||
@Override
|
||||
public Plan<C> maybeSimplify() {
|
||||
public Plan<C> simplify() {
|
||||
if (parallelTasks.isEmpty()) {
|
||||
return UnitPlan.of();
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ public interface SimplyComposedPlan<C> extends Plan<C> {
|
|||
}
|
||||
|
||||
@Override
|
||||
default Plan<C> maybeSimplify() {
|
||||
default Plan<C> simplify() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public class UnitPlan<C> implements Plan<C> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Plan<C> maybeSimplify() {
|
||||
public Plan<C> simplify() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,36 +15,36 @@ public class PlanSimplificationTest {
|
|||
@Test
|
||||
void emptyPlans() {
|
||||
var empty = NestedPlan.of();
|
||||
Assertions.assertEquals(empty.maybeSimplify(), UnitPlan.of());
|
||||
Assertions.assertEquals(empty.simplify(), UnitPlan.of());
|
||||
|
||||
var simpleEmpty = SimplePlan.of();
|
||||
Assertions.assertEquals(simpleEmpty.maybeSimplify(), UnitPlan.of());
|
||||
Assertions.assertEquals(simpleEmpty.simplify(), UnitPlan.of());
|
||||
}
|
||||
|
||||
@Test
|
||||
void nestedSimplePlans() {
|
||||
var twoSimple = NestedPlan.of(SimplePlan.of(NOOP, NOOP, NOOP), SIMPLE);
|
||||
Assertions.assertEquals(twoSimple.maybeSimplify(), SimplePlan.of(NOOP, NOOP, NOOP, NOOP));
|
||||
Assertions.assertEquals(twoSimple.simplify(), SimplePlan.of(NOOP, NOOP, NOOP, NOOP));
|
||||
|
||||
var threeSimple = NestedPlan.of(SIMPLE, SIMPLE, SIMPLE);
|
||||
Assertions.assertEquals(threeSimple.maybeSimplify(), SimplePlan.of(NOOP, NOOP, NOOP));
|
||||
Assertions.assertEquals(threeSimple.simplify(), SimplePlan.of(NOOP, NOOP, NOOP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneNestedPlan() {
|
||||
var oneSimple = NestedPlan.of(SIMPLE);
|
||||
|
||||
Assertions.assertEquals(oneSimple.maybeSimplify(), SIMPLE);
|
||||
Assertions.assertEquals(oneSimple.simplify(), SIMPLE);
|
||||
|
||||
var mainThreadNoop = new OnMainThreadPlan<>(NOOP);
|
||||
var oneMainThread = NestedPlan.of(mainThreadNoop);
|
||||
|
||||
Assertions.assertEquals(oneMainThread.maybeSimplify(), mainThreadNoop);
|
||||
Assertions.assertEquals(oneMainThread.simplify(), mainThreadNoop);
|
||||
|
||||
var barrier = new BarrierPlan<>(SIMPLE, SIMPLE);
|
||||
var oneBarrier = NestedPlan.of(barrier);
|
||||
|
||||
Assertions.assertEquals(oneBarrier.maybeSimplify(), barrier);
|
||||
Assertions.assertEquals(oneBarrier.simplify(), barrier);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -52,16 +52,16 @@ public class PlanSimplificationTest {
|
|||
var outer = NestedPlan.of(SIMPLE);
|
||||
var outermost = NestedPlan.of(outer);
|
||||
|
||||
Assertions.assertEquals(outermost.maybeSimplify(), SIMPLE);
|
||||
Assertions.assertEquals(outermost.simplify(), SIMPLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void nestedUnitPlan() {
|
||||
var onlyUnit = NestedPlan.of(UnitPlan.of(), UnitPlan.of(), UnitPlan.of());
|
||||
Assertions.assertEquals(onlyUnit.maybeSimplify(), UnitPlan.of());
|
||||
Assertions.assertEquals(onlyUnit.simplify(), UnitPlan.of());
|
||||
|
||||
var unitAndSimple = NestedPlan.of(UnitPlan.of(), UnitPlan.of(), SIMPLE);
|
||||
Assertions.assertEquals(unitAndSimple.maybeSimplify(), SIMPLE);
|
||||
Assertions.assertEquals(unitAndSimple.simplify(), SIMPLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -70,11 +70,11 @@ public class PlanSimplificationTest {
|
|||
});
|
||||
|
||||
var nested = NestedPlan.of(mainThreadNoop, SIMPLE);
|
||||
Assertions.assertEquals(nested.maybeSimplify(), nested); // cannot simplify
|
||||
Assertions.assertEquals(nested.simplify(), nested); // cannot simplify
|
||||
|
||||
var barrier = new BarrierPlan<>(SIMPLE, SIMPLE);
|
||||
var complex = NestedPlan.of(barrier, nested);
|
||||
Assertions.assertEquals(complex.maybeSimplify(), NestedPlan.of(barrier, mainThreadNoop, SIMPLE));
|
||||
Assertions.assertEquals(complex.simplify(), NestedPlan.of(barrier, mainThreadNoop, SIMPLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -84,7 +84,7 @@ public class PlanSimplificationTest {
|
|||
var barrier = new BarrierPlan<>(SIMPLE, SIMPLE);
|
||||
var oneMainThread = NestedPlan.of(mainThreadNoop, NestedPlan.of(mainThreadNoop, barrier, barrier));
|
||||
|
||||
Assertions.assertEquals(oneMainThread.maybeSimplify(), NestedPlan.of(mainThreadNoop, mainThreadNoop, barrier, barrier));
|
||||
Assertions.assertEquals(oneMainThread.simplify(), NestedPlan.of(mainThreadNoop, mainThreadNoop, barrier, barrier));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -92,21 +92,21 @@ public class PlanSimplificationTest {
|
|||
var barrier = new BarrierPlan<>(SIMPLE, SIMPLE);
|
||||
var oneMainThread = NestedPlan.of(barrier, NestedPlan.of(UnitPlan.of(), UnitPlan.of()));
|
||||
|
||||
Assertions.assertEquals(oneMainThread.maybeSimplify(), barrier);
|
||||
Assertions.assertEquals(oneMainThread.simplify(), barrier);
|
||||
}
|
||||
|
||||
@Test
|
||||
void barrierPlan() {
|
||||
var doubleUnit = new BarrierPlan<>(UnitPlan.of(), UnitPlan.of());
|
||||
Assertions.assertEquals(doubleUnit.maybeSimplify(), UnitPlan.of());
|
||||
Assertions.assertEquals(doubleUnit.simplify(), UnitPlan.of());
|
||||
|
||||
var simpleThenUnit = new BarrierPlan<>(SIMPLE, UnitPlan.of());
|
||||
Assertions.assertEquals(simpleThenUnit.maybeSimplify(), SIMPLE);
|
||||
Assertions.assertEquals(simpleThenUnit.simplify(), SIMPLE);
|
||||
|
||||
var unitThenSimple = new BarrierPlan<>(UnitPlan.of(), SIMPLE);
|
||||
Assertions.assertEquals(unitThenSimple.maybeSimplify(), SIMPLE);
|
||||
Assertions.assertEquals(unitThenSimple.simplify(), SIMPLE);
|
||||
|
||||
var simpleThenSimple = new BarrierPlan<>(SIMPLE, SIMPLE);
|
||||
Assertions.assertEquals(simpleThenSimple.maybeSimplify(), new BarrierPlan<>(SIMPLE, SIMPLE));
|
||||
Assertions.assertEquals(simpleThenSimple.simplify(), new BarrierPlan<>(SIMPLE, SIMPLE));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue