And I oobe

- Raise exception when trying to slice outside DrawBuffer bounds
- Count vertices in BufferPlan#execute to account for instance creation
  during Visual updates
- Mark DrawBuffers active by default
This commit is contained in:
Jozufozu 2023-04-17 15:02:45 -07:00
parent 907589fb23
commit a5139bdca4
4 changed files with 29 additions and 19 deletions

View file

@ -40,6 +40,13 @@ public class BatchingDrawTracker {
} }
} }
public void markInactive(RenderStage stage, DrawBuffer buffer) {
synchronized (activeBuffers) {
activeBuffers.get(stage)
.remove(buffer);
}
}
/** /**
* Draw and reset all DrawBuffers for the given RenderStage. * Draw and reset all DrawBuffers for the given RenderStage.
* *
@ -75,7 +82,9 @@ public class BatchingDrawTracker {
} }
public boolean hasStage(RenderStage stage) { public boolean hasStage(RenderStage stage) {
return !activeBuffers.get(stage) synchronized (activeBuffers) {
.isEmpty(); return !activeBuffers.get(stage)
.isEmpty();
}
} }
} }

View file

@ -51,15 +51,10 @@ public class BatchingEngine extends AbstractEngine {
var stack = FlwUtil.copyPoseStack(context.stack()); var stack = FlwUtil.copyPoseStack(context.stack());
stack.translate(renderOrigin.getX() - cameraPos.x, renderOrigin.getY() - cameraPos.y, renderOrigin.getZ() - cameraPos.z); stack.translate(renderOrigin.getX() - cameraPos.x, renderOrigin.getY() - cameraPos.y, renderOrigin.getZ() - cameraPos.z);
double cameraX = cameraPos.x;
double cameraY = cameraPos.y;
double cameraZ = cameraPos.z;
org.joml.Matrix4f proj = MatrixUtil.toJoml(context.viewProjection()); org.joml.Matrix4f proj = MatrixUtil.toJoml(context.viewProjection());
proj.translate((float) (renderOrigin.getX() - cameraX), (float) (renderOrigin.getY() - cameraY), (float) (renderOrigin.getZ() - cameraZ)); proj.translate((float) (renderOrigin.getX() - cameraPos.x), (float) (renderOrigin.getY() - cameraPos.y), (float) (renderOrigin.getZ() - cameraPos.z));
FrustumIntersection frustum = new FrustumIntersection(proj);
var ctx = new FrameContext(context.level(), stack.last(), frustum); var ctx = new FrameContext(context.level(), stack.last(), new FrustumIntersection(proj));
flush(); flush();

View file

@ -11,7 +11,6 @@ import com.jozufozu.flywheel.api.task.Plan;
import com.jozufozu.flywheel.api.task.TaskExecutor; import com.jozufozu.flywheel.api.task.TaskExecutor;
import com.jozufozu.flywheel.lib.task.NestedPlan; import com.jozufozu.flywheel.lib.task.NestedPlan;
import com.jozufozu.flywheel.lib.task.Synchronizer; import com.jozufozu.flywheel.lib.task.Synchronizer;
import com.jozufozu.flywheel.lib.task.UnitPlan;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
@ -51,7 +50,6 @@ public class BatchingStage {
private final DrawBuffer buffer; private final DrawBuffer buffer;
private final List<TransformCall<?>> transformCalls = new ArrayList<>(); private final List<TransformCall<?>> transformCalls = new ArrayList<>();
private FrameContext ctx; private FrameContext ctx;
private int vertexCount;
public BufferPlan(DrawBuffer drawBuffer) { public BufferPlan(DrawBuffer drawBuffer) {
buffer = drawBuffer; buffer = drawBuffer;
@ -60,14 +58,7 @@ public class BatchingStage {
public Plan update(FrameContext ctx) { public Plan update(FrameContext ctx) {
this.ctx = ctx; this.ctx = ctx;
vertexCount = setupAndCountVertices(); // Mark the tracker active by default...
if (vertexCount <= 0) {
return UnitPlan.INSTANCE;
}
// Moving this into execute leads to a race condition that causes things to flash in and out of existence.
// Sometimes the main thread decides there's nothing to render in a stage before the worker threads have
// marked a stage as active. Then in the next frame #markActive complains because it's already prepared.
tracker.markActive(stage, buffer); tracker.markActive(stage, buffer);
return this; return this;
} }
@ -78,7 +69,18 @@ public class BatchingStage {
@Override @Override
public void execute(TaskExecutor taskExecutor, Runnable onCompletion) { public void execute(TaskExecutor taskExecutor, Runnable onCompletion) {
// Count vertices here to account for instances being added during Visual updates.
var vertexCount = setupAndCountVertices();
if (vertexCount <= 0) {
// ...then mark it inactive if there's nothing to draw.
tracker.markInactive(stage, buffer);
onCompletion.run();
return;
}
AtomicInteger vertexCounter = new AtomicInteger(0); AtomicInteger vertexCounter = new AtomicInteger(0);
buffer.prepare(vertexCount); buffer.prepare(vertexCount);
var synchronizer = new Synchronizer(transformCalls.size(), () -> { var synchronizer = new Synchronizer(transformCalls.size(), () -> {

View file

@ -65,6 +65,10 @@ public class TransformCall<I extends Instance> {
final int baseVertex = vertexCount.getAndAdd(meshVertexCount); final int baseVertex = vertexCount.getAndAdd(meshVertexCount);
if (baseVertex + meshVertexCount > buffer.getVertexCount()) {
throw new IndexOutOfBoundsException("Vertex count greater than allocated: " + baseVertex + " + " + meshVertexCount + " > " + buffer.getVertexCount());
}
var sub = buffer.slice(baseVertex, meshVertexCount); var sub = buffer.slice(baseVertex, meshVertexCount);
mesh.copyTo(sub.ptr()); mesh.copyTo(sub.ptr());