Misc. tweaks

- Drastically reduce stutter on origin shift (it's still bad)
 - GPUInstancers mark their buffers as dynamic
This commit is contained in:
Jozufozu 2022-06-20 19:26:39 -07:00
parent 1ab1c9e6f6
commit aa10930fa8
6 changed files with 63 additions and 37 deletions

View file

@ -327,12 +327,18 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
AbstractInstance renderer = createRaw(obj);
if (renderer != null) {
setup(obj, renderer);
instances.put(obj, renderer);
}
return renderer;
}
private void setup(T obj, AbstractInstance renderer) {
renderer.init();
renderer.updateLight();
LightUpdater.get(renderer.level)
.addListener(renderer);
instances.put(obj, renderer);
if (renderer instanceof TickableInstance r) {
tickableInstances.put(obj, r);
r.tick();
@ -344,14 +350,21 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
}
}
return renderer;
}
@Override
public void onOriginShift() {
ArrayList<T> instanced = new ArrayList<>(instances.keySet());
invalidate();
instanced.forEach(this::add);
dynamicInstances.clear();
tickableInstances.clear();
instances.replaceAll((obj, instance) -> {
instance.remove();
AbstractInstance out = createRaw(obj);
if (out != null) {
setup(obj, out);
}
return out;
});
}
public void detachLightListeners() {

View file

@ -3,7 +3,6 @@ package com.jozufozu.flywheel.backend.instancing;
import java.util.List;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.model.MeshPool;
import com.jozufozu.flywheel.config.FlwCommands;
import com.jozufozu.flywheel.config.FlwConfig;
import com.jozufozu.flywheel.core.RenderContext;
@ -18,10 +17,7 @@ import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
public class InstancedRenderDispatcher {

View file

@ -268,8 +268,8 @@ public class ParallelTaskEngine implements TaskEngine {
}
public void oneDown() {
if (running.decrementAndGet() == 0) {
if (finalizer != null) {
if (running.decrementAndGet() == 0) {
ParallelTaskEngine.this.syncTasks.add(finalizer);
}
}

View file

@ -1,23 +1,33 @@
package com.jozufozu.flywheel.backend.instancing.batching;
import java.util.concurrent.atomic.AtomicInteger;
// https://stackoverflow.com/questions/29655531
public class WaitGroup {
private int jobs = 0;
private final AtomicInteger counter = new AtomicInteger(0);
public synchronized void add(int i) {
jobs += i;
if (i == 0) {
return;
}
if (i == 1) {
this.counter.incrementAndGet();
} else {
this.counter.addAndGet(i);
}
}
public synchronized void done() {
if (--jobs == 0) {
notifyAll();
if (this.counter.decrementAndGet() == 0) {
this.notifyAll();
}
}
public synchronized void await() throws InterruptedException {
while (jobs > 0) {
wait();
while (this.counter.get() > 0) {
this.wait();
}
}

View file

@ -10,6 +10,7 @@ import com.jozufozu.flywheel.api.struct.StructWriter;
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferUsage;
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
import com.jozufozu.flywheel.backend.instancing.AbstractInstancer;
@ -42,7 +43,7 @@ public class GPUInstancer<D extends InstancedPart> extends AbstractInstancer<D>
public void init() {
if (vbo != null) return;
vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER);
vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER, GlBufferUsage.DYNAMIC_DRAW);
vbo.setGrowthMargin(instanceFormat.getStride() * 16);
}
@ -53,6 +54,14 @@ public class GPUInstancer<D extends InstancedPart> extends AbstractInstancer<D>
private final Set<GlVertexArray> boundTo = new HashSet<>();
void renderSetup(GlVertexArray vao) {
update();
if (boundTo.add(vao)) {
bindInstanceAttributes(vao);
}
}
private void update() {
if (anyToRemove) {
removeDeletedInstances();
}
@ -68,10 +77,6 @@ public class GPUInstancer<D extends InstancedPart> extends AbstractInstancer<D>
glInstanceCount = data.size();
if (boundTo.add(vao)) {
bindInstanceAttributes(vao);
}
anyToRemove = anyToUpdate = false;
}

View file

@ -33,6 +33,7 @@ import com.jozufozu.flywheel.core.compile.ProgramCompiler;
import com.jozufozu.flywheel.core.crumbling.CrumblingProgram;
import com.jozufozu.flywheel.core.model.Mesh;
import com.jozufozu.flywheel.core.model.ModelSupplier;
import com.jozufozu.flywheel.core.shader.StateSnapshot;
import com.jozufozu.flywheel.core.shader.WorldProgram;
import com.jozufozu.flywheel.core.source.FileResolution;
import com.jozufozu.flywheel.core.vertex.Formats;
@ -140,6 +141,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
type.setupRenderState();
Textures.bindActiveTextures();
CoreShaderInfo coreShaderInfo = CoreShaderInfo.get();
StateSnapshot state = GameStateRegistry.takeSnapshot();
for (var entry : Multimaps.asMap(multimap).entrySet()) {
var shader = entry.getKey();
@ -151,7 +153,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
continue;
}
setup(shader, coreShaderInfo, camX, camY, camZ, viewProjection, level);
setup(shader, coreShaderInfo, camX, camY, camZ, viewProjection, level, state);
for (var drawCall : drawCalls) {
drawCall.render();
@ -162,7 +164,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
type.clearRenderState();
}
protected P setup(ShaderState desc, CoreShaderInfo coreShaderInfo, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) {
protected P setup(ShaderState desc, CoreShaderInfo coreShaderInfo, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level, StateSnapshot ctx) {
VertexType vertexType = desc.vertex();
FileResolution instanceShader = desc.instance()
@ -171,7 +173,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
P program = context.getProgram(new ProgramCompiler.Context(vertexType, instanceShader,
material.vertexShader(), material.fragmentShader(), coreShaderInfo.getAdjustedAlphaDiscard(),
coreShaderInfo.fogType(), GameStateRegistry.takeSnapshot()));
coreShaderInfo.fogType(), ctx));
program.bind();
program.uploadUniforms(camX, camY, camZ, viewProjection, level);