Skip to content

Commit

Permalink
Little light lut
Browse files Browse the repository at this point in the history
- Commit entire chunks of light at a time
- Share all light data between embeddings
  • Loading branch information
Jozufozu committed Jun 6, 2024
1 parent ee3958b commit 9ac7b4c
Show file tree
Hide file tree
Showing 16 changed files with 524 additions and 386 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import org.joml.Matrix4fc;

import dev.engine_room.flywheel.api.BackendImplemented;
import net.minecraft.world.level.BlockAndTintGetter;
import it.unimi.dsi.fastutil.longs.LongSet;

@BackendImplemented
public interface VisualEmbedding extends VisualizationContext {
Expand All @@ -16,30 +16,7 @@ public interface VisualEmbedding extends VisualizationContext {
*/
void transforms(Matrix4fc pose, Matrix3fc normal);

/**
* Collect light information from the given level for the given box.
*
* <p>Call this method on as many or as few boxes as you need to
* encompass all child visuals of this embedding.</p>
*
* <p>After this method is called, instances rendered from this
* embedding within the given box will be lit as if they were in
* the given level.</p>
*
* @param level The level to collect light information from.
* @param minX The minimum x coordinate of the box.
* @param minY The minimum y coordinate of the box.
* @param minZ The minimum z coordinate of the box.
* @param sizeX The size of the box in the x direction.
* @param sizeY The size of the box in the y direction.
* @param sizeZ The size of the box in the z direction.
*/
void collectLight(BlockAndTintGetter level, int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ);

/**
* Reset any collected lighting information.
*/
void invalidateLight();
void lightChunks(LongSet chunks);

/**
* Delete this embedding.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ public final class Backends {
* Use GPU instancing to render everything.
*/
public static final Backend INSTANCING = SimpleBackend.builder()
.engineFactory(level -> new EngineImpl(new InstancedDrawManager(InstancingPrograms.get()), 256))
.engineFactory(level -> new EngineImpl(level, new InstancedDrawManager(InstancingPrograms.get()), 256))
.supported(() -> GlCompat.SUPPORTS_INSTANCING && InstancingPrograms.allLoaded() && !ShadersModHandler.isShaderPackInUse())
.register(Flywheel.rl("instancing"));

/**
* Use Compute shaders to cull instances.
*/
public static final Backend INDIRECT = SimpleBackend.builder()
.engineFactory(level -> new EngineImpl(new IndirectDrawManager(IndirectPrograms.get()), 256))
.engineFactory(level -> new EngineImpl(level, new IndirectDrawManager(IndirectPrograms.get()), 256))
.fallback(() -> Backends.INSTANCING)
.supported(() -> GlCompat.SUPPORTS_INDIRECT && IndirectPrograms.allLoaded() && !ShadersModHandler.isShaderPackInUse())
.register(Flywheel.rl("indirect"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import dev.engine_room.flywheel.api.visualization.VisualEmbedding;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.backend.engine.embed.Environment;
import dev.engine_room.flywheel.backend.engine.embed.LightStorage;
import dev.engine_room.flywheel.backend.engine.embed.TopLevelEmbeddedEnvironment;
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
import dev.engine_room.flywheel.backend.gl.GlStateTracker;
Expand All @@ -24,19 +25,22 @@
import net.minecraft.client.Camera;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Vec3i;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.phys.Vec3;

public class EngineImpl implements Engine {
private final int sqrMaxOriginDistance;
private final DrawManager<? extends AbstractInstancer<?>> drawManager;
private final EnvironmentStorage environmentStorage = new EnvironmentStorage();
private final LightStorage lightStorage;
private final Flag flushFlag = new NamedFlag("flushed");

private BlockPos renderOrigin = BlockPos.ZERO;

public EngineImpl(DrawManager<? extends AbstractInstancer<?>> drawManager, int maxOriginDistance) {
public EngineImpl(LevelAccessor level, DrawManager<? extends AbstractInstancer<?>> drawManager, int maxOriginDistance) {
this.drawManager = drawManager;
sqrMaxOriginDistance = maxOriginDistance * maxOriginDistance;
lightStorage = new LightStorage(level);
}

@Override
Expand Down Expand Up @@ -93,6 +97,7 @@ public Vec3i renderOrigin() {
public void delete() {
drawManager.delete();
environmentStorage.delete();
lightStorage.delete();
}

public <I extends Instance> Instancer<I> instancer(Environment environment, InstanceType<I> type, Model model, RenderStage stage) {
Expand All @@ -113,6 +118,10 @@ public EnvironmentStorage environmentStorage() {
return environmentStorage;
}

public LightStorage lightStorage() {
return lightStorage;
}

private class VisualizationContextImpl implements VisualizationContext {
private final InstancerProviderImpl instancerProvider;
private final RenderStage stage;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,22 @@
package dev.engine_room.flywheel.backend.engine;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import dev.engine_room.flywheel.backend.engine.embed.AbstractEmbeddedEnvironment;
import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet;
import it.unimi.dsi.fastutil.objects.ReferenceSet;
import it.unimi.dsi.fastutil.objects.ReferenceSets;

public class EnvironmentStorage {
protected final ReferenceSet<AbstractEmbeddedEnvironment> environments = ReferenceSets.synchronize(new ReferenceLinkedOpenHashSet<>());
private final Queue<AbstractEmbeddedEnvironment> forDeletion = new ConcurrentLinkedQueue<>();

public void track(AbstractEmbeddedEnvironment environment) {
environments.add(environment);
}

public void enqueueDeletion(AbstractEmbeddedEnvironment environment) {
environments.remove(environment);

forDeletion.add(environment);
}

public void flush() {
AbstractEmbeddedEnvironment env;

while ((env = forDeletion.poll()) != null) {
env.actuallyDelete();
}

environments.forEach(AbstractEmbeddedEnvironment::flush);
}

public void delete() {
environments.forEach(AbstractEmbeddedEnvironment::actuallyDelete);
environments.clear();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public abstract class AbstractEmbeddedEnvironment extends AtomicReferenceCounted
private final Matrix4f poseComposed = new Matrix4f();
private final Matrix3f normalComposed = new Matrix3f();
private final InstancerProvider instancerProvider;
private final EngineImpl engine;
protected final EngineImpl engine;
private final RenderStage renderStage;

public AbstractEmbeddedEnvironment(EngineImpl engine, RenderStage renderStage) {
Expand Down Expand Up @@ -105,20 +105,7 @@ public void delete() {
release();
}

/**
* Called when referenceCount goes to 0
*/
@Override
public void _delete() {
engine.environmentStorage().enqueueDeletion(this);
}

public abstract void setupLight(GlProgram program);

public abstract void composeMatrices(Matrix4f pose, Matrix3f normal);

/**
* Called in EnvironmentStorage#flush
*/
public abstract void actuallyDelete();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package dev.engine_room.flywheel.backend.engine.embed;

import dev.engine_room.flywheel.lib.memory.MemoryBlock;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;

public class Arena {
private final long elementSizeBytes;

private MemoryBlock memoryBlock;

// Monotonic index, generally represents the size of the arena.
private int top = 0;
// List of free indices.
private final IntList freeStack = new IntArrayList();

public Arena(long elementSizeBytes, int initialCapacity) {
this.elementSizeBytes = elementSizeBytes;

memoryBlock = MemoryBlock.malloc(elementSizeBytes * initialCapacity);
}

public int alloc() {
// First re-use freed elements.
if (!freeStack.isEmpty()) {
return freeStack.removeInt(freeStack.size() - 1);
}

// Make sure there's room to increment top.
if (top * elementSizeBytes >= memoryBlock.size()) {
memoryBlock = memoryBlock.realloc(memoryBlock.size() * 2);
}

// Return the top index and increment.
return top++;
}

public void free(int i) {
// That's it! Now pls don't try to use it.
freeStack.add(i);
}

public long indexToPointer(int i) {
return memoryBlock.ptr() + i * elementSizeBytes;
}

public void delete() {
memoryBlock.free();
}
}

This file was deleted.

Loading

0 comments on commit 9ac7b4c

Please sign in to comment.