mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-22 19:07:54 +01:00
Misc. tweaks
- Drastically reduce stutter on origin shift (it's still bad) - GPUInstancers mark their buffers as dynamic
This commit is contained in:
parent
1ab1c9e6f6
commit
aa10930fa8
6 changed files with 63 additions and 37 deletions
|
@ -327,12 +327,18 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
AbstractInstance renderer = createRaw(obj);
|
AbstractInstance renderer = createRaw(obj);
|
||||||
|
|
||||||
if (renderer != null) {
|
if (renderer != null) {
|
||||||
|
setup(obj, renderer);
|
||||||
|
instances.put(obj, renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setup(T obj, AbstractInstance renderer) {
|
||||||
renderer.init();
|
renderer.init();
|
||||||
renderer.updateLight();
|
renderer.updateLight();
|
||||||
LightUpdater.get(renderer.level)
|
LightUpdater.get(renderer.level)
|
||||||
.addListener(renderer);
|
.addListener(renderer);
|
||||||
instances.put(obj, renderer);
|
|
||||||
|
|
||||||
if (renderer instanceof TickableInstance r) {
|
if (renderer instanceof TickableInstance r) {
|
||||||
tickableInstances.put(obj, r);
|
tickableInstances.put(obj, r);
|
||||||
r.tick();
|
r.tick();
|
||||||
|
@ -344,14 +350,21 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return renderer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOriginShift() {
|
public void onOriginShift() {
|
||||||
ArrayList<T> instanced = new ArrayList<>(instances.keySet());
|
dynamicInstances.clear();
|
||||||
invalidate();
|
tickableInstances.clear();
|
||||||
instanced.forEach(this::add);
|
instances.replaceAll((obj, instance) -> {
|
||||||
|
instance.remove();
|
||||||
|
|
||||||
|
AbstractInstance out = createRaw(obj);
|
||||||
|
|
||||||
|
if (out != null) {
|
||||||
|
setup(obj, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void detachLightListeners() {
|
public void detachLightListeners() {
|
||||||
|
|
|
@ -3,7 +3,6 @@ package com.jozufozu.flywheel.backend.instancing;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.model.MeshPool;
|
|
||||||
import com.jozufozu.flywheel.config.FlwCommands;
|
import com.jozufozu.flywheel.config.FlwCommands;
|
||||||
import com.jozufozu.flywheel.config.FlwConfig;
|
import com.jozufozu.flywheel.config.FlwConfig;
|
||||||
import com.jozufozu.flywheel.core.RenderContext;
|
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.entity.Entity;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.event.TickEvent;
|
import net.minecraftforge.event.TickEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
|
||||||
|
|
||||||
public class InstancedRenderDispatcher {
|
public class InstancedRenderDispatcher {
|
||||||
|
|
||||||
|
|
|
@ -268,8 +268,8 @@ public class ParallelTaskEngine implements TaskEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void oneDown() {
|
public void oneDown() {
|
||||||
if (running.decrementAndGet() == 0) {
|
|
||||||
if (finalizer != null) {
|
if (finalizer != null) {
|
||||||
|
if (running.decrementAndGet() == 0) {
|
||||||
ParallelTaskEngine.this.syncTasks.add(finalizer);
|
ParallelTaskEngine.this.syncTasks.add(finalizer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,33 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.batching;
|
package com.jozufozu.flywheel.backend.instancing.batching;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/29655531
|
// https://stackoverflow.com/questions/29655531
|
||||||
public class WaitGroup {
|
public class WaitGroup {
|
||||||
|
|
||||||
private int jobs = 0;
|
private final AtomicInteger counter = new AtomicInteger(0);
|
||||||
|
|
||||||
public synchronized void add(int i) {
|
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() {
|
public synchronized void done() {
|
||||||
if (--jobs == 0) {
|
if (this.counter.decrementAndGet() == 0) {
|
||||||
notifyAll();
|
this.notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void await() throws InterruptedException {
|
public synchronized void await() throws InterruptedException {
|
||||||
while (jobs > 0) {
|
while (this.counter.get() > 0) {
|
||||||
wait();
|
this.wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
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.MappedBuffer;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstancer;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstancer;
|
||||||
|
@ -42,7 +43,7 @@ public class GPUInstancer<D extends InstancedPart> extends AbstractInstancer<D>
|
||||||
public void init() {
|
public void init() {
|
||||||
if (vbo != null) return;
|
if (vbo != null) return;
|
||||||
|
|
||||||
vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER);
|
vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER, GlBufferUsage.DYNAMIC_DRAW);
|
||||||
vbo.setGrowthMargin(instanceFormat.getStride() * 16);
|
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<>();
|
private final Set<GlVertexArray> boundTo = new HashSet<>();
|
||||||
|
|
||||||
void renderSetup(GlVertexArray vao) {
|
void renderSetup(GlVertexArray vao) {
|
||||||
|
update();
|
||||||
|
|
||||||
|
if (boundTo.add(vao)) {
|
||||||
|
bindInstanceAttributes(vao);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void update() {
|
||||||
if (anyToRemove) {
|
if (anyToRemove) {
|
||||||
removeDeletedInstances();
|
removeDeletedInstances();
|
||||||
}
|
}
|
||||||
|
@ -68,10 +77,6 @@ public class GPUInstancer<D extends InstancedPart> extends AbstractInstancer<D>
|
||||||
|
|
||||||
glInstanceCount = data.size();
|
glInstanceCount = data.size();
|
||||||
|
|
||||||
if (boundTo.add(vao)) {
|
|
||||||
bindInstanceAttributes(vao);
|
|
||||||
}
|
|
||||||
|
|
||||||
anyToRemove = anyToUpdate = false;
|
anyToRemove = anyToUpdate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ import com.jozufozu.flywheel.core.compile.ProgramCompiler;
|
||||||
import com.jozufozu.flywheel.core.crumbling.CrumblingProgram;
|
import com.jozufozu.flywheel.core.crumbling.CrumblingProgram;
|
||||||
import com.jozufozu.flywheel.core.model.Mesh;
|
import com.jozufozu.flywheel.core.model.Mesh;
|
||||||
import com.jozufozu.flywheel.core.model.ModelSupplier;
|
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.shader.WorldProgram;
|
||||||
import com.jozufozu.flywheel.core.source.FileResolution;
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
import com.jozufozu.flywheel.core.vertex.Formats;
|
import com.jozufozu.flywheel.core.vertex.Formats;
|
||||||
|
@ -140,6 +141,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
type.setupRenderState();
|
type.setupRenderState();
|
||||||
Textures.bindActiveTextures();
|
Textures.bindActiveTextures();
|
||||||
CoreShaderInfo coreShaderInfo = CoreShaderInfo.get();
|
CoreShaderInfo coreShaderInfo = CoreShaderInfo.get();
|
||||||
|
StateSnapshot state = GameStateRegistry.takeSnapshot();
|
||||||
|
|
||||||
for (var entry : Multimaps.asMap(multimap).entrySet()) {
|
for (var entry : Multimaps.asMap(multimap).entrySet()) {
|
||||||
var shader = entry.getKey();
|
var shader = entry.getKey();
|
||||||
|
@ -151,7 +153,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
setup(shader, coreShaderInfo, camX, camY, camZ, viewProjection, level);
|
setup(shader, coreShaderInfo, camX, camY, camZ, viewProjection, level, state);
|
||||||
|
|
||||||
for (var drawCall : drawCalls) {
|
for (var drawCall : drawCalls) {
|
||||||
drawCall.render();
|
drawCall.render();
|
||||||
|
@ -162,7 +164,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
type.clearRenderState();
|
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();
|
VertexType vertexType = desc.vertex();
|
||||||
FileResolution instanceShader = desc.instance()
|
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,
|
P program = context.getProgram(new ProgramCompiler.Context(vertexType, instanceShader,
|
||||||
material.vertexShader(), material.fragmentShader(), coreShaderInfo.getAdjustedAlphaDiscard(),
|
material.vertexShader(), material.fragmentShader(), coreShaderInfo.getAdjustedAlphaDiscard(),
|
||||||
coreShaderInfo.fogType(), GameStateRegistry.takeSnapshot()));
|
coreShaderInfo.fogType(), ctx));
|
||||||
|
|
||||||
program.bind();
|
program.bind();
|
||||||
program.uploadUniforms(camX, camY, camZ, viewProjection, level);
|
program.uploadUniforms(camX, camY, camZ, viewProjection, level);
|
||||||
|
|
Loading…
Reference in a new issue